int faccessat(int fd, const char* path, int accessMode, int flag) { if (flag != AT_EACCESS && flag != 0) { // invalid flag errno = EINVAL; return -1; } if (fd == AT_FDCWD || (path != NULL && path[0] == '/')) { // call access() ignoring fd return (flag & AT_EACCESS) != 0 ? eaccess(path, accessMode) : access(path, accessMode); } if (fd < 0) { // Invalid file descriptor errno = EBADF; return -1; } char fullPath[MAXPATHLEN]; if (get_path(fd, path, fullPath) < 0) return -1; return (flag & AT_EACCESS) != 0 ? eaccess(fullPath, accessMode) : access(fullPath, accessMode); }
int pkgdb_dump(struct pkgdb *db, const char *dest) { sqlite3 *backup; int ret; if (eaccess(dest, W_OK)) { if (errno != ENOENT) { pkg_emit_error("eaccess(%s) -- %s", dest, strerror(errno)); return (EPKG_FATAL); } /* Could we create the Sqlite DB file? */ if (eaccess(dirname(dest), W_OK)) { pkg_emit_error("eaccess(%s) -- %s", dirname(dest), strerror(errno)); return (EPKG_FATAL); } } ret = sqlite3_open(dest, &backup); if (ret != SQLITE_OK) { ERROR_SQLITE(backup); sqlite3_close(backup); return (EPKG_FATAL); } ret = copy_database(db->sqlite, backup, dest); sqlite3_close(backup); return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL); }
int pkgdb_dump(struct pkgdb *db, const char *dest) { sqlite3 *backup; int ret; if (eaccess(dest, W_OK)) { if (errno != ENOENT) { pkg_fatal_errno("Unable to access '%s'", dest); } /* Could we create the Sqlite DB file? */ if (eaccess(bsd_dirname(dest), W_OK)) { pkg_fatal_errno("Unable to access '%s'", bsd_dirname(dest)); } } ret = sqlite3_open(dest, &backup); if (ret != SQLITE_OK) { ERROR_SQLITE(backup, "sqlite3_open"); sqlite3_close(backup); return (EPKG_FATAL); } pkg_emit_backup(); ret = copy_database(db->sqlite, backup); sqlite3_close(backup); return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL); }
static int mkmount(register Cs_t* state, int mode, int uid, int gid, char* endserv, char* endhost, char* endtype) { *(state->control - 1) = 0; if (eaccess(state->mount, R_OK|W_OK|X_OK)) { if (errno != ENOENT) goto bad; if (!endserv && !(endserv = strrchr(state->mount, '/'))) goto bad; *endserv = 0; if (eaccess(state->mount, X_OK)) { if (!endhost && !(endhost = strrchr(state->mount, '/'))) goto bad; *endhost = 0; if (eaccess(state->mount, X_OK)) { if (!endtype && !(endtype = strrchr(state->mount, '/'))) goto bad; *endtype = 0; if (eaccess(state->mount, X_OK) && (mkdir(state->mount, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(state->mount, S_IRWXU|S_IRWXG|S_IRWXO))) goto bad; *endtype = '/'; if (mkdir(state->mount, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(state->mount, S_IRWXU|S_IRWXG|S_IRWXO)) goto bad; } *endhost = '/'; if (mkdir(state->mount, S_IRWXU|S_IRWXG|S_IRWXO) || chmod(state->mount, S_IRWXU|S_IRWXG|S_IRWXO)) goto bad; } *endserv = '/'; if (mkdir(state->mount, mode)) goto bad; if (mode != (S_IRWXU|S_IRWXG|S_IRWXO) && (uid >= 0 || gid >= 0 && (mode |= S_ISGID)) && (chown(state->mount, uid, gid) || chmod(state->mount, mode))) { rmdir(state->mount); goto bad; } } *(state->control - 1) = '/'; return 0; bad: if (endtype && !*endtype) *endtype = '/'; if (endhost && !*endhost) *endhost = '/'; if (endserv && !*endserv) *endserv = '/'; *(state->control - 1) = '/'; messagef((state->id, NiL, -1, "mkmount: %s: cannot access physical mount directory", state->mount)); return -1; }
/* * Get human-readable description of the mime-type * If locale is NULL, current locale will be used. * The returned string should be freed when no longer used. */ char* mime_type_get_desc( const char* type, const char* locale ) { char* desc; const gchar* const * dir; char file_path[ 256 ]; int acc; /* //sfm 0.7.7+ FIXED * FIXME: According to specs on freedesktop.org, user_data_dir has * higher priority than system_data_dirs, but in most cases, there was * no file, or very few files in user_data_dir, so checking it first will * result in many unnecessary open() system calls, yealding bad performance. * Since the spec really sucks, we don't follow it here. */ /* FIXME: This path shouldn't be hard-coded. */ g_snprintf( file_path, 256, "%s/mime/%s.xml", g_get_user_data_dir(), type ); #if defined(HAVE_EUIDACCESS) acc = euidaccess( file_path, F_OK ); #elif defined(HAVE_EACCESS) acc = eaccess( file_path, F_OK ); #else acc = 0; #endif if ( acc != -1 ) { desc = _mime_type_get_desc( file_path, locale ); if ( desc ) return desc; } // look in system dirs dir = g_get_system_data_dirs(); for( ; *dir; ++dir ) { /* FIXME: This path shouldn't be hard-coded. */ g_snprintf( file_path, 256, "%s/mime/%s.xml", *dir, type ); #if defined(HAVE_EUIDACCESS) acc = euidaccess( file_path, F_OK ); #elif defined(HAVE_EACCESS) acc = eaccess( file_path, F_OK ); #else acc = 0; #endif if ( acc != -1 ) { desc = _mime_type_get_desc( file_path, locale ); if( G_LIKELY(desc) ) return desc; } } return NULL; }
static_fn char *get_pathtemp_dir() { char *tmpdir = getenv("TMPDIR"); if (tmpdir && eaccess(tmpdir, W_OK | X_OK) == 0) return tmpdir; #ifdef P_tmpdir if (eaccess(P_tmpdir, W_OK | X_OK) == 0) return P_tmpdir; #endif if (eaccess(TMP1, W_OK | X_OK) == 0) return TMP1; if (eaccess(TMP2, W_OK | X_OK) == 0) return TMP2; return NULL; }
static int filstat(char *nm, enum token mode) { struct stat s; if (mode == FILSYM ? lstat(nm, &s) : stat(nm, &s)) return 0; switch (mode) { case FILRD: return (eaccess(nm, R_OK) == 0); case FILWR: return (eaccess(nm, W_OK) == 0); case FILEX: /* XXX work around eaccess(2) false positives for superuser */ if (eaccess(nm, X_OK) != 0) return 0; if (S_ISDIR(s.st_mode) || geteuid() != 0) return 1; return (s.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) != 0; case FILEXIST: return (eaccess(nm, F_OK) == 0); case FILREG: return S_ISREG(s.st_mode); case FILDIR: return S_ISDIR(s.st_mode); case FILCDEV: return S_ISCHR(s.st_mode); case FILBDEV: return S_ISBLK(s.st_mode); case FILFIFO: return S_ISFIFO(s.st_mode); case FILSOCK: return S_ISSOCK(s.st_mode); case FILSYM: return S_ISLNK(s.st_mode); case FILSUID: return (s.st_mode & S_ISUID) != 0; case FILSGID: return (s.st_mode & S_ISGID) != 0; case FILSTCK: return (s.st_mode & S_ISVTX) != 0; case FILGZ: return s.st_size > (off_t)0; case FILUID: return s.st_uid == geteuid(); case FILGID: return s.st_gid == getegid(); default: return 1; } }
int pkgdb_load(struct pkgdb *db, const char *src) { sqlite3 *restore; int ret; if (eaccess(src, R_OK)) { pkg_emit_error("eaccess(%s) -- %s", src, strerror(errno)); return (EPKG_FATAL); } ret = sqlite3_open(src, &restore); if (ret != SQLITE_OK) { ERROR_SQLITE(restore); sqlite3_close(restore); return (EPKG_FATAL); } ret = copy_database(restore, db->sqlite, src); sqlite3_close(restore); return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL); }
/*+++++++++++++++++++++++++ get_afd_config_value() ++++++++++++++++++++++*/ static void get_afd_config_value(void) { char *buffer, config_file[MAX_PATH_LENGTH]; (void)snprintf(config_file, MAX_PATH_LENGTH, "%s%s%s", p_work_dir, ETC_DIR, AFD_CONFIG_FILE); if ((eaccess(config_file, F_OK) == 0) && (read_file_no_cr(config_file, &buffer, YES, __FILE__, __LINE__) != INCORRECT)) { char value[MAX_INT_LENGTH]; if (get_definition(buffer, ARCHIVE_WATCH_PRIORITY_DEF, value, MAX_INT_LENGTH) != NULL) { if (setpriority(PRIO_PROCESS, 0, atoi(value)) == -1) { system_log(WARN_SIGN, __FILE__, __LINE__, "Failed to set priority to %d : %s", atoi(value), strerror(errno)); } } free(buffer); } return; }
/** * \param[in] user user name * \return true = success, false = failure */ bool list_table(const char* user) { std::string tp(InCronTab::GetUserTablePath(user)); if (eaccess(tp.c_str(), R_OK) != 0) { if (errno == ENOENT) { fprintf(stderr, "no table for %s\n", user); return true; } else { fprintf(stderr, "cannot read table for %s: %s\n", user, strerror(errno)); return false; } } FILE* f = fopen(tp.c_str(), "r"); if (f == NULL) return false; char s[1024]; while (fgets(s, 1024, f) != NULL) { fputs(s, stdout); } fclose(f); return true; }
bool can_write_to_all_files(std::string path) { vector<string> files; vector<string> dirs; FileUtils::ListDir(path, files); vector<string>::iterator iter = files.begin(); while (iter != files.end()) { string file = *iter++; string fullPath = FileUtils::Join(path.c_str(), file.c_str(), NULL); if (FileUtils::IsDirectory(fullPath)) dirs.push_back(fullPath); if (eaccess(fullPath.c_str(), W_OK)) return false; } iter = dirs.begin(); while (iter != dirs.end()) { string fullPath = *iter++; if (!can_write_to_all_files(fullPath.c_str())) return false; } return true; }
/** * Append one directory to the context's include path. */ XKB_EXPORT int xkb_context_include_path_append(struct xkb_context *ctx, const char *path) { struct stat stat_buf; int err; char *tmp; tmp = strdup(path); if (!tmp) goto err; err = stat(path, &stat_buf); if (err != 0) goto err; if (!S_ISDIR(stat_buf.st_mode)) goto err; #if defined(HAVE_EACCESS) if (eaccess(path, R_OK | X_OK) != 0) goto err; #elif defined(HAVE_EUIDACCESS) if (euidaccess(path, R_OK | X_OK) != 0) goto err; #endif darray_append(ctx->includes, tmp); return 1; err: darray_append(ctx->failed_includes, tmp); return 0; }
int cosystem(const char* cmd) { Coshell_t* co; Cojob_t* cj; int status; if (!cmd) return !eaccess(pathshell(), X_OK); if (!(co = coopen(NiL, CO_ANY, NiL))) return -1; if (cj = coexec(co, cmd, CO_SILENT, NiL, NiL, NiL)) cj = cowait(co, cj, -1); if (!cj) return -1; /* * synthesize wait() status from shell status * lack of synthesis is the standard's proprietary sellout */ status = cj->status; if (EXITED_TERM(status)) status &= ((1<<(EXIT_BITS-1))-1); else status = (status & ((1<<EXIT_BITS)-1)) << EXIT_BITS; return status; }
static VALUE find_file(VALUE fname) { VALUE res; int nOK = 0; //RAWLOG_INFO1("find_file: fname: %s", RSTRING_PTR(fname)); if ( strncmp(RSTRING_PTR(fname), rho_native_rhopath(), strlen(rho_native_rhopath())) == 0 ){ res = rb_str_dup(fname); rb_str_cat(res,".iseq",5); //RAWLOG_INFO1("find_file: res: %s", RSTRING_PTR(res)); }else{ int i = 0; VALUE load_path = GET_VM()->load_path; //VALUE dir; VALUE fname1 = checkRhoBundleInPath(fname); //RAWLOG_INFO1("find_file: fname after checkRhoBundleInPath: %s", RSTRING_PTR(fname)); //TODO: support document relative require in case of multiple apps if (RARRAY_LEN(load_path)>1){ for( ; i < RARRAY_LEN(load_path); i++ ){ VALUE dir = RARRAY_PTR(load_path)[i]; //RAWLOG_INFO1("find_file: check dir %s", RSTRING_PTR(dir)); res = rb_str_dup(dir); rb_str_cat(res,"/",1); rb_str_cat(res,RSTRING_PTR(fname1),RSTRING_LEN(fname1)); rb_str_cat(res,".iseq",5); //RAWLOG_INFO1("find_file: check file: %s", RSTRING_PTR(res)); if( eaccess(RSTRING_PTR(res), R_OK) == 0 ){ nOK = 1; break; } } if ( !nOK ) return 0; } /*else { dir = RARRAY_PTR(load_path)[RARRAY_LEN(load_path)-1]; res = rb_str_dup(dir); rb_str_cat(res,"/",1); rb_str_cat(res,RSTRING_PTR(fname),RSTRING_LEN(fname)); rb_str_cat(res,".iseq",5); if ( g_curAppPath != 0 && eaccess(RSTRING_PTR(res), R_OK) != 0 ){ res = rb_str_new2(g_curAppPath); rb_str_cat(res,"/",1); rb_str_cat(res,RSTRING_PTR(fname),RSTRING_LEN(fname)); rb_str_cat(res,".iseq",5); } } */ } //RAWLOG_INFO1("find_file: RhoPreparePath: %s", RSTRING_PTR(res)); res = RhoPreparePath(res); if ( !nOK ) nOK = 1;//eaccess(RSTRING_PTR(res), R_OK) == 0 ? 1 : 0; return nOK ? res : 0; }
int pkgdb_load(struct pkgdb *db, const char *src) { sqlite3 *restore; int ret; if (eaccess(src, R_OK)) { pkg_fatal_errno("Unable to access '%s'", src); } ret = sqlite3_open(src, &restore); if (ret != SQLITE_OK) { ERROR_SQLITE(restore, "sqlite3_open"); sqlite3_close(restore); return (EPKG_FATAL); } pkg_emit_restore(); ret = copy_database(restore, db->sqlite); sqlite3_close(restore); return (ret == SQLITE_OK? EPKG_OK : EPKG_FATAL); }
int system(const char *cmd) { int pid, status; struct sigaction sa, savintr, savequit; char *argv[4]; spawn_inheritance_type inherit; char path[PATH_MAX + 1]; char buff[PATH_MAX + 1]; char *sh; if(confstr(_CS_PATH, path, sizeof path) == 0 || !(sh = pathfind_r(path, "sh", "x", buff, sizeof buff))) { sh = _PATH_BSHELL; // If cmd is NULL we do an existance check on the shell. if(!cmd) { return eaccess(sh, X_OK) != -1; } } // If cmd is NULL return existance of shell. if(!cmd) { return 1; } // Setup arguments for spawn. argv[0] = "sh"; argv[1] = "-c"; argv[2] = (char *)cmd; argv[3] = NULL; // Ignore SIGINT,SIGQUIT and mask SIGCHLD on parent. sa.sa_handler = SIG_IGN; sigemptyset(&sa.sa_mask); sa.sa_flags = 0; sigaction(SIGINT, &sa, &savintr); sigaction(SIGQUIT, &sa, &savequit); sigaddset(&sa.sa_mask, SIGCHLD); sigprocmask(SIG_BLOCK, &sa.sa_mask, &inherit.sigmask); // Inialize inheritance structure for spawn. sigfillset(&inherit.sigdefault); inherit.flags = SPAWN_SETSIGDEF | SPAWN_SETSIGMASK; // POSIX 1003.1d implementation. if((pid = spawn(sh, 0, NULL, &inherit, argv, environ)) == -1) { status = -1; } else while(waitpid(pid, &status, 0) == -1) { if(errno != EINTR) { status = -1; break; } } // restore SIGINT, SIGQUIT, SIGCHLD. sigaction(SIGINT, &savintr, NULL); sigaction(SIGQUIT, &savequit, NULL); sigprocmask(SIG_SETMASK, &inherit.sigmask, NULL); return(status); }
// // Return pointer to the full path name of the shell // // SHELL is read from the environment and must start with / // // if set-uid or set-gid then the executable and its containing // directory must not be owned by the real user/group // // root/administrator has its own test // // "/bin/sh" is returned by default. // // NOTE: csh is rejected because the bsh/csh differentiation is // not done for `csh script arg ...' // char *pathshell(void) { char *shell; int real_uid; int effective_uid; int real_gid; int effective_gid; struct stat statbuf; static char *val = NULL; shell = getenv("SHELL"); if (shell && *shell == '/' && strmatch(shell, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))?(.exe)")) { real_uid = getuid(); if (!real_uid || !eaccess("/bin", W_OK)) { if (stat(shell, &statbuf)) goto defshell; if (real_uid != statbuf.st_uid && !strmatch(shell, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh?(.exe)")) { goto defshell; } } else { effective_uid = geteuid(); real_gid = getgid(); effective_gid = getegid(); // Check if we are executing in setuid or setgid mode if (real_uid != effective_uid || real_gid != effective_gid) { char *s; char dir[PATH_MAX]; s = shell; // Check the uid and gid on shell and it's parent directory for (;;) { if (stat(s, &statbuf)) goto defshell; if (real_uid != effective_uid && statbuf.st_uid == real_uid) goto defshell; if (real_gid != effective_gid && statbuf.st_gid == real_gid) goto defshell; if (s != shell) break; if (strlen(s) >= sizeof(dir)) goto defshell; strcpy(dir, s); s = strrchr(dir, '/'); if (!s) break; *s = 0; s = dir; } } } return shell; } defshell: shell = val; if (!shell) shell = "/bin/sh"; return shell; }
bool is_executable(const CharArray &path) throw() { try { auto file = native_null_path(path); return eaccess(file.c_str_ref(), X_OK) == 0; } catch(empty_path_error) { return false; } }
extern int system(const char* cmd) { char* sh[4]; if (!cmd) return !eaccess(pathshell(), X_OK); sh[0] = "sh"; sh[1] = "-c"; sh[2] = (char*)cmd; sh[3] = 0; return procrun(NiL, sh, 0); }
static int settime(void* context, const char* cmd, Time_t now, int adjust, int network) { char* s; char** argv; char* args[5]; char buf[1024]; if (!adjust && !network) return tmxsettime(now); argv = args; s = "/usr/bin/date"; if (!streq(cmd, s) && (!eaccess(s, X_OK) || !eaccess(s+=4, X_OK))) { *argv++ = s; if (streq(astconf("UNIVERSE", NiL, NiL), "att")) { tmxfmt(buf, sizeof(buf), "%m%d%H" "%M%Y.%S", now); if (adjust) *argv++ = "-a"; } else { tmxfmt(buf, sizeof(buf), "%Y%m%d%H" "%M.%S", now); if (network) *argv++ = "-n"; if (tm_info.flags & TM_UTC) *argv++ = "-u"; } *argv++ = buf; *argv = 0; if (!sh_run(context, argv - args, args)) return 0; } return -1; }
static void _make_tmpdir(slurmd_job_t *job) { char *tmpdir; if (!(tmpdir = getenvp(job->env, "TMPDIR"))) setenvf(&job->env, "TMPDIR", "/tmp"); /* task may want it set */ else if (mkdir(tmpdir, 0700) < 0) { struct stat st; int mkdir_errno = errno; if (stat(tmpdir, &st)) { /* does the file exist ? */ /* show why we were not able to create it */ error("Unable to create TMPDIR [%s]: %s", tmpdir, strerror(mkdir_errno)); } else if (!S_ISDIR(st.st_mode)) { /* is it a directory? */ error("TMPDIR [%s] is not a directory", tmpdir); } /* Eaccess wasn't introduced until glibc 2.4 but euidaccess * has been around for a while. So to make sure we * still work with older systems we include this check. */ #if defined(__FreeBSD__) #define __GLIBC__ (1) #define __GLIBC_PREREQ(a,b) (1) #endif #if defined __GLIBC__ && __GLIBC_PREREQ(2, 4) else if (eaccess(tmpdir, X_OK|W_OK)) /* check permissions */ #else else if (euidaccess(tmpdir, X_OK|W_OK)) #endif error("TMPDIR [%s] is not writeable", tmpdir); else return; error("Setting TMPDIR to /tmp"); setenvf(&job->env, "TMPDIR", "/tmp"); } return; }
char* gethidden( const char* path ) //MOD added { // Read .hidden into string char* hidden_path = g_build_filename( path, ".hidden", NULL ); // test access first because open() on missing file may cause // long delay on nfs int acc; #if defined(HAVE_EUIDACCESS) acc = euidaccess( hidden_path, R_OK ); #elif defined(HAVE_EACCESS) acc = eaccess( hidden_path, R_OK ); #else acc = 0; #endif if ( acc != 0 ) { g_free( hidden_path ); return NULL; } int fd = open( hidden_path, O_RDONLY ); g_free( hidden_path ); if ( fd != -1 ) { struct stat s; // skip stat64 if ( G_LIKELY( fstat( fd, &s ) != -1 ) ) { char* buf = g_malloc( s.st_size + 1 ); if( (s.st_size = read( fd, buf, s.st_size )) != -1 ) { buf[ s.st_size ] = 0; close( fd ); return buf; } else g_free( buf ); } close( fd ); } return NULL; }
int faccessat(int fd, const char *path, int mode, int flag) { int ret; char saved_cwd[MAXPATHLEN]; const char *cwd; if ((cwd = getcwd(saved_cwd, sizeof(saved_cwd))) == NULL) return (-1); if ((ret = file_chdir_lock(fd) != 0)) return ret; if (flag & AT_EACCESS) { ret = eaccess(path, mode); } else { ret = access(path, mode); } file_chdir_unlock(fd); return ret; }
int main(int argc, char *argv[]) { if (argc != 3) { helpAndLeave(argv[0], EXIT_FAILURE); } char *accessString, *filename, *p; int mode; accessString = argv[1]; filename = argv[2]; mode = 0; for (p = accessString; *p != '\0'; ++p) { switch (*p) { case 'f': mode |= F_OK; break; case 'r': mode |= R_OK; break; case 'w': mode |= W_OK; break; case 'x': mode |= X_OK; break; default: fprintf(stderr, "%s: unknown flag %c\n", argv[0], *p); exit(EXIT_FAILURE); } } errno = 0; if (eaccess(filename, mode) == 0) { printf("%s: permission granted\n", filename); } else { if (errno != 0) { pexit("eaccess"); } printf("%s: permission denied\n", filename); } exit(EXIT_SUCCESS); }
static VALUE check_app_file_exist(VALUE dir, VALUE fname1, const char* szPlatform) { VALUE res = rb_str_dup(dir); //RAWLOG_INFO1("find_file: check dir %s", RSTRING_PTR(dir)); #ifdef __SYMBIAN32__ if(*RSTRING_PTR(res) == '/') res = rb_str_substr(res,1,RSTRING_LEN(res) - 1); #endif rb_str_cat(res,"/",1); rb_str_cat(res,RSTRING_PTR(fname1),RSTRING_LEN(fname1)); if (szPlatform) { rb_str_cat(res,".",1); rb_str_cat(res,szPlatform,strlen(szPlatform)); } rb_str_cat(res,RHO_RB_EXT,strlen(RHO_RB_EXT)); //RAWLOG_INFO1("find_file: check file: %s", RSTRING_PTR(res)); return eaccess(RSTRING_PTR(res), R_OK) == 0 ? res : 0; }
static int mvdir(const char* from, const char* to) { char* argv[4]; int oerrno; static const char mvdir[] = "/usr/lib/mv_dir"; oerrno = errno; if (!eaccess(mvdir, X_OK)) { argv[0] = mvdir; argv[1] = from; argv[2] = to; argv[3] = 0; if (!procrun(argv[0], argv, 0)) { errno = oerrno; return 0; } } errno = EPERM; return -1; }
/*########################### error_action() ############################*/ void error_action(char *alias_name, char *action, int type) { if (alias_name[0] == '\0') { system_log(DEBUG_SIGN, __FILE__, __LINE__, _("No alias_name set. [action=`%s' type=%d]"), action, type); } else { int default_action, event_action, event_class, status; char fullname[MAX_PATH_LENGTH], *p_alias_name; if (type == HOST_ERROR_ACTION) { p_alias_name = fullname + snprintf(fullname, MAX_PATH_LENGTH, "%s%s%s%s%s/", p_work_dir, ETC_DIR, ACTION_DIR, ACTION_TARGET_DIR, ACTION_ERROR_DIR); event_class = EC_HOST; if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'a') && (action[3] == 'r') && (action[4] == 't') && (action[5] == '\0')) { event_action = EA_EXEC_ERROR_ACTION_START; } else if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'o') && (action[3] == 'p') && (action[4] == '\0')) { event_action = EA_EXEC_ERROR_ACTION_STOP; } else { event_action = 0; } } else if (type == DIR_ERROR_ACTION) { p_alias_name = fullname + snprintf(fullname, MAX_PATH_LENGTH, "%s%s%s%s%s/", p_work_dir, ETC_DIR, ACTION_DIR, ACTION_SOURCE_DIR, ACTION_ERROR_DIR); event_class = EC_DIR; if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'a') && (action[3] == 'r') && (action[4] == 't') && (action[5] == '\0')) { event_action = EA_EXEC_ERROR_ACTION_START; } else if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'o') && (action[3] == 'p') && (action[4] == '\0')) { event_action = EA_EXEC_ERROR_ACTION_STOP; } else { event_action = 0; } } else if (type == HOST_WARN_ACTION) { p_alias_name = fullname + snprintf(fullname, MAX_PATH_LENGTH, "%s%s%s%s%s/", p_work_dir, ETC_DIR, ACTION_DIR, ACTION_TARGET_DIR, ACTION_WARN_DIR); event_class = EC_HOST; if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'a') && (action[3] == 'r') && (action[4] == 't') && (action[5] == '\0')) { event_action = EA_EXEC_WARN_ACTION_START; } else if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'o') && (action[3] == 'p') && (action[4] == '\0')) { event_action = EA_EXEC_WARN_ACTION_STOP; } else { event_action = 0; } } else if (type == DIR_INFO_ACTION) { p_alias_name = fullname + snprintf(fullname, MAX_PATH_LENGTH, "%s%s%s%s%s/", p_work_dir, ETC_DIR, ACTION_DIR, ACTION_SOURCE_DIR, ACTION_INFO_DIR); event_class = EC_DIR; if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'a') && (action[3] == 'r') && (action[4] == 't') && (action[5] == '\0')) { event_action = EA_EXEC_INFO_ACTION_START; } else if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'o') && (action[3] == 'p') && (action[4] == '\0')) { event_action = EA_EXEC_INFO_ACTION_STOP; } else { event_action = 0; } } else if (type == DIR_WARN_ACTION) { p_alias_name = fullname + snprintf(fullname, MAX_PATH_LENGTH, "%s%s%s%s%s/", p_work_dir, ETC_DIR, ACTION_DIR, ACTION_SOURCE_DIR, ACTION_WARN_DIR); event_class = EC_DIR; if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'a') && (action[3] == 'r') && (action[4] == 't') && (action[5] == '\0')) { event_action = EA_EXEC_WARN_ACTION_START; } else if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'o') && (action[3] == 'p') && (action[4] == '\0')) { event_action = EA_EXEC_WARN_ACTION_STOP; } else { event_action = 0; } } else if (type == HOST_SUCCESS_ACTION) { p_alias_name = fullname + snprintf(fullname, MAX_PATH_LENGTH, "%s%s%s%s%s/", p_work_dir, ETC_DIR, ACTION_DIR, ACTION_TARGET_DIR, ACTION_SUCCESS_DIR); event_class = EC_HOST; if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'a') && (action[3] == 'r') && (action[4] == 't') && (action[5] == '\0')) { event_action = EA_EXEC_SUCCESS_ACTION_START; } else if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'o') && (action[3] == 'p') && (action[4] == '\0')) { event_action = EA_EXEC_SUCCESS_ACTION_STOP; } else { event_action = 0; } } else if (type == DIR_SUCCESS_ACTION) { p_alias_name = fullname + snprintf(fullname, MAX_PATH_LENGTH, "%s%s%s%s%s/", p_work_dir, ETC_DIR, ACTION_DIR, ACTION_SOURCE_DIR, ACTION_SUCCESS_DIR); event_class = EC_DIR; if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'a') && (action[3] == 'r') && (action[4] == 't') && (action[5] == '\0')) { event_action = EA_EXEC_SUCCESS_ACTION_START; } else if ((action[0] == 's') && (action[1] == 't') && (action[2] == 'o') && (action[3] == 'p') && (action[4] == '\0')) { event_action = EA_EXEC_SUCCESS_ACTION_STOP; } else { event_action = 0; } } else { system_log(WARN_SIGN, __FILE__, __LINE__, _("Unknown action type %d, please contact maintainer %s."), type, AFD_MAINTAINER); return; } (void)strcpy(p_alias_name, alias_name); if ((status = eaccess(fullname, (R_OK | X_OK))) != 0) { default_action = YES; (void)strcpy(p_alias_name, DEFAULT_ACTION_FILE); status = eaccess(fullname, (R_OK | X_OK)); } else { default_action = NO; } if (status == 0) { pid_t pid; char reason_str[38 + MAX_INT_LENGTH + 1]; if ((pid = fork()) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Could not create a new process : %s"), strerror(errno)); return; } else if (pid == 0) /* Child process. */ { int ret; if ((pid = fork()) < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Could not create a new process : %s"), strerror(errno)); _exit(INCORRECT); } else if (pid > 0) { _exit(SUCCESS); } if (default_action == NO) { ret = execlp(fullname, fullname, action, (char *)0); } else { ret = execlp(fullname, fullname, action, alias_name, (char *)0); } if (ret < 0) { system_log(WARN_SIGN, __FILE__, __LINE__, _("Failed to start process %s (%d) : %s [type=%d alias_name=`%s' action=`%s']"), fullname, ret, strerror(errno), type, alias_name, action); _exit(INCORRECT); } else { system_log(DEBUG_SIGN, NULL, 0, _("Error action: %s %s"), fullname, action); } _exit(SUCCESS); } if (waitpid(pid, &status, 0) != pid) { system_log(WARN_SIGN, __FILE__, __LINE__, #if SIZEOF_PID_T == 4 "Failed to wait for pid %ld : %s", #else "Failed to wait for pid %lld : %s", #endif (pri_pid_t)pid, strerror(errno)); } if (WIFEXITED(status)) { (void)snprintf(reason_str, 38 + MAX_INT_LENGTH + 1, "%d", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { (void)snprintf(reason_str, 38 + MAX_INT_LENGTH + 1, _("Abnormal termination caused by signal %d"), WTERMSIG(status)); } else { (void)my_strncpy(reason_str, _("Unable to determine return code"), 38 + MAX_INT_LENGTH + 1); } if (event_action) { event_log(0L, event_class, ET_AUTO, event_action, "%s%c%s", alias_name, SEPARATOR_CHAR, reason_str); } } } return; }
static char * dln_find_1(const char *fname, const char *path, char *fbuf, int size, int exe_flag /* non 0 if looking for executable. */) { register const char *dp; register const char *ep; register char *bp; struct stat st; #define RETURN_IF(expr) if (expr) return (char *)fname; RETURN_IF(!fname); RETURN_IF(fname[0] == '/'); RETURN_IF(strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0); RETURN_IF(exe_flag && strchr(fname, '/')); #undef RETURN_IF for (dp = path;; dp = ++ep) { register int l; int i; int fspace; /* extract a component */ ep = strchr(dp, PATH_SEP[0]); if (ep == NULL) { ep = dp+strlen(dp); } /* find the length of that component */ l = ep - dp; bp = fbuf; fspace = size - 2; if (l > 0) { /* ** If the length of the component is zero length, ** start from the current directory. If the ** component begins with "~", start from the ** user's $HOME environment variable. Otherwise ** take the path literally. */ if (*dp == '~' && (l == 1 || dp[1] == '/')) { char *home; home = getenv("HOME"); if (home != NULL) { i = strlen(home); if ((fspace -= i) < 0) { goto toolong; } memcpy(bp, home, i); bp += i; } dp++; l--; } if (l > 0) { if ((fspace -= l) < 0) { goto toolong; } memcpy(bp, dp, l); bp += l; } /* add a "/" between directory and filename */ if (ep[-1] != '/') { *bp++ = '/'; } } /* now append the file name */ i = strlen(fname); if ((fspace -= i) < 0) { toolong: fprintf(stderr, "openpath: pathname too long (ignored)\n"); *bp = '\0'; fprintf(stderr, "\tDirectory \"%s\"\n", fbuf); fprintf(stderr, "\tFile \"%s\"\n", fname); goto next; } memcpy(bp, fname, i + 1); if (stat(fbuf, &st) == 0) { if (exe_flag == 0) { return fbuf; } /* looking for executable */ if (!S_ISDIR(st.st_mode) && eaccess(fbuf, X_OK) == 0) { return fbuf; } } next: /* if not, and no other alternatives, life is bleak */ if (*ep == '\0') { return NULL; } /* otherwise try the next component in the search path */ } }
const char * find_in_path (const char *progname) { #if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__ /* Win32, Cygwin, OS/2, DOS */ /* The searching rules with .COM, .EXE, .BAT, .CMD etc. suffixes are too complicated. Leave it to the OS. */ return progname; #else /* Unix */ char *path; char *path_rest; char *cp; if (strchr (progname, '/') != NULL) /* If progname contains a slash, it is either absolute or relative to the current directory. PATH is not used. */ return progname; path = getenv ("PATH"); if (path == NULL || *path == '\0') /* If PATH is not set, the default search path is implementation dependent. */ return progname; /* Make a copy, to prepare for destructive modifications. */ path = xstrdup (path); for (path_rest = path; ; path_rest = cp + 1) { const char *dir; bool last; char *progpathname; /* Extract next directory in PATH. */ dir = path_rest; for (cp = path_rest; *cp != '\0' && *cp != ':'; cp++) ; last = (*cp == '\0'); *cp = '\0'; /* Empty PATH components designate the current directory. */ if (dir == cp) dir = "."; /* Concatenate dir and progname. */ progpathname = concatenated_pathname (dir, progname, NULL); /* On systems which have the eaccess() system call, let's use it. On other systems, let's hope that this program is not installed setuid or setgid, so that it is ok to call access() despite its design flaw. */ if (eaccess (progpathname, X_OK) == 0) { /* Found! */ if (strcmp (progpathname, progname) == 0) { free (progpathname); /* Add the "./" prefix for real, that concatenated_pathname() optimized away. This avoids a second PATH search when the caller uses execlp/execvp. */ progpathname = xmalloc (2 + strlen (progname) + 1); progpathname[0] = '.'; progpathname[1] = '/'; memcpy (progpathname + 2, progname, strlen (progname) + 1); } free (path); return progpathname; } free (progpathname); if (last) break; } /* Not found in PATH. An error will be signalled at the first call. */ free (path); return progname; #endif }
static int rm(State_t* state, register FTSENT* ent) { register char* path; register int n; int v; struct stat st; if (ent->fts_info == FTS_NS || ent->fts_info == FTS_ERR || ent->fts_info == FTS_SLNONE) { if (!state->force) error(2, "%s: not found", ent->fts_path); } else if (state->fs3d && iview(ent->fts_statp)) fts_set(NiL, ent, FTS_SKIP); else switch (ent->fts_info) { case FTS_DNR: case FTS_DNX: if (state->unconditional) { if (!beenhere(ent)) break; if (!chmod(ent->fts_name, (ent->fts_statp->st_mode & S_IPERM)|S_IRWXU)) { fts_set(NiL, ent, FTS_AGAIN); break; } error_info.errors++; } else if (!state->force) error(2, "%s: cannot %s directory", ent->fts_path, (ent->fts_info & FTS_NR) ? "read" : "search"); else error_info.errors++; fts_set(NiL, ent, FTS_SKIP); nonempty(ent); break; case FTS_D: case FTS_DC: path = ent->fts_name; if (path[0] == '.' && (!path[1] || path[1] == '.' && !path[2]) && (ent->fts_level > 0 || path[1])) { fts_set(NiL, ent, FTS_SKIP); if (!state->force) error(2, "%s: cannot remove", ent->fts_path); else error_info.errors++; break; } if (!state->recursive) { fts_set(NiL, ent, FTS_SKIP); error(2, "%s: directory", ent->fts_path); break; } if (!beenhere(ent)) { if (state->unconditional && (ent->fts_statp->st_mode & S_IRWXU) != S_IRWXU) chmod(path, (ent->fts_statp->st_mode & S_IPERM)|S_IRWXU); if (ent->fts_level > 0) { char* s; if (ent->fts_accpath == ent->fts_name || !(s = strrchr(ent->fts_accpath, '/'))) v = !stat(".", &st); else { path = ent->fts_accpath; *s = 0; v = !stat(path, &st); *s = '/'; } if (v) v = st.st_nlink <= 2 || st.st_ino == ent->fts_parent->fts_statp->st_ino && st.st_dev == ent->fts_parent->fts_statp->st_dev || strchr(astconf("PATH_ATTRIBUTES", path, NiL), 'l'); } else v = 1; if (v) { if (state->interactive) { if ((v = astquery(-1, "remove directory %s? ", ent->fts_path)) < 0 || sh_checksig(state->context)) return -1; if (v > 0) { fts_set(NiL, ent, FTS_SKIP); nonempty(ent); } } if (ent->fts_info == FTS_D) break; } else { ent->fts_info = FTS_DC; error(1, "%s: hard link to directory", ent->fts_path); } } else if (ent->fts_info == FTS_D) break; /*FALLTHROUGH*/ case FTS_DP: if (isempty(ent) || state->directory) { path = ent->fts_name; if (path[0] != '.' || path[1]) { path = ent->fts_accpath; if (state->verbose) sfputr(sfstdout, ent->fts_path, '\n'); if ((ent->fts_info == FTS_DC || state->directory) ? remove(path) : rmdir(path)) switch (errno) { case ENOENT: break; case EEXIST: #if defined(ENOTEMPTY) && (ENOTEMPTY) != (EEXIST) case ENOTEMPTY: #endif if (ent->fts_info == FTS_DP && !beenhere(ent)) { retry(ent); fts_set(NiL, ent, FTS_AGAIN); break; } /*FALLTHROUGH*/ default: nonempty(ent); if (!state->force) error(ERROR_SYSTEM|2, "%s: directory not removed", ent->fts_path); else error_info.errors++; break; } } else if (!state->force) error(2, "%s: cannot remove", ent->fts_path); else error_info.errors++; } else { nonempty(ent); if (!state->force) error(2, "%s: directory not removed", ent->fts_path); else error_info.errors++; } break; default: path = ent->fts_accpath; if (state->verbose) sfputr(sfstdout, ent->fts_path, '\n'); if (state->interactive) { if ((v = astquery(-1, "remove %s? ", ent->fts_path)) < 0 || sh_checksig(state->context)) return -1; if (v > 0) { nonempty(ent); break; } } else if (!state->force && state->terminal && eaccess(path, W_OK)) { if ((v = astquery(-1, "override protection %s for %s? ", #ifdef ETXTBSY errno == ETXTBSY ? "``running program''" : #endif ent->fts_statp->st_uid != state->uid ? "``not owner''" : fmtmode(ent->fts_statp->st_mode & S_IPERM, 0) + 1, ent->fts_path)) < 0 || sh_checksig(state->context)) return -1; if (v > 0) { nonempty(ent); break; } } #if _lib_fsync if (state->clobber && S_ISREG(ent->fts_statp->st_mode) && ent->fts_statp->st_size > 0) { if ((n = open(path, O_WRONLY)) < 0) error(ERROR_SYSTEM|2, "%s: cannot clear data", ent->fts_path); else { off_t c = ent->fts_statp->st_size; for (;;) { if (write(n, state->buf, sizeof(state->buf)) != sizeof(state->buf)) { error(ERROR_SYSTEM|2, "%s: data clear error", ent->fts_path); break; } if (c <= sizeof(state->buf)) break; c -= sizeof(state->buf); } fsync(n); close(n); } } #endif if (remove(path)) { nonempty(ent); switch (errno) { case ENOENT: break; default: if (!state->force || state->interactive) error(ERROR_SYSTEM|2, "%s: not removed", ent->fts_path); else error_info.errors++; break; } } break; } return 0; }