Changeset c0c48d14


Ignore:
Timestamp:
Jul 9, 2011, 4:01:01 PM (13 years ago)
Author:
David Benjamin <davidben@mit.edu>
Branches:
master, release-1.10, release-1.8, release-1.9
Children:
bf5e6a2
Parents:
7feba19
git-author:
David Benjamin <davidben@mit.edu> (06/25/11 06:25:02)
git-committer:
David Benjamin <davidben@mit.edu> (07/09/11 16:01:01)
Message:
Reimplement owl_util_makepath

The new algorithm is cleaner and much more reasonable. foo/~/bar should
not expand the ~. Also don't expand '~user /bar' as '/home/user /bar'.
Also leave non-existant users unexpanded.

It still has some finicky bits of string manipulations, but what can you
do. A unit test is coming in the next commit.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • util.c

    rb8a3e00 rc0c48d14  
    3737CALLER_OWN char *owl_util_makepath(const char *in)
    3838{
    39   int i, j, x;
    40   char *out, user[MAXPATHLEN];
    41   struct passwd *pw;
    42 
    43   out=g_new(char, MAXPATHLEN+1);
    44   out[0]='\0';
    45   j=strlen(in);
    46   x=0;
    47   for (i=0; i<j; i++) {
    48     if (in[i]=='~') {
    49       if ( (i==(j-1)) ||          /* last character */
    50            (in[i+1]=='/') ) {     /* ~/ */
    51         /* use my homedir */
    52         pw=getpwuid(getuid());
    53         if (!pw) {
    54           out[x]=in[i];
    55         } else {
    56           out[x]='\0';
    57           strcat(out, pw->pw_dir);
    58           x+=strlen(pw->pw_dir);
    59         }
    60       } else {
    61         /* another user homedir */
    62         int a, b;
    63         b=0;
    64         for (a=i+1; i<j; a++) {
    65           if (in[a]==' ' || in[a]=='/') {
    66             break;
    67           } else {
    68             user[b]=in[a];
    69             i++;
    70             b++;
    71           }
    72         }
    73         user[b]='\0';
    74         pw=getpwnam(user);
    75         if (!pw) {
    76           out[x]=in[i];
    77         } else {
    78           out[x]='\0';
    79           strcat(out, pw->pw_dir);
    80           x+=strlen(pw->pw_dir);
    81         }
    82       }
    83     } else if (in[i]=='/') {
    84       /* check for a double / */
    85       if (i<(j-1) && (in[i+1]=='/')) {
    86         /* do nothing */
    87       } else {
    88         out[x]=in[i];
    89         x++;
    90       }
     39  char *out;
     40  int i, j;
     41  if (in[0] == '~') {
     42    /* Attempt tilde-expansion of the first component. Get the
     43       tilde-prefix, which goes up to the next slash. */
     44    struct passwd *pw;
     45    const char *end = strchr(in + 1, '/');
     46    if (end == NULL)
     47      end = in + strlen(in);
     48
     49    if (end == in + 1) {
     50      /* My home directory. */
     51      pw = getpwuid(getuid());
    9152    } else {
    92       out[x]=in[i];
    93       x++;
    94     }
    95   }
    96   out[x]='\0';
    97   return(out);
     53      /* Someone else's home directory. */
     54      char *user = g_strndup(in + 1, end - (in + 1));
     55      pw = getpwnam(user);
     56      g_free(user);
     57    }
     58
     59    /* Patch together a new path. Replace the ~ and tilde-prefix with
     60       the homedir. */
     61    if (pw) {
     62      out = g_strconcat(pw->pw_dir, end, NULL);
     63    } else {
     64      out = g_strdup(in);
     65    }
     66  } else {
     67      out = g_strdup(in);
     68  }
     69
     70  /* And a quick pass to remove duplicate slashes. */
     71  for (i = j = 0; out[i] != '\0'; i++) {
     72    if (out[i] != '/' || i == 0 || out[i-1] != '/')
     73      out[j++] = out[i];
     74  }
     75  out[j] = '\0';
     76  return out;
    9877}
    9978
Note: See TracChangeset for help on using the changeset viewer.