2 * Copyright 2000, International Business Machines Corporation and others.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
10 /*------------------------------------------------------------------------
14 * Routines that actually do the disk updates.
16 *------------------------------------------------------------------------*/
18 #include <afs/param.h>
20 #include <sys/types.h>
22 #include <sys/param.h>
26 #if defined(AFS_SGI_ENV) || defined(AFS_SUN5_ENV)
27 #include <sys/mkdev.h>
29 #ifdef AFS_LINUX20_ENV
30 #include <sys/sysmacros.h>
37 CTREEPTR LocateChildNode();
39 static struct stat stb;
51 static int FixLostFoundDir();
55 /* $$important: these will have to be fixed with an error recovery mechanism */
69 #endif /* AFS_AIX_ENV */
104 (void)dochtyp(np, path);
118 ret = dochtyp(np, path);
124 if ((np->flag & F_PROTO) != 0) {
126 if (np->proto.info.rdev != stb.st_rdev) {
144 message("Unknown device type: %d\n", np->type);
148 loudonly_message("mknod %s %d %d %s", type,
149 major(np->proto.info.rdev),
150 minor(np->proto.info.rdev), path);
153 (path, (int)np->mode | (int)np->type,
154 (int)np->proto.info.rdev) < 0)
155 message("mknod %s %d %d %s; %m", type,
156 major(np->proto.info.rdev),
157 minor(np->proto.info.rdev), path);
158 if ((ret = lstat(path, &stb)) < 0)
159 message("lstat %s; %m", path);
180 * Don't have to call dochtyp() here; just set ret to the value
181 * saying everything is fine.
189 if ((np->flag & F_PROTO) != 0) {
191 if (np->proto.info.rdev != stb.st_rdev) {
197 loudonly_message("mknod p %s", path);
201 (path, (int)(np->mode) | (int)(np->type),
202 (int)(np->proto.info.rdev)) < 0)
203 message("mknod p %s; %m", path);
204 if ((ret = lstat(path, &stb)) < 0)
205 message("lstat %s; %m", path);
225 char temp[MAXPATHLEN], temp2[MAXPATHLEN];
228 ret = dochtyp(np, path);
233 if ((np->flag & F_PROTO) == 0)
235 if (np->updtspec & U_ABSPATH)
236 sprintf(temp, "%s", np->proto.info.path);
238 sprintf(temp, "%s%s", np->proto.info.path, path);
240 if ((cc = readlink(path, temp2, sizeof(temp2) - 1)) < 0) {
241 message("readlink %s; %m", path);
245 if (strcmp(temp2, temp)) {
246 if ((np->updtspec & U_NOOVERWRITE) == 0) {
250 loudonly_message("INHIBIT %s updating", path);
255 loudonly_message("ln %s %s", path, temp);
256 if (!opt_lazy && symlink(temp, path) < 0)
257 message("symlink %s %s; %m", temp, path);
272 ret = dochtyp(np, path);
278 loudonly_message("mkdir %s", path);
280 if (mkdir(path, (int)np->mode & ~S_IFMT) < 0)
281 message("mkdir %s; %m", path);
282 if ((ret = lstat(path, &stb)) < 0)
283 message("lstat %s; %m", path);
286 if (np->updtspec & U_LOSTFOUND)
287 (void)FixLostFoundDir(path);
288 if (np->updtspec & U_RMEXTRA)
289 (void)FixDir(np, path);
307 ret = dochtyp(np, path);
312 if ((np->flag & F_PROTO) != 0) {
314 np->updtspec &= ~U_RENAMEOLD;
316 if ((np->updtspec & U_NOOVERWRITE) == 0)
317 if (np->mtime != stb.st_mtime)
321 if ((ret = FixReg(np, path)) >= 0)
322 ret = lstat(path, &stb);
338 * This function makes sure the path on local disk has the same file type
339 * as that in the given prototype. If it doesn't (and the -rebootfile
340 * flag hasn't been used with a file marked as requiring a reboot), then
341 * we delete the local disk copy and return -1. If inhibiting the overwrite
342 * is in order, we return 1. If the types already match (or the above
343 * reboot scenario is true), we return 0.
353 if (lstat(path, &stb) < 0)
356 if (opt_kflag && (stb.st_mode & 0222) == 0) {
357 loudonly_message("INHIBIT %s updating", path);
361 if ((stb.st_mode & S_IFMT) == np->type)
363 if (!opt_reboot && (np->flag & F_UPDT) && (np->updtspec & U_REBOOT)) {
364 message("%s is out of date; please REBOOT!", path);
380 if ((np->flag & F_MODE) == 0)
382 if ((np->mode & ~S_IFMT) == (stb.st_mode & ~S_IFMT))
384 loudonly_message("chmod %s %o", path, np->mode & ~S_IFMT);
385 if (!opt_lazy && chmod(path, (int)np->mode & ~S_IFMT) < 0)
386 message("chmod %s; %m", path);
397 if ((np->flag & F_UID) == 0)
398 np->uid = stb.st_uid;
399 if ((np->flag & F_GID) == 0)
400 np->gid = stb.st_gid;
401 if (np->uid == stb.st_uid && np->gid == stb.st_gid)
403 loudonly_message("chown %s %d %d", path, np->uid, np->gid);
404 if (!opt_lazy && chown(path, np->uid, np->gid) < 0)
405 message("chown %s; %m", path);
416 struct timeval tm[2];
418 if (np->mtime == stb.st_mtime
419 || (!opt_reboot && (np->updtspec & U_REBOOT)))
421 tm[0].tv_sec = tm[1].tv_sec = np->mtime;
422 tm[0].tv_usec = tm[1].tv_usec = 0;
426 date = ctime((time_t *) & np->mtime);
428 loudonly_message("utimes %s [%s]", path, date);
430 if (!opt_lazy && utimes(path, tm) < 0)
431 message("utimes %s; %m", path);
436 FixLostFoundDir(path)
439 { /*FixLostFoundDir */
441 if (stb.st_size >= 3584)
443 return mklostfound(path);
445 } /*FixLostFoundDir */
455 register struct dirent *de;
458 verbose_message("cleandir %s", path);
459 if ((dp = opendir(path)) == 0) {
460 message("opendir %s; %m", path);
463 endp = path + strlen(path);
465 while ((de = readdir(dp)) != 0) {
466 if (de->d_name[0] == '.') {
467 if (de->d_name[1] == 0)
469 if (de->d_name[1] == '.' && de->d_name[2] == 0)
472 if (LocateChildNode(np, de->d_name, C_LOCATE) != 0)
474 (void)strcpy(endp, de->d_name);
490 char new[MAXPATHLEN], old[MAXPATHLEN], temp[MAXPATHLEN];
492 if (!opt_reboot && (np->updtspec & U_REBOOT)) {
494 ("%s is a 'Q' file and -rebootfiles is set; not updated!", path);
497 (void)sprintf(new, "%s.new", path);
498 if (np->updtspec & U_ABSPATH)
499 (void)sprintf(temp, "%s", np->proto.info.path);
501 (void)sprintf(temp, "%s%s", np->proto.info.path, path);
504 if (np->updtspec & U_RENAMEOLD) {
505 (void)sprintf(old, "%s.old", path);
511 if (np->updtspec & U_REBOOT)
512 status = status_reboot;