📄 cmdline.c
字号:
*ptr++ = 'q'; /* ** Suppress creation of any extra field. */ status = cli$present(&cli_extra_fields); if (!(status & 1)) *ptr++ = 'X'; /* ** Save the VMS file attributes. */ status = cli$present(&cli_vms); if (status & 1) *ptr++ = 'V'; /* ** Keep the VMS version number as part of the file name when stored. */ status = cli$present(&cli_keep_version); if (status & 1) *ptr++ = 'w'; /* ** `Batch' processing: read filenames to archive from stdin ** or the specified file. */ status = cli$present(&cli_batch); if (status & 1) { status = cli$get_value(&cli_batch, &work_str); if (status & 1) { work_str.dsc$a_pointer[work_str.dsc$w_length] = '\0'; if ((stdin = freopen(work_str.dsc$a_pointer, "r", stdin)) == NULL) { sprintf(errbuf, "could not open list file: %s", work_str.dsc$a_pointer); ziperr(ZE_PARMS, errbuf); } } *ptr++ = '@'; } /* ** 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); } /* ** ** OK. We've done all the regular options, so check for -b (temporary ** file path), -t (exclude before time), -n (special suffixes), zipfile, ** files to zip, and exclude list. ** */ status = cli$present(&cli_temp_path); if (status & 1) { status = cli$get_value(&cli_temp_path, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-b"); strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Handle "-t mmddyyyy". */ status = cli$present(&cli_since); if (status & 1) { char since_time[9]; status = get_time(&cli_since, &since_time[0]); if (!(status & 1)) return (status); /* ** Now let's add the option "-t mmddyyyy" to the new command line. */ x = cmdl_len; cmdl_len += (3 + 9); CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-t"); strcpy(&the_cmd_line[x+3], since_time); } /* ** Handle "-tt mmddyyyy". */ status = cli$present(&cli_before); if (status & 1) { char before_time[9]; status = get_time(&cli_before, &before_time[0]); if (!(status & 1)) return (status); /* ** Now let's add the option "-tt mmddyyyy" to the new command line. */ x = cmdl_len; cmdl_len += (4 + 9); CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-tt"); strcpy(&the_cmd_line[x+4], before_time); } /* ** Handle "-n suffix:suffix:...". (File types to store only.) */ status = cli$present(&cli_store_types); if (status & 1) { x = cmdl_len; cmdl_len += 3; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-n"); status = get_list(&cli_store_types, &foreign_cmdline, ':', &the_cmd_line, &cmdl_size, &cmdl_len); if (!(status & 1)) return (status); } /* ** 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'; } /* ** Run through the list of input files. */ 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); } /* ** List file containing exclude patterns present? ("-x@exclude.lst") */ status = cli$present(&cli_exlist); if (status & 1) { status = cli$get_value(&cli_exlist, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strncpy(&the_cmd_line[x], "-x@", 3); strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Any files to exclude? ("-x file file") */ status = cli$present(&cli_exclude); if (status & 1) { 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); } /* ** List file containing include patterns present? ("-x@exclude.lst") */ status = cli$present(&cli_inlist); if (status & 1) { status = cli$get_value(&cli_inlist, &work_str); x = cmdl_len; cmdl_len += work_str.dsc$w_length + 4; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strncpy(&the_cmd_line[x], "-i@", 3); strncpy(&the_cmd_line[x+3], work_str.dsc$a_pointer, work_str.dsc$w_length); the_cmd_line[cmdl_len-1] = '\0'; } /* ** Any files to include? ("-i file file") */ status = cli$present(&cli_include); if (status & 1) { x = cmdl_len; cmdl_len += 3; CHECK_BUFFER_ALLOCATION(the_cmd_line, cmdl_size, cmdl_len) strcpy(&the_cmd_line[x], "-i"); 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 longget_time (struct dsc$descriptor_s *qual, char *timearg){/*** Routine: get_time**** Function: This routine reads the argument string of the qualifier** "qual" that should be a VMS syntax date-time string. The** date-time string is converted into the standard format** "mmddyyyy", specifying an absolute date. The converted** string is written into the 9 bytes wide buffer "timearg".**** Formal parameters:**** qual - Address of descriptor for the qualifier name** timearg - Address of a buffer carrying the 8-char time string returned***/ register unsigned long status; struct dsc$descriptor_d time_str; struct quadword { long high; long low; } bintimbuf = {0,0};#ifdef __DECC#pragma member_alignment save#pragma nomember_alignment#endif /* __DECC */ struct tim { short year; short month; short day; short hour; short minute; short second; short hundred; } numtimbuf;#ifdef __DECC#pragma member_alignment restore#endif init_dyndesc(time_str); status = cli$get_value(qual, &time_str); /* ** If a date is given, convert it to 64-bit binary. */ if (time_str.dsc$w_length) { status = sys$bintim(&time_str, &bintimbuf); if (!(status & 1)) return (status); str$free1_dx(&time_str); } /* ** Now call $NUMTIM to get the month, day, and year. */ status = sys$numtim(&numtimbuf, (bintimbuf.low ? &bintimbuf : NULL)); /* ** Write the "mmddyyyy" string to the return buffer. */ if (!(status & 1)) { *timearg = '\0'; } else { sprintf(timearg, "%02d%02d%04d", numtimbuf.month, numtimbuf.day, numtimbuf.year); } return (status);}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 TESTvoid VMSCLI_help(void) /* VMSCLI version *//* Print help (along with license info) to stdout. */{ extent i; /* counter for help array */ /* help array */ static char *text[] = {"Zip %s (%s). Usage: zip==\"$disk:[dir]zip.exe\"","zip zipfile[.zip] [list] [/EXCL=(xlist)] /options /modifiers"," The default action is to add or replace zipfile entries from list, except"," those in xlist. The include file list may contain the special name - to"," compress standard input. If both zipfile and list are omitted, zip"," compresses stdin to stdout."," Type zip -h for Unix style flags."," Major options include:"," /FRESHEN, /UPDATE, /DELETE, /[NO]MOVE, /COMMENTS[={ZIP_FILE|FILES}],"," /LATEST, /TEST, /ADJUST_OFFSETS, /FIX_ARCHIVE[=FULL], /UNSFX"," Modifiers include:"," /EXCLUDE=(file list), /INCLUDE=(file list), /SINCE=\"creation time\",",#if CRYPT"\ /QUIET,/VERBOSE[=MORE],/[NO]RECURSE,/[NO]DIRNAMES,/JUNK,/ENCRYPT[=\"pwd\"],\",#else /* !CRYPT */" /QUIET, /VERBOSE[=MORE], /[NO]RECURSE, /[NO]DIRNAMES, /JUNK,",#endif /* ?CRYPT */" /[NO]KEEP_VERSION, /[NO]VMS, /[NO]PKZIP, /TRANSLATE_EOL[={LF|CRLF}],"," /[NO]EXTRA_FIELDS /LEVEL=[0-9], /TEMP_PATH=directory, /BATCH[=list file]" }; if (!show_VMSCLI_help) { help(); return; } for (i = 0; i < sizeof(copyright)/sizeof(char *); i++) { printf(copyright[i], "zip"); putchar('\n'); } for (i = 0; i < sizeof(text)/sizeof(char *); i++) { printf(text[i], VERSION, REVDATE); putchar('\n'); }} /* end function VMSCLI_help() */#endif /* !TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -