home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / std_unix / pax / 2 / pathname.c < prev    next >
C/C++ Source or Header  |  1989-01-07  |  5KB  |  234 lines

  1. /* $Source: /u/mark/src/pax/RCS/pathname.c,v $
  2.  *
  3.  * $Revision: 1.1 $
  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 MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  * $Log:    pathname.c,v $
  32.  * Revision 1.1  88/12/23  18:02:21  mark
  33.  * Initial revision
  34.  * 
  35.  */
  36.  
  37. #ifndef lint
  38. static char *ident = "$Id: pathname.c,v 1.1 88/12/23 18:02:21 mark Rel $";
  39. static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
  40. #endif /* ! lint */
  41.  
  42.  
  43. /* Headers */
  44.  
  45. #include "pax.h"
  46.  
  47.  
  48. /* dirneed  - checks for the existance of directories and possibly create
  49.  *
  50.  * DESCRIPTION
  51.  *
  52.  *    Dirneed checks to see if a directory of the name pointed to by name
  53.  *    exists.  If the directory does exist, then dirneed returns 0.  If
  54.  *    the directory does not exist and the f_create_dirs flag is set,
  55.  *    then dirneed will create the needed directory, recursively creating
  56.  *    any needed intermediate directory.
  57.  *
  58.  *    If f_create_dirs is not set, then no directories will be created
  59.  *    and a value of -1 will be returned if the directory does not
  60.  *    exist.
  61.  *
  62.  * PARAMETERS
  63.  *
  64.  *    name        - name of the directory to create
  65.  *
  66.  * RETURNS
  67.  *
  68.  *    Returns a 0 if the creation of the directory succeeded or if the
  69.  *    directory already existed.  If the f_create_dirs flag was not set
  70.  *    and the named directory does not exist, or the directory creation 
  71.  *    failed, a -1 will be returned to the calling routine.
  72.  */
  73.  
  74. #ifdef __STDC__
  75.  
  76. int dirneed(char *name)
  77.  
  78. #else
  79.  
  80. int dirneed(name)
  81. char           *name;
  82.  
  83. #endif
  84. {
  85.     char           *cp;
  86.     char           *last;
  87.     int             ok;
  88.     static Stat     sb;
  89.  
  90.     last = NULL;
  91.     for (cp = name; *cp;) {
  92.     if (*cp++ == '/') {
  93.         last = cp;
  94.     }
  95.     }
  96.     if (last == NULL) {
  97.     return (STAT(".", &sb));
  98.     }
  99.     *--last = '\0';
  100.     ok = STAT(*name ? name : ".", &sb) == 0
  101.     ? ((sb.sb_mode & S_IFMT) == S_IFDIR)
  102.     : (f_create_dirs && dirneed(name) == 0 && dirmake(name, &sb) == 0);
  103.     *last = '/';
  104.     return (ok ? 0 : -1);
  105. }
  106.  
  107.  
  108. /* nameopt - optimize a pathname
  109.  *
  110.  * DESCRIPTION
  111.  *
  112.  *     Confused by "<symlink>/.." twistiness. Returns the number of final 
  113.  *     pathname elements (zero for "/" or ".") or -1 if unsuccessful. 
  114.  *
  115.  * PARAMETERS
  116.  *
  117.  *    char    *begin    - name of the path to optimize
  118.  *
  119.  * RETURNS
  120.  *
  121.  *    Returns 0 if successful, non-zero otherwise.
  122.  *
  123.  */
  124.  
  125. #ifdef __STDC__
  126.  
  127. int nameopt(char *begin)
  128.  
  129. #else
  130.  
  131. int nameopt(begin)
  132. char           *begin;
  133.  
  134. #endif
  135. {
  136.     char           *name;
  137.     char           *item;
  138.     int             idx;
  139.     int             absolute;
  140.     char           *element[PATHELEM];
  141.  
  142.     absolute = (*(name = begin) == '/');
  143.     idx = 0;
  144.     for (;;) {
  145.     if (idx == PATHELEM) {
  146.         warn(begin, "Too many elements");
  147.         return (-1);
  148.     }
  149.     while (*name == '/') {
  150.         ++name;
  151.     }
  152.     if (*name == '\0') {
  153.         break;
  154.     }
  155.     element[idx] = item = name;
  156.     while (*name && *name != '/') {
  157.         ++name;
  158.     }
  159.     if (*name) {
  160.         *name++ = '\0';
  161.     }
  162.     if (strcmp(item, "..") == 0) {
  163.         if (idx == 0) {
  164.         if (!absolute) {
  165.             ++idx;
  166.         }
  167.         } else if (strcmp(element[idx - 1], "..") == 0) {
  168.         ++idx;
  169.         } else {
  170.         --idx;
  171.         }
  172.     } else if (strcmp(item, ".") != 0) {
  173.         ++idx;
  174.     }
  175.     }
  176.     if (idx == 0) {
  177.     element[idx++] = absolute ? "" : "."; 
  178.     }
  179.     element[idx] = NULL;
  180.     name = begin;
  181.     if (absolute) {
  182.     *name++ = '/';
  183.     }
  184.     for (idx = 0; item = element[idx]; ++idx, *name++ = '/') {
  185.     while (*item) {
  186.         *name++ = *item++;
  187.     }
  188.     }
  189.     *--name = '\0';
  190.     return (idx);
  191. }
  192.  
  193.  
  194. /* dirmake - make a directory  
  195.  *
  196.  * DESCRIPTION
  197.  *
  198.  *    Dirmake makes a directory with the appropritate permissions.
  199.  *
  200.  * PARAMETERS
  201.  *
  202.  *    char     *name    - Name of directory make
  203.  *    Stat    *asb    - Stat structure of directory to make
  204.  *
  205.  * RETURNS
  206.  *
  207.  *     Returns zero if successful, -1 otherwise. 
  208.  *
  209.  */
  210.  
  211. #ifdef __STDC__
  212.  
  213. int dirmake(char *name, Stat *asb)
  214.  
  215. #else
  216.  
  217. int dirmake(name, asb)
  218. char           *name;
  219. Stat           *asb;
  220.  
  221. #endif
  222. {
  223.     if (mkdir(name, (int) (asb->sb_mode & S_IPOPN)) < 0) {
  224.     return (-1);
  225.     }
  226.     if (asb->sb_mode & S_IPEXE) {
  227.     chmod(name, (int) (asb->sb_mode & S_IPERM));
  228.     }
  229.     if (f_owner) {
  230.     chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
  231.     }
  232.     return (0);
  233. }
  234.