示例#1
0
文件: hha.c 项目: maksverver/hha
int main(int argc, char *argv[])
{
    assert(sizeof(Header)     == 16);
    assert(sizeof(IndexEntry) == 24);

    parse_args(argc, argv);

    switch (arg_mode)
    {
    case LIST:
        open_archive(arg_archive);
        process_header();
        list_entries();
        close_archive();
        break;

    case EXTRACT:
        open_archive(arg_archive);
        process_header();
        extract_entries();
        close_archive();
        break;

    case CREATE:
        create_archive(arg_archive, (const char**)arg_files_begin,
                                    (const char**)arg_files_end, arg_com);
        break;
    }

    return 0;
}
示例#2
0
int open_archive(char *name, int mode)
{
  unsigned short magic = 0;
  int fd;

  if (mode == CREATE) {
	if ((fd = creat(name, 0666)) < 0)
		error2(TRUE, "cannot creat %s\n", name);
	magic = MAGIC_NUMBER;
	wr_int2(fd, magic);
	return fd;
  }

  if ((fd = open(name, mode)) < 0) {
	if (mode == APPEND) {
		close(open_archive(name, CREATE));
		if (!nocr_fl) error3(FALSE, "%s: creating %s\n", progname, name);
		return open_archive(name, APPEND);
	}
	error2(TRUE, "cannot open %s\n", name);
  }
  lseek(fd, 0L, 0);
  magic = rd_unsigned2(fd);
  if (magic != AALMAG && magic != ARMAG)
	error2(TRUE, "%s is not in ar format\n", name);
  
  return fd;
}
示例#3
0
文件: gsf.c 项目: arcean/libgsf
static int
gsf_list (int argc, char **argv)
{
	int i;

	for (i = 0; i < argc; i++) {
		char const *filename = argv[i];
		char *display_name;
		GsfInfile *infile = open_archive (filename);
		if (!infile)
			return 1;

		if (i > 0)
			g_print ("\n");

		display_name = g_filename_display_name (filename);
		g_print ("%s:\n", display_name);
		g_free (display_name);

		ls_R (GSF_INPUT (infile), NULL);
		g_object_unref (infile);
	}

	return 0;
}
示例#4
0
文件: gsf.c 项目: arcean/libgsf
static int
gsf_list_props (int argc, char **argv)
{
	GsfInfile *infile;
	GsfDocMetaData *meta_data;
	char const *filename;
	GSList *names = NULL;

	if (argc != 1)
		return 1;

	filename = argv[0];
	infile = open_archive (filename);
	if (!infile)
		return 1;

	meta_data = get_meta_data (infile, filename);
	gsf_doc_meta_data_foreach (meta_data, cb_collect_names, &names);
	names = g_slist_sort (names, (GCompareFunc)strcmp);
	g_slist_foreach (names, (GFunc)cb_print_names, NULL);
	g_slist_free (names);

	g_object_unref (meta_data);
	g_object_unref (infile);
	return 0;
}
示例#5
0
void archive_impl::open(service_ptr_t<file> & p_out,const char * path,t_open_mode mode, abort_callback & p_abort)
{
	if (mode != open_mode_read) throw exception_io_denied();
	pfc::string8 archive,file;
	if (!g_parse_unpack_path(path,archive,file)) throw exception_io_not_found();
	open_archive(p_out,archive,file,p_abort);
}
示例#6
0
文件: zip.c 项目: ccxvii/mio
void register_archive(const char *zipname)
{
	struct archive *zip = open_archive(zipname);
	if (zip) {
		zip->next = zip_head;
		zip_head = zip;
	}
}
示例#7
0
// opens the various archive files.  Guarantees that the timestamp
// does not equal the previous timestamp
//
void open_all_archives() {
    int old_time=time_int;
    
    // make sure we get a NEW value of the file timestamp!
    //
    while (old_time == (time_int = (int)time(0))) {
        sleep(1);
    }
    
    // open all the archives.
    open_archive(WU_FILENAME_PREFIX, wu_stream);
    open_archive(RESULT_FILENAME_PREFIX, re_stream);
    open_archive(RESULT_INDEX_FILENAME_PREFIX, re_index_stream);
    open_archive(WU_INDEX_FILENAME_PREFIX, wu_index_stream);
    fprintf(wu_stream, "<archive>\n");
    fprintf(re_stream, "<archive>\n");

    return;
}
示例#8
0
文件: build.c 项目: UNGLinux/Obase
int
build(void)
{
	CF cf;
	int afd, tfd;
	int current_mid;
	off_t size;

	current_mid = -1;
	afd = open_archive(O_RDWR);
	fp = fdopen(afd, "r+");
	tfd = tmp();

	SETCF(afd, archive, tfd, tname, RPAD|WPAD);

	/* Read through the archive, creating list of symbols. */
	symcnt = tsymlen = 0;
	pnext = &rhead;
	while(get_arobj(afd)) {
		int new_mid;

		if (!strcmp(chdr.name, RANLIBMAG)) {
			skip_arobj(afd);
			continue;
		}
		new_mid = rexec(afd, tfd);
		if (new_mid != -1) {
			if (current_mid == -1)
				current_mid = new_mid;
			else if (new_mid != current_mid)
				errx(1, "Mixed object format archive: %d / %d", 
					new_mid, current_mid);
		}
		put_arobj(&cf, (struct stat *)NULL);
	}
	*pnext = NULL;

	/* Create the symbol table.  Endianess the same as last mid seen */
	symobj(current_mid);

	/* Copy the saved objects into the archive. */
	size = lseek(tfd, (off_t)0, SEEK_CUR);
	(void)lseek(tfd, (off_t)0, SEEK_SET);
	SETCF(tfd, tname, afd, archive, NOPAD);
	copy_ar(&cf, size);
	(void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR));
	(void)close(tfd);

	/* Set the time. */
	settime(afd);
	close_archive(afd);
	return(0);
}
示例#9
0
void
create_archive()
{
	register char	*p;

	open_archive(0);		/* Open for writing */

	while (p = name_next()) {
		dump_file(p, -1);
	}

	write_eot();
	close_archive();
	name_close();
}		
示例#10
0
文件: touch.c 项目: aunali1/exopc
int touch()
{
	int afd;

	afd = open_archive(O_RDWR);

	if (!get_arobj(afd) ||
	    strncmp(RANLIBMAG, chdr.name, sizeof(RANLIBMAG) - 1)) {
		(void)fprintf(stderr,
		    "ranlib: %s: no symbol table.\n", archive);
		return(1);
	}
	settime(afd);
	close_archive(afd);
	return(0);
}
示例#11
0
/*
 * append --
 *	Append files to the archive - modifies original archive or creates
 *	a new archive if named archive does not exist.
 */
