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

📄 pax.c

📁 这是一个同样来自贝尔实验室的和UNIX有着渊源的操作系统, 其简洁的设计和实现易于我们学习和理解
💻 C
字号:
/* $Source: /u/mark/src/pax/RCS/pax.c,v $ * * $Revision: 1.2 $ * * DESCRIPTION * *	Pax is the archiver described in IEEE P1003.2.  It is an archiver *	which understands both tar and cpio archives and has a new interface. * * SYNOPSIS * *	pax -[cimopuvy] [-f archive] [-s replstr] [-t device] [pattern...] *	pax -r [-cimopuvy] [-f archive] [-s replstr] [-t device] [pattern...] *	pax -w [-adimuvy] [-b blocking] [-f archive] [-s replstr]...] *	       [-t device][-x format][pathname...] *	pax -r -w [-ilmopuvy][-s replstr][pathname...] directory * * DESCRIPTION * * 	PAX - POSIX conforming tar and cpio archive handler.  This *	program implements POSIX conformant versions of tar, cpio and pax *	archive handlers for UNIX.  These handlers have defined befined *	by the IEEE P1003.2 commitee. * * COMPILATION * *	A number of different compile time configuration options are *	available, please see the Makefile and config.h for more details. * * AUTHOR * *     Mark H. Colburn, NAPS International (mark@jhereg.mn.org) * * * Sponsored by The USENIX Association for public distribution.  * * Copyright (c) 1989 Mark H. Colburn. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice is duplicated in all such  * forms and that any documentation, advertising materials, and other  * materials related to such distribution and use acknowledge that the  * software was developed * by Mark H. Colburn and sponsored by The  * USENIX Association.  * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * $Log:	pax.c,v $ * Revision 1.2  89/02/12  10:05:17  mark * 1.2 release fixes *  * Revision 1.1  88/12/23  18:02:23  mark * Initial revision *  */#ifndef lintstatic char *ident = "$Id: pax.c,v 1.2 89/02/12 10:05:17 mark Exp $";static char *copyright = "Copyright (c) 1989 Mark H. Colburn.\nAll rights reserved.\n";#endif /* ! lint *//* Headers */#define NO_EXTERN#include "pax.h"/* Globally Available Identifiers */char           *ar_file;		/* File containing name of archive */char           *bufend;			/* End of data within archive buffer */char           *bufstart;		/* Archive buffer */char           *bufidx;			/* Archive buffer index */char           *myname;			/* name of executable (argv[0]) */char          **n_argv;			/* Argv used by name routines */int             n_argc;			/* Argc used by name routines */int             archivefd;		/* Archive file descriptor */int             blocking;		/* Size of each block, in records */int             gid;			/* Group ID */int             head_standard;		/* true if archive is POSIX format */int             ar_interface;		/* defines interface we are using */int             ar_format;		/* defines current archve format */int             mask;			/* File creation mask */int             ttyf;			/* For interactive queries */int             uid;			/* User ID */int		names_from_stdin;	/* names for files are from stdin */OFFSET          total;			/* Total number of bytes transferred */short           f_access_time;		/* Reset access times of input files */short           areof;			/* End of input volume reached */short           f_dir_create;		/* Create missing directories */short           f_append;		/* Add named files to end of archive */short           f_create;		/* create a new archive */short           f_extract;		/* Extract named files from archive */short           f_follow_links;		/* follow symbolic links */short           f_interactive;		/* Interactivly extract files */short           f_linksleft;		/* Report on unresolved links */short           f_list;			/* List files on the archive */short           f_modified;		/* Don't restore modification times */short           f_verbose;		/* Turn on verbose mode */short		f_link;			/* link files where possible */short		f_owner;		/* extract files as the user */short		f_pass;			/* pass files between directories */short           f_newer;		/* append files to archive if newer */short		f_disposition;		/* ask for file disposition */short           f_reverse_match;	/* Reverse sense of pattern match */short           f_mtime;		/* Retain file modification time */short           f_unconditional;	/* Copy unconditionally */time_t          now = 0;		/* Current time */uint            arvolume;		/* Volume number */uint            blocksize = BLOCKSIZE;	/* Archive block size */FILE	       *msgfile;		/* message outpu file stdout/stderr */Replstr        *rplhead = (Replstr *)NULL;	/*  head of replstr list */Replstr        *rpltail;		/* pointer to tail of replstr list *//* Function Prototypes */#ifdef __STDC__static void 	usage(void);static OFFSET   pax_optsize(char *);#else /* !__STDC__ */static void 	usage();static OFFSET   pax_optsize();#endif /* __STDC__ *//* main - main routine for handling all archive formats. * * DESCRIPTION * * 	Set up globals and call the proper interface as specified by the user. * * PARAMETERS * *	int argc	- count of user supplied arguments *	char **argv	- user supplied arguments  * * RETURNS * *	Returns an exit code of 0 to the parent process. */#ifdef __STDC__int main(int argc, char **argv)#elseint main(argc, argv)int             argc;char          **argv;#endif{    /* strip the pathname off of the name of the executable */    if ((myname = strrchr(argv[0], '/')) != (char *)NULL) {	myname++;    } else {	myname = argv[0];    }    /* set upt for collecting other command line arguments */    name_init(argc, argv);    /* get all our necessary information */    mask = umask(0);    uid = getuid();    gid = getgid();    now = time((time_t *) 0);    /* open terminal for interactive queries */    ttyf = open_tty();    if (strcmp(myname, "tar")==0) {	do_tar(argc, argv);    } else if (strcmp(myname, "cpio")==0) {	do_cpio(argc, argv);    } else {	do_pax(argc, argv);    }    exit(0);    /* NOTREACHED */}/* do_pax - provide a PAX conformant user interface for archive handling * * DESCRIPTION * *	Process the command line parameters given, doing some minimal sanity *	checking, and then launch the specified archiving functions. * * PARAMETERS * *    int ac		- A count of arguments in av.  Should be passed argc  *			  from main *    char **av		- A pointer to an argument list.  Should be passed  *			  argv from main * * RETURNS * *    Normally returns 0.  If an error occurs, -1 is returned  *    and state is set to reflect the error. * */#ifdef __STDC__int do_pax(int ac, char **av)#elseint do_pax(ac, av)int             ac;		/* argument counter */char          **av;		/* arguments */#endif{    int             c;    char	   *dirname;    Stat	    st;    /* default input/output file for PAX is STDIN/STDOUT */    ar_file = "-";    /*     * set up the flags to reflect the default pax inteface.  Unfortunately     * the pax interface has several options which are completely opposite     * of the tar and/or cpio interfaces...     */    f_unconditional = 1;    f_mtime = 1;    f_dir_create = 1;    f_list = 1;    blocksize = 0;    blocking = 0;    ar_interface = PAX;    ar_format = TAR;	/* default interface if none given for -w */    msgfile=stdout;    while ((c = getopt(ac, av, "ab:cdf:ilmoprs:t:uvwx:y")) != EOF) {	switch (c) {	case 'a':	    f_append = 1;	    f_list = 0;	    break;	case 'b':	    if ((blocksize = pax_optsize(optarg)) == 0) {		fatal("Bad block size");	    }	    break;	case 'c':	    f_reverse_match = 1;	    break;	case 'd':	    f_dir_create = 0;	    break;	case 'f':	    if (blocksize == 0) {		blocking = 1;		blocksize = 1 * BLOCKSIZE;	    }	    ar_file = optarg;	    break;	case 'i':	    f_interactive = 1;	    break;	case 'l':	    f_link = 1;	    break;	case 'm':	    f_mtime = 0;	    break;	case 'o':	    f_owner = 1;	    break;	case 'p':	    f_access_time = 1;	    break;	case 'r':	    if (f_create) {		f_create = 0;		f_pass = 1;	    } else {		f_list = 0;		f_extract = 1;	    } 	    msgfile=stderr;	    break;	case 's':	    add_replstr(optarg);	    break;	case 't':	    if (blocksize == 0) {		blocking = 1;		blocksize = 10 * BLOCKSIZE;	    }	    ar_file = optarg;	    break;	case 'u':	    f_unconditional = 1;	    break;	case 'v':	    f_verbose = 1;	    break;	case 'w':	    if (f_extract) {		f_extract = 0;		f_pass = 1;	    } else {		f_list = 0;		f_create = 1;	    } 	    msgfile=stderr;	    break;	case 'x':	    if (strcmp(optarg, "ustar") == 0) {		ar_format = TAR;	    } else if (strcmp(optarg, "cpio") == 0) {		ar_format = CPIO;	    } else {		usage();	    }	    break;	case 'y':	    f_disposition = 1;	    break;	default:	    usage();	}    }    if (blocksize == 0) {	blocking = 1;	blocksize = blocking * BLOCKSIZE;    }    buf_allocate((OFFSET) blocksize);    if (f_extract || f_list) {	open_archive(AR_READ);	get_archive_type();	read_archive();    } else if (f_create) {	if (optind >= n_argc) {	    names_from_stdin++;		/* args from stdin */	}	open_archive(AR_WRITE);	create_archive();    } else if (f_append) {	open_archive(AR_APPEND);	get_archive_type();	append_archive();    } else if (f_pass && optind < n_argc) {	dirname = n_argv[--n_argc];	if (LSTAT(dirname, &st) < 0) {	    fatal(strerror());	}	if ((st.sb_mode & S_IFMT) != S_IFDIR) {	    fatal("Not a directory");	}	if (optind >= n_argc) {	    names_from_stdin++;		/* args from stdin */	}	pass(dirname);    } else {	usage();    }    return (0);}/* get_archive_type - determine input archive type from archive header * * DESCRIPTION * * 	reads the first block of the archive and determines the archive  *	type from the data.  If the archive type cannot be determined,  *	processing stops, and a 1 is returned to the caller.  If verbose *	mode is on, then the archive type will be printed on the standard *	error device as it is determined. * * FIXME  * *	be able to understand TAR and CPIO magic numbers */#ifdef __STDC__void get_archive_type(void)#elsevoid get_archive_type()#endif{    if (ar_read() != 0) {	fatal("Unable to determine archive type.");    }    if (strncmp(bufstart, "070707", 6) == 0) {	ar_format = CPIO;	if (f_verbose) {	    fputs("CPIO format archive\n", stderr);	}    } else if (strncmp(&bufstart[257], "ustar", 5) == 0) {	ar_format = TAR;	if (f_verbose) {	    fputs("USTAR format archive\n", stderr);	}    } else {	ar_format = TAR;    }}/* pax_optsize - interpret a size argument * * DESCRIPTION * * 	Recognizes suffixes for blocks (512-bytes), k-bytes and megabytes.   * 	Also handles simple expressions containing '+' for addition. * * PARAMETERS * *    char 	*str	- A pointer to the string to interpret * * RETURNS * *    Normally returns the value represented by the expression in the  *    the string. * * ERRORS * *	If the string cannot be interpretted, the program will fail, since *	the buffering will be incorrect. * */#ifdef __STDC__static OFFSET pax_optsize(char *str)#elsestatic OFFSET pax_optsize(str)char           *str;		/* pointer to string to interpret */#endif{    char           *idx;    OFFSET          number;	/* temporary storage for current number */    OFFSET          result;	/* cumulative total to be returned to caller */    result = 0;    idx = str;    for (;;) {	number = 0;	while (*idx >= '0' && *idx <= '9')	    number = number * 10 + *idx++ - '0';	switch (*idx++) {	case 'b':	    result += number * 512L;	    continue;	case 'k':	    result += number * 1024L;	    continue;	case 'm':	    result += number * 1024L * 1024L;	    continue;	case '+':	    result += number;	    continue;	case '\0':	    result += number;	    break;	default:	    break;	}	break;    }    if (*--idx) {	fatal("Unrecognizable value");    }    return (result);}/* usage - print a helpful message and exit * * DESCRIPTION * *	Usage prints out the usage message for the PAX interface and then *	exits with a non-zero termination status.  This is used when a user *	has provided non-existant or incompatible command line arguments. * * RETURNS * *	Returns an exit status of 1 to the parent process. * */#ifdef __STDC__static void usage(void)#elsestatic void usage()#endif{    fprintf(stderr, "Usage: %s -[cimopuvy] [-f archive] [-s replstr] [-t device] [pattern...]\n",	myname);    fprintf(stderr, "       %s -r [-cimopuvy] [-f archive] [-s replstr] [-t device] [pattern...]\n",	myname);    fprintf(stderr, "       %s -w [-adimuvy] [-b blocking] [-f archive] [-s replstr]\n              [-t device] [-x format] [pathname...]\n",	myname);    fprintf(stderr, "       %s -r -w [-ilmopuvy] [-s replstr] [pathname...] directory\n",	myname);    exit(1);}

⌨️ 快捷键说明

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