1 /* ------------------------------------------------------------------------ */
3 /* lhext.c -- LHarc extract */
5 /* Copyright (C) MCMLXXXIX Yooichi.Tagawa */
6 /* Modified Nobutaka Watazaki */
8 /* Ver. 0.00 Original 1988.05.23 Y.Tagawa */
9 /* Ver. 1.00 Fixed 1989.09.22 Y.Tagawa */
10 /* Ver. 0.03 LHa for UNIX 1991.12.17 M.Oki */
11 /* Ver. 1.12 LHa for UNIX 1993.10.01 N.Watazaki */
12 /* Ver. 1.13b Symbolic Link Update Bug Fix 1994.06.21 N.Watazaki */
13 /* Ver. 1.14 Source All chagned 1995.01.14 N.Watazaki */
14 /* Ver. 1.14e bugfix 1999.04.30 T.Okamoto */
15 /* ------------------------------------------------------------------------ */
17 /* ------------------------------------------------------------------------ */
18 static int skip_flg = FALSE; /* FALSE..No Skip , TRUE..Skip */
19 static char *methods[] =
21 LZHUFF0_METHOD, LZHUFF1_METHOD, LZHUFF2_METHOD, LZHUFF3_METHOD,
22 LZHUFF4_METHOD, LZHUFF5_METHOD, LZHUFF6_METHOD,
23 LARC_METHOD, LARC5_METHOD, LARC4_METHOD,
28 /* ------------------------------------------------------------------------ */
36 if (stat(name, &stbuf) >= 0) {
37 if (!is_regularfile(&stbuf)) {
38 error("Already exist (not a file)", name);
43 printf("EXTRACT %s but file is exist.\n", name);
50 switch (inquire("OverWrite ?(Yes/[No]/All/Skip)", name, "YyNnAaSs\n")) {
70 printf("EXTRACT %s\n", name);
75 /* ------------------------------------------------------------------------ */
77 make_parent_path(name)
80 char path[FILENAME_LENGTH];
84 /* make parent directory name into PATH for recursive call */
86 for (p = path + strlen(path); p > path; p--)
93 message("Why?", "ROOT");
94 return FALSE; /* no more parent. */
97 if (GETSTAT(path, &stbuf) >= 0) {
98 if (is_directory(&stbuf))
100 error("Not a directory", path);
106 printf("Making directory \"%s\".\n", path);
108 if (mkdir(path, 0777) >= 0) /* try */
109 return TRUE; /* successful done. */
112 if (!make_parent_path(path))
115 if (mkdir(path, 0777) < 0) { /* try again */
116 message("Cannot make directory", path);
123 /* ------------------------------------------------------------------------ */
125 open_with_make_path(name)
130 if ((fp = fopen(name, WRITE_BINARY)) == NULL) {
132 if (!make_parent_path(name) ||
133 (fp = fopen(name, WRITE_BINARY)) == NULL)
134 error("Cannot extract", name);
140 /* ------------------------------------------------------------------------ */
142 adjust_info(name, hdr)
148 /* adjust file stamp */
149 utimebuf[0] = utimebuf[1] = hdr->unix_last_modified_stamp;
151 if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) != UNIX_FILE_SYMLINK)
152 utime(name, utimebuf);
154 if (hdr->extend_type == EXTEND_UNIX
155 || hdr->extend_type == EXTEND_OS68K
156 || hdr->extend_type == EXTEND_XOSK) {
157 #ifdef NOT_COMPATIBLE_MODE
158 Please need your modification in this space.
160 if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) != UNIX_FILE_SYMLINK)
161 chmod(name, hdr->unix_mode);
164 #ifndef HAVE_NO_LCHOWN
165 if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) != UNIX_FILE_SYMLINK)
166 lchown(name, hdr->unix_uid, hdr->unix_gid);
168 #endif /* HAVE_NO_LCHWON */
169 chown(name, hdr->unix_uid, hdr->unix_gid);
175 /* ------------------------------------------------------------------------ */
177 extract_one(afp, hdr)
178 FILE *afp; /* archive file */
181 FILE *fp; /* output file */
186 boolean save_quiet, save_verbose, up_flag;
187 char *q = hdr->name, c;
189 if (ignore_directory && rindex(hdr->name, '/')) {
190 q = (char *) rindex(hdr->name, '/') + 1;
196 * if OSK then strip device name
198 if (hdr->extend_type == EXTEND_OS68K
199 || hdr->extend_type == EXTEND_XOSK) {
202 while (c && c != '/');
204 q = "."; /* if device name only */
209 if (extract_directory)
210 sprintf(name, "%s/%s", extract_directory, q);
215 /* LZHDIRS_METHOD¤ò»ý¤Ä¥Ø¥Ã¥À¤ò¥Á¥§¥Ã¥¯¤¹¤ë */
216 /* 1999.4.30 t.okamoto */
217 for (method = 0;; method++) {
218 if (methods[method] == NULL) {
219 error("Unknown method skiped ...", name);
222 if (bcmp(hdr->method, methods[method], 5) == 0)
226 if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR
227 && method != LZHDIRS_METHOD_NUM) {
229 for (method = 0;; method++) {
230 if (methods[method] == NULL) {
231 error("Unknown method skiped ...", name);
234 if (bcmp(hdr->method, methods[method], 5) == 0)
239 reading_filename = archive_name;
240 writting_filename = name;
241 if (output_to_stdout || verify_mode) {
243 printf("%s %s\n", verify_mode ? "VERIFY" : "EXTRACT", name);
245 int i = hdr->packed_size;
253 save_verbose = verbose;
254 if (!quiet && output_to_stdout) {
255 printf("::::::::\n%s\n::::::::\n", name);
259 else if (verify_mode) {
265 (afp, stdout, hdr->original_size, hdr->packed_size, name, method);
267 verbose = save_verbose;
270 if (skip_flg == FALSE) {
271 up_flag = inquire_extract(name);
272 if (up_flag == FALSE && force == FALSE) {
277 if (skip_flg == TRUE) { /* if skip_flg */
278 if (stat(name, &stbuf) == 0 && force != TRUE) {
279 if (stbuf.st_mtime >= hdr->unix_last_modified_stamp) {
281 printf("%s : Skipped...\n", name);
288 int i = hdr->packed_size;
295 signal(SIGINT, interrupt);
296 signal(SIGHUP, interrupt);
300 remove_extracting_file_when_interrupt = TRUE;
302 if ((fp = open_with_make_path(name)) != NULL) {
304 (afp, fp, hdr->original_size, hdr->packed_size, name, method);
307 remove_extracting_file_when_interrupt = FALSE;
308 signal(SIGINT, SIG_DFL);
309 signal(SIGHUP, SIG_DFL);
316 if (hdr->has_crc && crc != hdr->crc)
317 error("CRC error", name);
319 else if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY
320 || (hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_SYMLINK
321 || method == LZHDIRS_METHOD_NUM) {
322 /* ¢¬¤³¤ì¤Ç¡¢Symblic Link ¤Ï¡¢Âç¾æÉפ«¡© */
323 if (!ignore_directory && !verify_mode) {
326 printf("EXTRACT %s (directory)\n", name);
329 /* NAME has trailing SLASH '/', (^_^) */
330 if ((hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_SYMLINK) {
331 char buf[256], *bb1, *bb2;
334 bb1 = strtok(buf, "|");
335 bb2 = strtok(NULL, "|");
338 if (skip_flg == FALSE) {
339 up_flag = inquire_extract(name);
340 if (up_flag == FALSE && force == FALSE) {
344 if (GETSTAT(bb1, &stbuf) == 0 && force != TRUE) {
345 if (stbuf.st_mtime >= hdr->unix_last_modified_stamp) {
347 printf("%s : Skipped...\n", bb1);
354 l_code = symlink(bb2, bb1);
357 warning("Can't make Symbolic Link : ");
360 printf("Symbolic Link %s -> %s\n", bb1, bb2);
362 strcpy(name, bb1); /* Symbolic's name set */
364 sprintf(buf, "%s -> %s", bb1, bb2);
365 warning("Can't make Symbolic Link", buf);
368 } else { /* make directory */
369 if (!output_to_stdout && !make_parent_path(name))
375 error("Unknown information", name);
378 if (!output_to_stdout)
379 adjust_info(name, hdr);
382 /* ------------------------------------------------------------------------ */
383 /* EXTRACT COMMAND MAIN */
384 /* ------------------------------------------------------------------------ */
392 /* open archive file */
393 if ((afp = open_old_archive()) == NULL)
394 fatal_error(archive_name);
396 if (archive_is_msdos_sfx1(archive_name))
397 skip_msdos_sfx1_code(afp);
399 /* extract each files */
400 while (get_header(afp, &hdr)) {
401 if (need_file(hdr.name)) {
403 extract_one(afp, &hdr);
404 fseek(afp, pos + hdr.packed_size, SEEK_SET);
408 fseek(afp, hdr.packed_size, SEEK_CUR);
410 int i = hdr.packed_size;
417 /* close archive file */