int
append(char **argv)
{
	struct stat sb;
	CF cf;
	FILE *afp;
	char *file;
	int eval, ntsz;

	afp = open_archive(O_CREAT|O_RDWR);
	if (fseeko(afp, 0, SEEK_END) == (off_t)-1)
		err(1, "lseek: %s", archive);

	/* Read from disk, write to an archive; pad on write. */
	SETCF(0, 0, afp, archive, 0);

	if (options & AR_C) {
		/* ain't no need for a.out but a small price to pay */
		if ((ntsz = mknametab(argv)) == 0)
			;

		/* build and write the symdef, also need a mid! */
		/* mkranlib(argv);
		if (mid & ELF) */ {
			options |= AR_S5;
			/* write out the nametab */
			if (ntsz)
				put_nametab(&cf);
		}
	}

	for (eval = 0; (file = *argv++);) {
		if (!(cf.rfp = fopen(file, "r"))) {
			warn("fopen: %s", file);
			eval = 1;
			continue;
		}
		if (options & AR_V)
			(void)printf("q - %s\n", file);
		cf.rname = file;
		put_arobj(&cf, &sb);
		(void)fclose(cf.rfp);
	}
	close_archive(afp);
	return (eval);
}
示例#12
0
文件: ranlib.c 项目: McIkye/tools
int
touch(void)
{
	FILE *afp;

	afp = open_archive(O_RDWR);

	if (!get_arobj(afp) ||
	    (strncmp(RANLIBMAG, chdr.name, sizeof(RANLIBMAG) - 1) &&
	     strncmp(RANLIBMAG2, chdr.name, sizeof(RANLIBMAG2) - 1))) {
		warnx("%s: no symbol table.", archive);
		return(1);
	}
	settime(afp);
	close_archive(afp);
	return(0);
}
示例#13
0
文件: print.c 项目: McIkye/tools
/*
 * print --
 *	Prints archive members on stdout - if member names given only
 *	print those members, otherwise print all members.
 */
