int main(void) { int status; int sd; struct packet_st pkt; struct sockaddr_in myend, hisend; socklen_t hislen; int val; int ret; int recv_len; database_init(); sd = socket(AF_INET, SOCK_DGRAM, 0); if (sd == -1) { perror("socket()"); goto socket_err; } val = 1; setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val)); myend.sin_family = AF_INET; myend.sin_port = SERVER_PORT; myend.sin_addr.s_addr = INADDR_ANY; ret = bind(sd, (struct sockaddr *)&myend, sizeof(myend)); if (ret == -1) { perror("bind()"); goto bind_err; } hislen = sizeof(hisend); status = ST_RECV; while (status != ST_QUIT) { switch (status) { case ST_RECV: recv_len = recvfrom(sd, &pkt, sizeof(pkt), 0, (struct sockaddr *)&hisend, &hislen); if (recv_len == -1) { status = ST_ERROR; break; } if (pkt.major == MAJOR_LOGIN) { status = ST_LOGIN; } else if (pkt.major == MAJOR_MESSAGE) { status = ST_MSG; } else if (pkt.major == MAJOR_LIST) { status = ST_LIST; } else if (pkt.major == MAJOR_HEART) { status = ST_HEART; } else if (pkt.major == MAJOR_MANAGE) { /* fix me */ status = ST_RECV; } else if (pkt.major == MAJOR_ERROR) { status = ST_ERROR; } else { status = ST_ERROR; } break; case ST_LOGIN: ret = login(sd, &pkt, recv_len, &hisend); if (ret == 0) { status = ST_RECV; } else { status = ST_ERROR; } break; case ST_MSG: message(sd, &pkt, recv_len, &hisend); status = ST_RECV; break; case ST_LIST: list(sd, &pkt, recv_len, &hisend); status = ST_RECV; break; case ST_HEART: heart(sd, &pkt, recv_len, &hisend); status = ST_RECV; break; case ST_ERROR: /* fix me */ status = ST_QUIT; break; } } close(sd); database_destroy(); return 0; bind_err: close(sd); socket_err: database_destroy(); return 1; }
/** * Runs the program. */ int main(int argc, char **argv) { char *category, **all_categories; customer_t *customer; float revenue; int i, num_categories; receipt_t *receipt; void *ignore; // Check for the proper amount of arguments if (argc != 4) { fprintf(stderr, "Error: wrong number of arguments\n"); print_usage(); exit(EXIT_FAILURE); } // Figure out how many categories there are input_categories = malloc(strlen(argv[3]) + 1); strcpy(input_categories, argv[3]); all_categories = (char **) calloc(1024, sizeof(char *)); num_categories = 0; category = strtok(argv[3], " "); if (category == NULL) { fprintf(stderr, "Error: Must specify at least one category.\n"); exit(EXIT_FAILURE); } all_categories[0] = malloc(strlen(category) + 1); strcpy(all_categories[0], category); num_categories++; while ((category = strtok(NULL, " ")) != NULL) { all_categories[num_categories] = malloc(strlen(category) + 1); strcpy(all_categories[num_categories], category); num_categories++; } // Holds all the thread ids spawned later pthread_t tid[num_categories + 1]; // Set up customer database from file and our queue customerDatabase = setup_database(argv[1]); queue = queue_create(); // Spawn producer thread pthread_create(&tid[0], NULL, producer_thread, (void *) argv[2]); // Spawn all the consumer threads for (i = 0; i < num_categories; i++) { pthread_create(&tid[i + 1], NULL, consumer_thread, all_categories[i]); } // Wait for all the other threads to finish before continuing for (i = 0; i < num_categories + 1; i++) { pthread_join(tid[i], &ignore); } // Now we can print our final report printf("\n\n"); revenue = 0.0f; for (i = 0; i < MAXCUSTOMERS; i++) { customer = customerDatabase->customer[i]; if (customer == NULL) { continue; } // Print out this customer's data printf("=== Customer Info ===\n"); printf("--- Balance ---\n"); printf("Customer name: %s\n", customer->name); printf("Customer ID number: %d\n", customer->customer_id); printf("Remaining credit: %.2f\n", customer->credit_limit); // Successful book orders printf("\n--- Successful orders ---\n"); if (queue_isempty(customer->successful_orders)) { printf("\tNone.\n"); } else { while ((receipt = (receipt_t *) queue_dequeue(customer->successful_orders)) != NULL) { printf("%s|%.2f|%.2f\n", receipt->title, receipt->price, receipt->remaining_credit); revenue += receipt->price; receipt_destroy(receipt); } } // Failed book orders printf("\n--- Failed orders ---\n"); if (queue_isempty(customer->failed_orders)) { printf("None.\n"); } else { while ((receipt = (receipt_t *) queue_dequeue(customer->failed_orders)) != NULL) { printf("%s|%.2f\n", receipt->title, receipt->price); receipt_destroy(receipt); } } printf("=== End Customer Info ===\n\n"); } printf("Total Revenue: $%.2f\n", revenue); // Free all the memory we allocated database_destroy(customerDatabase); queue_destroy(queue, NULL); return EXIT_SUCCESS; }