/* 'resolved' argument needs to be at least CF_BUFSIZE long */ static bool ResolveFilename(const char *req_path, char *res_path) { #if !defined _WIN32 if (realpath(req_path, res_path) == NULL) { return false; } #else memset(res_path, 0, CF_BUFSIZE); CompressPath(res_path, req_path); #endif /* Adjust for forward slashes */ MapName(res_path); /* NT has case-insensitive path names */ #ifdef __MINGW32__ int i; for (i = 0; i < strlen(res_path); i++) { res_path[i] = ToLower(res_path[i]); } #endif /* __MINGW32__ */ return true; }
PromiseResult VerifyAbsoluteLink(EvalContext *ctx, char *destination, const char *source, Attributes attr, const Promise *pp) { char absto[CF_BUFSIZE]; char expand[CF_BUFSIZE]; char linkto[CF_BUFSIZE]; if (*source == '.') { strcpy(linkto, destination); ChopLastNode(linkto); AddSlash(linkto); strcat(linkto, source); } else { strcpy(linkto, source); } CompressPath(absto, linkto); expand[0] = '\0'; if (attr.link.when_no_file == cfa_force) { if (!ExpandLinks(expand, absto, 0)) /* begin at level 1 and beam out at 15 */ { Log(LOG_LEVEL_ERR, "Failed to make absolute link in"); PromiseRef(LOG_LEVEL_ERR, pp); return PROMISE_RESULT_FAIL; } else { Log(LOG_LEVEL_DEBUG, "ExpandLinks returned '%s'", expand); } } else { strcpy(expand, absto); } CompressPath(linkto, expand); return VerifyLink(ctx, destination, linkto, attr, pp); }
void KillOldLink(char *name, char *defs) { char linkbuf[CF_BUFSIZE]; char linkpath[CF_BUFSIZE],*sp; struct stat statbuf; Debug("KillOldLink(%s)\n",name); memset(linkbuf,0,CF_BUFSIZE); memset(linkpath,0,CF_BUFSIZE); if (readlink(name,linkbuf,CF_BUFSIZE-1) == -1) { snprintf(g_output,CF_BUFSIZE*2, "(Can't read link %s while checking for deadlinks)\n",name); CfLog(cfverbose,g_output,""); return; } if (linkbuf[0] != '/') { strcpy(linkpath,name); /* Get path to link */ for (sp = linkpath+strlen(linkpath); (*sp != '/') && (sp >= linkpath); sp-- ) { *sp = '\0'; } } strcat(linkpath,linkbuf); CompressPath(g_vbuff,linkpath); /* link points nowhere */ if (stat(g_vbuff,&statbuf) == -1) { if (g_killoldlinks || g_debug || g_d2) { snprintf(g_output, CF_BUFSIZE*2, "%s is a link which points to %s, " "but that file doesn't seem to exist\n", name, g_vbuff); CfLog(cfverbose,g_output,""); } if (g_killoldlinks) { snprintf(g_output,CF_BUFSIZE*2,"Removing dead link %s\n",name); CfLog(cfinform,g_output,""); if (! g_dontdo) { /* May not work on a client-mounted system ! */ unlink(name); AddMultipleClasses(defs); } } } }
int AbsoluteLink(char *from, char *to, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short nofile, struct Link *ptr) { char absto[CF_BUFSIZE]; char expand[CF_BUFSIZE]; Debug2("AbsoluteLink(%s,%s)\n",from,to); if (*to == '.') { strcpy(g_linkto,from); ChopLastNode(g_linkto); AddSlash(g_linkto); strcat(g_linkto,to); } else { strcpy(g_linkto,to); } CompressPath(absto,g_linkto); expand[0] = '\0'; if (!nofile) { /* begin at level 1 and beam out at 15 */ if (!ExpandLinks(expand,absto,0)) { CfLog(cferror,"Failed to make absolute link in\n",""); snprintf(g_output,CF_BUFSIZE*2,"%s -> %s\n",from,to); CfLog(cferror,g_output,""); return false; } else { Debug2("ExpandLinks returned %s\n",expand); } } else { strcpy(expand,absto); } CompressPath(g_linkto,expand); return LinkFiles(from,g_linkto,inclusions,exclusions,copy,nofile,ptr); }
bool KillGhostLink(EvalContext *ctx, const char *name, Attributes attr, const Promise *pp, PromiseResult *result) { char linkbuf[CF_BUFSIZE], tmp[CF_BUFSIZE]; char linkpath[CF_BUFSIZE], *sp; struct stat statbuf; memset(linkbuf, 0, CF_BUFSIZE); memset(linkpath, 0, CF_BUFSIZE); if (readlink(name, linkbuf, CF_BUFSIZE - 1) == -1) { Log(LOG_LEVEL_VERBOSE, "Can't read link '%s' while checking for deadlinks", name); return true; /* ignore */ } if (!IsAbsoluteFileName(linkbuf)) { strcpy(linkpath, name); /* Get path to link */ for (sp = linkpath + strlen(linkpath); (*sp != FILE_SEPARATOR) && (sp >= linkpath); sp--) { *sp = '\0'; } } strcat(linkpath, linkbuf); CompressPath(tmp, sizeof(tmp), linkpath); if (stat(tmp, &statbuf) == -1) /* link points nowhere */ { if ((attr.link.when_no_file == cfa_delete) || (attr.recursion.rmdeadlinks)) { Log(LOG_LEVEL_VERBOSE, "'%s' is a link which points to '%s', but that file doesn't seem to exist", name, linkbuf); if (!DONTDO) { unlink(name); /* May not work on a client-mounted system ! */ cfPS(ctx, LOG_LEVEL_INFO, PROMISE_RESULT_CHANGE, pp, attr, "Removing ghost '%s', reference to something that is not there", name); *result = PromiseResultUpdate(*result, PROMISE_RESULT_CHANGE); return true; } } } return false; }
/* 'resolved' argument needs to be at least CF_BUFSIZE long */ bool ResolveFilename(const char *req_path, char *res_path) { char req_dir[CF_BUFSIZE]; char req_filename[CF_BUFSIZE]; /* * Eliminate symlinks from path, but do not resolve the file itself if it is a * symlink. */ strlcpy(req_dir, req_path, CF_BUFSIZE); ChopLastNode(req_dir); strlcpy(req_filename, ReadLastNode(req_path), CF_BUFSIZE); #if defined HAVE_REALPATH && !defined _WIN32 if (realpath(req_dir, res_path) == NULL) { return false; } #else memset(res_path, 0, CF_BUFSIZE); CompressPath(res_path, req_dir); #endif AddSlash(res_path); strlcat(res_path, req_filename, CF_BUFSIZE); /* Adjust for forward slashes */ MapName(res_path); /* NT has case-insensitive path names */ #ifdef __MINGW32__ int i; for (i = 0; i < strlen(res_path); i++) { res_path[i] = ToLower(res_path[i]); } #endif /* __MINGW32__ */ return true; }
PromiseResult VerifyRelativeLink(EvalContext *ctx, char *destination, const char *source, Attributes attr, const Promise *pp) { char *sp, *commonto, *commonfrom; char buff[CF_BUFSIZE], linkto[CF_BUFSIZE], add[CF_BUFSIZE]; int levels = 0; if (*source == '.') { return VerifyLink(ctx, destination, source, attr, pp); } if (!CompressPath(linkto, source)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, attr, "Failed to link %s to %s\n", destination, source); return PROMISE_RESULT_FAIL; } commonto = linkto; commonfrom = destination; if (strcmp(commonto, commonfrom) == 0) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, attr, "Failed to link %s to %s - can't link file %s to itself\n", destination, source, commonto); return PROMISE_RESULT_FAIL; } while (*commonto == *commonfrom) { commonto++; commonfrom++; } while (!((IsAbsoluteFileName(commonto)) && (IsAbsoluteFileName(commonfrom)))) { commonto--; commonfrom--; } commonto++; for (sp = commonfrom; *sp != '\0'; sp++) { if (IsFileSep(*sp)) { levels++; } } memset(buff, 0, CF_BUFSIZE); strcat(buff, "."); strcat(buff, FILE_SEPARATOR_STR); while (--levels > 0) { snprintf(add, CF_BUFSIZE - 1, "..%c", FILE_SEPARATOR); if (!JoinPath(buff, add)) { return PROMISE_RESULT_FAIL; } } if (!JoinPath(buff, commonto)) { return PROMISE_RESULT_FAIL; } return VerifyLink(ctx, destination, buff, attr, pp); }
bool Path::appendPath( const Path &p ) { mPath = CompressPath(Join(mPath,'/',p.getPath())); mIsDirtyPath = true; return true; }
PromiseResult VerifyRelativeLink(EvalContext *ctx, char *destination, const char *source, Attributes attr, const Promise *pp) { char *sp, *commonto, *commonfrom; char buff[CF_BUFSIZE], linkto[CF_BUFSIZE]; int levels = 0; if (*source == '.') { return VerifyLink(ctx, destination, source, attr, pp); } if (!CompressPath(linkto, sizeof(linkto), source)) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, attr, "Failed to link '%s' to '%s'", destination, source); return PROMISE_RESULT_INTERRUPTED; } commonto = linkto; commonfrom = destination; if (strcmp(commonto, commonfrom) == 0) { cfPS(ctx, LOG_LEVEL_ERR, PROMISE_RESULT_INTERRUPTED, pp, attr, "Failed to link '%s' to '%s', can't link file '%s' to itself", destination, source, commonto); return PROMISE_RESULT_INTERRUPTED; } while (*commonto == *commonfrom) { commonto++; commonfrom++; } while (!((IsAbsoluteFileName(commonto)) && (IsAbsoluteFileName(commonfrom)))) { commonto--; commonfrom--; } commonto++; for (sp = commonfrom; *sp != '\0'; sp++) { if (IsFileSep(*sp)) { levels++; } } memset(buff, 0, CF_BUFSIZE); strcat(buff, "."); strcat(buff, FILE_SEPARATOR_STR); while (--levels > 0) { const char add[] = ".." FILE_SEPARATOR_STR; if (!PathAppend(buff, sizeof(buff), add, FILE_SEPARATOR)) { Log(LOG_LEVEL_ERR, "Internal limit reached in VerifyRelativeLink()," " path too long: '%s' + '%s'", buff, add); return PROMISE_RESULT_FAIL; } } if (!PathAppend(buff, sizeof(buff), commonto, FILE_SEPARATOR)) { Log(LOG_LEVEL_ERR, "Internal limit reached in VerifyRelativeLink() end," " path too long: '%s' + '%s'", buff, commonto); return PROMISE_RESULT_FAIL; } return VerifyLink(ctx, destination, buff, attr, pp); }
int RelativeLink(char *from, char *to, struct Item *inclusions, struct Item *exclusions, struct Item *copy, short nofile, struct Link *ptr) { char *sp, *commonto, *commonfrom; char buff[CF_BUFSIZE],linkto[CF_BUFSIZE]; int levels=0; Debug2("RelativeLink(%s,%s)\n",from,to); if (*to == '.') { return LinkFiles(from,to,inclusions,exclusions,copy,nofile,ptr); } if (!CompressPath(linkto,to)) { snprintf(g_output,CF_BUFSIZE*2,"Failed to link %s to %s\n",from,to); CfLog(cferror,g_output,""); return false; } commonto = linkto; commonfrom = from; if (strcmp(commonto,commonfrom) == 0) { CfLog(cferror,"Can't link file to itself!\n",""); snprintf(g_output,CF_BUFSIZE*2,"(%s -> %s)\n",from,to); CfLog(cferror,g_output,""); return false; } while (*commonto == *commonfrom) { commonto++; commonfrom++; } while (!((*commonto == '/') && (*commonfrom == '/'))) { commonto--; commonfrom--; } commonto++; Debug("Commonto = %s, common from = %s\n",commonto,commonfrom); for (sp = commonfrom; *sp != '\0'; sp++) { if (*sp == '/') { levels++; } } Debug("LEVELS = %d\n",levels); memset(buff,0,CF_BUFSIZE); strcat(buff,"./"); while(--levels > 0) { if (BufferOverflow(buff,"../")) { return false; } strcat(buff,"../"); } if (BufferOverflow(buff,commonto)) { return false; } strcat(buff,commonto); return LinkFiles(from,buff,inclusions,exclusions,copy,nofile,ptr); }