/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch_ofc_controllers_ofc_controller (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); print_element_names(node, 0); if (NULL == *data) { *data = calloc(1, sizeof(struct lsi)); assert(*data); } if ((XMLDIFF_ADD) & op) { if (NULL == LSI(data)->controller_list_add) { LSI(data)->controller_list_add = list_new(); assert(LSI(data)->controller_list_add); } list_append_data(LSI(data)->controller_list_add, __data); __data = NULL; } else if ((XMLDIFF_REM) & op) { if (NULL == LSI(data)->controller_list_del) { LSI(data)->controller_list_del = list_new(); assert(LSI(data)->controller_list_del); } list_append_data(LSI(data)->controller_list_del, __data); __data = NULL; } else { nc_verb_error("not implemented"); assert(0); } return EXIT_SUCCESS; }
/* add a bundle_result to the results list */ static void add_bundle_file_result(char *bundlename, char *filename, double score) { struct bundle_result *bundle = NULL; struct file_result *file; struct list *ptr; ptr = results; while (ptr) { struct bundle_result *item; item = ptr->data; if (strcmp(item->bundle_name, bundlename) == 0) { bundle = item; break; } ptr = ptr->next; } if (!bundle) { bundle = calloc(sizeof(struct bundle_result), 1); ON_NULL_ABORT(bundle); results = list_append_data(results, bundle); strncpy(bundle->bundle_name, bundlename, BUNDLE_NAME_MAXLEN - 1); /* record if the bundle is tracked on the system */ bundle->is_tracked = is_tracked_bundle(bundlename); } file = calloc(sizeof(struct file_result), 1); ON_NULL_ABORT(file); file->filename = strdup_or_die(filename); bundle->files = list_append_data(bundle->files, file); file->score = score; bundle->score += score; }
extern int bits_route_add(t_uint16 bits_addr, t_connection * conn) { t_bits_routing_table_entry * rte; if (!conn) { eventlog(eventlog_level_error,"bits_route_add","got NULL connection"); return -1; } if ((bits_addr==BITS_ADDR_PEER)||(bits_addr==BITS_ADDR_MASTER)||(bits_addr==BITS_ADDR_BCAST)) { /* eventlog(eventlog_level_warn,"bits_route_add","adding routes for special addresses would make no sense"); */ return 0; } rte = bits_route_find(bits_addr); if (rte) { if (rte->conn == conn) return 0; eventlog(eventlog_level_debug,"bits_route_add","changing existing route for 0x%04x from [%d] to [%d].",bits_addr,conn_get_socket(rte->conn),conn_get_socket(conn)); rte->conn = conn; } else { eventlog(eventlog_level_debug,"bits_route_add","adding route for 0x%04x to [%d].",bits_addr,conn_get_socket(conn)); rte = malloc(sizeof(t_bits_routing_table_entry)); if (!rte) { eventlog(eventlog_level_error,"bits_route_add","malloc failed: %s",strerror(errno)); return -1; } rte->bits_addr = bits_addr; rte->conn = conn; list_append_data(bits_routing_table,rte); } return 0; }
int dbs_server_list_add_socket(int sd, unsigned int ipaddr) { t_d2dbs_connection *it; struct in_addr in; it = (t_d2dbs_connection*)xmalloc(sizeof(t_d2dbs_connection)); std::memset(it, 0, sizeof(t_d2dbs_connection)); it->sd = sd; it->ipaddr = ipaddr; it->major = 0; it->minor = 0; it->type = 0; it->stats = 0; it->verified = 0; it->serverid = get_preset_d2gsid(ipaddr); it->last_active = std::time(NULL); it->nCharsInReadBuffer = 0; it->nCharsInWriteBuffer = 0; list_append_data(dbs_server_connection_list, it); in.s_addr = htonl(ipaddr); char addrstr[INET_ADDRSTRLEN] = { 0 }; inet_ntop(AF_INET, &(in), addrstr, sizeof(addrstr)); std::strncpy((char*)it->serverip, addrstr, sizeof(it->serverip) - 1); return 1; }
extern int addrlist_append(t_addrlist * addrlist, char const * str, unsigned int defipaddr, unsigned short defport) { t_addr * addr; char * tstr; char * tok; assert(addrlist != NULL); if (!str) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL str"); return -1; } tstr = xstrdup(str); for (tok = std::strtok(tstr, ","); tok; tok = std::strtok(NULL, ",")) /* std::strtok modifies the string it is passed */ { if (!(addr = addr_create_str(tok, defipaddr, defport))) { eventlog(eventlog_level_error, __FUNCTION__, "could not create addr"); xfree(tstr); return -1; } list_append_data(addrlist, addr); } xfree(tstr); return 0; }
extern int friendlist_add_account(t_list * flist, t_account * acc, int mutual) { t_friend * fr; if(flist==NULL) return -1; fr = xmalloc(sizeof(t_friend)); fr->friendacc = acc; fr->mutual = mutual; list_append_data(flist, fr); return 0; }
static bool parse_options(int argc, char **argv, struct list **opts) { int opt; while ((opt = getopt_long(argc, argv, "nb:h", prog_opts, NULL)) != -1) { command_option_t *option = NULL; bool bool_true = true; switch (opt) { case '?': case 'h': print_help(argv[0]); exit(EXIT_SUCCESS); case 'b': if (!optarg) { printf("Invalid --basepath argument\n\n"); return false; } option = construct_command_option("basepath", TYPE_STRING, optarg); *opts = list_append_data(*opts, option); break; case 'n': option = construct_command_option("no-xattrs", TYPE_BOOL, &bool_true); *opts = list_append_data(*opts, option); break; default: printf("error: unrecognized option\n\n"); return false; } } if (argc == optind) { printf("error: file name missing\n\n"); return false; } return true; }
int d2ladderlist_init(void) { t_d2ladder * d2ladder; unsigned int i; if (!d2ladder_ladder_file) return -1; d2ladder_list=list_create(); d2ladder_maxtype=D2LADDER_MAXTYPE; for (i=0;i<d2ladder_maxtype;i++) { d2ladder=(t_d2ladder*)xmalloc(sizeof(t_d2ladder)); d2ladder->type=i; d2ladder->info=NULL; d2ladder->len=0; list_append_data(d2ladder_list,d2ladder); } return 0; }
extern int addrlist_append(t_addrlist * addrlist, char const * str, unsigned int defipaddr, unsigned short defport) { t_addr * addr; char * tstr; char * tok; if (!str) { eventlog(eventlog_level_error,"addrlist_append","got NULL str"); return -1; } if (!addrlist) { eventlog(eventlog_level_error,"addrlist_append","got NULL addrlist"); return -1; } if (!(tstr = strdup(str))) { eventlog(eventlog_level_error,"addrlist_append","could not allocate memory for tstr"); return -1; } for (tok=strtok(tstr,","); tok; tok=strtok(NULL,",")) /* strtok modifies the string it is passed */ { if (!(addr = addr_create_str(tok,defipaddr,defport))) { eventlog(eventlog_level_error,"addrlist_append","could not create addr"); free(tstr); return -1; } if (list_append_data(addrlist,addr)<0) { eventlog(eventlog_level_error,"addrlist_append","could not add item to list"); addr_destroy(addr); free(tstr); return -1; } } free(tstr); return 0; }
int dbs_server_list_add_socket(int sd, unsigned int ipaddr) { t_d2dbs_connection *it; struct in_addr in; it=xmalloc(sizeof(t_d2dbs_connection)); memset(it, 0, sizeof(t_d2dbs_connection)); it->sd=sd; it->ipaddr=ipaddr; it->major=0; it->minor=0; it->type=0; it->stats=0; it->verified=0; it->serverid=get_preset_d2gsid(ipaddr); it->last_active=time(NULL); it->nCharsInReadBuffer=0; it->nCharsInWriteBuffer=0; list_append_data(dbs_server_connection_list,it); in.s_addr = htonl(ipaddr); strncpy(it->serverip, inet_ntoa(in), sizeof(it->serverip)-1); return 1; }
extern int autoupdate_load(char const * filename) { unsigned int line; unsigned int pos; char * buff; char * temp; char const * archtag; char const * clienttag; char const * mpqfile; char const * versiontag; t_autoupdate * entry; if (!filename) { eventlog(eventlog_level_error,__FUNCTION__,"got NULL filename"); return -1; } if (!(fp = fopen(filename,"r"))) { eventlog(eventlog_level_error,__FUNCTION__,"could not open file \"%s\" for reading (fopen: %s)",filename,pstrerror(errno)); return -1; } autoupdate_head = list_create(); for (line=1; (buff = file_get_line(fp)); line++) { for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++); if (buff[pos]=='\0' || buff[pos]=='#') { continue; } if ((temp = strrchr(buff,'#'))) { unsigned int len; unsigned int endpos; *temp = '\0'; len = strlen(buff)+1; for (endpos=len-1; buff[endpos]=='\t' || buff[endpos]==' '; endpos--); buff[endpos+1] = '\0'; } /* FIXME: use next_token instead of strtok */ if (!(archtag = strtok(buff, " \t"))) { /* strtok modifies the string it is passed */ eventlog(eventlog_level_error,__FUNCTION__,"missing archtag on line %u of file \"%s\"",line,filename); continue; } if (!(clienttag = strtok(NULL," \t"))) { eventlog(eventlog_level_error,__FUNCTION__,"missing clienttag on line %u of file \"%s\"",line,filename); continue; } if (!(versiontag = strtok(NULL, " \t"))) { eventlog(eventlog_level_error,__FUNCTION__,"missing versiontag on line %u of file \"%s\"",line,filename); continue; } if (!(mpqfile = strtok(NULL," \t"))) { eventlog(eventlog_level_error,__FUNCTION__,"missing mpqfile on line %u of file \"%s\"",line,filename); continue; } entry = (t_autoupdate*)xmalloc(sizeof(t_autoupdate)); if (!tag_check_arch((entry->archtag = tag_str_to_uint(archtag)))) { eventlog(eventlog_level_error,__FUNCTION__,"got unknown archtag"); xfree(entry); continue; } if (!tag_check_client((entry->clienttag = tag_str_to_uint(clienttag)))) { eventlog(eventlog_level_error,__FUNCTION__,"got unknown clienttag"); xfree(entry); continue; } entry->versiontag = xstrdup(versiontag); entry->mpqfile = xstrdup(mpqfile); eventlog(eventlog_level_debug,__FUNCTION__,"update '%s' version '%s' with file %s",clienttag,versiontag,mpqfile); list_append_data(autoupdate_head,entry); } file_get_line(NULL); // clear file_get_line buffer fclose(fp); return 0; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch_ofc_resources_ofc_port (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); print_element_names(node, 0); // retrieve the dpid of this twig xmlNodePtr tmp = find_element(BAD_CAST "datapath-id", node->parent->parent->children); assert(tmp); uint64_t dpid = parse_dpid(tmp->children->content); int rv = EXIT_SUCCESS; // fixme depending on the erropt (e.g. NC_EDIT_ERROPT_ROLLBACK we might still have *data set) assert(data); if (NULL == *data) { *data = calloc(1, sizeof(struct lsi)); assert(*data); } if (XMLDIFF_ADD & op) { xmlChar buf[255]; // check if port is already attached xmlStrPrintf(buf, sizeof(buf), "/ofc:capable-switch/ofc:logical-switches/ofc:switch/ofc:resources/ofc:port[text()='%s']", XML_GET_CONTENT(node->children)); xmlXPathObjectPtr xpath_obj_ptr = get_node(node->doc, namespace_mapping, buf); assert(xpath_obj_ptr); assert(xpath_obj_ptr->nodesetval); if (1 == xpath_obj_ptr->nodesetval->nodeNr) { if (NULL == LSI(data)->res.port_list_add) { LSI(data)->res.port_list_add = list_new(); assert(((struct lsi* )*data)->res.port_list_add); } struct port *p = calloc(1, sizeof(struct port)); p->resource_id = xmlNodeListGetString(node->doc, node->children, 1); p->op = ADD; p->dpid = dpid; list_append_data(LSI(data)->res.port_list_add, p); nc_verb_verbose("added to list: dpid=%lx port %s with op=%u\n", p->dpid, p->resource_id, p->op); } else { // nodeNr > 1 ==> already attached port nc_verb_verbose("attachment failed dpid=%lx port %s: port already attached.\n", dpid, XML_GET_CONTENT(node->children)); rv = EXIT_FAILURE; } xmlXPathFreeObject(xpath_obj_ptr); } else if (XMLDIFF_REM & op) { if (NULL == LSI(data)->res.port_list_del) { LSI(data)->res.port_list_del = list_new(); assert(((struct lsi* ) *data)->res.port_list_del); } struct port *p = calloc(1, sizeof(struct port)); p->resource_id = xmlNodeListGetString(node->doc, node->children, 1); p->op = DELETE; p->dpid = dpid; list_append_data(LSI(data)->res.port_list_del, p); nc_verb_verbose("added to list: dpid=%lx port %s with op=%u\n", p->dpid, p->resource_id, p->op); } else { // todo implement nc_verb_error("not implemented"); assert(0); } return rv; }
int main(int argc, char **argv) { struct list *list = NULL; struct list *list1, *list2; struct list *item, *item2, *item3, *head, *tail; unsigned int i; struct timeval tod; unsigned int seed; unsigned int len = TEST_LIST_LEN; clock_t t; unsigned int *data; /* List length must be greater than 3 for all tests to work */ if (argc > 1) { len = atoi(argv[1]); } if (len < 4) { printf("List length must be at least 4 for tests.\n"); return EXIT_FAILURE; } /* seed the random generator so that we get different lists each time */ gettimeofday(&tod, NULL); seed = (unsigned int) tod.tv_sec; srand(seed); /* create a list with random data between 0 and len */ for (i = 1; i <= len; i++) { data = malloc(sizeof(unsigned int)); if (!data) { printf("data allocation failed\n"); exit(-1); } *data = (unsigned int) rand() % len; list = list_append_data(list, data); } printf("List constructed, seed = %d, len = %d\n", seed, list_len(list)); t = clock(); list = list_sort(list, data_compare); t = clock() - t; /* check list elements are in right order */ if (check_list_order(list, 1) != 0) { printf ("Sorted (1) List is in wrong order\n"); return EXIT_FAILURE; } /* check sorted list has the expected len */ if (list_len(list) != len) { printf("Wrong sorted (1) list len = %d instead of %d", i, len); return EXIT_FAILURE; } // dump_list(list); printf("List sorted in %f seconds\n", (float) t / CLOCKS_PER_SEC); /* sort again on sorted list to check special case */ t = clock(); list = list_sort(list, data_compare); t = clock() - t; if (check_list_order(list, 1) != 0) { printf ("Sorted (2) List is in wrong order\n"); return EXIT_FAILURE; } if (list_len(list) != len) { printf("Wrong sorted (2) list len = %d instead of %d", i, len); return EXIT_FAILURE; } // dump_list(list); printf("Sorted list sorted again in %f seconds\n", (float) t / CLOCKS_PER_SEC); /* reverse sort from sorted state */ t = clock(); list = list_sort(list, data_compare_reverse); t = clock() - t; if (check_list_order(list, -1) != 0) { printf ("Sorted (3) List is in wrong order\n"); return EXIT_FAILURE; } if (list_len(list) != len) { printf("Wrong sorted (3) list len = %d instead of %d", i, len); return EXIT_FAILURE; } // dump_list(list); printf("Sorted list sorted reverse in %f seconds\n", (float) t / CLOCKS_PER_SEC); /* Check freeing the head item. * This must return the 2nd item, which must be the new head */ head = list_head(list); item2 = head->next; list = list_free_item(head, free); if (list != item2) { printf("removing head item did not return 2nd item\n"); return EXIT_FAILURE; } if (item2->prev) { printf("item returned after removing head is not new head\n"); return EXIT_FAILURE; } if (list_len(item2) != len - 1) { printf("removing head item did not result in the right list len\n"); return EXIT_FAILURE; } printf ("Removing head correctly returned 2nd item as new head\n"); /* Check freeing middle item, must return previous item */ head = list_head(list); item2 = head->next; item3 = item2->next; list = list_free_item(item2, free); if (list != head) { printf("removing 2nd item did not return head item\n"); return EXIT_FAILURE; } if ((head != item3->prev) || (head->next != item3)) { printf("removing 2nd item did not link 3rd item to head\n"); return EXIT_FAILURE; } if (list_len(list) != len - 2) { printf("removing 2nd item did not result in the right list len\n"); return EXIT_FAILURE; } printf ("Removing middle item correctly returned previous item\n"); /* Check freeing tail, must return new tail */ tail = list_tail(list); item = tail->prev; list = list_free_item(tail, free); if (list != item) { printf("removing tail did not return prev item\n"); return EXIT_FAILURE; } tail = list_tail(list); if (list != tail) { printf("removing tail did not return new tail\n"); return EXIT_FAILURE; } if (list_len(list) != len - 3) { printf("removing tail did not result in the right list len\n"); return EXIT_FAILURE; } printf ("Removing tail correctly returned previous item as new tail\n"); list_free_list_and_data(list, free); list = NULL; /* Check list_concat */ list1 = NULL; list2 = NULL; for (i = 3; i > 0; i--) { data = malloc(sizeof(unsigned int)); if (!data) { printf("data allocation failed\n"); exit(-1); } *data = (unsigned int) i; list1 = list_prepend_data(list1, data); } for (i = 6; i > 3; i--) { data = malloc(sizeof(unsigned int)); if (!data) { printf("data allocation failed\n"); exit(-1); } *data = (unsigned int) i; list2 = list_prepend_data(list2, data); } /* Check concat one list with empty list */ list = list_concat(list1, NULL); if (list_len(list) != 3) { printf("concat(list1, NULL) did not result in a list len of 3\n"); return EXIT_FAILURE; } if (list != list1) { printf("concat(list1, NULL) did not return list1\n"); return EXIT_FAILURE; } if (list_head(list) != list) { printf("concat(list1, NULL) did not return list1 head\n"); return EXIT_FAILURE; } if (*((unsigned int*)(list->data)) != 1) { printf("concat(list1, NULL) head is wrong\n"); return EXIT_FAILURE; } printf ("concat(list1, NULL) is OK\n"); // dump_list(list); /* Check concat empty list with one list*/ list = list_concat(NULL, list2); if (list_len(list) != 3) { printf("concat(NULL, list2) did not result in a list len of 3\n"); return EXIT_FAILURE; } if (list != list2) { printf("concat(NULL, list2) did not return list2\n"); return EXIT_FAILURE; } if (list_head(list) != list) { printf("concat(NULL, list2) did not return list2 head\n"); return EXIT_FAILURE; } if (*((unsigned int*)(list->data)) != 4) { printf("concat(NULL, list2) head is wrong\n"); return EXIT_FAILURE; } printf ("concat(NULL, list2) is OK\n"); // dump_list(list); /* Check concat two lists */ list = list_concat(list1->next, list2->next->next); if (list_len(list) != 6) { printf("concat(list1, list2) did not result in a list len of 6\n"); return EXIT_FAILURE; } if (*((unsigned int*)(list->data)) != 1) { printf("concat(list1, list2) did not return list1 head\n"); return EXIT_FAILURE; } if (*((unsigned int*)(list->next->next->next->data)) != 4) { printf("concat(list1, list2) 4th item is not 4\n"); return EXIT_FAILURE; } printf ("concat(list1, list2) is OK\n"); // dump_list(list); list_free_list_and_data(list, free); printf ("*** ALL LIST TESTS COMPLETED OK***\n"); return EXIT_SUCCESS; }
extern int gametrans_load(char const * filename) { FILE * fp; unsigned int line; unsigned int pos; char * buff; char * temp; char const * viewer; char const * client; char const * output; char const * exclude; t_gametrans * entry; if (!filename) { eventlog(eventlog_level_error,"gametrans_load","got NULL filename"); return -1; } if (!(gametrans_head = list_create())) { eventlog(eventlog_level_error,"gametrans_load","could not create list"); return -1; } if (!(fp = fopen(filename,"r"))) { eventlog(eventlog_level_error,"gametrans_load","could not open file \"%s\" for reading (fopen: %s)",filename,strerror(errno)); list_destroy(gametrans_head); gametrans_head = NULL; return -1; } for (line=1; (buff = file_get_line(fp)); line++) { for (pos=0; buff[pos]=='\t' || buff[pos]==' '; pos++); if (buff[pos]=='\0' || buff[pos]=='#') { free(buff); continue; } if ((temp = strrchr(buff,'#'))) { unsigned int len; unsigned int endpos; *temp = '\0'; len = strlen(buff)+1; for (endpos=len-1; buff[endpos]=='\t' || buff[endpos]==' '; endpos--); buff[endpos+1] = '\0'; } if (!(viewer = strtok(buff," \t"))) /* strtok modifies the string it is passed */ { eventlog(eventlog_level_error,"gametrans_load","missing viewer on line %u of file \"%s\"",line,filename); free(buff); continue; } if (!(client = strtok(NULL," \t"))) { eventlog(eventlog_level_error,"gametrans_load","missing client on line %u of file \"%s\"",line,filename); free(buff); continue; } if (!(output = strtok(NULL," \t"))) { eventlog(eventlog_level_error,"gametrans_load","missing output on line %u of file \"%s\"",line,filename); free(buff); continue; } if (!(exclude = strtok(NULL," \t"))) exclude = "0.0.0.0/0"; /* no excluded network address */ if (!(entry = malloc(sizeof(t_gametrans)))) { eventlog(eventlog_level_error,"gametrans_load","could not allocate memory for entry"); free(buff); continue; } if (!(entry->viewer = addr_create_str(viewer,0,0))) { eventlog(eventlog_level_error,"gametrans_load","could not allocate memory for viewer address"); free(entry); free(buff); continue; } if (!(entry->client = addr_create_str(client,0,6112))) { eventlog(eventlog_level_error,"gametrans_load","could not allocate memory for client address"); addr_destroy(entry->viewer); free(entry); free(buff); continue; } if (!(entry->output = addr_create_str(output,0,6112))) { eventlog(eventlog_level_error,"gametrans_load","could not allocate memory for output address"); addr_destroy(entry->client); addr_destroy(entry->viewer); free(entry); free(buff); continue; } if (!(entry->exclude = netaddr_create_str(exclude))) { eventlog(eventlog_level_error,"gametrans_load","could not allocate memory for exclude address"); addr_destroy(entry->output); addr_destroy(entry->client); addr_destroy(entry->viewer); free(entry); free(buff); continue; } free(buff); if (list_append_data(gametrans_head,entry)<0) { eventlog(eventlog_level_error,"gametrans_load","could not append item"); netaddr_destroy(entry->exclude); addr_destroy(entry->output); addr_destroy(entry->client); addr_destroy(entry->viewer); free(entry); } } if (fclose(fp)<0) eventlog(eventlog_level_error,"gametrans_load","could not close gametrans file \"%s\" after reading (fclose: %s)",filename,strerror(errno)); return 0; }
/* !DO NOT ALTER FUNCTION SIGNATURE! */ int callback_ofc_capable_switch_ofc_logical_switches_ofc_switch (void ** data, XMLDIFF_OP op, xmlNodePtr node, struct nc_err** error) { nc_verb_verbose("%s: data=%p, op=%d\n", __PRETTY_FUNCTION__, data, op); print_element_names(node, 0); if (NULL == ofc_state.lsi_list) { ofc_state.lsi_list = list_new(); assert(ofc_state.lsi_list); } assert(data); assert(*data); if (!(XMLDIFF_REM & op)) { list_append_data(ofc_state.lsi_list, *data); } int rv = EXIT_SUCCESS; if (XMLDIFF_ADD & op) { assert(XMLDIFF_CHAIN & op); nc_verb_verbose("create new lsi (dpid=%lu, name=%s)\n", LSI(data)->dpid, LSI(data)->dpname); if (lsi_create(ofc_state.xmp_client_handle, *data)) { rv = EXIT_FAILURE; } } else if (XMLDIFF_REM& op) { assert(XMLDIFF_CHAIN & op); nc_verb_verbose("destroy lsi (dpid=%lu, name=%s)\n", LSI(data)->dpid, LSI(data)->dpname); if ( lsi_destroy(ofc_state.xmp_client_handle, LSI(data)->dpid) ) { rv = EXIT_FAILURE; } // cannot have a port add during a lsi destroy assert(NULL == LSI(data)->res.port_list_add); // check if there were ports attached, then clean the list, because detachment takes place during lsi destruction if (NULL != LSI(data)->res.port_list_del) { struct port *p; while ((p = list_pop_head(LSI(data)->res.port_list_del))) { xmlFree(p->resource_id); free(p); } } // no need to deal with controllers seperately here lsi_cleanup(*data); } else if (XMLDIFF_MOD & op) { // direct sub elements changed nc_verb_error("not implemented XMLDIFF_MOD"); assert(0); } else if (XMLDIFF_CHAIN & op) { // resources or controllers changed (attachment of ports handled in parent) nc_verb_verbose("XMLDIFF_CHAIN\n"); // check dpid if (0 == LSI(data)->dpid) { xmlNodePtr tmp = find_element(BAD_CAST "datapath-id", node->children); assert(tmp); uint64_t dpid = parse_dpid(tmp->children->content); if (LSI(data)->dpid != dpid) { LSI(data)->dpid = dpid; } } if (LSI(data)->controller_list_add) { lsi_connect_to_controller(ofc_state.xmp_client_handle, LSI(data)); } if (LSI(data)->controller_list_del) { // fixme implement // assert(0); } } else { nc_verb_error("unsupported op"); assert(0); } *data = NULL; return rv; }
extern int versioncheck_load(char const * filename) { std::FILE * fp; unsigned int line; unsigned int pos; char * buff; char * temp; char const * eqn; char const * mpqfile; char const * archtag; char const * clienttag; char const * exeinfo; char const * versionid; char const * gameversion; char const * checksum; char const * versiontag; t_versioninfo * vi; if (!filename) { eventlog(eventlog_level_error, __FUNCTION__, "got NULL filename"); return -1; } if (!(versioninfo_head = list_create())) { eventlog(eventlog_level_error, __FUNCTION__, "could create list"); return -1; } if (!(fp = std::fopen(filename, "r"))) { eventlog(eventlog_level_error, __FUNCTION__, "could not open file \"%s\" for reading (std::fopen: %s)", filename, std::strerror(errno)); list_destroy(versioninfo_head); versioninfo_head = NULL; return -1; } line = 1; for (; (buff = file_get_line(fp)); line++) { for (pos = 0; buff[pos] == '\t' || buff[pos] == ' '; pos++); if (buff[pos] == '\0' || buff[pos] == '#') { continue; } if ((temp = std::strrchr(buff, '#'))) { unsigned int len; unsigned int endpos; *temp = '\0'; len = std::strlen(buff) + 1; for (endpos = len - 1; buff[endpos] == '\t' || buff[endpos] == ' '; endpos--); buff[endpos + 1] = '\0'; } if (!(eqn = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing eqn near line %u of file \"%s\"", line, filename); continue; } line++; if (!(mpqfile = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing mpqfile near line %u of file \"%s\"", line, filename); continue; } line++; if (!(archtag = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing archtag near line %u of file \"%s\"", line, filename); continue; } line++; if (!(clienttag = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing clienttag near line %u of file \"%s\"", line, filename); continue; } line++; if (!(exeinfo = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing exeinfo near line %u of file \"%s\"", line, filename); continue; } line++; if (!(versionid = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing versionid near line %u of file \"%s\"", line, filename); continue; } line++; if (!(gameversion = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing gameversion near line %u of file \"%s\"", line, filename); continue; } line++; if (!(checksum = next_token(buff, &pos))) { eventlog(eventlog_level_error, __FUNCTION__, "missing checksum near line %u of file \"%s\"", line, filename); continue; } line++; if (!(versiontag = next_token(buff, &pos))) { versiontag = NULL; } vi = (t_versioninfo*)xmalloc(sizeof(t_versioninfo)); vi->eqn = xstrdup(eqn); vi->mpqfile = xstrdup(mpqfile); if (std::strlen(archtag) != 4) { eventlog(eventlog_level_error, __FUNCTION__, "invalid arch tag on line %u of file \"%s\"", line, filename); xfree((void *)vi->mpqfile); /* avoid warning */ xfree((void *)vi->eqn); /* avoid warning */ xfree(vi); continue; } if (!tag_check_arch((vi->archtag = tag_str_to_uint(archtag)))) { eventlog(eventlog_level_error, __FUNCTION__, "got unknown archtag \"%s\"", archtag); xfree((void *)vi->mpqfile); /* avoid warning */ xfree((void *)vi->eqn); /* avoid warning */ xfree(vi); continue; } if (std::strlen(clienttag) != 4) { eventlog(eventlog_level_error, __FUNCTION__, "invalid client tag on line %u of file \"%s\"", line, filename); xfree((void *)vi->mpqfile); /* avoid warning */ xfree((void *)vi->eqn); /* avoid warning */ xfree(vi); continue; } if (!tag_check_client((vi->clienttag = tag_str_to_uint(clienttag)))) { eventlog(eventlog_level_error, __FUNCTION__, "got unknown clienttag\"%s\"", clienttag); xfree((void *)vi->mpqfile); /* avoid warning */ xfree((void *)vi->eqn); /* avoid warning */ xfree(vi); continue; } if (std::strcmp(exeinfo, "NULL") == 0) vi->parsed_exeinfo = NULL; else { if (!(vi->parsed_exeinfo = parse_exeinfo(exeinfo))) { eventlog(eventlog_level_error, __FUNCTION__, "encountered an error while parsing exeinfo"); xfree((void *)vi->mpqfile); /* avoid warning */ xfree((void *)vi->eqn); /* avoid warning */ xfree(vi); continue; } } vi->versionid = std::strtoul(versionid, NULL, 0); if (verstr_to_vernum(gameversion, &vi->gameversion) < 0) { eventlog(eventlog_level_error, __FUNCTION__, "malformed version on line %u of file \"%s\"", line, filename); xfree((void *)vi->parsed_exeinfo); /* avoid warning */ xfree((void *)vi->mpqfile); /* avoid warning */ xfree((void *)vi->eqn); /* avoid warning */ xfree(vi); continue; } vi->checksum = std::strtoul(checksum, NULL, 0); if (versiontag) vi->versiontag = xstrdup(versiontag); else vi->versiontag = NULL; list_append_data(versioninfo_head, vi); } file_get_line(NULL); // clear file_get_line buffer if (std::fclose(fp) < 0) eventlog(eventlog_level_error, __FUNCTION__, "could not close versioncheck file \"%s\" after reading (std::fclose: %s)", filename, std::strerror(errno)); return 0; }
/* * Download fullfiles from the list of files. * * Return 0 on success or a negative number or errors. */ int download_fullfiles(struct list *files, int *num_downloads) { struct swupd_curl_parallel_handle *download_handle; struct list *iter; struct list *need_download = NULL; struct file *file; struct stat stat; struct download_progress download_progress = { 0, 0, 0 }; unsigned int complete = 0; unsigned int list_length; const unsigned int MAX_FILES = 1000; if (!files) { /* nothing needs to be downloaded */ return SWUPD_OK; } /* make a new list with only the files we actually need to download */ for (iter = list_head(files); iter; iter = iter->next) { char *targetfile; file = iter->data; if (file->is_deleted || file->do_not_update) { continue; } string_or_die(&targetfile, "%s/staged/%s", state_dir, file->hash); if (lstat(targetfile, &stat) != 0 || !verify_file(file, targetfile)) { need_download = list_append_data(need_download, file); } free_string(&targetfile); } if (!need_download) { /* no file needs to be downloaded */ info("No extra files need to be downloaded\n"); progress_complete_step(); return 0; } /* we need to download some files, so set up curl */ download_handle = swupd_curl_parallel_download_start(get_max_xfer(MAX_XFER)); swupd_curl_parallel_download_set_callbacks(download_handle, download_successful, download_error, NULL); if (!download_handle) { /* If we hit this point, the network is accessible but we were * unable to download the needed files. This is a terminal error * and we need good logging */ return -SWUPD_COULDNT_DOWNLOAD_FILE; } /* getting the size of many files can be very expensive, so if * the files are not too many, get their size, otherwise just use their count * to report progress */ list_length = list_len(need_download); if (list_length < MAX_FILES) { download_progress.total_download_size = fullfile_query_total_download_size(need_download); if (download_progress.total_download_size > 0) { /* enable the progress callback */ swupd_curl_parallel_download_set_progress_callbacks(download_handle, swupd_progress_callback, &download_progress); } else { debug("Couldn't get the size of the files to download, using number of files instead\n"); download_progress.total_download_size = 0; } } else { debug("Too many files to calculate download size (%d files), maximum is %d. Using number of files instead\n", list_length, MAX_FILES); } /* download loop */ info("Starting download of remaining update content. This may take a while...\n"); for (iter = list_head(need_download); iter; iter = iter->next) { file = iter->data; if (file->is_mix) { download_mix_file(file); } else { download_file(download_handle, file); } /* fall back for progress reporting when the download size * could not be determined */ if (download_progress.total_download_size == 0) { complete++; progress_report(complete, list_length); } } info("\n"); list_free_list(need_download); return swupd_curl_parallel_download_end(download_handle, num_downloads); }