src/findlib/mkpath.c
bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode,
            uid_t owner, gid_t group, int keep_dir_modes)
{
   struct stat statp;
   mode_t omask, tmode;
   char *path = (char *)apath;
   char *p;
   int len;
   bool ok = false;
   int created;
   char new_dir[5000];
   int ndir = 0;
   int i = 0;
   int max_dirs = (int)sizeof(new_dir);
   JCR *jcr = attr->jcr;

   if (stat(path, &statp) == 0) {     /* Does dir exist? */
      if (!S_ISDIR(statp.st_mode)) {
         Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path);
         return false;
      }
      /* Full path exists */
      if (keep_dir_modes) {
         return true;
      }
      set_own_mod(attr, path, owner, group, mode);
      return true;
   }
   omask = umask(0);
   umask(omask);
   len = strlen(apath);
   path = (char *)alloca(len+1);
   bstrncpy(path, apath, len+1);
   strip_trailing_slashes(path);
   /*
    * Now for one of the complexities. If we are not running as root,
    *  then if the parent_mode does not have wx user perms, or we are
    *  setting the userid or group, and the parent_mode has setuid, setgid,
    *  or sticky bits, we must create the dir with open permissions, then
    *  go back and patch all the dirs up with the correct perms.
    * Solution, set everything to 0777, then go back and reset them at the
    *  end.
    */
   tmode = 0777;

#if defined(HAVE_WIN32)
   /* Validate drive letter */
   if (path[1] == ':') {
      char drive[4] = "X:\\";

      drive[0] = path[0];

      UINT drive_type = GetDriveType(drive);

      if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) {
         Jmsg1(jcr, M_ERROR, 0, _("%c: is not a valid drive.\n"), path[0]);
         goto bail_out;
      }

      if (path[2] == '\0') {          /* attempt to create a drive */
         ok = true;
         goto bail_out;               /* OK, it is already there */
      }

      p = &path[3];
   } else {
      p = path;
   }
#else
   p = path;
#endif

   /* Skip leading slash(es) */
   while (IsPathSeparator(*p)) {
      p++;
   }
   while ((p = first_path_separator(p))) {
      char save_p;
      save_p = *p;
      *p = 0;
      if (!makedir(jcr, path, tmode, &created)) {
         goto bail_out;
      }
      if (ndir < max_dirs) {
         new_dir[ndir++] = created;
      }
      *p = save_p;
      while (IsPathSeparator(*p)) {
         p++;
      }
   }
   /* Create final component */
   if (!makedir(jcr, path, tmode, &created)) {
      goto bail_out;
   }
   if (ndir < max_dirs) {
      new_dir[ndir++] = created;
   }
   if (ndir >= max_dirs) {
      Jmsg0(jcr, M_WARNING, 0, _("Too many subdirectories. Some permissions not reset.\n"));
   }

   /* Now set the proper owner and modes */
#if defined(HAVE_WIN32)

   /* Don't propagate the hidden or encrypted attributes to parent directories */
   parent_mode &= ~S_ISVTX;
   parent_mode &= ~S_ISGID;

   if (path[1] == ':') {
      p = &path[3];
   } else {
      p = path;
   }
#else
   p = path;
#endif
   /* Skip leading slash(es) */
   while (IsPathSeparator(*p)) {
      p++;
   }
   while ((p = first_path_separator(p))) {
      char save_p;
      save_p = *p;
      *p = 0;
      if (i < ndir && new_dir[i++] && !keep_dir_modes) {
         set_own_mod(attr, path, owner, group, parent_mode);
      }
      *p = save_p;
      while (IsPathSeparator(*p)) {
         p++;
      }
   }

   /* Set for final component */
   if (i < ndir && new_dir[i++]) {
      set_own_mod(attr, path, owner, group, mode);
   }

   ok = true;
bail_out:
   umask(omask);
   return ok;
}
/*
 * mode is the mode bits to use in creating a new directory
 *
 * parent_mode are the parent's modes if we need to create parent
 *    directories.
 *
 * owner and group are to set on any created dirs
 *
 * keep_dir_modes if set means don't change mode bits if dir exists
 */
