home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 May / W2KPRK.iso / apps / posix / source / PAX / PATHNAME.C < prev    next >
Encoding:
C/C++ Source or Header  |  1999-11-17  |  5.7 KB  |  255 lines

  1. /* $Source: /u/mark/src/pax/RCS/pathname.c,v $
  2.  *
  3.  * $Revision: 1.2 $
  4.  *
  5.  * pathname.c - directory/pathname support functions 
  6.  *
  7.  * DESCRIPTION
  8.  *
  9.  *    These functions provide directory/pathname support for PAX
  10.  *
  11.  * AUTHOR
  12.  *
  13.  *    Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
  14.  *
  15.  * Sponsored by The USENIX Association for public distribution. 
  16.  *
  17.  * Copyright (c) 1989 Mark H. Colburn.
  18.  * All rights reserved.
  19.  *
  20.  * Redistribution and use in source and binary forms are permitted
  21.  * provided that the above copyright notice is duplicated in all such 
  22.  * forms and that any documentation, advertising materials, and other 
  23.  * materials related to such distribution and use acknowledge that the 
  24.  * software was developed * by Mark H. Colburn and sponsored by The 
  25.  * USENIX Association. 
  26.  *
  27.  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
  28.  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
  29.  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  * $Log:    pathname.c,v $
  32.  * Revision 1.2  89/02/12  10:05:13  mark
  33.  * 1.2 release fixes
  34.  * 
  35.  * Revision 1.1  88/12/23  18:02:21  mark
  36.  * Initial revision
  37.  * 
  38.  */
  39.  
  40. #ifndef lint
  41. static char *ident = "$Id: pathname.c,v 1.2 89/02/12 10:05:13 mark Exp $";
  42. static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  43. #endif /* ! lint */
  44.  
  45.  
  46. /* Headers */
  47.  
  48. #include "pax.h"
  49.  
  50.  
  51. /* dirneed  - checks for the existance of directories and possibly create
  52.  *
  53.  * DESCRIPTION
  54.  *
  55.  *    Dirneed checks to see if a directory of the name pointed to by name
  56.  *    exists.  If the directory does exist, then dirneed returns 0.  If
  57.  *    the directory does not exist and the f_dir_create flag is set,
  58.  *    then dirneed will create the needed directory, recursively creating
  59.  *    any needed intermediate directory.
  60.  *
  61.  *    If f_dir_create is not set, then no directories will be created
  62.  *    and a value of -1 will be returned if the directory does not
  63.  *    exist.
  64.  *
  65.  * PARAMETERS
  66.  *
  67.  *    name        - name of the directory to create
  68.  *
  69.  * RETURNS
  70.  *
  71.  *    Returns a 0 if the creation of the directory succeeded or if the
  72.  *    directory already existed.  If the f_dir_create flag was not set
  73.  *    and the named directory does not exist, or the directory creation 
  74.  *    failed, a -1 will be returned to the calling routine.
  75.  */
  76.  
  77. #ifdef __STDC__
  78.  
  79. int dirneed(char *name)
  80.  
  81. #else
  82.  
  83. int dirneed(name)
  84. char           *name;
  85.  
  86. #endif
  87. {
  88.     char           *cp;
  89.     char           *last;
  90.     int             ok;
  91.     static Stat     sb;
  92.  
  93. #ifdef DF_TRACE_DEBUG
  94. printf("DF_TRACE_DEBUG: int dirneed() in pathname.c\n");
  95. #endif
  96.     last = (char *)NULL;
  97.     for (cp = name; *cp;) {
  98.     if (*cp++ == '/') {
  99.         last = cp;
  100.     }
  101.     }
  102.     if (last == (char *)NULL) {
  103.     return (STAT(".", &sb));
  104.     }
  105.     *--last = '\0';
  106.     ok = STAT(*name ? name : ".", &sb) == 0
  107.     ? ((sb.sb_mode & S_IFMT) == S_IFDIR)
  108.     : (f_dir_create && dirneed(name) == 0 && dirmake(name, &sb) == 0);
  109.     *last = '/';
  110.     return (ok ? 0 : -1);
  111. }
  112.  
  113.  
  114. /* nameopt - optimize a pathname
  115.  *
  116.  * DESCRIPTION
  117.  *
  118.  *     Confused by "<symlink>/.." twistiness. Returns the number of final 
  119.  *     pathname elements (zero for "/" or ".") or -1 if unsuccessful. 
  120.  *
  121.  * PARAMETERS
  122.  *
  123.  *    char    *begin    - name of the path to optimize
  124.  *
  125.  * RETURNS
  126.  *
  127.  *    Returns 0 if successful, non-zero otherwise.
  128.  *
  129.  */
  130.  
  131. #ifdef __STDC__
  132.  
  133. int nameopt(char *begin)
  134.  
  135. #else
  136.  
  137. int nameopt(begin)
  138. char           *begin;
  139.  
  140. #endif
  141. {
  142.     char           *name;
  143.     char           *item;
  144.     int             idx;
  145.     int             absolute;
  146.     char           *element[PATHELEM];
  147.  
  148. #ifdef DF_TRACE_DEBUG
  149. printf("DF_TRACE_DEBUG:     ok = STAT() in pathname.c\n");
  150. #endif
  151.     absolute = (*(name = begin) == '/');
  152.     idx = 0;
  153.     for (;;) {
  154.     if (idx == PATHELEM) {
  155.         warn(begin, "Too many elements");
  156.         return (-1);
  157.     }
  158.     while (*name == '/') {
  159.         ++name;
  160.     }
  161.     if (*name == '\0') {
  162.         break;
  163.     }
  164.     element[idx] = item = name;
  165.     while (*name && *name != '/') {
  166.         ++name;
  167.     }
  168.     if (*name) {
  169.         *name++ = '\0';
  170.     }
  171.     if (strcmp(item, "..") == 0) {
  172.         if (idx == 0) {
  173.         if (!absolute) {
  174.             ++idx;
  175.         }
  176.         } else if (strcmp(element[idx - 1], "..") == 0) {
  177.         ++idx;
  178.         } else {
  179.         --idx;
  180.         }
  181.     } else if (strcmp(item, ".") != 0) {
  182.         ++idx;
  183.     }
  184.     }
  185.     if (idx == 0) {
  186.     element[idx++] = absolute ? "" : "."; 
  187.     }
  188.     element[idx] = (char *)NULL;
  189.     name = begin;
  190.     if (absolute) {
  191.     *name++ = '/';
  192.     }
  193.     for (idx = 0; (item = element[idx]) != NULL; ++idx, *name++ = '/') {  /* Xn */
  194.     while (*item) {
  195.         *name++ = *item++;
  196.     }
  197.     }
  198.     *--name = '\0';
  199.     return (idx);
  200. }
  201.  
  202.  
  203. /* dirmake - make a directory  
  204.  *
  205.  * DESCRIPTION
  206.  *
  207.  *    Dirmake makes a directory with the appropritate permissions.
  208.  *
  209.  * PARAMETERS
  210.  *
  211.  *    char     *name    - Name of directory make
  212.  *    Stat    *asb    - Stat structure of directory to make
  213.  *
  214.  * RETURNS
  215.  *
  216.  *     Returns zero if successful, -1 otherwise. 
  217.  *
  218.  */
  219.  
  220. #ifdef __STDC__
  221.  
  222. int dirmake(char *name, Stat *asb)
  223.  
  224. #else
  225.  
  226. int dirmake(name, asb)
  227. char           *name;
  228. Stat           *asb;
  229.  
  230. #endif
  231. {
  232. #ifdef DF_TRACE_DEBUG
  233. printf("DF_TRACE_DEBUG: int dirmake() in pathname.c\n");
  234. #endif
  235.  
  236. #if 0 && WIN_NT /* DSC 1993-01-09: permission stuff not working in POSIX */
  237.     mkdir (name,0777);
  238.     return (0);
  239. #endif
  240.  
  241.     if (mkdir(name, (int) (asb->sb_mode & S_IPOPN)) < 0) {
  242.     return (-1);
  243.     }
  244.     if (asb->sb_mode & S_IPEXE) {
  245. #if 0 && WIN_NT
  246.     printf("pathname.c/dirmake - name: \"%s\"; asb->sb_mode: %lo\n", name, (unsigned long) asb->sb_mode);
  247. #endif
  248.     chmod(name, (int) (asb->sb_mode & S_IPERM));
  249.     }
  250.     if (f_owner) {
  251.     chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
  252.     }
  253.     return (0);
  254. }
  255.