int
print(char **argv)
{
	off_t size;
	CF cf;
	FILE *afp;
	char *file;
	int all;

	afp = open_archive(O_RDONLY);

	/* Read from an archive, write to stdout; pad on read. */
	SETCF(afp, archive, stdout, "stdout", 0);
	for (all = !*argv; get_arobj(afp);) {
		if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
			size = ftello(afp);
			get_namtab(afp);
			(void)fseeko(afp, size, SEEK_SET);
			skip_arobj(afp);
			continue;
		}

		if (all)
			file = chdr.name;
		else if (!(file = files(argv))) {
			skip_arobj(afp);
			continue;
		}
		if (options & AR_V) {
			(void)printf("\n<%s>\n\n", file);
			(void)fflush(stdout);
		}
		copy_ar(&cf, chdr.size);
		if (!all && !*argv)
			break;
	}
	close_archive(afp);

	if (*argv) {
		orphans(argv);
		return (1);
	}
	return (0);
}
示例#14
0
文件: create.c 项目: npe9/sprite
void
create_archive()
{
	register char	*p;
	char *name_from_list();

	open_archive(0);		/* Open for writing */

	if(f_gnudump) {
		char buf[MAXNAMLEN],*q,*bufp;

		collect_and_sort_names();

		while(p=name_from_list())
			dump_file(p,-1);
		/* if(!f_dironly) { */
			blank_name_list();
			while(p=name_from_list()) {
				strcpy(buf,p);
				if(p[strlen(p)-1]!='/')
					strcat(buf,"/");
				bufp=buf+strlen(buf);
				for(q=gnu_list_name->dir_contents;*q;q+=strlen(q)+1) {
					if(*q=='Y') {
						strcpy(bufp,q+1);
						dump_file(buf,-1);
					}
				}
			}
		/* } */

	} else {
		while (p = name_next(1)) {
			dump_file(p, -1);
		}
	}

	write_eot();
	close_archive();
	name_close();
}
示例#15
0
文件: gsf.c 项目: arcean/libgsf
static int
gsf_dump (int argc, char **argv, gboolean hex)
{
	char const *filename;
	GsfInfile *infile;
	int i;
	int res = 0;

	if (argc < 2)
		return 1;

	filename = argv[0];
	infile = open_archive (filename);
	if (!infile)
		return 1;

	for (i = 1; i < argc; i++) {
		char const *name = argv[i];
		GsfInput *member = find_member (infile, name);
		if (!member) {
			char *display_name = g_filename_display_name (name);
			g_print ("%s: archive has no member %s\n",
				 g_get_prgname (), display_name);
			g_free (display_name);
			res = 1;
			break;
		}

		if (hex) {
			char *display_name = g_filename_display_name (name);
			g_print ("%s:\n", display_name);
			g_free (display_name);
		}
		gsf_input_dump (member, hex);
		g_object_unref (member);
	}

	g_object_unref (infile);
	return res;
}
示例#16
0
build()
{
	CF cf;
	int afd, tfd;
	off_t size;

	afd = open_archive(O_RDWR);
	fp = fdopen(afd, "r+");
	tfd = tmp();

	SETCF(afd, archive, tfd, tname, RPAD|WPAD);

	/* Read through the archive, creating list of symbols. */
	pnext = &rhead;
	while(get_arobj(afd)) {
		if (!strcmp(chdr.name, RANLIBMAG)) {
			skip_arobj(afd);
			continue;
		}
		rexec(afd, tfd);
		put_arobj(&cf, (struct stat *)NULL);
	}
	*pnext = NULL;

	/* Create the symbol table. */
	symobj();

	/* Copy the saved objects into the archive. */
	size = lseek(tfd, (off_t)0, SEEK_CUR);
	(void)lseek(tfd, (off_t)0, SEEK_SET);
	SETCF(tfd, tname, afd, archive, RPAD|WPAD);
	copy_ar(&cf, size);
	(void)ftruncate(afd, lseek(afd, (off_t)0, SEEK_CUR));
	(void)close(tfd);

	/* Set the time. */
	settime(afd);
	close_archive(afd);
	return(0);
}
示例#17
0
文件: gsf.c 项目: arcean/libgsf
static int
gsf_dump_props (int argc, char **argv)
{
	GsfInfile *infile;
	GsfDocMetaData *meta_data;
	char const *filename;
	int res = 0;
	int i;

	if (argc < 2)
		return 1;

	filename = argv[0];
	infile = open_archive (filename);
	if (!infile)
		return 1;

	meta_data = get_meta_data (infile, filename);

	for (i = 1; i < argc; i++) {
		const char *name = argv[i];
		GsfDocProp const *prop =
			gsf_doc_meta_data_lookup (meta_data, name);
		if (prop) {
			if (argc > 2)
				g_print ("%s: ", name);
			gsf_doc_prop_dump (prop);
		} else {
			g_printerr (_("No property named %s\n"), name);
		}
	}

	g_object_unref (meta_data);
	g_object_unref (infile);
	return res;
}
示例#18
0
文件: main.c 项目: petabi/pkgsrc
int
main(int argc, char *argv[])
{
    Boolean		 use_default_sfx = TRUE;
    Boolean 	 show_basename_only = FALSE;
    char		 lsdir[MaxPathSize];
    char		 sfx[MaxPathSize];
    char		*lsdirp = NULL;
    int		 ch;

    setprogname(argv[0]);

    if (argc < 2)
        usage();

    while ((ch = getopt(argc, argv, Options)) != -1)
        switch (ch) {
        case 'C':
            config_file = optarg;
            break;

        case 'K':
            pkgdb_set_dir(optarg, 3);
            break;

        case 'S':
            sfx[0] = 0x0;
            use_default_sfx = FALSE;
            break;

        case 'V':
            show_version();
        /* NOTREACHED */

        case 'b':
            show_basename_only = TRUE;
            break;

        case 'd':
            (void) strlcpy(lsdir, optarg, sizeof(lsdir));
            lsdirp = lsdir;
            break;

        case 'q':
            quiet = 1;
            break;

        case 's':
            (void) strlcpy(sfx, optarg, sizeof(sfx));
            use_default_sfx = FALSE;
            break;

        case 'v':
            ++verbose;
            break;

        default:
            usage();
            /* NOTREACHED */
        }

    argc -= optind;
    argv += optind;

    if (argc <= 0) {
        usage();
    }

    /*
     * config-var is reading the config file implicitly,
     * so skip it here.
     */
    if (strcasecmp(argv[0], "config-var") != 0)
        pkg_install_config();

    if (use_default_sfx)
        (void) strlcpy(sfx, DEFAULT_SFX, sizeof(sfx));

    if (strcasecmp(argv[0], "pmatch") == 0) {

        char *pattern, *pkg;

        argv++;		/* "pmatch" */

        if (argv[0] == NULL || argv[1] == NULL) {
            usage();
        }

        pattern = argv[0];
        pkg = argv[1];

        if (pkg_match(pattern, pkg)) {
            return 0;
        } else {
            return 1;
        }

    } else if (strcasecmp(argv[0], "rebuild") == 0) {

        rebuild();
        printf("Done.\n");


    } else if (strcasecmp(argv[0], "rebuild-tree") == 0) {

        rebuild_tree();
        printf("Done.\n");

    } else if (strcasecmp(argv[0], "check") == 0) {
        argv++;		/* "check" */

        check(argv);

        if (!quiet) {
            printf("Done.\n");
        }

    } else if (strcasecmp(argv[0], "lsall") == 0) {
        argv++;		/* "lsall" */

        while (*argv != NULL) {
            /* args specified */
            int     rc;
            const char *basep, *dir;

            dir = lsdirp ? lsdirp : dirname_of(*argv);
            basep = basename_of(*argv);

            if (show_basename_only)
                rc = match_local_files(dir, use_default_sfx, 1, basep, lsbasepattern, NULL);
            else
                rc = match_local_files(dir, use_default_sfx, 1, basep, lspattern, __UNCONST(dir));
            if (rc == -1)
                errx(EXIT_FAILURE, "Error from match_local_files(\"%s\", \"%s\", ...)",
                     dir, basep);

            argv++;
        }

    } else if (strcasecmp(argv[0], "lsbest") == 0) {
        argv++;		/* "lsbest" */

        while (*argv != NULL) {
            /* args specified */
            const char *basep, *dir;
            char *p;

            dir = lsdirp ? lsdirp : dirname_of(*argv);
            basep = basename_of(*argv);

            p = find_best_matching_file(dir, basep, use_default_sfx, 1);

            if (p) {
                if (show_basename_only)
                    printf("%s\n", p);
                else
                    printf("%s/%s\n", dir, p);
                free(p);
            }

            argv++;
        }
    } else if (strcasecmp(argv[0], "list") == 0 ||
               strcasecmp(argv[0], "dump") == 0) {

        pkgdb_dump();

    } else if (strcasecmp(argv[0], "add") == 0) {
        struct pkgdb_count count;

        count.files = 0;
        count.directories = 0;
        count.packages = 0;

        for (++argv; *argv != NULL; ++argv)
            add_pkg(*argv, &count);
    } else if (strcasecmp(argv[0], "set") == 0) {
        argv++;		/* "set" */
        set_unset_variable(argv, FALSE);
    } else if (strcasecmp(argv[0], "unset") == 0) {
        argv++;		/* "unset" */
        set_unset_variable(argv, TRUE);
    } else if (strcasecmp(argv[0], "config-var") == 0) {
        argv++;
        if (argv == NULL || argv[1] != NULL)
            errx(EXIT_FAILURE, "config-var takes exactly one argument");
        pkg_install_show_variable(argv[0]);
    } else if (strcasecmp(argv[0], "check-license") == 0) {
        if (argv[1] == NULL)
            errx(EXIT_FAILURE, "check-license takes exactly one argument");

        load_license_lists();

        switch (acceptable_pkg_license(argv[1])) {
        case 0:
            puts("no");
            return 0;
        case 1:
            puts("yes");
            return 0;
        case -1:
            errx(EXIT_FAILURE, "invalid license condition");
        }
    } else if (strcasecmp(argv[0], "check-single-license") == 0) {
        if (argv[1] == NULL)
            errx(EXIT_FAILURE, "check-license takes exactly one argument");
        load_license_lists();

        switch (acceptable_license(argv[1])) {
        case 0:
            puts("no");
            return 0;
        case 1:
            puts("yes");
            return 0;
        case -1:
            errx(EXIT_FAILURE, "invalid license");
        }
    }
#ifndef BOOTSTRAP
    else if (strcasecmp(argv[0], "findbest") == 0) {
        struct url *url;
        char *output;
        int rc;

        process_pkg_path();

        rc = 0;
        for (++argv; *argv != NULL; ++argv) {
            url = find_best_package(NULL, *argv, 1);
            if (url == NULL) {
                rc = 1;
                continue;
            }
            output = fetchStringifyURL(url);
            puts(output);
            fetchFreeURL(url);
            free(output);
        }

        return rc;
    } else if (strcasecmp(argv[0], "fetch-pkg-vulnerabilities") == 0) {
        fetch_pkg_vulnerabilities(--argc, ++argv);
    } else if (strcasecmp(argv[0], "check-pkg-vulnerabilities") == 0) {
        check_pkg_vulnerabilities(--argc, ++argv);
    } else if (strcasecmp(argv[0], "audit") == 0) {
        audit_pkgdb(--argc, ++argv);
    } else if (strcasecmp(argv[0], "audit-pkg") == 0) {
        audit_pkg(--argc, ++argv);
    } else if (strcasecmp(argv[0], "audit-batch") == 0) {
        audit_batch(--argc, ++argv);
    } else if (strcasecmp(argv[0], "audit-history") == 0) {
        audit_history(--argc, ++argv);
    } else if (strcasecmp(argv[0], "check-signature") == 0) {
        struct archive *pkg;
        int rc;

        rc = 0;
        for (--argc, ++argv; argc > 0; --argc, ++argv) {
            char *archive_name;

            pkg = open_archive(*argv, &archive_name);
            if (pkg == NULL) {
                warnx("%s could not be opened", *argv);
                continue;
            }
            if (pkg_full_signature_check(archive_name, &pkg))
                rc = 1;
            free(archive_name);
            if (!pkg)
                archive_read_finish(pkg);
        }
        return rc;
    } else if (strcasecmp(argv[0], "x509-sign-package") == 0) {
#ifdef HAVE_SSL
        --argc;
        ++argv;
        if (argc != 4)
            errx(EXIT_FAILURE, "x509-sign-package takes exactly four arguments");
        pkg_sign_x509(argv[0], argv[1], argv[2], argv[3]);
#else
        errx(EXIT_FAILURE, "OpenSSL support is not included");
#endif
    } else if (strcasecmp(argv[0], "gpg-sign-package") == 0) {
        --argc;
        ++argv;
        if (argc != 2)
            errx(EXIT_FAILURE, "gpg-sign-package takes exactly two arguments");
        pkg_sign_gpg(argv[0], argv[1]);
    }
#endif
    else {
        usage();
    }

    return 0;
}
示例#19
0
文件: delete.c 项目: probonopd/klik
#include "extern.h"
#include "pathnames.h"

/*-
 * delete --
 *	Deletes named members from the archive.
 */
