home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume28 / ssh-1.3 / part01 / ssh.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-03-22  |  6.3 KB  |  228 lines

  1. /* @(#)ssh.c 1.30 (HaB) 92/03/17
  2.  *
  3.  * NAME:
  4.  *    ssh
  5.  *
  6.  * SYNTAX:
  7.  *    ssh [-h]
  8.  *        [-x] < shar_archive
  9.  *        [-v] 
  10.  *
  11.  * OPTIONS:
  12.  *    -h    Display usage information.
  13.  *
  14.  *    -x    Extract files in archive instead
  15.  *          of splitting it into parts. 
  16.  *
  17.  *    -v    Display version information. 
  18.  *
  19.  *    Without any options ssh splits archives
  20.  *    into extractable 'PartXX' files.
  21.  *
  22.  * DESCRIPTION:
  23.  *    Splits, strips and extracts appended shell
  24.  *    archives and stores the result in 'PartXX'
  25.  *    files (not when extracting). 
  26.  *
  27.  * NOTES:
  28.  *    The program should work on all archives created
  29.  *    using 'shar' (or equals) provided that they have
  30.  *    not been changed since they were first generated.  
  31.  *
  32.  * BUGS:
  33.  *    I have noticed that when the archives contains
  34.  *    archives themselves (happens sometimes) it does 
  35.  *    not always work properly.
  36.  *
  37.  * DATE:
  38.  *    1992-03-17
  39.  *
  40.  * AUTHOR:
  41.  *    Hans C. Beckerus         
  42.  *    etxerus@james.ericsson.se
  43.  *
  44.  *    Thanks to Pat Myrto, rwing!pat@relay.EU.net, for
  45.  *    solving the problems with System V compatibility.
  46.  *    
  47.  * DISCLAIMER:
  48.  *    This program is free to distribute to anyone as 
  49.  *    long as the code is not changed in anyway without
  50.  *    me knowing about it.  
  51.  *
  52.  *                                            /HaB :-)
  53.  */
  54.  
  55. #include <stdio.h>
  56. #include <string.h>
  57. #include <malloc.h>
  58.  
  59. #define SEARCH  0
  60. #define START   1
  61. #define INSIDE  2
  62. #define MSTEP   80     /* Allocation steps */
  63.  
  64. #ifndef SHELL
  65. #define SHELL  "/bin/sh"     /* Just in case... */
  66. #endif
  67.  
  68. #ifdef SYSV     /* HPUX/SYSV */
  69. #include <sys/types.h>     /* Non-ansi/PONIX sites needs this for size_t */
  70. #define nl_fprintf  fprintf     /* Provided for XPG2 compatibility */
  71. #define nl_sprintf  sprintf
  72. #define nl_strcmp   strcmp
  73. size_t msize;
  74. #endif
  75.  
  76. #ifdef SUN     /* SunOS/Berkeley */
  77. unsigned int msize;
  78. #endif
  79.  
  80. #ifdef SCCSID
  81. char sccsid[] = "@(#)ssh.c    1.30 (HaB) 92/03/17";
  82. #endif
  83.  
  84. enum boolean {     /* Boolean constants */
  85.     FALSE,
  86.     TRUE
  87. };
  88.  
  89. char *pattern[] = {                 /* Add more patterns here if needed.   */ 
  90.     "# this is a shell archive",
  91.     "# this is part", 
  92.     "#!/bin/sh",
  93.     "# !/bin/sh",
  94.     "#! /bin/sh",
  95.     ""     /* This is a flag and must not be removed */
  96. };
  97.  
  98. /* usage:
  99.  * 
  100.  * Display usage information and exit with status rc.
  101.  *
  102.  */
  103.  
  104. void usage (rc) 
  105.  
  106. int rc;     /* Return code */
  107.  
  108. {
  109.     puts ("\nUsage: ssh [-h]");
  110.     puts ("           [-x] < shar_archive");
  111.     puts ("           [-v]\n");
  112.     puts ("Options:");
  113.     puts ("  -h       - This help text.");
  114.     puts ("  -x       - Extract files in archive instead");
  115.     puts ("             of splitting it into parts.");
  116.     puts ("  -v       - Display version information.\n");
  117.     puts ("  Without any options ssh splits archives");
  118.     puts ("  into extractable 'PartXX' files.\n");
  119.     exit (rc);
  120. }
  121.  
  122. void main (argn, argv)
  123.  
  124. int   argn;
  125. char *argv[];
  126.  
  127. {
  128.     FILE     *fr = stdin;          /* Input filepointer  */
  129.     FILE     *fw;                  /* Output filepointer */
  130.     FILE     *pipe;                /* Stream pipe        */
  131.     int       state = SEARCH;      /* The current state  */
  132.     int       fc = 0;              /* File part counter  */
  133.     int       extract = FALSE;     /* Extract/write flag */
  134.     char     *s;                   /* Read line          */
  135.     char      fout[7];             /* Output filenames   */
  136.     register  j = 0;               /* Counter            */
  137.     register  c;                   /* Read character     */
  138.  
  139.     /* Check the arguments if any */
  140.     while (--argn) {
  141.         argv++;
  142.         if (!(strcmp (*argv, "-h"))) {     /* Help screen */
  143.             if (!(argn-1))     /* Single option */
  144.                 usage (0);
  145.         }
  146.         else if (!(strcmp (*argv, "-x"))) {     /* Extract files */ 
  147.             if (!(argn-1)) {     /* Single option */
  148.                 extract = TRUE;
  149.                 continue;
  150.             }
  151.         }
  152.         else if (!(strcmp (*argv, "-v"))) {
  153.             if (!(argn-1)) {     /* Single option */
  154.                 puts ("ssh v1.30  (bugs to etxerus@james.ericsson.se)");
  155.                 exit (0);
  156.             }
  157.         }
  158.         usage (1);
  159.     }  
  160.  
  161.     msize = MSTEP;
  162.     s = malloc (msize);     /* Allocate buffer */
  163.  
  164.     while ((c = getc (fr)) != EOF) {
  165.     if (c != '\n') {     /* Check for EOL */
  166.         s[j++] = c;
  167.             if (j == msize) {
  168.                 msize += MSTEP;
  169.                 if ((s = realloc (s, msize)) == NULL) {
  170.                     fprintf (stderr, "ssh: Allocation error, cannot continue.\n");
  171.                     exit (1);
  172.                 }
  173.             }
  174.         }
  175.     else {
  176.         s[j] = '\0';     /* One line has been read */
  177.         switch (state) {
  178.         case SEARCH:
  179.                     for (j = 0; pattern[j][0] != NULL; j++) {
  180.                         if (!(strncasecmp (s, pattern[j], strlen (pattern[j])))) {
  181.                             state = START;
  182.                             break;    
  183.                         }
  184.                     }
  185.                     if (state != START)
  186.                         break;
  187.  
  188.         case START:     /* Start writing or extracting */
  189.                     if (!extract) {
  190.                 sprintf (fout, "Part%.2d", ++fc);
  191.                 fw = fopen (fout, "w");
  192.                         fprintf (fw, "%s\n", s);
  193.                     }
  194.                     else {
  195.                         if ((pipe = popen (SHELL, "w")) == NULL) {
  196.                             fprintf (stderr, "ssh: Cannot create process.\n");
  197.                             exit (1);
  198.                         }
  199.                         fprintf (pipe, "%s\n", s);
  200.                     }
  201.                     state = INSIDE;
  202.             break;
  203.  
  204.                 case INSIDE:
  205.             if (!(strcmp (s, "exit 0"))) {     /* Look for end */
  206.                         if (!extract) {
  207.                             fprintf (fw, "%s\n", s);
  208.                             fclose (fw);
  209.                         }
  210.                         else {
  211.                             fprintf (pipe, "%s\n", s);
  212.                             pclose (pipe);
  213.                         }
  214.                         state = SEARCH;
  215.                     }
  216.                     else {
  217.                         if (extract)
  218.                             fprintf (pipe, "%s\n", s);
  219.                         else
  220.                 fprintf (fw, "%s\n", s);
  221.                     }
  222.             break;
  223.             }
  224.             j = 0;    /* Reset counter */
  225.         }
  226.     }
  227. }
  228.