static void adjust_dirinfo();
#ifdef HAVE_LIBAPPLEFILE
-static boolean decode_macbinary(FILE *ofp, size_t size, const char *outPath);
+static boolean decode_macbinary(FILE *ofp, off_t size, const char *outPath);
#endif
/* ------------------------------------------------------------------------ */
}
static boolean
-make_name_with_pathcheck(char *name, size_t namesz, const char *dir, const char *q)
+make_name_with_pathcheck(char *name, size_t namesz, const char *q)
{
int offset = 0;
const char *p;
offset += sz;
}
+#ifdef S_IFLNK
while ((p = strchr(q, '/')) != NULL) {
if (namesz - offset < (p - q) + 2) {
return FALSE;
}
name[offset++] = '/';
}
+#endif
str_safe_copy(name + offset, q, namesz - offset);
}
/* ------------------------------------------------------------------------ */
+static int
+symlink_with_make_path(realname, name)
+ const char *realname;
+ const char *name;
+{
+ int l_code;
+
+ l_code = symlink(realname, name);
+ if (l_code < 0) {
+ make_parent_path(name);
+ l_code = symlink(realname, name);
+ }
+
+ return l_code;
+}
+
+/* ------------------------------------------------------------------------ */
static void
adjust_info(name, hdr)
char *name;
}
else {
if (is_directory_traversal(q)) {
- fprintf(stderr, "Possible directory traversal hack attempt in %s\n", q);
- exit(111);
+ error("Possible directory traversal hack attempt in %s", q);
+ exit(1);
}
if (*q == '/') {
}
}
- if (!make_name_with_pathcheck(name, sizeof(name), extract_directory, q)) {
- fprintf(stderr, "Possible symlink traversal hack attempt in %s\n", q);
- exit(111);
+ if (!make_name_with_pathcheck(name, sizeof(name), q)) {
+ error("Possible symlink traversal hack attempt in %s", q);
+ exit(1);
}
/* LZHDIRS_METHODを持つヘッダをチェックする */
}
}
- if (skip_flg == TRUE) { /* if skip_flg */
+ if (skip_flg == TRUE) {
if (stat(name, &stbuf) == 0 && force != TRUE) {
- if (stbuf.st_mtime >= hdr->unix_last_modified_stamp) {
- if (quiet != TRUE)
- printf("%s : Skipped...\n", name);
- return read_size;
- }
+ if (quiet != TRUE)
+ printf("%s : Skipped...\n", name);
+ return read_size;
}
}
if (noexec) {
|| (hdr->unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_SYMLINK
|| method == LZHDIRS_METHOD_NUM) {
/* ↑これで、Symbolic Link は、大丈夫か? */
- if (!ignore_directory && !verify_mode) {
+ if (!ignore_directory && !verify_mode && !output_to_stdout) {
if (noexec) {
if (quiet != TRUE)
printf("EXTRACT %s (directory)\n", name);
if (up_flag == FALSE && force == FALSE) {
return read_size;
}
- } else {
+ }
+
+ if (skip_flg == TRUE) {
if (GETSTAT(name, &stbuf) == 0 && force != TRUE) {
- if (stbuf.st_mtime >= hdr->unix_last_modified_stamp) {
- if (quiet != TRUE)
- printf("%s : Skipped...\n", name);
- return read_size;
- }
+ if (quiet != TRUE)
+ printf("%s : Skipped...\n", name);
+ return read_size;
}
}
unlink(name);
- make_parent_path(name);
- l_code = symlink(hdr->realname, name);
+ l_code = symlink_with_make_path(hdr->realname, name);
if (l_code < 0) {
if (quiet != TRUE)
warning("Can't make Symbolic Link \"%s\" -> \"%s\"",
#endif
}
else { /* make directory */
- if (!output_to_stdout && !make_parent_path(name))
+ if (!make_parent_path(name))
return read_size;
/* save directory information */
add_dirinfo(name, hdr);
return read_size;
}
+static int
+skip_to_nextpos(FILE *fp, off_t pos, off_t off, off_t read_size)
+{
+ if (pos != -1) {
+ if (fseeko(fp, pos + off, SEEK_SET) != 0) {
+ return -1;
+ }
+ }
+ else {
+ off_t i = off - read_size;
+ while (i--) {
+ if (fgetc(fp) == EOF) {
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
+
/* ------------------------------------------------------------------------ */
/* EXTRACT COMMAND MAIN */
/* ------------------------------------------------------------------------ */
/* extract each files */
while (get_header(afp, &hdr)) {
+ pos = ftello(afp);
if (need_file(hdr.name)) {
- pos = ftello(afp);
read_size = extract_one(afp, &hdr);
if (read_size != hdr.packed_size) {
/* when error occurred in extract_one(), should adjust
point of file stream */
- if (pos != -1 && afp != stdin)
- fseeko(afp, pos + hdr.packed_size, SEEK_SET);
- else {
- off_t i = hdr.packed_size - read_size;
- while (i--) fgetc(afp);
+ if (skip_to_nextpos(afp, pos, hdr.packed_size, read_size) == -1) {
+ fatal_error("Cannot seek to next header position from \"%s\"", hdr.name);
}
}
} else {
- if (afp != stdin)
- fseeko(afp, hdr.packed_size, SEEK_CUR);
- else {
- off_t i = hdr.packed_size;
- while (i--) fgetc(afp);
+ if (skip_to_nextpos(afp, pos, hdr.packed_size, 0) == -1) {
+ fatal_error("Cannot seek to next header position from \"%s\"", hdr.name);
}
}
}
af_file_t *afp = NULL;
FILE *ifp = NULL;
unsigned char *datap;
- off_t dlen;
+ size_t dlen;
if ((afp = af_open(temporary_name)) != NULL) {
/* fetch datafork */