Switch to unified view

a/src/utils/copyfile.cpp b/src/utils/copyfile.cpp
...
...
15
 *   You should have received a copy of the GNU General Public License
15
 *   You should have received a copy of the GNU General Public License
16
 *   along with this program; if not, write to the
16
 *   along with this program; if not, write to the
17
 *   Free Software Foundation, Inc.,
17
 *   Free Software Foundation, Inc.,
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19
 */
19
 */
20
20
#ifndef TEST_COPYFILE
21
#include <stdio.h>
21
#include <stdio.h>
22
#include <fcntl.h>
22
#include <fcntl.h>
23
#include <errno.h>
23
#include <errno.h>
24
#include <unistd.h>
24
#include <unistd.h>
25
#include <cstring>
25
#include <cstring>
26
#include <sys/stat.h>
27
#include <sys/times.h>
26
28
27
#include <string>
29
#include "copyfile.h"
28
using std::string;
29
30
#include "debuglog.h"
30
#include "debuglog.h"
31
31
32
#define CPBSIZ 8192
32
#define CPBSIZ 8192
33
#define COPYFILE_NOERRUNLINK 1
33
#define COPYFILE_NOERRUNLINK 1
34
34
35
bool copyfile(const char *src, const char *dst, string &reason, int flags = 0)
35
bool copyfile(const char *src, const char *dst, string &reason, int flags)
36
{
36
{
37
  int sfd = -1;
37
  int sfd = -1;
38
  int dfd = -1;
38
  int dfd = -1;
39
  bool ret = false;
39
  bool ret = false;
40
  char buf[CPBSIZ];
40
  char buf[CPBSIZ];
41
42
  reason.erase();
43
41
44
  LOGDEB(("copyfile: %s to %s\n", src, dst));
42
  LOGDEB(("copyfile: %s to %s\n", src, dst));
45
43
46
  if ((sfd = open(src, O_RDONLY)) < 0) {
44
  if ((sfd = open(src, O_RDONLY)) < 0) {
47
      reason += string("open ") + src + ": " + strerror(errno);
45
      reason += string("open ") + src + ": " + strerror(errno);
...
...
68
      if (write(dfd, buf, didread) != didread) {
66
      if (write(dfd, buf, didread) != didread) {
69
      reason += string("write dst ") + src + ": " + strerror(errno);
67
      reason += string("write dst ") + src + ": " + strerror(errno);
70
      goto out;
68
      goto out;
71
      }
69
      }
72
  }
70
  }
71
73
  ret = true;
72
  ret = true;
74
 out:
73
 out:
75
  if (ret == false && !(flags&COPYFILE_NOERRUNLINK))
74
  if (ret == false && !(flags&COPYFILE_NOERRUNLINK))
76
    unlink(dst);
75
    unlink(dst);
77
  if (sfd >= 0)
76
  if (sfd >= 0)
78
    close(sfd);
77
    close(sfd);
79
  if (dfd >= 0)
78
  if (dfd >= 0)
80
    close(dfd);
79
    close(dfd);
81
  return ret;
80
  return ret;
82
}
81
}
82
83
bool renameormove(const char *src, const char *dst, string &reason)
84
{
85
    // First try rename(2). If this succeeds we're done. If this fails
86
    // with EXDEV, try to copy. Unix really should have a library function
87
    // for this.
88
    if (rename(src, dst) == 0) {
89
        return true;
90
    }
91
    if (errno != EXDEV) {
92
        reason += string("rename(2) failed: ") + strerror(errno);
93
        return false;
94
    } 
95
96
    struct stat st;
97
    if (stat(src, &st) < 0) {
98
        reason += string("Can't stat ") + src + " : " + strerror(errno);
99
        return false;
100
    }
101
    if (!copyfile(src, dst, reason))
102
        return false;
103
104
    struct stat st1;
105
    if (stat(dst, &st1) < 0) {
106
        reason += string("Can't stat ") + dst + " : " + strerror(errno);
107
        return false;
108
    }
109
110
    // Try to preserve modes, owner, times. This may fail for a number
111
    // of reasons
112
    if ((st1.st_mode & 0777) != (st.st_mode & 0777)) {
113
        chmod(dst, st.st_mode&0777);
114
    }
115
    if (st.st_uid != st1.st_uid || st.st_gid != st1.st_gid) {
116
        chown(dst, st.st_uid, st.st_gid);
117
    }
118
    struct timeval times[2];
119
    times[0].tv_sec = st.st_atime;
120
    times[0].tv_usec = 0;
121
    times[1].tv_sec = st.st_mtime;
122
    times[1].tv_usec = 0;
123
    utimes(dst, times);
124
125
    // All ok, get rid of origin
126
    if (unlink(src) < 0) {
127
        reason += string("Can't unlink ") + src + "Error : " + strerror(errno);
128
    }
129
130
    return true;
131
}
132
133
134
#else 
135
136
#include <stdlib.h>
137
#include <unistd.h>
138
139
#include <string>
140
#include <iostream>
141
using namespace std;
142
143
#include "copyfile.h"
144
145
static int     op_flags;
146
#define OPT_MOINS 0x1
147
#define OPT_m     0x2
148
149
static const char *thisprog;
150
static char usage [] =
151
"trcopyfile [-m] src dst\n"
152
" -m : move instead of copying\n"
153
"\n"
154
;
155
static void
156
Usage(void)
157
{
158
    fprintf(stderr, "%s: usage:\n%s", thisprog, usage);
159
    exit(1);
160
}
161
162
int main(int argc, const char **argv)
163
{
164
    thisprog = argv[0];
165
    argc--; argv++;
166
167
    while (argc > 0 && **argv == '-') {
168
        (*argv)++;
169
        if (!(**argv))
170
            /* Cas du "adb - core" */
171
            Usage();
172
        while (**argv)
173
            switch (*(*argv)++) {
174
            case 'm': op_flags |= OPT_m; break;
175
            default: Usage(); break;
176
            }
177
        argc--; argv++;
178
    }
179
180
    if (argc != 2)
181
        Usage();
182
    string src = *argv++;argc--;
183
    string dst = *argv++;argc--;
184
    bool ret;
185
    string reason;
186
    if (op_flags & OPT_m) {
187
        ret = renameormove(src.c_str(), dst.c_str(), reason);
188
    } else {
189
        ret = copyfile(src.c_str(), dst.c_str(), reason);
190
    }
191
    if (!ret) {
192
        cerr << reason << endl;
193
        exit(1);
194
    } 
195
    exit(0);
196
}
197
198
199
#endif