int queue_empty(int sockfd) { socket_data_t *socket_data = get_socket_data(sockfd); if (socket_data->queue.head == NULL) return 1; else return 0; }
void queue_add(int sockfd, upload_queue_entry_t *entry) { socket_data_t *socket_data = get_socket_data(sockfd); mutex_acquire(&g_mutex); if (socket_data->queue.head == NULL) { socket_data->queue.head = entry; socket_data->queue.tail = entry; } else { socket_data->queue.tail->next = entry; socket_data->queue.tail = entry; } manage_queue(socket_data); mutex_release(&g_mutex); }
void queue_complete_head(int sockfd) { socket_data_t *socket_data = get_socket_data(sockfd); upload_queue_entry_t *entry = socket_data->queue.head; assert(entry != NULL); mutex_acquire(&g_mutex); socket_data->queue.head = entry->next; if (socket_data->queue.tail == entry) socket_data->queue.tail = NULL; free_entry(entry); socket_data->upload_active = 0; manage_queue(socket_data); mutex_release(&g_mutex); }
static int serve_client_in(CLIENT *client, int sock, const char *dir, const char *hostname) { FILE *fp = NULL; FILESTATS fstats; char in_dir[PATH_LEN+1]; char path[PATH_LEN+1]; int buflen; int cur_ptr = 0; int file_recvcnt = 0; int moredata = TRUE; int workbuflen = 0; unsigned char *workbuf = NULL; /*-------------------------------------------------------------------------+ | Create and validate the incoming file directory. +------------------------------------------------------------------------*/ errno = 0; sprintf(in_dir, "%s/%s/%s", dir, client->hostname, CHOUSESYS_INLOC); if ( !directory_validate(in_dir) ) { fprintf(stderr, "%s: %s: error: invalid input directory: %s\n", timestamp(), ProgName, in_dir); return 1; } /*-------------------------------------------------------------------------+ | Allocate space for working with the input data as it is received. This | buffer must be dynamically allocated to be the combined size of the | socket input data buffer and the end-of-data buffer. This size of | work buffer will allow enough input data to be read to scan for the | end-of-data marker even if it spans multiple socket retrievals. +------------------------------------------------------------------------*/ workbuf = (unsigned char *) malloc (CH_MSG_SIZE + client->eod.hex_buflen); if ( workbuf == NULL ) { fprintf(stderr, "%s: %s: error: could not allocate work buffer: %s\n", timestamp(), ProgName, strerror(errno)); return 1; } /*-------------------------------------------------------------------------+ | Process data in the work buffer until there isn't enough data left to | match the end-of-data marker. Add data to the work buffer from the | input socket connection when needed. +------------------------------------------------------------------------*/ while ( moredata || workbuflen >= client->eod.hex_buflen) { if ( workbuflen < client->eod.hex_buflen) { if (cur_ptr > 0) memmove(workbuf,&workbuf[cur_ptr],workbuflen); if ( get_socket_data(sock,hostname,&workbuf[workbuflen], &buflen,&moredata) != 0) break; workbuflen = workbuflen + buflen; cur_ptr = 0; } /*-------------------------------------------------------------------------+ | There is enough data in the work buffer to process. Prepare an | output file if there isn't one connected yet. +------------------------------------------------------------------------*/ else { if ( fp == NULL) { memset(&fstats, 0, sizeof(fstats)); sprintf(path, "%s/%s", in_dir, create_name(in_dir, client->hostname, "data")); if ( (fstats.name = (char *)strrchr(path, '/')) == NULL ) fstats.name = path; /* no path in path */ else fstats.name++; /* skip leading '/' */ if ( (fp = fopen(path, "w+")) == NULL ) { fprintf(stderr, "%s: %s: error: "); fprintf(stderr, "open \"%s\" failed: %s\n", fstats.name, strerror(ferror(fp))); if (workbuf != NULL) free(workbuf); return 1; } #ifdef DEBUG if ( Debug > 2 ) { PRINT_DBGLOC; fprintf(stderr, "Created/Opened file \"%s\"\n", basename(path)); } #endif } /*-------------------------------------------------------------------------+ | Check the current position in the work buffer for the | end-of-data marker. If found, switch to the next file. | Otherwise copy the character at the current position into the | current file. +------------------------------------------------------------------------*/ if ( memcmp(workbuf+cur_ptr, client->eod.hex_buf, client->eod.hex_buflen) == 0 ) { fflush(fp); fclose(fp); fp = NULL; file_recvcnt++; fprintf(stderr, "%s: %s: info: ", timestamp(), ProgName); fprintf(stderr, "receive succeeded from %s - ", hostname); fprintf(stderr, "file \"%s (%d bytes)\" saved\n", fstats.name, fstats.filesize); memset(&fstats, 0, sizeof(fstats)); sprintf(path, "%s/%s", in_dir, create_name(in_dir, client->hostname, "data")); if ( (fstats.name = (char *)strrchr(path, '/')) == NULL ) fstats.name = path; /* no path in path */ else fstats.name++; /* skip leading '/' */ if ( (fp = fopen(path, "w+")) == NULL ) { fprintf(stderr, "%s: %s: error: "); fprintf(stderr, "open \"%s\" failed: %s\n", fstats.name, strerror(ferror(fp))); if (workbuf != NULL) free(workbuf); return 1; } #ifdef DEBUG if ( Debug > 2 ) { PRINT_DBGLOC; fprintf(stderr, "Created/Opened file \"%s\"\n", basename(path)); } #endif cur_ptr = cur_ptr + client->eod.hex_buflen; workbuflen = workbuflen - client->eod.hex_buflen; } else { fstats.socksize++; if ( fputc(workbuf[cur_ptr], fp) == EOF ) { fprintf(stderr, "%s: %s: error: "); fprintf(stderr, "write \"%s\" failed: %s\n", fstats.name, strerror(ferror(fp))); break; } fstats.filesize++; cur_ptr++; workbuflen--; } } } /*-------------------------------------------------------------------------+ | Close connections for the last file processed. The last file should be | empty. The socket data stream should end with the end-of-data marker | which causes the last data to be written to the previous file. An | empty next file is created because we don't really know when the end | of the data will occur. If any data was written to the last file, then | an error in transmission occurred. +------------------------------------------------------------------------*/ if (fp != NULL) { fflush(fp); fclose(fp); fp = NULL; if ( fstats.filesize == 0 ) { unlink(path); } else { file_recvcnt++; fprintf(stderr, "%s: %s: info: ", timestamp(), ProgName); fprintf(stderr, "Error, extra data received from %s - ", hostname); fprintf(stderr, "file \"%s (%d bytes)\" saved\n", fstats.name, fstats.filesize); } } /*-------------------------------------------------------------------------+ | Log final statistics for this pass. +------------------------------------------------------------------------*/ fprintf(stderr, "%s: %s: info: completed %s: %d files received\n", timestamp(), ProgName, hostname, file_recvcnt); if (workbuf != NULL) free(workbuf); return 0; } /* serve_client_in() */