Ejemplo n.º 1
0
void do_auto(const char *const *argv) {
    const char *partfile;
    struct partinfo *pi, *refi, *npi, **partlist, *otherthispart;
    struct partqueue *pq;
    unsigned int i;
    int j, ap;
    long nr;
    FILE *part;
    void *buffer;
    char *p, *q;

    if (!opt_outputfile)
        badusage(_("--auto requires the use of the --output option"));
    if (!(partfile= *argv++) || *argv)
        badusage(_("--auto requires exactly one part file argument"));

    refi= nfmalloc(sizeof(struct partqueue));
    part= fopen(partfile,"r");
    if (!part) ohshite(_("unable to read part file `%.250s'"),partfile);
    if (!read_info(part,partfile,refi)) {
        if (!opt_npquiet)
            printf(_("File `%.250s' is not part of a multipart archive.\n"),partfile);
        m_output(stdout, _("<standard output>"));
        exit(1);
    }
    fclose(part);
    scandepot();
    partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn);
    for (i = 0; i < refi->maxpartn; i++)
        partlist[i] = NULL;
    for (pq= queue; pq; pq= pq->nextinqueue) {
        pi= &pq->info;
        if (!partmatches(pi,refi)) continue;
        npi= nfmalloc(sizeof(struct partinfo));
        mustgetpartinfo(pi->filename,npi);
        addtopartlist(partlist,npi,refi);
    }
    /* If we already have a copy of this version we ignore it and prefer the
     * new one, but we still want to delete the one in the depot, so we
     * save its partinfo (with the filename) for later. This also prevents
     * us from accidentally deleting the source file. */
    otherthispart= partlist[refi->thispartn-1];
    partlist[refi->thispartn-1]= refi;
    for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--);

    if (j>=0) {

        part= fopen(partfile,"r");
        if (!part) ohshite(_("unable to reopen part file `%.250s'"),partfile);
        buffer= nfmalloc(refi->filesize);
        nr= fread(buffer,1,refi->filesize,part);
        if (nr != refi->filesize) rerreof(part,partfile);
        if (getc(part) != EOF) ohshit(_("part file `%.250s' has trailing garbage"),partfile);
        if (ferror(part)) rerr(partfile);
        fclose(part);
        p = nfmalloc(strlen(opt_depotdir) + 50);
        q = nfmalloc(strlen(opt_depotdir) + 200);
        sprintf(p, "%st.%lx", opt_depotdir, (long)getpid());
        sprintf(q, "%s%s.%lx.%x.%x", opt_depotdir, refi->md5sum,
                refi->maxpartlen,refi->thispartn,refi->maxpartn);
        part= fopen(p,"w");
        if (!part) ohshite(_("unable to open new depot file `%.250s'"),p);
        nr= fwrite(buffer,1,refi->filesize,part);
        if (nr != refi->filesize) werr(p);
        if (fflush(part))
            ohshite(_("unable to flush file '%s'"), p);
        if (fsync(fileno(part)))
            ohshite(_("unable to sync file '%s'"), p);
        if (fclose(part)) werr(p);
        if (rename(p,q)) ohshite(_("unable to rename new depot file `%.250s' to `%.250s'"),p,q);

        printf(_("Part %d of package %s filed (still want "),refi->thispartn,refi->package);
        /* There are still some parts missing. */
        for (i=0, ap=0; i<refi->maxpartn; i++)
            if (!partlist[i])
                printf("%s%d", !ap++ ? "" : i == (unsigned int)j ? _(" and ") : ", ", i + 1);
        printf(").\n");

        dir_sync_path(opt_depotdir);
    } else {

        /* We have all the parts. */
        reassemble(partlist, opt_outputfile);

        /* OK, delete all the parts (except the new one, which we never copied). */
        partlist[refi->thispartn-1]= otherthispart;
        for (i=0; i<refi->maxpartn; i++)
            if (partlist[i])
                if (unlink(partlist[i]->filename))
                    ohshite(_("unable to delete used-up depot file `%.250s'"),partlist[i]->filename);

    }

    m_output(stderr, _("<standard error>"));
}
Ejemplo n.º 2
0
int
do_auto(const char *const *argv)
{
  const char *partfile;
  struct partinfo *refi, **partlist, *otherthispart;
  struct partqueue *pq;
  unsigned int i;
  int j;
  FILE *part;

  if (!opt_outputfile)
    badusage(_("--auto requires the use of the --output option"));
  if (!(partfile= *argv++) || *argv)
    badusage(_("--auto requires exactly one part file argument"));

  refi= nfmalloc(sizeof(struct partqueue));
  part= fopen(partfile,"r");
  if (!part) ohshite(_("unable to read part file `%.250s'"),partfile);
  if (!read_info(part,partfile,refi)) {
    if (!opt_npquiet)
      printf(_("File `%.250s' is not part of a multipart archive.\n"),partfile);
    m_output(stdout, _("<standard output>"));
    return 1;
  }
  fclose(part);
  scandepot();
  partlist= nfmalloc(sizeof(struct partinfo*)*refi->maxpartn);
  for (i = 0; i < refi->maxpartn; i++)
    partlist[i] = NULL;
  for (pq= queue; pq; pq= pq->nextinqueue) {
    struct partinfo *npi, *pi = &pq->info;

    if (!partmatches(pi,refi)) continue;
    npi= nfmalloc(sizeof(struct partinfo));
    mustgetpartinfo(pi->filename,npi);
    addtopartlist(partlist,npi,refi);
  }
  /* If we already have a copy of this version we ignore it and prefer the
   * new one, but we still want to delete the one in the depot, so we
   * save its partinfo (with the filename) for later. This also prevents
   * us from accidentally deleting the source file. */
  otherthispart= partlist[refi->thispartn-1];
  partlist[refi->thispartn-1]= refi;
  for (j=refi->maxpartn-1; j>=0 && partlist[j]; j--);

  if (j>=0) {
    int fd_src, fd_dst;
    int ap;
    char *p, *q;

    m_asprintf(&p, "%st.%lx", opt_depotdir, (long)getpid());
    m_asprintf(&q, "%s%s.%jx.%x.%x", opt_depotdir, refi->md5sum,
               (intmax_t)refi->maxpartlen, refi->thispartn, refi->maxpartn);

    fd_src = open(partfile, O_RDONLY);
    if (fd_src < 0)
      ohshite(_("unable to reopen part file `%.250s'"), partfile);
    fd_dst = creat(p, 0644);
    if (fd_dst < 0)
      ohshite(_("unable to open new depot file `%.250s'"), p);

    fd_fd_copy(fd_src, fd_dst, refi->filesize, _("extracting split part"));

    if (fsync(fd_dst))
      ohshite(_("unable to sync file '%s'"), p);
    if (close(fd_dst))
      ohshite(_("unable to close file '%s'"), p);
    close(fd_src);

    if (rename(p,q)) ohshite(_("unable to rename new depot file `%.250s' to `%.250s'"),p,q);
    free(q);
    free(p);

    printf(_("Part %d of package %s filed (still want "),refi->thispartn,refi->package);
    /* There are still some parts missing. */
    for (i=0, ap=0; i<refi->maxpartn; i++)
      if (!partlist[i])
        printf("%s%d", !ap++ ? "" : i == (unsigned int)j ? _(" and ") : ", ", i + 1);
    printf(").\n");

    dir_sync_path(opt_depotdir);
  } else {

    /* We have all the parts. */
    reassemble(partlist, opt_outputfile);

    /* OK, delete all the parts (except the new one, which we never copied). */
    partlist[refi->thispartn-1]= otherthispart;
    for (i=0; i<refi->maxpartn; i++)
      if (partlist[i])
        if (unlink(partlist[i]->filename))
          ohshite(_("unable to delete used-up depot file `%.250s'"),partlist[i]->filename);

  }

  m_output(stderr, _("<standard error>"));

  return 0;
}