Collabra Server API Guide

[Contents] [Previous] [Next] [Index]

Chapter 2
News Program


The News Program is a code example that shows how to create and post a news message from within your application using the Collabra Server API.

This example posts a message to an NNTP server using the PostArticle function and other functions from the plugin.h header file. For the text of this file, see "The plugin.h Header File."

To run this program from the command line, use this code:

post -f sender -n newsserver [-h header file | -s subject ]  
         -b body file -g newsgroup [-g newsgroup]\n
Bracketed arguments are optional.


News Program Example: post.c

/* post.c. This sample program posts a message */
/* to an NNTP server using system PostArticle APIs. */
#include <stdio.h>
#include "plugin.h"
#define FALSE 0
#define TRUE 1
#define SMTP_LINELEN 1024
#define NL "\n"
/* Define global variables for getopt function. */
int     opterr = 1;
int     optind = 1;
int     optopt = 0;
char    *optarg;
static void
usage()
{
    fprintf(stderr, "Usage: post -f sender -n newsserver [-h header file | -s subject ]  -b body file -g newsgroup [-g newsgroup]\n");
}
main (int ac, char **av) {
    int         i;
    char        *rcpt;
        char    *sznewsSvr=NULL;
        char    *szBody=NULL;
        char    *szHeader=NULL;
        char    szTempHead[SMTP_LINELEN];
        char    *szSender=NULL;
        char    *szSubject=NULL;
        char    **pszAddr=NULL,**rgAddr=NULL;
        char    fFirst=FALSE;
        FILE    *pF1 = NULL;
        Message *pMessage;
        Recipient *pRecipient;
        int     result;
    while ((i = getopt(ac, av, "s:n:b:h:g:f:")) != EOF)
        switch (i) {
        case 'n':
            sznewsSvr = optarg;
            break;
        case 'b': 
                
            szBody= optarg;
            break;
        case 'h':
            szHeader = optarg;
            break;
        case 'f':
                szSender=optarg;
            break;
        case 'g':
                if(pszAddr==NULL) {
                        rgAddr = pszAddr= malloc(sizeof (char *) );
                }
                *pszAddr= optarg;
                rgAddr=realloc(rgAddr,
                  ((pszAddr-rgAddr)+2) * sizeof (char *));
                if(rgAddr==NULL)
                {
                        fprintf(stderr, "Couldn't allocate memory\n");
                        exit(1);
                }
                        
                *(++pszAddr)=NULL;
                
            break;
        case 's':
                szSubject=optarg;
            break;
        case '?':
            usage();
            exit(1);
        }
    ac -= optind;
    av += optind;
    if(szBody == NULL || ( szHeader == NULL &amp;&amp; szSubject==NULL) || szSender == NULL || sznewsSvr == NULL || pszAddr == NULL) 
    {
                usage();
                exit(1);
    }
    rcpt = av[0];
        if(szHeader==NULL)
        {
/* Create a unique filename. */
#ifndef WINNT
/* Use Process ID for uniqueness. */
                sprintf(szTempHead,"/tmp/news.tmp.%d",getpid());
                pF1 = fopen (szTempHead, "w");
                szHeader=szTempHead;
#else
/* Similar to previous sprintf call, */
/* but, in this case, call _getpid() */
/* and do not include a /tmp/ path. */
                sprintf(szTempHead,"news.tmp.%d",_getpid());
                pF1 = fopen (szTempHead, "w+b");
                szHeader=szTempHead;
#endif                   
           /* Produces a new header file. */
                if(pF1==NULL)
                {
                        fprintf(stderr, "Couldn't create temp header file\n");
                        exit(1);
                }
  
                if (fprintf(pF1, "Subject: %s\r\n", szSubject) &lt; 0) {
                        goto FileError;
            }
         /* Followups, x-headers, and other items, could go here.*/
                
                #ifdef NEVER
                if (fprintf(pF1, "From: &lt;%s&gt;\r\n", szSender) &lt; 0) {
                        goto FileError;
            }
                pszAddr=rgAddr;
                if (fprintf(pF1, "To: ") &lt; 0) {
                        goto FileError;
                }
                while(*pszAddr)
                {
                        if (fprintf(pF1, (fFirst ? ", %s" : "%s") , *pszAddr) &lt; 0) {          /* Comma trickiness. */
                                goto FileError;
                    }
                        fFirst=TRUE;
                        pszAddr++;
                }
                if (fprintf(pF1,"\r\n") &lt; 0) {
                        goto FileError;
                }
                fflush(pF1);
#endif NEVER
                if(( result= fclose(pF1)) != 0)
                {
                        fprintf(stderr, "Couldn't close temp header file\n");
                        exit(1);
                }
        }
        if((pMessage = NewMessage(szBody,szHeader,szSender))==NULL)
        {
                fprintf(stderr, "Couldn't create message\n");
                exit(1);
        }       
        pszAddr=rgAddr;
        
        while(*pszAddr)
        {
                if((pRecipient=NewRecipient(*pszAddr,ADDRTYPE_NEWS)) 
                  == NULL)
                {
                        fprintf(stderr, "Couldn't create 'address'\n");
                        exit(1);
                }
               /* Add a recipient */
                AddRecipient (pMessage,pRecipient);
                pszAddr++;
        }       
    PostArticle(sznewsSvr, pMessage); /* Call the simple send API. */ 
        FileError:
        if(pF1)
        {
                if(( result= remove(szHeader)) != 0)
                {
                        fprintf(stderr, "Couldn't delete 
                           temp header file\n");
                        exit(1);
                }
        }
        exit(0);
}
/* This comes from the AT&T public-domain getopt published in */
/* mod.sources (that is, comp.sources.unix before Usenet renaming).*/
#define ERR(s, c)                                       \
    if (opterr) {                                       \
        char buff[2];                                   \
        int fd = _fileno (stderr);                      \
        buff[0] = c; buff[1] = '\n';                    \
        (void)write(fd, av[0], strlen(av[0]));          \
        (void)write(fd, s, strlen(s));                  \
        (void)write(fd, buff, 2);                       \
    }
/* Return options and their values from the command line. */
int
getopt(ac, av, opts)
    int         ac;
    char        *av[];
    char        *opts;
{
    extern char *strchr();
    static int  i = 1;
    char        *p;
    /* Move to next value from argv?. */
    if (i == 1) {
        if (optind &gt;= ac || av[optind][0] != '-' || 
            av[optind][1]== '\0')
            return EOF;
        if (strcmp(av[optind], &quot;--&quot;) == 0) {
            optind++;
            return EOF;
        }
    }
    /* Get next option character. */
    if ((optopt = av[optind][i]) == ':'
     || (p = strchr(opts,  optopt)) == NULL) {
        ERR(&quot;: illegal option -- &quot;, optopt);
        if (av[optind][++i] == '\0') {
            optind++;
            i = 1;
        }
        return '?';
    }
    /* Snarf argument? */
    if (*++p == ':') {
        if (av[optind][i + 1] != '\0')
            optarg = &amp;av[optind++][i + 1];
        else {
            if (++optind &gt;= ac) {
                ERR(&quot;: option requires an argument -- 
                  &quot;, optopt);
                i = 1;
                return '?';
            }
            optarg = av[optind++];
        }
        i = 1;
    }
    else {
        if (av[optind][++i] == '\0') {
            i = 1;
            optind++;
        }
        optarg = NULL;
    }
    return optopt;
}
[Top]


[Contents] [Previous] [Next] [Index]

Last Updated: 10/01/97 14:01:18


Copyright © 1997 Netscape Communications Corporation

Any sample code included above is provided for your use on an "AS IS" basis, under the Netscape License Agreement - Terms of Use