home *** CD-ROM | disk | FTP | other *** search
- /* $Source: /u/mark/src/pax/RCS/pathname.c,v $
- *
- * $Revision: 1.2 $
- *
- * pathname.c - directory/pathname support functions
- *
- * DESCRIPTION
- *
- * These functions provide directory/pathname support for PAX
- *
- * AUTHOR
- *
- * Mark H. Colburn, NAPS International (mark@jhereg.mn.org)
- *
- * Sponsored by The USENIX Association for public distribution.
- *
- * Copyright (c) 1989 Mark H. Colburn.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice is duplicated in all such
- * forms and that any documentation, advertising materials, and other
- * materials related to such distribution and use acknowledge that the
- * software was developed * by Mark H. Colburn and sponsored by The
- * USENIX Association.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * $Log: pathname.c,v $
- * Revision 1.2 89/02/12 10:05:13 mark
- * 1.2 release fixes
- *
- * Revision 1.1 88/12/23 18:02:21 mark
- * Initial revision
- *
- */
-
- #ifndef lint
- static char *ident = "$Id: pathname.c,v 1.2 89/02/12 10:05:13 mark Exp $";
- static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";
- #endif /* ! lint */
-
-
- /* Headers */
-
- #include "pax.h"
-
-
- /* dirneed - checks for the existance of directories and possibly create
- *
- * DESCRIPTION
- *
- * Dirneed checks to see if a directory of the name pointed to by name
- * exists. If the directory does exist, then dirneed returns 0. If
- * the directory does not exist and the f_dir_create flag is set,
- * then dirneed will create the needed directory, recursively creating
- * any needed intermediate directory.
- *
- * If f_dir_create is not set, then no directories will be created
- * and a value of -1 will be returned if the directory does not
- * exist.
- *
- * PARAMETERS
- *
- * name - name of the directory to create
- *
- * RETURNS
- *
- * Returns a 0 if the creation of the directory succeeded or if the
- * directory already existed. If the f_dir_create flag was not set
- * and the named directory does not exist, or the directory creation
- * failed, a -1 will be returned to the calling routine.
- */
-
- #ifdef __STDC__
-
- int dirneed(char *name)
-
- #else
-
- int dirneed(name)
- char *name;
-
- #endif
- {
- char *cp;
- char *last;
- int ok;
- static Stat sb;
-
- #ifdef DF_TRACE_DEBUG
- printf("DF_TRACE_DEBUG: int dirneed() in pathname.c\n");
- #endif
- last = (char *)NULL;
- for (cp = name; *cp;) {
- if (*cp++ == '/') {
- last = cp;
- }
- }
- if (last == (char *)NULL) {
- return (STAT(".", &sb));
- }
- *--last = '\0';
- ok = STAT(*name ? name : ".", &sb) == 0
- ? ((sb.sb_mode & S_IFMT) == S_IFDIR)
- : (f_dir_create && dirneed(name) == 0 && dirmake(name, &sb) == 0);
- *last = '/';
- return (ok ? 0 : -1);
- }
-
-
- /* nameopt - optimize a pathname
- *
- * DESCRIPTION
- *
- * Confused by "<symlink>/.." twistiness. Returns the number of final
- * pathname elements (zero for "/" or ".") or -1 if unsuccessful.
- *
- * PARAMETERS
- *
- * char *begin - name of the path to optimize
- *
- * RETURNS
- *
- * Returns 0 if successful, non-zero otherwise.
- *
- */
-
- #ifdef __STDC__
-
- int nameopt(char *begin)
-
- #else
-
- int nameopt(begin)
- char *begin;
-
- #endif
- {
- char *name;
- char *item;
- int idx;
- int absolute;
- char *element[PATHELEM];
-
- #ifdef DF_TRACE_DEBUG
- printf("DF_TRACE_DEBUG: ok = STAT() in pathname.c\n");
- #endif
- absolute = (*(name = begin) == '/');
- idx = 0;
- for (;;) {
- if (idx == PATHELEM) {
- warn(begin, "Too many elements");
- return (-1);
- }
- while (*name == '/') {
- ++name;
- }
- if (*name == '\0') {
- break;
- }
- element[idx] = item = name;
- while (*name && *name != '/') {
- ++name;
- }
- if (*name) {
- *name++ = '\0';
- }
- if (strcmp(item, "..") == 0) {
- if (idx == 0) {
- if (!absolute) {
- ++idx;
- }
- } else if (strcmp(element[idx - 1], "..") == 0) {
- ++idx;
- } else {
- --idx;
- }
- } else if (strcmp(item, ".") != 0) {
- ++idx;
- }
- }
- if (idx == 0) {
- element[idx++] = absolute ? "" : ".";
- }
- element[idx] = (char *)NULL;
- name = begin;
- if (absolute) {
- *name++ = '/';
- }
- for (idx = 0; (item = element[idx]) != NULL; ++idx, *name++ = '/') { /* Xn */
- while (*item) {
- *name++ = *item++;
- }
- }
- *--name = '\0';
- return (idx);
- }
-
-
- /* dirmake - make a directory
- *
- * DESCRIPTION
- *
- * Dirmake makes a directory with the appropritate permissions.
- *
- * PARAMETERS
- *
- * char *name - Name of directory make
- * Stat *asb - Stat structure of directory to make
- *
- * RETURNS
- *
- * Returns zero if successful, -1 otherwise.
- *
- */
-
- #ifdef __STDC__
-
- int dirmake(char *name, Stat *asb)
-
- #else
-
- int dirmake(name, asb)
- char *name;
- Stat *asb;
-
- #endif
- {
- #ifdef DF_TRACE_DEBUG
- printf("DF_TRACE_DEBUG: int dirmake() in pathname.c\n");
- #endif
-
- #if 0 && WIN_NT /* DSC 1993-01-09: permission stuff not working in POSIX */
- mkdir (name,0777);
- return (0);
- #endif
-
- if (mkdir(name, (int) (asb->sb_mode & S_IPOPN)) < 0) {
- return (-1);
- }
- if (asb->sb_mode & S_IPEXE) {
- #if 0 && WIN_NT
- printf("pathname.c/dirmake - name: \"%s\"; asb->sb_mode: %lo\n", name, (unsigned long) asb->sb_mode);
- #endif
- chmod(name, (int) (asb->sb_mode & S_IPERM));
- }
- if (f_owner) {
- chown(name, (int) asb->sb_uid, (int) asb->sb_gid);
- }
- return (0);
- }
-