int
delete(char **argv)
{
	CF cf;
	off_t size;
	int afd, tfd;
	char *file;

	afd = open_archive(O_RDWR);
	tfd = tmp();

	/* Read and write to an archive; pad on both. */
	SETCF(afd, archive, tfd, tname, RPAD|WPAD);
	while (get_arobj(afd)) {
		if (*argv && (file = files(argv))) {
			if (options & AR_V)
				(void)printf("d - %s\n", file);
			skip_arobj(afd);
			continue;
		}
		put_arobj(&cf, NULL);
	}

	size = lseek(tfd, (off_t)0, SEEK_CUR);
示例#20
0
文件: rw.c 项目: ah42/CUDALucas
void archivebits(double *x, UL q, UL n, UL totalbits, UL b, UL c, double hi, double lo,
		const char *version_info, FILE *outfp, FILE *dupfp) {

	FILE *archfp = NULL;
	
	archfp = open_archive();

	if (is_zero(x, n, 0, 0)) {
		if (outfp != NULL && !ferror(outfp)) fprintf(outfp,  "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info);
		if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp,  "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info);
		if (archfp != NULL)                  fprintf(archfp, "M( " PRINTF_FMT_UL " )P, n = " PRINTF_FMT_UL ", %s\n", q, n, version_info);
		
		if (archfp != NULL) close_archive(archfp, outfp, dupfp);
		
		return;
	}

	if (outfp != NULL && !ferror(outfp)) fprintf(outfp,  "M( " PRINTF_FMT_UL " )C", q);
	if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp,  "M( " PRINTF_FMT_UL " )C", q);
	if (archfp != NULL)                  fprintf(archfp, "M( " PRINTF_FMT_UL " )C", q);

	balancedtostdrep(x, n, b, c, hi, lo, 0, 0);
	static UL *hex = NULL;
	static UL prior_hex = 0;
	if (hex != NULL && totalbits/BITS_IN_LONG + 1 > prior_hex) {
		free(hex);
		hex = NULL;
		prior_hex = totalbits/BITS_IN_LONG + 1;
	}

	if (hex == NULL && (hex = (UL *)calloc(totalbits/BITS_IN_LONG + 1, sizeof(UL))) == NULL) {
		perror(program_name);
		fprintf(stderr, "%s: cannot get memory for residue bits; calloc() errno %d\n", program_name, errno);
		exit(errno);
	}
	
	int i = 0;
	int j = 0;
	do {
		UL k = (long)(ceil((double)q*(j + 1)/n) - ceil((double)q*j/n));
		if (k > totalbits) k = totalbits;
		totalbits -= k;
		int word = (long)x[j];
		for (j++; k > 0; k--, i++) {
			if (i % BITS_IN_LONG == 0)
				hex[i/BITS_IN_LONG] = 0L;
			hex[i/BITS_IN_LONG] |= ((word & 0x1) << (i % BITS_IN_LONG));
			word >>= 1;
		}
	} while(totalbits > 0);
	
	if (outfp != NULL && !ferror(outfp)) fputs(", 0x", outfp);
	if (dupfp != NULL && !ferror(dupfp)) fputs(", 0x", dupfp);
	if (archfp != NULL)                  fputs(", 0x", archfp);
	
	static char bits_fmt[16] = "\0"; /* "%%0%ulx" -> "%08lx" or "%016lx" depending on sizeof(UL) */
	
	if (bits_fmt[0] != '%')
		sprintf(bits_fmt, "%%0" PRINTF_FMT_UL "%s", (UL)(BITS_IN_LONG/4), "lx"); /* 4 bits per hex 'digit' */
	
	for (j = (i - 1)/BITS_IN_LONG; j >= 0; j--) {
		if (outfp != NULL && !ferror(outfp)) fprintf(outfp, bits_fmt, hex[j]);
		if (dupfp != NULL && !ferror(dupfp)) fprintf(dupfp, bits_fmt, hex[j]);
		if (archfp != NULL)                  fprintf(archfp, bits_fmt, hex[j]);
	}
	
	if (outfp != NULL && !ferror(outfp)) {
		fprintf(outfp, ", n = " PRINTF_FMT_UL ", %s", n, version_info);
		fprintf(outfp, "\n");
		fflush(outfp);
	}

	if (dupfp != NULL && !ferror(dupfp))
		fprintf(dupfp, ", n = " PRINTF_FMT_UL ", %s\n", n, version_info);
	if (archfp != NULL) {
		fprintf(archfp, ", n = " PRINTF_FMT_UL ", %s\n", n, version_info);
		close_archive(archfp, outfp, dupfp);
	}
	return;
}
示例#21
0
static void
create_archive (const char *archivefname, struct locarhandle *ah)
{
  int fd;
  char fname[strlen (archivefname) + sizeof (".XXXXXX")];
  struct locarhead head;
  void *p;
  size_t total;

  strcpy (stpcpy (fname, archivefname), ".XXXXXX");

  /* Create a temporary file in the correct directory.  */
  fd = mkstemp (fname);
  if (fd == -1)
    error (EXIT_FAILURE, errno, _("cannot create temporary file"));

  /* Create the initial content of the archive.  */
  head.magic = AR_MAGIC;
  head.serial = 0;
  head.namehash_offset = sizeof (struct locarhead);
  head.namehash_used = 0;
  head.namehash_size = next_prime (INITIAL_NUM_NAMES);

  head.string_offset = (head.namehash_offset
			+ head.namehash_size * sizeof (struct namehashent));
  head.string_used = 0;
  head.string_size = INITIAL_SIZE_STRINGS;

  head.locrectab_offset = head.string_offset + head.string_size;
  head.locrectab_used = 0;
  head.locrectab_size = INITIAL_NUM_LOCREC;

  head.sumhash_offset = (head.locrectab_offset
			 + head.locrectab_size * sizeof (struct locrecent));
  head.sumhash_used = 0;
  head.sumhash_size = next_prime (INITIAL_NUM_SUMS);

  total = head.sumhash_offset + head.sumhash_size * sizeof (struct sumhashent);

  /* Write out the header and create room for the other data structures.  */
  if (TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head))) != sizeof (head))
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot initialize archive file"));
    }

  if (ftruncate64 (fd, total) != 0)
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot resize archive file"));
    }

  /* To prepare for enlargements of the mmaped area reserve some
     address space.  */
  size_t reserved = RESERVE_MMAP_SIZE;
  int xflags = 0;
  if (total < reserved
      && ((p = mmap64 (NULL, reserved, PROT_NONE, MAP_PRIVATE | MAP_ANON,
		       -1, 0)) != MAP_FAILED))
    xflags = MAP_FIXED;
  else
    {
      p = NULL;
      reserved = total;
    }

  /* Map the header and all the administration data structures.  */
  p = mmap64 (p, total, PROT_READ | PROT_WRITE, MAP_SHARED | xflags, fd, 0);
  if (p == MAP_FAILED)
    {
      int errval = errno;
      unlink (fname);
      error (EXIT_FAILURE, errval, _("cannot map archive header"));
    }

  /* Now try to rename it.  We don't use the rename function since
     this would overwrite a file which has been created in
     parallel.  */
  if (link (fname, archivefname) == -1)
    {
      int errval = errno;

      /* We cannot use the just created file.  */
      close (fd);
      unlink (fname);

      if (errval == EEXIST)
	{
	  /* There is already an archive.  Must have been a localedef run
	     which happened in parallel.  Simply open this file then.  */
	  open_archive (ah, false);
	  return;
	}

      error (EXIT_FAILURE, errval, _("failed to create new locale archive"));
    }

  /* Remove the temporary name.  */
  unlink (fname);

  /* Make the file globally readable.  */
  if (fchmod (fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) == -1)
    {
      int errval = errno;
      unlink (archivefname);
      error (EXIT_FAILURE, errval,
	     _("cannot change mode of new locale archive"));
    }

  ah->fd = fd;
  ah->addr = p;
  ah->mmaped = total;
  ah->reserved = reserved;
}
void
delete_archive_members (void)
{
  enum read_header logical_status = HEADER_STILL_UNREAD;
  enum read_header previous_status = HEADER_STILL_UNREAD;

  /* FIXME: Should clean the routine before cleaning these variables :-( */
  struct name *name;
  off_t blocks_to_skip = 0;
  off_t blocks_to_keep = 0;
  int kept_blocks_in_record;

  name_gather ();
  open_archive (ACCESS_UPDATE);
  acting_as_filter = strcmp (archive_name_array[0], "-") == 0;

  do
    {
      enum read_header status = read_header (true);

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:
	  if ((name = name_scan (current_stat_info.file_name)) == NULL)
	    {
	      skip_member ();
	      break;
	    }
	  name->found_count++;
	  if (!ISFOUND(name))
	    {
	      skip_member ();
	      break;
	    }

	  /* Fall through.  */
	case HEADER_SUCCESS_EXTENDED:
	  logical_status = status;
	  break;

	case HEADER_ZERO_BLOCK:
	  if (ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      break;
	    }
	  /* Fall through.  */
	case HEADER_END_OF_FILE:
	  logical_status = HEADER_END_OF_FILE;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_SUCCESS_EXTENDED:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	      abort ();
	    }
	  break;
	}

      previous_status = status;
    }
  while (logical_status == HEADER_STILL_UNREAD);

  records_skipped = records_read - 1;
  new_record = xmalloc (record_size);

  if (logical_status == HEADER_SUCCESS
      || logical_status == HEADER_SUCCESS_EXTENDED)
    {
      write_archive_to_stdout = false;

      /* Save away blocks before this one in this record.  */

      new_blocks = current_block - record_start;
      if (new_blocks)
	memcpy (new_record, record_start, new_blocks * BLOCKSIZE);

      if (logical_status == HEADER_SUCCESS)
	{
	  /* FIXME: Pheew!  This is crufty code!  */
	  logical_status = HEADER_STILL_UNREAD;
	  goto flush_file;
	}

      /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says:
	 "delete.c", line 223: warning: loop not entered at top
	 Reported by Bruno Haible.  */
      while (1)
	{
	  enum read_header status;

	  /* Fill in a record.  */

	  if (current_block == record_end)
	    flush_archive ();
	  status = read_header (false);

	  xheader_decode (&current_stat_info);

	  if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      continue;
	    }
	  if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK)
	    {
	      logical_status = HEADER_END_OF_FILE;
	      break;
	    }

	  if (status == HEADER_FAILURE)
	    {
	      ERROR ((0, 0, _("Deleting non-header from archive")));
	      set_next_block_after (current_header);
	      continue;
	    }

	  /* Found another header.  */

	  if ((name = name_scan (current_stat_info.file_name)) != NULL)
	    {
	      name->found_count++;
	      if (ISFOUND(name))
		{
		flush_file:
		  set_next_block_after (current_header);
		  blocks_to_skip = (current_stat_info.stat.st_size
				    + BLOCKSIZE - 1) / BLOCKSIZE;
		  
		  while (record_end - current_block <= blocks_to_skip)
		    {
		      blocks_to_skip -= (record_end - current_block);
		      flush_archive ();
		    }
		  current_block += blocks_to_skip;
		  blocks_to_skip = 0;
		  continue;
		}
	    }
	  /* Copy header.  */

	  if (extended_header.size)
	    {
	      write_recent_bytes (extended_header.buffer,
				  extended_header.size);
	    }
	  else
	    {
	      write_recent_blocks (recent_long_name, recent_long_name_blocks);
	      write_recent_blocks (recent_long_link, recent_long_link_blocks);
	    }
	  new_record[new_blocks] = *current_header;
	  new_blocks++;
	  blocks_to_keep
	    = (current_stat_info.stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
	  set_next_block_after (current_header);
	  if (new_blocks == blocking_factor)
	    write_record (1);

	  /* Copy data.  */

	  kept_blocks_in_record = record_end - current_block;
	  if (kept_blocks_in_record > blocks_to_keep)
	    kept_blocks_in_record = blocks_to_keep;

	  while (blocks_to_keep)
	    {
	      int count;

	      if (current_block == record_end)
		{
		  flush_read ();
		  current_block = record_start;
		  kept_blocks_in_record = blocking_factor;
		  if (kept_blocks_in_record > blocks_to_keep)
		    kept_blocks_in_record = blocks_to_keep;
		}
	      count = kept_blocks_in_record;
	      if (blocking_factor - new_blocks < count)
		count = blocking_factor - new_blocks;

	      if (! count)
		abort ();

	      memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE);
	      new_blocks += count;
	      current_block += count;
	      blocks_to_keep -= count;
	      kept_blocks_in_record -= count;

	      if (new_blocks == blocking_factor)
		write_record (1);
	    }
	}

      if (logical_status == HEADER_END_OF_FILE)
	{
	  /* Write the end of tape.  FIXME: we can't use write_eot here,
	     as it gets confused when the input is at end of file.  */

	  int total_zero_blocks = 0;

	  do
	    {
	      int zero_blocks = blocking_factor - new_blocks;
	      memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks);
	      total_zero_blocks += zero_blocks;
	      write_record (total_zero_blocks < 2);
	    }
	  while (total_zero_blocks < 2);
	}

      if (! acting_as_filter && ! _isrmt (archive))
	{
	  if (sys_truncate (archive))
	    truncate_warn (archive_name_array[0]);
	}
    }
  free (new_record);

  close_archive ();
  names_notfound ();
}
示例#23
0
文件: ranlib.c 项目: McIkye/tools
int
do_ranlib(void)
{
	CF cf;
	off_t size;
	FILE	*afp, *tfp;
	long	symcnt;			/* symbol count */
	long	tsymlen;		/* total string length */
	int	i, current_mid;

	current_mid = -1;
	afp = open_archive(O_RDWR);
	tfp = tmp();

	SETCF(afp, archive, tfp, tname, 0);

	/* Read through the archive, creating list of symbols. */
	symcnt = tsymlen = 0;
	ntsize = 0;
	r_fuzz = SARMAG;
	pnext = &rhead;
	while(get_arobj(afp)) {
		int new_mid;

		if (!strncmp(chdr.name, AR_NAMTAB, sizeof(AR_NAMTAB) - 1)) {
			size = ftello(afp);
			get_namtab(afp);
			ntsize = chdr.size + sizeof(struct ar_hdr);
			(void)fseeko(afp, size, SEEK_SET);
			r_fuzz += skip_arobj(afp);
			continue;
		}

		if (!strncmp(chdr.name, RANLIBMAG, sizeof(RANLIBMAG) - 1) ||
		    !strncmp(chdr.name, RANLIBMAG2, sizeof(RANLIBMAG2) - 1)) {
			r_fuzz += skip_arobj(afp);
			continue;
		}
		new_mid = read_exec(afp, tfp, &symcnt, &tsymlen);
		if (new_mid != -1) {
			if (current_mid == -1)
				current_mid = new_mid;
			else if (new_mid != current_mid)
				errx(1, "mixed object format archive: %x / %x",
					new_mid, current_mid);
		}
		put_arobj(&cf, NULL);
	}
	*pnext = NULL;

	SETCF(tfp, tname, afp, archive, NOPAD);

	/* Create the symbol table.  Endianess the same as last mid seen */
	symobj(afp, current_mid, symcnt, tsymlen);
	put_nametab(&cf);

	/* Copy the saved objects into the archive. */
	size = ftello(tfp);
	rewind(tfp);
	copy_ar(&cf, size);
	fflush(afp);
	(void)ftruncate(fileno(afp), ftello(afp));
	(void)fclose(tfp);

	/* Set the time. */
	settime(afp);
	close_archive(afp);
	return(0);
}
示例#24
0
void
read_and (void (*do_something) ())
{
  enum read_header status = HEADER_STILL_UNREAD;
  enum read_header prev_status;
  char save_typeflag;

  name_gather ();
  open_archive (ACCESS_READ);

  while (1)
    {
      prev_status = status;
      status = read_header ();
      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:

	  /* Valid header.  We should decode next field (mode) first.
	     Ensure incoming names are null terminated.  */

	  /* FIXME: This is a quick kludge before 1.12 goes out.  */
	  current_stat.st_mtime
	    = from_oct (1 + 12, current_header->header.mtime);

	  if (!name_match (current_file_name)
	      || current_stat.st_mtime < newer_mtime_option
	      || (exclude_option && check_exclude (current_file_name)))
	    {
	      int isextended = 0;

	      if (current_header->header.typeflag == GNUTYPE_VOLHDR
		  || current_header->header.typeflag == GNUTYPE_MULTIVOL
		  || current_header->header.typeflag == GNUTYPE_NAMES)
		{
		  (*do_something) ();
		  continue;
		}
	      if (show_omitted_dirs_option
		  && current_header->header.typeflag == DIRTYPE)
		WARN ((0, 0, _("Omitting %s"), current_file_name));

	      /* Skip past it in the archive.  */

	      if (current_header->oldgnu_header.isextended)
		isextended = 1;
	      save_typeflag = current_header->header.typeflag;
	      set_next_block_after (current_header);
	      if (isextended)
		{
#if 0
		  union block *exhdr;

		  while (1)
		    {
		      exhdr = find_next_block ();
		      if (!exhdr->sparse_header.isextended)
			{
			  set_next_block_after (exhdr);
			  break;
			}
		    }
		  set_next_block_after (exhdr);
#endif
		  skip_extended_headers ();
		}

	      /* Skip to the next header on the archive.  */

	      if (save_typeflag != DIRTYPE)
		skip_file ((long long) current_stat.st_size);
	      continue;
	    }

	  (*do_something) ();
	  continue;

	case HEADER_ZERO_BLOCK:
	  if (block_number_option)
	    fprintf (stdlis, _("block %10ld: ** Block of NULs **\n"),
		     current_block_ordinal ());

	  set_next_block_after (current_header);
	  status = prev_status;
	  if (ignore_zeros_option)
	    continue;
	  break;

	case HEADER_END_OF_FILE:
	  if (block_number_option)
	    fprintf (stdlis, _("block %10ld: ** End of File **\n"),
		     current_block_ordinal ());
	  break;

	case HEADER_FAILURE:
	  /* If the previous header was good, tell them that we are
	     skipping bad ones.  */
	  set_next_block_after (current_header);
	  switch (prev_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("Could not extract file(s); file might not be a tar archive")));
	      /* Fall through.  */

	    case HEADER_ZERO_BLOCK:
	    case HEADER_SUCCESS:
	      WARN ((0, 0, _("Skipping to next file header")));
	      break;

	    case HEADER_END_OF_FILE:
	    case HEADER_FAILURE:
	      /* We are in the middle of a cascade of errors.  */
	      break;
	    }
	  continue;
	}
      break;
    }

  apply_delayed_set_stat ();
  close_archive ();
  names_notfound ();		/* print names not found */
}
示例#25
0
void
delete_archive_members (void)
{
  enum read_header logical_status = HEADER_STILL_UNREAD;
  enum read_header previous_status = HEADER_STILL_UNREAD;

  /* FIXME: Should clean the routine before cleaning these variables :-( */
  struct name *name;
  int blocks_to_skip = 0;
  int blocks_to_keep = 0;
  int kept_blocks_in_record;

  name_gather ();
  open_archive (ACCESS_UPDATE);

  while (logical_status == HEADER_STILL_UNREAD)
    {
      enum read_header status = read_header ();

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:
	  if (name = name_scan (current_file_name), !name)
	    {
	      set_next_block_after (current_header);
	      if (current_header->oldgnu_header.isextended)
		skip_extended_headers ();
	      skip_file ((long) (current_stat.st_size));
	      break;
	    }
	  name->found = 1;
	  logical_status = HEADER_SUCCESS;
	  break;

	case HEADER_ZERO_BLOCK:
	case HEADER_END_OF_FILE:
	  logical_status = HEADER_END_OF_FILE;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	      abort ();
	    }
	  break;
	}

      previous_status = status;
    }

  if (logical_status != HEADER_SUCCESS)
    {
      write_eot ();
      close_archive ();
      names_notfound ();
      return;
    }

  write_archive_to_stdout = 0;
  new_record = (union block *) xmalloc ((size_t) record_size);

  /* Save away blocks before this one in this record.  */

  new_blocks = current_block - record_start;
  blocks_needed = blocking_factor - new_blocks;
  if (new_blocks)
    memcpy ((void *) new_record, (void *) record_start,
	   (size_t) (new_blocks * BLOCKSIZE));

