diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/mlib.c | 123 | ||||
-rw-r--r-- | lib/parse.c | 3 | ||||
-rw-r--r-- | lib/varbuf.c | 16 |
3 files changed, 93 insertions, 49 deletions
diff --git a/lib/mlib.c b/lib/mlib.c index 1a70dd5a3..cf2951371 100644 --- a/lib/mlib.c +++ b/lib/mlib.c @@ -30,6 +30,7 @@ #include <config.h> #include <dpkg.h> +#include <dpkg-db.h> /* Incremented when we do some kind of generally necessary operation, so that * loops &c know to quit if we take an error exit. Decremented again afterwards. @@ -123,54 +124,82 @@ void waitsubproc(pid_t pid, const char *description, int sigpipeok) { checksubprocerr(status,description,sigpipeok); } -int do_fd_copy(int fd1, int fd2, int limit, char *desc) { - char *buf, *sbuf; - int count, bufsize = 32768; - char *er_msg_1 = _("failed to allocate buffer for copy (%s)"); - char *er_msg_2 = _("failed in copy on write (%s)"); - char *er_msg_3 = _("failed in copy on read (%s)"); - - count = strlen(er_msg_1) + strlen(desc) + 1; - sbuf = malloc(count); - if(sbuf == NULL) - ohshite(_("failed to allocate buffer for snprintf 1")); - snprintf(sbuf, count, er_msg_1, desc); - sbuf[count-1] = 0; - - if((limit != -1) && (limit < bufsize)) - bufsize = limit; - buf = malloc(bufsize); - if(buf == NULL) - ohshite(sbuf); - free(sbuf); - - while((count = read(fd1, buf, bufsize)) > 0) { - if(write(fd2, buf, count) < count) { - count = strlen(er_msg_2) + strlen(desc) + 1; - sbuf = malloc(count); - if(sbuf == NULL) - ohshite(_("failed in copy on write")); - snprintf(sbuf, count, er_msg_2, desc); - sbuf[count-1] = 0; - ohshite(sbuf); - } - if(limit != -1) { - limit -= count; - if(limit < bufsize) - bufsize = limit; - } - } - free(sbuf); +typedef void (*do_fd_write_t)(char *, int, char *, void *data); +typedef struct do_fd_copy_data { + int fd; +} do_fd_copy_data_t; +typedef struct do_fd_buf_data { + char *buf; +} do_fd_buf_data_t; + +int do_fd_write_fd(char* buf, int length, void *proc_data, char *desc) { + do_fd_copy_data_t *data = (do_fd_copy_data_t *)proc_data; + if(write(data->fd, buf, length) < length) + ohshite(_("failed in do_fd_write_fd (%s)"), dsc); +} + +int do_fd_copy(int fd1, int fd2, int limit, char *desc, ...) { + do_fd_copy_data_t data = { fd2 }; + va_list al; + struct varbuf v; + + varbufinit(&v); + + va_start(al,desc); + varbufvprintf(&v, desc, al); + va_end(al); + + do_fd_read(fd1, limit, do_fd_write_fd, &data, v.buf); + varbuffree(&v); +} + +int do_fd_write_buf(char *buf, int length, void *proc_data, char *desc) { + do_fd_buf_data_t *data = (do_fd_buf_data_t *)proc_data; + memcpy(data->buf, buf, length); + data->buf += length; +} + +int read_fd_into_buf(int fd, char *buf, int limit, char *desc, ...) { + do_fd_buf_data_t data = { buf }; + va_list al; + struct varbuf v; + + varbufinit(&v); + + va_start(al,desc); + varbufvprintf(&v, desc, al); + va_end(al); + + do_fd_read(fd, limit, do_fd_write_buf, &data, v.buf); + varbuffree(&v); +} + +int do_fd_read(int fd1, int limit, do_fd_write_t write_proc, void *proc_data, char *desc) { + char *buf; + int count, bufsize= 32768, 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); if (count<0) { - count = strlen(er_msg_3) + strlen(desc) + 1; - sbuf = malloc(count); - if(sbuf == NULL) - ohshite(_("failed in copy on read")); - snprintf(sbuf, count, er_msg_3, desc); - sbuf[count-1] = 0; - ohshite(sbuf); + if (errno==EINTR) continue; + break; } + if (count==0) + break; + + bytesread+= count; + write_proc(buf, count, proc_data, desc); + if(limit!=-1) { + limit-= count; + if(limit<bufsize) + bufsize=limit; + } + } + if (count<0) ohshite(_("failed in do_fd_read on read (%s)"), desc); - free(sbuf); - free(buf); + free(buf); } diff --git a/lib/parse.c b/lib/parse.c index 14b9337bb..8d163e609 100644 --- a/lib/parse.c +++ b/lib/parse.c @@ -102,8 +102,7 @@ int parsedb(const char *filename, enum parsedbflags flags, lno= 1; pdone= 0; for (;;) { /* loop per package */ - i= sizeof(fieldencountered)/sizeof(int); ip= fieldencountered; - while (i--) *ip++= 0; + memset(fieldencountered, 0, sizeof(fieldencountered)); blankpackage(&newpig); blankpackageperfile(newpifp); for (;;) { diff --git a/lib/varbuf.c b/lib/varbuf.c index a8d6c87a6..dabdbd00c 100644 --- a/lib/varbuf.c +++ b/lib/varbuf.c @@ -49,6 +49,22 @@ void varbufprintf(struct varbuf *v, const char *fmt, ...) { } while (r >= v->size-ou-1); } +void varbufvprintf(struct varbuf *v, char *fmt, va_list va) { + int ou, r; + va_list al; + + ou= v->used; + v->used+= strlen(fmt); + + do { + varbufextend(v); + al= va; + r= vsnprintf(v->buf+ou,v->size-ou,fmt,al); + if (r < 0) r= (v->size-ou+1) * 2; + v->used= ou+r; + } while (r >= v->size-ou-1); +} + void varbufaddstr(struct varbuf *v, const char *s) { int l, ou; l= strlen(s); |