char* realpath(const char* file, char* dest) { int fd=open(".",O_RDONLY); /* save directory */ char* res=myrealpath(file,dest,31); fchdir(fd); close(fd); return res; }
char * canonicalize_path(const char *path) { char *canonical; char *p; if (path == NULL) return NULL; canonical = malloc(PATH_MAX+2); if (!canonical) return NULL; if (!myrealpath(path, canonical, PATH_MAX+1)) { free(canonical); return strdup(path); } p = strrchr(canonical, '/'); if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { p = canonicalize_dm_name(p+1); if (p) { free(canonical); return p; } } return canonical; }
char * canonicalize_path(const char *path) { char canonical[PATH_MAX+2]; char *p; if (path == NULL) return NULL; if (!myrealpath(path, canonical, PATH_MAX+1)) { char *res = strdup(path); if (res) { p = strrchr(res, '/'); /* delete trailing slash */ if (p && p > res && *(p + 1) == '\0') *p = '\0'; } return res; } p = strrchr(canonical, '/'); if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { p = canonicalize_dm_name(p+1); if (p) return p; } return strdup(canonical); }
void set_cmdfile_history_file(int linenr, char *cmd, char *par) { if (par[0] == 0x00) { cmdfile_h.history_file = NULL; cmdfile_h.history_size = 0; } else { cmdfile_h.history_file = myrealpath(par); } }
void set_searchhistory_file(int linenr, char *cmd, char *par) { if (par[0] == 0x00) { search_h.history_file = NULL; search_h.history_size = 0; } else { search_h.history_file = myrealpath(par); } }
int nilfs_cleaner_reload(struct nilfs_cleaner *cleaner, const char *conffile) { struct nilfs_cleaner_request_with_path req; struct nilfs_cleaner_response res; size_t pathlen, reqsz; int bytes, ret = -1; if (cleaner->sendq < 0 || cleaner->recvq < 0) { errno = EBADF; goto out; } if (nilfs_cleaner_clear_queueu(cleaner) < 0) goto out; if (conffile) { if (myrealpath(conffile, req.pathname, NILFS_CLEANER_MSG_MAX_PATH) == NULL) goto out; pathlen = strlen(req.pathname); req.hdr.argsize = pathlen + 1; reqsz = sizeof(req.hdr) + pathlen + 1; } else { req.hdr.argsize = 0; reqsz = sizeof(req.hdr); } req.hdr.cmd = NILFS_CLEANER_CMD_RELOAD; uuid_copy(req.hdr.client_uuid, cleaner->client_uuid); ret = mq_send(cleaner->sendq, (char *)&req, reqsz, NILFS_CLEANER_PRIO_NORMAL); if (ret < 0) goto out; bytes = mq_receive(cleaner->recvq, (char *)&res, sizeof(res), NULL); if (bytes < sizeof(res)) { if (bytes >= 0) errno = EIO; ret = -1; goto out; } if (res.result == NILFS_CLEANER_RSP_NACK) { ret = -1; errno = res.err; } out: return ret; }
static int is_in_proc_swaps(const char *fname) { int i; char canonical[PATH_MAX + 2]; if (!myrealpath(fname, canonical, PATH_MAX + 1)) { fprintf(stderr, _("%s: cannot canonicalize %s: %s\n"), progname, fname, strerror(errno)); strncpy(canonical, fname, PATH_MAX + 1); *(canonical + (PATH_MAX + 1)) = '\0'; } for (i = 0; i < numSwaps; i++) if (swapFiles[i] && !strcmp(canonical, swapFiles[i])) return 1; return 0; }
char *canonicalize_path(const char *path) { char canonical[PATH_MAX+2]; char *p; if (path == NULL) return NULL; if (!myrealpath(path, canonical, PATH_MAX+1)) return strdup(path); p = strrchr(canonical, '/'); if (p && strncmp(p, "/dm-", 4) == 0 && isdigit(*(p + 4))) { p = canonicalize_dm_name(p+1); if (p) return p; } return strdup(canonical); }
/* * "Resolve" a pathname. * * Makes sure that 'path' falls within the 'dir' after application of * realpath to resolve "..", symlinks, etc. If 'create' is set, it will * create missing intermediate directories. In detail: * * The path (and dir) must be absolute, or it is an error. * If 'create' is zero, then all components of the path must exist * or it is an error. * If 'create' is non-zero, then missing components except the last * will be created. * If 'dir' is non-null, the existing part of the path must resolve * within this directory or it is an error. * If 'dir' is null, then the path is resolved as far as it exists * ('create' is ignored and assumed to be zero). * * Returns NULL on an error, a malloc'ed pointer to a canonicalized * path otherwise. */ char * resolvepath(char *path, char *dir, int create) { char rpath[PATH_MAX], *next, *ep, *pathcopy; struct stat sb; int pathlen = strlen(path); int dirlen = 0; int rpathlen; mode_t omask, cmask; char *npath; if (debug > 1) info("resolvepath '%s' in dir '%s'", path, dir); /* validate path */ if (path == NULL) { if (debug > 1) info(" null path"); return NULL; } if (path[0] != '/') { if (debug > 1) info(" path is not absolute"); return NULL; } if (pathlen >= sizeof rpath) { if (debug > 1) info(" path is too long"); return NULL; } /* validate dir */ if (dir) { dirlen = strlen(dir); if (dir[0] != '/') { if (debug > 1) info(" path and dir (%s) must be absolute", dir); return NULL; } /* XXX make dir=='/' work */ if (dirlen == 1) dirlen = 0; } else { create = 0; } /* * If the full path resolves, make sure it falls in dir (if given) * and is a regular file. */ if (myrealpath(path, rpath) != NULL) { if (dir && !INDIR(dir, dirlen, rpath)) { if (debug > 1) info(" resolved path (%s) not in dir (%s)", rpath, dir); return NULL; } if (stat(rpath, &sb) < 0 || !S_ISREG(sb.st_mode)) { if (debug > 1) info(" not a regular file"); return NULL; } return strdup(rpath); } if (debug > 1) { int oerrno = errno; info(" partially resolved to '%s' (errno %d)", rpath, errno); errno = oerrno; } /* * If create is not set or we failed for any reason other than * a non-existent component, we return an error. */ if (!create || errno != ENOENT) { if (debug > 1) info(" realpath failed at %s with %d", rpath, errno); return NULL; } /* * Need to create intermediate directories. * * First, check that what does exist of the path falls within * the directory given. */ assert(dir != NULL); if (!INDIR(dir, dirlen, rpath)) { if (debug > 1) info(" resolved path (%s) not in dir (%s)", rpath, dir); return NULL; } /* * Establish permission (mode) for new directories. * Start with permission of 'dir'; this will get updated with * every component that resolves, so that new directories will * get created with the permission of the most recent ancestor. */ if (stat(dir, &sb) < 0) { if (debug > 1) info(" stat failed on dir (%s)?!", dir); return NULL; } cmask = (sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IRWXU; omask = umask(0); if (debug > 1) info(" umask=0 (was 0%o), initial cmask=0%o", omask, cmask); /* * Find the first component of the original path that does not * exist (i.e., what part of the original path maps to what realpath * returned) and create everything from there on. * * Note that if what realpath returned is a prefix of the original * path then nothing was translated and we are already at the first * component that needs creation. So we find the appropriate location * in the original string and go from there. */ npath = NULL; if ((pathcopy = strdup(path)) == NULL) goto done; rpathlen = strlen(rpath); assert(rpathlen <= pathlen); if (rpathlen > 1 && strncmp(pathcopy, rpath, rpathlen) == 0 && (pathcopy[rpathlen] == '\0' || pathcopy[rpathlen] == '/')) { /* same string, start at last slash in path */ if (pathcopy[rpathlen] == '\0') { next = rindex(pathcopy, '/'); assert(next != NULL); } /* rpath is a prefix, start at last slash in that prefix */ else { next = rindex(rpath, '/'); assert(next != NULL); next = &pathcopy[next-rpath]; } } /* rpath is not a prefix, must scan entire path */ else { next = pathcopy; } assert(next >= pathcopy && next < &pathcopy[pathlen]); assert(*next == '/'); next++; if (debug > 1) info(" pathscan: path='%s', rpath='%s', start at '%s'", pathcopy, rpath, next); while ((ep = index(next, '/')) != NULL) { *ep = '\0'; if (debug > 1) info(" testing: %s", pathcopy); /* * We use realpath here instead of just stat to make * sure someone isn't actively tweaking the filesystem * and messing with our head. * * If realpath fails, it should fail with ENOENT and * the realpath-ified part should fall in our directory. * Otherwise, someone really is playing games. */ if (myrealpath(pathcopy, rpath) == NULL) { if (errno != ENOENT || (dir && !INDIR(dir, dirlen, rpath))) { if (debug > 1) info(" resolves bad (%s)\n", rpath); goto done; } /* * We have hit a missing component. * Create the component and carry on. */ if (mkdir(rpath, cmask) < 0) { if (debug > 1) info(" create failed (%s)\n", rpath); goto done; } if (debug > 1) info(" created (%s)", rpath); } else { if (debug > 1) info(" exists (%s)", rpath); /* * Update the creation permission; see comment above. */ if (stat(rpath, &sb) < 0) { if (debug > 1) info(" stat failed (%s)?!", rpath); goto done; } cmask = (sb.st_mode & (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IRWXU; } *ep = '/'; next = ep+1; } /* * We are down to the final component of the original path. * It should either exist and be a regular file or not * exist at all. */ if (myrealpath(pathcopy, rpath) == NULL && (errno != ENOENT || !INDIR(dir, dirlen, rpath))) { if (debug > 1) info(" final resolved path (%s) bad (%d)", rpath, errno); goto done; } /* * We are in our happy place. rpath is the canonicalized path. */ npath = strdup(rpath); if (debug > 1) info("resolvepath: '%s' resolved to '%s'", path, npath); done: umask(omask); if (pathcopy) free(pathcopy); return npath; }
int main (int argc, char ** argv) { char * result; int fd, i, errors = 0; char buf[PATH_MAX]; getcwd (cwd, sizeof(buf)); cwd_len = strlen (cwd); /* this segfaults with dietlibc man page documents: EINVAL Either path or resolved_path is NULL. (In libc5 this would just cause a segfault.) errno = 0; if (myrealpath (NULL, buf) != NULL || errno != EINVAL) { printf ("%s: expected return value NULL and errno set to EINVAL" " for myrealpath(NULL,...)\n", argv[0]); ++errors; } */ /* according to glibc, this test is invalid errno = 0; if (myrealpath ("/", NULL) != NULL || errno != EINVAL) { printf ("%s: expected return value NULL and errno set to EINVAL" " for myrealpath(...,NULL)\n", argv[0]); ++errors; } */ errno = 0; if (myrealpath ("", buf) != NULL || errno != ENOENT) { printf ("%s: expected return value NULL and set errno to ENOENT" " for myrealpath(\"\",...)\n", argv[0]); ++errors; } for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i) symlink (symlinks[i].value, symlinks[i].name); fd = open("doesExist", O_CREAT | O_EXCL, 0777); for (i = 0; i < (int) (sizeof (tests) / sizeof (tests[0])); ++i) { buf[0] = '\0'; result = myrealpath (tests[i].in, buf); if (!check_path (result, tests[i].out)) { printf ("%s: flunked test %d (expected `%s', got `%s')\n", argv[0], i, tests[i].out ? tests[i].out : "NULL", result ? result : "NULL"); ++errors; continue; } if (!check_path (buf, tests[i].out ? tests[i].out : tests[i].resolved)) { printf ("%s: flunked test %d (expected resolved `%s', got `%s')\n", argv[0], i, tests[i].out ? tests[i].out : tests[i].resolved, buf); ++errors; continue; } if (!tests[i].out && errno != tests[i].error) { printf ("%s: flunked test %d (expected errno %d, got %d)\n", argv[0], i, tests[i].error, errno); ++errors; continue; } } getcwd (buf, sizeof(buf)); if (strcmp (buf, cwd)) { printf ("%s: current working directory changed from %s to %s\n", argv[0], cwd, buf); ++errors; } if (fd >= 0) unlink("doesExist"); for (i = 0; i < (int) (sizeof (symlinks) / sizeof (symlinks[0])); ++i) unlink (symlinks[i].name); if (errors != 0) { printf ("%d errors.\n", errors); return EXIT_FAILURE; } puts ("No errors."); return EXIT_SUCCESS; }
static int nilfs_cleaner_find_fs(struct nilfs_cleaner *cleaner, const char *device, const char *mntdir) { struct mntent *mntent, mntbuf; char buf[LINE_MAX]; char canonical[PATH_MAX + 2]; char *cdev = NULL, *cdir = NULL; char *mdir, *mdev; char *last_match_dev = NULL, *last_match_dir = NULL; pid_t last_match_pid = 0; FILE *fp = NULL; int ret = -1, nfound = 0; if (device && myrealpath(device, canonical, sizeof(canonical))) { cdev = strdup(canonical); if (!cdev) goto error; cleaner->device = cdev; } if (mntdir && myrealpath(mntdir, canonical, sizeof(canonical))) { cdir = strdup(canonical); if (!cdir) goto error; cleaner->mountdir = cdir; } fp = fopen(MTAB, "r"); if (fp == NULL) { nilfs_cleaner_logger(LOG_ERR, _("Error: cannot open " MTAB ".")); goto abort; } while ((mntent = getmntent_r(fp, &mntbuf, buf, sizeof(buf))) != NULL) { if (strcmp(mntent->mnt_type, MNTTYPE_NILFS) != 0) continue; if (cleaner->mountdir != NULL) { mdir = mntent->mnt_dir; if (myrealpath(mdir, canonical, sizeof(canonical))) mdir = canonical; if (strcmp(mdir, cleaner->mountdir) != 0) continue; } if (cleaner->device != NULL) { mdev = mntent->mnt_fsname; if (myrealpath(mdev, canonical, sizeof(canonical))) mdev = canonical; if (strcmp(mdev, cleaner->device) != 0) continue; } if (hasmntopt(mntent, MNTOPT_RW)) { /* we found a candidate */ nfound++; if (cleaner->device == NULL) { mdev = mntent->mnt_fsname; if (myrealpath(mdev, canonical, sizeof(canonical))) { mdev = canonical; } if (last_match_dev) free(last_match_dev); last_match_dev = strdup(mdev); if (!last_match_dev) goto error; } if (cleaner->mountdir == NULL) { mdir = mntent->mnt_dir; if (myrealpath(mdir, canonical, sizeof(canonical))) { mdir = canonical; } if (last_match_dir) free(last_match_dir); last_match_dir = strdup(mdir); if (!last_match_dir) goto error; } last_match_pid = 0; ret = nilfs_find_gcpid_opt(mntent->mnt_opts, &last_match_pid); if (ret < 0) goto error; } } if (nfound == 0) { nilfs_cleaner_logger(LOG_ERR, _("Error: no valid nilfs mountpoint " "found.")); goto abort; } if (last_match_dir) cleaner->mountdir = last_match_dir; if (last_match_dev) cleaner->device = last_match_dev; if (last_match_pid) cleaner->cleanerd_pid = last_match_pid; endmntent(fp); return 0; error: nilfs_cleaner_logger(LOG_ERR, _("Error: failed to find fs: %s."), strerror(errno)); abort: free(last_match_dir); /* free(NULL) is just ignored */ free(last_match_dev); if (fp) endmntent(fp); return -1; }