home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 9 Archive / 09-Archive.zip / unzip512.zip / vms / cmdline.c < prev    next >
C/C++ Source or Header  |  1994-08-23  |  20KB  |  776 lines

  1. #define module_name VMS_UNZIP_CMDLINE
  2. #define module_ident "02-002"
  3. /*
  4. **
  5. **  Facility:    UNZIP
  6. **
  7. **  Module:    VMS_UNZIP_CMDLINE
  8. **
  9. **  Author:    Hunter Goatley <goathunter@wkuvx1.wku.edu>
  10. **
  11. **  Date:    12 Jul 94 (orig. Zip version, 30 Jul 93)
  12. **
  13. **  Abstract:    Routines to handle a VMS CLI interface for UnZip.  The CLI
  14. **        command line is parsed and a new argc/argv are built and
  15. **        returned to UnZip.
  16. **
  17. **  Modified by:
  18. **
  19. **    02-002        Hunter Goatley        16-JUL-1994 10:20
  20. **        Fixed some typos.
  21. **    02-001        Cave Newt             14-JUL-1994 15:18
  22. **        Removed obsolete /EXTRACT option; fixed /*TEXT options;
  23. **        wrote VMSCLI usage() function
  24. **    02-000        Hunter Goatley        12-JUL-1994 00:00
  25. **        Original UnZip version (v5.11).
  26. **    01-000        Hunter Goatley        30-JUL-1993 07:54
  27. **        Original version (for Zip v1.9p1).
  28. **
  29. */
  30.  
  31.  
  32. #ifdef __alpha
  33. #pragma module module_name module_ident
  34. #else
  35. #module module_name module_ident
  36. #endif
  37.  
  38. #include "unzip.h"
  39. #include "version.h"    /* for usage() */
  40.  
  41. #include <ssdef.h>
  42. #include <descrip.h>
  43. #include <climsgdef.h>
  44. #include <clidef.h>
  45. #include <lib$routines.h>
  46. #include <str$routines.h>
  47.  
  48. #ifndef CLI$_COMMA
  49. globalvalue CLI$_COMMA;
  50. #endif
  51.  
  52. /*
  53. **  "Macro" to initialize a dynamic string descriptor.
  54. */
  55. #define init_dyndesc(dsc) {\
  56.     dsc.dsc$w_length = 0;\
  57.     dsc.dsc$b_dtype = DSC$K_DTYPE_T;\
  58.     dsc.dsc$b_class = DSC$K_CLASS_D;\
  59.     dsc.dsc$a_pointer = 0;}
  60.  
  61. /*
  62. **  Define descriptors for all of the CLI parameters and qualifiers.
  63. */
  64. #if 0
  65. $DESCRIPTOR(cli_extract,    "EXTRACT");    /* obsolete */
  66. #endif
  67. $DESCRIPTOR(cli_autotext,    "AUTOTEXT");    /* -a */
  68. $DESCRIPTOR(cli_text,        "TEXT");    /* -aa */
  69. $DESCRIPTOR(cli_case_insensitive,    "CASE_INSENSITIVE");    /* -C */
  70. $DESCRIPTOR(cli_screen,        "SCREEN");    /* -c */
  71. $DESCRIPTOR(cli_directory,    "DIRECTORY");    /* see JUNK */
  72. $DESCRIPTOR(cli_freshen,    "FRESHEN");    /* -f */
  73. $DESCRIPTOR(cli_junk,        "JUNK");    /* -j */
  74. $DESCRIPTOR(cli_lowercase,    "LOWERCASE");    /* -L */
  75. $DESCRIPTOR(cli_list,        "LIST");    /* -l */
  76. $DESCRIPTOR(cli_brief,        "BRIEF");    /* -l */
  77. $DESCRIPTOR(cli_full,        "FULL");    /* -v */
  78. $DESCRIPTOR(cli_overwrite,    "OVERWRITE");    /* -o, -n */
  79. $DESCRIPTOR(cli_quiet,        "QUIET");    /* -q */
  80. $DESCRIPTOR(cli_super_quiet,    "SUPER_QUIET");    /* -qq */
  81. $DESCRIPTOR(cli_test,        "TEST");    /* -t */
  82. $DESCRIPTOR(cli_type,        "TYPE");    /* -c */
  83. $DESCRIPTOR(cli_pipe,        "PIPE");    /* -p */
  84. $DESCRIPTOR(cli_uppercase,    "UPPERCASE");    /* -U */
  85. $DESCRIPTOR(cli_update,        "UPDATE");    /* -u */
  86. $DESCRIPTOR(cli_version,    "VERSION");    /* -V */
  87. $DESCRIPTOR(cli_verbose,    "VERBOSE");    /* -v */
  88. $DESCRIPTOR(cli_restore,    "RESTORE");    /* -X */
  89. $DESCRIPTOR(cli_comment,    "COMMENT");    /* -z */
  90. $DESCRIPTOR(cli_exclude,    "EXCLUDE");    /* -x */
  91.  
  92. $DESCRIPTOR(cli_information,    "ZIPINFO");    /* -Z */
  93. $DESCRIPTOR(cli_short,        "SHORT");    /* -Zs */
  94. $DESCRIPTOR(cli_medium,        "MEDIUM");    /* -Zm */
  95. $DESCRIPTOR(cli_long,        "LONG");    /* -Zl */
  96. $DESCRIPTOR(cli_header,        "HEADER");    /* -Zh */
  97. $DESCRIPTOR(cli_totals,        "TOTALS");    /* -Zt */
  98. $DESCRIPTOR(cli_times,        "TIMES");    /* -ZT */
  99. $DESCRIPTOR(cli_one_line,    "ONE_LINE");    /* -Z2 */
  100.  
  101. $DESCRIPTOR(cli_yyz,        "YYZ");
  102.  
  103. $DESCRIPTOR(cli_zipfile,    "ZIPFILE");
  104. $DESCRIPTOR(cli_infile,        "INFILE");
  105. $DESCRIPTOR(unzip_command,    "unzip ");
  106. $DESCRIPTOR(blank,        " ");
  107.  
  108. #ifdef __alpha
  109. extern void *vms_unzip_cld;
  110. #else
  111. globalref void *vms_unzip_cld;
  112. #endif
  113.  
  114. /* extern unsigned long LIB$GET_INPUT(void), LIB$SIG_TO_RET(void); */
  115.  
  116. extern unsigned long cli$dcl_parse ();
  117. extern unsigned long cli$present ();
  118. extern unsigned long cli$get_value ();
  119.  
  120. unsigned long vms_unzip_cmdline (int *, char ***);
  121. unsigned long get_list (struct dsc$descriptor_s *, char **,
  122.             struct dsc$descriptor_d *, char);
  123. unsigned long check_cli (struct dsc$descriptor_s *);
  124.  
  125.  
  126. #ifdef TEST
  127. unsigned long
  128. main(int argc, char **argv)
  129. {
  130.     register status;
  131.     return (vms_unzip_cmdline(&argc, &argv));
  132. }
  133. #endif /* TEST */
  134.  
  135.  
  136. unsigned long
  137. vms_unzip_cmdline (int *argc_p, char ***argv_p)
  138. {
  139. /*
  140. **  Routine:    vms_unzip_cmdline
  141. **
  142. **  Function:
  143. **
  144. **    Parse the DCL command line and create a fake argv array to be
  145. **    handed off to Zip.
  146. **
  147. **    NOTE: the argv[] is built as we go, so all the parameters are
  148. **    checked in the appropriate order!!
  149. **
  150. **  Formal parameters:
  151. **
  152. **    argc_p        - Address of int to receive the new argc
  153. **    argv_p        - Address of char ** to receive the argv address
  154. **
  155. **  Calling sequence:
  156. **
  157. **    status = vms_unzip_cmdline (&argc, &argv);
  158. **
  159. **  Returns:
  160. **
  161. **    SS$_NORMAL    - Success.
  162. **    SS$_INSFMEM    - A malloc() or realloc() failed
  163. **    SS$_ABORT    - Bad time value
  164. **
  165. */
  166.     register status;
  167.     char options[256];
  168.     char *the_cmd_line;
  169.     char *ptr;
  170.     int  x, len, zipinfo;
  171.  
  172.     int new_argc;
  173.     char **new_argv;
  174.  
  175.     struct dsc$descriptor_d work_str;
  176.     struct dsc$descriptor_d foreign_cmdline;
  177.     struct dsc$descriptor_d output_directory;
  178.  
  179.     init_dyndesc (work_str);
  180.     init_dyndesc (foreign_cmdline);
  181.     init_dyndesc (output_directory);
  182.  
  183.     /*
  184.     **  See if the program was invoked by the CLI (SET COMMAND) or by
  185.     **  a foreign command definition.  Check for /YYZ, which is a
  186.     **  valid default qualifier solely for this test.
  187.     */
  188.     status = check_cli (&cli_yyz);
  189.     if (!(status & 1)) {
  190.     lib$get_foreign (&foreign_cmdline);
  191.     /*
  192.     **  If nothing was returned or the first character is a "-", then
  193.     **  assume it's a UNIX-style command and return.
  194.     */
  195.         if ((foreign_cmdline.dsc$w_length == 0) || (*(foreign_cmdline.dsc$a_pointer) == '-'))
  196.             return(SS$_NORMAL);
  197.  
  198.     str$concat (&work_str, &unzip_command, &foreign_cmdline);
  199.     status = cli$dcl_parse(&work_str, &vms_unzip_cld, lib$get_input,
  200.             lib$get_input, 0);
  201.     if (!(status & 1)) return(status);
  202.     }
  203.  
  204.     /*
  205.     **  There's always going to be an new_argv[] because of the image name.
  206.     */
  207.     if ((the_cmd_line = (char *) malloc (sizeof("unzip")+1)) == NULL)
  208.     return(SS$_INSFMEM);
  209.  
  210.     strcpy (the_cmd_line, "unzip");
  211.  
  212.     /*
  213.     **  First, check to see if any of the regular options were specified.
  214.     */
  215.  
  216.     options[0] = '-';
  217.     ptr = &options[1];        /* Point to temporary buffer */
  218.  
  219.     /*
  220.     **  Is it Zipinfo??
  221.     */
  222.     zipinfo = 0;
  223.     status = cli$present (&cli_information);
  224.     if (status & 1) {
  225.  
  226.     zipinfo = 1;
  227.  
  228.     *ptr++ = 'Z';
  229.     *ptr++ = ' ';
  230.     *ptr++ = '-';
  231.  
  232.     if (cli$present(&cli_one_line) & 1)
  233.         *ptr++ = '2';
  234.     if (cli$present(&cli_short) & 1)
  235.         *ptr++ = 's';
  236.     if (cli$present(&cli_medium) & 1)
  237.         *ptr++ = 'm';
  238.     if (cli$present(&cli_long) & 1)
  239.         *ptr++ = 'l';
  240.     if (cli$present(&cli_header) & 1)
  241.         *ptr++ = 'h';
  242.     if (cli$present(&cli_comment) & 1)
  243.         *ptr++ = 'c';
  244.     if (cli$present(&cli_totals) & 1)
  245.         *ptr++ = 't';
  246.     if (cli$present(&cli_times) & 1)
  247.         *ptr++ = 'T';
  248.  
  249.     /* If no other options were specified, remove the " -". */
  250.     if (*(ptr - 1) == '-')
  251.         ptr = ptr - 2;
  252.  
  253.     }
  254.     else {
  255.  
  256. #if 0
  257.     /*
  258.     **  Extract files?
  259.     */
  260.     status = cli$present (&cli_extract);
  261.     if (status == CLI$_NEGATED)
  262.     *ptr++ = '-';
  263.     if (status != CLI$_ABSENT)
  264.     *ptr++ = 'x';
  265. #endif
  266.  
  267.     /*
  268.     **  Convert all files as text (CR LF -> LF, etc.)
  269.     */
  270.     status = cli$present (&cli_text);
  271.     if (status == CLI$_NEGATED)
  272.     *ptr++ = '-';
  273.     if (status != CLI$_ABSENT) {
  274.     *ptr++ = 'a';
  275.     *ptr++ = 'a';
  276.     }
  277.  
  278.     /*
  279.     **  Auto-convert only text files as text
  280.     */
  281.     status = cli$present (&cli_autotext);
  282.     if (status == CLI$_NEGATED)
  283.     *ptr++ = '-';
  284.     if (status != CLI$_ABSENT)
  285.     *ptr++ = 'a';
  286.  
  287.     /*
  288.     **  Extract files to screen?
  289.     */
  290.     status = cli$present (&cli_screen);
  291.     if (status == CLI$_NEGATED)
  292.     *ptr++ = '-';
  293.     if (status != CLI$_ABSENT)
  294.     *ptr++ = 'c';
  295.  
  296.     /*
  297.     **  Re-create directory structure?  (default)
  298.     */
  299.     status = cli$present (&cli_directory);
  300.     if (status == CLI$_PRESENT) {
  301.     status = cli$get_value (&cli_directory, &output_directory);
  302.     }
  303.  
  304.     /*
  305.     **  Freshen existing files, create none
  306.     */
  307.     status = cli$present (&cli_freshen);
  308.     if (status == CLI$_NEGATED)
  309.     *ptr++ = '-';
  310.     if (status != CLI$_ABSENT)
  311.     *ptr++ = 'f';
  312.  
  313.     /*
  314.     **  Junk stored directory names on unzip
  315.     */
  316.     status = cli$present (&cli_junk);
  317.     if (status == CLI$_NEGATED)
  318.     *ptr++ = '-';
  319.     if (status != CLI$_ABSENT)
  320.     *ptr++ = 'j';
  321.  
  322.     /*
  323.     **  List contents (/BRIEF or /FULL (default))
  324.     */
  325.     status = cli$present (&cli_list);
  326.     if (status & 1) {
  327.     if (cli$present(&cli_full) & 1)
  328.        *ptr++ = 'v';
  329.     else
  330.        *ptr++ = 'l';
  331.     }
  332.  
  333.     /*
  334.     **  Overwrite files?
  335.     */
  336.     status = cli$present (&cli_overwrite);
  337.     if (status == CLI$_NEGATED)
  338.     *ptr++ = 'n';
  339.     else if (status != CLI$_ABSENT)
  340.     *ptr++ = 'o';
  341.  
  342.     /*
  343.     **  Pipe files to SYS$OUTPUT with no informationals?
  344.     */
  345.     status = cli$present (&cli_pipe);
  346.     if (status != CLI$_ABSENT)
  347.     *ptr++ = 'p';
  348.  
  349.     /*
  350.     **  Quiet
  351.     */
  352.     status = cli$present (&cli_quiet);
  353.     if (status & 1)
  354.     *ptr++ = 'q';
  355.  
  356.     status = cli$present (&cli_super_quiet);
  357.     if (status & 1)
  358.     *ptr++ = 'q';
  359.  
  360.     /*
  361.     **  Test archive integrity
  362.     */
  363.     status = cli$present (&cli_test);
  364.     if (status == CLI$_NEGATED)
  365.     *ptr++ = '-';
  366.     if (status != CLI$_ABSENT)
  367.     *ptr++ = 't';
  368.  
  369.     /*
  370.     **  Match filenames case-insensitively (-C)
  371.     */
  372.     status = cli$present (&cli_case_insensitive);
  373.     if (status == CLI$_NEGATED)
  374.     *ptr++ = '-';
  375.     if (status != CLI$_ABSENT)
  376.     *ptr++ = 'C';
  377.  
  378.     /*
  379.     **  Make (some) names lowercase
  380.     */
  381.     status = cli$present (&cli_lowercase);
  382.     if (status == CLI$_NEGATED)
  383.     *ptr++ = '-';
  384.     if (status != CLI$_ABSENT)
  385.     *ptr++ = 'L';
  386.  
  387.     /*
  388.     **  Uppercase (don't convert to lower)
  389.     */
  390.     status = cli$present (&cli_uppercase);
  391.     if (status == CLI$_NEGATED)
  392.     *ptr++ = '-';
  393.     if (status != CLI$_ABSENT)
  394.     *ptr++ = 'U';
  395.  
  396.     /*
  397.     **  Update (extract only new and newer files)
  398.     */
  399.     status = cli$present (&cli_update);
  400.     if (status == CLI$_NEGATED)
  401.     *ptr++ = '-';
  402.     if (status != CLI$_ABSENT)
  403.     *ptr++ = 'u';
  404.  
  405.     /*
  406.     **  Version (retain VMS/DEC-20 file versions)
  407.     */
  408.     status = cli$present (&cli_version);
  409.     if (status == CLI$_NEGATED)
  410.     *ptr++ = '-';
  411.     if (status != CLI$_ABSENT)
  412.     *ptr++ = 'V';
  413.  
  414.     /*
  415.     **  Verbose
  416.     */
  417.     status = cli$present (&cli_verbose);
  418.     if (status & 1)
  419.     *ptr++ = 'v';
  420.  
  421.     /*
  422.     **  Restore owner/protection info
  423.     */
  424.     status = cli$present (&cli_restore);
  425.     if (status == CLI$_NEGATED)
  426.     *ptr++ = '-';
  427.     if (status != CLI$_ABSENT)
  428.     *ptr++ = 'X';
  429.  
  430.     /*
  431.     **  Display only the archive comment
  432.     */
  433.     status = cli$present (&cli_comment);
  434.     if (status == CLI$_NEGATED)
  435.     *ptr++ = '-';
  436.     if (status != CLI$_ABSENT)
  437.     *ptr++ = 'z';
  438.  
  439.     }    /* Zipinfo check way up there.... */
  440.  
  441.     /*
  442.     **  If the user didn't give any DCL qualifier, assume he wants the
  443.     **  Un*x interface.
  444.     if (ptr == &options[1])
  445.       return(SS$_NORMAL);
  446.     */
  447.  
  448.     /*
  449.     **  Now copy the final options string to the_cmd_line.
  450.     */
  451.     x = ptr - &options[0];
  452.     if (x > 1) {
  453.     options[x] = '\0';
  454.     len = strlen(the_cmd_line) + x + 2;
  455.     if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
  456.         return(SS$_INSFMEM);
  457.     strcat (the_cmd_line, " ");
  458.     strcat (the_cmd_line, options);
  459.     }
  460.  
  461.     /*
  462.     **  Now get the specified zip file name.
  463.     */
  464.     status = cli$present (&cli_zipfile);
  465.     if (status & 1) {
  466.     status = cli$get_value (&cli_zipfile, &work_str);
  467.  
  468.     len = strlen(the_cmd_line) + work_str.dsc$w_length + 2;
  469.     if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
  470.         return(SS$_INSFMEM);
  471.     strcat (the_cmd_line, " ");
  472.     x = strlen(the_cmd_line);
  473.     strncpy(&the_cmd_line[x], work_str.dsc$a_pointer,
  474.         work_str.dsc$w_length);
  475.     the_cmd_line[len] = '\0';
  476.  
  477.     }
  478.  
  479.     /*
  480.     **  Run through the list of files to unzip.
  481.     */
  482.     status = cli$present (&cli_infile);
  483.     if (status & 1) {
  484.     len = strlen(the_cmd_line) + 2;
  485.     if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
  486.         return(SS$_INSFMEM);
  487.     strcat (the_cmd_line, " ");
  488.     status = get_list (&cli_infile, &the_cmd_line, &foreign_cmdline, ' ');
  489.     if (!(status & 1)) return (status);
  490.     }
  491.  
  492.     /*
  493.     **  Get the list of files to exclude, if there are any.
  494.     */
  495.     status = cli$present (&cli_exclude);
  496.     if (status & 1) {
  497.     len = strlen(the_cmd_line) + 5;
  498.     if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
  499.         return(SS$_INSFMEM);
  500.     strcat (the_cmd_line, " -x ");
  501.     status = get_list (&cli_exclude, &the_cmd_line, &foreign_cmdline, ' ');
  502.     if (!(status & 1)) return (status);
  503.     }
  504.  
  505.     /*
  506.     **  Get the output directory, for UnZip.
  507.     **/
  508.     if (output_directory.dsc$w_length != 0) {
  509.     len = strlen(the_cmd_line) + output_directory.dsc$w_length + 5;
  510.     if ((the_cmd_line = (char *) realloc (the_cmd_line, len)) == NULL)
  511.         return(SS$_INSFMEM);
  512.     strcat (the_cmd_line, " -d ");
  513.     x = strlen(the_cmd_line);
  514.     strncpy(&the_cmd_line[x], output_directory.dsc$a_pointer,
  515.         output_directory.dsc$w_length);
  516.     the_cmd_line[len] = '\0';
  517.     }
  518.  
  519.     /*
  520.     **  Now that we've built our new UNIX-like command line, count the
  521.     **  number of args and build an argv array.
  522.     */
  523.  
  524. #if defined(TEST) || defined(DEBUG)
  525.     printf("%s\n",the_cmd_line);
  526. #endif /* TEST */
  527.  
  528.     new_argc = 1;
  529.     for (ptr = the_cmd_line;
  530.      (ptr = strchr(ptr,' ')) != NULL;
  531.      ptr++, new_argc++);
  532.  
  533.     /*
  534.     **  Allocate memory for the new argv[].  The last element of argv[]
  535.     **  is supposed to be 0, so allocate enough for new_argc+1.
  536.     */
  537.     if ((new_argv = (char **) calloc (new_argc+1, sizeof(char *))) == NULL)
  538.     return(SS$_INSFMEM);
  539.  
  540.     /*
  541.     **  For each option, store the address in new_argv[] and convert the
  542.     **  separating blanks to nulls so each argv[] string is terminated.
  543.     */
  544.     for (ptr = the_cmd_line, x = 0; x < new_argc; x++) {
  545.     new_argv[x] = ptr;
  546.     if ((ptr = strchr (ptr, ' ')) != NULL)
  547.         *ptr++ = '\0';
  548.     }
  549.     new_argv[new_argc] = 0;
  550.  
  551. #if defined(TEST) || defined(DEBUG)
  552.     printf("new_argc    = %d\n", new_argc);
  553.     for (x = 0; x < new_argc; x++)
  554.     printf("new_argv[%d] = %s\n", x, new_argv[x]);
  555. #endif /* TEST */
  556.  
  557.     /*
  558.     **  All finished.  Return the new argc and argv[] addresses to Zip.
  559.     */
  560.     *argc_p = new_argc;
  561.     *argv_p = new_argv;
  562.  
  563.     return(SS$_NORMAL);
  564. }
  565.  
  566.  
  567.  
  568. unsigned long
  569. get_list (struct dsc$descriptor_s *qual, char **str,
  570.       struct dsc$descriptor_d *cmdline, char c)
  571. {
  572. /*
  573. **  Routine:    get_list
  574. **
  575. **  Function:    This routine runs through a comma-separated CLI list
  576. **        and copies the strings to the command line.  The
  577. **        specified separation character is used to separate
  578. **        the strings on the command line.
  579. **
  580. **        All strings are converted to lower-case.
  581. **
  582. **  Formal parameters:
  583. **
  584. **    qual    - Address of descriptor for the qualifier name
  585. **    str    - Address of pointer pointing to string (command line)
  586. **    c    - Character to use to separate the list items
  587. **
  588. */
  589.  
  590.     register status;
  591.     struct dsc$descriptor_d work_str;
  592.  
  593.     init_dyndesc(work_str);
  594.  
  595.     status = cli$present (qual);
  596.     if (status & 1) {
  597.  
  598.     unsigned long len, old_len, lower_it, ind, sind;
  599.  
  600.     len = strlen(*str);
  601.     while ((status = cli$get_value (qual, &work_str)) & 1) {
  602.         /*
  603.         **  Just in case the string doesn't exist yet, though it does.
  604.         */
  605.         if (*str == NULL) {
  606.         len = work_str.dsc$w_length + 1;
  607.         if ((*str = (char *) malloc (work_str.dsc$w_length)) == NULL)
  608.             return(SS$_INSFMEM);
  609.         strncpy(*str,work_str.dsc$a_pointer,len);
  610.         } else {
  611.         char *src, *dst; int x;
  612.         old_len = len;
  613.         len += work_str.dsc$w_length + 1;
  614.         if ((*str = (char *) realloc (*str, len)) == NULL)
  615.             return(SS$_INSFMEM);
  616.  
  617.         /*
  618.         **  Look for the filename in the original foreign command
  619.         **  line to see if it was originally quoted.  If so, then
  620.         **  don't convert it to lowercase.
  621.         */
  622.         lower_it = 0;
  623.         str$find_first_substring (cmdline, &ind, &sind, &work_str);
  624.         if (*(cmdline->dsc$a_pointer + ind - 2) == '"')
  625.             lower_it = 1;
  626.  
  627.         /*
  628.         **  Copy the string to the buffer, converting to lowercase.
  629.         */
  630.         src = work_str.dsc$a_pointer;
  631.         dst = *str+old_len;
  632.         for (x = 0; x < work_str.dsc$w_length; x++) {
  633.             if (!lower_it && ((*src >= 'A') && (*src <= 'Z')))
  634.             *dst++ = *src++ + 32;
  635.             else
  636.             *dst++ = *src++;
  637.         }
  638.         }
  639.         if (status == CLI$_COMMA)
  640.         (*str)[len-1] = c;
  641.         else
  642.         (*str)[len-1] = '\0';
  643.     }
  644.     }
  645.  
  646.     return (SS$_NORMAL);
  647.  
  648. }
  649.  
  650.  
  651. unsigned long
  652. check_cli (struct dsc$descriptor_s *qual)
  653. {
  654. /*
  655. **  Routine:    check_cli
  656. **
  657. **  Function:    Check to see if a CLD was used to invoke the program.
  658. **
  659. **  Formal parameters:
  660. **
  661. **    qual    - Address of descriptor for qualifier name to check.
  662. **
  663. */
  664.     lib$establish(lib$sig_to_ret);    /* Establish condition handler */
  665.     return (cli$present(qual));        /* Just see if something was given */
  666. }
  667.  
  668.  
  669.  
  670. #ifndef SFX
  671.  
  672. #ifdef VMSWILD
  673. #  define ZI_XMPL  "*, %, () (e.g., \"(a-j)*pk.%%\")"
  674. #else
  675. #  define ZI_XMPL  "*, ?, [] (e.g., \"[a-j]*pk.??\")"
  676. #endif
  677.  
  678. int usage( int error)   /* VMSCLI version; returns PK-type error code */
  679. {
  680.     FILE *usagefp;
  681.     extern char UnzipUsageLine1[];
  682.  
  683.  
  684. /*---------------------------------------------------------------------------
  685.     If user requested usage, send it to stdout; else send to stderr.
  686.   ---------------------------------------------------------------------------*/
  687.  
  688.     if (error)
  689.         usagefp = (FILE *)stderr;
  690.     else
  691.         usagefp = (FILE *)stdout;
  692.  
  693. /*---------------------------------------------------------------------------
  694.     Print either ZipInfo usage or UnZip usage, depending on incantation.
  695.   ---------------------------------------------------------------------------*/
  696.  
  697.     if (zipinfo_mode) {
  698.  
  699. #ifndef NO_ZIPINFO
  700.  
  701.         fprintf(usagefp, "\
  702. ZipInfo %s, by Newtware and the fine folks at Info-ZIP.\n\n\
  703. List name, date/time, attribute, size, compression method, etc., about files\n\
  704. in list (excluding those in xlist) contained in the specified .zip archive(s).\
  705. \n\"file[.zip]\" may be a wildcard name containing %s.\n", ZI_VERSION, ZI_XMPL);
  706.  
  707.         fprintf(usagefp, "\n\
  708.    usage:  zipinfo file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options\n\
  709.    or:  unzip /ZIPINFO file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options\
  710. \n\nmain\
  711.  listing-format options:              /SHORT   short \"ls -l\" format (def.)\n\
  712.   /ONE_LINE  just filenames, one/line     /MEDIUM  medium Unix \"ls -l\" format\n\
  713.   /VERBOSE   verbose, multi-page format   /LONG    long Unix \"ls -l\" format\n\
  714.     ");
  715.  
  716.         fprintf(usagefp, "\n\
  717. miscellaneous options:\n  \
  718. /HEADER   print header line       /TOTALS  totals for listed files or for all\n\
  719.   /COMMENT  print zipfile comment   /TIMES   times in sortable decimal format\n\
  720.   /EXCLUDE=(file-spec1,etc.)  exclude file-specs from listing\n");
  721.  
  722.         fprintf(usagefp, "\nRemember that non-lowercase filespecs must be\
  723.  quoted in VMS (e.g., \"Makefile\").\n");
  724.  
  725. #endif /* !NO_ZIPINFO */
  726.  
  727.     } else {   /* UnZip mode */
  728.  
  729.         fprintf(usagefp, UnzipUsageLine1, UZ_VERSION);
  730.  
  731. #ifdef BETA
  732.         fprintf(usagefp, "\
  733.       THIS IS STILL A BETA VERSION OF UNZIP%s -- DO NOT DISTRIBUTE.\n\n",
  734.           "", "");
  735. #endif
  736.  
  737.         fprintf(usagefp, "\
  738. Usage: unzip file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options /modifiers\
  739. \n  Default action is to extract files in list, except those in xlist, to exdir\
  740. ;\n  file[.zip] may be a wildcard.  %s\n\n",
  741. #ifdef NO_ZIPINFO
  742.           "(ZipInfo mode is disabled in this version.)"
  743. #else
  744.           "Type \"unzip /ZIPINFO\" for ZipInfo-mode usage."
  745. #endif
  746.           );
  747.  
  748.         fprintf(usagefp, "\
  749. Major options include:\n\
  750.    /[NO]TEST, /LIST, /[NO]SCREEN, /PIPE, /[NO]FRESHEN, /[NO]UPDATE,\n\
  751.    /[NO]COMMENT, /DIRECTORY=directory-spec, /EXCLUDE=(file-spec1,etc.)\n\n\
  752. Modifiers include:\n\
  753.    /BRIEF, /FULL, /[NO]AUTOTEXT, /[NO]TEXT, /[NO]OVERWRITE, /[NO]JUNK,\n\
  754.    /QUIET, /SUPER_QUIET, /[NO]CASE_INSENSITIVE, /[NO]LOWERCASE,\n\
  755.    /[NO]VERSION, /[NO]RESTORE\n\n");
  756.  
  757.         fprintf(usagefp, "\
  758. Examples (see unzip.doc or \"HELP UNZIP\" for more info):\n   \
  759. unzip edit1 /EXCL=joe.jou /CASE_INSENSITIVE    => extract all files except\n   \
  760.    joe.jou (or JOE.JOU, or any combination of case) from zipfile edit1.zip\n   \
  761. unzip zip201 \"Makefile.VMS\" vms/*.[ch]         => extract VMS Makefile and\n\
  762.       *.c and *.h files; must quote uppercase names if /CASE_INSENS not used\n\
  763.    unzip foo /DIR=tmp:[.test] /JUNK /AUTO /OVER   => extract all files to temp.\
  764. \n      directory without paths, auto-converting text files and overwriting\n");
  765.  
  766.     } /* end if (zipinfo_mode) */
  767.  
  768.     if (error)
  769.         return PK_PARAM;
  770.     else
  771.         return PK_COOL;     /* just wanted usage screen: no error */
  772.  
  773. } /* end function usage() */
  774.  
  775. #endif /* !SFX */
  776.