/**************************************************************************** Create a directory given an absolute path, perms based upon another directory path ****************************************************************************/ static int make_bak_dir(char *fname,char *bak_path) { STRUCT_STAT st; STRUCT_STAT *st2; char fullpath[MAXPATHLEN]; extern int orig_umask; char *p; char *q; while(strncmp(bak_path,"./",2)==0) bak_path += 2; if(bak_path[strlen(bak_path)-1]!='/') { snprintf(fullpath,sizeof(fullpath),"%s/",bak_path); } else { snprintf(fullpath,sizeof(fullpath),"%s",bak_path); } p=fullpath; q=&fullpath[strlen(fullpath)]; /* End of bak_path string */ strcat(fullpath,fname); /* Make the directories */ while ((p=strchr(p,'/'))) { *p = 0; if(do_lstat(fullpath,&st)!=0) { do_mkdir(fullpath,0777 & ~orig_umask); if(p>q) { if(do_lstat(q,&st)!=0) { rprintf(FERROR,"make_bak_dir stat %s : %s\n",fullpath,strerror(errno)); } else { st2=&st; set_modtime(fullpath,st2->st_mtime); if(do_lchown(fullpath,st2->st_uid,st2->st_gid)!=0) { rprintf(FERROR,"make_bak_dir chown %s : %s\n",fullpath,strerror(errno)); }; if(do_chmod(fullpath,st2->st_mode)!=0) { rprintf(FERROR,"make_bak_dir failed to set permissions on %s : %s\n",fullpath,strerror(errno)); }; }; } }; *p = '/'; p++; } return 0; }
/** * validateOptions * * - Sanity check the options * - massage the SUBBLOCK options into something * more easily used during the source text processing. * - compile the regular expressions * - make sure we can find all the input files and their mod times * - Set up our entry ordering database (if specified) * - Make sure we have valid strings for SRCFILE and LINENUM * (if we are to use these things). * - Initialize the user name characters array. */ LOCAL void validateOptions(void) { set_define_re(); /* * Prepare each sub-block entry so we can parse easily later. */ if (HAVE_OPT(SUBBLOCK)) { int ct = STACKCT_OPT( SUBBLOCK); tCC** ppz = STACKLST_OPT(SUBBLOCK); /* * FOR each SUBBLOCK argument, * DO condense each name list to be a list of names * separated by a single space and NUL terminated. */ do { *ppz = fixupSubblockString(*ppz); ppz++; } while (--ct > 0); } if (! HAVE_OPT(INPUT)) SET_OPT_INPUT("-"); set_modtime(); /* * IF the output is to have order AND it is to be based on a file, * THEN load the contents of that file. * IF we cannot load the file, * THEN it must be new or empty. Allocate several K to start. */ if ( HAVE_OPT(ORDERING) && (OPT_ARG(ORDERING) != NULL)) { tSCC zIndexPreamble[] = "# -*- buffer-read-only: t -*- vi: set ro:\n" "#\n# DO NOT EDIT THIS FILE - it is auto-edited by getdefs\n"; pzIndexText = loadFile(OPT_ARG(ORDERING)); if (pzIndexText == NULL) { pzIndexText = pzEndIndex = pzIndexEOF = malloc((size_t)0x4000); indexAlloc = 0x4000; pzEndIndex += sprintf(pzEndIndex, "%s", zIndexPreamble); } else { pzEndIndex = pzIndexEOF = pzIndexText + strlen(pzIndexText); indexAlloc = (pzEndIndex - pzIndexText) + 1; } /* * We map the name entries to a connonical form. * By default, everything is mapped to lower case already. * This call will map these three characters to '_'. */ strequate("_-^"); } { char const * pz = OPT_ARG(SRCFILE); if ((pz == NULL) || (*pz == NUL)) OPT_ARG(SRCFILE) = "srcfile"; pz = OPT_ARG(LINENUM); if ((pz == NULL) || (*pz == NUL)) OPT_ARG(LINENUM) = "linenum"; } { tSCC zAgNameChars[] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789" "_-^"; tSCC zUserNameChs[] = ":.$%*!~<>&@"; tCC* p = zAgNameChars; while (*p) zUserNameCh[(unsigned)(*p++)] = 3; p = zUserNameChs; while (*p) zUserNameCh[(unsigned)(*p++)] = 1; } }
int set_perms(char *fname,struct file_struct *file,STRUCT_STAT *st, int report) { int updated = 0; STRUCT_STAT st2; int change_uid, change_gid; extern int am_daemon; if (dry_run) return 0; if (!st) { if (link_stat(fname,&st2) != 0) { rprintf(FERROR,"stat %s : %s\n",fname,strerror(errno)); return 0; } st = &st2; } if (preserve_times && !S_ISLNK(st->st_mode) && st->st_mtime != file->modtime) { /* don't complain about not setting times on directories because some filesystems can't do it */ if (set_modtime(fname,file->modtime) != 0 && !S_ISDIR(st->st_mode)) { rprintf(FERROR,"failed to set times on %s : %s\n", fname,strerror(errno)); return 0; } else { updated = 1; } } change_uid = am_root && preserve_uid && st->st_uid != file->uid; change_gid = !am_daemon && preserve_gid && file->gid != (gid_t) -1 && \ st->st_gid != file->gid; if (change_gid && !am_root) { /* enforce bsd-style group semantics: non-root can only change to groups that the user is a member of */ change_gid = is_in_group(file->gid); } if (change_uid || change_gid) { if (do_lchown(fname, change_uid?file->uid:st->st_uid, change_gid?file->gid:st->st_gid) != 0) { /* shouldn't have attempted to change uid or gid unless have the privilege */ rprintf(FERROR,"chown %s : %s\n", fname,strerror(errno)); return 0; } updated = 1; } #ifdef HAVE_CHMOD if (!S_ISLNK(st->st_mode)) { int file_mode; if (preserve_perms) file_mode = file->mode; else file_mode = file->mode & ACCESSPERMS; if (st->st_mode != file->mode) { updated = 1; if (do_chmod(fname,file_mode) != 0) { rprintf(FERROR,"failed to set permissions on %s : %s\n", fname,strerror(errno)); return 0; } } } #endif if (verbose > 1 && report) { if (updated) rprintf(FINFO,"%s\n",fname); else rprintf(FINFO,"%s is uptodate\n",fname); } return updated; }
static BUFFER * gettagsfile(int n, int *endofpathflagp, int *did_read) { #ifdef MDCHK_MODTIME time_t current; #endif char *tagsfile; BUFFER *tagbp; char tagbufname[NBUFN]; char tagfilename[NFILEN]; *endofpathflagp = FALSE; *did_read = FALSE; (void) lsprintf(tagbufname, TAGFILE_BufName, n + 1); /* is the buffer around? */ if ((tagbp = find_b_name(tagbufname)) == NULL) { char *tagf = global_b_val_ptr(VAL_TAGS); nth_name(tagfilename, tagf, n); if (!doglob(tagfilename) || tagfilename[0] == EOS) { *endofpathflagp = TRUE; return NULL; } /* look up the tags file */ tagsfile = cfg_locate(tagfilename, LOCATE_TAGS); /* if it isn't around, don't sweat it */ if (tagsfile == NULL) { return NULL; } /* find the pointer to that buffer */ if ((tagbp = bfind(tagbufname, BFINVS)) == NULL) { mlforce("[Can't create tags buffer]"); return NULL; } if (readin(tagsfile, FALSE, tagbp, FALSE) != TRUE) { zotbuf(tagbp); return NULL; } *did_read = TRUE; } #ifdef MDCHK_MODTIME /* * Re-read the tags buffer if we are checking modification-times and * find that the tags file's been changed. We check the global mode * value because it's too awkward to set the local mode value for a * scratch buffer. */ if (global_b_val(MDCHK_MODTIME) && get_modtime(tagbp, ¤t) && tagbp->b_modtime != current) { if (!*did_read && readin(tagbp->b_fname, FALSE, tagbp, FALSE) != TRUE) { zotbuf(tagbp); return NULL; } set_modtime(tagbp, tagbp->b_fname); *did_read = TRUE; } #endif b_set_invisible(tagbp); return tagbp; }