"SfR Fresh" - the SfR Freeware/Shareware Archive

Member "lha-114i/src/lharc.c" of archive lha-114i.tar.gz:


As a special service "SfR Fresh" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. That can be also achieved for any archive member file by clicking within an archive contents listing on the first character of the file(path) respectively on the according byte size field.
    1 /* ------------------------------------------------------------------------ */
    2 /* LHa for UNIX    															*/
    3 /*				lharc.c -- append to archive								*/
    4 /*																			*/
    5 /*		Copyright (C) MCMLXXXIX Yooichi.Tagawa								*/
    6 /*		Modified          		Nobutaka Watazaki							*/
    7 /*							Thanks to H.Yoshizaki. (MS-DOS LHarc)			*/
    8 /*																			*/
    9 /*  Ver. 0.00  Original							1988.05.23  Y.Tagawa		*/
   10 /*  Ver. 0.01  Alpha Version (for 4.2BSD)		1989.05.28  Y.Tagawa		*/
   11 /*  Ver. 0.02  Alpha Version Rel.2				1989.05.29  Y.Tagawa		*/
   12 /*  Ver. 0.03  Release #3  Beta Version			1989.07.02  Y.Tagawa		*/
   13 /*  Ver. 0.03a Debug							1989.07.03  Y.Tagawa		*/
   14 /*  Ver. 0.03b Modified							1989.07.13  Y.Tagawa		*/
   15 /*  Ver. 0.03c Debug (Thanks to void@rena.dit.junet)						*/
   16 /*												1989.08.09  Y.Tagawa		*/
   17 /*  Ver. 0.03d Modified (quiet and verbose)		1989.09.14  Y.Tagawa		*/
   18 /*  V1.00  Fixed								1989.09.22  Y.Tagawa		*/
   19 /*  V1.01  Bug Fixed							1989.12.25  Y.Tagawa		*/
   20 /*																			*/
   21 /*  DOS-Version Original LHx V C2.01 		(C) H.Yohizaki					*/
   22 /*																			*/
   23 /*  V2.00  UNIX Lharc + DOS LHx -> OSK LHx		1990.11.01  Momozou			*/
   24 /*  V2.01  Minor Modified						1990.11.24  Momozou			*/
   25 /*																			*/
   26 /*  Ver. 0.02  LHx for UNIX						1991.11.18  M.Oki			*/
   27 /*  Ver. 0.03  LHa for UNIX						1991.12.17  M.Oki			*/
   28 /*  Ver. 0.04  LHa for UNIX	beta version		1992.01.20  M.Oki			*/
   29 /*  Ver. 1.00  LHa for UNIX	Fixed				1992.03.19  M.Oki			*/
   30 /*																			*/
   31 /*  Ver. 1.10  for Symblic Link					1993.06.25  N.Watazaki		*/
   32 /*  Ver. 1.11  for Symblic Link	Bug Fixed		1993.08.18  N.Watazaki		*/
   33 /*  Ver. 1.12  for File Date Check				1993.10.28  N.Watazaki		*/
   34 /*  Ver. 1.13  Bug Fixed (Idicator calcurate)	1994.02.21  N.Watazaki		*/
   35 /*  Ver. 1.13a Bug Fixed (Sym. Link delete)		1994.03.11  N.Watazaki		*/
   36 /*	Ver. 1.13b Bug Fixed (Sym. Link delete)		1994.07.29  N.Watazaki		*/
   37 /*	Ver. 1.14  Source All chagned				1995.01.14	N.Watazaki		*/
   38 /*	Ver. 1.14b,c  Bug Fixed                     1996.03.07  t.okamoto		*/
   39 /*  Ver. 1.14d Version up                       1997.01.12  t.okamoto       */
   40 /*  Ver. 1.14g Bug Fixed                        2000.05.06  t.okamoto       */
   41 /*  Ver. 1.14i Modified                         2000.10.06  t.okamoto       */
   42 /* ------------------------------------------------------------------------ */
   43 #define LHA_MAIN_SRC
   44 
   45 #include "lha.h"
   46 
   47 /* ------------------------------------------------------------------------ */
   48 /*								PROGRAM										*/
   49 /* ------------------------------------------------------------------------ */
   50 static int      cmd = CMD_UNKNOWN;
   51 
   52 /* 1996.8.13 t.okamoto */
   53 #if 0
   54 char          **cmd_filev;
   55 int             cmd_filec;
   56 
   57 char           *archive_name;
   58 char            expanded_archive_name[FILENAME_LENGTH];
   59 char            temporary_name[FILENAME_LENGTH];
   60 char            backup_archive_name[FILENAME_LENGTH];
   61 #endif
   62 
   63 /* static functions */
   64 static void     sort_files();
   65 static void		print_version();
   66 
   67 char		    *extract_directory = NULL;
   68 char		  **xfilev;
   69 int             xfilec = 257;
   70 
   71 /* 1996.8.13 t.okamoto */
   72 #if 0
   73 char           *writting_filename;
   74 char           *reading_filename;
   75 
   76 int             archive_file_mode;
   77 int             archive_file_gid;
   78 #endif
   79 /* ------------------------------------------------------------------------ */
   80 static void
   81 init_variable()		/* Added N.Watazaki */
   82 {
   83 /* options */
   84 	quiet			= FALSE;
   85 	text_mode		= FALSE;
   86 	verbose			= FALSE;
   87 	noexec			= FALSE;	/* debugging option */
   88 	force			= FALSE;
   89 	prof			= FALSE;
   90 #ifndef SUPPORT_LH7
   91 	compress_method = LZHUFF5_METHOD_NUM;
   92 #endif
   93 #ifdef SUPPORT_LH7
   94 	compress_method = LZHUFF7_METHOD_NUM;
   95 #endif
   96 
   97 	header_level	= HEADER_LEVEL1;
   98 	quiet_mode		= 0;
   99 
  100 #ifdef EUC
  101 	euc_mode		= FALSE;
  102 #endif
  103 
  104 /* view command flags */
  105 	verbose_listing = FALSE;
  106 
  107 /* extract command flags */
  108 	output_to_stdout = FALSE;
  109 
  110 /* append command flags */
  111 	new_archive			= FALSE;
  112 	update_if_newer		= FALSE;
  113 	delete_after_append = FALSE;
  114 	generic_format		= FALSE;
  115 
  116 	remove_temporary_at_error 				= FALSE;
  117 	recover_archive_when_interrupt			= FALSE;
  118 	remove_extracting_file_when_interrupt	= FALSE;
  119 	get_filename_from_stdin					= FALSE;
  120 	ignore_directory						= FALSE;
  121 	verify_mode								= FALSE;
  122 
  123 	noconvertcase							= FALSE;
  124 
  125 	extract_directory = NULL;
  126 	xfilec = 257;
  127 }
  128 
  129 /* ------------------------------------------------------------------------ */
  130 /* NOTES :			Text File Format										*/
  131 /* GENERATOR		NewLine													*/
  132 /* [generic]		0D 0A													*/
  133 /* [MS-DOS]			0D 0A													*/
  134 /* [OS9][MacOS]		0D														*/
  135 /* [UNIX]			0A														*/
  136 /* ------------------------------------------------------------------------ */
  137 static void
  138 print_tiny_usage_and_exit()
  139 {
  140 	fprintf(stderr, "\
  141 LHarc    for UNIX  V 1.02  Copyright(C) 1989  Y.Tagawa\n\
  142 LHx      for MSDOS V C2.01 Copyright(C) 1990  H.Yoshizaki\n\
  143 LHx(arc) for OSK   V 2.01  Modified     1990  Momozou\n\
  144 LHa      for UNIX  V 1.00  Copyright(C) 1992  Masaru Oki\n\
  145 LHa      for UNIX  V 1.14  Modified     1995  Nobutaka Watazaki\n\
  146 LHa      for UNIX  V 1.14i Modified     2000  Tsugio Okamoto\n\
  147 ");
  148 	fprintf(stderr, "\
  149 usage: lha [-]{axelvudmcp[q[num]][vnfodizg012]}[w=<dir>] archive_file [file...]\n\
  150 commands:                           options:\n\
  151  a   Add(or replace) to archive      q{num} quiet (num:quiet mode)\n\
  152  x,e EXtract from archive            v  verbose\n\
  153  l,v List / Verbose List             n  not execute\n\
  154  u   Update newer files to archive   f  force (over write at extract)\n\
  155  d   Delete from archive             t  FILES are TEXT file\n");
  156 #ifdef SUPPORT_LH7
  157 	fprintf(stderr, "\
  158  m   Move to archive (means 'ad')    o[567] compression method (a/u)\n\
  159 ");
  160 #endif
  161 #ifndef SUPPORT_LH7
  162 	fprintf(stderr, "\
  163  m   Move to archive (means 'ad')    o  use LHarc compatible method (a/u)\n\
  164 ");
  165 #endif
  166 	fprintf(stderr, "\
  167  c   re-Construct new archive        w=<dir> specify extract directory (a/u/m/x/e)\n\
  168  p   Print to STDOUT from archive    d  delete FILES after (a/u/c)\n\
  169  t   Test file CRC in archive        i  ignore directory path (x/e)\n\
  170                                      z  files not compress (a/u)\n\
  171                                      g  Generic format (for compatibility)\n\
  172                                         or not convert case when extracting\n\
  173                                      0/1/2 header level (a/u)\n\
  174 ");
  175 #ifdef EUC
  176 	fprintf(stderr, "\
  177                                      e  TEXT code convert from/to EUC\n\
  178 ");
  179 #endif
  180 	exit(1);
  181 }
  182 
  183 /* ------------------------------------------------------------------------ */
  184 int
  185 main(argc, argv)
  186 	int             argc;
  187 	char           *argv[];
  188 {
  189 	char           *p, inpbuf[256];
  190 
  191 	int i;
  192 	int  ac;
  193 	char **av, *m;
  194 
  195 	init_variable();		/* Added N.Watazaki */
  196 
  197 	ac = argc;
  198 	av = (char **)malloc( sizeof(char*)*argc );
  199 	if (av == NULL) fatal_error("not enough memory\n");
  200 	for (i=0; i<argc; i++) {
  201 	  if ((av[i] = strdup( argv[i] )) == NULL)
  202 		fatal_error("not enough memory\n");
  203 	}
  204 
  205 	if (ac < 2)
  206 		print_tiny_usage_and_exit();
  207 
  208 	if (strcmp(av[1], "--version") == 0) {
  209 		print_version();
  210 		exit(1);
  211 	}
  212 
  213 	if (ac < 3) {
  214 		cmd = CMD_LIST;
  215 		av--; /* argv--; */ /* 1999.7.18 */
  216 		ac++; /* argc++; */
  217 		goto work;
  218 	}
  219 
  220 	m = av[1];
  221 
  222 	if (m[0] == '-')
  223 		m++;
  224 	/* commands */
  225 	switch (*m) {
  226 	case 'x':
  227 	case 'e':
  228 		cmd = CMD_EXTRACT;
  229 		break;
  230 
  231 	case 'p':
  232 		output_to_stdout = TRUE;
  233 		cmd = CMD_EXTRACT;
  234 		break;
  235 
  236 	case 'c':
  237 		new_archive = TRUE;
  238 		cmd = CMD_ADD;
  239 		break;
  240 
  241 	case 'a':
  242 		cmd = CMD_ADD;
  243 		break;
  244 
  245 	case 'd':
  246 		cmd = CMD_DELETE;
  247 		break;
  248 
  249 	case 'u':
  250 		update_if_newer = TRUE;
  251 		cmd = CMD_ADD;
  252 		break;
  253 
  254 	case 'm':
  255 		delete_after_append = TRUE;
  256 		cmd = CMD_ADD;
  257 		break;
  258 
  259 	case 'v':
  260 		verbose_listing = TRUE;
  261 		cmd = CMD_LIST;
  262 		break;
  263 
  264 	case 'l':
  265 		cmd = CMD_LIST;
  266 		break;
  267 
  268 	case 't':
  269 		cmd = CMD_EXTRACT;
  270 		verify_mode = TRUE;
  271 		break;
  272 
  273 	default:
  274 		print_tiny_usage_and_exit();
  275 
  276 	}
  277 
  278 	/* options */
  279 	/* p = &argv[1][1]; */
  280 	p = m+1;
  281 	while ( *p != 0 ) {
  282 		switch ((*p++)) {
  283 		case 'q':
  284 			switch (*p) {
  285 			case '0':
  286 			case '1':
  287 				quiet_mode = *p - '0';
  288 				++p;
  289 				break;
  290 			case '2':
  291 			default:
  292 				quiet = TRUE;
  293 				break;
  294 			}
  295 		case 'f':
  296 			force = TRUE;
  297 			break;
  298 		case 'p':
  299 			prof = TRUE;
  300 			break;
  301 		case 'v':
  302 			verbose = TRUE;
  303 			break;
  304 		case 't':
  305 			text_mode = TRUE;
  306 			break;
  307 #ifdef EUC
  308 		case 'e':
  309 			text_mode = TRUE;
  310 			euc_mode = TRUE;
  311 			break;
  312 #endif
  313 		case 'n':
  314 			noexec = TRUE;
  315 			break;
  316 		case 'g':
  317 			generic_format = TRUE;
  318 			noconvertcase = TRUE;
  319 			header_level = 0;
  320 			break;
  321 		case 'd':
  322 			delete_after_append = TRUE;
  323 			break;
  324 		case 'o':
  325 			switch (*p) {
  326 			case 0:
  327 				compress_method = LZHUFF1_METHOD_NUM;
  328 				header_level = 0;
  329 				break;
  330 			case '5':
  331 				compress_method = LZHUFF5_METHOD_NUM;
  332 				p++;
  333 				break;
  334 #ifdef SUPPORT_LH7
  335 			case '6':
  336 				compress_method = LZHUFF6_METHOD_NUM;
  337 				p++;
  338 				break;
  339 			case '7':
  340 				compress_method = LZHUFF7_METHOD_NUM;
  341 				p++;
  342 				break;
  343 #endif
  344 			default:
  345 				fprintf(stderr, "LHa: error option o%c\n", p[-1]);
  346 				exit(1);
  347 			}
  348 			break;
  349 		case 'z':
  350 			compress_method = LZHUFF0_METHOD_NUM;	/* Changed N.Watazaki */
  351 			break;
  352 		case 'i':
  353 			ignore_directory = TRUE;
  354 			break;
  355 		case 'w':
  356 			if (*p == '=')
  357 				p++;
  358 			extract_directory = p;
  359 			while (*p)
  360 				p++;
  361 			break;
  362 		case '0':
  363 			header_level = HEADER_LEVEL0;
  364 			break;
  365 		case '1':
  366 			header_level = HEADER_LEVEL1;
  367 			break;
  368 		case '2':
  369 			header_level = HEADER_LEVEL2;
  370 			break;
  371 		default:
  372 			fprintf(stderr, "LHa: Unknown option '%c'.\n", p[-1]);
  373 			exit(1);
  374 		}
  375 	}
  376 
  377 work:
  378 	/* archive file name */
  379 	archive_name = av[2];
  380 
  381 	if (!strcmp(archive_name, "-")) {
  382 		if (!isatty(1) && cmd == CMD_ADD)
  383 			quiet = TRUE;
  384 	}
  385 	else {
  386 		if (ac == 3 && !isatty(0)) { /* 1999.7.18 */
  387 			get_filename_from_stdin = TRUE;
  388 		}
  389 	}
  390 
  391 	/* target file name */
  392 	if (get_filename_from_stdin) {
  393 		cmd_filec = 0;
  394 		if ((xfilev = (char **) malloc(sizeof(char *) * xfilec)) == NULL)
  395 			fatal_error("Virtual memory exhausted\n");
  396 		while (fgets(inpbuf, sizeof(inpbuf), stdin)) {
  397 		    /* delete \n if it exist */
  398 			i=0; p=inpbuf;
  399 			while (i < sizeof(inpbuf) && p != 0) {
  400 			    if (*p == '\n') {
  401 				    *p = 0;
  402 					break;
  403 				}
  404 				p++; i++;
  405 			}
  406 
  407 			if (cmd_filec >= xfilec) {
  408 				xfilec += 256;
  409 				cmd_filev = (char **) realloc(xfilev,
  410 						   sizeof(char *) * xfilec);
  411 				if (cmd_filev == NULL)
  412 					fatal_error("Virtual memory exhausted\n");
  413 				xfilev = cmd_filev;
  414 			}
  415 			if (strlen(inpbuf) < 1)
  416 				continue;
  417 			if ((xfilev[cmd_filec++] = (char *) strdup(inpbuf)) == NULL)
  418 				fatal_error("Virtual memory exhausted\n");
  419 		}
  420 		xfilev[cmd_filec] = NULL;
  421 		cmd_filev = xfilev;
  422 	} else {
  423 		cmd_filec = ac - 3;
  424 		cmd_filev = av + 3;
  425 	}
  426 	sort_files();
  427 
  428 	/* make crc table */
  429 	make_crctable();
  430 
  431 	switch (cmd) {
  432 	case CMD_EXTRACT:
  433 		cmd_extract();
  434 		break;
  435 	case CMD_ADD:
  436 		cmd_add();
  437 		break;
  438 	case CMD_LIST:
  439 		cmd_list();
  440 		break;
  441 	case CMD_DELETE:
  442 		cmd_delete();
  443 		break;
  444 	}
  445 
  446 #ifdef USE_PROF
  447 	if (!prof)
  448 		exit(0);
  449 #endif
  450 
  451 	return 0;
  452 }
  453 
  454 
  455 /* ------------------------------------------------------------------------ */
  456 /* */
  457 /* ------------------------------------------------------------------------ */
  458 
  459 /* ------------------------------------------------------------------------ */
  460 static void
  461 print_version()
  462 {
  463 	fprintf(stderr, "%s\n", LHA_VERSION);
  464 }
  465 
  466 /* ------------------------------------------------------------------------ */
  467 static void
  468 message_1(title, subject, name)
  469 	char           *title, *subject, *name;
  470 {
  471 	fprintf(stderr, "LHa: %s%s ", title, subject);
  472 	fflush(stderr);
  473 
  474 	if (errno == 0)
  475 		fprintf(stderr, "%s\n", name);
  476 	else
  477 		perror(name);
  478 }
  479 
  480 /* ------------------------------------------------------------------------ */
  481 void
  482 message(subject, name)
  483 	char           *subject, *name;
  484 {
  485 	message_1("", subject, name);
  486 }
  487 
  488 /* ------------------------------------------------------------------------ */
  489 void
  490 warning(subject, name)
  491 	char           *subject, *name;
  492 {
  493 	message_1("Warning: ", subject, name);
  494 }
  495 
  496 /* ------------------------------------------------------------------------ */
  497 void
  498 error(subject, msg)
  499 	char           *subject, *msg;
  500 {
  501 	message_1("Error: ", subject, msg);
  502 }
  503 
  504 /* ------------------------------------------------------------------------ */
  505 void
  506 fatal_error(msg)
  507 	char           *msg;
  508 {
  509 	message_1("Fatal error:", "", msg);
  510 
  511 	if (remove_temporary_at_error)
  512 		unlink(temporary_name);
  513 
  514 	exit(1);
  515 }
  516 
  517 /* ------------------------------------------------------------------------ */
  518 void
  519 write_error()
  520 {
  521 	fatal_error(writting_filename);
  522 }
  523 
  524 /* ------------------------------------------------------------------------ */
  525 void
  526 read_error()
  527 {
  528 	fatal_error(reading_filename);
  529 }
  530 
  531 /* ------------------------------------------------------------------------ */
  532 void
  533 interrupt(signo)
  534 	int             signo;
  535 {
  536 	errno = 0;
  537 	message("Interrupted\n", "");
  538 
  539 	if (temporary_fp)
  540 		fclose(temporary_fp);
  541 	unlink(temporary_name);
  542 	if (recover_archive_when_interrupt)
  543 		rename(backup_archive_name, archive_name);
  544 	if (remove_extracting_file_when_interrupt) {
  545 		errno = 0;
  546 		message("Removing", writting_filename);
  547 		unlink(writting_filename);
  548 	}
  549 	signal(SIGINT, SIG_DFL);
  550 	signal(SIGHUP, SIG_DFL);
  551 	kill(getpid(), signo);
  552 }
  553 
  554 /* ------------------------------------------------------------------------ */
  555 /*																			*/
  556 /* ------------------------------------------------------------------------ */
  557 static int
  558 sort_by_ascii(a, b)
  559 	char          **a, **b;
  560 {
  561 	register char  *p, *q;
  562 	register int    c1, c2;
  563 
  564 	p = *a, q = *b;
  565 	if (generic_format) {
  566 		do {
  567 			c1 = *(unsigned char *) p++;
  568 			c2 = *(unsigned char *) q++;
  569 			if (!c1 || !c2)
  570 				break;
  571 			if (islower(c1))
  572 				c1 = toupper(c1);
  573 			if (islower(c2))
  574 				c2 = toupper(c2);
  575 		}
  576 		while (c1 == c2);
  577 		return c1 - c2;
  578 	}
  579 	else {
  580 		while (*p == *q && *p != '\0')
  581 			p++, q++;
  582 		return *(unsigned char *) p - *(unsigned char *) q;
  583 	}
  584 }
  585 
  586 /* ------------------------------------------------------------------------ */
  587 static void
  588 sort_files()
  589 {
  590 	if (cmd_filec > 1)
  591 		qsort(cmd_filev, cmd_filec, sizeof(char *), sort_by_ascii);
  592 }
  593 
  594 /* ------------------------------------------------------------------------ */
  595 char           *
  596 xmalloc(size)
  597 	int             size;
  598 {
  599 	char           *p = (char *) malloc(size);
  600 	if (!p)
  601 		fatal_error("Not enough memory");
  602 	return p;
  603 }
  604 
  605 /* ------------------------------------------------------------------------ */
  606 char           *
  607 xrealloc(old, size)
  608 	char           *old;
  609 	int             size;
  610 {
  611 	char           *p = (char *) realloc(old, size);
  612 	if (!p)
  613 		fatal_error("Not enough memory");
  614 	return p;
  615 }
  616 
  617 /* ------------------------------------------------------------------------ */
  618 /*								STRING POOL									*/
  619 /* ------------------------------------------------------------------------ */
  620 /*
  621   string pool :
  622 	+-------------+-------------+------+-------------+----------+
  623 	| N A M E 1 \0| N A M E 2 \0| .... | N A M E n \0|			|
  624 	+-------------+-------------+------+-------------+----------+
  625 	  ^ ^		 ^ buffer+0 buffer+used buffer+size
  626 
  627   vector :
  628 	+---------------+---------------+------------- -----------------+
  629 	| pointer to	| pointer to	| pointer to   ...  pointer to	|
  630 	|  stringpool	|  N A M E 1	|  N A M E 2   ...   N A M E n	|
  631 	+---------------+---------------+-------------     -------------+
  632 	^ malloc base      returned
  633 */
  634 
  635 /* ------------------------------------------------------------------------ */
  636 void
  637 init_sp(sp)
  638 	struct string_pool *sp;
  639 {
  640 	sp->size = 1024 - 8;	/* any ( >=0 ) */
  641 	sp->used = 0;
  642 	sp->n = 0;
  643 	sp->buffer = (char *) xmalloc(sp->size * sizeof(char));
  644 }
  645 
  646 /* ------------------------------------------------------------------------ */
  647 void
  648 add_sp(sp, name, len)
  649 	struct string_pool *sp;
  650 	char           *name;	/* stored '\0' at tail */
  651 	int             len;	/* include '\0' */
  652 {
  653 	while (sp->used + len > sp->size) {
  654 		sp->size *= 2;
  655 		sp->buffer = (char *) xrealloc(sp->buffer, sp->size * sizeof(char));
  656 	}
  657 	bcopy(name, sp->buffer + sp->used, len);
  658 	sp->used += len;
  659 	sp->n++;
  660 }
  661 
  662 /* ------------------------------------------------------------------------ */
  663 void
  664 finish_sp(sp, v_count, v_vector)
  665 	register struct string_pool *sp;
  666 	int            *v_count;
  667 	char         ***v_vector;
  668 {
  669 	int             i;
  670 	register char  *p;
  671 	char          **v;
  672 
  673 	v = (char **) xmalloc((sp->n + 1) * sizeof(char *));
  674 	*v++ = sp->buffer;
  675 	*v_vector = v;
  676 	*v_count = sp->n;
  677 	p = sp->buffer;
  678 	for (i = sp->n; i; i--) {
  679 		*v++ = p;
  680 		if (i - 1)
  681 			p += strlen(p) + 1;
  682 	}
  683 }
  684 
  685 /* ------------------------------------------------------------------------ */
  686 void
  687 free_sp(vector)
  688 	char          **vector;
  689 {
  690 	vector--;
  691 	free(*vector);		/* free string pool */
  692 	free(vector);
  693 }
  694 
  695 
  696 /* ------------------------------------------------------------------------ */
  697 /*							READ DIRECTORY FILES							*/
  698 /* ------------------------------------------------------------------------ */
  699 static          boolean
  700 include_path_p(path, name)
  701 	char           *path, *name;
  702 {
  703 	char           *n = name;
  704 	while (*path)
  705 		if (*path++ != *n++)
  706 			return (path[-1] == '/' && *n == '\0');
  707 	return (*n == '/' || (n != name && path[-1] == '/' && n[-1] == '/'));
  708 }
  709 
  710 /* ------------------------------------------------------------------------ */
  711 void
  712 cleaning_files(v_filec, v_filev)
  713 	int            *v_filec;
  714 	char         ***v_filev;
  715 {
  716 	char           *flags;
  717 	struct stat     stbuf;
  718 
  719 	register char **filev = *v_filev;
  720 	register int    filec = *v_filec;
  721 	register char  *p;
  722 	register int    i, j;
  723 
  724 	if (filec == 0)
  725 		return;
  726 
  727 	flags = xmalloc(filec * sizeof(char));
  728 
  729 	/* flags & 0x01 :	1: ignore */
  730 	/* flags & 0x02 :	1: directory, 0 : regular file */
  731 	/* flags & 0x04 :	1: need delete */
  732 
  733 
  734 	for (i = 0; i < filec; i++)
  735 		if (GETSTAT(filev[i], &stbuf) < 0) {
  736 			flags[i] = 0x04;
  737 			fprintf(stderr,
  738 			 "LHa: Cannot access \"%s\", ignored.\n", filev[i]);
  739 		}
  740 		else {
  741 			if (is_regularfile(&stbuf))
  742 				flags[i] = 0x00;
  743 			else if (is_directory(&stbuf))
  744 				flags[i] = 0x02;
  745 #ifdef S_IFLNK
  746 			else if (is_symlink(&stbuf)) /* t.okamoto */
  747 				flags[i] = 0x00;
  748 #endif
  749 			else {
  750 				flags[i] = 0x04;
  751 				fprintf(stderr,
  752 					"LHa: Cannot archive \"%s\", ignored.\n", filev[i]);
  753 			}
  754 		}
  755 	errno = 0;
  756 
  757 	for (i = 0; i < filec; i++) {
  758 		p = filev[i];
  759 		if ((flags[i] & 0x07) == 0x00) {	/* regular file, not
  760 							 * deleted/ignored */
  761 			for (j = i + 1; j < filec; j++) {
  762 				if ((flags[j] & 0x07) == 0x00) {	/* regular file, not
  763 									 * deleted/ignored */
  764 					if (STREQU(p, filev[j]))
  765 						flags[j] = 0x04;	/* delete */
  766 				}
  767 			}
  768 		}
  769 		else if ((flags[i] & 0x07) == 0x02) {	/* directory, not
  770 							 * deleted/ignored */
  771 			for (j = i + 1; j < filec; j++) {
  772 				if ((flags[j] & 0x07) == 0x00) {	/* regular file, not
  773 									 * deleted/ignored */
  774 					if (include_path_p(p, filev[j]))
  775 						flags[j] = 0x04;	/* delete */
  776 				}
  777 				else if ((flags[j] & 0x07) == 0x02) {	/* directory, not
  778 									 * deleted/ignored */
  779 					if (include_path_p(p, filev[j]))
  780 						flags[j] = 0x04;	/* delete */
  781 				}
  782 			}
  783 		}
  784 	}
  785 
  786 	for (i = j = 0; i < filec; i++) {
  787 		if ((flags[i] & 0x04) == 0) {
  788 			if (i != j)
  789 				filev[j] = filev[i];
  790 			j++;
  791 		}
  792 	}
  793 	*v_filec = j;
  794 
  795 	free(flags);
  796 }
  797 
  798 /* ------------------------------------------------------------------------ */
  799 #ifdef NODIRECTORY
  800 /* please need your imprementation */
  801 boolean
  802 find_files(name, v_filec, v_filev)
  803 	char           *name;
  804 	int            *v_filec;
  805 	char         ***v_filev;
  806 {
  807 	return FALSE;		/* DUMMY */
  808 }
  809 
  810 /* ------------------------------------------------------------------------ */
  811 void
  812 free_files(filec, filev)
  813 	int             filec;
  814 	char          **filev;
  815 {
  816 	/* do nothing */
  817 }
  818 /* ------------------------------------------------------------------------ */
  819 #else
  820 boolean
  821 find_files(name, v_filec, v_filev)
  822 	char           *name;
  823 	int            *v_filec;
  824 	char         ***v_filev;
  825 {
  826 	struct string_pool sp;
  827 	char            newname[FILENAME_LENGTH];
  828 	int             len, n;
  829 	DIR            *dirp;
  830 	DIRENTRY       *dp;
  831 	struct stat     tmp_stbuf, arc_stbuf, fil_stbuf;
  832 
  833 	strcpy(newname, name);
  834 	len = strlen(name);
  835 	if (len > 0 && newname[len - 1] != '/')
  836 		newname[len++] = '/';
  837 
  838 	dirp = opendir(name);
  839 	if (!dirp)
  840 		return FALSE;
  841 
  842 	init_sp(&sp);
  843 
  844 	GETSTAT(temporary_name, &tmp_stbuf);
  845 	GETSTAT(archive_name, &arc_stbuf);
  846 
  847 	for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
  848 		n = NAMLEN(dp);
  849 		strncpy(newname + len, dp->d_name, n);
  850 		newname[len + n] = '\0';
  851 		if (GETSTAT(newname, &fil_stbuf) < 0)
  852 			continue;
  853 #ifdef NO_INODE
  854 		if ( dp->d_name[0] != '.' ||
  855 			(n != 1 &&
  856 			 (dp->d_name[1] != '.' ||
  857 			  n != 2))  ) {
  858 			add_sp(&sp, newname, len+n+1);
  859 		}
  860 #else
  861 		if ((dp->d_ino != 0) &&
  862 		/* exclude '.' and '..' */
  863 		    ((dp->d_name[0] != '.') ||
  864 		     ((n != 1) &&
  865 		      ((dp->d_name[1] != '.') ||
  866 		       (n != 2)))) &&
  867 		    ((tmp_stbuf.st_dev != fil_stbuf.st_dev ||
  868 		      tmp_stbuf.st_ino != fil_stbuf.st_ino) &&
  869 		     (arc_stbuf.st_dev != fil_stbuf.st_dev ||
  870 		      arc_stbuf.st_ino != fil_stbuf.st_ino))) {
  871 			add_sp(&sp, newname, len + n + 1);
  872 		}
  873 #endif
  874 	}
  875 	closedir(dirp);
  876 	finish_sp(&sp, v_filec, v_filev);
  877 	if (*v_filec > 1)
  878 		qsort(*v_filev, *v_filec, sizeof(char *), sort_by_ascii);
  879 	cleaning_files(v_filec, v_filev);
  880 
  881 	return TRUE;
  882 }
  883 
  884 /* ------------------------------------------------------------------------ */
  885 void
  886 free_files(filec, filev)
  887 	int             filec;
  888 	char          **filev;
  889 {
  890 	free_sp(filev);
  891 }
  892 #endif
  893 /* ------------------------------------------------------------------------ */
  894 /*																			*/
  895 /* ------------------------------------------------------------------------ */
  896 /* Build temporary file name and store to TEMPORARY_NAME */
  897 void
  898 build_temporary_name()
  899 {
  900 #ifdef TMP_FILENAME_TEMPLATE
  901 	/* "/tmp/lhXXXXXX" etc. */
  902 	if (extract_directory == NULL) {
  903 		strcpy(temporary_name, TMP_FILENAME_TEMPLATE);
  904 	}
  905 	else {
  906 		sprintf(temporary_name, "%s/lhXXXXXX", extract_directory);
  907 	}
  908 #ifdef MKSTEMP
  909 	mkstemp(temporary_name);
  910 #else
  911 	mktemp(temporary_name);
  912 #endif
  913 #else
  914 	char           *p, *s;
  915 
  916 	strcpy(temporary_name, archive_name);
  917 	for (p = temporary_name, s = (char *) 0; *p; p++)
  918 		if (*p == '/')
  919 			s = p;
  920 	strcpy((s ? s + 1 : temporary_name), "lhXXXXXX");
  921 #ifdef MKSTEMP
  922 	mkstemp(temporary_name);
  923 #else
  924 	mktemp(temporary_name);
  925 #endif
  926 #endif
  927 }
  928 
  929 /* ------------------------------------------------------------------------ */
  930 static void
  931 modify_filename_extention(buffer, ext)
  932 	char           *buffer;
  933 	char           *ext;
  934 {
  935 	register char  *p, *dot;
  936 
  937 	for (p = buffer, dot = (char *) 0; *p; p++) {
  938 		if (*p == '.')
  939 			dot = p;
  940 		else if (*p == '/')
  941 			dot = (char *) 0;
  942 	}
  943 
  944 	if (dot)
  945 		p = dot;
  946 
  947 	strcpy(p, ext);
  948 }
  949 
  950 /* ------------------------------------------------------------------------ */
  951 /* build backup file name */
  952 void
  953 build_backup_name(buffer, original)
  954 	char           *buffer;
  955 	char           *original;
  956 {
  957 	strcpy(buffer, original);
  958 	modify_filename_extention(buffer, BACKUPNAME_EXTENTION);	/* ".bak" */
  959 }
  960 
  961 /* ------------------------------------------------------------------------ */
  962 void
  963 build_standard_archive_name(buffer, orginal)
  964 	char           *buffer;
  965 	char           *orginal;
  966 {
  967 	strcpy(buffer, orginal);
  968 	modify_filename_extention(buffer, ARCHIVENAME_EXTENTION);	/* ".lzh" */
  969 }
  970 
  971 /* ------------------------------------------------------------------------ */
  972 /*																			*/
  973 /* ------------------------------------------------------------------------ */
  974 boolean
  975 need_file(name)
  976 	char           *name;
  977 {
  978 	int             i;
  979 
  980 	if (cmd_filec == 0)
  981 		return TRUE;
  982 
  983 	for (i = 0; i < cmd_filec; i++) {
  984 		if (patmatch(cmd_filev[i], name, 0))
  985 			return TRUE;
  986 	}
  987 
  988 	return FALSE;
  989 }
  990 
  991 FILE           *
  992 xfopen(name, mode)
  993 	char           *name, *mode;
  994 {
  995 	FILE           *fp;
  996 
  997 	if ((fp = fopen(name, mode)) == NULL)
  998 		fatal_error(name);
  999 
 1000 	return fp;
 1001 }
 1002 
 1003 /* ------------------------------------------------------------------------ */
 1004 /*																			*/
 1005 /* ------------------------------------------------------------------------ */
 1006