home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / Tools / mpack-1.2 / amigapk.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-05-03  |  7.0 KB  |  235 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.  
  26. #ifdef __SASC
  27. #include <proto/exec.h>
  28. #include <proto/dos.h>
  29. #else
  30. #include <clib/exec_protos.h>
  31. #include <clib/dos_protos.h>
  32. #endif
  33.  
  34. #include <stdio.h>
  35. #include <stdlib.h>
  36. #include <string.h>
  37. #include <ctype.h>
  38. #include <errno.h>
  39.  
  40. #include "version.h"
  41. #include "xmalloc.h"
  42.  
  43. #ifdef AMIGA
  44. static const char DOSId[] = "\0$VER: MPack " MPACK_VERSION " (" __DATE__ ")" ;
  45. #endif
  46.  
  47. #define MAXADDRESS 100
  48.  
  49. extern int errno;
  50. extern int optind;
  51. extern char *optarg;
  52.  
  53. #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"
  54. enum {
  55.     FROM ,
  56.     DESTINATION ,
  57.     TO ,
  58.     SUBJECT ,
  59.     DESCRIPTION ,
  60.     CONTENTS ,
  61.     SPLITSIZE ,
  62.     NEWS ,
  63.     OPT_COUNT
  64.     } ;
  65.     
  66. #define HELPSTRING "mpack vesion " MPACK_VERSION "\n\
  67. Pack the given file into a MIME message for sending to a remote machine\n\
  68. by either mail or news. Automatically splits the file into a multi-part\n\
  69. message if it is larger than splitsize. The options are:\n\
  70. From/A            The file you are going to send.\n\
  71. Dest=Destination/M    One or more electronic mail addresses or newsgroups.\n\
  72.             May not be used with the To option.\n\
  73. -o=To/K            A file  to output to. The message will be written to\n\
  74.             the given file name. If more than one message is\n\
  75.             needed, this is the base name, and a sequence number\n\
  76.             is provided as a suffix.\n\
  77. -s=Subject/K        Subject of the mail message or article. Will be put\n\
  78.             in each message sent, with sequence numbers appended\n\
  79.             for more than one messages.\n\
  80. -d=Description/K    The name of a file that describes the file being\n\
  81.             sent. Add more here later, Mike.\n\
  82. -c=Contents/K        Mime content-type field for the file being sent. The\n\
  83.             default is application/octet-stream (binary data)\n\
  84.             but some other MIME types will be recognized.\n\
  85. -m=SplitSize/K/N    Maximum size of a single message in bytes. The\n\
  86.             default is taken from the environment variable\n\
  87.             SPLITSIZE. If that is not defined, then there is no\n\
  88.             limit.\n\
  89. -n=News/S        Causes the destinations to be interpreted as\n\
  90.             newsgroups to be posted to instead of electronic mail\n\
  91.             addresses. Has no effect if there are no destinations\n\
  92.             (i.e. - To is used to write to a file).\n"
  93.  
  94. /* The one thing we have to fre by hand */
  95. static struct RDArgs *my_args = NULL, *args = NULL ;
  96.  
  97. /* A simple utilities */
  98. void post(char *, char *) ;
  99.  
  100. void
  101. FinishArgs(void) {
  102.  
  103.     if (args) FreeArgs(args) ;
  104.     if (my_args) FreeDosObject(DOS_RDARGS, my_args) ;
  105.     }
  106.  
  107. int
  108. main(int argc, char **argv) {
  109.     char *p, **pp, *from, *to, *subject, *description, *contents ;
  110.     char *header = NULL ;
  111.     char **destination ;
  112.     long news, count, splitsize = 0 ;
  113.     char buffer[512] ;
  114.     long part, opts[OPT_COUNT] ;
  115.  
  116.     onexit(FinishArgs) ;
  117.     memset((char *) opts, 0, sizeof(opts)) ;
  118.     if ((p = getenv("SPLITSIZE")) && *p >= '0' && *p <= '9')
  119.         splitsize = atoi(p) ;
  120.  
  121.     opts[SPLITSIZE] = (long) &splitsize ;
  122.  
  123.     if (!(my_args = AllocDosObject(DOS_RDARGS, NULL))) {
  124.         PrintFault(IoErr(), *argv) ;
  125.         exit(RETURN_FAIL) ;
  126.         }
  127.     my_args->RDA_ExtHelp = HELPSTRING ;
  128.     if (!(args = ReadArgs(TEMPLATE, opts, my_args))) {
  129.         PrintFault(IoErr(), *argv) ;
  130.         exit(RETURN_FAIL) ;
  131.         }
  132.     
  133.     from = (char *) opts[FROM] ;
  134.     to = (char *) opts[TO] ;
  135.     subject = (char *) opts[SUBJECT] ;
  136.     description = (char *) opts[DESCRIPTION] ;
  137.     contents = (char *) opts[CONTENTS] ;
  138.     news = opts[NEWS] ;
  139.     splitsize = *((long *) opts[SPLITSIZE]) ;
  140.     destination = (char **) opts[DESTINATION] ;
  141.  
  142.     /* Make sure we're sending something reasonable. */
  143.     if (contents) {
  144.         if (!cistrncmp(contents, "text/", 5)) {
  145.             fprintf(stderr, "This program is not appropriate for encoding textual data\n") ;
  146.             exit(RETURN_ERROR) ;
  147.             }
  148.         if (cistrncmp(contents, "application/", 12)
  149.         && cistrncmp(contents, "audio/", 6)
  150.         && cistrncmp(contents, "image/", 6)
  151.         && cistrncmp(contents, "video/", 6)) {
  152.             fprintf(stderr, "Content type must be subtype of application, audio, image, or video\n") ;
  153.             exit(RETURN_ERROR) ;
  154.             }
  155.         }
  156.  
  157.     /* Gotta have something to send! */
  158.     if (!from) {
  159.         fprintf(stderr, "The From argument is required\n") ;
  160.         exit(RETURN_ERROR) ;
  161.         }
  162.  
  163.     /* We must have either To or Destinations, but not both! */
  164.     if (to && destination) {
  165.         fprintf(stderr, "The To keyword and Destination are mutually exclusive.\n") ;
  166.         exit(RETURN_ERROR) ;
  167.         }
  168.     else if (!to && !destination) {
  169.         fprintf(stderr, "Either a destination or the To keyword is required\n");
  170.         exit(RETURN_ERROR) ;
  171.         }
  172.  
  173.     /* And we gotta have a subject! */
  174.     if (!subject) {
  175.         fputs("Subject: ", stdout) ;
  176.         fflush(stdout) ;
  177.         if (!fgets(buffer, sizeof(buffer), stdin)) {
  178.             fprintf(stderr, "A subject is required\n") ;
  179.             exit(RETURN_ERROR) ;
  180.             }
  181.         if (p = strchr(buffer, '\n')) *p = '\0' ;
  182.         subject = buffer ;
  183.         }    
  184.  
  185.     /* Build the To: or Newsgroups: line */
  186.     if (destination) {
  187.         for (count = 25, pp = destination; *pp; pp += 1)
  188.             count += strlen(*pp) + 3 ;
  189.         header = xmalloc(count) ;
  190.         p = stpcpy(header, news ? "Newsgroups: " : "To: ") ;
  191.         p = stpcpy(p, *destination) ;
  192.         for (pp = destination + 1; *pp; pp += 1) {
  193.             p = stpcpy(p, news ? "," : ",\n\t") ;
  194.             p = stpcpy(p, *pp) ;
  195.             }
  196.         stpcpy(p, "\n") ;
  197.         }
  198.  
  199.     /* Get a name to put the output into */
  200.     if (!to) to = tmpnam(NULL) ;
  201.  
  202.     if (encode(from, description, subject, header, splitsize, contents, to))
  203.             exit(RETURN_FAIL) ;
  204.  
  205.     /* Hey, we did it. Now send it if we need to */
  206.     if (destination)
  207.         if (!access(to, R_OK)) {
  208.             post(to, news ? "postnews" : "sendmail") ;
  209.             remove(to) ;
  210.             }
  211.         else
  212.             for (part = 1;; part += 1) {
  213.                 sprintf(buffer, "%s.%02d", to, part) ;
  214.                 if (access(buffer, R_OK)) break ;
  215.                 post(buffer, news ? "postnews" : "sendmail") ;
  216.                 remove(buffer) ;
  217.                 }
  218.  
  219.     exit(RETURN_OK) ;
  220.     }
  221.  
  222. void
  223. post(char *name, char *command) {
  224.     char *p, buffer[512] ;
  225.  
  226.     if (p = getenv(command)) sprintf(buffer, "%s < %s", p, name) ;
  227.     else sprintf(buffer, "%s < %s", command, name) ;
  228.     system(buffer) ;
  229.     }
  230.  
  231. void
  232. warn(void) {
  233.     exit(RETURN_ERROR) ;
  234.     }
  235.