10 struct flist *flist_create(void)
14 if(!(flist = calloc(1, sizeof *flist))) {
15 perror("flist_create");
18 flist->final_size = -1;
22 void flist_destroy(struct flist *flist)
31 int flist_add(struct flist *flist, const char *fname, int contents)
34 struct proto_file_entry fent;
35 int namelen, datalen, sz;
41 if(flist->final_size >= 0) {
42 fprintf(stderr, "flist_add: can't add more files to a finalized file list\n");
46 if(!(fp = fopen(fname, "rb"))) {
47 fprintf(stderr, "flist_add: failed to open file: %s: %s\n", fname, strerror(errno));
50 fstat(fileno(fp), &st);
52 fent.size = st.st_size;
53 fent.mtime = st.st_mtime;
55 namelen = datalen = strlen(fname);
60 if(!flist->flist || flist->flist->num_files >= flist->max_files) {
61 struct proto_flist *tmp;
62 int newsz = flist->max_files ? flist->max_files << 1 : 32;
64 if(!(tmp = realloc(flist->flist, sizeof *tmp + (newsz - 1) * sizeof *tmp->files))) {
65 fprintf(stderr, "flist_add: failed to resize file list to %d entries\n", newsz);
72 flist->max_files = newsz;
74 if(flist->data_sz + datalen >= flist->max_data_sz) {
76 int newsz = flist->max_data_sz + datalen;
84 if(!(tmp = realloc(flist->data, newsz))) {
85 fprintf(stderr, "flist_add: failed to resize data buffer to %d bytes\n", newsz);
89 flist->max_data_sz = newsz;
92 fent.nameoffs = flist->data_sz;
93 fent.namelen = namelen;
94 dptr = flist->data + flist->data_sz;
95 memcpy(dptr, fname, namelen);
101 while((sz = fread(dptr, 1, st.st_size, fp)) > 0) {
102 md5_msg(&md, dptr, sz);
107 while((sz = fread(buf, 1, sizeof buf, fp)) > 0) {
108 md5_msg(&md, buf, sz);
112 memcpy(fent.csum, md.sum, sizeof fent.csum);
116 flist->flist->files[flist->flist->num_files++] = fent;
117 flist->data_sz += datalen;
121 int flist_finalize(struct flist *flist)
124 struct proto_flist *tmp;
126 if(!flist->flist || flist->flist->num_files <= 0) {
127 fprintf(stderr, "flist_finalize: nothing to finalize, file list empty\n");
131 newsz = sizeof *tmp + (flist->flist->num_files - 1) * sizeof *tmp->files + flist->data_sz;
132 if(!(tmp = realloc(flist->flist, newsz))) {
133 fprintf(stderr, "flist_finalize: failed to resize file list buffer to %d bytes\n", newsz);
137 memcpy(tmp->files + flist->flist->num_files, flist->data, flist->data_sz);
140 memset(flist, 0, sizeof *flist);
142 flist->final_size = newsz;
146 int read_line(int s, char *buf, int bufsz)
149 while(bufsz > 1 && read(s, ptr, 1) > 0 && *ptr++ != '\n');
151 return ptr == buf ? -1 : 0;
160 while(msglen < 3 && (sz = read(s, buf + msglen, 3 - msglen)) > 0) {
163 if(msglen < 3) return -1;
165 if(memcmp(buf, "ERR", 3) == 0) {
170 while(read(s, ptr, 1) > 0 && *ptr++ != '\n');