[6434] | 1 | /* |
---|
| 2 | * Copyright (C) 1988 Tim Shepard All rights reserved. |
---|
| 3 | * Copyright (C) 1989 MIT/Project Athena All rights reserved. |
---|
| 4 | */ |
---|
| 5 | |
---|
| 6 | #if defined(_AIX) && defined(i386) |
---|
| 7 | #define unlink(a) (rmslink(a) && unlink(a)) |
---|
| 8 | #endif |
---|
| 9 | |
---|
| 10 | #define noupdate(problem) printf("Not %sing %s because %s\n",action,targname,problem) |
---|
[8318] | 11 | #define update_error(problem) printf("Error %sing %s: %s: %s\n",action,targname,problem,strerror(errno)) |
---|
[6434] | 12 | |
---|
| 13 | switch (typeofaction) { |
---|
| 14 | int status; |
---|
| 15 | #define action "copy" |
---|
| 16 | case ACTION_COPY: |
---|
| 17 | case ACTION_LOCAL: |
---|
| 18 | /* We want to ignore "virtual" files */ |
---|
| 19 | if (srctype == TYPE_V) |
---|
| 20 | break; |
---|
| 21 | |
---|
| 22 | if (exists) { |
---|
| 23 | if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)) { |
---|
| 24 | noupdate("the target is a local version."); |
---|
| 25 | break; |
---|
| 26 | } |
---|
| 27 | if (srctype != targtype && (srctype & TYPE_V) == 0) { |
---|
| 28 | if (!fflag && (targtype != TYPE_L)) { |
---|
| 29 | noupdate("the file types diff. Use -f to override."); |
---|
| 30 | break; |
---|
| 31 | } |
---|
| 32 | if (verbosef || nflag) |
---|
| 33 | printf("Removing %s (file types differ).\n", targname); |
---|
| 34 | if (!nflag) { |
---|
| 35 | if (targtype == TYPE_D) { |
---|
| 36 | if (recursive_rmdir(targname)) { |
---|
| 37 | update_error("recursive rmdir failed"); |
---|
| 38 | break; |
---|
| 39 | } |
---|
| 40 | } else |
---|
| 41 | if (unlink(targname)) { |
---|
| 42 | update_error("unlink failed"); |
---|
| 43 | break; |
---|
| 44 | } |
---|
| 45 | } |
---|
| 46 | exists = FALSE; |
---|
| 47 | } |
---|
| 48 | } |
---|
| 49 | switch (srctype) { |
---|
| 50 | case TYPE_R: |
---|
| 51 | if (!exists) { |
---|
| 52 | if (nflag) { |
---|
| 53 | printf("Copying %s (mode is %5.5o).\n", |
---|
| 54 | srcname,targname,srcmode); |
---|
| 55 | break; |
---|
| 56 | } |
---|
| 57 | if (copyfile(srcname,targname,srcmode)) |
---|
| 58 | update_error("copy failed"); |
---|
| 59 | setdates(); |
---|
| 60 | if (pflag && |
---|
| 61 | (chown(targname, -1, srcgid) || |
---|
| 62 | chown(targname, srcuid, -1))) |
---|
| 63 | update_error("chown failed"); |
---|
| 64 | break; |
---|
| 65 | } |
---|
| 66 | switch(status = filecheck3()) { |
---|
| 67 | case UPTODATE: |
---|
| 68 | break; |
---|
| 69 | case NEWERDATE: |
---|
| 70 | if (!fflag) { |
---|
| 71 | noupdate("the target is a more recent copy."); |
---|
| 72 | break; |
---|
| 73 | } |
---|
| 74 | /* fall through */ |
---|
| 75 | case OUTOFDATE: |
---|
| 76 | if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)){ |
---|
| 77 | noupdate("the target is a local version (the target is old)."); |
---|
| 78 | break; |
---|
| 79 | } |
---|
| 80 | if (verbosef || nflag) |
---|
| 81 | printf("Updating out of date %s .\n", targname); |
---|
| 82 | if (!nflag) { |
---|
| 83 | if (unlink(targname)) { |
---|
| 84 | update_error("unlink failed"); |
---|
| 85 | break; |
---|
| 86 | } else if (copyfile(srcname,targname,srcmode)) { |
---|
| 87 | update_error("copy failed"); |
---|
| 88 | break; |
---|
| 89 | } |
---|
| 90 | setdates(); |
---|
| 91 | } |
---|
| 92 | /* fall through */ |
---|
| 93 | case FIXOWNANDMODE: |
---|
| 94 | case FIXMODE: |
---|
| 95 | if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)){ |
---|
| 96 | noupdate("the target is a local version (the ownership is different)."); |
---|
| 97 | break; |
---|
| 98 | } |
---|
| 99 | if ((verbosef || nflag) && (status == FIXOWNANDMODE)) |
---|
| 100 | printf("Fixing ownership and modes of %s .\n", |
---|
| 101 | targname); |
---|
| 102 | if ((verbosef || nflag) && (status == FIXMODE)) |
---|
| 103 | printf("Fixing modes of %s .\n", targname); |
---|
| 104 | |
---|
| 105 | if (!nflag && chmod(targname, srcmode)) |
---|
| 106 | update_error("chmod() failed"); |
---|
| 107 | if (!nflag && pflag && (status != FIXMODE) && |
---|
| 108 | (chown(targname, -1, srcgid) || |
---|
| 109 | chown(targname, srcuid, -1))) |
---|
| 110 | update_error("chown failed"); |
---|
| 111 | break; |
---|
| 112 | default: |
---|
| 113 | noupdate("of an internal error: filecheck3() returned an unknown value."); |
---|
| 114 | } |
---|
| 115 | break; |
---|
| 116 | |
---|
| 117 | case TYPE_L: |
---|
| 118 | if (exists) { |
---|
| 119 | char buf1[BUFSIZ], buf2[BUFSIZ]; |
---|
| 120 | int buf1_len, buf2_len; |
---|
| 121 | |
---|
| 122 | if (((buf1_len = readlink(srcname, buf1, BUFSIZ)) == |
---|
| 123 | (buf2_len = readlink(targname, buf2, BUFSIZ))) && |
---|
| 124 | !strncmp(buf1,buf2,buf1_len)) |
---|
| 125 | break; |
---|
| 126 | if ((verbosef || nflag) && (typeofaction == ACTION_LOCAL)){ |
---|
| 127 | noupdate("the target is a local link (the links are different)."); |
---|
| 128 | break; |
---|
| 129 | } |
---|
| 130 | if (verbosef || nflag) |
---|
| 131 | printf("Updating symbolic link %s .\n", targname); |
---|
| 132 | if (!nflag && unlink(targname)) |
---|
| 133 | update_error("unlink failed"); |
---|
| 134 | } else |
---|
| 135 | if (verbosef || nflag) |
---|
| 136 | printf("Copying symbolic link %s .\n",srcname); |
---|
| 137 | if (nflag) |
---|
| 138 | break; |
---|
| 139 | if (copylink(srcname,targname,srcmode)) |
---|
| 140 | update_error("copy of symbolic link failed."); |
---|
[10508] | 141 | #ifdef HAVE_LCHOWN |
---|
[8564] | 142 | else if (pflag && lchown(targname,srcuid,srcgid)) |
---|
| 143 | update_error("lchown() failed."); |
---|
| 144 | #endif |
---|
[6434] | 145 | break; |
---|
| 146 | |
---|
| 147 | case TYPE_D: |
---|
| 148 | if (!exists) { |
---|
| 149 | if (verbosef || nflag) |
---|
| 150 | printf("Creating directory %s .\n", targname); |
---|
| 151 | if (nflag) |
---|
| 152 | break; |
---|
| 153 | if (mkdir(targname,0777)) { |
---|
| 154 | update_error("mkdir() failed"); |
---|
| 155 | break; /* No point continuing... */ |
---|
| 156 | } |
---|
| 157 | else if (chmod(targname, srcmode)) |
---|
| 158 | update_error("chmod() failed"); |
---|
| 159 | else if (pflag && chown(targname, srcuid, srcgid)) |
---|
| 160 | update_error("chown() failed"); |
---|
| 161 | } else { |
---|
| 162 | switch(status = dircheck()) { |
---|
| 163 | case FIXMODE: |
---|
| 164 | case FIXOWNANDMODE: |
---|
| 165 | if ((verbosef || nflag) && |
---|
| 166 | (typeofaction == ACTION_LOCAL)) { |
---|
| 167 | noupdate("the target is a local version"); |
---|
| 168 | break; |
---|
| 169 | } |
---|
| 170 | if ((verbosef || nflag) && (status == FIXMODE)) |
---|
| 171 | printf("Fixing modes of %s .\n", targname); |
---|
| 172 | else if (verbosef || nflag) |
---|
| 173 | printf("Fixing ownership and modes of %s .\n", |
---|
| 174 | targname); |
---|
| 175 | if (!nflag && chmod(targname, srcmode)) |
---|
| 176 | update_error("chmod() failed"); |
---|
| 177 | if (!nflag && pflag && |
---|
| 178 | (chown(targname, -1, srcgid) || |
---|
| 179 | chown(targname, srcuid, -1))) { |
---|
| 180 | update_error("chown() failed"); |
---|
| 181 | break; |
---|
| 182 | } |
---|
| 183 | break; |
---|
| 184 | } |
---|
| 185 | } |
---|
| 186 | if (dodir(srcname, targname, part)) |
---|
| 187 | printf("The update of %s from %s aborted prematurely.\n", |
---|
| 188 | targname, srcname); |
---|
| 189 | break; |
---|
| 190 | |
---|
| 191 | case TYPE_C: |
---|
| 192 | case TYPE_B: |
---|
| 193 | noupdate("copying of devices is not yet supported."); |
---|
| 194 | break; |
---|
| 195 | } |
---|
| 196 | break; |
---|
| 197 | |
---|
| 198 | #undef action |
---|
| 199 | #define action "link" |
---|
| 200 | case ACTION_LINK: |
---|
| 201 | if (exists) { |
---|
| 202 | char linkbuf[MAXPATHLEN]; |
---|
| 203 | int linklen; |
---|
| 204 | |
---|
| 205 | switch(targtype) { |
---|
| 206 | case TYPE_V: |
---|
| 207 | /* This is a virtual file... so we should ignore it */ |
---|
| 208 | break; |
---|
| 209 | case TYPE_L: |
---|
| 210 | linklen = readlink(targname, linkbuf, MAXPATHLEN); |
---|
| 211 | if ((!strncmp(linkbuf, srcname, linklen)) && |
---|
| 212 | (*((char *)srcname + linklen) == 0)) |
---|
| 213 | break; |
---|
| 214 | /* fall through */ |
---|
| 215 | default: |
---|
| 216 | if (!fflag && targtype != TYPE_L) { |
---|
| 217 | noupdate("the target was not a symlink. Use -f to override.\n"); |
---|
| 218 | break; |
---|
| 219 | } |
---|
| 220 | if (verbosef || nflag) printf("Removing %s .\n",targname); |
---|
| 221 | if (!nflag) |
---|
| 222 | if (targtype == TYPE_D) { |
---|
| 223 | if (recursive_rmdir(targname)) { |
---|
| 224 | update_error("recursive rmdir failed"); |
---|
| 225 | break; |
---|
| 226 | } |
---|
| 227 | } else |
---|
| 228 | if (unlink(targname)) { |
---|
| 229 | update_error("unlink failed"); |
---|
| 230 | break; |
---|
| 231 | } |
---|
| 232 | exists = FALSE; |
---|
| 233 | break; |
---|
| 234 | } |
---|
| 235 | } |
---|
| 236 | if (exists) break; |
---|
| 237 | if (verbosef || nflag) |
---|
| 238 | printf("Creating symbolic link from %s to %s .\n", targname, srcname); |
---|
| 239 | if (!nflag && symlink(srcname,targname)) |
---|
| 240 | update_error("symlink failed"); |
---|
| 241 | break; |
---|
| 242 | |
---|
| 243 | /* |
---|
| 244 | * The action words are intentionally mispelled to |
---|
| 245 | * get the correct spelling during message displays |
---|
| 246 | */ |
---|
| 247 | #undef action |
---|
| 248 | #define action "ignor" |
---|
| 249 | case ACTION_IGNORE: |
---|
| 250 | break; |
---|
| 251 | |
---|
| 252 | #undef update_error |
---|
[8318] | 253 | #define update_error(problem) printf("Error %sing %s: %s: %s\n",action,targname,problem,strerror(errno)) |
---|
[6434] | 254 | |
---|
| 255 | #undef action |
---|
| 256 | #define action "delet" |
---|
| 257 | case ACTION_DELETE: |
---|
| 258 | if (!exists) |
---|
| 259 | break; |
---|
| 260 | if (verbosef || nflag) |
---|
| 261 | printf("Removing %s.\n", targname); |
---|
| 262 | if (!nflag) { |
---|
| 263 | if (targtype & TYPE_D) { |
---|
| 264 | if (recursive_rmdir(targname)) |
---|
| 265 | update_error("recursive rmdir failed"); |
---|
| 266 | } |
---|
| 267 | else if (unlink(targname)) |
---|
| 268 | update_error("unlink failed"); |
---|
| 269 | } |
---|
| 270 | break; |
---|
| 271 | } |
---|