#if 0
  /* FIXME: Old code, before the goto was inserted.  To be redesigned.  */
  set_next_block_after (current_header);
  if (current_header->oldgnu_header.isextended)
    skip_extended_headers ();
  skip_file ((long) (current_stat.st_size));
#endif
  logical_status = HEADER_STILL_UNREAD;
  goto flush_file;

  /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says:
       "delete.c", line 223: warning: loop not entered at top
     Reported by Bruno Haible.  */
  while (1)
    {
      enum read_header status;

      /* Fill in a record.  */

      if (current_block == record_end)
	{
	  flush_archive ();
	  records_read++;
	}
      status = read_header ();

      if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
	{
	  set_next_block_after (current_header);
	  continue;
	}
      if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK)
	{
	  logical_status = HEADER_END_OF_FILE;
	  memset (new_record[new_blocks].buffer, 0,
		 (size_t) (BLOCKSIZE * blocks_needed));
	  new_blocks += blocks_needed;
	  blocks_needed = 0;
	  write_record (0);
	  break;
	}

      if (status == HEADER_FAILURE)
	{
	  ERROR ((0, 0, _("Deleting non-header from archive")));
	  set_next_block_after (current_header);
	  continue;
	}

      /* Found another header.  */

      if (name = name_scan (current_file_name), name)
	{
	  name->found = 1;
	flush_file:
	  set_next_block_after (current_header);
	  blocks_to_skip = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;

	  while (record_end - current_block <= blocks_to_skip)
	    {
	      blocks_to_skip -= (record_end - current_block);
	      flush_archive ();
	      records_read++;
	    }
	  current_block += blocks_to_skip;
	  blocks_to_skip = 0;
	  continue;
	}

      /* Copy header.  */

      new_record[new_blocks] = *current_header;
      new_blocks++;
      blocks_needed--;
      blocks_to_keep
	= (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
      set_next_block_after (current_header);
      if (blocks_needed == 0)
	write_record (1);

      /* Copy data.  */

      kept_blocks_in_record = record_end - current_block;
      if (kept_blocks_in_record > blocks_to_keep)
	kept_blocks_in_record = blocks_to_keep;

      while (blocks_to_keep)
	{
	  int count;

	  if (current_block == record_end)
	    {
	      flush_read ();
	      records_read++;
	      current_block = record_start;
	      kept_blocks_in_record = blocking_factor;
	      if (kept_blocks_in_record > blocks_to_keep)
		kept_blocks_in_record = blocks_to_keep;
	    }
	  count = kept_blocks_in_record;
	  if (count > blocks_needed)
	    count = blocks_needed;

	  memcpy ((void *) (new_record + new_blocks),
		  (void *) current_block,
		  (size_t) (count * BLOCKSIZE));
	  new_blocks += count;
	  blocks_needed -= count;
	  current_block += count;
	  blocks_to_keep -= count;
	  kept_blocks_in_record -= count;

	  if (blocks_needed == 0)
	    write_record (1);
	}
    }

  write_eot ();
  close_archive ();
  names_notfound ();
}
示例#26
0
文件: replace.c 项目: UNGLinux/Obase
/*
 * replace --
 *	Replace or add named members to archive.  Entries already in the
 *	archive are swapped in place.  Others are added before or after 
 *	the key entry, based on the a, b and i options.  If the u option
 *	is specified, modification dates select for replacement.
 */
