PUBLIC void HTTPResponse_free(struct HTTPResponse *response) { if(response) { am_free(response->data); am_free(response->content_filename); am_free(response); } }
void kvp_free (kvp_t *k){ if (k == NULL) return; if (k->key != NULL) am_free (k->key); if (k->value != NULL) am_free (k->value); am_free (k); }
int ea_delete(EA *ea) { int rc = 0; if ( ea->st_type == EA_STORE_TYPE_MEMORY ) { KV_TRC(pAT, "free ea %p ea->st_memory %p", ea, ea->st_memory); // Simple free the block of store if (ea->st_memory) { free(ea->st_memory); ea->st_memory=NULL; } } else { // Call to close out the chunk and free the space // for the device name rc = cblk_close(ea->st_flash, 0); am_free(ea->st_device); } if ( rc == 0 ) { KV_TRC(pAT, "free ea %p", ea); am_free(ea); } return rc; }
PRIVATE void freeOptionItem(void* item) { if(item != NULL) { suboption_t* obj = (suboption_t*)item; am_free(obj->option); am_free(obj->value); am_free(obj); } }
void *si_new(uint64_t nh, uint64_t ne, uint64_t nb) { SI *si = am_malloc(sizeof(SI)); if (si == NULL) { errno = ENOMEM; KV_TRC_FFDC(pAT, "FFDC1: nh %ld ne %ld nb %ld, rc = %d", nh, ne, nb, errno); return NULL; } si->nh = nh; si->ne = ne; si->nb = nb; si->ent_next = 0; si->gid_next = 0; si->dat_next = 0; si->tbl = am_malloc(nh * sizeof(uint64_t)); if ( si->tbl == NULL ) { errno = ENOMEM; KV_TRC_FFDC(pAT, "FFDC2: nh %ld ne %ld nb %ld, rc = %d", nh, ne, nb, errno); } else { memset(si->tbl, 0xFF, nh * sizeof(uint64_t)); si->dat = am_malloc(nb); if (si->dat == NULL) { errno = ENOMEM; KV_TRC_FFDC(pAT, "FFDC3: nh %ld ne %ld nb %ld, rc = %d", nh, ne, nb, errno); am_free(si->tbl); am_free(si); si = NULL; } else { si->ent = am_malloc(ne * sizeof(SIE)); if (si->ent == NULL) { errno = ENOMEM; KV_TRC_FFDC(pAT, "FFDC4: nh %ld ne %ld nb %ld, rc = %d", nh, ne, nb, errno); am_free(si->tbl); am_free(si->dat); am_free(si); si = NULL; } } } memset(si->tbl, 0xFF, nh * sizeof(uint64_t)); return si; }
/** \brief Free the memory associated with the given feed-list item * * \param listItem Pointer to a feed-list item * * This function is to be used in the generic list functions freeList(), removeFirst() and * removeLast() as the 2nd parameter to ensure proper memory deallocation. */ void feed_free(void* listItem) { rss_feed* x = (rss_feed*)listItem; if(x != NULL) { am_free(x->url); am_free(x->cookies); am_free(x); } }
void clean_main_menu() { int i; if (menu_size > 0) { for (i = 0; i < menu_size; ++i) { am_free(menu_values[i]); } am_free(menu_values); } }
/** \brief Free a WebData object and all memory associated with it * * \param[in] data Pointer to a WebData object */ PRIVATE void WebData_free(struct WebData *data) { if(data) { am_free(data->url); am_free(data->content_filename); HTTPData_free(data->response); am_free(data); data = NULL; } }
PRIVATE void HTTPData_free(HTTPData* data) { if(data) { am_free(data->data); data->buffer_size = 0; data->buffer_pos = 0; } am_free(data); }
/** \brief Create a Transmission-specific JSON packet in order to add a new download * to Transmission. * * \param[in] data Pointer to the torrent data * \param[in] tsize size of the torrent data * \param[in] start Determines if the torrent shall start to download right away or be added in a paused state * \param[in] folder Optional parameter to set the download folder for this torrent * \param[out] setme_size size of the resulting JSON packet * \return pointer to the JSON string * * The function Base64-encodes the given torrent content and encapsulates it in a JSON packet. * The packet can then be sent to Transmission via HTTP POST. */ char* makeTorrentAddMetaInfoJSON(const void *data, uint32_t tsize, uint8_t start, const char* folder, uint32_t *setme_size) { char *encoded = NULL; char *buf = NULL; char *folder_str = NULL; int buf_size, json_size, folderstr_size = 0; uint32_t enc_size; const char *JSONstr = "{\n" "\"method\": \"torrent-add\",\n" "\"arguments\": {\n" "\"metainfo\": \"%s\",\n" "%s" "\"paused\": %d\n" "}\n" "}"; *setme_size = 0; encoded = base64_encode((const char*)data, tsize, &enc_size); if(encoded && enc_size > 0) { if(folder && *folder) { folderstr_size = strlen(folder) + 20; folder_str = (char*)am_malloc(folderstr_size); assert(folder_str && "am_malloc(folder_str) failed!"); snprintf(folder_str, folderstr_size, "\"download-dir\": \"%s\",\n", folder); dbg_printf(P_INFO, "folder_str: %s", folder_str); } buf_size = enc_size + strlen(JSONstr) + folderstr_size + 10; buf = (char*)am_malloc(buf_size); memset(buf, 0, buf_size); json_size = snprintf(buf, buf_size, JSONstr, encoded, folder_str ? folder_str : "", start ? 0 : 1); if(json_size < 0 || json_size >= buf_size) { dbg_printf(P_ERROR, "Error producing JSON string with Base64-encoded metadata: %s", strerror(errno)); am_free(encoded); am_free(buf); return NULL; } buf[json_size] = '\0'; dbg_printf(P_INFO2, "JSON: %s", buf); if(setme_size) { *setme_size = json_size; } am_free(folder_str); am_free(encoded); return buf; } return NULL; }
PRIVATE void WebData_clear(struct WebData *data) { if(data) { am_free(data->content_filename); data->content_filename = NULL; if(data->response) { am_free(data->response->data); data->response->data = NULL; data->response->buffer_size = 0; data->response->buffer_pos = 0; } } }
PRIVATE void set_path(const char *src, char **dst) { char *tmp; if(src && strlen(src) < MAXPATHLEN) { tmp = resolve_path(src); if(tmp) { if ( *dst != NULL ) { am_free(*dst); } *dst = am_strdup(tmp); am_free(tmp); } } }
int8_t getRPCVersion(const char* host, uint16_t port, const char* auth) { char url[MAX_URL_LEN]; int8_t result = 0; char *response = NULL; HTTPResponse *res = NULL; const char *JSONstr = "{\n" "\"method\": \"session-get\",\n" "\"arguments\": {}\n" "}"; if(!host) { return 0; } snprintf( url, MAX_URL_LEN, "http://%s:%d/transmission/rpc", host, port); res = sendHTTPData(url, auth, JSONstr, strlen(JSONstr)); if(res != NULL && res->responseCode == 200) { dbg_printf(P_DBG, "[getRPCVersion] got response!"); response = parseResponse(res->data); if(response) { if(!strncmp(response, "success", 7)) { result = parseRPCVersion(res->data); dbg_printf(P_DBG, "[getRPCVersion] RPC version: %d", result); } am_free((void*)response); } HTTPResponse_free(res); } return result; }
/** \brief Free a list and all memory associated with it * * \param[in,out] head Pointer to a list * \param[in] freeFunc function pointer for freeing the memory of each list item * * The function removes all items from a list, freeing all associated memory. * If freeFunc is NULL, it tries to directly free the data of each node. * For complex nodes (e.g. structs) the user needs to provide a node-specific free() function. */ void freeList( NODE **head, listFuncPtr freeFunc ) { NODE* node = NULL; dbg_printf(P_DBG, "[cleanupList] size before: %d", listCount(*head)); while (*head != NULL) { node = *head; *head = (*head)->next; if(freeFunc != NULL) { freeFunc(node->data); } else { am_free(node->data); } am_free(node); } dbg_printf(P_DBG, "[cleanupList] size after: %d", listCount(*head)); }
int16_t sendProwlNotification(const char* apikey, const char* event, const char* desc) { int16_t result = -1; int32_t data_size; char url[128]; HTTPResponse *response = NULL; char *data = NULL; data = createProwlMessage(apikey, event, desc, &data_size); if(data) { snprintf(url, 128, "%s%s", PROWL_URL, PROWL_ADD); response = sendHTTPData(url, NULL, data, data_size); if(response) { if(response->responseCode == 200) { result = 1; } else { dbg_printf(P_ERROR, "Prowl Notification failed: %s (%d)", getProwlErrorMessage(response->responseCode), response->responseCode); result = -response->responseCode; } HTTPResponse_free(response); } am_free(data); } return result; }
static void on_agent_request_data_cb(void *udata, const char *data, size_t data_sz, int status) { struct request_data *ld = (struct request_data *) udata; if (ld->data == NULL) { ld->data = malloc(data_sz + 1); if (ld->data == NULL) { ld->error = AM_ENOMEM; return; } memcpy(ld->data, data, data_sz); ld->data[data_sz] = 0; ld->data_size = data_sz; } else { char *rd_tmp = realloc(ld->data, ld->data_size + data_sz + 1); if (rd_tmp == NULL) { am_free(ld->data); ld->error = AM_ENOMEM; return; } else { ld->data = rd_tmp; } memcpy(ld->data + ld->data_size, data, data_sz); ld->data_size += data_sz; ld->data[ld->data_size] = 0; } }
char * am_mysql_query_return_row_0 (char *raw_query, struct plugin_conf *conf, struct client_context *client_context, const char *envp[], const char *argv[]) { MYSQL mysql; char *q = NULL; char *res = NULL; if (am_mysql_prepare_mysql (&mysql, conf) < 0 ){ LOGERROR ("Could not prepare MySQL connection in am_mysql_query_return_row_0\n"); return NULL; } q = am_mysql_prepare_query (&mysql, raw_query, client_context, envp, argv); if (q == NULL){ res = NULL; LOGERROR ("Failed to expand query %s\n", raw_query); goto query_return_row_0_free; } res = _am_mysql_query_return_row_0 (&mysql, q); query_return_row_0_free: /* Free resources */ mysql_close(&mysql); if (q != NULL) am_free (q); return res; }
auto_handle* session_init(void) { char path[MAXPATHLEN]; char *home; auto_handle *ses = am_malloc(sizeof(auto_handle)); /* numbers */ ses->max_bucket_items = AM_DEFAULT_MAXBUCKET; ses->bucket_changed = 0; ses->check_interval = AM_DEFAULT_INTERVAL; /* strings */ ses->download_folder = get_temp_folder(); home = get_home_folder(); sprintf(path, "%s/%s", home, AM_DEFAULT_STATEFILE); am_free(home); ses->statefile = am_strdup(path); ses->prowl_key = NULL; ses->prowl_key_valid = 0; ses->download_done_script = NULL; ses->match_only = 0; /* lists */ ses->filters = NULL; ses->feeds = NULL; ses->downloads = NULL; return ses; }
int am_mysql_simple_query (char *raw_query, struct plugin_conf *conf, struct client_context *client_context, const char *envp[], const char *argv[]){ MYSQL mysql; char *q = NULL; int rc = -1; if (am_mysql_prepare_mysql (&mysql, conf) < 0 ){ LOGERROR ("Could not prepare MySQL connection in am_mysql_simple_query\n"); return -1; } q = am_mysql_prepare_query (&mysql, raw_query, client_context, envp, argv); if (q == NULL){ rc = -1; LOGERROR ("Failed to expand query %s\n", raw_query); goto simple_query_free; } rc = _am_mysql_simple_query (&mysql, q); simple_query_free: /* Free resources */ mysql_close(&mysql); if (q != NULL) am_free (q); return rc; }
PRIVATE size_t write_header_callback(void *ptr, size_t size, size_t nmemb, void *data) { size_t line_len = size * nmemb; WebData *mem = (WebData*)data; const char *line = (const char*)ptr; char *tmp = NULL; char *filename = NULL; const char *content_pattern = "Content-Disposition:\\s(inline|attachment);\\s+filename=\"?(.+?)\"?;?\\r?\\n?$"; int content_length = 0; static uint8_t isMoveHeader = 0; /* check the header if it is a redirection header */ if(line_len >= 9 && !memcmp(line, "Location:", 9)) { isMoveHeader = 1; if(mem->response->data != NULL) { am_free(mem->response->data); mem->response->data = NULL; mem->response->buffer_size = 0; mem->content_length = 0; } } else if(line_len >= 15 && !memcmp(line, "Content-Length:", 15)) { /* parse header for Content-Length to allocate correct size for data->response->data */ tmp = getRegExMatch("Content-Length:\\s(\\d+)", line, 1); if(tmp != NULL) { dbg_printf(P_INFO2, "Content-Length: %s", tmp); content_length = atoi(tmp); if(content_length > 0 && !isMoveHeader) { mem->content_length = content_length; mem->response->buffer_size = content_length + 1; mem->response->data = am_realloc(mem->response->data, mem->response->buffer_size); } am_free(tmp); } } else if(line_len >= 19 && !memcmp(line, "Content-Disposition", 19)) { /* parse header for Content-Disposition to get correct filename */ filename = getRegExMatch(content_pattern, line, 2); if(filename) { mem->content_filename = filename; dbg_printf(P_INFO2, "[write_header_callback] Found filename: %s", mem->content_filename); } } else if(line_len >= 2 && !memcmp(line, "\r\n", 2)) { /* We're at the end of a header, reaset the relocation flag */ isMoveHeader = 0; } return line_len; }
PRIVATE int parseFeed(rss_feeds *feeds, const char* feedstr) { char *line = NULL, *option = NULL, *param = NULL; char *saveptr; char *str = NULL; rss_feed* feed = NULL; int result = SUCCESS; /* be optimistic */ str = shorten(feedstr); line = strtok_r(str, AM_DELIMITER, &saveptr); while (line) { if(!feed) { feed = feed_new(); assert(feed && "feed_new() failed!"); } if(parseSubOption(line, &option, ¶m) == 0) { if(!strncmp(option, "url", 3)) { feed->url = shorten(param); } else if(!strncmp(option, "cookies", 6)) { feed->cookies = shorten(param); } else { dbg_printf(P_ERROR, "Unknown suboption '%s'!", option); } am_free(option); am_free(param); } else { dbg_printf(P_ERROR, "Invalid suboption string: '%s'!", line); } line = strtok_r(NULL, AM_DELIMITER, &saveptr); } if(feed && feed->url) { /* Maybe the cookies are encoded within the URL */ if(feed->cookies == NULL) { parseCookiesFromURL(feed); } feed->id = listCount(*feeds); feed_add(feed, feeds); } else { dbg_printf(P_ERROR, "Invalid feed: '%s'", str); result = FAILURE; } am_free(str); return result; }
PRIVATE void session_free(auto_handle *as) { if (as) { am_free(as->download_folder); as->download_folder = NULL; am_free(as->statefile); as->statefile = NULL; am_free(as->prowl_key); as->prowl_key = NULL; am_free(as->download_done_script); as->download_done_script = NULL; freeList(&as->feeds, feed_free); freeList(&as->downloads, NULL); freeList(&as->filters, filter_free); am_free(as); as = NULL; } }
/** * Parse a <LO>-<HI> ip address range, and test that an ip address is in that range * * @return 0 on success */ static am_status_t get_in_bounded_range_status(const char * addr, const char * range) { int c; char *lo_p, *hi_p; char *p = strchr(range, '-'); if (p == NULL) { return AM_ENOMEM; } lo_p = strndup(range, p - range); hi_p = strdup(p + 1); if (lo_p && hi_p) { c = test_within_bounds(addr, lo_p, hi_p) ? AM_SUCCESS : AM_NOT_FOUND; } else { c = AM_ENOMEM; } am_free(lo_p); am_free(hi_p); return c; }
char* makeChangeUpSpeedJSON(torrent_id_t tID, uint32_t upspeed, uint8_t rpcVersion, uint32_t *setme_size) { char *buf = NULL; int buf_size, json_size = 0; const char *JSONstr = "{\n" "\"method\": \"torrent-set\",\n" "\"arguments\": {\n" "\"ids\": %d,\n" "\"%s\": %d,\n" "\"%s\": true\n" "}\n" "}"; *setme_size = 0; if(rpcVersion <= 0) { dbg_printf(P_ERROR, "Invalid RPC version: %d", rpcVersion); return NULL; } if(upspeed <= 0) { dbg_printf(P_ERROR, "Invalid upspeed value: %d", upspeed); return NULL; } if(tID <= 0) { dbg_printf(P_ERROR, "Invalid torrent ID: %d", tID); return NULL; } buf_size = strlen(JSONstr) + 60; buf = am_malloc(buf_size); if(!buf) { dbg_printf(P_DBG, "Mem alloc for JSON string failed!"); return NULL; } memset(buf, 0, buf_size); if(rpcVersion <= 4) { json_size = snprintf(buf, buf_size, JSONstr, tID, "speed-limit-up", upspeed, "speed-limit-up-enabled"); } else if(rpcVersion >= 5 ) { json_size = snprintf(buf, buf_size, JSONstr, tID, "uploadLimit", upspeed, "uploadLimited"); } if(json_size < 0 || json_size >= buf_size) { dbg_printf(P_ERROR, "Error producing JSON string with Base64-encoded metadata: %s", strerror(errno)); am_free(buf); return NULL; } buf[json_size] = '\0'; if(setme_size) { *setme_size = json_size; } return buf; }
/** * Create a list of expandable variables from envp and possibly argv */ am_list_t * create_expandable_variable_list (MYSQL *mysql, const char *envp[], const char *argv[]){ time_t t; char *escaped_username = NULL; char *escaped_password = NULL; const char *username, *password; am_list_t *l = am_list_new (); if (l == NULL) return l; t = time (NULL); username = get_env ("username", envp); password = get_env ("password", envp); if (username != NULL){ escaped_username = (char *) am_malloc (sizeof(char) * (strlen (username) * 2 + 1)); mysql_real_escape_string (mysql, escaped_username, username, strlen (username)); } if (password != NULL){ escaped_password = (char *) am_malloc (sizeof(char) * (strlen (password) * 2 + 1)); mysql_real_escape_string (mysql, escaped_password, password, strlen (password)); } am_list_append (l, kvp_new_with_kv (EV_DUP ("time_now"), strdupf ("%d", t))); am_list_append (l, kvp_new_with_kv (EV_DUP ("username"), NULL_OR_DUP (username))); am_list_append (l, kvp_new_with_kv (EV_DUP ("password"), NULL_OR_DUP (password))); am_list_append (l, kvp_new_with_kv (EV_DUP ("escaped_username"), NULL_OR_DUP (escaped_username))); am_list_append (l, kvp_new_with_kv (EV_DUP ("escaped_password"), NULL_OR_DUP (escaped_password))); am_list_append (l, kvp_new_with_kv (EV_DUP ("trusted_port"), NULL_OR_DUP (get_env ("trusted_port", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("trusted_ip"), NULL_OR_DUP (get_env ("trusted_ip", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("time_unix"), NULL_OR_DUP (get_env ("time_unix", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("ifconfig_pool_remote_ip"), NULL_OR_DUP (get_env ("ifconfig_pool_remote_ip", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("ifconfig_pool_local_ip"), NULL_OR_DUP (get_env ("ifconfig_pool_local_ip", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("ifconfig_local"), NULL_OR_DUP (get_env ("ifconfig_local", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("time_duration"), NULL_OR_DUP (get_env ("time_duration", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("bytes_sent"), NULL_OR_DUP (get_env ("bytes_sent", envp)))); am_list_append (l, kvp_new_with_kv (EV_DUP ("bytes_received"), NULL_OR_DUP (get_env ("bytes_received", envp)))); am_free (escaped_username); am_free (escaped_password); return l; }
static void deleteFirst(NODE **ptr_to_head) { NODE *p = NULL; if(*ptr_to_head != NULL) { p = *ptr_to_head; *ptr_to_head = p->next; am_free(p); p = NULL; } }
/** \brief Remove the first item of a list * * \param[in,out] head Pointer to a list * \param[in] freeFunc Function pointer for freeing the memory of the list item * * Removes the first element of the given list and frees all associated memory. * If freeFunc is NULL, it tries to directly free the data of each node. * For complex nodes (e.g. structs) the user needs to provide a node-specific free() function. */ void removeFirst(NODE **head, listFuncPtr freeFunc) { dbg_printf(P_DBG, "Removing first item..."); if (*head != NULL) { if(freeFunc) { freeFunc((*head)->data); } else { am_free((*head)->data); } deleteFirst(head); } }
PRIVATE void set_path(const char *src, char **dst) { char *tmp; if(src && strlen(src) < MAXPATHLEN) { tmp = resolve_path(src); if(tmp) { if ( *dst != NULL ) { am_free(*dst); } *dst = am_replace_str(tmp, "\\ ", " "); if(*dst == NULL) { dbg_printf(P_ERROR, "[set_path] Error executing am_replace_str()!"); } am_free(tmp); } } }
PRIVATE int parseFilter(am_filters *patlist, const char* match) { char *line = NULL, *option = NULL, *param = NULL; char *saveptr; char *str = NULL; am_filter filter = NULL; int result = SUCCESS; /* be optimistic */ str = shorten(match); line = strtok_r(str, AM_DELIMITER, &saveptr); while (line) { if(!filter) { filter = filter_new(); assert(filter && "filter_new() failed!"); } if(parseSubOption(line, &option, ¶m) == 0) { if(!strncmp(option, "pattern", 7)) { filter->pattern = shorten(param); } else if(!strncmp(option, "useragent", 9)) { filter->agent = shorten(param); } else { dbg_printf(P_ERROR, "Unknown suboption '%s'!", option); } am_free(option); am_free(param); } else { dbg_printf(P_ERROR, "Invalid suboption string: '%s'!", line); } line = strtok_r(NULL, AM_DELIMITER, &saveptr); } if(filter && filter->pattern) { filter_add(filter, patlist); } else { dbg_printf(P_ERROR, "Invalid filter: '%s'", str); result = FAILURE; } am_free(str); return result; }
torrent_id_t parseTorrentID(const char* response) { const char* result_regex = "\"id\":\\s*(\\d+)"; char *result_str = NULL; torrent_id_t id = -1; result_str = getRegExMatch(result_regex, response, 1); if(result_str) { id = atoi(result_str); am_free(result_str); } return id; }