void *ferite_classic_calloc( size_t size, size_t blk_size, char *file, int line, FeriteScript *script ) { #ifdef FERITE_MEM_DEBUG struct ferite_memory_block *ptr; #endif LOCK_MEMORY; ferite_classic_calloc_count++; #ifdef FERITE_MEM_DEBUG for( ptr = mem_rootblk; ptr->next != NULL; ptr = ptr->next ) ; ptr->next = malloc(sizeof( struct ferite_memory_block )); ptr->next->data = rcalloc( size, blk_size ); ptr->next->size = size * blk_size; ptr->next->file = strdup( file ); ptr->next->line = line; if( !ptr->next->data ) FUD(("ERROR: Unable to (c)allocate %ld bytes.\n", size * blk_size)); ptr->next->next = NULL; UNLOCK_MEMORY; return ptr->next->data; #else UNLOCK_MEMORY; return rcalloc( size, blk_size ); #endif }
char * json_escape(const char *data, size_t len, size_t *out_len) { char *ret; size_t i = 0, j = 0; for(i = 0; i < len; ++i) { /* count quotes */ if(data[i] == '"' || data[i] == '\\') { j++; } j++; } /* allocate output buffer */ ret = rcalloc(1 + j, 1); j = 0; /* copy into output buffer */ for(i = 0; i < len; ++i) { if(data[i] == '"' || data[i] == '\\') { ret[j] = '\\'; j++; } ret[j] = data[i]; j++; } if(out_len) { *out_len = j; } return ret; }
char * json_wrap(const char *data, size_t data_len, const char *jsonp, size_t jsonp_len, size_t *out) { size_t sz = jsonp_len + 1 + data_len + 4; char *buffer = rcalloc(sz + 1, 1); memcpy(buffer, jsonp, jsonp_len); memcpy(buffer + jsonp_len, "(", 1); memcpy(buffer + jsonp_len + 1, data, data_len); memcpy(buffer + jsonp_len + 1 + data_len, ");\r\n", 4); if(out) { *out = sz; } return buffer; }
int http_response_ct(struct connection *cx, int code, const char *status, const char *data, size_t len, const char *content_type) { int ret; size_t sz; char *buffer; const char template[] = "HTTP/1.1 %d %s\r\n" "Content-Type: %s\r\n" "Content-Length: %lu\r\n" "\r\n"; sz = sizeof(template)-1 + integer_length(code) + strlen(status) + strlen(content_type) + integer_length((int)len) - (2 + 2 + 2 + 3) /* %d %s %s %lu*/ + len; buffer = rcalloc(sz + 1, 1); ret = sprintf(buffer, template, code, status, content_type, (long unsigned int)len); memcpy(buffer + ret, data, len); ret = write(cx->fd, buffer, sz); rfree(buffer); return ret; } void http_streaming_start(struct connection *cx, int code, const char *status) { http_streaming_start_ct(cx, code, status, "text/html"); } void http_streaming_start_ct(struct connection *cx, int code, const char *status, const char *content_type) {
static int processFile(const char *fn, int dtype) { int rc = 1; int fdno = -1; struct stat st; GElf_Ehdr *ehdr, ehdr_mem; elfInfo *ei = rcalloc(1, sizeof(*ei)); fdno = open(fn, O_RDONLY); if (fdno < 0 || fstat(fdno, &st) < 0) goto exit; (void) elf_version(EV_CURRENT); ei->elf = elf_begin(fdno, ELF_C_READ, NULL); if (ei->elf == NULL || elf_kind(ei->elf) != ELF_K_ELF) goto exit; ehdr = gelf_getehdr(ei->elf, &ehdr_mem); if (ehdr == NULL) goto exit; if (ehdr->e_type == ET_DYN || ehdr->e_type == ET_EXEC) { ei->marker = mkmarker(ehdr); ei->isDSO = (ehdr->e_type == ET_DYN); ei->isExec = (st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)); processProgHeaders(ei, ehdr); processSections(ei); } /* * For DSOs which use the .gnu_hash section and don't have a .hash * section, we need to ensure that we have a new enough glibc. */ if (ei->isExec && ei->gotGNUHASH && !ei->gotHASH && !soname_only) { argvAdd(&ei->requires, "rtld(GNU_HASH)"); } /* * For DSOs, add DT_SONAME as provide. If its missing, we can fake * it from the basename if requested. The bizarre looking DT_DEBUG * check is used to avoid adding basename provides for PIE executables. */ if (ei->isDSO && !ei->gotDEBUG) { if (!ei->soname && fake_soname) { const char *bn = strrchr(fn, '/'); ei->soname = rstrdup(bn ? bn + 1 : fn); } if (ei->soname) addDep(&ei->provides, ei->soname, NULL, ei->marker); } /* If requested and present, add dep for interpreter (ie dynamic linker) */ if (ei->interp && require_interp) argvAdd(&ei->requires, ei->interp); rc = 0; /* dump the requested dependencies for this file */ for (ARGV_t dep = dtype ? ei->requires : ei->provides; dep && *dep; dep++) { fprintf(stdout, "%s\n", *dep); } exit: if (fdno >= 0) close(fdno); if (ei) { argvFree(ei->provides); argvFree(ei->requires); free(ei->soname); free(ei->interp); if (ei->elf) elf_end(ei->elf); rfree(ei); } return rc; }
char * json_msg(const char *channel, size_t channel_len, const unsigned long long seq, const char *data, size_t data_len, size_t *out_len) { size_t needed = 0; char *buffer = NULL, *pos; char fmt0[] = "[\"msg\", {\"channel\": \""; char fmt1[] = "\", \"seq\": "; char fmt2[] = ", \"data\": \""; char fmt3[] = "\"}]"; char seq_str[40]; int seq_len = sprintf(seq_str, "%lld", seq); /* escape data */ char *esc_data, *esc_channel; esc_data = json_escape(data, data_len, &data_len); esc_channel = json_escape(channel, channel_len, &channel_len); needed = sizeof(fmt0)-1 + channel_len + sizeof(fmt1)-1 + seq_len + sizeof(fmt2)-1 + data_len + sizeof(fmt3)-1; pos = buffer = rcalloc(needed + 1, 1); buffer[needed] = 0; memcpy(pos, fmt0, sizeof(fmt0)-1); pos += sizeof(fmt0)-1; memcpy(pos, esc_channel, channel_len); pos += channel_len; memcpy(pos, fmt1, sizeof(fmt1)-1); pos += sizeof(fmt1)-1; memcpy(pos, seq_str, seq_len); pos += seq_len; memcpy(pos, fmt2, sizeof(fmt2)-1); pos += sizeof(fmt2)-1; memcpy(pos, esc_data, data_len); pos += data_len; memcpy(pos, fmt3, sizeof(fmt3)-1); if(out_len) { *out_len = needed; } rfree(esc_data); rfree(esc_channel); return buffer; }