Пример #1
0
void extracthalf(const char *debar, const char *directory,
                 const char *taroption, int admininfo) {
  char versionbuf[40];
  float versionnum;
  char ctrllenbuf[40], *infobuf;
  size_t ctrllennum, memberlen= 0;
  int dummy, l= 0;
  pid_t c1=0,c2,c3;
  void *ctrlarea = NULL;
  int p1[2], p2[2];
  FILE *ar, *pi;
  struct stat stab;
  char nlc;
  char *cur;
  struct ar_hdr arh;
  int readfromfd, oldformat= 0, header_done, adminmember;
  enum compress_type compress_type = compress_type_gzip;
  
  ar= fopen(debar,"r"); if (!ar) ohshite(_("failed to read archive `%.255s'"),debar);
  if (fstat(fileno(ar),&stab)) ohshite(_("failed to fstat archive"));
  if (!fgets(versionbuf,sizeof(versionbuf),ar)) readfail(ar,debar,_("version number"));

  if (!strcmp(versionbuf,"!<arch>\n")) {
    oldformat= 0;

    ctrllennum= 0;
    header_done= 0;
    for (;;) {
      if (fread(&arh,1,sizeof(arh),ar) != sizeof(arh))
        readfail(ar,debar,_("between members"));
      if (memcmp(arh.ar_fmag,ARFMAG,sizeof(arh.ar_fmag)))
        ohshit(_("file `%.250s' is corrupt - bad magic at end of first header"),debar);
      memberlen= parseheaderlength(arh.ar_size,sizeof(arh.ar_size),
                                   debar, _("member length"));
      if (!header_done) {
        if (memcmp(arh.ar_name,"debian-binary   ",sizeof(arh.ar_name)) &&
	    memcmp(arh.ar_name,"debian-binary/   ",sizeof(arh.ar_name)))
          ohshit(_("file `%.250s' is not a debian binary archive (try dpkg-split?)"),debar);
        infobuf= m_malloc(memberlen+1);
        if (fread(infobuf,1, memberlen + (memberlen&1), ar) != memberlen + (memberlen&1))
          readfail(ar,debar,_("header info member"));
        infobuf[memberlen] = '\0';
        cur= strchr(infobuf,'\n');
        if (!cur) ohshit(_("archive has no newlines in header"));
        *cur = '\0';
        cur= strchr(infobuf,'.');
        if (!cur) ohshit(_("archive has no dot in version number"));
        *cur = '\0';
        if (strcmp(infobuf,"2"))
          ohshit(_("archive version %.250s not understood, get newer dpkg-deb"), infobuf);
        *cur= '.';
        strncpy(versionbuf,infobuf,sizeof(versionbuf));
        versionbuf[sizeof(versionbuf) - 1] = '\0';
        header_done= 1;
      } else if (arh.ar_name[0] == '_') {
          /* Members with `_' are noncritical, and if we don't understand them
           * we skip them.
           */
	stream_null_copy(ar, memberlen + (memberlen&1),_("skipped member data from %s"), debar);
      } else {
        adminmember=
          (!memcmp(arh.ar_name,ADMINMEMBER,sizeof(arh.ar_name)) ||
	  !memcmp(arh.ar_name,ADMINMEMBER_COMPAT,sizeof(arh.ar_name))) ? 1 : -1;
	if (adminmember == -1) {
	  if (!memcmp(arh.ar_name,DATAMEMBER_GZ,sizeof(arh.ar_name)) ||
	      !memcmp(arh.ar_name,DATAMEMBER_COMPAT_GZ,sizeof(arh.ar_name))) {
	    adminmember= 0;
	    compress_type = compress_type_gzip;
	  } else if (!memcmp(arh.ar_name,DATAMEMBER_BZ2,sizeof(arh.ar_name)) ||
		     !memcmp(arh.ar_name,DATAMEMBER_COMPAT_BZ2,sizeof(arh.ar_name))) {
	    adminmember= 0;
	    compress_type = compress_type_bzip2;
	  } else if (!memcmp(arh.ar_name, DATAMEMBER_LZMA, sizeof(arh.ar_name)) ||
		     !memcmp(arh.ar_name, DATAMEMBER_COMPAT_LZMA, sizeof(arh.ar_name))) {
	    adminmember = 0;
	    compress_type = compress_type_lzma;
	  } else if (!memcmp(arh.ar_name,DATAMEMBER_CAT,sizeof(arh.ar_name)) ||
		     !memcmp(arh.ar_name,DATAMEMBER_COMPAT_CAT,sizeof(arh.ar_name))) {
	    adminmember= 0;
	    compress_type = compress_type_cat;
	  } else {
            ohshit(_("file `%.250s' contains ununderstood data member %.*s, giving up"),
                   debar, (int)sizeof(arh.ar_name), arh.ar_name);
	  }
        }
        if (adminmember == 1) {
          if (ctrllennum != 0)
            ohshit(_("file `%.250s' contains two control members, giving up"), debar);
          ctrllennum= memberlen;
        }
        if (!adminmember != !admininfo) {
	  stream_null_copy(ar, memberlen + (memberlen&1),_("skipped member data from %s"), debar);
        } else {
          break; /* Yes ! - found it. */
        }
      }
    }

    if (admininfo >= 2) {
      printf(_(" new debian package, version %s.\n"
               " size %ld bytes: control archive= %zi bytes.\n"),
             versionbuf, (long)stab.st_size, ctrllennum);
      m_output(stdout, _("<standard output>"));
    }
  } else if (!strncmp(versionbuf,"0.93",4) &&
             sscanf(versionbuf,"%f%c%d",&versionnum,&nlc,&dummy) == 2 &&
             nlc == '\n') {
    
    oldformat= 1;
    l = strlen(versionbuf);
    if (l && versionbuf[l - 1] == '\n')
      versionbuf[l - 1] = '\0';
    if (!fgets(ctrllenbuf,sizeof(ctrllenbuf),ar))
      readfail(ar, debar, _("control information length"));
    if (sscanf(ctrllenbuf,"%zi%c%d",&ctrllennum,&nlc,&dummy) !=2 || nlc != '\n')
      ohshit(_("archive has malformatted control length `%s'"), ctrllenbuf);

    if (admininfo >= 2) {
      printf(_(" old debian package, version %s.\n"
               " size %ld bytes: control archive= %zi, main archive= %ld.\n"),
             versionbuf, (long)stab.st_size, ctrllennum,
             (long) (stab.st_size - ctrllennum - strlen(ctrllenbuf) - l));
      m_output(stdout, _("<standard output>"));
    }

    ctrlarea = m_malloc(ctrllennum);

    errno=0; if (fread(ctrlarea,1,ctrllennum,ar) != ctrllennum)
      readfail(ar, debar, _("control area"));

  } else {
    
    if (!strncmp(versionbuf,"!<arch>",7)) {
      fprintf(stderr,
              _("dpkg-deb: file looks like it might be an archive which has been\n"
                "dpkg-deb:    corrupted by being downloaded in ASCII mode\n"));
    }

    ohshit(_("`%.255s' is not a debian format archive"),debar);

  }

  safe_fflush(ar);

  if (oldformat) {
    if (admininfo) {
      m_pipe(p1);
      if (!(c1= m_fork())) {
        close(p1[0]);
	pi = fdopen(p1[1], "w");
	if (!pi)
	  ohshite(_("failed to open pipe descriptor `1' in paste"));
        errno=0; if (fwrite(ctrlarea,1,ctrllennum,pi) != ctrllennum)
          ohshit(_("failed to write to gzip -dc"));
        if (fclose(pi)) ohshit(_("failed to close gzip -dc"));
        exit(0);
      }
      close(p1[1]);
      readfromfd= p1[0];
    } else {
      if (lseek(fileno(ar),l+strlen(ctrllenbuf)+ctrllennum,SEEK_SET) == -1)
        ohshite(_("failed to syscall lseek to files archive portion"));
      c1= -1;
      readfromfd= fileno(ar);
    }
  } else {
    m_pipe(p1);
    if (!(c1= m_fork())) {
      close(p1[0]);
      stream_fd_copy(ar, p1[1], memberlen, _("failed to write to pipe in copy"));
      if (close(p1[1]) == EOF) ohshite(_("failed to close pipe in copy"));
      exit(0);
    }
    close(p1[1]);
    readfromfd= p1[0];
  }
  
  if (taroption) m_pipe(p2);
  
  if (!(c2= m_fork())) {
    m_dup2(readfromfd,0);
    if (admininfo) close(p1[0]);
    if (taroption) { m_dup2(p2[1],1); close(p2[0]); close(p2[1]); }
    decompress_cat(compress_type, 0, 1, _("data"));
  }
  if (readfromfd != fileno(ar)) close(readfromfd);
  if (taroption) close(p2[1]);

  if (taroption && directory) {
    if (chdir(directory)) {
      if (errno == ENOENT) {
        if (mkdir(directory,0777)) ohshite(_("failed to create directory"));
        if (chdir(directory)) ohshite(_("failed to chdir to directory after creating it"));
      } else {
        ohshite(_("failed to chdir to directory"));
      }
    }
  }

  if (taroption) {
    if (!(c3= m_fork())) {
      char buffer[30+2];
      if (strlen(taroption) > 30)
        internerr("taroption is too long '%s'", taroption);
      strcpy(buffer, taroption);
      strcat(buffer, "f");
      m_dup2(p2[0],0);
      close(p2[0]);

      unsetenv("TAR_OPTIONS");

      execlp(TAR, "tar", buffer, "-", NULL);
      ohshite(_("failed to exec tar"));
    }
    close(p2[0]);
    waitsubproc(c3,"tar",0);
  }
  
  waitsubproc(c2, _("<decompress>"), PROCPIPE);
  if (c1 != -1)
    waitsubproc(c1, _("paste"), 0);
  if (oldformat && admininfo) {
    if (versionnum == 0.931F) {
      movecontrolfiles(OLDOLDDEBDIR);
    } else if (versionnum == 0.932F || versionnum == 0.933F) {
      movecontrolfiles(OLDDEBDIR);
    }
  }
}
Пример #2
0
void factor_vm::primitive_fflush() {
  FILE* file = pop_file_handle();
  safe_fflush(file);
}