From 756323ca14eab46141fdf14d62b3b3d2aaa5672d Mon Sep 17 00:00:00 2001 From: Wichert Akkerman Date: Sun, 17 Dec 2000 16:37:04 +0000 Subject: [PATCH] More Adam stuff: + lib/mlib.c, include/dpkg.h.in: make do_fd_copy even more modular + dpkg-deb/{build.c,extract.c,info.c}, lib/showcright.c, main/{enquiry.c,filesdb.c}: updated for new do_fd_copy routines + main/{archives,[ch],main/processarc.c}: use fds instead of streams so we don't mix fd and stream-based IO which can cause havoc --- ChangeLog | 6 ++++ dpkg-deb/build.c | 6 ++-- dpkg-deb/extract.c | 2 +- dpkg-deb/info.c | 2 +- include/dpkg.h.in | 54 ++++++++++++++++++++++++------ lib/mlib.c | 83 ++++++++++++++++++++++++++++++++-------------- lib/showcright.c | 2 +- main/archives.c | 43 +++++------------------- main/archives.h | 2 +- main/enquiry.c | 2 +- main/filesdb.c | 4 +-- main/processarc.c | 14 +++----- 12 files changed, 131 insertions(+), 89 deletions(-) diff --git a/ChangeLog b/ChangeLog index de8547af..dd5c8429 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,6 +1,12 @@ Sun Dec 17 13:34:06 CET 2000 Wichert Akkerman * debian/control: fix typo in Build-Depends and add zlib1g-dev + * More Adam stuff: + + lib/mlib.c, include/dpkg.h.in: make do_fd_copy even more modular + + dpkg-deb/{build.c,extract.c,info.c}, lib/showcright.c, + main/{enquiry.c,filesdb.c}: updated for new do_fd_copy routines + + main/{archives,[ch],main/processarc.c}: use fds instead of streams + so we don't mix fd and stream-based IO which can cause havoc Wed Dec 13 16:48:47 CET 2000 Wichert Akkerman diff --git a/dpkg-deb/build.c b/dpkg-deb/build.c index 693a5109..be0e8532 100644 --- a/dpkg-deb/build.c +++ b/dpkg-deb/build.c @@ -161,7 +161,7 @@ int internalGzip(int fd1, int fd2, const char *compression, char *desc, ...) { if(compression != NULL) if(*compression == '0') { - do_fd_copy(0, 1, -1, _("%s: no compression copy loop"), v.buf); + fd_fd_copy(0, 1, -1, _("%s: no compression copy loop"), v.buf); exit(0); } #ifdef USE_ZLIB @@ -416,7 +416,7 @@ void do_build(const char *const *argv) { } if (lseek(gzfd,0,SEEK_SET)) ohshite(_("failed to rewind tmpfile (control)")); - do_fd_copy(gzfd, fileno(ar), -1, _("control")); + fd_fd_copy(gzfd, fileno(ar), -1, _("control")); /* Control is done, now we need to archive the data. Start by creating * a new temporary file. Immediately unlink the temporary file so others @@ -500,7 +500,7 @@ void do_build(const char *const *argv) { werr(debar); if (lseek(gzfd,0,SEEK_SET)) ohshite(_("failed to rewind tmpfile (data)")); - do_fd_copy(gzfd, fileno(ar), -1, _("cat (data)")); + fd_fd_copy(gzfd, fileno(ar), -1, _("cat (data)")); if (datastab.st_size & 1) if (putc('\n',ar) == EOF) diff --git a/dpkg-deb/extract.c b/dpkg-deb/extract.c index 58d6416a..b6df1075 100644 --- a/dpkg-deb/extract.c +++ b/dpkg-deb/extract.c @@ -254,7 +254,7 @@ void extracthalf(const char *debar, const char *directory, m_pipe(p1); if (!(c1= m_fork())) { close(p1[0]); - do_fd_copy(fileno(ar), p1[1], memberlen, _("failed to write to pipe in copy")); + 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); } diff --git a/dpkg-deb/info.c b/dpkg-deb/info.c index 324009f6..5c8b6ac2 100644 --- a/dpkg-deb/info.c +++ b/dpkg-deb/info.c @@ -90,7 +90,7 @@ static void info_spew(const char *debar, const char *directory, while ((component= *argv++) != 0) { co= fopen(component,"r"); if (co) { - do_fd_copy(fileno(co), 1, -1, _("info_spew")); + stream_fd_copy(co, 1, -1, _("info_spew")); } else if (errno == ENOENT) { if (fprintf(stderr, _("dpkg-deb: `%.255s' contains no control component `%.255s'\n"), debar, component) == EOF) werr("stderr"); diff --git a/include/dpkg.h.in b/include/dpkg.h.in index 45a1b86b..8c31a213 100644 --- a/include/dpkg.h.in +++ b/include/dpkg.h.in @@ -197,16 +197,50 @@ void m_pipe(int fds[2]); void checksubprocerr(int status, const char *description, int sigpipeok); void waitsubproc(pid_t pid, const char *description, int sigpipeok); -#define FD_WRITE_BUF 0 -#define FD_WRITE_VBUF 1 -#define FD_WRITE_FD 2 - -typedef void (*do_fd_write_t)(char *, int, void *, char *); -#define do_fd_copy(fd1, fd2, limit, desc...) read_fd_combined(fd1, (void*)fd2, FD_WRITE_FD, limit, desc) -#define read_fd_buf(fd1, buf, limit, desc...) read_fd_combined(fd1, buf, FD_WRITE_BUF, limit, desc) -#define read_fd_vbuf(fd1, buf, limit, desc...) read_fd_combined(fd1, buf, FD_WRITE_VBUF, limit, desc) -int read_fd_combined(int fd, void *buf, int type, int limit, char *desc, ...); -int do_fd_read(int fd1, int limit, do_fd_write_t write_proc, void *proc_data, char *desc); +#define BUFFER_WRITE_BUF 0 +#define BUFFER_WRITE_VBUF 1 +#define BUFFER_WRITE_FD 2 +#define BUFFER_WRITE_NULL 3 +#define BUFFER_WRITE_STREAM 4 +#define BUFFER_READ_FD 0 +#define BUFFER_READ_STREAM 1 + +typedef struct buffer_data *buffer_data_t; +typedef long (*buffer_proc_t)(buffer_data_t data, void *buf, long size, char *desc); +struct buffer_data { + buffer_proc_t proc; + void *data; + int type; +}; + +#define fd_fd_copy(fd1, fd2, limit, desc...)\ + buffer_copy_setup((void *)fd1, BUFFER_READ_FD, NULL, \ + (void *)fd2, BUFFER_WRITE_FD, NULL, \ + limit, desc) +#define fd_buf_copy(fd, buf, limit, desc...)\ + buffer_copy_setup((void *)fd, BUFFER_READ_FD, NULL, \ + buf, BUFFER_WRITE_BUF, NULL, \ + limit, desc) +#define fd_vbuf_copy(fd, buf, limit, desc...)\ + buffer_copy_setup((void *)fd, BUFFER_READ_FD, NULL, \ + buf, BUFFER_WRITE_VBUF, NULL, \ + limit, desc) +#define fd_null_copy(fd, limit, desc...)\ + buffer_copy_setup((void *)fd, BUFFER_READ_FD, NULL, \ + NULL, BUFFER_WRITE_NULL, NULL, \ + limit, desc) +#define stream_null_copy(file, limit, desc...)\ + buffer_copy_setup((void *)file, BUFFER_READ_STREAM, NULL, \ + NULL, BUFFER_WRITE_NULL, NULL, \ + limit, desc) +#define stream_fd_copy(file, fd, limit, desc...)\ + buffer_copy_setup((void *)file, BUFFER_READ_STREAM, NULL, \ + (void *)fd, BUFFER_WRITE_FD, NULL, \ + limit, desc) +long buffer_copy_setup(void *argIn, int typeIn, void *procIn, + void *argOut, int typeOut, void *procOut, + long limit, char *desc, ...); +long buffer_copy(buffer_data_t read_data, buffer_data_t write_data, long limit, char *desc); extern volatile int onerr_abort; diff --git a/lib/mlib.c b/lib/mlib.c index d527cdba..0318eb28 100644 --- a/lib/mlib.c +++ b/lib/mlib.c @@ -124,33 +124,61 @@ void waitsubproc(pid_t pid, const char *description, int sigpipeok) { checksubprocerr(status,description,sigpipeok); } -typedef struct do_fd_buf_data { - void *buf; - int type; -} do_fd_buf_data_t; - -void do_fd_write_combined(char *buf, int length, void *proc_data, char *desc) { - do_fd_buf_data_t *data = (do_fd_buf_data_t *)proc_data; +long buffer_write(buffer_data_t data, void *buf, long length, char *desc) { + long ret= length; switch(data->type) { - case FD_WRITE_BUF: - memcpy(data->buf, buf, length); - data->buf += length; + case BUFFER_WRITE_BUF: + memcpy(data->data, buf, length); + data->data += length; + break; + case BUFFER_WRITE_VBUF: + varbufaddbuf((struct varbuf *)data->data, buf, length); + break; + case BUFFER_WRITE_FD: + if((ret= write((int)data->data, buf, length)) < 0) + ohshite(_("failed in buffer_write(fd) (%i, ret=%i, %s)"), (int)data->data, ret, desc); + break; + case BUFFER_WRITE_NULL: + break; + case BUFFER_WRITE_STREAM: + ret= fwrite(buf, 1, length, (FILE *)data->data); + if(feof((FILE *)data->data)) + ohshite(_("eof in buffer_write(stream): %s"), desc); + if(ferror((FILE *)data->data)) + ohshite(_("error in buffer_write(stream): %s"), desc); break; - case FD_WRITE_VBUF: - varbufaddbuf((struct varbuf *)data->buf, buf, length); - data->buf += length; + default: + fprintf(stderr, _("unknown data type `%i' in buffer_write\n"), data->type); + } + return ret; +} + +long buffer_read(buffer_data_t data, void *buf, long length, char *desc) { + long ret= length; + switch(data->type) { + case BUFFER_READ_FD: + if((ret= read((int)data->data, buf, length)) < 0) + ohshite(_("failed in buffer_read(fd): %s"), desc); break; - case FD_WRITE_FD: - if(write((int)data->buf, buf, length) < length) - ohshite(_("failed in do_fd_write_combined (%i, %s)"), FD_WRITE_FD, desc); + case BUFFER_READ_STREAM: + ret= fread(buf, 1, length, (FILE *)data->data); + if(feof((FILE *)data->data)) + ohshite(_("eof in buffer_read(stream): %s"), desc); + if(ferror((FILE *)data->data)) + ohshite(_("error in buffer_read(stream): %s"), desc); break; default: - fprintf(stderr, _("unknown data type `%i' in do_fd_write_buf\n"), data->type); + fprintf(stderr, _("unknown data type `%i' in buffer_read\n"), data->type); } + return ret; } -int read_fd_combined(int fd, void *buf, int type, int limit, char *desc, ...) { - do_fd_buf_data_t data = { buf, type }; +long buffer_copy_setup(void *argIn, int typeIn, void *procIn, + void *argOut, int typeOut, void *procOut, + long limit, char *desc, ...) +{ + struct buffer_data read_data = { procIn, argIn, typeIn }, + write_data = { procOut, argOut, typeOut }; va_list al; struct varbuf v; int ret; @@ -161,22 +189,27 @@ int read_fd_combined(int fd, void *buf, int type, int limit, char *desc, ...) { varbufvprintf(&v, desc, al); va_end(al); - ret = do_fd_read(fd, limit, do_fd_write_combined, &data, v.buf); + if ( procIn == NULL ) + read_data.proc = buffer_read; + if ( procOut == NULL ) + write_data.proc = buffer_write; + ret = buffer_copy(&read_data, &write_data, limit, v.buf); varbuffree(&v); return ret; } -int do_fd_read(int fd1, int limit, do_fd_write_t write_proc, void *proc_data, char *desc) { +long buffer_copy(buffer_data_t read_data, buffer_data_t write_data, long limit, char *desc) { char *buf; - int count, bufsize= 32768, bytesread= 0; + int count, bufsize= 32768; + long bytesread= 0; if((limit != -1) && (limit < bufsize)) bufsize= limit; buf= malloc(bufsize); if(buf== NULL) ohshite(_("failed to allocate buffer in do_fd_read (%s)"), desc); - while(1) { - count= read(fd1, buf, bufsize); + while(bufsize) { + count= read_data->proc(read_data, buf, bufsize, desc); if (count<0) { if (errno==EINTR) continue; break; @@ -185,7 +218,7 @@ int do_fd_read(int fd1, int limit, do_fd_write_t write_proc, void *proc_data, ch break; bytesread+= count; - write_proc(buf, count, proc_data, desc); + write_data->proc(write_data, buf, count, desc); if(limit!=-1) { limit-= count; if(limitbackendpipe); - if (r != len && ferror(tc->backendpipe)) + if ((r= read(tc->backendpipe,buf,len)) == -1) ohshite(_("error reading from dpkg-deb pipe")); return r; } @@ -223,7 +217,7 @@ int tarobject(struct TarInfo *ti) { int statr, fd, r, i, existingdirectory; struct stat stab, stabd; size_t sz, wsz; - FILE *thefile; + int thefile; char databuf[TARBLKSZ]; struct fileinlist *nifd; struct pkginfo *divpkg, *otherpkg; @@ -398,26 +392,13 @@ int tarobject(struct TarInfo *ti) { * it until we apply the proper mode, which might be a statoverride. */ fd= open(fnamenewvb.buf, (O_CREAT|O_EXCL|O_WRONLY), 0); - if (fd < 0) ohshite("unable to create `%.255s'",ti->Name); - thefile= fdopen(fd,"w"); - if (!thefile) { close(fd); ohshite(_("unable to fdopen for `%.255s'"),ti->Name); } - push_cleanup(cu_closefile,ehflag_bombout, 0,0, 1,(void*)thefile); + if (fd < 0) ohshite("unable to create 1 `%.255s'",ti->Name); + push_cleanup(cu_closefd,ehflag_bombout, 0,0, 1,(void*)fd); debug(dbg_eachfiledetail,"tarobject NormalFile[01] open size=%lu", (unsigned long)ti->Size); - for (sz= ti->Size; sz > 0; sz -= wsz) { - wsz= sz > TARBLKSZ ? TARBLKSZ : sz; - r= fread(databuf,1,TARBLKSZ,tc->backendpipe); - if (rbackendpipe)) { - ohshite(_("error reading dpkg-deb during `%.255s'"),ti->Name); - } else { - errno= 0; - return -1; - } - } - if (fwrite(databuf,1,wsz,thefile) != wsz) - ohshite(_("error writing to `%.255s'"),ti->Name); - } + fd_fd_copy(tc->backendpipe, fd, ti->Size, _("backend dpkg-deb during `%.255s'"),ti->Name); + r= ti->Size % TARBLKSZ; + if (r > 0) r= read(tc->backendpipe,databuf,TARBLKSZ - r); if (nifd->namenode->statoverride) debug(dbg_eachfile, _("tarobject ... stat override, uid=%d, gid=%d, mode=%04o"), nifd->namenode->statoverride->uid, @@ -427,17 +408,11 @@ int tarobject(struct TarInfo *ti) { nifd->namenode->statoverride ? nifd->namenode->statoverride->uid : ti->UserID, nifd->namenode->statoverride ? nifd->namenode->statoverride->gid : ti->GroupID)) ohshite(_("error setting ownership of `%.255s'"),ti->Name); - /* We flush the stream here to avoid any future - * writes, which will mask any setuid or setgid - * attemps by fchmod below. - */ - if (fflush(thefile) == EOF) - ohshite(_("error flushing `%.255s'"),ti->Name); am=(nifd->namenode->statoverride ? nifd->namenode->statoverride->mode : ti->Mode) & ~S_IFMT; if (fchmod(fd,am)) ohshite(_("error setting permissions of `%.255s'"),ti->Name); - pop_cleanup(ehflag_normaltidy); /* thefile= fdopen(fd) */ - if (fclose(thefile)) + pop_cleanup(ehflag_normaltidy); /* fd= open(fnamenewvb.buf) */ + if (close(fd)) ohshite(_("error closing/writing `%.255s'"),ti->Name); newtarobject_utime(fnamenewvb.buf,ti); break; diff --git a/main/archives.h b/main/archives.h index a8464264..65f85c2b 100644 --- a/main/archives.h +++ b/main/archives.h @@ -23,7 +23,7 @@ #define ARCHIVES_H struct tarcontext { - FILE *backendpipe; + int backendpipe; struct pkginfo *pkg; struct fileinlist **newfilesp; }; diff --git a/main/enquiry.c b/main/enquiry.c index 0575ac72..b3476419 100644 --- a/main/enquiry.c +++ b/main/enquiry.c @@ -697,7 +697,7 @@ void printarch(const char *const *argv) { exit(0); } close(p1[1]); - read_fd_vbuf(fileno(ccpipe), &vb, -1, _("error reading from CC pipe")); + fd_vbuf_copy(fileno(ccpipe), &vb, -1, _("error reading from CC pipe")); waitsubproc(c1,"gcc --print-libgcc-file-name",0); if (!vb.used) badlgccfn(ccompiler,"",_("empty output")); varbufaddc(&vb,0); diff --git a/main/filesdb.c b/main/filesdb.c index 02544c92..49147619 100644 --- a/main/filesdb.c +++ b/main/filesdb.c @@ -147,7 +147,7 @@ void ensure_packagefiles_available(struct pkginfo *pkg) { loaded_list = nfmalloc(stat_buf.st_size); loaded_list_end = loaded_list + stat_buf.st_size; - read_fd_buf(fileno(file), loaded_list, stat_buf.st_size, _("files list for package `%.250s'"), pkg->name); + fd_buf_copy(fileno(file), loaded_list, stat_buf.st_size, _("files list for package `%.250s'"), pkg->name); lendp= &pkg->clientdata->files; thisline = loaded_list; @@ -346,7 +346,7 @@ void ensure_statoverrides(void) { loaded_list = nfmalloc(stab2.st_size); loaded_list_end = loaded_list + stab2.st_size; - read_fd_buf(fileno(file), loaded_list, stab2.st_size, _("statoverride file `%.250s'"), vb.buf); + fd_buf_copy(fileno(file), loaded_list, stab2.st_size, _("statoverride file `%.250s'"), vb.buf); thisline = loaded_list; while (thisline