int
replace(char **argv)
{
	char *file;
	int afd, curfd, errflg, exists, mods, sfd, tfd1, tfd2;
	struct stat sb;
	CF cf;
	off_t size, tsize;

	errflg = 0;
	/*
	 * If doesn't exist, simply append to the archive.  There's
	 * a race here, but it's pretty short, and not worth fixing.
	 */
	exists = !stat(archive, &sb);
	afd = open_archive(O_CREAT|O_RDWR);

	if (!exists) {
		tfd1 = -1;
		tfd2 = tmp();
		goto append;
	} 

	tfd1 = tmp();			/* Files before key file. */
	tfd2 = tmp();			/* Files after key file. */

	/*
	 * Break archive into two parts -- entries before and after the key
	 * entry.  If positioning before the key, place the key at the
	 * beginning of the after key entries and if positioning after the
	 * key, place the key at the end of the before key entries.  Put it
	 * all back together at the end.
	 */
	mods = (options & (AR_A|AR_B));
	for (curfd = tfd1; get_arobj(afd);) {
		if (*argv && (file = files(argv))) {
			if ((sfd = open(file, O_RDONLY)) < 0) {
				errflg = 1;
				warn("%s", file);
				goto useold;
			}
			(void)fstat(sfd, &sb);
			if (options & AR_U && sb.st_mtime <= chdr.date) {
				close(sfd);
				goto useold;
			}

			if (options & AR_V)
			     (void)printf("r - %s\n", file);

			/* Read from disk, write to an archive; pad on write */
			SETCF(sfd, file, curfd, tname, WPAD);
			put_arobj(&cf, &sb);
			(void)close(sfd);
			skip_arobj(afd);
			continue;
		}

		if (mods && compare(posname)) {
			mods = 0;
			if (options & AR_B)
				curfd = tfd2;
			/* Read and write to an archive; pad on both. */
			SETCF(afd, archive, curfd, tname, RPAD|WPAD);
			put_arobj(&cf, NULL);
			if (options & AR_A)
				curfd = tfd2;
		} else {
			/* Read and write to an archive; pad on both. */
useold:			SETCF(afd, archive, curfd, tname, RPAD|WPAD);
			put_arobj(&cf, NULL);
		}
	}

	if (mods) {
		warnx("%s: archive member not found", posarg);
                close_archive(afd);
                return (1);
        }

	/* Append any left-over arguments to the end of the after file. */
append:	while ((file = *argv++)) {
		if (options & AR_V)
			(void)printf("a - %s\n", file);
		if ((sfd = open(file, O_RDONLY)) < 0) {
			errflg = 1;
			warn("%s", file);
			continue;
		}
		(void)fstat(sfd, &sb);
		/* Read from disk, write to an archive; pad on write. */
		SETCF(sfd, file,
		    options & (AR_A|AR_B) ? tfd1 : tfd2, tname, WPAD);
		put_arobj(&cf, &sb);
		(void)close(sfd);
	}
	
	(void)lseek(afd, (off_t)SARMAG, SEEK_SET);

	SETCF(tfd1, tname, afd, archive, NOPAD);
	if (tfd1 != -1) {
		tsize = size = lseek(tfd1, (off_t)0, SEEK_CUR);
		(void)lseek(tfd1, (off_t)0, SEEK_SET);
		copy_ar(&cf, size);
	} else
		tsize = 0;

	tsize += size = lseek(tfd2, (off_t)0, SEEK_CUR);
	(void)lseek(tfd2, (off_t)0, SEEK_SET);
	cf.rfd = tfd2;
	copy_ar(&cf, size);

	(void)ftruncate(afd, tsize + SARMAG);
	close_archive(afd);
	return (errflg);
}	
示例#27
0
/* Implement the 'r' (add files to end of archive), and 'u' (add files
   to end of archive if they aren't there, or are more up to date than
   the version in the archive) commands.  */
