Exemple #1
0
const char *S_pathname_impl(const char *inpath, char *buffer) {
  if (*inpath != '~') { return inpath; }
  else {
#define setp(c) if (p > buffer + PATH_MAX) return NULL; else *p++ = (c)
    static char path[PATH_MAX];
    char *p;
    const char *ip, *dir;

    if (buffer == NULL) buffer = path;

    ip = inpath + 1;
    if (*ip == 0 || DIRMARKERP(*ip)) {
      if (!(dir = S_homedir())) return NULL;
    } else {
#ifdef WIN32
      return inpath;
#else
      struct passwd *pwent;
      p = buffer;
      while (*ip != 0 && !DIRMARKERP(*ip)) setp(*ip++);
      setp(0);
      if (!(pwent = getpwnam(buffer)) || !(dir = pwent->pw_dir))
        return NULL;
#endif /* WIN32 */
    }

    p = buffer;
    while (*dir != 0) setp(*dir++);
    while (*ip != 0) setp(*ip++);
    setp(0);
    return buffer;
#undef setp
  }
}
Exemple #2
0
/* raises an exception if insufficient space cannot be malloc'd.
   otherwise returns a freshly allocated version of inpath with ~ (home directory)
   prefix expanded, if possible */
char *S_malloc_pathname(const char *inpath) {
    char *outpath;
    const char *ip;

#ifdef WIN32
    if (*inpath == '~' && (*(ip = inpath + 1) == 0 || DIRMARKERP(*ip))) {
        const char *homedrive, *homepath;
        size_t n1, n2, n3;

        if ((homedrive = getenv("HOMEDRIVE")) != NULL && (homepath = getenv("HOMEPATH")) != NULL) {
            n1 = strlen(homedrive);
            n2 = strlen(homepath);
            n3 = strlen(ip) + 1;
            if ((outpath = malloc(n1 + n2 + n3)) == NULL) S_error("expand_pathname", "malloc failed");
            memcpy(outpath, homedrive, n1);
            memcpy(outpath + n1, homepath, n2);
            memcpy(outpath + n1 + n2, ip, n3);
            return outpath;
        }
    }
#else /* WIN32 */
    if (*inpath == '~') {
        const char *dir;
        size_t n1, n2;
        struct passwd *pwent;
        if (*(ip = inpath + 1) == 0 || DIRMARKERP(*ip)) {
            if ((dir = getenv("HOME")) == NULL)
                if ((pwent = getpwuid(getuid())) != NULL)
                    dir = pwent->pw_dir;
        } else {
            char *userbuf;
            const char *user_start = ip;
            do {
                ip += 1;
            }
            while (*ip != 0 && !DIRMARKERP(*ip));
            if ((userbuf = malloc(ip - user_start + 1)) == NULL) S_error("expand_pathname", "malloc failed");
            memcpy(userbuf, user_start, ip - user_start);
            userbuf[ip - user_start] = 0;
            dir = (pwent = getpwnam(userbuf)) != NULL ? pwent->pw_dir : NULL;
            free(userbuf);
        }
        if (dir != NULL) {
            n1 = strlen(dir);
            n2 = strlen(ip) + 1;
            if ((outpath = malloc(n1 + n2)) == NULL) S_error("expand_pathname", "malloc failed");
            memcpy(outpath, dir, n1);
            memcpy(outpath + n1, ip, n2);
            return outpath;
        }
    }
#endif /* WIN32 */

    /* if no ~ or tilde dir can't be found, copy inpath */
    {
        size_t n = strlen(inpath) + 1;
        outpath = (char *)malloc(n);
        memcpy(outpath, inpath, n);
        return outpath;
    }
}