home *** CD-ROM | disk | FTP | other *** search
/ PC-Online 1996 May / PCOnline_05_1996.bin / linux / source / n / tcpip / wu-ftpd-.000 / wu-ftpd- / wu-ftpd-2.4 / src / realpath.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-04-01  |  4.8 KB  |  162 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. #include "config.h"
  33.  
  34. #include <stdio.h>
  35. #include <sys/types.h>
  36. #include <sys/stat.h>
  37. #include <sys/param.h>
  38. #include <string.h>
  39.  
  40. #ifndef HAVE_SYMLINK
  41. #define lstat stat
  42. #endif
  43.  
  44. char *
  45. realpath(char *pathname, char *result)
  46. {
  47.     struct stat sbuf;
  48.     char curpath[MAXPATHLEN],
  49.       workpath[MAXPATHLEN],
  50.       linkpath[MAXPATHLEN],
  51.       namebuf[MAXPATHLEN],
  52.      *where,
  53.      *ptr,
  54.      *last;
  55.     int len;
  56.  
  57.     strcpy(curpath, pathname);
  58.  
  59.     if (*pathname != '/') {
  60.         uid_t userid;
  61.         
  62. #ifdef HAVE_GETCWD
  63.     if (!getcwd(workpath,MAXPATHLEN)) {
  64. #else
  65.         if (!getwd(workpath)) {
  66. #endif    
  67.         userid = geteuid();
  68.         seteuid(0);
  69. #ifdef HAVE_GETCWD
  70.             if (!getcwd(workpath,MAXPATHLEN)) {
  71. #else
  72.             if (!getwd(workpath)) {
  73. #endif
  74.                 strcpy(result, ".");
  75.             seteuid(userid);
  76.                 return (NULL);
  77.             }
  78.         seteuid(userid);
  79.     }
  80.     } else
  81.         *workpath = NULL;
  82.  
  83.     /* curpath is the path we're still resolving      */
  84.     /* linkpath is the path a symbolic link points to */
  85.     /* workpath is the path we've resolved            */
  86.  
  87.   loop:
  88.     where = curpath;
  89.     while (*where != NULL) {
  90.         if (!strcmp(where, ".")) {
  91.             where++;
  92.             continue;
  93.         }
  94.         /* deal with "./" */
  95.         if (!strncmp(where, "./", 2)) {
  96.             where += 2;
  97.             continue;
  98.         }
  99.         /* deal with "../" */
  100.         if (!strncmp(where, "../", 3)) {
  101.             where += 3;
  102.             ptr = last = workpath;
  103.             while (*ptr) {
  104.                 if (*ptr == '/')
  105.                     last = ptr;
  106.                 ptr++;
  107.             }
  108.             *last = NULL;
  109.             continue;
  110.         }
  111.         ptr = strchr(where, '/');
  112.         if (!ptr)
  113.             ptr = where + strlen(where) - 1;
  114.         else
  115.             *ptr = NULL;
  116.  
  117.         strcpy(namebuf, workpath);
  118.         for (last = namebuf; *last; last++)
  119.             continue;
  120.         if (*--last != '/')
  121.             strcat(namebuf, "/");
  122.         strcat(namebuf, where);
  123.  
  124.         where = ++ptr;
  125.         if (lstat(namebuf, &sbuf) == -1) {
  126.             strcpy(result, namebuf);
  127.             return (NULL);
  128.         }
  129.         /* was IFLNK */
  130. #ifdef HAVE_SYMLINK
  131.         if ((sbuf.st_mode & S_IFMT) == S_IFLNK) {
  132.             len = readlink(namebuf, linkpath, MAXPATHLEN);
  133.             if (len == 0) {
  134.                 strcpy(result, namebuf);
  135.                 return (NULL);
  136.             }
  137.             *(linkpath + len) = NULL;   /* readlink doesn't null-terminate
  138.                                          * result */
  139.             if (*linkpath == '/')
  140.                 *workpath = NULL;
  141.             if (*where) {
  142.                 strcat(linkpath, "/");
  143.                 strcat(linkpath, where);
  144.             }
  145.             strcpy(curpath, linkpath);
  146.             goto loop;
  147.         }
  148. #endif
  149.         if ((sbuf.st_mode & S_IFDIR) == S_IFDIR) {
  150.             strcpy(workpath, namebuf);
  151.             continue;
  152.         }
  153.         if (*where) {
  154.             strcpy(result, namebuf);
  155.             return (NULL);      /* path/notadir/morepath */
  156.         } else
  157.             strcpy(workpath, namebuf);
  158.     }
  159.     strcpy(result, workpath);
  160.     return (result);
  161. }
  162.