home *** CD-ROM | disk | FTP | other *** search
/ The Best of Windows 95.com 1996 September / WIN95_09964.iso / unix / SOUPER95.ZIP / source / souper.c < prev    next >
C/C++ Source or Header  |  1996-02-12  |  7KB  |  331 lines

  1. /* $Id: souper.c 1.5 1995/08/01 14:28:34 cthuang Exp $
  2.  *
  3.  * Fetch mail and news using POP3 and NNTP into a SOUP packet.
  4.  */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <signal.h>
  9. #include "souper.h"
  10.  
  11. #ifdef __WIN32__
  12. #include <fcntl.h>
  13. #include <winsock.h>
  14. WSADATA WSAData;
  15. #endif
  16.  
  17. /* getopt declarations */
  18. #if HAVE_GETOPT_H
  19. #include <getopt.h>
  20. #else
  21. extern int getopt(int argc, char *const *argv, const char *shortopts);
  22. extern char *optarg;
  23. extern int optind;
  24. #endif
  25.  
  26. /* global data */
  27. char progname[] = "souper";
  28.  
  29. #ifdef __OS2__
  30. char doIni = 1;        /* if TRUE, read TCPOS2.INI file */
  31. #endif
  32. char *nntpServer;
  33. char *mailGateway;
  34.  
  35. /* program options */
  36. enum Mode { RECEIVE, SEND, CATCHUP } mode = RECEIVE;
  37. char doMail = 1;
  38. char doNews = 1;
  39. char doXref = 1;
  40. char doSummary = 0;
  41. char doNewGroups = 0;
  42. char readOnly = 0;
  43. long maxBytes = 2048*1024L;
  44. char *homeDir = NULL;
  45. char newsrcFile[FILENAME_MAX];
  46. char killFile[FILENAME_MAX];
  47. int maxLines = 0;
  48. int catchupCount;
  49. char *popServer, *popUser, *popPassword;
  50.  
  51. /* Try to allocate some memory.  Exit if unsuccessful.
  52.  */
  53. void *
  54. xmalloc (size_t sz)
  55. {
  56.     void *p;
  57.  
  58.     if ((p = malloc(sz)) == NULL) {
  59.     fputs("out of memory\n", stderr);
  60.     exit(EXIT_FAILURE);
  61.     }
  62.     return p;
  63. }
  64.  
  65. /* Copy string to allocated memory.  Exit if unsuccessful.
  66.  */
  67. char *
  68. xstrdup (const char *s)
  69. {
  70.     return strcpy((char *)xmalloc(strlen(s)+1), s);
  71. }
  72.  
  73. static void
  74. setDefaults (void)
  75. {
  76.     char *s;
  77.  
  78.     if (!homeDir)
  79.     if ((homeDir = getenv("HOME")) == NULL)
  80.         homeDir = ".";
  81.  
  82.     if ((s = getenv("NNTPSERVER")) != NULL)
  83.     nntpServer = s;
  84.  
  85. #ifdef __OS2__
  86.     sprintf(newsrcFile, "%s/newsrc", homeDir);
  87.     sprintf(killFile, "%s/kill", homeDir);
  88. #else
  89.     sprintf(newsrcFile, "%s/.newsrc", homeDir);
  90.     sprintf(killFile, "%s/.kill", homeDir);
  91. #endif
  92. }
  93.  
  94. static void
  95. usage (void)
  96. {
  97.     fputs("Souper v1.5 - transfer POP3 mail and NNTP news to SOUP\n", stderr);
  98.     fprintf(stderr, "usage: %s [options] [mailhost userid password]\n", progname);
  99.     fputs("  -a       Add new newsgroups to newsrc file\n", stderr);
  100.     fputs("  -c n     Mark every article as read except for the last n in each newsgroup\n", stderr);
  101.     fputs("  -h dir   Set home directory\n", stderr);
  102. #ifdef __OS2__
  103.     fputs("  -i       Do not read Internet Connection for OS/2 settings\n", stderr);
  104. #endif
  105.     fputs("  -k n     Set maximum news packet size in Kbytes\n", stderr);
  106.     fputs("  -l n     Kill articles longer than n lines\n", stderr);
  107.     fputs("  -m       Do not get mail\n", stderr);
  108.     fputs("  -n       Do not get news\n", stderr);
  109.     fputs("  -N file  Set newsrc file\n", stderr);
  110.     fputs("  -K file  Set kill file\n", stderr);
  111.     fputs("  -r       Read only mode.  Do not delete mail or update newsrc\n", stderr);
  112.     fputs("  -s       Send replies\n", stderr);
  113.     fputs("  -u       Create news summary\n", stderr);
  114.     fputs("  -x       Do not process news Xref headers\n", stderr);
  115.     exit(EXIT_FAILURE);
  116. }
  117.  
  118. static void
  119. parseOptions (int argc, char **argv)
  120. {
  121.     int c;
  122.  
  123.     while ((c = getopt(argc, argv, "ac:h:iK:k:l:mN:nrsux")) != EOF) {
  124.     switch (c) {
  125.     case 'a':
  126.         doNewGroups = 1;
  127.         break;
  128.     case 'c':
  129.         mode = CATCHUP;
  130.         catchupCount = atoi(optarg);
  131.         break;
  132.     case 'h':
  133.         homeDir = optarg;
  134.         setDefaults();
  135.         break;
  136. #ifdef __OS2__
  137.     case 'i':
  138.         doIni = 0;
  139.         break;
  140. #endif
  141.     case 'K':
  142.         strcpy(killFile, optarg);
  143.         break;
  144.     case 'k':
  145.         maxBytes = atol(optarg) * 1024L;
  146.         break;
  147.     case 'l':
  148.         maxLines = atoi(optarg);
  149.         break;
  150.     case 'm':
  151.         doMail = 0;
  152.         break;
  153.     case 'N':
  154.         strcpy(newsrcFile, optarg);
  155.         break;
  156.     case 'n':
  157.         doNews = 0;
  158.         break;
  159.     case 'r':
  160.         readOnly = 1;
  161.         break;
  162.     case 's':
  163.         mode = SEND;
  164.         break;
  165.     case 'u':
  166.         doNews = 1;
  167.         doSummary = 1;
  168.         break;
  169.     case 'x':
  170.         doXref = 0;
  171.         break;
  172.     default:
  173.         usage();
  174.     }
  175.     }
  176.  
  177. }
  178.  
  179. #ifdef __OS2__
  180. #define INCL_WINSHELLDATA
  181. #include <os2.h>
  182.  
  183. static void
  184. readTcpIni (void)
  185. {
  186.     HAB hab;
  187.     HINI hini;
  188.     char *etc;
  189.     char buf[BUFSIZ], curConnect[20], host[40], domain[40];
  190.  
  191.     etc = getenv("ETC");
  192.     if (etc == NULL) {
  193.     fputs("Must set ETC\n", stderr);
  194.     exit(EXIT_FAILURE);
  195.     }
  196.     sprintf(buf, "%s\\TCPOS2.INI", etc);
  197.  
  198.     hab = WinInitialize(0);
  199.     hini = PrfOpenProfile(hab, buf);
  200.     if (hini == NULLHANDLE) {
  201.     fprintf(stderr, "Cannot open profile %s\n", buf);
  202.     exit(EXIT_FAILURE);
  203.     }
  204.  
  205.     PrfQueryProfileString(hini, "CONNECTION", "CURRENT_CONNECTION", NULL,
  206.                           curConnect, sizeof(curConnect));
  207.  
  208. #if 0
  209.     PrfQueryProfileString(hini, curConnect, "HOSTNAME", NULL, host,
  210.     sizeof(host));
  211.     PrfQueryProfileString(hini, curConnect, "DOMAIN_NAME", NULL, domain,
  212.     sizeof(domain));
  213.     sprintf(buf, "%s.%s", host, domain);
  214.     hostName = xstrdup(buf);
  215. #endif
  216.  
  217.     PrfQueryProfileString(hini, curConnect, "POPSRVR", NULL, buf, sizeof(buf));
  218.     popServer = xstrdup(buf);
  219.     PrfQueryProfileString(hini, curConnect, "POP_ID", NULL, buf, sizeof(buf));
  220.     popUser = xstrdup(buf);
  221.     PrfQueryProfileString(hini, curConnect, "POP_PWD", NULL, buf, sizeof(buf));
  222.     popPassword = xstrdup(buf);
  223.  
  224.     if (!nntpServer) {
  225.     PrfQueryProfileString(hini, curConnect, "DEFAULT_NEWS", NULL, buf, sizeof(buf));
  226.     nntpServer = xstrdup(buf);
  227.     }
  228.  
  229.     PrfQueryProfileString(hini, curConnect, "MAIL_GW", NULL, buf, sizeof(buf));
  230.     mailGateway = xstrdup(buf);
  231. #if 0
  232.     PrfQueryProfileString(hini, curConnect, "REPLY_DOMAIN", NULL, buf, sizeof(buf));
  233.     replyDomain = xstrdup(buf);
  234. #endif
  235.  
  236.     PrfCloseProfile(hini);
  237.     WinTerminate(hab);
  238. }
  239. #endif
  240.  
  241. int
  242. main (int argc, char **argv)
  243. {
  244. #ifdef __WIN32__ /* Set up to save the old signal */
  245.    typedef void (*Sig_t)(int);
  246.    Sig_t functionCall;
  247. #endif
  248. #if 0
  249. #ifdef __OS2__
  250.     progname = strrchr(argv[0], '\\');
  251. #else
  252.     progname = strrchr(argv[0], '/');
  253. #endif
  254.     if (progname == NULL)
  255.     progname = argv[0];
  256.     else
  257.     ++progname;
  258. #endif
  259.  
  260. #ifdef __WIN32__
  261. {
  262.     int err;
  263.     WORD wVerReq;
  264.  
  265.     wVerReq = MAKEWORD(1,1);
  266.    
  267.     err = WSAStartup(wVerReq, &WSAData);
  268.     if (err != 0) {
  269.         printf("Help!!!");
  270.         return -1;
  271.     }
  272. }
  273. #endif
  274.  
  275.     setDefaults();
  276.     parseOptions(argc, argv);
  277. #ifdef __OS2__
  278.     if (doIni)
  279.     readTcpIni();
  280. #endif
  281.  
  282.     switch (mode) {
  283.     case RECEIVE:
  284.     if (doMail) {
  285.         if (argc - optind == 3) {
  286.         popServer = argv[optind];
  287.         popUser = argv[optind+1];
  288.         popPassword = argv[optind+2];
  289.         } else {
  290. #ifndef __OS2__
  291.         usage();
  292. #endif
  293.         }
  294.     }
  295.  
  296.     openAreas();
  297. #ifdef __WIN32__
  298.     /* Save the old signal handler. */
  299.         functionCall = signal(SIGINT, closeAreasOnSignal);
  300. #else
  301.     signal(SIGINT, closeAreasOnSignal);
  302. #endif  
  303.     if (doMail) getMail(popServer, popUser, popPassword);
  304.     if (doNews) {
  305.         if (doSummary)
  306.         sumNews();
  307.         else
  308.         getNews();
  309.     }
  310.     closeAreas();
  311.     break;
  312.  
  313.     case SEND:
  314.     if (argc - optind >= 1) {
  315.         mailGateway = argv[optind];
  316.     }
  317.     sendReply();
  318.     break;
  319.  
  320.     case CATCHUP:
  321.     catchupNews(catchupCount);
  322.     break;
  323.     }
  324.  
  325. #ifdef __WIN32__
  326.     signal(SIGINT, functionCall);    /* Restore the old signal handler. */
  327.     WSACleanup();
  328. #endif
  329.     return 0;
  330. }
  331.