home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / gnulib / ohlutil / mkdir.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-08-24  |  6.5 KB  |  273 lines

  1. /* mkdir -- make directories
  2.    Copyright (C) 1990 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /*
  19.  * MS-DOS port (c) 1990 by Thorsten Ohl, td12@ddagsi3.bitnet
  20.  *
  21.  * To this port, the same copying conditions apply as to the
  22.  * original release.
  23.  *
  24.  * IMPORTANT:
  25.  * This file is not identical to the original GNU release!
  26.  * You should have received this code as patch to the official
  27.  * GNU release.
  28.  *
  29.  * MORE IMPORTANT:
  30.  * This port comes with ABSOLUTELY NO WARRANTY.
  31.  *
  32.  * $Header: e:/gnu/fileutil/RCS/mkdir.c'v 1.3.0.2 90/06/29 00:46:57 tho Stable $
  33.  */
  34.  
  35. /* Usage: mkdir [-p] [-m mode] [+path] [+mode mode] dir...
  36.  
  37.    Options:
  38.    -p, +path        Ensure that the given path(s) exist:
  39.             Make any missing parent directories for each argument.
  40.             Parent dirs default to umask modified by `u+wx'.
  41.             Do not consider an argument directory that already
  42.             exists to be an error.
  43.    -m, +mode mode    Set the mode of created directories to `mode', which is
  44.             symbolic as in chmod and uses the umask as a point of
  45.             departure.
  46.  
  47.    David MacKenzie <djm@ai.mit.edu>  */
  48.  
  49. #include <stdio.h>
  50. #include <sys/types.h>
  51. #include "system.h"
  52. #include "getopt.h"
  53.  
  54. #ifdef MSDOS
  55. #include <direct.h>
  56. extern void main (int argc, char **argv);
  57. extern void error (int status, int errnum, char *message, ...);
  58. static int make_path (char *path, unsigned short mode,\
  59.               unsigned short parent_mode);
  60. static void strip_trailing_slashes (char *path);
  61. static void usage (void);
  62. #else /* not MSDOS */
  63. #include "modechange.h"
  64. #endif /* not MSDOS */
  65.   
  66. #ifdef STDC_HEADERS
  67. #include <errno.h>
  68. #include <stdlib.h>
  69. #else
  70. extern int errno;
  71. #endif
  72.  
  73. int make_path ();
  74. void error ();
  75. void strip_trailing_slashes ();
  76. void usage ();
  77.  
  78. /* If nonzero, ensure that a path exists.  */
  79. int path_mode;
  80.  
  81. /* The name this program was run with. */
  82. char *program_name;
  83.  
  84. struct option longopts[] =
  85. {
  86. #ifndef MSDOS
  87.   {"mode", 1, NULL, 'm'},
  88. #endif /* not MSDOS */
  89.   {"path", 0, &path_mode, 1},
  90.   {NULL, 0, NULL, 0}
  91. };
  92.  
  93. void
  94. main (argc, argv)
  95.      int argc;
  96.      char **argv;
  97. {
  98.   unsigned short newmode;
  99.   unsigned short parent_mode;
  100. #ifndef MSDOS
  101.   struct modechange *change;
  102. #endif /* not MSDOS */
  103.   char *symbolic_mode;
  104.   int errors = 0;
  105.   int optc;
  106.   int ind;
  107.  
  108.   program_name = argv[0];
  109. #ifdef MSDOS
  110.   strlwr (program_name);
  111. #endif /* MSDOS */
  112.   path_mode = 0;
  113.   symbolic_mode = NULL;
  114.  
  115. #ifdef MSDOS
  116.   while ((optc = getopt_long (argc, argv, "p", longopts, &ind)) != EOF)
  117. #else /* not MSDOS */
  118.   while ((optc = getopt_long (argc, argv, "pm:", longopts, &ind)) != EOF)
  119. #endif /* not MSDOS */
  120.     {
  121.       if (optc == 0 && longopts[ind].flag == 0)
  122.     optc = longopts[ind].val;
  123.       switch (optc)
  124.     {
  125.     case 0:            /* Long option. */
  126.       break;
  127.     case 'p':
  128.       path_mode = 1;
  129.       break;
  130. #ifndef MSDOS
  131.     case 'm':
  132.       symbolic_mode = optarg;
  133.       break;
  134.     default:
  135. #endif /* not MSDOS */
  136.       usage ();
  137.     }
  138.     }
  139.  
  140.   if (optind == argc)
  141.     usage ();
  142.   
  143. #ifndef MSDOS
  144.   newmode = 0777 & ~umask (0);
  145.   parent_mode = newmode | 0300;    /* u+wx */
  146.   if (symbolic_mode)
  147.     {
  148.       change = mode_compile (symbolic_mode, MODE_MASK_EQUALS | MODE_MASK_PLUS);
  149.       if (change == MODE_INVALID)
  150.     error (1, 0, "invalid mode");
  151.       else if (change == MODE_MEMORY_EXHAUSTED)
  152.     error (1, 0, "virtual memory exhausted");
  153.       newmode = mode_adjust (newmode, change);
  154.     }
  155. #endif /* not MSDOS */
  156.  
  157.   for (; optind < argc; ++optind)
  158.     {
  159. #ifdef MSDOS
  160.       strlwr (argv[optind]);
  161. #endif /* MSDOS */
  162.       strip_trailing_slashes (argv[optind]);
  163.       if (path_mode)
  164.     errors |= make_path (argv[optind], newmode, parent_mode);
  165. #ifdef MSDOS
  166.       else if (mkdir (argv[optind]) == -1)
  167. #else /* not MSDOS */
  168.       else if (mkdir (argv[optind], newmode))
  169. #endif /* not MSDOS */
  170.     {
  171.       error (0, errno, "cannot make directory `%s'", argv[optind]);
  172.       errors = 1;
  173.     }
  174.     }
  175.  
  176.   exit (errors);
  177. }
  178.  
  179. /* Make sure directory `path' and all leading directories exist,
  180.    and give it permission mode `mode'.
  181.    If any leading directories are created, give them permission
  182.    mode `parent_mode'.
  183.    Return 0 if successful, 1 if errors occur. */
  184.  
  185. int
  186. make_path (path, mode, parent_mode)
  187.      char *path;
  188.      unsigned short mode;
  189.      unsigned short parent_mode;
  190. {
  191.   char *slash;
  192.   struct stat stats;
  193.  
  194.   if (stat (path, &stats))
  195.     {
  196.       slash = path;
  197.       while (*slash == '/')
  198.     slash++;
  199.       while (slash = index (slash, '/'))
  200.     {
  201.       *slash = 0;
  202.       if (stat (path, &stats))
  203.         {
  204. #ifdef MSDOS
  205.           if (mkdir (path) == -1)
  206. #else /* not MSDOS */
  207.           if (mkdir (path, parent_mode))
  208. #endif /* not MSDOS */
  209.         {
  210.           error (0, errno, "cannot make directory `%s'", path);
  211.           return 1;
  212.         }
  213.         }
  214.       else if ((stats.st_mode & S_IFMT) != S_IFDIR)
  215.         {
  216.           error (0, 0, "`%s' is not a directory", path);
  217.           return 1;
  218.         }
  219.       *slash++ = '/';
  220.     }
  221.  
  222. #ifdef MSDOS
  223.       if (mkdir (path) == -1)
  224. #else /* not MSDOS */
  225.       if (mkdir (path, mode))
  226. #endif /* not MSDOS */
  227.     {
  228.       error (0, errno, "cannot make directory `%s'", path);
  229.       return 1;
  230.     }
  231.     }
  232.   else if ((stats.st_mode & S_IFMT) != S_IFDIR)
  233.     {
  234.       error (0, 0, "`%s' is not a directory", path);
  235.       return 1;
  236.     }
  237. #ifndef MSDOS
  238.   else if (chmod (path, mode))
  239.     {
  240.       error (0, errno, "cannot change mode of `%s'", path);
  241.       return 1;
  242.     }
  243. #endif /* not MSDOS */
  244.   return 0;
  245. }
  246.  
  247. /* Remove trailing slashes from PATH; they cause some system calls to fail. */
  248.  
  249. void
  250. strip_trailing_slashes (path)
  251.      char *path;
  252. {
  253.   int last;
  254.  
  255.   last = strlen (path) - 1;
  256.   while (last > 0 && path[last] == '/')
  257.     path[last--] = '\0';
  258. }
  259.  
  260. void
  261. usage ()
  262. {
  263.  
  264. #ifdef MSDOS
  265.   fprintf (stderr, "Usage: %s [-p] [+path] dir...\n", program_name);
  266. #else /* not MSDOS */
  267.   fprintf (stderr, "\
  268. Usage: %s [-p] [-m mode] [+path] [+mode mode] dir...\n",
  269.        program_name);
  270. #endif /* not MSDOS */
  271.   exit (1);
  272. }
  273.