home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / PAX20.ZIP / PATHNAME.C < prev    next >
C/C++ Source or Header  |  1990-11-12  |  6KB  |  248 lines

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