📄 cmdline.c
字号:
/* ** Make (some) names lowercase */ status = cli$present(&cli_lowercase); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'L'; /* ** Uppercase (don't convert to lower) */ status = cli$present(&cli_uppercase); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'U'; /* ** Update (extract only new and newer files) */ status = cli$present(&cli_update); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'u'; /* ** Version (retain VMS/DEC-20 file versions) */ status = cli$present(&cli_version); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'V'; /* ** Restore owner/protection info */ status = cli$present(&cli_restore); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'X'; /* ** Display only the archive comment */ status = cli$present(&cli_comment); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'z'; } /* ZipInfo check way up there.... */ /* The following options are common to both UnZip and ZipInfo mode. */ /* ** Match filenames case-insensitively (-C) */ status = cli$present(&cli_case_insensitive); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'C'; /* ** Use builtin pager for all screen output */ status = cli$present(&cli_page); if (status == CLI$_NEGATED) *ptr++ = '-'; if (status != CLI$_ABSENT) *ptr++ = 'M'; /* ** Check existence of a list of files to exclude, fetch is done later. */ status = cli$present(&cli_exclude); exclude_list = ((status & 1) != 0); /* ** If the user didn't give any DCL qualifier, assume he wants the ** Un*x interface. if ( (ptr == &options[1]) && (output_directory.dsc$w_length == 0) && (password_arg.dsc$w_length == 0) && (!exclude_list) ) { free(the_cmd_line); return (SS$_NORMAL); } */ /* ** Now copy the final options string to the_cmd_line. */ len = ptr - &options[0]; if (len > 1) { options[len] = '\0'; x = cmdl_len; cmdl_len += len + 1; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], options); } /* ** If specified, add the decryption password argument. **/ if (password_arg.dsc$w_length != 0) { x = cmdl_len; cmdl_len += password_arg.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-P"); strncpy(&the_cmd_line[x+3], password_arg.dsc$a_pointer, password_arg.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Now get the specified zip file name. */ status = cli$present(&cli_zipfile); if (status & 1) { status = cli$get_value(&cli_zipfile, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 1; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strncpy(&the_cmd_line[x], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Get the output directory, for UnZip. **/ if (output_directory.dsc$w_length != 0) { x = cmdl_len; cmdl_len += output_directory.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-d"); strncpy(&the_cmd_line[x+3], output_directory.dsc$a_pointer, output_directory.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Run through the list of files to unzip. */ status = cli$present(&cli_infile); if (status & 1) { status = get_list(&cli_infile, &foreign_cmdline, '\0', &the_cmd_line, &cmdl_size, &cmdl_len); if (!(status & 1)) return (status); } /* ** Get the list of files to exclude, if there are any. */ if (exclude_list) { x = cmdl_len; cmdl_len += 3; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-x"); status = get_list(&cli_exclude, &foreign_cmdline, '\0', &the_cmd_line, &cmdl_size, &cmdl_len); if (!(status & 1)) return (status); } /* ** We have finished collecting the strings for the argv vector, ** release unused space. */ if ((the_cmd_line = (char *) realloc(the_cmd_line, cmdl_len)) == NULL) return (SS$_INSFMEM); /* ** Now that we've built our new UNIX-like command line, count the ** number of args and build an argv array. */ for (new_argc = 0, x = 0; x < cmdl_len; x++) if (the_cmd_line[x] == '\0') new_argc++; /* ** Allocate memory for the new argv[]. The last element of argv[] ** is supposed to be NULL, so allocate enough for new_argc+1. */ if ((new_argv = (char **) calloc(new_argc+1, sizeof(char *))) == NULL) return (SS$_INSFMEM); /* ** For each option, store the address in new_argv[] and convert the ** separating blanks to nulls so each argv[] string is terminated. */ for (ptr = the_cmd_line, x = 0; x < new_argc; x++) { new_argv[x] = ptr; ptr += strlen(ptr) + 1; } new_argv[new_argc] = NULL;#if defined(TEST) || defined(DEBUG) printf("new_argc = %d\n", new_argc); for (x = 0; x < new_argc; x++) printf("new_argv[%d] = %s\n", x, new_argv[x]);#endif /* TEST || DEBUG */ /* ** All finished. Return the new argc and argv[] addresses to Zip. */ *argc_p = new_argc; *argv_p = new_argv; return (SS$_NORMAL);}static unsigned longget_list (struct dsc$descriptor_s *qual, struct dsc$descriptor_d *rawtail, int delim, char **p_str, unsigned long *p_size, unsigned long *p_end){/*** Routine: get_list**** Function: This routine runs through a comma-separated CLI list** and copies the strings to the argv buffer. The** specified separation character is used to separate** the strings in the argv buffer.**** All unquoted strings are converted to lower-case.**** Formal parameters:**** qual - Address of descriptor for the qualifier name** rawtail - Address of descriptor for the full command line tail** delim - Character to use to separate the list items** p_str - Address of pointer pointing to output buffer (argv strings)** p_size - Address of number containing allocated size for output string** p_end - Address of number containing used length in output buf***/ register unsigned long status; struct dsc$descriptor_d work_str; init_dyndesc(work_str); status = cli$present(qual); if (status & 1) { unsigned long len, old_len; long ind, sind; int keep_case; char *src, *dst; int x; /* ** Just in case the string doesn't exist yet, though it does. */ if (*p_str == NULL) { *p_size = ARGBSIZE_UNIT; if ((*p_str = (char *) malloc(*p_size)) == NULL) return (SS$_INSFMEM); len = 0; } else { len = *p_end; } while ((status = cli$get_value(qual, &work_str)) & 1) { old_len = len; len += work_str.dsc$w_length + 1; CHECK_BUFFER_ALLOCATION(*p_str, *p_size, len) /* ** Look for the filename in the original foreign command ** line to see if it was originally quoted. If so, then ** don't convert it to lowercase. */ keep_case = FALSE; str$find_first_substring(rawtail, &ind, &sind, &work_str); if ((ind > 1 && *(rawtail->dsc$a_pointer + ind - 2) == '"') || (ind == 0)) keep_case = TRUE; /* ** Copy the string to the buffer, converting to lowercase. */ src = work_str.dsc$a_pointer; dst = *p_str+old_len; for (x = 0; x < work_str.dsc$w_length; x++) { if (!keep_case && ((*src >= 'A') && (*src <= 'Z'))) *dst++ = *src++ + 32; else *dst++ = *src++; } if (status == CLI$_COMMA) (*p_str)[len-1] = (char)delim; else (*p_str)[len-1] = '\0'; } *p_end = len; } return (SS$_NORMAL);}static unsigned longcheck_cli (struct dsc$descriptor_s *qual){/*** Routine: check_cli**** Function: Check to see if a CLD was used to invoke the program.**** Formal parameters:**** qual - Address of descriptor for qualifier name to check.***/ lib$establish(lib$sig_to_ret); /* Establish condition handler */ return (cli$present(qual)); /* Just see if something was given */}#ifndef TEST#ifdef SFX#ifdef SFX_EXDIR# define SFXOPT_EXDIR "\n and /DIRECTORY=exdir-spec"#else# define SFXOPT_EXDIR ""#endif#ifdef MORE# define SFXOPT1 "/PAGE, "#else# define SFXOPT1 ""#endifint VMSCLI_usage(__GPRO__ int error) /* returns PK-type error code */{ extern ZCONST char UnzipSFXBanner[];#ifdef BETA extern ZCONST char BetaVersion[];#endif int flag; if (!show_VMSCLI_usage) return usage(__G__ error); flag = (error? 1 : 0); Info(slide, flag, ((char *)slide, UnzipSFXBanner, UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL, UZ_VERSION_DATE)); Info(slide, flag, ((char *)slide, "\Valid main options are /TEST, /FRESHEN, /UPDATE, /PIPE, /SCREEN, /COMMENT%s.\n", SFXOPT_EXDIR)); Info(slide, flag, ((char *)slide, "\Modifying options are /TEXT, /BINARY, /JUNK, /[NO]OVERWRITE, /QUIET,\n\ /CASE_INSENSITIVE, /LOWERCASE, %s/VERSION, /RESTORE.\n", SFXOPT1));#ifdef BETA Info(slide, flag, ((char *)slide, BetaVersion, "\n", "SFX"));#endif if (error) return PK_PARAM; else return PK_COOL; /* just wanted usage screen: no error */} /* end function VMSCLI_usage() */#else /* !SFX */int VMSCLI_usage(__GPRO__ int error) /* returns PK-type error code */{ extern ZCONST char UnzipUsageLine1[];#ifdef BETA extern ZCONST char BetaVersion[];#endif int flag; if (!show_VMSCLI_usage) return usage(__G__ error);/*--------------------------------------------------------------------------- If user requested usage, send it to stdout; else send to stderr. ---------------------------------------------------------------------------*/ flag = (error? 1 : 0);/*--------------------------------------------------------------------------- Print either ZipInfo usage or UnZip usage, depending on incantation. ---------------------------------------------------------------------------*/ if (uO.zipinfo_mode) {#ifndef NO_ZIPINFO Info(slide, flag, ((char *)slide, "\ZipInfo %d.%d%d%s %s, by Newtware and the fine folks at Info-ZIP.\n\n\List name, date/time, attribute, size, compression method, etc., about files\n\in list (excluding those in xlist) contained in the specified .zip archive(s).\\n\"file[.zip]\" may be a wildcard name containing * or %% (e.g., \"*font-%%\.zip\").\n", ZI_MAJORVER, ZI_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL, UZ_VERSION_DATE)); Info(slide, flag, ((char *)slide, "\ usage: zipinfo file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options\n\ or: unzip /ZIPINFO file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options\\n\nmain\ listing-format options: /SHORT short \"ls -l\" format (def.)\n\ /ONE_LINE just filenames, one/line /MEDIUM medium Unix \"ls -l\" format\n\ /VERBOSE verbose, multi-page format /LONG long Unix \"ls -l\" format\n\")); Info(slide, flag, ((char *)slide, "\miscellaneous options:\n \/HEADER print header line /TOTALS totals for listed files or for all\n\ /COMMENT print zipfile comment /TIMES times in sortable decimal format\n\ /[NO]CASE_INSENSITIVE match filenames case-insensitively\n\ /[NO]PAGE page output through built-in \"more\"\n\ /EXCLUDE=(file-spec1,etc.) exclude file-specs from listing\n")); Info(slide, flag, ((char *)slide, "\n\Type unzip \"-Z\" for Unix style flags\n\Remember that non-lowercase filespecs must be\ quoted in VMS (e.g., \"Makefile\").\n"));#endif /* !NO_ZIPINFO */ } else { /* UnZip mode */ Info(slide, flag, ((char *)slide, UnzipUsageLine1, UZ_MAJORVER, UZ_MINORVER, UZ_PATCHLEVEL, UZ_BETALEVEL, UZ_VERSION_DATE));#ifdef BETA Info(slide, flag, ((char *)slide, BetaVersion, "", ""));#endif Info(slide, flag, ((char *)slide, "\Usage: unzip file[.zip] [list] [/EXCL=(xlist)] [/DIR=exdir] /options /modifiers\\n Default action is to extract files in list, except those in xlist, to exdir\;\n file[.zip] may be a wildcard. %s\n\n",#ifdef NO_ZIPINFO "(ZipInfo mode is disabled in this version.)"#else "Type \"unzip /ZIPINFO\" for ZipInfo-mode usage."#endif )); Info(slide, flag, ((char *)slide, "\Major options include (type unzip -h for Unix style flags):\n\ /[NO]TEST, /LIST, /[NO]SCREEN, /PIPE, /[NO]FRESHEN, /[NO]UPDATE,\n\ /[NO]COMMENT, /DIRECTORY=directory-spec, /EXCLUDE=(file-spec1,etc.)\n\n\Modifiers include:\n\ /BRIEF, /FULL, /[NO]TEXT[=NONE|AUTO|ALL], /[NO]BINARY[=NONE|AUTO|ALL],\n\ /[NO]OVERWRITE, /[NO]JUNK, /QUIET, /QUIET[=SUPER], /[NO]PAGE,\n\ /[NO]CASE_INSENSITIVE, /[NO]LOWERCASE, /[NO]VERSION, /[NO]RESTORE\n\n")); Info(slide, flag, ((char *)slide, "\Examples (see unzip.txt or \"HELP UNZIP\" for more info):\n \unzip edit1 /EXCL=joe.jou /CASE_INSENSITIVE => extract all files except\n \ joe.jou (or JOE.JOU, or any combination of case) from zipfile edit1.zip\n \unzip zip201 \"Makefile.VMS\" vms/*.[ch] => extract VMS Makefile and\n\ *.c and *.h files; must quote uppercase names if /CASE_INSENS not used\n\ unzip foo /DIR=tmp:[.test] /JUNK /TEXT /OVER => extract all files to temp.\\n directory without paths, auto-converting text files and overwriting\\n")); } /* end if (zipinfo_mode) */ if (error) return PK_PARAM; else return PK_COOL; /* just wanted usage screen: no error */} /* end function VMSCLI_usage() */#endif /* ?SFX */#endif /* !TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -