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); } } }
void factor_vm::primitive_fflush() { FILE* file = pop_file_handle(); safe_fflush(file); }