Skip to content
Snippets Groups Projects
main.c 123 KiB
Newer Older
  • Learn to ignore specific revisions
  • */
    static int create_dir_hierarchy(char *outfile)
    {
      char *tempdir;
      char *tempdir2;
      char *outdup;
      char *dirbuildup;
      int result=0;
    
      outdup = strdup(outfile);
      dirbuildup = malloc(sizeof(char) * strlen(outfile));
    
      if(!dirbuildup)
        return -1;
      dirbuildup[0] = '\0';
    
    
      tempdir = strtok(outdup, DIR_CHAR);
    
      while (tempdir != NULL) {
        tempdir2 = strtok(NULL, DIR_CHAR);
        /* since strtok returns a token for the last word even
           if not ending with DIR_CHAR, we need to prune it */
        if (tempdir2 != NULL) {
          if (strlen(dirbuildup) > 0)
            sprintf(dirbuildup,"%s%s%s",dirbuildup, DIR_CHAR, tempdir);
          else {
    
            if (0 != strncmp(outdup, DIR_CHAR, 1))
    
              sprintf(dirbuildup,"%s",tempdir);
            else
              sprintf(dirbuildup,"%s%s", DIR_CHAR, tempdir);
          }
    
    Daniel Stenberg's avatar
    Daniel Stenberg committed
          if (access(dirbuildup, F_OK) == -1) {
    
            result = mkdir(dirbuildup,(mode_t)0000750);
            if (-1 == result) {
              switch (errno) {
    #ifdef EACCES
              case EACCES:
                fprintf(stderr,"You don't have permission to create %s.\n",
                        dirbuildup);
                break;
    #endif
    #ifdef ENAMETOOLONG
              case ENAMETOOLONG:
                fprintf(stderr,"The directory name %s is too long.\n",
                        dirbuildup);
                break;
    #endif
    #ifdef EROFS
              case EROFS:
                fprintf(stderr,"%s resides on a read-only file system.\n",
                        dirbuildup);
                break;
    #endif
    #ifdef ENOSPC
              case ENOSPC:
                fprintf(stderr,"No space left on the file system that will "
                        "contain the directory %s.\n", dirbuildup);
                break;
    #endif
    #ifdef EDQUOT
              case EDQUOT:
                fprintf(stderr,"Cannot create directory %s because you "
                        "exceeded your quota.\n", dirbuildup);
                break;
    #endif
              default :
                fprintf(stderr,"Error creating directory %s.\n", dirbuildup);
                break;
              }
              break; /* get out of loop */
            }
          }
        }
        tempdir = tempdir2;
      }
      free(dirbuildup);
      free(outdup);
    
      return result; /* 0 is fine, -1 is badness */
    }
    
    
    #ifdef __DJGPP__
    /* The following functions are taken with modification from the DJGPP
     * port of tar 1.12. They use algorithms originally from DJTAR. */
    
    char *
    msdosify (char *file_name)
    {
      static char dos_name[PATH_MAX];
    
      static const char illegal_chars_dos[] = ".+, ;=[]|<>\\\":?*";
      static const char *illegal_chars_w95 = &illegal_chars_dos[8];
    
      int idx, dot_idx;
      char *s = file_name, *d = dos_name;
    
      const char *illegal_aliens = illegal_chars_dos;
    
      size_t len = sizeof (illegal_chars_dos) - 1;
      int lfn = 0;
    
      /* Support for Windows 9X VFAT systems, when available.  */
      if (_use_lfn (file_name))
        lfn = 1;
      if (lfn) {
        illegal_aliens = illegal_chars_w95;
        len -= (illegal_chars_w95 - illegal_chars_dos);
      }
    
      /* Get past the drive letter, if any. */
      if (s[0] >= 'A' && s[0] <= 'z' && s[1] == ':') {
        *d++ = *s++;
        *d++ = *s++;
      }
    
      for (idx = 0, dot_idx = -1; *s; s++, d++) {
        if (memchr (illegal_aliens, *s, len)) {
          /* Dots are special: DOS doesn't allow them as the leading character,
             and a file name cannot have more than a single dot.  We leave the
             first non-leading dot alone, unless it comes too close to the
             beginning of the name: we want sh.lex.c to become sh_lex.c, not
             sh.lex-c.  */
          if (*s == '.') {
            if (idx == 0 && (s[1] == '/' || (s[1] == '.' && s[2] == '/'))) {
              /* Copy "./" and "../" verbatim.  */
              *d++ = *s++;
              if (*s == '.')
                *d++ = *s++;
              *d = *s;
            }
            else if (idx == 0)
              *d = '_';
            else if (dot_idx >= 0) {
              if (dot_idx < 5) { /* 5 is a heuristic ad-hoc'ery */
                d[dot_idx - idx] = '_'; /* replace previous dot */
                *d = '.';
              }
              else
                *d = '-';
            }
            else
              *d = '.';
    
            if (*s == '.')
              dot_idx = idx;
          }
          else if (*s == '+' && s[1] == '+') {
            if (idx - 2 == dot_idx) { /* .c++, .h++ etc. */
              *d++ = 'x';
              *d   = 'x';
            }
            else {
              /* libg++ etc.  */
              memcpy (d, "plus", 4);
              d += 3;
            }
            s++;
            idx++;
          }
          else
            *d = '_';
        }
        else
          *d = *s;
        if (*s == '/') {
          idx = 0;
          dot_idx = -1;
        }
        else
          idx++;
      }
    
      *d = '\0';
      return dos_name;
    }
    
    char *
    rename_if_dos_device_name (char *file_name)
    {
      /* We could have a file whose name is a device on MS-DOS.  Trying to
       * retrieve such a file would fail at best and wedge us at worst.  We need
       * to rename such files. */
      char *base;
      struct stat st_buf;
      char fname[PATH_MAX];
    
      strcpy (fname, file_name);
      base = basename (fname);
      if (((stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
        size_t blen = strlen (base);
    
        /* Prepend a '_'.  */
        memmove (base + 1, base, blen + 1);
        base[0] = '_';
        strcpy (file_name, fname);
      }
      return file_name;
    }
    
    #endif /* __DJGPP__ */