Exemplo n.º 1
0
/**
 * Get file mode from external attributes.
 */
void FileNode::processExternalAttributes () {
    zip_uint8_t opsys;
    zip_uint32_t attr;
    assert(id >= 0);
    assert (zip != NULL);
    zip_file_get_external_attributes(zip, id, 0, &opsys, &attr);
    switch (opsys) {
        case ZIP_OPSYS_UNIX: {
            m_mode = attr >> 16;
            // force is_dir value
            if (is_dir) {
                m_mode = (m_mode & ~S_IFMT) | S_IFDIR;
            } else {
                m_mode = m_mode & ~S_IFDIR;
            }
            break;
        }
        case ZIP_OPSYS_DOS:
        case ZIP_OPSYS_WINDOWS_NTFS:
        case ZIP_OPSYS_MVS: {
            /*
             * Both WINDOWS_NTFS and OPSYS_MVS used here because of
             * difference in constant assignment by PKWARE and Info-ZIP
             */
            m_mode = 0444;
            // http://msdn.microsoft.com/en-us/library/windows/desktop/gg258117%28v=vs.85%29.aspx
            // http://en.wikipedia.org/wiki/File_Allocation_Table#attributes
            // FILE_ATTRIBUTE_READONLY
            if ((attr & 1) == 0) {
                m_mode |= 0220;
            }
            // directory
            if (is_dir) {
                m_mode |= S_IFDIR | 0111;
            } else {
                m_mode |= S_IFREG;
            }

            break;
        }
        default: {
            if (is_dir) {
                m_mode = S_IFDIR | 0775;
            } else {
                m_mode = S_IFREG | 0664;
            }
        }
    }
}
Exemplo n.º 2
0
struct input_file *read_file_list (int argc, char **argv,
                                   int *nf_r, char *errstr) {
  struct input_file *list = (struct input_file *) NULL;

  FILE *fp = (FILE *) NULL;
  char line[16384], *av, *p, *s;

  int a, f, nf = 0;

#ifndef _WIN32
  glob_t gbuf;
  int rv, op;

  /* Init */
  gbuf.gl_pathv = (char **) NULL;
#endif

  int is_zip;

#ifdef ZIPSUPPORT
  zip_t *z = (zip_t *) NULL;
  zip_error_t ze;
  struct zip_stat sb;

  int zerrno;
  int ent, nent;
  const char *name;
  int namelen;

  zip_uint8_t opsys;
  zip_uint32_t extattr;
#endif

  /* Loop over arguments */
  for(a = 0; a < argc; a++) {
    av = argv[a];

    if(*av == '@') {  /* @list form */
      av++;  /* skip past the @ */

      is_zip = is_zip_file(av, errstr);
      if(is_zip < 0)
        goto error;

      if(is_zip) {
#ifdef ZIPSUPPORT
        z = zip_open(av, 0, &zerrno);
        if(!z) {
          zip_error_init_with_code(&ze, zerrno);
          report_err(errstr, "zip_open: %s: %s",
                     av, zip_error_strerror(&ze));
          zip_error_fini(&ze);
          goto error;
        }
        
        nent = zip_get_num_entries(z, 0);
        if(nent < 0) {
          report_err(errstr, "zip_get_num_entries: %s",
                     zip_strerror(z));
          goto error;
        }
        
        for(ent = 0; ent < nent; ent++) {
          if(zip_stat_index(z, ent, 0, &sb)) {
            report_err(errstr, "zip_stat_index(%d): %s\n",
                       ent, zip_strerror(z));
            goto error;
          }
          
          if(zip_file_get_external_attributes(z, ent, 0, &opsys, &extattr)) {
            report_err(errstr, "zip_get_external_attributes(%d): %s\n",
                       ent, zip_strerror(z));
            goto error;
          }
          
          name = sb.name;
          namelen = strlen(name);
          
          if((opsys != ZIP_OPSYS_AMIGA && extattr & 0x10) ||
             (namelen > 0 && name[namelen-1] == '/'))
            /* Is directory */
            continue;
          
          /* Otherwise, add to list */
          list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
          if(!list) {
            report_syserr(errstr, "realloc");
            goto error;
          }
          
          s = strdup(name);
          if(!s) {
            report_syserr(errstr, "strdup");
            goto error;
          }
          
          list[nf].filename = s;
          list[nf].ient = ent;
          list[nf].iarg = a;
          list[nf].arg = av;
          nf++;
        }
        
        if(zip_close(z)) {
          report_err(errstr, "zip_close: %s",
                     zip_strerror(z));
          goto error;
        }

        z = (zip_t *) NULL;
#else
        report_err(errstr, "not compiled with zip support");
        goto error;
#endif
      }
      else {
        fp = fopen(av, "r");
        if(!fp) {
          report_syserr(errstr, "open: %s", av);
          goto error;
        }
        
        while(fgets(line, sizeof(line), fp)) {
          p = sstrip(line);
          
          if(*p) {
            list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
            if(!list) {
              report_syserr(errstr, "realloc");
              goto error;
            }
            
            s = strdup(p);
            if(!s) {
              report_syserr(errstr, "strdup");
              goto error;
            }
            
            list[nf].filename = s;
            list[nf].ient = -1;
            list[nf].iarg = a;
            list[nf].arg = av;
            nf++;
          }
        }
        
        if(ferror(fp)) {
          report_syserr(errstr, "read: %s", av);
          goto error;
        }
        
        fclose(fp);
        fp = (FILE *) NULL;
      }
    }
    else {  /* glob or single filename */
#ifndef _WIN32
      rv = glob(av, 0, NULL, &gbuf);
      if(rv == 0) {  /* succeeded */
        /* Allocate block */
        list = (struct input_file *) realloc(list,
                                             (nf+gbuf.gl_pathc) * sizeof(struct input_file));
        if(!list) {
          report_syserr(errstr, "realloc");
          goto error;
        }

        /* Zero out the new pointers */
        memset(list+nf, 0, gbuf.gl_pathc * sizeof(struct input_file));

        /* Record so we know to free them */
        op = nf;

        nf += gbuf.gl_pathc;
        
        for(f = 0; f < gbuf.gl_pathc; f++) {
          s = strdup(gbuf.gl_pathv[f]);
          if(!s) {
            report_syserr(errstr, "strdup");
            goto error;
          }

          list[op].filename = s;
          list[op].ient = -1;
          list[op].iarg = a;
          list[op].arg = av;
          op++;
        }

        globfree(&gbuf);
        gbuf.gl_pathv = (char **) NULL;
      }
      else if(rv == GLOB_NOMATCH) {  /* no match */
#endif  /* _WIN32 */

        /* Assume it's a single entry. */
        list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file));
        if(!list) {
          report_syserr(errstr, "realloc");
          goto error;
        }
        
        s = strdup(av);
        if(!s) {
          report_syserr(errstr, "strdup");
          goto error;
        }
        
        list[nf].filename = s;
        list[nf].ient = -1;
        list[nf].iarg = a;
        list[nf].arg = av;
        nf++;
#ifndef _WIN32
      }
      else {
        report_err(errstr, "glob error: %s", av);
        goto error;
      }
#endif
    }
  }

  *nf_r = nf;

  return(list);

 error:
  if(fp)
    fclose(fp);

#ifndef _WIN32
  if(gbuf.gl_pathv)
    globfree(&gbuf);
#endif

#ifdef ZIPSUPPORT
  if(z) {
    zip_close(z);
    z = (zip_t *) NULL;
  }
#endif

  if(list) {
    for(f = 0; f < nf; f++)
      if(list[f].filename)
        free((void *) list[f].filename);

    free((void *) list);
  }

  return((struct input_file *) NULL);
}