コード例 #1
0
ファイル: npost.c プロジェクト: PietjeBell88/npost
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;

}
コード例 #2
0
ファイル: scannews.c プロジェクト: bbs-io/mbse
/*
 *  Scan for new news available at the nntp server.
 */
void ScanNews(void)
{
    List		*art = NULL;
    POverview		tmp, old;
    FILE		*pAreas;
    char		*sAreas;
    struct msgareashdr	Msgshdr;
    struct msgareas	Msgs;

    IsDoing((char *)"Scan News");
    if (nntp_connect() == -1) {
	WriteError("Can't connect to newsserver");
	return;
    }
    if (get_xoverview()) {
	return;
    }

    if (!do_quiet) {
	mbse_colour(LIGHTGREEN, BLACK);
	printf("Scan for new news articles\n");
    }

    sAreas = calloc(PATH_MAX, sizeof(char));
    snprintf(sAreas, PATH_MAX, "%s/etc/mareas.data", getenv("MBSE_ROOT"));
    if(( pAreas = fopen (sAreas, "r")) == NULL) {
	WriteError("$Can't open Messages Areas File.");
	return;
    }
    fread(&Msgshdr, sizeof(Msgshdr), 1, pAreas);

    while (fread(&Msgs, Msgshdr.recsize, 1, pAreas) == 1) {
	fseek(pAreas, Msgshdr.syssize, SEEK_CUR);
#ifdef USE_NEWSGATE
	if ((Msgs.Active) && strlen(Msgs.Newsgroup)) {
#else
	if ((Msgs.Active) && strlen(Msgs.Newsgroup) && (Msgs.Type == NEWS)) {
#endif
	    if (IsSema((char *)"upsalarm")) {
		Syslog('+', "Detected upsalarm semafore, aborting newsscan");
		break;
	    }
	    Syslog('m', "Scan newsgroup: %s", Msgs.Newsgroup);
	    if (!do_quiet) {
		mbse_colour(CYAN, BLACK);
		printf("\r%-40s", Msgs.Newsgroup);
		fflush(stdout);
	    }
	    Nopper();
	    if (do_one_group(&art, Msgs.Newsgroup, Msgs.Tag, Msgs.MaxArticles) == RETVAL_ERROR)
		break;
	    /*
	     * To be safe, update the dupes database after each area.
	     */
	    CloseDupes();
	}
    }
    fclose(pAreas);
    free(sAreas);

    for (tmp = xoverview; tmp; tmp = old) {
	old = tmp->next;
	if (tmp->header)
	    free(tmp->header);
	if (tmp->field)
	    free(tmp->field);
	free(tmp);
    }

    nntp_close();

    do_flush = TRUE;
    if (!do_quiet)
	printf("\r                                                    \r");
}



int do_one_group(List **art, char *grpname, char *ftntag, int maxarticles)
{
    List    *tmp;
    char    temp[128], *resp;
    int	    retval, fetched = 0;
    int	    total, start, end;

    Syslog('m', "do_one_group(%s, %s)", grpname, ftntag);
    IsDoing((char *)"Scan %s", grpname);
    snprintf(temp, 128, "GROUP %s\r\n", grpname);
    nntp_send(temp);
    resp = nntp_receive();
    retval = atoi(strtok(resp, " "));
    if (retval == 480) {
	/*
	 * We must login
	 */
	if (nntp_auth() == FALSE) {
	    WriteError("Authorisation failure");
	    nntp_close();
	    return RETVAL_NOAUTH;
	}
	nntp_send(temp);
	resp = nntp_receive();
	retval = atoi(strtok(resp, " "));
    }
    if (retval != 211) {
	if (retval == 411) {
	    WriteError("No such newsgroup: %s", grpname);
	    return RETVAL_UNEXPECTEDANS;
	}
	WriteError("Unknown response %d to GROUP command", retval);
	return RETVAL_ERROR;
    }

    total = atol(strtok(NULL, " "));
    start = atol(strtok(NULL, " "));
    end   = atol(strtok(NULL, " '\0'"));
    Syslog('m', "GROUP total %d, start %d, end %d, max %d", total, start, end, maxarticles);
    if ((maxarticles) && (total > maxarticles)) {
	start = end - maxarticles;
	total = maxarticles;
	Syslog('m', "NEW:  total %d, start %d, end %d", total, start, end);
    }
    if (!total) {
	Syslog('+', "Fetched 0 articles from %s", grpname);
	return RETVAL_NOARTICLES;
    }

    retval = get_xover(grpname, start, end, art);
    if (retval != RETVAL_OK) {
	tidy_artlist(art);
	return retval;
    }

    if (!do_learn) {
	for (tmp = *art; tmp; tmp = tmp->next) {
	    if (!tmp->isdupe) {
		/*
		 *  If the message isn't a dupe, it must be new for us.
		 */
		get_article(tmp->msgid, ftntag);
		fetched++;
	    }
	}
    }

    tidy_artlist(art);

    if ((maxarticles) && (fetched == maxarticles))
	Syslog('!', "Warning: the max. articles value in newsgroup %s might be to low", grpname);

    Syslog('+', "Fetched %d article%s from %s", fetched, (fetched == 1) ? "":"s", grpname);
    return RETVAL_OK;
}
コード例 #3
0
ファイル: npost.c プロジェクト: PietjeBell88/npost
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;
}