mode is the mode bits to use in creating a new directory
parent_mode are the parent's modes if we need to create parent
directories.

owner and group are to set on any created dirs

keep_dir_modes if set means don't change mode bits if dir exists
mode is the mode bits to use in creating a new directory parent_mode are the parent ' s modes if we need to create parent directories . owner and group are to set on any created dirs keep_dir_modes if set means don ' t change mode bits if dir exists
bool makepath(ATTR *attr, const char *apath, mode_t mode, mode_t parent_mode,
            uid_t owner, gid_t group, int keep_dir_modes)
{
   struct stat statp;
   mode_t omask, tmode;
   char *path = (char *)apath;
   char *p;
   int len;
   bool ok = false;
   int created;
   char new_dir[5000];
   int ndir = 0;
   int i = 0;
   int max_dirs = (int)sizeof(new_dir);
   JCR *jcr = attr->jcr;
   if (stat(path, &statp) == 0) {     
      if (!S_ISDIR(statp.st_mode)) {
         Jmsg1(jcr, M_ERROR, 0, _("%s exists but is not a directory.\n"), path);
         return false;
      }
      if (keep_dir_modes) {
         return true;
      }
      set_own_mod(attr, path, owner, group, mode);
      return true;
   }
   omask = umask(0);
   umask(omask);
   len = strlen(apath);
   path = (char *)alloca(len+1);
   bstrncpy(path, apath, len+1);
   strip_trailing_slashes(path);
   tmode = 0777;
#if defined(HAVE_WIN32)
   if (path[1] == ':') {
      char drive[4] = "X:\\";
      drive[0] = path[0];
      UINT drive_type = GetDriveType(drive);
      if (drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR) {
         Jmsg1(jcr, M_ERROR, 0, _("%c: is not a valid drive.\n"), path[0]);
         goto bail_out;
      }
      if (path[2] == '\0') {          
         ok = true;
         goto bail_out;               
      }
      p = &path[3];
   } else {
      p = path;
   }
#else
   p = path;
#endif
   while (IsPathSeparator(*p)) {
      p++;
   }
   while ((p = first_path_separator(p))) {
      char save_p;
      save_p = *p;
      *p = 0;
      if (!makedir(jcr, path, tmode, &created)) {
         goto bail_out;
      }
      if (ndir < max_dirs) {
         new_dir[ndir++] = created;
      }
      *p = save_p;
      while (IsPathSeparator(*p)) {
         p++;
      }
   }
   if (!makedir(jcr, path, tmode, &created)) {
      goto bail_out;
   }
   if (ndir < max_dirs) {
      new_dir[ndir++] = created;
   }
   if (ndir >= max_dirs) {
      Jmsg0(jcr, M_WARNING, 0, _("Too many subdirectories. Some permissions not reset.\n"));
   }
#if defined(HAVE_WIN32)
   parent_mode &= ~S_ISVTX;
   parent_mode &= ~S_ISGID;
   if (path[1] == ':') {
      p = &path[3];
   } else {
      p = path;
   }
#else
   p = path;
#endif
   while (IsPathSeparator(*p)) {
      p++;
   }
   while ((p = first_path_separator(p))) {
      char save_p;
      save_p = *p;
      *p = 0;
      if (i < ndir && new_dir[i++] && !keep_dir_modes) {
         set_own_mod(attr, path, owner, group, parent_mode);
      }
      *p = save_p;
      while (IsPathSeparator(*p)) {
         p++;
      }
   }
   if (i < ndir && new_dir[i++]) {
      set_own_mod(attr, path, owner, group, mode);
   }
   ok = true;
bail_out:
   umask(omask);
   return ok;
}
bool makepath ( ATTR * attr , const char * apath , mode_t mode , mode_t parent_mode , uid_t owner , gid_t group , int keep_dir_modes ) { struct stat statp ; mode_t omask , tmode ; char * path = ( char * ) apath ; char * p ; int len ; bool ok = false ; int created ; char new_dir [ 5000 ] ; int ndir = 0 ; int i = 0 ; int max_dirs = ( int ) sizeof ( new_dir ) ; JCR * jcr = attr -> jcr ; if ( stat ( path , & statp ) == 0 ) { if ( ! S_ISDIR ( statp . st_mode ) ) { Jmsg1 ( jcr , M_ERROR , 0 , _ ( " \n " ) , path ) ; return false ; } if ( keep_dir_modes ) { return true ; } set_own_mod ( attr , path , owner , group , mode ) ; return true ; } omask = umask ( 0 ) ; umask ( omask ) ; len = strlen ( apath ) ; path = ( char * ) alloca ( len + 1 ) ; bstrncpy ( path , apath , len + 1 ) ; strip_trailing_slashes ( path ) ; tmode = 0777 ; #if defined ( HAVE_WIN32 ) if ( path [ 1 ] == ' ' ) { char drive [ 4 ] = " \\ " ; drive [ 0 ] = path [ 0 ] ; UINT drive_type = GetDriveType ( drive ) ; if ( drive_type == DRIVE_UNKNOWN || drive_type == DRIVE_NO_ROOT_DIR ) { Jmsg1 ( jcr , M_ERROR , 0 , _ ( " \n " ) , path [ 0 ] ) ; goto bail_out ; } if ( path [ 2 ] == ' \0 ' ) { ok = true ; goto bail_out ; } p = & path [ 3 ] ; } else { p = path ; } #else p = path ; #endif while ( IsPathSeparator ( * p ) ) { p ++ ; } while ( ( p = first_path_separator ( p ) ) ) { char save_p ; save_p = * p ; * p = 0 ; if ( ! makedir ( jcr , path , tmode , & created ) ) { goto bail_out ; } if ( ndir < max_dirs ) { new_dir [ ndir ++ ] = created ; } * p = save_p ; while ( IsPathSeparator ( * p ) ) { p ++ ; } } if ( ! makedir ( jcr , path , tmode , & created ) ) { goto bail_out ; } if ( ndir < max_dirs ) { new_dir [ ndir ++ ] = created ; } if ( ndir >= max_dirs ) { Jmsg0 ( jcr , M_WARNING , 0 , _ ( " \n " ) ) ; } #if defined ( HAVE_WIN32 ) parent_mode &= ~ S_ISVTX ; parent_mode &= ~ S_ISGID ; if ( path [ 1 ] == ' ' ) { p = & path [ 3 ] ; } else { p = path ; } #else p = path ; #endif while ( IsPathSeparator ( * p ) ) { p ++ ; } while ( ( p = first_path_separator ( p ) ) ) { char save_p ; save_p = * p ; * p = 0 ; if ( i < ndir && new_dir [ i ++ ] && ! keep_dir_modes ) { set_own_mod ( attr , path , owner , group , parent_mode ) ; } * p = save_p ; while ( IsPathSeparator ( * p ) ) { p ++ ; } } if ( i < ndir && new_dir [ i ++ ] ) { set_own_mod ( attr , path , owner , group , mode ) ; } ok = true ; bail_out : umask ( omask ) ; return ok ; }
mode is the mode bits to use in creating a new directory
 parent_mode are the parent's modes if we need to create parent
    directories.
mode is the mode bits to use in creating a new directory parent_mode are the parent ' s modes if we need to create parent directories .
/* Does dir exist? */ /* Full path exists */ /*
    * Now for one of the complexities. If we are not running as root,
    *  then if the parent_mode does not have wx user perms, or we are
    *  setting the userid or group, and the parent_mode has setuid, setgid,
    *  or sticky bits, we must create the dir with open permissions, then
    *  go back and patch all the dirs up with the correct perms.
    * Solution, set everything to 0777, then go back and reset them at the
    *  end.
    */ /* Validate drive letter */ /* attempt to create a drive */ /* OK, it is already there */ /* Skip leading slash(es) */ /* Create final component */ /* Now set the proper owner and modes */ /* Don't propagate the hidden or encrypted attributes to parent directories */ /* Skip leading slash(es) */ /* Set for final component */