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 */
58 update(CTREEPTR np, char *path)
66 #endif /* AFS_AIX_ENV */
95 UpdateSock(CTREEPTR np, char *path)
98 (void)dochtyp(np, path);
104 UpdateDev(CTREEPTR np, char *path)
109 ret = dochtyp(np, path);
115 if ((np->flag & F_PROTO) != 0) {
117 if (np->proto.info.rdev != stb.st_rdev) {
135 message("Unknown device type: %d\n", np->type);
139 loudonly_message("mknod %s %d %d %s", type,
140 major(np->proto.info.rdev),
141 minor(np->proto.info.rdev), path);
144 (path, (int)np->mode | (int)np->type,
145 (int)np->proto.info.rdev) < 0)
146 message("mknod %s %d %d %s; %m", type,
147 major(np->proto.info.rdev),
148 minor(np->proto.info.rdev), path);
149 if ((ret = lstat(path, &stb)) < 0)
150 message("lstat %s; %m", path);
162 UpdatePipe(CTREEPTR np, char *path)
168 * Don't have to call dochtyp() here; just set ret to the value
169 * saying everything is fine.
177 if ((np->flag & F_PROTO) != 0) {
179 if (np->proto.info.rdev != stb.st_rdev) {
185 loudonly_message("mknod p %s", path);
189 (path, (int)(np->mode) | (int)(np->type),
190 (int)(np->proto.info.rdev)) < 0)
191 message("mknod p %s; %m", path);
192 if ((ret = lstat(path, &stb)) < 0)
193 message("lstat %s; %m", path);
206 UpdateLnk(CTREEPTR np, char *path)
210 char temp[MAXPATHLEN], temp2[MAXPATHLEN];
213 ret = dochtyp(np, path);
218 if ((np->flag & F_PROTO) == 0)
220 if (np->updtspec & U_ABSPATH)
221 sprintf(temp, "%s", np->proto.info.path);
223 sprintf(temp, "%s%s", np->proto.info.path, path);
225 if ((cc = readlink(path, temp2, sizeof(temp2) - 1)) < 0) {
226 message("readlink %s; %m", path);
230 if (strcmp(temp2, temp)) {
231 if ((np->updtspec & U_NOOVERWRITE) == 0) {
235 loudonly_message("INHIBIT %s updating", path);
240 loudonly_message("ln %s %s", path, temp);
241 if (!opt_lazy && symlink(temp, path) < 0)
242 message("symlink %s %s; %m", temp, path);
249 UpdateDir(CTREEPTR np, char *path)
254 ret = dochtyp(np, path);
260 loudonly_message("mkdir %s", path);
262 if (mkdir(path, (int)np->mode & ~S_IFMT) < 0)
263 message("mkdir %s; %m", path);
264 if ((ret = lstat(path, &stb)) < 0)
265 message("lstat %s; %m", path);
268 if (np->updtspec & U_LOSTFOUND)
269 (void)FixLostFoundDir(path);
270 if (np->updtspec & U_RMEXTRA)
271 (void)FixDir(np, path);
281 UpdateReg(CTREEPTR np, char *path)
286 ret = dochtyp(np, path);
291 if ((np->flag & F_PROTO) != 0) {
293 np->updtspec &= ~U_RENAMEOLD;
295 if ((np->updtspec & U_NOOVERWRITE) == 0)
296 if (np->mtime != stb.st_mtime)
300 if ((ret = FixReg(np, path)) >= 0)
301 ret = lstat(path, &stb);
317 * This function makes sure the path on local disk has the same file type
318 * as that in the given prototype. If it doesn't (and the -rebootfile
319 * flag hasn't been used with a file marked as requiring a reboot), then
320 * we delete the local disk copy and return -1. If inhibiting the overwrite
321 * is in order, we return 1. If the types already match (or the above
322 * reboot scenario is true), we return 0.
326 dochtyp(CTREEPTR np, char *path)
328 if (lstat(path, &stb) < 0)
331 if (opt_kflag && (stb.st_mode & 0222) == 0) {
332 loudonly_message("INHIBIT %s updating", path);
336 if ((stb.st_mode & S_IFMT) == np->type)
338 if (!opt_reboot && (np->flag & F_UPDT) && (np->updtspec & U_REBOOT)) {
339 message("%s is out of date; please REBOOT!", path);
348 dochmod(CTREEPTR np, char *path)
350 if ((np->flag & F_MODE) == 0)
352 if ((np->mode & ~S_IFMT) == (stb.st_mode & ~S_IFMT))
354 loudonly_message("chmod %s %o", path, np->mode & ~S_IFMT);
355 if (!opt_lazy && chmod(path, (int)np->mode & ~S_IFMT) < 0)
356 message("chmod %s; %m", path);
360 dochown(CTREEPTR np, char *path)
362 if ((np->flag & F_UID) == 0)
363 np->uid = stb.st_uid;
364 if ((np->flag & F_GID) == 0)
365 np->gid = stb.st_gid;
366 if (np->uid == stb.st_uid && np->gid == stb.st_gid)
368 loudonly_message("chown %s %d %d", path, np->uid, np->gid);
369 if (!opt_lazy && chown(path, np->uid, np->gid) < 0)
370 message("chown %s; %m", path);
374 dochtim(CTREEPTR np, char *path)
376 struct timeval tm[2];
378 if (np->mtime == stb.st_mtime
379 || (!opt_reboot && (np->updtspec & U_REBOOT)))
381 tm[0].tv_sec = tm[1].tv_sec = np->mtime;
382 tm[0].tv_usec = tm[1].tv_usec = 0;
386 date = ctime((time_t *) & np->mtime);
388 loudonly_message("utimes %s [%s]", path, date);
390 if (!opt_lazy && utimes(path, tm) < 0)
391 message("utimes %s; %m", path);
395 FixLostFoundDir(char *path)
396 { /*FixLostFoundDir */
397 if (stb.st_size >= 3584)
399 return mklostfound(path);
400 } /*FixLostFoundDir */
403 FixDir(CTREEPTR np, char *path)
406 register struct dirent *de;
409 verbose_message("cleandir %s", path);
410 if ((dp = opendir(path)) == 0) {
411 message("opendir %s; %m", path);
414 endp = path + strlen(path);
416 while ((de = readdir(dp)) != 0) {
417 if (de->d_name[0] == '.') {
418 if (de->d_name[1] == 0)
420 if (de->d_name[1] == '.' && de->d_name[2] == 0)
423 if (LocateChildNode(np, de->d_name, C_LOCATE) != 0)
425 (void)strcpy(endp, de->d_name);
434 FixReg(CTREEPTR np, char *path)
436 char new[MAXPATHLEN], old[MAXPATHLEN], temp[MAXPATHLEN];
438 if (!opt_reboot && (np->updtspec & U_REBOOT)) {
440 ("%s is a 'Q' file and -rebootfiles is set; not updated!", path);
443 (void)sprintf(new, "%s.new", path);
444 if (np->updtspec & U_ABSPATH)
445 (void)sprintf(temp, "%s", np->proto.info.path);
447 (void)sprintf(temp, "%s%s", np->proto.info.path, path);
450 if (np->updtspec & U_RENAMEOLD) {
451 (void)sprintf(old, "%s.old", path);
457 if (np->updtspec & U_REBOOT)
458 status = status_reboot;