int DoRecursiveEditFiles(char *name,int level,struct Edit *ptr,struct stat *sb) { DIR *dirh; struct dirent *dirp; char pcwd[CF_BUFSIZE]; struct stat statbuf; int goback; if (level == -1) { return false; } Debug("RecursiveEditFiles(%s)\n",name); if (!DirPush(name,sb)) { return false; } if ((dirh = opendir(".")) == NULL) { return true; } for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) { if (!SensibleFile(dirp->d_name,name,NULL)) { continue; } if (IgnoreFile(name,dirp->d_name,ptr->ignores)) { continue; } strcpy(pcwd,name); /* Assemble pathname */ AddSlash(pcwd); if (BufferOverflow(pcwd,dirp->d_name)) { return true; } strcat(pcwd,dirp->d_name); if (!FileObjectFilter(pcwd,&statbuf,ptr->filters,editfiles)) { Verbose("Skipping filtered file %s\n",pcwd); continue; } if (TRAVLINKS) { if (lstat(dirp->d_name,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"Can't stat %s\n",pcwd); CfLog(cferror,OUTPUT,"stat"); continue; } if (S_ISLNK(statbuf.st_mode) && (statbuf.st_mode != getuid())) { snprintf(OUTPUT,CF_BUFSIZE,"File %s is an untrusted link. cfagent will not follow it with a destructive operation (tidy)",pcwd); continue; } if (stat(dirp->d_name,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"RecursiveCheck was working on %s when this happened:\n",pcwd); CfLog(cferror,OUTPUT,"stat"); continue; } } else { if (lstat(dirp->d_name,&statbuf) == -1) { snprintf(OUTPUT,CF_BUFSIZE*2,"RecursiveCheck was working in %s when this happened:\n",pcwd); CfLog(cferror,OUTPUT,"lstat"); continue; } } if (S_ISDIR(statbuf.st_mode)) { if (IsMountedFileSystem(&statbuf,pcwd,level)) { continue; } else { if ((ptr->recurse > 1) || (ptr->recurse == CF_INF_RECURSE)) { goback = DoRecursiveEditFiles(pcwd,level-1,ptr,&statbuf); DirPop(goback,name,sb); } else { WrapDoEditFile(ptr,pcwd); } } } else { WrapDoEditFile(ptr,pcwd); } } closedir(dirh); return true; }
int RecursiveLink(struct Link *lp,char *from,char *to,int maxrecurse) { struct stat statbuf; DIR *dirh; struct dirent *dirp; char newfrom[CF_BUFSIZE]; char newto[CF_BUFSIZE]; void *bug_check; int (*linkfiles)(char *from, char *to, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short int nofile, struct Link *ptr); /* reached depth limit */ if (maxrecurse == 0) { Debug2("MAXRECURSE ran out, quitting at level %s with " "endlist = %d\n", to, lp->next); return false; } if (IgnoreFile(to,"",lp->ignores)) { Verbose("%s: Ignoring directory %s\n",g_vprefix,from); return false; } /* Check for root dir */ if (strlen(to) == 0) { to = "/"; } bug_check = lp->next; if ((dirh = opendir(to)) == NULL) { snprintf(g_output,CF_BUFSIZE*2,"Can't open directory [%s]\n",to); CfLog(cferror,g_output,"opendir"); return false; } if (lp->next != bug_check) { printf("%s: solaris BSD compat bug: opendir wrecked " "the heap memory!!", g_vprefix); printf("%s: in copy to %s, using workaround...\n",g_vprefix,from); lp->next = bug_check; } for (dirp = readdir(dirh); dirp != NULL; dirp = readdir(dirh)) { if (!SensibleFile(dirp->d_name,to,NULL)) { continue; } if (IgnoreFile(to,dirp->d_name,lp->ignores)) { continue; } /* Assemble pathname */ strcpy(newfrom,from); AddSlash(newfrom); strcpy(newto,to); AddSlash(newto); if (BufferOverflow(newfrom,dirp->d_name)) { closedir(dirh); return true; } strcat(newfrom,dirp->d_name); if (BufferOverflow(newto,dirp->d_name)) { closedir(dirh); return true; } strcat(newto,dirp->d_name); if (g_travlinks) { if (stat(newto,&statbuf) == -1) { snprintf(g_output,CF_BUFSIZE*2,"Can't stat %s\n",newto); CfLog(cfverbose,g_output,""); continue; } } else { if (lstat(newto,&statbuf) == -1) { snprintf(g_output,CF_BUFSIZE*2,"Can't stat %s\n",newto); CfLog(cfverbose,g_output,""); memset(g_vbuff,0,CF_BUFSIZE); if (readlink(newto,g_vbuff,CF_BUFSIZE-1) != -1) { Verbose("File is link to -> %s\n",g_vbuff); } continue; } } if (!FileObjectFilter(newto,&statbuf,lp->filters,links)) { Debug("Skipping filtered file %s\n",newto); continue; } if (S_ISDIR(statbuf.st_mode)) { RecursiveLink(lp,newfrom,newto,maxrecurse-1); } else { switch (lp->type) { case 's': linkfiles = LinkFiles; break; case 'r': linkfiles = RelativeLink; break; case 'a': linkfiles = AbsoluteLink; break; case 'h': linkfiles = HardLinkFiles; break; default: printf("cfagent: internal error, link type was [%c]\n",lp->type); continue; } (*linkfiles)(newfrom,newto,lp->inclusions,lp->exclusions, lp->copy,lp->nofile,lp); } } closedir(dirh); return true; }