示例#1
0
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;
}
示例#2
0
int main( int argc, char **argv )
{
    npost_param_t param;

    int ret = npost_parse( argc, argv, &param );

    if ( ret < 0 ) {
        printf( "Error parsing commandline arguments.\n" );
        exit(1);
    }

    // First try to make just one connection, and see if it fails
    int testfd = 0;
    signal( SIGPIPE, SIG_IGN );
    ret = nntp_connect( &testfd, param.server, param.port, param.username, param.password );
    if( ret == CONNECT_FAILURE )
    {
        printf( "Failed to make even a single connection! Exiting...\n" );
        return -1;
    }
    nntp_logoff( &testfd );

    // Initialize a handle to be used by the threads
    npost_t h;

    memcpy( &h, &param, sizeof(npost_param_t) );
    h.threads = NULL;
    h.head = NULL;
    h.tail = NULL;
    h.mut = malloc( sizeof(pthread_mutex_t) );
    pthread_mutex_init( h.mut, NULL);

    h.cond_list_empty = malloc( sizeof(pthread_cond_t) );
    pthread_cond_init( h.cond_list_empty, NULL );

    // Let's add parts to the queue!
    size_t blocksize = YENC_LINE_LENGTH * param.lines;
    for( int f = 0; f < param.n_split_files; f++ )
    {
        diskfile_t *df = &param.split_files[f];
        crc32_file( df );
        int parts = (param.split_files[f].filesize + blocksize - 1) / blocksize;

        for( int p = 0; p < parts; p++ )
        {
            if( h.head == NULL )
            {
                h.head = malloc( sizeof(npost_item_t) );
                h.tail = h.head;
            }
            else
            {
                h.tail->next = malloc( sizeof(npost_item_t) );
                h.tail = h.tail->next;
            }

            h.tail->filenum = f;
            h.tail->partnum = p;
            h.tail->next = NULL;
        }
    }

    // Initialize the threads, and give each thread its own copy of the handle
    h.threads = malloc( param.threads * sizeof(pthread_t) );

    for ( int i = 0; i < param.threads; i++ )
        pthread_create( &h.threads[i], NULL, poster_thread, &h );

    for( int i = 0; i < param.threads; i++ )
        pthread_join( h.threads[i], NULL );

    // free all the mallocs!
    free( h.threads );

    pthread_mutex_destroy( h.mut );
    free( h.mut );

    pthread_cond_destroy( h.cond_list_empty );
    free( h.cond_list_empty );

    free( param.server );
    free( param.username );
    free( param.password );
    free( param.name );
    free( param.email );
    free( param.newsgroups );
    free( param.comment );

    for ( int i = 0; i < param.n_input_files; i++ )
    {
        free( param.input_files[i].filename_in );
        free( param.input_files[i].filename_out );
    }
    free( param.input_files );

    for ( int i = 0; i < param.n_split_files; i++ )
    {
        free( param.split_files[i].filename_in );
        free( param.split_files[i].filename_out );
    }
    free( param.split_files );

    return 0;

}
示例#3
0
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;
}
示例#4
0
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;
}