static int post_file(newspost_data *data, file_entry *file_data, int filenumber, int number_of_files, const char *filestring, char *data_buffer) { long number_of_bytes; int j, retval; int number_of_tries = 0; int parts_posted = 0; int number_of_parts = get_number_of_encoded_parts(data, file_data); static int total_failures = 0; boolean posting_started = FALSE; Buff * subject = NULL; if(file_data->parts != NULL){ if(file_data->parts[0] == TRUE) return NORMAL; } for (j = 1; j <= number_of_parts; j++) { if ((file_data->parts != NULL) && (file_data->parts[j] == FALSE)) continue; subject = make_subject(subject, data, filenumber, number_of_files, file_data->filename->data, j, number_of_parts, filestring); number_of_bytes = get_encoded_part(data, file_data, j, data_buffer); if (posting_started == FALSE) { ui_posting_file_start(data, file_data, number_of_parts, number_of_bytes); posting_started = TRUE; } ui_posting_part_start(file_data, j, number_of_parts, number_of_bytes); retval = nntp_post(subject->data, data, data_buffer, number_of_bytes, FALSE); if (retval == NORMAL) { ui_posting_part_done(file_data, j, number_of_parts, number_of_bytes); parts_posted++; } else if (retval == POSTING_NOT_ALLOWED) return retval; else { if (number_of_tries < 5) { ui_nntp_posting_retry(); sleep(5); number_of_tries++; continue; } else { total_failures++; if (total_failures == 5) { nntp_logoff(); socket_close(); ui_too_many_failures(); } } } number_of_tries = 0; } buff_free(subject); ui_posting_file_done(); return NORMAL; }
static int encode_and_post(newspost_data *data, SList *file_list, SList *parfiles) { int number_of_parts; int number_of_files; int i; file_entry *file_data = NULL; int retval = NORMAL; char *data_buffer = (char *) malloc(get_buffer_size_per_encoded_part(data)); Buff *subject = NULL; Buff *text_buffer = NULL; /* create the socket */ ui_socket_connect_start(data->address->data); retval = socket_create(data->address->data, data->port); if (retval < 0) return retval; ui_socket_connect_done(); /* log on to the server */ ui_nntp_logon_start(data->address->data); if (nntp_logon(data) == FALSE) { socket_close(); return LOGON_FAILED; } ui_nntp_logon_done(); if (data->text == TRUE) { file_data = file_list->data; /* post */ text_buffer = read_text_file(text_buffer, file_data->filename->data); if(text_buffer != NULL) retval = nntp_post(data->subject->data, data, text_buffer->data, text_buffer->length, TRUE); } else { /* post any sfv files... */ if (data->sfv != NULL) { file_data = file_entry_alloc(file_data); file_data->filename = buff_create(file_data->filename, "%s", data->sfv->data); if (stat(data->sfv->data, &file_data->fileinfo) == -1) ui_sfv_gen_error(data->sfv->data, errno); else { retval = post_file(data, file_data, 1, 1, "SFV File", data_buffer); if (retval < 0) return retval; unlink(data->sfv->data); } free(file_data); } number_of_files = slist_length(file_list); /* if there's a prefix, post that */ if (data->prefix != NULL) { ui_posting_prefix_start(data->prefix->data); file_data = (file_entry *) file_list->data; number_of_parts = get_number_of_encoded_parts(data, file_data); subject = make_subject(subject, data, 1 , number_of_files, file_data->filename->data, 0 , number_of_parts, "File"); text_buffer = read_text_file(text_buffer, data->prefix->data); if (text_buffer != NULL) { retval = nntp_post(subject->data, data, text_buffer->data, text_buffer->length, TRUE); if (retval == POSTING_NOT_ALLOWED) return retval; else if (retval == POSTING_FAILED) { /* dont bother retrying... who knows what's in that file */ ui_posting_prefix_failed(); retval = NORMAL; } else if (retval == NORMAL) ui_posting_prefix_done(); } else ui_posting_prefix_failed(); buff_free(subject); } /* post the files */ i = 1; while (file_list != NULL) { file_data = (file_entry *) file_list->data; retval = post_file(data, file_data, i, number_of_files, "File", data_buffer); if (retval < 0) return retval; i++; file_list = slist_next(file_list); } /* post any par files */ i = 1; file_list = parfiles; number_of_files = slist_length(parfiles); while (file_list != NULL) { file_data = (file_entry *) file_list->data; retval = post_file(data, file_data, i, number_of_files, "PAR File", data_buffer); if (retval < 0) return retval; unlink(file_data->filename->data); buff_free(file_data->filename); free(file_data); i++; file_list = slist_next(file_list); } slist_free(parfiles); } nntp_logoff(); socket_close(); free(data_buffer); buff_free(text_buffer); return retval; }
void * poster_thread( void *arg ) { npost_t *h = (npost_t *)arg; // Allocate buffers char *buffer; int ret; npost_item_t *item; int sockfd = -1; while( 1 ) { // Connect when necessary while( sockfd <= 0 ) { ret = nntp_connect( &sockfd, h->param.server, h->param.port, h->param.username, h->param.password ); if( ret == CONNECT_FAILURE ) return NULL; else if (ret == CONNECT_TRY_AGAIN_LATER ) { ret = conditional_sleep( h ); if( ret == 0 ) // Article list is empty return NULL; } } // Get an article to post pthread_mutex_lock(h->mut); item = h->head; if( h->head == NULL ) { // We're done pthread_cond_broadcast( h->cond_list_empty ); pthread_mutex_unlock(h->mut); break; } h->head = h->head->next; pthread_mutex_unlock(h->mut); // Post the article printf( "**** Posting! sockfd: %2d, filenum: %2d, partnum: %3d *****\n", sockfd, item->filenum, item->partnum ); size_t bytes_to_post = npost_get_part( &h->param, item->filenum, item->partnum, &buffer ); ret = nntp_post( sockfd, buffer, bytes_to_post ); free( buffer ); if( ret < 0 ) { // Put the article back in the queue as something went wrong item->next = NULL; pthread_mutex_lock(h->mut); if( h->head == NULL ) h->head = item; else h->tail->next = item; h->tail = item; pthread_mutex_unlock(h->mut); } // Depending on what went wrong, we either try again later, or kill ourselves if( ret == POST_TRY_LATER ) { nntp_logoff( tid, &sockfd ); int retval = conditional_sleep( h ); if( retval == 0 ) // Article list is empty return NULL; } else if ( ret == POST_FATAL_ERROR ) return NULL; // If posting went succesfully, free this item if( ret == 0 ) free( item ); } nntp_logoff( &sockfd ); return NULL; }