home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / archivers / mpackppc-wos / src / amigapk.c < prev    next >
C/C++ Source or Header  |  1998-04-27  |  12KB  |  315 lines

  1. /* (C) Copyright 1993 by Mike W. Meyer
  2.  *
  3.  * Permission to use, copy, modify, distribute, and sell this software
  4.  * and its documentation for any purpose is hereby granted without
  5.  * fee, provided that the above copyright notice appear in all copies
  6.  * and that both that copyright notice and this permission notice
  7.  * appear in supporting documentation, and that the name of Mike W.
  8.  * Meyer not be used in advertising or publicity pertaining to
  9.  * distribution of the software without specific, written prior
  10.  * permission.  Mike W. Meyer makes no representations about the
  11.  * suitability of this software for any purpose.  It is provided "as
  12.  * is" without express or implied warranty.
  13.  *
  14.  * MIKE W. MEYER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  15.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  16.  * FITNESS, IN NO EVENT SHALL MIKE W. MEYER BE LIABLE FOR ANY SPECIAL,
  17.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  18.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  19.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
  20.  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  21.  */
  22. #include <exec/types.h>
  23. #include <exec/execbase.h>
  24. #include <dos/dos.h>
  25. #ifndef __PPC__
  26. #include <libraries/netsupport.h>
  27. #else
  28. #define POSTNEWS ""
  29. #define SENDMAIL ""
  30. #endif
  31.  
  32. #ifdef __SASC
  33. #include <proto/exec.h>
  34. #include <proto/dos.h>
  35. #ifndef __PPC__
  36. #include <proto/netsupport.h>
  37. #endif
  38. #else
  39. #include <clib/exec_protos.h>
  40. #include <clib/dos_protos.h>
  41. //#include <clib/netsupport_protos.h>
  42. #endif
  43.  
  44. #define R_OK 0
  45.  
  46. #include <stdio.h>
  47. #include <stdlib.h>
  48. #include <string.h>
  49. #include <ctype.h>
  50. #include <errno.h>
  51.  
  52. #include "xmalloc.h"
  53. #include "version.h"
  54.  
  55. #if defined(__SASC) && (__VERSION__ > 5) && (__REVISION__ > 50)
  56. static const char DOSId[] = "\0$VER: MPack " MPACK_VERSION " " __AMIGADATE__ ;
  57. #else
  58. static const char DOSId[] = "\0$VER: MPack " MPACK_VERSION " (" __DATE__ ")" ;
  59. #endif
  60.  
  61. #define MAXADDRESS 100
  62.  
  63. extern char *myGetConfig(char *, char *);
  64. extern int errno;
  65. extern int optind;
  66. extern char *optarg;
  67. #ifndef __PPC__
  68. struct NetSupportLibrary *NetSupportBase;
  69. #endif
  70.  
  71. #define TEMPLATE "From/A,Dest=Destination/M,-o=To/K,-s=Subject/K,-d=Description/K,-c=Contents/K,-m=SplitSize/K/N,-n=News/S"
  72. enum {
  73.         FROM ,
  74.         DESTINATION ,
  75.         TO ,
  76.         SUBJECT ,
  77.         DESCRIPTION ,
  78.         CONTENTS ,
  79.         SPLITSIZE ,
  80.         NEWS ,
  81.         OPT_COUNT
  82.         } ;
  83.  
  84. #define HS1 "mpack version " MPACK_VERSION "\n"
  85. #define HS2 "Pack the given file into a MIME message for sending to a remote machine\n"
  86. #define HS3 "by either mail or news. Automatically splits the file into a multi-part\n"
  87. #define HS4 "message if it is larger than splitsize. The options are:\n"
  88. #define HS5 "From/A                  The file you are going to send.\n"
  89. #define HS6 "Dest=Destination/M      One or more electronic mail addresses or newsgroups.\n"
  90. #define HS7 "                        May not be used with the To option.\n"
  91. #define HS8 "-o=To/K                 A file  to output to. The message will be written to\n"
  92. #define HS9 "                        the given file name. If more than one message is\n"
  93. #define HS10 "                        needed, this is the base name, and a sequence number\n"
  94. #define HS11 "                        is provided as a suffix.\n"
  95. #define HS12 "-s=Subject/K            Subject of the mail message or article. Will be put\n"
  96. #define HS13 "                        in each message sent, with sequence numbers appended\n"
  97. #define HS14 "                        for more than one messages.\n"
  98. #define HS15 "-d=Description/K        The name of a file that describes the file being\n"
  99. #define HS16 "                        sent. Add more here later, Mike.\n"
  100. #define HS17 "-c=Contents/K           Mime content-type field for the file being sent. The\n"
  101. #define HS18 "                        default is application/octet-stream (binary data)\n"
  102. #define HS19 "                        but some other MIME types will be recognized.\n"
  103. #define HS20 "-m=SplitSize/K/N        Maximum size of a single message in bytes. The\n"
  104. #define HS21 "                        default is taken from the environment variable\n"
  105. #define HS22 "                        SPLITSIZE. If that is not defined, then there is no\n"
  106. #define HS23 "                        limit.\n"
  107. #define HS24 "-n=News/S               Causes the destinations to be interpreted as\n"
  108. #define HS25 "                        newsgroups to be posted to instead of electronic mail\n"
  109. #define HS26 "                        addresses. Has no effect if there are no destinations\n"
  110. #define HS27 "                        (i.e. - To is used to write to a file).\n"
  111.  
  112. char helpstuff[4096];
  113.  
  114. /* The one thing we have to fre by hand */
  115. static struct RDArgs *my_args = NULL, *args = NULL ;
  116.  
  117. /* A simple utilities */
  118. void post(char *, char *) ;
  119. void warn(char *) ;
  120.  
  121. void
  122. FreeSystem(void) {
  123.  
  124. #ifndef __PPC__
  125.         if (NetSupportBase) {
  126.                 UnLockFiles() ;
  127.                 CloseLibrary((struct Library *) NetSupportBase) ;
  128.                 }
  129. #endif
  130.  
  131.         if (args) FreeArgs(args) ;
  132.         if (my_args) FreeDosObject(DOS_RDARGS, my_args) ;
  133.         }
  134.  
  135. int
  136. main(int argc, char **argv) {
  137.         FILE *infile, *descfile;
  138.         char *p, **pp, *from, *to, *subject, *description, *contents ;
  139.         char *header = NULL ;
  140.         char **destination ;
  141.         long news, count, splitsize = 0 ;
  142.         char buffer[512] ;
  143.         long part, opts[OPT_COUNT] ;
  144.  
  145. #ifndef __PPC__
  146.         if (!(NetSupportBase = (struct NetSupportLibrary *) OldOpenLibrary(NETSUPPORTNAME)))
  147.                 fprintf(stderr,
  148.                         "No NetSupport.Library: Can't parse configfiles.\n");
  149. #endif
  150.  
  151.         memset((char *) opts, 0, sizeof(opts)) ;
  152.         if ((p = myGetConfig("SPLITSIZE", NULL)) && *p >= '0' && *p <= '9')
  153.                 splitsize = atoi(p) ;
  154.  
  155.         opts[SPLITSIZE] = (long) &splitsize ;
  156.  
  157.         if (!(my_args = AllocDosObject(DOS_RDARGS, NULL))) {
  158.                 PrintFault(IoErr(), *argv) ;
  159.                 exit(RETURN_FAIL) ;
  160.                 }
  161.                 my_args->RDA_ExtHelp=&(helpstuff[0]);
  162.                 strcpy(my_args->RDA_ExtHelp,HS1);
  163.                 strcat(my_args->RDA_ExtHelp,HS2);
  164.                 strcat(my_args->RDA_ExtHelp,HS3);
  165.                 strcat(my_args->RDA_ExtHelp,HS4);
  166.                 strcat(my_args->RDA_ExtHelp,HS5);
  167.                 strcat(my_args->RDA_ExtHelp,HS6);
  168.                 strcat(my_args->RDA_ExtHelp,HS7);
  169.                 strcat(my_args->RDA_ExtHelp,HS8);
  170.                 strcat(my_args->RDA_ExtHelp,HS9);
  171.                 strcat(my_args->RDA_ExtHelp,HS10);
  172.                 strcat(my_args->RDA_ExtHelp,HS11);
  173.                 strcat(my_args->RDA_ExtHelp,HS12);
  174.                 strcat(my_args->RDA_ExtHelp,HS13);
  175.                 strcat(my_args->RDA_ExtHelp,HS14);
  176.                 strcat(my_args->RDA_ExtHelp,HS15);
  177.                 strcat(my_args->RDA_ExtHelp,HS16);
  178.                 strcat(my_args->RDA_ExtHelp,HS17);
  179.                 strcat(my_args->RDA_ExtHelp,HS18);
  180.                 strcat(my_args->RDA_ExtHelp,HS19);
  181.                 strcat(my_args->RDA_ExtHelp,HS20);
  182.                 strcat(my_args->RDA_ExtHelp,HS21);
  183.                 strcat(my_args->RDA_ExtHelp,HS22);
  184.                 strcat(my_args->RDA_ExtHelp,HS23);
  185.                 strcat(my_args->RDA_ExtHelp,HS24);
  186.                 strcat(my_args->RDA_ExtHelp,HS25);
  187.                 strcat(my_args->RDA_ExtHelp,HS26);
  188.                 strcat(my_args->RDA_ExtHelp,HS27);
  189.         if (!(args = ReadArgs(TEMPLATE, opts, my_args))) {
  190.                 PrintFault(IoErr(), *argv) ;
  191.                 exit(RETURN_FAIL) ;
  192.                 }
  193.  
  194.         from = (char *) opts[FROM] ;
  195.         to = (char *) opts[TO] ;
  196.         subject = (char *) opts[SUBJECT] ;
  197.         description = (char *) opts[DESCRIPTION] ;
  198.         contents = (char *) opts[CONTENTS] ;
  199.         news = opts[NEWS] ;
  200.         splitsize = *((long *) opts[SPLITSIZE]) ;
  201.         destination = (char **) opts[DESTINATION] ;
  202.  
  203.         /* Make sure we can open the description file. */
  204.         if (description) {
  205.                 if (!(descfile = fopen(description, "r"))) {
  206.                         fprintf(stderr, "Can't open the description file \"%s\"!\n", description);
  207.                         exit(RETURN_ERROR) ;
  208.                 }
  209.         }
  210.         else
  211.                 descfile = NULL;
  212.  
  213.         /* Make sure we're sending something reasonable. */
  214.         if (contents) {
  215.                 if (!cistrncmp(contents, "text/", 5)) {
  216.                         fprintf(stderr, "This program is not appropriate for encoding textual data\n") ;
  217.                         exit(RETURN_ERROR) ;
  218.                         }
  219.                 if (cistrncmp(contents, "application/", 12)
  220.                 && cistrncmp(contents, "audio/", 6)
  221.                 && cistrncmp(contents, "image/", 6)
  222.                 && cistrncmp(contents, "video/", 6)) {
  223.                         fprintf(stderr, "Content type must be subtype of application, audio, image, or video\n") ;
  224.                         exit(RETURN_ERROR) ;
  225.                         }
  226.                 }
  227.  
  228.         /* Gotta have something to send! */
  229.         if (!from) {
  230.                 fprintf(stderr, "The From argument is required\n") ;
  231.                 exit(RETURN_ERROR) ;
  232.                 }
  233.  
  234.         /* We must have either To or Destinations, but not both! */
  235.         if (to && destination) {
  236.                 fprintf(stderr, "The To keyword and Destination are mutually exclusive.\n") ;
  237.                 exit(RETURN_ERROR) ;
  238.                 }
  239.         else if (!to && !destination) {
  240.                 fprintf(stderr, "Either a destination or the To keyword is required\n");
  241.                 exit(RETURN_ERROR) ;
  242.                 }
  243.  
  244.         /* And we gotta have a subject! */
  245.         if (!subject) {
  246.                 fputs("Subject: ", stdout) ;
  247.                 fflush(stdout) ;
  248.                 if (!fgets(buffer, sizeof(buffer), stdin)) {
  249.                         fprintf(stderr, "A subject is required\n") ;
  250.                         exit(RETURN_ERROR) ;
  251.                         }
  252.                 if (p = strchr(buffer, '\n')) *p = '\0' ;
  253.                 subject = buffer ;
  254.                 }
  255.  
  256.         /* Build the To: or Newsgroups: line */
  257.         if (destination) {
  258.                 for (count = 25, pp = destination; *pp; pp += 1)
  259.                         count += strlen(*pp) + 3 ;
  260.                 header = xmalloc(count) ;
  261.                 p = (char *)strcpy(header, news ? "Newsgroups: " : "To: ") ;
  262.                 p = (char *)strcpy(p, *destination) ;
  263.                 strcat(p,"\0");
  264.                 for (pp = destination + 1; *pp; pp += 1) {
  265.                         p = (char *)strcpy(p, news ? "," : ",\n\t") ;
  266.                         p = (char *)strcpy(p, *pp) ;
  267.                         strcat(p,"\0");
  268.                         }
  269.                 strcpy(p, "\n") ;
  270.                 strcat(p,"\0");
  271.                 }
  272.  
  273.         /* Get a name to put the output into */
  274.         if (!to) to = tmpnam(NULL) ;
  275.  
  276.         /* Sigh */
  277.         infile = fopen(from, "r");
  278.         if (!infile) {
  279.                 os_perror(from);
  280.                 exit(1);
  281.                 }
  282.  
  283.         if (encode(infile, (FILE *) 0, from, descfile, subject, header, splitsize, contents, to))
  284.                 exit(RETURN_FAIL) ;
  285.  
  286.         /* Hey, we did it. Now send it if we need to */
  287.         if (destination)
  288.                 if (!access(to, R_OK)) {
  289.                         post(to, news ? POSTNEWS : SENDMAIL) ;
  290.                         remove(to) ;
  291.                         }
  292.                 else
  293.                         for (part = 1;; part += 1) {
  294.                                 sprintf(buffer, "%s.%02d", to, part) ;
  295.                                 if (access(buffer, R_OK)) break ;
  296.                                 post(buffer, news ? POSTNEWS : SENDMAIL) ;
  297.                                 remove(buffer) ;
  298.                                 }
  299.  
  300.         exit(RETURN_OK) ;
  301.         }
  302.  
  303. void
  304. post(char *name, char *command) {
  305.         char buffer[512] ;
  306.  
  307.         sprintf(buffer, "%s < %s", myGetConfig(command, command), name);
  308.         system(buffer) ;
  309.         }
  310.  
  311. void
  312. warn(char *s) {
  313.         abort() ;
  314.         }
  315.