char *fdreadline(int sock) { static char buffer[BSIZ]; char *pos; #define RECV(len, flags, lbl_restart) \ lbl_restart: \ switch(recv(sock, buffer, len, flags)){ \ case -1: \ if(errno == EINTR) \ goto lbl_restart; \ output_perror("recv()"); \ return NULL; \ case 0: /* unexpected here - need \r\n\r\n */ \ return NULL; \ } RECV(sizeof buffer, MSG_PEEK, recv_1); if((pos = strchr(buffer, '\n'))){ int len = pos - buffer + 1; RECV(len, 0, recv_2); if(pos > buffer && pos[-1] == '\r') pos[-1] = '\0'; else *pos = '\0'; /* just \n, not \r\n, deal with it */ return strdup(buffer); } output_err(OUT_ERR, "util::readline(): buffer too small"); return NULL; }
/** * Process a purchase of one or more products and return the total cost. * * @return SUCCESS on success, else -1 */ static int do_buy(void) { Product *p = NULL; Product *p_copy = NULL; char buy_status[4]; char bc[BARCODE_SZ] = {0}; double cost = 0.0; struct list buy_list; // create buy list list_init(&buy_list, free); RECV(STDIN, buy_status, sizeof(buy_status)); // BUG: this loop could be used for memory exhaustion, it has no bound on buy_list. while (0 == memcmp(buy_status, (void *)BUY_MORE, sizeof(BUY_MORE))) { // recv barcode RECV(STDIN, bc, BARCODE_SZ); // find product in inventory with matching bar code p = get_product_by_barcode(bc); // if not found, return -1 if (NULL == p) { // clear buy list list_destroy(&buy_list); return -1; } // make copy of product p_copy = malloc(sizeof(Product)); MALLOC_OK(p_copy); memcpy(p_copy, p, sizeof(Product)); // add product to buy list list_insert_at_end(&buy_list, p_copy); // add to cost sum cost += p_copy->sfn(p_copy->model_num, p_copy->cost); // recv buy status RECV(STDIN, buy_status, sizeof(buy_status)); } if (0 != memcmp(buy_status, (void *)BUY_TERM, sizeof(BUY_TERM))) { list_destroy(&buy_list); return -1; } // send total cost SEND(STDOUT, (char *)&cost, sizeof(cost)); // clear buy list list_destroy(&buy_list); return SUCCESS; }
int recv_block(int sockfd, decoder& dpack) { dpack.reset(); char* buf = dpack.buffer(); size_t left = c_header_size; while (left) { int offset = c_header_size - left; int n = RECV(sockfd, buf + offset, left, 0); if (n <= 0) { return n; } left -= n; if (0 == left) { break; } } uint8_t version = dpack.version(); uint8_t headsize = dpack.headsize(); if (version != c_default_version || headsize != c_header_size) { printf("packet format error, version:%d, headsize:%d\n", version, headsize); return 0; } size_t bodyleft = dpack.length(); if (bodyleft > (c_buffer_size - c_header_size)) { printf("packet format error, bodylen:%lu\n", bodyleft); return 0; } size_t bodyoffset = c_header_size; while (bodyleft) { int n = RECV(sockfd, buf + bodyoffset, bodyleft, 0); if (n <= 0) { return n; } bodyleft -= n; bodyoffset += n; if (0 == bodyleft) { break; } } dpack.setsize(dpack.length() + c_header_size); return dpack.size(); }
/*Function is used to receive all data from the client. It also creates or overwrites the file in lab2/output directory.*/ void receiveFile(int sock){ int bytesIn = 0; long fileSize =0; char buffer[1000]; bzero(buffer,1000); int totalRecv = 0; char fileIn[50] = "output/"; /*Recieves the size of the file in 1st 4 bytes*/ bytesIn = RECV(sock,buffer,4,MSG_WAITALL); printf("bytes in: %d %s\n",bytesIn,buffer); if(bytesIn < 0){ perror("Error reading from socket!1st"); exit(1); } memcpy(&fileSize,buffer,4); fileSize = ntohl(fileSize); printf("The size of the file is: %d bytes.\n",fileSize); bzero(buffer,1000); /*Recieves the file name in 20 bytes*/ bytesIn = RECV(sock,buffer,20,MSG_WAITALL); printf("bytes in: %d\n",bytesIn); if(bytesIn < 0){ printf("Error reading from socket! Here"); exit(1); } strcat(fileIn,buffer); printf("The name of the outputfile will be %s.\n",fileIn); bzero(buffer,1000); /*Open the file and start receiving bytes as long as the total received is less than the total size of the file */ FILE *fname = fopen(fileIn,"wb"); if(fname == NULL){ printf("Could not write to file %s\n",fileIn); exit(1); } /* The while condition could probably be written more elegantly,I was getting 1000 more bytes than what was really in the file*/ while((fileSize-totalRecv) > 0){ bytesIn = RECV(sock,buffer,1000,0); if(bytesIn < 0){ printf("Error reading from socket!"); exit(1); } fwrite(buffer,1,bytesIn,fname); bzero(buffer,1000); totalRecv += bytesIn; printf("Total rcv'd this far %d\n",totalRecv); } printf("Total bytes recieved: %d\n",totalRecv); close(fname); close(sock); }
/** * Determine the model number, cost, and description of the product * that is associated with a barcode. If the product is on sale, this * check will return the sale price. * * @return SUCCESS on success, else -1 */ static int do_check(void) { Product *p = NULL; char bc[BARCODE_SZ] = {0}; float sale_price = 0.0; unsigned int d_len = 0; // recv barcode RECV(STDIN, bc, BARCODE_SZ); // find product in inventory with matching bar code p = get_product_by_barcode(bc); // if not found, return -1 if (NULL == p) return -1; // if found, send model number, cost, and description SEND(STDOUT, (char *)&p->model_num, sizeof(unsigned int)); sale_price = p->sfn(p->model_num, p->cost); SEND(STDOUT, (char *)&sale_price, sizeof(float)); d_len = strlen(p->desc, '\0'); if (0 < d_len) SEND(STDOUT, p->desc, d_len); // terminate the description string SEND(STDOUT, DESC_TERM, 1); return SUCCESS; }
void echo_connection_handler(schedule* s, void* args) { int connfd = (int)(intptr_t)args; const size_t len = 1024; char buf[len] = { 0 }; while (true) { memset(buf, 0, len); ssize_t n = RECV(connfd, buf, len, 0); if (n <= 0) { printf("RECV return %ld\n", n); break; } cnt += 1; if (cnt % 2) { set_device_online("abc", "xyz", 0); } else { set_device_offline("abc", "xyz"); } printf("receive: %s\n", buf); SEND(connfd, buf, n, 0); } close(connfd); }
/** * Process the input to determine if there is a relationship between 2 people * * @param bytes Number of bytes available to receive * @return SUCCESS on success, else -1 on error */ int cgc_cmd_are_related(cgc_size_t bytes) { int ret = SUCCESS; cgc_size_t bytes_needed = 2*sizeof(uint32_t); // IDs for person1 and person2 if (bytes != bytes_needed) { return -1; } char *buf = cgc_calloc(bytes_needed); MALLOC_OK(buf); RECV(buf, bytes_needed); uint32_t *id = (uint32_t *)buf; Person *person1 = cgc_get_person_by_id(cgc_person_list, id[0]); Person *person2 = cgc_get_person_by_id(cgc_person_list, id[1]); if ((NULL == person1) || (NULL == person2)) { ret = -1; goto ar_end; } ret = cgc_find_are_related(person1, person2); if ((RELATED == ret) || (NOT_RELATED == ret)) { cgc_send((char *)&ret, sizeof(int)); ret = SUCCESS; } ar_end: cgc_free(buf); return ret; }
/** * Process the input to set 2 persons as separated * * @param bytes Number of bytes available to receive * @return SUCCESS on success, else -1 */ int cgc_cmd_set_separated(cgc_size_t bytes) { int ret = SUCCESS; cgc_size_t bytes_needed = 2*sizeof(uint32_t); // IDs for person1 and person2 if (bytes != bytes_needed) { return -1; } char *buf = cgc_calloc(bytes_needed); MALLOC_OK(buf); RECV(buf, bytes_needed); uint32_t *id = (uint32_t *)buf; Person *person1 = cgc_get_person_by_id(cgc_person_list, id[0]); Person *person2 = cgc_get_person_by_id(cgc_person_list, id[1]); if ((NULL == person1) || (NULL == person2)) { ret = -1; goto ss_end; } ret = cgc_separate_two_persons(person1, person2); ss_end: cgc_free(buf); return ret; }
/** * Process the input to set a person as deceased. * * @param bytes Number of bytes available to receive * @return SUCCESS on success, else -1 */ int cgc_cmd_set_deceased(cgc_size_t bytes) { int ret = SUCCESS; cgc_size_t bytes_needed = sizeof(uint32_t) + sizeof(uint16_t); // ID, death_year for person1 if (bytes != bytes_needed) { return -1; } char *buf = cgc_calloc(bytes_needed); MALLOC_OK(buf); RECV(buf, bytes_needed); uint32_t *id = (uint32_t *)buf; uint16_t *death_year = (uint16_t *)buf; Person *person1 = cgc_get_person_by_id(cgc_person_list, id[0]); if (NULL == person1) { ret = -1; goto die_end; } person1->lifecycle.death_year = death_year[2]; die_end: cgc_free(buf); return ret; }
short process_cmd(void) { char cmd[4]; short ret = 0; RECV(STDIN, cmd, sizeof(cmd)); if (0 == memcmp((void *)CMD_BUY, cmd, sizeof(CMD_BUY))) { ret = do_buy(); } else if (0 == memcmp((void *)CMD_CHECK, cmd, sizeof(CMD_CHECK))) { ret = do_check(); } else if (0 == memcmp((void *)CMD_ADD, cmd, sizeof(CMD_ADD))) { ret = do_add(); } else if (0 == memcmp((void *)CMD_RM, cmd, sizeof(CMD_RM))) { ret = do_rm(); } else if (0 == memcmp((void *)CMD_UPDATE, cmd, sizeof(CMD_UPDATE))) { ret = do_update(); } else if (0 == memcmp((void *)CMD_ONSALE, cmd, sizeof(CMD_ONSALE))) { ret = do_onsale(); } else if (0 == memcmp((void *)CMD_NOSALE, cmd, sizeof(CMD_NOSALE))) { ret = do_nosale(); } else if (0 == memcmp((void *)CMD_LIST, cmd, sizeof(CMD_LIST))) { ret = do_list(); } else if (0 == memcmp((void *)CMD_QUIT, cmd, sizeof(CMD_QUIT))) { ret = -2; } else { ret = -1; } return ret; }
static THREAD_RETURN returnChannelMain(void *args) { struct returnChannel *returnChannel = (struct returnChannel *) args; fd_set read_set; int r=0; FD_ZERO(&read_set); while(1) { struct sockaddr_in from; int clNo; int pos = pc_getConsumerPosition(returnChannel->freeSpace); pc_consumeAny(returnChannel->freeSpace); do { struct timeval tv; if(returnChannel->stopIt) return 0; FD_SET(returnChannel->rcvSock,&read_set); tv.tv_sec=0; tv.tv_usec=100; r = select(returnChannel->rcvSock+1, &read_set, NULL, NULL, &tv); } while(r==0); RECV(returnChannel->rcvSock, returnChannel->q[pos].msg, from, returnChannel->config->portBase); clNo = udpc_lookupParticipant(returnChannel->participantsDb, &from); if (clNo < 0) { /* packet from unknown provenance */ continue; } returnChannel->q[pos].clNo = clNo; pc_consumed(returnChannel->freeSpace, 1); pc_produce(returnChannel->incoming, 1); } }
/* * Control operation to convert received syllables into notes * and send resulting notes back to client. * * Returns: * Success: SUCCESS * Failure: ERR_INVALID_SYLLABLE, ERR_TOO_MANY_SYLLABLES, * ERR_NO_SYLLABLES, ERR_NO_NOTES */ int cgc_to_notes(char *syllables_buf, char *notes_buf) { int ret = 0; int total_bytes_written = 0; uint32_t bytes_count = cgc_recv_bytes_count(); if (0 >= bytes_count) { return ERR_NO_SYLLABLES; } if (MAX_SYLLABLES_BYTES < bytes_count) { return ERR_TOO_MANY_SYLLABLES; } RECV(syllables_buf, bytes_count); total_bytes_written = cgc_process_syllables(bytes_count, syllables_buf, notes_buf); if (0 < total_bytes_written) { cgc_send_notes(total_bytes_written, notes_buf); ret = SUCCESS; } else if (0 == total_bytes_written) { ret = ERR_NO_NOTES; } else { ret = total_bytes_written; } return ret; }
int main(void) { uint32_t command[1] = {0}; int ret = 0; char *syllables_buf_p; ALLOC(BUFFER_LEN, &syllables_buf_p); char *notes_buf_p; ALLOC(BUFFER_LEN, ¬es_buf_p); while (1) { RECV(command, sizeof(uint32_t)); switch (command[0]) { case CMD_TO_SYLLABLES: ret = to_syllables(syllables_buf_p, notes_buf_p); break; case CMD_TO_NOTES: ret = to_notes(syllables_buf_p, notes_buf_p); break; default: ret = ERR_INVALID_CMD; } if (ret < 0) { SENDSI(ret); return ret; } else { memset((void *)syllables_buf_p, 0, BUFFER_LEN); memset((void *)notes_buf_p, 0, BUFFER_LEN); } } return ret; }
int main(void) { uint32_t mode[1] = {0}; int ret = 0; while (1) { if ((ret = do_nonce()) == 0) { RECV(mode, sizeof(uint32_t)); switch (mode[0]) { case MODE_BUILD: ret = do_build(); break; case MODE_EXAMINE: ret = do_examine(); break; default: ret = ERR_INVALID_MODE; } } if (ret < 0) { SENDSI(ret); return ret; } } return ret; }
long CALLBACK NETrecvPadData(void *pData, int Pad) { if (PadInit == 0) { if (conf.PlayerNum == Pad) { memset(pData, 0xff, PadSendSize); } else { memset(pData, 0xff, PadRecvSize); } } else { if (conf.PlayerNum == Pad) { memcpy(pData, &PadSendData[PadCount == 0 ? PadCountMax-1 : PadCount-1], PadSendSize); } else { if (RECV(pData, PadRecvSize, PSE_NET_BLOCKING) == -1) return -1; } } if (Pad == 2) { PadCount++; if (PadCount == PadCountMax) { PadCount = 0; PadInit = 1; } } return 0; }
/** * Add a new person to the family tree * * @param bytes Number of bytes available to receive * @return SUCCESS on success, else -1 */ int cgc_cmd_add_person(cgc_size_t bytes) { int ret = SUCCESS; Person *p; if (bytes != PERSON_IN_SZ) { return -1; } char *buf = cgc_calloc(PERSON_IN_SZ); MALLOC_OK(buf); RECV(buf, PERSON_IN_SZ); p = cgc_new_person(buf); if (NULL == p) { ret = -1; goto cap_end; } cgc_add_person_to_list(&cgc_person_list, p); cgc_total_person_count++; cap_end: cgc_free(buf); return ret; }
/** * Process the addition of one new product to the inventory. * * @return SUCCESS on success, else -1 */ static int do_add(void) { Product *p = NULL; Product *p2 = NULL; int bytes_recvd = 0; // create product struct p = malloc(sizeof(Product)); MALLOC_OK(p); // set sfn to not on sale p->sfn = onsale_fn[0]; p->update_serial = 0; // recv barcode RECV(STDIN, (char *)p->barcode, BARCODE_SZ); // if barcode already exists, return -1 p2 = get_product_by_barcode((char *)p->barcode); if (NULL != p2) { free(p); return -1; } // recv model_num RECV(STDIN, (char *)&p->model_num, sizeof(unsigned int)); // recv cost RECV(STDIN, (char *)&p->cost, sizeof(float)); // recv desc // VULN: sizeof(Product) is > MAX_DESC_LEN, so can overflow 24 bytes // (4 model_num, 4 cost, 4 sfn and 12 heap meta). #ifdef PATCHED_1 bytes_recvd = recv_until_delim_n(STDIN, DESC_TERM[0], (char *)p->desc, MAX_DESC_LEN); #else bytes_recvd = recv_until_delim_n(STDIN, DESC_TERM[0], (char *)p->desc, sizeof(Product)); #endif if (0 >= bytes_recvd) _terminate(ERRNO_RECV); // make desc NULL terminated p->desc[bytes_recvd - 1] = '\0'; // add to Inventory list_insert_at_end(&inv, p); return SUCCESS; }
int TcpSocket::rawReceiveBytes(char *buffer, shared_int num_bytes) { int rc = this->SOCKET_FAIL; rc = RECV(this->getSockHandle(), buffer, num_bytes, 0); return rc; }
void com_message_loop(void *parameters) { MessageLoopParameter *mlp = (MessageLoopParameter*)parameters; char data[mlp->buffer_size]; int32_t length; int32_t received; while(true) { length = 0; while(length < SIZE_OF_MESSAGE_HEADER) { received = RECV(data + length, mlp->buffer_size - length, mlp->com_type, NULL); if(received == 0) { taskYIELD(); } else { length += received; } } MessageHeader *header = (MessageHeader*)data; // TODO: If header->length > 80: Out-Of-Sync-Handling while(length < header->length) { received = RECV(data + length, header->length - length, mlp->com_type, NULL); if(received == 0) { taskYIELD(); } else { length += received; } } // com_debug_message(header); led_rxtx++; mlp->return_func(data, header->length); taskYIELD(); } }
/* * discard: if true, discard the payloads. If false, enqueue the work */ static adlb_code steal_payloads(int target, int count, int *single_count, int *par_count, bool discard) { assert(count > 0); MPI_Status status; int length = count * (int)sizeof(struct packed_steal_work); struct packed_steal_work* wus = malloc((size_t)length); valgrind_assert(wus); RECV(wus, length, MPI_BYTE, target, ADLB_TAG_RESPONSE_STEAL); int single = 0, par = 0; for (int i = 0; i < count; i++) { assert(wus[i].length > 0); xlb_work_unit *work = work_unit_alloc((size_t)wus[i].length); RECV(work->payload, wus[i].length, MPI_BYTE, target, ADLB_TAG_RESPONSE_STEAL); if (!discard) { xlb_work_unit_init(work, wus[i].type, wus[i].putter, wus[i].answer, wus[i].target, wus[i].length, wus[i].opts); xlb_workq_add(work); } else { xlb_work_unit_free(work); } if (wus[i].opts.parallelism > 1) { par++; } else { single++; } } free(wus); DEBUG("[%i] received batch size %i", xlb_s.layout.rank, count); *single_count = single; *par_count = par; return ADLB_SUCCESS; }
/** * Process the update of one product in the inventory. * * @return SUCCESS on success, else -1 */ static int do_update(void) { int bytes_recvd = 0; Product *p = NULL; unsigned int (*desc_copy)(void *dst, const void *src, unsigned int cnt) = memcpy; char bc[BARCODE_SZ] = {0}; char desc_buf[MAX_DESC_LEN] = {0}; // recv barcode RECV(STDIN, (char *)bc, BARCODE_SZ); // if barcode does not exist, return -1 p = get_product_by_barcode((char *)bc); if (NULL == p) { return -1; } // recv new model_num RECV(STDIN, (char *)&p->model_num, sizeof(unsigned int)); // recv new cost RECV(STDIN, (char *)&p->cost, sizeof(float)); // recv desc // VULN: sizeof(Product) is > MAX_DESC_LEN, so can overflow 24 bytes // 8 bc, 4 desc_copy, 4 p, 4 bytes_recvd, 4 extra #ifdef PATCHED_2 bytes_recvd = recv_until_delim_n(STDIN, DESC_TERM[0], desc_buf, MAX_DESC_LEN); #else bytes_recvd = recv_until_delim_n(STDIN, DESC_TERM[0], desc_buf, sizeof(Product)); #endif if (0 >= bytes_recvd) _terminate(ERRNO_RECV); // make desc NULL terminated desc_buf[bytes_recvd - 1] = '\0'; desc_copy(p->desc, desc_buf, MAX_DESC_LEN); p->update_serial = get_next_update_serial(); // make use of the FLAG_PAGE... just cuz. return SUCCESS; }
int sockPing() { char data[32]; struct timeval tv, tvn; memset(data, 0, sizeof(data)); gettimeofday(&tv, NULL); SEND(data, 32, PSE_NET_BLOCKING); RECV(data, 32, PSE_NET_BLOCKING); gettimeofday(&tvn, NULL); return (int)(tvn.tv_sec - tv.tv_sec) * 1000 + (tvn.tv_usec - tv.tv_usec) / 1000; }
/** * Process the activation of a sale on one product in the inventory. * * @return SUCCESS on success, else -1 */ static int do_onsale(void) { Product *p = NULL; char bc[BARCODE_SZ] = {0}; unsigned int sale_percent = 0; // recv barcode RECV(STDIN, bc, BARCODE_SZ); // find product in inventory with matching bar code p = get_product_by_barcode(bc); // if not found, return -1 if (NULL == p) return -1; // get the sale percent (as an int) RECV(STDIN, (char *)&sale_percent, sizeof(unsigned int)); if (100 <= sale_percent) return -1; // update product's sale fn ptr p->sfn = onsale_fn[sale_percent]; return SUCCESS; }
int main(int cgc_argc, char *cgc_argv[]) { int res = 0; reqpkt_t req = {0}; char *r; RAND(&valvepos,sizeof(valvepos),NULL); RECV(sizeof(reqpkt_t),(char *)&req); r = cgc_process_pkt(&req); SSENDL(cgc_strlen(r),r); return 0; }
/* * Generate a random nonce and send it to the client. * Read the value sent back from the client and verify that it matches the nonce. * * Returns: * Success: SUCCESS * Failure: ERR_INVALID_NONCE */ int do_nonce() { int ret = 0; char nonce[8] = "1234567"; if((ret = rand(nonce, 8)) < 0) {_terminate(ERR_RAND_FAILED);} SENDLL(nonce); char nonce_reply[8] = "1234567"; RECV(nonce_reply, 8); if (nonce[0] == nonce_reply[0]) { return SUCCESS; } else { return ERR_INVALID_NONCE; } }
/** * Process the listing of all products. Provide more detail depending on selected options. * * @return SUCCESS on success, else -1 */ static int do_list(void) { Product *p = NULL; char options[4] = {0}; unsigned int count = list_length(&inv); unsigned int d_len = 0; float sale_price = 0.0; struct node *cur = list_head_node(&inv); struct node *end = list_end_marker(&inv); // recv options RECV(STDIN, options, sizeof(options)); if (0 == count) return -1; // send product info while ((NULL != cur) && (cur != end)) { p = (Product *)cur->data; // send barcode SEND(STDOUT, (char *)p->barcode, BARCODE_SZ); if (0 == options[0] % 2) { // send model_num SEND(STDOUT, (char *)&p->model_num, sizeof(unsigned int)); } if (0 != options[1] % 2) { // send cost SEND(STDOUT, (char *)&p->cost, sizeof(float)); } if (0 == options[2] % 2) { // send sale cost sale_price = p->sfn(p->model_num, p->cost); SEND(STDOUT, (char *)&sale_price, sizeof(float)); } if (0 != options[3] % 2) { // send description d_len = strlen(p->desc, '\0'); if (0 < d_len) SEND(STDOUT, p->desc, d_len); // terminate the description string SEND(STDOUT, DESC_TERM, 1); } cur = list_next_node(cur); } return SUCCESS; }
long CALLBACK NETsendPadData(void *pData, int Size) { if (PadSendSize == -1) { PadSendSize = Size; if (SEND(&PadSendSize, 1, PSE_NET_BLOCKING) == -1) return -1; if (RECV(&PadRecvSize, 1, PSE_NET_BLOCKING) == -1) return -1; } memcpy(&PadSendData[PadCount], pData, Size); if (SEND(pData, PadSendSize, PSE_NET_BLOCKING) == -1) return -1; return 0; }
/** Non blocking read of socket. Put frame in temporary buffer. * @param[in] port = port context struct * @param[in] stacknumber = 0=primary 1=secondary stack * @return >0 if frame is available and read */ static int ecx_recvpkt(ecx_portt *port, int stacknumber) { int lp, bytesrx; ec_stackT *stack; if (!stacknumber) { stack = &(port->stack); } else { stack = &(port->redport->stack); } lp = sizeof(port->tempinbuf); bytesrx = RECV(*stack->sock, (*stack->tempbuf), lp, 0); port->tempinbufs = bytesrx; return (bytesrx > 0); }
/** * Process the de-activation of a sale on one product in the inventory. * * @return SUCCESS on success, else -1 */ static int do_nosale(void) { Product *p = NULL; char bc[BARCODE_SZ] = {0}; unsigned int sale_percent = 0; // recv barcode RECV(STDIN, bc, BARCODE_SZ); // find product in inventory with matching bar code p = get_product_by_barcode(bc); // if not found, return -1 if (NULL == p) return -1; // update product's sale fn ptr p->sfn = onsale_fn[0]; return SUCCESS; }
/** * Process the input to set a biological child relationship between child * and its father and/or mother. * * @param bytes Number of bytes available to receive * @return SUCCESS on success, else -1 */ int cgc_cmd_set_biological_child(cgc_size_t bytes) { int ret = SUCCESS; cgc_size_t bytes_needed = 3*sizeof(uint32_t); // IDs for child, mother, and father if (bytes != bytes_needed) { return -1; } char *buf = cgc_calloc(bytes_needed); MALLOC_OK(buf); RECV(buf, bytes_needed); uint32_t *id = (uint32_t *)buf; Person *child = cgc_get_person_by_id(cgc_person_list, id[0]); Person *mother = cgc_get_person_by_id(cgc_person_list, id[1]); Person *father = cgc_get_person_by_id(cgc_person_list, id[2]); // parent and children relations default to PERSON_UNKNOWN, so only change // if a known person is given as each parent. // Also, make sure both parents can have more biological children if ((NULL == child) || (NULL == mother) || (NULL == father) || (FALSE == cgc_can_have_more_biological_children(mother)) || (FALSE == cgc_can_have_more_biological_children(father))) { ret = -1; goto sbc_end; } // set child first, because it can fail; althrough it shouldn't if we got this far ret = cgc_set_biological_child(child, mother); if (-1 == ret) goto sbc_end; cgc_set_biological_mother(child, mother); // set child first, because it can fail; althrough it shouldn't if we got this far ret = cgc_set_biological_child(child, father); if (-1 == ret) goto sbc_end; cgc_set_biological_father(child, father); sbc_end: cgc_free(buf); return ret; }