void
update_archive (void)
{
  enum read_header previous_status = HEADER_STILL_UNREAD;
  bool found_end = false;

  name_gather ();
  open_archive (ACCESS_UPDATE);
  xheader_write_global ();

  while (!found_end)
    {
      enum read_header status = read_header (false);

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	case HEADER_SUCCESS_EXTENDED:
	  abort ();

	case HEADER_SUCCESS:
	  {
	    struct name *name;

	    decode_header (current_header, &current_stat_info,
			   &current_format, 0);
	    archive_format = current_format;
	    
	    if (subcommand_option == UPDATE_SUBCOMMAND
		&& (name = name_scan (current_stat_info.file_name)) != NULL)
	      {
		struct stat s;

		chdir_do (name->change_dir);
		if (deref_stat (dereference_option,
				current_stat_info.file_name, &s) == 0
		    && s.st_mtime <= current_stat_info.stat.st_mtime)
		  add_avoided_name (current_stat_info.file_name);
	      }

	    skip_member ();
	    break;
	  }

	case HEADER_ZERO_BLOCK:
	  current_block = current_header;
	  found_end = true;
	  break;

	case HEADER_END_OF_FILE:
	  found_end = true;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	    case HEADER_SUCCESS_EXTENDED:
	      abort ();
	    }
	  break;
	}

      tar_stat_destroy (&current_stat_info);
      xheader_destroy (&extended_header);
      previous_status = status;
    }

  reset_eof ();
  time_to_start_writing = true;
  output_start = current_block->buffer;

  {
    char *file_name;

    while ((file_name = name_from_list ()) != NULL)
      {
	if (excluded_name (file_name))
	  continue;
	if (interactive_option && !confirm ("add", file_name))
	  continue;
	if (subcommand_option == CAT_SUBCOMMAND)
	  append_file (file_name);
	else
	  dump_file (file_name, 1, (dev_t) 0);
      }
  }

  write_eot ();
  close_archive ();
  names_notfound ();
}
示例#28
0
文件: delete.c 项目: WndSks/msys
void
delete_archive_members (void)
{
  enum read_header logical_status = HEADER_STILL_UNREAD;
  enum read_header previous_status = HEADER_STILL_UNREAD;

  /* FIXME: Should clean the routine before cleaning these variables :-( */
  struct name *name;
  off_t blocks_to_skip = 0;
  off_t blocks_to_keep = 0;
  int kept_blocks_in_record;

  name_gather ();
  open_archive (ACCESS_UPDATE);
  acting_as_filter = strcmp (archive_name_array[0], "-") == 0;

  do
    {
      enum read_header status = read_header ();

      switch (status)
	{
	case HEADER_STILL_UNREAD:
	  abort ();

	case HEADER_SUCCESS:
	  if (name = name_scan (current_file_name), !name)
	    {
	      skip_member ();
	      break;
	    }
	  name->found = 1;
	  logical_status = HEADER_SUCCESS;
	  break;

	case HEADER_ZERO_BLOCK:
	  if (ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      break;
	    }
	  /* Fall through.  */
	case HEADER_END_OF_FILE:
	  logical_status = HEADER_END_OF_FILE;
	  break;

	case HEADER_FAILURE:
	  set_next_block_after (current_header);
	  switch (previous_status)
	    {
	    case HEADER_STILL_UNREAD:
	      WARN ((0, 0, _("This does not look like a tar archive")));
	      /* Fall through.  */

	    case HEADER_SUCCESS:
	    case HEADER_ZERO_BLOCK:
	      ERROR ((0, 0, _("Skipping to next header")));
	      /* Fall through.  */

	    case HEADER_FAILURE:
	      break;

	    case HEADER_END_OF_FILE:
	      abort ();
	    }
	  break;
	}

      previous_status = status;
    }
  while (logical_status == HEADER_STILL_UNREAD);

  new_record = xmalloc (record_size);

  if (logical_status == HEADER_SUCCESS)
    {
      write_archive_to_stdout = 0;

      /* Save away blocks before this one in this record.  */

      new_blocks = current_block - record_start;
      if (new_blocks)
	memcpy (new_record, record_start, new_blocks * BLOCKSIZE);

#if 0
      /* FIXME: Old code, before the goto was inserted.  To be redesigned.  */
      skip_member ();
#endif
      logical_status = HEADER_STILL_UNREAD;
      goto flush_file;

      /* FIXME: Solaris 2.4 Sun cc (the ANSI one, not the old K&R) says:
	 "delete.c", line 223: warning: loop not entered at top
	 Reported by Bruno Haible.  */
      while (1)
	{
	  enum read_header status;

	  /* Fill in a record.  */

	  if (current_block == record_end)
	    {
	      flush_archive ();
	      records_read++;
	    }
	  status = read_header ();

	  if (status == HEADER_ZERO_BLOCK && ignore_zeros_option)
	    {
	      set_next_block_after (current_header);
	      continue;
	    }
	  if (status == HEADER_END_OF_FILE || status == HEADER_ZERO_BLOCK)
	    {
	      logical_status = HEADER_END_OF_FILE;
	      break;
	    }

	  if (status == HEADER_FAILURE)
	    {
	      ERROR ((0, 0, _("Deleting non-header from archive")));
	      set_next_block_after (current_header);
	      continue;
	    }

	  /* Found another header.  */

	  if (name = name_scan (current_file_name), name)
	    {
	      name->found = 1;
	    flush_file:
	      set_next_block_after (current_header);
	      blocks_to_skip = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;

	      while (record_end - current_block <= blocks_to_skip)
		{
		  blocks_to_skip -= (record_end - current_block);
		  flush_archive ();
		  records_read++;
		}
	      current_block += blocks_to_skip;
	      blocks_to_skip = 0;
	      continue;
	    }

	  /* Copy header.  */

	  new_record[new_blocks] = *current_header;
	  new_blocks++;
	  blocks_to_keep
	    = (current_stat.st_size + BLOCKSIZE - 1) / BLOCKSIZE;
	  set_next_block_after (current_header);
	  if (new_blocks == blocking_factor)
	    write_record (1);

	  /* Copy data.  */

	  kept_blocks_in_record = record_end - current_block;
	  if (kept_blocks_in_record > blocks_to_keep)
	    kept_blocks_in_record = blocks_to_keep;

	  while (blocks_to_keep)
	    {
	      int count;

	      if (current_block == record_end)
		{
		  flush_read ();
		  records_read++;
		  current_block = record_start;
		  kept_blocks_in_record = blocking_factor;
		  if (kept_blocks_in_record > blocks_to_keep)
		    kept_blocks_in_record = blocks_to_keep;
		}
	      count = kept_blocks_in_record;
	      if (blocking_factor - new_blocks < count)
		count = blocking_factor - new_blocks;

	      if (! count)
		abort ();

	      memcpy (new_record + new_blocks, current_block, count * BLOCKSIZE);
	      new_blocks += count;
	      current_block += count;
	      blocks_to_keep -= count;
	      kept_blocks_in_record -= count;

	      if (new_blocks == blocking_factor)
		write_record (1);
	    }
	}
    }

  if (logical_status == HEADER_END_OF_FILE)
    {
      /* Write the end of tape.  FIXME: we can't use write_eot here,
	 as it gets confused when the input is at end of file.  */

      int total_zero_blocks = 0;

      do
	{
	  int zero_blocks = blocking_factor - new_blocks;
	  memset (new_record + new_blocks, 0, BLOCKSIZE * zero_blocks);
	  total_zero_blocks += zero_blocks;
	  write_record (total_zero_blocks < 2);
	}
      while (total_zero_blocks < 2);
    }

  free (new_record);

  if (! acting_as_filter && ! _isrmt (archive))
    {
#if MSDOS
      int status = write (archive, "", 0);
#else
      off_t pos = lseek (archive, (off_t) 0, SEEK_CUR);
      int status = pos < 0 ? -1 : ftruncate (archive, pos);
#endif
      if (status != 0)
	truncate_warn (archive_name_array[0]);
    }

  close_archive ();
  names_notfound ();
}
示例#29
0
文件: Far.c 项目: danieltahara/far
int main(int argc, char** argv)
{
    // Print an error if the user invokes Far with an incorrect number of
    // arguments. There should be at least "Far key archive"
    if (argc < 3) {
        ERROR("Usage: Far key archive [name]*");
        return 1;
    }

    char* key = argv[1];
    char* archive_name = argv[2];

    int num_files = argc - 3;
    char** filenames = argv + 3;

    // Ignore trailing / in NAME arguments
    for (int i = 0; i < num_files; i++) strip_trailing_slash(filenames[i]);

    if (!strcmp(key, "r")) {
        member_list* members = make_list_recursive(filenames, num_files);
        archive_t* archive = open_archive(archive_name, true);
        member_list* processed_members =
          process_members(archive, members, replace_current_member);
        // Now that previously existing files have been deleted, add the
        // files to the end of the archive
        member_node* cur_member = members;
        while (cur_member) {
            add_member(archive, cur_member->filename);
            cur_member = cur_member->next;
        }
        delete_list(processed_members);
        close_archive(archive, true);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "x")) {
        member_list* members = make_list(filenames, num_files);
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, members, extract_current_member);
        // Error handling for unprocessed NAME arguments
        for (int i = 0; i < num_files; i++) {
            char* name = filenames[i];
            if (!find_member(name, processed_members)) {
                ERROR_CREATE(name);
            }
        }
        delete_list(processed_members);
        close_archive(archive, false);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "d")) {
        member_list* members = make_list(filenames, num_files);
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, members, delete_current_member);
        // Error handling for unprocessed NAME arguments
        for (int i = 0; i < num_files; i++) {
            char* name = filenames[i];
            if (!find_member(name, processed_members) &&
                !find_child(name, processed_members)) {
                ERROR_FIND(name);
            }
        }
        delete_list(processed_members);
        close_archive(archive, true);

        delete_list(members);
        return 0;
    } else if (!strcmp(key, "t")) {
        archive_t* archive = open_archive(archive_name, false);
        member_list* processed_members =
          process_members(archive, NULL, print_current_member);
        delete_list(processed_members);
        close_archive(archive, false);
        return 0;
    } else {
        ERROR("Key options: 'r', 'x', 'd', 't'");
        return 1;
    }
}
示例#30
0
	///===================================================================================== Archive
	Archive::Archive(const Lib & lib, const ustring & path)
	{
		LogNoise(L"%p, '%s', 0x%Iu\n", &lib, path.c_str());
		open_archive(lib, path);
		init_props();
	}