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->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);
69 flist->max_files = newsz;
71 if(flist->data_sz + datalen >= flist->max_data_sz) {
73 int newsz = flist->max_data_sz + datalen;
81 if(!(tmp = realloc(flist->data, newsz))) {
82 fprintf(stderr, "flist_add: failed to resize data buffer to %d bytes\n", newsz);
86 flist->max_data_sz = newsz;
89 fent.nameoffs = flist->data_sz;
90 fent.namelen = namelen;
91 dptr = flist->data + flist->data_sz;
92 memcpy(dptr, fname, namelen);
98 while((sz = fread(dptr, 1, st.st_size, fp)) > 0) {
99 md5_msg(&md, dptr, sz);
104 while((sz = fread(buf, 1, sizeof buf, fp)) > 0) {
105 md5_msg(&md, buf, sz);
109 memcpy(fent.csum, md.sum, sizeof fent.csum);
113 flist->flist->files[flist->flist->num_files++] = fent;
114 flist->data_sz += datalen;
118 int flist_finalize(struct flist *flist)
121 struct proto_flist *tmp;
123 if(!flist->flist || flist->flist->num_files <= 0) {
124 fprintf(stderr, "flist_finalize: nothing to finalize, file list empty\n");
128 newsz = sizeof *tmp + (flist->flist->num_files - 1) * sizeof *tmp->files + flist->data_sz;
129 if(!(tmp = realloc(flist->flist, newsz))) {
130 fprintf(stderr, "flist_finalize: failed to resize file list buffer to %d bytes\n", newsz);
134 memcpy(tmp->files + flist->flist->num_files, flist->data, flist->data_sz);
137 memset(flist, 0, sizeof *flist);
139 flist->final_size = newsz;