⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 unshar.c

📁 操作系统源代码
💻 C
字号:
/* unshar - extract files from a shell archive	Author: Warren Toomey *//* Copyright 1989 by Warren Toomey	wkt@cs.adfa.oz.au[@uunet.uu.net] * * You may freely copy or distribute this code as long as this notice * remains intact. * * You may modify this code, as long as this notice remains intact, and * you add another notice indicating that the code has been modified. * * You may NOT sell this code or in any way profit from this code without * prior agreement from the author. * * Modified by Andy Tanenbaum, Nov. 1992 * Modified by Bruce Evans, Jan. 1993 */#include <stdlib.h>#include <string.h>#include <stdio.h>/* Methods of unsharing */#define UNKNOWN	0#define BRUTAL	1/* Whitespace indicators */#define WHITE	0#define NOWHITE 1/* Leading character indicators */#define NOX	0#define YESX	1/* Misc. constants */#define BUFSIZE	512		/* Size of line buffer *//* Emulation types available */#define NUMTOKS    4		/* NUMTOKS must equal # of emulation types */#define SED	   1#define GRES 	   2#define CAT	   3/* The list of emulation types. */static char *token[NUMTOKS] = {"", "sed", "gres", "cat"};/* Global variables */int table;			/* Generate a table, or extract */int numext;			/* Number of files to extract */unsigned long nulchars;		/* # Nuls discarded from input */unsigned long overrunchars;	/* # Chars overruning line buffers */char *exfile[100];		/* Files to extract */extern char *optarg;_PROTOTYPE(int main, (int argc, char **argv));_PROTOTYPE(int fgetline, (FILE * zin, int how, char *buf, size_t max));_PROTOTYPE(char *getstring, (char *buf));_PROTOTYPE(int firstword, (char *buf));_PROTOTYPE(int mustget, (char *s1));_PROTOTYPE(void extract, (int how, char *file, char *end, char *lead));_PROTOTYPE(void getnames, (char *buf, char *file, char *word));_PROTOTYPE(void disembowel, (void));_PROTOTYPE(void usage, (void));int main(argc, argv)int argc;char *argv[];{  int i, c, first;  int method;			/* Method of unsharing */  method = BRUTAL;		/* Only BRUTAL currently available */  table = 0;			/* Don't generate a table */  numext = 0;			/* Initially no files to extract */  while ((c = getopt(argc, argv, "x:tbv")) != EOF) switch (c) {	    case 't':		table = 1;	/* Get the various options */		break;	    case 'b':	method = BRUTAL;	break;	    case 'x':		exfile[numext] = (char *) malloc(strlen(optarg) + 1);		strcpy(exfile[numext++], optarg);		break;	    default:	usage();	}  if (argc == 1) {	first = argc;		/* Find first file argument */  } else {	for (first = 1; first < argc; first++)		if (argv[first][0] != '-') break;  }  if (first == argc) {		/* If no file argument use stdin only */	switch (method) {	    case BRUTAL:		disembowel();	/* Unshar brutally! */		break;	    default:		fprintf(stderr, "unshar: Unknown method of unsharing\n");		exit(1);	}  } else {	for (i = first; i < argc; i++) {	/* open stdio with every						 * file */		if (table) printf("%s:\n", argv[i]);		if (freopen(argv[i], "r", stdin) != stdin) {			perror("unshar");			exit(1);		}		switch (method) {		    case BRUTAL:			disembowel();	/* Unshar brutally! */			break;		    default:			fprintf(stderr,"unshar: Unknown method of unsharing\n");			exit(1);		}	}  }  return(0);}int fgetline(zin, how, buf, max)FILE *zin;int how;			/* Ignore leading whitespace if how=NOWHITE */char *buf;size_t max;			/* Buffer size, must be >= 2 */{/* Get a line from a file */  int ch = 0;  char *limit = buf + max - 1;  *buf = 0;			/* Null the buffer */  if (how == NOWHITE) {		/* If skip any whitespace */	while (((ch = getc(zin)) == ' ') || (ch == '\t'));	if (ch == EOF) return(EOF);	/* Returning EOF or 0 */	if (ch == '\n') return (0);	*buf++ = ch;		/* Put char in buffer */  }  while ((ch = getc(zin)) != '\n') {	/* Now get the line */	if (ch == EOF) {		*buf = 0;		return(EOF);	}	if (ch == 0) {		nulchars++;		continue;	}	if (buf == limit)		overrunchars++;	else		*buf++ = ch;  }  *buf = 0;			/* Finally null-terminate the buffer */  return(0);			/* and return */}char *getstring(buf)char *buf;{/* Get the next string from the buffer ignoring any quotes. */  char out[BUFSIZE];  char *temp = out;  char inquotes = 0, ok = 1;  while ((*buf == ' ') || (*buf == '\t'))	buf++;			/* Skip whitespace */  *temp = 0;  while (ok) {			/* Parse line */	switch (*buf) {	    case '\"':	    case '\'':		buf++;		inquotes = !inquotes;	/* Toggle inquotes */		break;	    case 0:	    case '\n':		/* Stop on <, >, NULL */	    case '>':		/* \n, and sometimes */	    case '<':	ok = 0;	break;	/* space & tab */	    case '\t':	    case ' ':		if (!inquotes) ok = 0;	    case '\\':		if (!inquotes) {/* Ignore backquotes */			buf++;			break;		}	    default:		*temp++ = *buf++;	/* Copy chars :-) */	}  }  *temp = 0;  return(out);}int firstword(buf)char *buf;{/* Return token value of the first word in the buffer.  Assume no leading * white space in the buffer. */  int i;  for (i = 1; i < NUMTOKS; i++)	if (strncmp(buf, token[i], strlen(token[i])) == 0) return(i);  return(UNKNOWN);}int mustget(s1)char *s1;{/* Return 1 if s1 is in he list of files to extract.  Else return 0. */  int i;  if (numext == 0) return(0);  for (i = 0; i < numext; i++)	if (!strcmp(s1, exfile[i])) return(1);  return(0);}void extract(how, file, end, lead)int how;		/* If how==YESX, ignore 1st char on each line */char *file;char *end;char *lead;{/* Extract file, up until end word */  FILE *zout;  char line[BUFSIZE];  char *temp;  int ch, match;  size_t n;  n = strlen(lead);  zout = fopen(file, "w");	/* Open output file */  if (zout == NULL) {	perror("unshar");	return;  }  while (1) {	ch = fgetline(stdin, WHITE, line, sizeof line);	temp = line;	if (ch == EOF) {		fprintf(zout, "%s\n", line);		fclose(zout);		return;	}	if (strcmp(temp, end) == 0) {	/* If end word */		fclose(zout);	/* close the file */		return;	}	match = strncmp(temp, lead, n);	if ((how == YESX) && (match == 0))		temp += n;	/* Skip any lead */	fprintf(zout, "%s\n", temp);  }}void getnames(buf, file, word)	/* Get the file & end word */char *buf, *file, *word;	/* from the buffer */{  char *temp;  temp = buf;  while (*temp != 0) {		/* Scan along buffer */	switch (*temp) {	/* Get file or end word */	    case '>':		strcpy(file, getstring(++temp));	/* Get the file name */		break;	    case '<':		if (*(++temp) == '<') ++temp;	/* Skip 2nd < */		strcpy(word, getstring(temp));	/* Get next word */		break;	    default:	temp++;	}  }}void disembowel(){				/* Unshar brutally! */  char buf[BUFSIZE];		/* Line buffer */  char file[BUFSIZE];		/* File name */  char word[BUFSIZE];		/* Word buffer */  char lead_string[BUFSIZE];	/* lead string */  char *p, *p1;  int ch;  overrunchars = nulchars = 0;  while (1) {	ch = fgetline(stdin, NOWHITE, buf, sizeof buf);	if (ch == EOF) {		if (nulchars + overrunchars != 0) fprintf(stderr,				"unshar: Discarded %lu characters from input.  Output may be garbled\n",				nulchars + overrunchars);		return;	}	switch (firstword(buf)) {	/* Extract, depending on first word */	    case CAT:		getnames(buf, file, word);		/* Find the leading string. */		p = buf;		while (*p != '/') p++;		p++;		if (*p == '^') p++;	/* ^ has no width */		p1 = p;		while (*p1 != '/') p1++;		strncpy(lead_string, p, (size_t) (p1 - p));		if (table == 0) {			if ((numext == 0) || (mustget(file))) {				printf("unshar: Extracting  %s\n", file);				extract(NOX, file, word, lead_string);			}		} else {			printf("  %s\n", file);		}		break;	    case GRES:	    case SED:		getnames(buf, file, word);		/* Find the leading string. */		p = buf;		while (*p != '/') p++;		p++;		if (*p == '^') p++;	/* ^ has no width */		p1 = p;		while (*p1 != '/') p1++;		strncpy(lead_string, p, (size_t) (p1 - p));		if (table == 0) {			if ((numext == 0) || (mustget(file))) {				printf("unshar: Extracting  %s\n", file);				extract(YESX, file, word, lead_string);			}		} else {			printf("  %s\n", file);		}		break;	    default:	break;	}  }}void usage(){  fprintf(stderr, "Usage: unshar [-t] [-b] [-v] [-xfile] [file(s)]\n");  exit(0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -