Quellcode durchsuchen

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

Wichert Akkerman vor 25 Jahren
Ursprung
Commit
756323ca14
12 geänderte Dateien mit 131 neuen und 89 gelöschten Zeilen
  1. 6 0
      ChangeLog
  2. 3 3
      dpkg-deb/build.c
  3. 1 1
      dpkg-deb/extract.c
  4. 1 1
      dpkg-deb/info.c
  5. 44 10
      include/dpkg.h.in
  6. 58 25
      lib/mlib.c
  7. 1 1
      lib/showcright.c
  8. 9 34
      main/archives.c
  9. 1 1
      main/archives.h
  10. 1 1
      main/enquiry.c
  11. 2 2
      main/filesdb.c
  12. 4 10
      main/processarc.c

+ 6 - 0
ChangeLog

@@ -1,6 +1,12 @@
 Sun Dec 17 13:34:06 CET 2000 Wichert Akkerman <wakkerma@debian.org>
 
   * 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 <wakkerma@debian.org>
 

+ 3 - 3
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)

+ 1 - 1
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);
     }

+ 1 - 1
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");

+ 44 - 10
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;
 

+ 58 - 25
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(limit<bufsize)

+ 1 - 1
lib/showcright.c

@@ -29,6 +29,6 @@ void showcopyright(const struct cmdinfo *c, const char *v) {
   int fd;
   fd= open(COPYINGFILE,O_RDONLY);
   if (fd < 0) ohshite(_("cannot open GPL file "));
-  do_fd_copy(fd, 1, -1, "showcopyright");
+  fd_fd_copy(fd, 1, -1, "showcopyright");
   exit(0);
 }

+ 9 - 34
main/archives.c

@@ -115,16 +115,10 @@ void cu_pathname(int argc, void **argv) {
   ensure_pathname_nonexisting((char*)(argv[0]));
 } 
 
-void cu_backendpipe(int argc, void **argv) {
-  FILE *f= *(FILE**)argv[0];
-  if (f) fclose(f);
-} 
-
 int tarfileread(void *ud, char *buf, int len) {
   struct tarcontext *tc= (struct tarcontext*)ud;
   int r;
-  r= fread(buf,1,len,tc->backendpipe);
-  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 (r<TARBLKSZ) {
-        if (ferror(tc->backendpipe)) {
-          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;

+ 1 - 1
main/archives.h

@@ -23,7 +23,7 @@
 #define ARCHIVES_H
 
 struct tarcontext {
-  FILE *backendpipe;
+  int backendpipe;
   struct pkginfo *pkg;
   struct fileinlist **newfilesp;
 };

+ 1 - 1
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);

+ 2 - 2
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<loaded_list_end) {

+ 4 - 10
main/processarc.c

@@ -514,25 +514,19 @@ void process_archive(const char *filename) {
   newfileslist= 0; tc.newfilesp= &newfileslist;
   push_cleanup(cu_fileslist,~0, 0,0, 1,(void*)&newfileslist);
   tc.pkg= pkg;
-  tc.backendpipe= fdopen(p1[0],"r");
-  if (!tc.backendpipe) ohshite(_("unable to fdopen dpkg-deb extract pipe"));
-  push_cleanup(cu_backendpipe,~ehflag_bombout, 0,0, 1,(void*)&tc.backendpipe);
+  tc.backendpipe= p1[0];
+  push_cleanup(cu_closefd,~ehflag_bombout, 0,0, 1,(void*)&tc.backendpipe);
 
   r= TarExtractor((void*)&tc, &tf);
   if (r) {
     if (errno) {
       ohshite(_("error reading dpkg-deb tar output"));
-    } else if (feof(tc.backendpipe)) {
-      waitsubproc(c1,BACKEND " --fsys-tarfile (EOF)",1);
-      ohshite(_("unexpected EOF in filesystem tarfile - corrupted package archive"));
     } else {
       ohshite(_("corrupted filesystem tarfile - corrupted package archive"));
     }
   }
-  tmpf= tc.backendpipe;
-  tc.backendpipe= 0;
-  while (getc(tmpf) != EOF) ; /* zap possible trailing zeros */
-  fclose(tmpf);
+  fd_null_copy(tc.backendpipe,-1,_("dpkg-deb: zap possible trailing zeros"));
+  close(tc.backendpipe);
   waitsubproc(c1,BACKEND " --fsys-tarfile",1);
 
   if (oldversionstatus == stat_halfinstalled || oldversionstatus == stat_unpacked) {