home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / octa21fs.zip / octave / kpathsea / tilde.c < prev    next >
C/C++ Source or Header  |  2000-01-15  |  4KB  |  142 lines

  1. /* tilde.c: Expand user's home directories.
  2.  
  3. Copyright (C) 1993, 95, 96, 97 Karl Berry.
  4.  
  5. This library is free software; you can redistribute it and/or
  6. modify it under the terms of the GNU Library General Public
  7. License as published by the Free Software Foundation; either
  8. version 2 of the License, or (at your option) any later version.
  9.  
  10. This library is distributed in the hope that it will be useful,
  11. but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13. Library General Public License for more details.
  14.  
  15. You should have received a copy of the GNU Library General Public
  16. License along with this library; if not, write to the Free Software
  17. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
  18.  
  19. #include <kpathsea/config.h>
  20.  
  21. #include <kpathsea/c-pathch.h>
  22. #include <kpathsea/tilde.h>
  23.  
  24. #ifdef HAVE_PWD_H
  25. #include <pwd.h>
  26. #endif
  27.  
  28.  
  29. /* If NAME has a leading ~ or ~user, Unix-style, expand it to the user's
  30.    home directory, and return a new malloced string.  If no ~, or no
  31.    <pwd.h>, just return NAME.  */
  32.  
  33. string
  34. kpse_tilde_expand P1C(const_string, name)
  35. {
  36.   const_string expansion;
  37.   const_string home;
  38.   
  39.   assert (name);
  40.   
  41.   /* If no leading tilde, do nothing.  */
  42.   if (*name != '~') {
  43.     expansion = name;
  44.   
  45.   /* If a bare tilde, return the home directory or `.'.  (Very unlikely
  46.      that the directory name will do anyone any good, but ...  */
  47.   } else if (name[1] == 0) {
  48.     expansion = xstrdup (getenv ("HOME"));
  49.     if (!expansion) {
  50.       expansion = xstrdup (".");
  51.     }
  52.   
  53.   /* If `~/', remove any trailing / or replace leading // in $HOME.
  54.      Should really check for doubled intermediate slashes, too.  */
  55.   } else if (IS_DIR_SEP (name[1])) {
  56.     unsigned c = 1;
  57.     home = getenv ("HOME");
  58.     if (!home) {
  59.       home = ".";
  60.     }
  61.     if (IS_DIR_SEP (*home) && IS_DIR_SEP (home[1])) {  /* handle leading // */
  62.       home++;
  63.     }
  64.     if (IS_DIR_SEP (home[strlen (home) - 1])) {        /* omit / after ~ */
  65.       c++;
  66.     }
  67.     expansion = concat (home, name + c);
  68.   
  69.   /* If `~user' or `~user/', look up user in the passwd database (but
  70.      OS/2 doesn't have this concept.  */
  71.   } else
  72. #ifdef HAVE_PWD_H
  73.     {
  74.       struct passwd *p;
  75.       string user;
  76.       unsigned c = 2;
  77.       while (!IS_DIR_SEP (name[c]) && name[c] != 0) /* find user name */
  78.         c++;
  79.       
  80.       user = (string) xmalloc (c);
  81.       strncpy (user, name + 1, c - 1);
  82.       user[c - 1] = 0;
  83.       
  84.       /* We only need the cast here for (deficient) systems
  85.          which do not declare `getpwnam' in <pwd.h>.  */
  86.       p = (struct passwd *) getpwnam (user);
  87.       free (user);
  88.  
  89.       /* If no such user, just use `.'.  */
  90.       home = p ? p->pw_dir : ".";
  91.       if (IS_DIR_SEP (*home) && IS_DIR_SEP (home[1])) { /* handle leading // */
  92.         home++;
  93.       }
  94.       if (IS_DIR_SEP (home[strlen (home) - 1]) && name[c] != 0)
  95.         c++; /* If HOME ends in /, omit the / after ~user. */
  96.  
  97.       expansion = name[c] == 0 ? xstrdup (home) : concat (home, name + c);
  98.     }
  99. #else /* not HAVE_PWD_H */
  100.     expansion = name;
  101. #endif /* not HAVE_PWD_H */
  102.  
  103.   /* We may return the same thing as the original, and then we might not
  104.      be returning a malloc-ed string.  Callers beware.  Sorry.  */
  105.   return (string) expansion;
  106. }
  107.  
  108. #ifdef TEST
  109.  
  110. void
  111. test_expand_tilde (const_string filename)
  112. {
  113.   string answer;
  114.   
  115.   printf ("Tilde expansion of `%s':\t", filename ? filename : "(nil)");
  116.   answer = kpse_tilde_expand (filename);
  117.   puts (answer);
  118. }
  119.  
  120. int
  121. main ()
  122. {
  123.   string tilde_path = "tilde";
  124.  
  125.   test_expand_tilde ("");
  126.   test_expand_tilde ("none");
  127.   test_expand_tilde ("~root");
  128.   test_expand_tilde ("~");
  129.   test_expand_tilde ("foo~bar");
  130.   
  131.   return 0;
  132. }
  133.  
  134. #endif /* TEST */
  135.  
  136.  
  137. /*
  138. Local variables:
  139. standalone-compile-command: "gcc -g -I. -I.. -DTEST tilde.c kpathsea.a"
  140. End:
  141. */
  142.