home *** CD-ROM | disk | FTP | other *** search
/ Big Green CD 8 / BGCD_8_Dev.iso / NEXTSTEP / UNIX / Networking / wu-ftpd-2.4.2b13-MIHS / src / realpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-03-03  |  5.5 KB  |  202 lines

  1. /* Copyright (c) 1993, 1994  Washington University in Saint Louis
  2.  * All rights reserved.
  3.  *
  4.  * Redistribution and use in source and binary forms, with or without
  5.  * modification, are permitted provided that the following conditions are
  6.  * met: 1. Redistributions of source code must retain the above copyright
  7.  * notice, this list of conditions and the following disclaimer. 2.
  8.  * Redistributions in binary form must reproduce the above copyright notice,
  9.  * this list of conditions and the following disclaimer in the documentation
  10.  * and/or other materials provided with the distribution. 3. All advertising
  11.  * materials mentioning features or use of this software must display the
  12.  * following acknowledgement: This product includes software developed by the
  13.  * Washington University in Saint Louis and its contributors. 4. Neither the
  14.  * name of the University nor the names of its contributors may be used to
  15.  * endorse or promote products derived from this software without specific
  16.  * prior written permission.
  17.  *
  18.  * THIS SOFTWARE IS PROVIDED BY WASHINGTON UNIVERSITY AND CONTRIBUTORS
  19.  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20.  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21.  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASHINGTON
  22.  * UNIVERSITY OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
  23.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
  24.  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  26.  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
  28.  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
  29.  * POSSIBILITY OF SUCH DAMAGE.
  30.  */
  31.  
  32. #ifndef lint
  33. static char rcsid[] = "@(#)$Id: realpath.c,v 1.8 1997/01/16 09:54:38 sob Exp $";
  34. #endif
  35.  
  36. #include "config.h"
  37.  
  38. #include <stdio.h>
  39. #include <sys/types.h>
  40. #include <sys/stat.h>
  41. #include <sys/param.h>
  42. #include <string.h>
  43.  
  44. #ifndef HAVE_SYMLINK
  45. #define lstat stat
  46. #endif
  47.  
  48. char *
  49. #ifdef __STDC__
  50. realpath(const char *pathname, char *result)
  51. #else
  52. realpath(pathname,result)
  53. char *pathname;
  54. char *result;
  55. #endif
  56. {
  57.     struct stat sbuf;
  58.     char curpath[MAXPATHLEN],
  59.       workpath[MAXPATHLEN],
  60.       linkpath[MAXPATHLEN],
  61.       namebuf[MAXPATHLEN],
  62.      *where,
  63.      *ptr,
  64.      *last;
  65.     int len;
  66.  
  67.     /* check arguments! */
  68.  
  69.   
  70.     if (result == NULL) /* result must not be null! */
  71.       return(NULL);
  72.  
  73.     if(pathname == NULL){ /* if pathname is null, there is nothing to do */
  74.       *result = '\0'; 
  75.       return(NULL);
  76.     }
  77.  
  78.     strcpy(curpath, pathname);
  79.  
  80.     if (*pathname != '/') {
  81.         uid_t userid;
  82.         
  83. #ifdef HAVE_GETCWD
  84.     if (!getcwd(workpath,MAXPATHLEN)) {
  85. #else
  86.         if (!getwd(workpath)) {
  87. #endif    
  88.         userid = geteuid();
  89.         delay_signaling(); /* we can't allow any signals while euid==0: kinch */
  90.         seteuid(0);
  91. #ifdef HAVE_GETCWD
  92.             if (!getcwd(workpath,MAXPATHLEN)) {
  93. #else
  94.             if (!getwd(workpath)) {
  95. #endif
  96.                 strcpy(result, ".");
  97.             seteuid(userid);
  98.             enable_signaling(); /* we can allow signals once again: kinch */
  99.                 return (NULL);
  100.             }
  101.         seteuid(userid);
  102.         enable_signaling(); /* we can allow signals once again: kinch */
  103.     }
  104.     } else
  105.         *workpath = '\0';
  106.  
  107.     /* curpath is the path we're still resolving      */
  108.     /* linkpath is the path a symbolic link points to */
  109.     /* workpath is the path we've resolved            */
  110.  
  111.   loop:
  112.     where = curpath;
  113.     while (*where != '\0') {
  114.         if (!strcmp(where, ".")) {
  115.             where++;
  116.             continue;
  117.         }
  118.         /* deal with "./" */
  119.         if (!strncmp(where, "./", 2)) {
  120.             where += 2;
  121.             continue;
  122.         }
  123.         /* deal with "../" */
  124.         if (!strncmp(where, "../", 3)) {
  125.             where += 3;
  126.             ptr = last = workpath;
  127.             while (*ptr != '\0') {
  128.                 if (*ptr == '/')
  129.                     last = ptr;
  130.                 ptr++;
  131.             }
  132.             *last = '\0';
  133.             continue;
  134.         }
  135.         ptr = strchr(where, '/');
  136.         if (ptr == (char *)NULL)
  137.             ptr = where + strlen(where) - 1;
  138.         else
  139.             *ptr = '\0';
  140.  
  141.         strcpy(namebuf, workpath);
  142.         for (last = namebuf; *last; last++)
  143.             continue;
  144.         if (*--last != '/')
  145.             strcat(namebuf, "/");
  146.         strcat(namebuf, where);
  147.  
  148.         where = ++ptr;
  149.         if (lstat(namebuf, &sbuf) == -1) {
  150.             strcpy(result, namebuf);
  151.             return (NULL);
  152.         }
  153.         /* was IFLNK */
  154. #ifdef HAVE_SYMLINK
  155.         if ((sbuf.st_mode & S_IFMT) == S_IFLNK) {
  156.             len = readlink(namebuf, linkpath, MAXPATHLEN);
  157.             if (len == 0) {
  158.                 strcpy(result, namebuf);
  159.                 return (NULL);
  160.             }
  161.             *(linkpath + len) = '\0';   /* readlink doesn't null-terminate
  162.                                          * result */
  163.             if (*linkpath == '/')
  164.                 *workpath = '\0';
  165.             if (*where) {
  166.                 strcat(linkpath, "/");
  167.                 strcat(linkpath, where);
  168.             }
  169.             strcpy(curpath, linkpath);
  170.             goto loop;
  171.         }
  172. #endif
  173.         if ((sbuf.st_mode & S_IFDIR) == S_IFDIR) {
  174.             strcpy(workpath, namebuf);
  175.             continue;
  176.         }
  177.         if (*where) {
  178.             strcpy(result, namebuf);
  179.             return (NULL);      /* path/notadir/morepath */
  180.         } else
  181.             strcpy(workpath, namebuf);
  182.     }
  183.     strcpy(result, workpath);
  184.     return (result);
  185. }
  186.  
  187.  
  188.  
  189.  
  190.  
  191.  
  192.  
  193.  
  194.  
  195.  
  196.  
  197.  
  198.  
  199.  
  200.  
  201.  
  202.