int incoming_grow_maybe(struct incoming *in) { if(++in->size<in->allocated) return 0; // Make the incoming array bigger. in->allocated+=32; //printf("grow incoming to %d\n", in->allocated); if((in->weak=(uint64_t *) realloc_w(in->weak, in->allocated*sizeof(uint64_t), __func__)) && (in->found=(uint8_t *) realloc_w(in->found, in->allocated*sizeof(uint8_t), __func__))) return 0; return -1; }
int get_vss(BFILE *bfd, struct sbuf *sb, char **vssdata, size_t *vlen, struct conf **confs) { bsid sid; char *tmp=NULL; *vlen=0; while(!ensure_read(bfd, (char *)&sid, bsidsize, 0)) { int64_t s=0; if(!(tmp=(char *)realloc_w(tmp, (*vlen)+bsidsize, __func__))) goto error; memcpy(tmp+(*vlen), &sid, bsidsize); (*vlen)+=bsidsize; // dwStreamId==1 means start of backup data, so finish. if(sid.dwStreamId==1) { // logp("\n%s: %d + %d\n", // path, (int)sid.Size, (int)sid.dwStreamNameSize); bfd->datalen=sid.Size; break; } // Otherwise, need to read in the rest of the VSS header. s=(sid.Size)+(sid.dwStreamNameSize); if(!(tmp=(char *)realloc_w(tmp, (*vlen)+s, __func__)) || ensure_read(bfd, tmp+(*vlen), s, 1)) { goto error; return -1; } (*vlen)+=s; } if(!(*vssdata=(char *)realloc_w(*vssdata, (*vlen)+9, __func__))) goto error; snprintf(*vssdata, 9, "%c%08X", META_VSS, (unsigned int)*vlen); memcpy((*vssdata)+9, tmp, *vlen); (*vlen)+=9; return 0; error: if(tmp) free(tmp); if(*vssdata) { free(*vssdata); *vssdata=NULL; } *vlen=0; return -1; }
int extract_params(char *msg, char **argv[]) { char *savedptr; int argc = 0, size = STARTING_PARAMS; *argv = NULL; if (!msg) return 0; // Allocate enough starting space for most bot commands *argv = malloc_w(size * sizeof(char *)); // split parameters separated by space or tab (*argv)[argc] = strtok_r(msg, " \t", &savedptr); while ((*argv)[argc]) { if (argc == size - 1) { // Double the array if it gets full *argv = realloc_w(*argv, size * 2 * sizeof(char *)); size *= 2; } (*argv)[++argc] = strtok_r(NULL, " \t", &savedptr); } if (!argc) { free(*argv); *argv = NULL; } return argc; }
// Return 0 on OK, -1 on error, 1 when there is no more to read. static int read_next_data(FILE *fp, struct rblk *rblk, int ind, int r) { char cmd='\0'; size_t bytes; unsigned int len; char buf[5]; // FIX THIS: Check for the appropriate return value that means there // is no more to read. if(fread(buf, 1, 5, fp)!=5) return 1; if((sscanf(buf, "%c%04X", &cmd, &len))!=2) { logp("sscanf failed in %s: %s\n", __func__, buf); return -1; } if(cmd!=CMD_DATA) { logp("unknown cmd in %s: %c\n", __func__, cmd); return -1; } if(!(rblk[ind].readbuf[r].buf= (char *)realloc_w(rblk[ind].readbuf[r].buf, len, __func__))) return -1; if((bytes=fread(rblk[ind].readbuf[r].buf, 1, len, fp))!=len) { logp("Short read: %d wanted: %d\n", (int)bytes, (int)len); return -1; } rblk[ind].readbuf[r].len=len; //printf("read: %d:%d %04X\n", r, len, r); return 0; }
int do_get_entries_in_directory(DIR *directory, struct dirent ***nl, int *count, int (*compar)(const void *, const void *)) { int status; int allocated=0; struct dirent **ntmp=NULL; struct dirent *entry=NULL; struct dirent *result=NULL; // This here is doing a funky kind of scandir/alphasort // that can also run on Windows. while(1) { char *p; if(!(entry=(struct dirent *)malloc_w( sizeof(struct dirent)+fs_name_max+100, __func__))) goto error; status=readdir_r(directory, entry, &result); if(status || !result) { free_v((void **)&entry); break; } p=entry->d_name; ASSERT(fs_name_max+1 > (int)sizeof(struct dirent)+strlen(p)); if(!p || !strcmp(p, ".") || !strcmp(p, "..")) { free_v((void **)&entry); continue; } if(*count==allocated) { if(!allocated) allocated=10; else allocated*=2; if(!(ntmp=(struct dirent **) realloc_w(*nl, allocated*sizeof(**nl), __func__))) goto error; *nl=ntmp; } (*nl)[(*count)++]=entry; } if(*nl && compar) qsort(*nl, *count, sizeof(**nl), compar); return 0; error: free_v((void **)&entry); if(*nl) { int i; for(i=0; i<*count; i++) free_v((void **)&((*nl)[i])); free_v((void **)nl); } return -1; }
static void ioevent_list_grow(struct ioevent_list *list) { list->size++; list->ioevent=(struct ioevent *) realloc_w(list->ioevent, list->size*sizeof(struct ioevent), __func__); fail_unless(list->ioevent!=NULL); }
// Return -1 or error, 0 on OK. int scores_grow(struct scores *scores, size_t count) { if(!scores || !count) return 0; scores->size=count; if(!(scores->scores=(uint16_t *)realloc_w(scores->scores, sizeof(uint16_t)*scores->size, __func__))) return -1; return 0; }
static int get_files_in_directory(DIR *directory, struct dirent ***nl, int *count) { int status; int allocated=0; struct dirent **ntmp=NULL; struct dirent *entry=NULL; struct dirent *result=NULL; /* Graham says: this here is doing a funky kind of scandir/alphasort that can also run on Windows. TODO: split into a scandir function */ while(1) { char *p; if(!(entry=(struct dirent *)malloc( sizeof(struct dirent)+name_max+100))) { log_out_of_memory(__func__); return -1; } status=readdir_r(directory, entry, &result); if(status || !result) { free(entry); break; } p=entry->d_name; ASSERT(name_max+1 > (int)sizeof(struct dirent)+strlen(p)); /* Skip `.', `..', and excluded file names. */ if(!p || !strcmp(p, ".") || !strcmp(p, "..")) { free(entry); continue; } if(*count==allocated) { if(!allocated) allocated=10; else allocated*=2; if(!(ntmp=(struct dirent **) realloc_w(*nl, allocated*sizeof(**nl), __func__))) { free(entry); return -1; } *nl=ntmp; } (*nl)[(*count)++]=entry; } if(*nl) qsort(*nl, *count, sizeof(**nl), (int (*)(const void *, const void *))myalphasort); return 0; }
int add_to_sbufl_arr(struct sbuf ***sblist, struct sbuf *sb, int *count) { struct sbuf **sbtmp=NULL; if(!(sbtmp=(struct sbuf **)realloc_w(*sblist, ((*count)+1)*sizeof(struct sbuf *), __func__))) return -1; *sblist=sbtmp; (*sblist)[(*count)++]=sb; return 0; }
struct candidate *candidates_add_new(void) { struct candidate *candidate; if(!(candidate=candidate_alloc())) return NULL; if(!(candidates=(struct candidate **)realloc_w(candidates, (candidates_len+1)*sizeof(struct candidate *), __func__))) return NULL; candidates[candidates_len++]=candidate; return candidate; }
int del_from_sbufl_arr(struct sbuf ***sblist, int *count) { struct sbuf **sbtmp=NULL; (*count)--; if((*sblist)[*count]) sbuf_free(&((*sblist)[*count])); if(*count && !(sbtmp=(struct sbuf **)realloc_w(*sblist, (*count)*sizeof(struct sbuf *), __func__))) return -1; *sblist=sbtmp; return 0; }
static int append_to_extrameta(const char *toappend, char metasymbol, char **xattrtext, size_t *xlen, ssize_t totallen) { char tmp3[10]; size_t newlen=0; snprintf(tmp3, sizeof(tmp3), "%c%08X", metasymbol, (unsigned int)totallen); newlen=(*xlen)+9+totallen; if(!(*xattrtext=(char *) realloc_w(*xattrtext, newlen, __func__))) return -1; memcpy((*xattrtext)+(*xlen), tmp3, 9); (*xlen)+=9; memcpy((*xattrtext)+(*xlen), toappend, totallen); (*xlen)+=totallen; return 0; }
// Return 0 for OK, -1 for error, 1 for finished reading the file. static int get_next_set_of_hooks(struct hooks **hnew, struct sbuf *sb, struct fzp *spzp, char **path, uint64_t **fingerprints, size_t *len) { struct blk blk; while(1) { switch(sbuf_fill_from_file(sb, spzp, NULL, NULL)) { case -1: goto error; case 1: // Reached the end. if(hooks_alloc(hnew, path, fingerprints, len)) goto error; return 1; } if(sb->path.cmd==CMD_MANIFEST) { if(hooks_alloc(hnew, path, fingerprints, len)) break; *path=sb->path.buf; sb->path.buf=NULL; sbuf_free_content(sb); if(*hnew) return 0; } else if(sb->path.cmd==CMD_FINGERPRINT) { if(!(*fingerprints=(uint64_t *)realloc_w(*fingerprints, ((*len)+1)*sizeof(uint64_t), __func__))) goto error; if(blk_set_from_iobuf_fingerprint(&blk, &sb->path)) goto error; (*fingerprints)[(*len)++]=blk.fingerprint; sbuf_free_content(sb); } else { iobuf_log_unexpected(&sb->path, __func__); break; } } error: sbuf_free_content(sb); return -1; }
size_t curl_write_memory(char *data, size_t size, size_t elements, void *membuf) { struct mem_buffer *mem = membuf; size_t total_size = size * elements; // Our function will be called as many times as needed by curl_easy_perform to complete the operation so, // we increase the size of our buffer each time to accommodate for it (and the null char) mem->buffer = realloc_w(mem->buffer, mem->size + total_size + 1); // Our mem_buffer struct keeps the current size so far, so we begin writing to the end of it each time memcpy(&(mem->buffer[mem->size]), data, total_size); mem->size += total_size; mem->buffer[mem->size] = '\0'; // if the return value isn't the total number of bytes that was passed in our function, // curl_easy_perform will return an error return total_size; }
static int get_meta( struct asfd *asfd, struct cntr *cntr, char **metadata, size_t *metalen) { int ret=-1; struct iobuf *rbuf=asfd->rbuf; while(1) { iobuf_free_content(rbuf); if(asfd->read(asfd)) goto end; switch(rbuf->cmd) { case CMD_DATA: if(!(*metadata=(char *)realloc_w(*metadata, (*metalen)+rbuf->len, __func__))) goto end; memcpy((*metadata)+(*metalen), rbuf->buf, rbuf->len); *metalen+=rbuf->len; break; case CMD_END_FILE: ret=0; goto end; case CMD_MESSAGE: case CMD_WARNING: log_recvd(rbuf, cntr, 0); break; default: iobuf_log_unexpected(rbuf, __func__); goto end; } } end: iobuf_free_content(rbuf); return ret; }
static int process_files_in_directory(struct asfd *asfd, struct dirent **nl, int count, int *rtn_stat, char **link, size_t len, size_t *link_len, struct conf *conf, FF_PKT *ff_pkt, dev_t our_device) { int m=0; for(m=0; m<count; m++) { size_t i; char *p=NULL; char *q=NULL; p=nl[m]->d_name; if(strlen(p)+len>=*link_len) { *link_len=len+strlen(p)+1; if(!(*link=(char *) realloc_w(*link, (*link_len)+1, __func__))) return -1; } q=(*link)+len; for(i=0; i<strlen(nl[m]->d_name); i++) *q++=*p++; *q=0; ff_pkt->flen=i; if(file_is_included_no_incext(conf, *link)) { *rtn_stat=find_files(asfd, ff_pkt, conf, *link, our_device, false); } else { struct strlist *x; // Excluded, but there might be a subdirectory that is // included. for(x=conf->incexcdir; x; x=x->next) { if(x->flag && is_subdir(*link, x->path)) { struct strlist *y; if((*rtn_stat=find_files(asfd, ff_pkt, conf, x->path, our_device, false))) break; // Now need to skip subdirectories of // the thing that we just stuck in // find_one_file(), or we might get // some things backed up twice. for(y=x->next; y; y=y->next) if(is_subdir(x->path, y->path)) y=y->next; } } } free_v((void **)&(nl[m])); if(*rtn_stat) break; } return 0; }
static int get_toappend(struct asfd *asfd, const char *path, char **toappend, const char *xattrlist, ssize_t len, ssize_t *totallen, int have_acl, struct cntr *cntr) { char *val=NULL; const char *z=NULL; ssize_t maxlen=0xFFFFFFFF/2; for(z=xattrlist; z-xattrlist < len; z=strchr(z, '\0')+1) { char tmp1[9]; char tmp2[9]; ssize_t vlen; ssize_t zlen=0; ssize_t newlen=0; free_w(&val); if((zlen=strlen(z))>maxlen) { logw(asfd, cntr, "xattr element of '%s' too long: %zd\n", path, zlen); goto carryon; } if(have_acl && in_skiplist(z)) continue; if((vlen=lgetxattr(path, z, NULL, 0))<0) { logw(asfd, cntr, "could not lgetxattr on %s for %s: %zd %s\n", path, z, vlen, strerror(errno)); continue; } if(vlen) { if(!(val=(char *)malloc_w(vlen+1, __func__))) goto error; if((vlen=lgetxattr(path, z, val, vlen))<0) { logw(asfd, cntr, "could not lgetxattr %s for %s: %zd %s\n", path, z, vlen, strerror(errno)); continue; } val[vlen]='\0'; if(vlen>maxlen) { logw(asfd, cntr, "xattr value of '%s' too long: %zd\n", path, vlen); goto carryon; } } snprintf(tmp1, sizeof(tmp1), "%08X", (unsigned int)zlen); snprintf(tmp2, sizeof(tmp2), "%08X", (unsigned int)vlen); newlen=(*totallen)+8+zlen+8+vlen; if(!(*toappend=(char *)realloc_w(*toappend, newlen, __func__))) goto error; memcpy((*toappend)+(*totallen), tmp1, 8); *totallen+=8; memcpy((*toappend)+(*totallen), z, zlen); *totallen+=zlen; memcpy((*toappend)+(*totallen), tmp2, 8); *totallen+=8; memcpy((*toappend)+(*totallen), val, vlen); *totallen+=vlen; if(*totallen>maxlen) { logw(asfd, cntr, "xattr length of '%s' grew too long: %zd\n", path, *totallen); goto carryon; } } free_w(&val); return 0; error: free_w(&val); free_w(toappend); return -1; carryon: free_w(&val); free_w(toappend); return 0; }
int get_xattr(struct asfd *asfd, const char *path, char **xattrtext, size_t *xlen, struct cntr *cntr) { int i=0; ssize_t maxlen=0xFFFFFFFF/2; for(i=0; i<(int)(sizeof(namespaces)/sizeof(int)); i++) { int j=0; ssize_t len=0; int have_acl=0; char *xattrlist=NULL; char *cnamespace=NULL; ssize_t totallen=0; char *toappend=NULL; char z[BSD_BUF_SIZE]=""; char cattrname[BSD_BUF_SIZE]=""; if((len=extattr_list_link(path, namespaces[i], NULL, 0))<0) { logw(asfd, cntr, "could not extattr_list_link of '%s': %zd\n", path, len); return 0; // carry on } if(!len) continue; if(xattrtext && *xattrtext) { // Already have some meta text, which means that some // ACLs were set. have_acl++; } if(!(xattrlist=(char *)calloc_w(1, len+1, __func__))) return -1; if((len=extattr_list_link(path, namespaces[i], xattrlist, len))<=0) { logw(asfd, cntr, "could not extattr_list_link '%s': %zd\n", path, len); free_w(&xattrlist); return 0; // carry on } xattrlist[len]='\0'; if(extattr_namespace_to_string(namespaces[i], &cnamespace)) { logp("Failed to convert %d into namespace on '%s'\n", namespaces[i], path); free_w(&xattrlist); return 0; // carry on } for(j=0; j<(int)len; j+=xattrlist[j]+1) { int cnt=0; char tmp1[9]; char tmp2[9]; size_t newlen=0; size_t zlen=0; ssize_t vlen=0; char *val=NULL; cnt=xattrlist[j]; if(cnt>((int)sizeof(cattrname)-1)) cnt=((int)sizeof(cattrname)-1); strncpy(cattrname, xattrlist+(j+1), cnt); cattrname[cnt]='\0'; snprintf(z, sizeof(z), "%s.%s", cnamespace, cattrname); if(have_acl && in_skiplist(z)) continue; zlen=strlen(z); //printf("\ngot: %s (%s)\n", z, path); if((vlen=extattr_list_link(path, namespaces[i], xattrlist, len))<0) { logw(asfd, cntr, "could not extattr_list_link on %s for %s: %zd\n", path, cnamespace, vlen); continue; } if(vlen) { if(!(val=(char *)malloc_w(vlen+1, __func__))) { free_w(&xattrlist); free_w(&toappend); return -1; } if((vlen=extattr_get_link(path, namespaces[i], cattrname, val, vlen))<0) { logw(asfd, cntr, "could not extattr_list_link %s for %s: %zd\n", path, cnamespace, vlen); free_w(&val); continue; } val[vlen]='\0'; if(vlen>maxlen) { logw(asfd, cntr, "xattr value of '%s' too long: %zd\n", path, vlen); free_w(&toappend); free_w(&val); break; } } snprintf(tmp1, sizeof(tmp1), "%08X", (unsigned int)zlen); snprintf(tmp2, sizeof(tmp2), "%08X", (unsigned int)vlen); newlen=totallen+8+zlen+8+vlen; if(!(toappend=(char *)realloc_w(toappend, newlen, __func__))) { free_w(&val); free_w(&xattrlist); return -1; } memcpy(toappend+totallen, tmp1, 8); totallen+=8; memcpy(toappend+totallen, z, zlen); totallen+=zlen; memcpy(toappend+totallen, tmp2, 8); totallen+=8; memcpy(toappend+totallen, val, vlen); totallen+=vlen; free_w(&val); if(totallen>maxlen) { logw(asfd, cntr, "xattr length of '%s' grew too long: %lu\n", path, (unsigned long)totallen); free_w(&val); free_w(&toappend); free_w(&xattrlist); return 0; // carry on } } if(toappend) { if(append_to_extrameta(toappend, META_XATTR_BSD, xattrtext, xlen, totallen)) { free_w(&toappend); free_w(&xattrlist); return -1; } } free_w(&toappend); free_w(&xattrlist); } return 0; }