OSDN Git Service

Merge commit 'origin/master' into pmarc
[lha/lha.git] / src / lhadd.c
index de15e8a..c9facf0 100644 (file)
@@ -1,11 +1,11 @@
 /* ------------------------------------------------------------------------ */
-/* LHa for UNIX                                                                                                                        */
-/*                             lhadd.c -- LHarc Add Command                                                            */
-/*                                                                                                                                                     */
-/*             Copyright (C) MCMLXXXIX Yooichi.Tagawa                                                          */
-/*             Modified                        Nobutaka Watazaki                                                       */
-/*                                                                                                                                                     */
-/*     Ver. 1.14       Source All chagned                              1995.01.14      N.Watazaki              */
+/* LHa for UNIX                                                             */
+/*              lhadd.c -- LHarc Add Command                                */
+/*                                                                          */
+/*      Copyright (C) MCMLXXXIX Yooichi.Tagawa                              */
+/*      Modified                Nobutaka Watazaki                           */
+/*                                                                          */
+/*  Ver. 1.14   Source All chagned              1995.01.14  N.Watazaki      */
 /* ------------------------------------------------------------------------ */
 #include "lha.h"
 /* ------------------------------------------------------------------------ */
@@ -16,253 +16,250 @@ static char    *new_archive_name;
 /* ------------------------------------------------------------------------ */
 static void
 add_one(fp, nafp, hdr)
-       FILE           *fp, *nafp;
-       LzHeader       *hdr;
+    FILE           *fp, *nafp;
+    LzHeader       *hdr;
 {
-       long            header_pos, next_pos, org_pos, data_pos;
-       long            v_original_size, v_packed_size;
-
-       reading_filename = hdr->name;
-       writing_filename = temporary_name;
-
-       if (!fp && generic_format)      /* [generic] doesn't need directory info. */
-               return;
-       header_pos = ftell(nafp);
-       write_header(nafp, hdr);/* DUMMY */
-
-       if ((hdr->unix_mode & UNIX_FILE_SYMLINK) == UNIX_FILE_SYMLINK) {
-               char            buf[256], *b1, *b2;
-               if (!quiet) {
-                       strcpy(buf, hdr->name);
-                       b1 = strtok(buf, "|");
-                       b2 = strtok(NULL, "|");
-                       printf("%s -> %s\t- Symbolic Link\n", b1, b2);
-               }               /* if quiet .. */
-       }
-
-       if (hdr->original_size == 0) {  /* empty file or directory */
+    off_t header_pos, next_pos, org_pos, data_pos;
+    off_t v_original_size, v_packed_size;
+
+    reading_filename = hdr->name;
+    writing_filename = temporary_name;
+
+    if (!fp && generic_format)  /* [generic] doesn't need directory info. */
+        return;
+    header_pos = ftello(nafp);
+    write_header(nafp, hdr);/* DUMMY */
+
+    if ((hdr->unix_mode & UNIX_FILE_SYMLINK) == UNIX_FILE_SYMLINK) {
+        if (!quiet)
+            printf("%s -> %s\t- Symbolic Link\n", hdr->name, hdr->realname);
+    }
+
+    if (hdr->original_size == 0) {  /* empty file, symlink or directory */
         finish_indicator2(hdr->name, "Frozen", 0);
-               return;         /* previous write_header is not DUMMY. (^_^) */
-    }
-       org_pos = ftell(fp);
-       data_pos = ftell(nafp);
-
-       hdr->crc = encode_lzhuf(fp, nafp, hdr->original_size,
-                 &v_original_size, &v_packed_size, hdr->name, hdr->method);
-
-       if (v_packed_size < v_original_size) {
-               next_pos = ftell(nafp);
-       }
-       else {                  /* retry by stored method */
-               fseek(fp, org_pos, SEEK_SET);
-               fseek(nafp, data_pos, SEEK_SET);
-               hdr->crc = encode_stored_crc(fp, nafp, hdr->original_size,
-                                         &v_original_size, &v_packed_size);
-               fflush(nafp);
-               next_pos = ftell(nafp);
+        return;     /* previous write_header is not DUMMY. (^_^) */
+    }
+    org_pos = ftello(fp);
+    data_pos = ftello(nafp);
+
+    hdr->crc = encode_lzhuf(fp, nafp, hdr->original_size,
+          &v_original_size, &v_packed_size, hdr->name, hdr->method);
+
+    if (v_packed_size < v_original_size) {
+        next_pos = ftello(nafp);
+    }
+    else {          /* retry by stored method */
+        fseeko(fp, org_pos, SEEK_SET);
+        fseeko(nafp, data_pos, SEEK_SET);
+        hdr->crc = encode_stored_crc(fp, nafp, hdr->original_size,
+                      &v_original_size, &v_packed_size);
+        fflush(nafp);
+        next_pos = ftello(nafp);
 #if HAVE_FTRUNCATE
-               ftruncate(fileno(nafp), next_pos);
+        if (ftruncate(fileno(nafp), next_pos) == -1)
+            error("cannot truncate archive");
+#elif HAVE_CHSIZE
+        if (chsize(fileno(nafp), next_pos) == -1)
+            error("cannot truncate archive");
+#else
+        CAUSE COMPILE ERROR
 #endif
-               memcpy(hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STORAGE);
-       }
-       hdr->original_size = v_original_size;
-       hdr->packed_size = v_packed_size;
-       fseek(nafp, header_pos, SEEK_SET);
-       write_header(nafp, hdr);
-       fseek(nafp, next_pos, SEEK_SET);
+        memcpy(hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STORAGE);
+    }
+    hdr->original_size = v_original_size;
+    hdr->packed_size = v_packed_size;
+    fseeko(nafp, header_pos, SEEK_SET);
+    write_header(nafp, hdr);
+    fseeko(nafp, next_pos, SEEK_SET);
 }
 
-
-/* ------------------------------------------------------------------------ */
 FILE           *
 append_it(name, oafp, nafp)
-       char           *name;
-       FILE           *oafp, *nafp;
+    char           *name;
+    FILE           *oafp, *nafp;
 {
-       LzHeader        ahdr, hdr;
-       FILE           *fp;
-       long            old_header;
-       int             cmp;
-       int             filec;
-       char          **filev;
-       int             i;
-       struct stat     stbuf /*, lstbuf*/;
-
-       boolean         directory, symlink;
-
-       if (GETSTAT(name, &stbuf) < 0) {
-               error("Cannot access file \"%s\"", name);       /* See cleaning_files, Why? */
-               return oafp;
-       }
-       
-       directory = is_directory(&stbuf);
+    LzHeader        ahdr, hdr;
+    FILE           *fp;
+    long            old_header;
+    int             cmp;
+    int             filec;
+    char          **filev;
+    int             i;
+    struct stat     stbuf;
+
+    boolean         directory, symlink;
+
+    if (GETSTAT(name, &stbuf) < 0) {
+        error("Cannot access file \"%s\"", name);   /* See cleaning_files, Why? */
+        return oafp;
+    }
+
+    directory = is_directory(&stbuf);
 #ifdef S_IFLNK
-       symlink = is_symlink(&stbuf);
+    symlink = is_symlink(&stbuf);
 #else
-       symlink = 0;
+    symlink = 0;
 #endif
-       init_header(name, &stbuf, &hdr);
-
-       if (!directory && !noexec)
-               if (symlink)
-                       fp = NULL;
-               else
-                       fp = xfopen(name, READ_BINARY);
-       else {
-               fp = NULL;
-       }
-
-       while (oafp) {
-               old_header = ftell(oafp);
-               if (!get_header(oafp, &ahdr)) {
-                       fclose(oafp);
-                       oafp = NULL;
-                       break;
-               } else {
-                       /* for symbolic link. t.okamoto */
-                       cmp = strcmp_filename(ahdr.name, hdr.name);
-                       if (cmp < 0) {  /* SKIP */
-                               /* copy old to new */
-                               if (!noexec) {
-                                       fseek(oafp, old_header, SEEK_SET);
-                                       copy_old_one(oafp, nafp, &ahdr);
-                               }
-                               else
-                                       fseek(oafp, ahdr.packed_size, SEEK_CUR);
-                       } else if (cmp == 0) {  /* REPLACE */
-                               /* drop old archive's */
-                               fseek(oafp, ahdr.packed_size, SEEK_CUR);
-                               break;
-                       } else {        /* cmp > 0, INSERT */
-                               fseek(oafp, old_header, SEEK_SET);
-                               break;
-                       }
-               }
-       }
-
-       if (update_if_newer) {
-               if (!oafp ||    /* not in archive */
-                   cmp > 0 ||  /* // */
-                   ahdr.unix_last_modified_stamp <     /* newer than archive's */
-                   hdr.unix_last_modified_stamp) {
-                       if (noexec)
-                               printf("ADD %s\n", name);
-                       else
-                               add_one(fp, nafp, &hdr);
-               } else {                /* cmp == 0 *//* copy old to new */
-                       if (!noexec) {
-                               fseek(oafp, old_header, SEEK_SET);
-                               copy_old_one(oafp, nafp, &ahdr);
-                       }
-               }
-       } else {
-               if (!oafp || cmp > 0) { /* not in archive or dropped */
-                       if (noexec)
-                               printf("ADD %s\n", name);
-                       else
-                               add_one(fp, nafp, &hdr);
-               }
-               else {          /* cmp == 0 */
-                       /* replace */
-                       if (noexec)
-                               printf("REPLACE\n");
-                       else
-                               add_one(fp, nafp, &hdr);
-               }
-       }
-
-       if (!directory) {
-               if (!noexec)
-                       if (!symlink)
-                               fclose(fp);
-       }
-       else {                  /* recurcive call */
-               if (find_files(name, &filec, &filev)) {
-                       for (i = 0; i < filec; i++)
-                               oafp = append_it(filev[i], oafp, nafp);
-                       free_files(filec, filev);
-               }
-       }
-       return oafp;
+
+    fp = NULL;
+    if (!directory && !symlink && !noexec) {
+        fp = fopen(name, READ_BINARY);
+        if (!fp) {
+            error("Cannot open file \"%s\": %s", name, strerror(errno));
+            return oafp;
+        }
+    }
+
+    init_header(name, &stbuf, &hdr);
+
+    cmp = 0;                    /* avoid compiler warnings `uninitialized' */
+    while (oafp) {
+        old_header = ftello(oafp);
+        if (!get_header(oafp, &ahdr)) {
+            /* end of archive or error occurred */
+            fclose(oafp);
+            oafp = NULL;
+            break;
+        }
+
+        if (!sort_contents) {
+            if (!noexec) {
+                fseeko(oafp, old_header, SEEK_SET);
+                copy_old_one(oafp, nafp, &ahdr);
+            }
+            else
+                fseeko(oafp, ahdr.packed_size, SEEK_CUR);
+            cmp = -1;           /* to be -1 always */
+            continue;
+        }
+
+        cmp = strcmp(ahdr.name, hdr.name);
+        if (cmp < 0) {          /* SKIP */
+            /* copy old to new */
+            if (!noexec) {
+                fseeko(oafp, old_header, SEEK_SET);
+                copy_old_one(oafp, nafp, &ahdr);
+            }
+            else
+                fseeko(oafp, ahdr.packed_size, SEEK_CUR);
+        } else if (cmp == 0) {  /* REPLACE */
+            /* drop old archive's */
+            fseeko(oafp, ahdr.packed_size, SEEK_CUR);
+            break;
+        } else {                /* cmp > 0, INSERT */
+            fseeko(oafp, old_header, SEEK_SET);
+            break;
+        }
+    }
+
+    if (!oafp || cmp > 0) { /* not in archive */
+        if (noexec)
+            printf("ADD %s\n", name);
+        else
+            add_one(fp, nafp, &hdr);
+    }
+    else {      /* cmp == 0 */
+        if (!update_if_newer ||
+            ahdr.unix_last_modified_stamp < hdr.unix_last_modified_stamp) {
+                                /* newer than archive's */
+            if (noexec)
+                printf("REPLACE %s\n", name);
+            else
+                add_one(fp, nafp, &hdr);
+        }
+        else {                  /* copy old to new */
+            if (!noexec) {
+                fseeko(oafp, old_header, SEEK_SET);
+                copy_old_one(oafp, nafp, &ahdr);
+            }
+        }
+    }
+
+    if (fp) fclose(fp);
+
+    if (directory && recursive_archiving) {            /* recursive call */
+        if (find_files(name, &filec, &filev)) {
+            for (i = 0; i < filec; i++)
+                oafp = append_it(filev[i], oafp, nafp);
+            free_files(filec, filev);
+        }
+    }
+    return oafp;
 }
 
 /* ------------------------------------------------------------------------ */
 static void
 find_update_files(oafp)
-       FILE           *oafp;   /* old archive */
+    FILE           *oafp;   /* old archive */
 {
-       char            name[FILENAME_LENGTH];
-       struct string_pool sp;
-       LzHeader        hdr;
-       long            pos;
-       struct stat     stbuf;
-       int             len;
-
-       pos = ftell(oafp);
-
-       init_sp(&sp);
-       while (get_header(oafp, &hdr)) {
-               if ((hdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR) {
-                       if (stat(hdr.name, &stbuf) >= 0)        /* exist ? */
-                               add_sp(&sp, hdr.name, strlen(hdr.name) + 1);
-               }
-               else if ((hdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY) {
-                       strcpy(name, hdr.name);
-                       len = strlen(name);
-                       if (len > 0 && name[len - 1] == '/')
-                               name[--len] = '\0';     /* strip tail '/' */
-                       if (stat(name, &stbuf) >= 0)    /* exist ? */
-                               add_sp(&sp, name, len + 1);
-               }
-               fseek(oafp, hdr.packed_size, SEEK_CUR);
-       }
-
-       fseek(oafp, pos, SEEK_SET);
-
-       finish_sp(&sp, &cmd_filec, &cmd_filev);
+    char            name[FILENAME_LENGTH];
+    struct string_pool sp;
+    LzHeader        hdr;
+    off_t           pos;
+    struct stat     stbuf;
+    int             len;
+
+    pos = ftello(oafp);
+
+    init_sp(&sp);
+    while (get_header(oafp, &hdr)) {
+        if ((hdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_REGULAR) {
+            if (stat(hdr.name, &stbuf) >= 0)    /* exist ? */
+                add_sp(&sp, hdr.name, strlen(hdr.name) + 1);
+        }
+        else if ((hdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_DIRECTORY) {
+            strcpy(name, hdr.name); /* ok */
+            len = strlen(name);
+            if (len > 0 && name[len - 1] == '/')
+                name[--len] = '\0'; /* strip tail '/' */
+            if (stat(name, &stbuf) >= 0)    /* exist ? */
+                add_sp(&sp, name, len + 1);
+        }
+        fseeko(oafp, hdr.packed_size, SEEK_CUR);
+    }
+
+    fseeko(oafp, pos, SEEK_SET);
+
+    finish_sp(&sp, &cmd_filec, &cmd_filev);
 }
 
 /* ------------------------------------------------------------------------ */
 static void
 delete(oafp, nafp)
-       FILE           *oafp, *nafp;
+    FILE           *oafp, *nafp;
 {
-       LzHeader        ahdr;
-       long            old_header_pos;
-       char            lpath[256], *b1, *b2;
-
-       old_header_pos = ftell(oafp);
-       while (get_header(oafp, &ahdr)) {
-               strcpy(lpath, ahdr.name);
-               b1 = strtok(lpath, "|");
-               b2 = strtok(NULL, "|");
-               if (need_file(b1)) {    /* skip */
-                       fseek(oafp, ahdr.packed_size, SEEK_CUR);
-                       if (noexec || !quiet) {
-                               if (b2 != NULL)
-                                       message("delete %s -> %s", b1, b2);
-                               else
-                                       message("delete %s", b1);
+    LzHeader ahdr;
+    off_t old_header_pos;
+
+    old_header_pos = ftello(oafp);
+    while (get_header(oafp, &ahdr)) {
+        if (need_file(ahdr.name)) { /* skip */
+            fseeko(oafp, ahdr.packed_size, SEEK_CUR);
+            if (noexec || !quiet) {
+                if ((ahdr.unix_mode & UNIX_FILE_TYPEMASK) == UNIX_FILE_SYMLINK)
+                    message("delete %s -> %s", ahdr.name, ahdr.realname);
+                else
+                    message("delete %s", ahdr.name);
+            }
+        }
+        else {      /* copy */
+            if (noexec) {
+                fseeko(oafp, ahdr.packed_size, SEEK_CUR);
+            }
+            else {
+                fseeko(oafp, old_header_pos, SEEK_SET);
+                copy_old_one(oafp, nafp, &ahdr);
             }
-               }
-               else {          /* copy */
-                       if (noexec) {
-                               fseek(oafp, ahdr.packed_size, SEEK_CUR);
-                       }
-                       else {
-                               fseek(oafp, old_header_pos, SEEK_SET);
-                               copy_old_one(oafp, nafp, &ahdr);
-                       }
-               }
-               old_header_pos = ftell(oafp);
-       }
-       return;
+        }
+        old_header_pos = ftello(oafp);
+    }
+    return;
 }
 
 /* ------------------------------------------------------------------------ */
-/*                                                                                                                                                     */
+/*                                                                          */
 /* ------------------------------------------------------------------------ */
-static FILE    *
+FILE    *
 build_temporary_file()
 {
     FILE *afp;
@@ -272,7 +269,6 @@ build_temporary_file()
     signal(SIGHUP, interrupt);
 #endif
 
-    remove_temporary_at_error = TRUE;
     temporary_fd = build_temporary_name();
     if (temporary_fd == -1)
         fatal_error("Cannot open temporary file \"%s\"", temporary_name);
@@ -289,13 +285,14 @@ static void
 build_backup_file()
 {
 
-       build_backup_name(backup_archive_name, archive_name);
-       if (!noexec) {
-               signal(SIGINT, SIG_IGN);
+    build_backup_name(backup_archive_name, archive_name,
+                      sizeof(backup_archive_name));
+    if (!noexec) {
+        signal(SIGINT, SIG_IGN);
 #ifdef SIGHUP
-               signal(SIGHUP, SIG_IGN);
+        signal(SIGHUP, SIG_IGN);
 #endif
-               if (rename(archive_name, backup_archive_name) < 0) {
+        if (rename(archive_name, backup_archive_name) < 0) {
 #if __MINGW32__
             /* On MinGW, cannot rename when
                newfile (backup_archive_name) already exists */
@@ -304,167 +301,165 @@ build_backup_file()
 #endif
             fatal_error("Cannot make backup file \"%s\"", archive_name);
         }
-               recover_archive_when_interrupt = TRUE;
-               signal(SIGINT, interrupt);
+        recover_archive_when_interrupt = TRUE;
+        signal(SIGINT, interrupt);
 #ifdef SIGHUP
-               signal(SIGHUP, interrupt);
+        signal(SIGHUP, interrupt);
 #endif
-       }
+    }
 }
 
 /* ------------------------------------------------------------------------ */
 static void
 report_archive_name_if_different()
 {
-       if (!quiet && new_archive_name == new_archive_name_buffer) {
-               /* warning at old archive is SFX */
-               message("New archive file is \"%s\"", new_archive_name);
-       }
+    if (!quiet && new_archive_name == new_archive_name_buffer) {
+        /* warning at old archive is SFX */
+        message("New archive file is \"%s\"", new_archive_name);
+    }
 }
 
 /* ------------------------------------------------------------------------ */
 void
 temporary_to_new_archive_file(new_archive_size)
-       long            new_archive_size;
+    off_t new_archive_size;
 {
-       FILE           *oafp, *nafp;
+    FILE *oafp, *nafp;
 
-       if (!strcmp(new_archive_name, "-")) {
-               nafp = stdout;
-               writing_filename = "starndard output";
-#if __MINGW32__
+    if (!strcmp(new_archive_name, "-")) {
+        nafp = stdout;
+        writing_filename = "standard output";
+#if defined(__MINGW32__) || defined(__DJGPP__)
         setmode(fileno(stdout), O_BINARY);
 #endif
-       }
-       else {
+    }
+    else {
         unlink(new_archive_name);
         if (rename(temporary_name, new_archive_name) == 0)
             return;
-               nafp = xfopen(new_archive_name, WRITE_BINARY);
-               writing_filename = archive_name;
-       }
-
-       oafp = xfopen(temporary_name, READ_BINARY);
-       reading_filename = temporary_name;
-       copyfile(oafp, nafp, new_archive_size, 0);
-       if (nafp != stdout)
-               fclose(nafp);
-       fclose(oafp);
+        nafp = xfopen(new_archive_name, WRITE_BINARY);
+        writing_filename = archive_name;
+    }
 
-       recover_archive_when_interrupt = FALSE;
-       unlink(temporary_name);
+    oafp = xfopen(temporary_name, READ_BINARY);
+    reading_filename = temporary_name;
+    copyfile(oafp, nafp, new_archive_size, 0, 0);
+    if (nafp != stdout)
+        fclose(nafp);
+    fclose(oafp);
 
-       remove_temporary_at_error = FALSE;
+    recover_archive_when_interrupt = FALSE;
+    unlink(temporary_name);
 }
 
 /* ------------------------------------------------------------------------ */
 static void
 set_archive_file_mode()
 {
-       int             umask_value;
-       struct stat     stbuf;
-
-       if (archive_file_gid < 0) {
-               umask(umask_value = umask(0));
-               archive_file_mode = (~umask_value) & 0666;      /* rw-rw-rw- */
-               if (stat(".", &stbuf) >= 0)
-                       archive_file_gid = stbuf.st_gid;
-       }
-       if (archive_file_gid >= 0)
-               chown(new_archive_name, getuid(), archive_file_gid);
-
-       chmod(new_archive_name, archive_file_mode);
+    int             umask_value;
+    struct stat     stbuf;
+
+    if (archive_file_gid < 0) {
+        umask(umask_value = umask(0));
+        archive_file_mode = (~umask_value) & 0666;  /* rw-rw-rw- */
+        if (stat(".", &stbuf) >= 0)
+            archive_file_gid = stbuf.st_gid;
+    }
+    if (archive_file_gid >= 0)
+        chown(new_archive_name, getuid(), archive_file_gid);
+
+    chmod(new_archive_name, archive_file_mode);
 }
 
 /* ------------------------------------------------------------------------ */
-/*                                                     REMOVE FILE/DIRECTORY                                                   */
+/*                          REMOVE FILE/DIRECTORY                           */
 /* ------------------------------------------------------------------------ */
 static void
 remove_one(name)
-       char           *name;
+    char           *name;
 {
-       struct stat     stbuf;
-       int             filec;
-       char          **filev;
-
-       if (GETSTAT(name, &stbuf) < 0) {
-               warning("Cannot access \"%s\": %s", name, strerror(errno));
-       }
-       else if (is_directory(&stbuf)) {
-               if (find_files(name, &filec, &filev)) {
-                       remove_files(filec, filev);
-                       free_files(filec, filev);
-               }
-               else
-                       warning("Cannot open directory \"%s\"", name);
-
-               if (noexec)
-                       message("REMOVE DIRECTORY %s", name);
-               else if (rmdir(name) < 0)
-                       warning("Cannot remove directory \"%s\"", name);
-               else if (verbose)
-                       message("Removed %s.", name);
-       }
-       else if (is_regularfile(&stbuf)) {
-               if (noexec)
-                       message("REMOVE FILE %s.", name);
-               else if (unlink(name) < 0)
-                       warning("Cannot remove \"%s\"", name);
-               else if (verbose)
-                       message("Removed %s.", name);
-       }
+    struct stat     stbuf;
+    int             filec;
+    char          **filev;
+
+    if (GETSTAT(name, &stbuf) < 0) {
+        warning("Cannot access \"%s\": %s", name, strerror(errno));
+    }
+    else if (is_directory(&stbuf)) {
+        if (find_files(name, &filec, &filev)) {
+            remove_files(filec, filev);
+            free_files(filec, filev);
+        }
+        else
+            warning("Cannot open directory \"%s\"", name);
+
+        if (noexec)
+            message("REMOVE DIRECTORY %s", name);
+        else if (rmdir(name) < 0)
+            warning("Cannot remove directory \"%s\"", name);
+        else if (verbose)
+            message("Removed %s.", name);
+    }
+    else if (is_regularfile(&stbuf)) {
+        if (noexec)
+            message("REMOVE FILE %s.", name);
+        else if (unlink(name) < 0)
+            warning("Cannot remove \"%s\"", name);
+        else if (verbose)
+            message("Removed %s.", name);
+    }
 #ifdef S_IFLNK
-       else if (is_symlink(&stbuf)) {
-               if (noexec)
-                       printf("REMOVE SYMBOLIC LINK %s.\n", name);
-               else if (unlink(name) < 0)
-                       warning("Cannot remove", name);
-               else if (verbose)
-                       message("Removed %s.", name);
-       }
+    else if (is_symlink(&stbuf)) {
+        if (noexec)
+            message("REMOVE SYMBOLIC LINK %s.", name);
+        else if (unlink(name) < 0)
+            warning("Cannot remove", name);
+        else if (verbose)
+            message("Removed %s.", name);
+    }
 #endif
-       else {
-               error("Cannot remove file \"%s\" (not a file or directory)", name);
-       }
+    else {
+        error("Cannot remove file \"%s\" (not a file or directory)", name);
+    }
 }
 
 static void
 remove_files(filec, filev)
-       int             filec;
-       char          **filev;
+    int             filec;
+    char          **filev;
 {
-       int             i;
+    int             i;
 
-       for (i = 0; i < filec; i++)
-               remove_one(filev[i]);
+    for (i = 0; i < filec; i++)
+        remove_one(filev[i]);
 }
 
 /* ------------------------------------------------------------------------ */
-/*                                                                                                                                                     */
+/*                                                                          */
 /* ------------------------------------------------------------------------ */
 void
 cmd_add()
 {
-       LzHeader        ahdr;
-       FILE           *oafp, *nafp;
-       int             i;
-       long            old_header;
-       boolean         old_archive_exist;
-       long            new_archive_size;
-
-       /* exit if no operation */
-       if (!update_if_newer && cmd_filec == 0) {
-               error("No files given in argument, do nothing.");
+    LzHeader        ahdr;
+    FILE           *oafp, *nafp;
+    int             i;
+    long            old_header;
+    boolean         old_archive_exist;
+    off_t           new_archive_size;
+
+    /* exit if no operation */
+    if (!update_if_newer && cmd_filec == 0) {
+        error("No files given in argument, do nothing.");
         exit(1);
-       }
+    }
 
-       /* open old archive if exist */
-       if ((oafp = open_old_archive()) == NULL)
-               old_archive_exist = FALSE;
-       else
-               old_archive_exist = TRUE;
+    /* open old archive if exist */
+    if ((oafp = open_old_archive()) == NULL)
+        old_archive_exist = FALSE;
+    else
+        old_archive_exist = TRUE;
 
-       if (update_if_newer && cmd_filec == 0) {
+    if (update_if_newer && cmd_filec == 0) {
         warning("No files given in argument");
         if (!oafp) {
             error("archive file \"%s\" does not exists.",
@@ -473,50 +468,46 @@ cmd_add()
         }
     }
 
-       if (new_archive && old_archive_exist) {
-               fclose(oafp);
-               oafp = NULL;
-       }
-
-       if (oafp && archive_is_msdos_sfx1(archive_name)) {
-               skip_msdos_sfx1_code(oafp);
-               build_standard_archive_name(new_archive_name_buffer, archive_name);
-               new_archive_name = new_archive_name_buffer;
-       }
-       else {
-               new_archive_name = archive_name;
-       }
-
-       /* build temporary file */
-       if (!noexec) {
-        if (STREQU(new_archive_name, "-")) {
-            nafp = stdout;
-#if __MINGW32__
-            setmode(fileno(stdout), O_BINARY);
-#endif
-        }
-        else
-            nafp = build_temporary_file();
+    if (new_archive && old_archive_exist) {
+        fclose(oafp);
+        oafp = NULL;
     }
 
-       /* find needed files when automatic update */
-       if (update_if_newer && cmd_filec == 0)
-               find_update_files(oafp);
+    if (oafp && archive_is_msdos_sfx1(archive_name)) {
+        seek_lha_header(oafp);
+        build_standard_archive_name(new_archive_name_buffer,
+                                    archive_name,
+                                    sizeof(new_archive_name_buffer));
+        new_archive_name = new_archive_name_buffer;
+    }
+    else {
+        new_archive_name = archive_name;
+    }
 
-       /* build new archive file */
-       /* cleaning arguments */
-       cleaning_files(&cmd_filec, &cmd_filev);
-       if (cmd_filec == 0) {
-               if (oafp)
-                       fclose(oafp);
-               if (!noexec && nafp != stdout)
-                       fclose(nafp);
-               return;
-       }
+    /* build temporary file */
+    nafp = NULL;                /* avoid compiler warnings `uninitialized' */
+    if (!noexec)
+        nafp = build_temporary_file();
+
+    /* find needed files when automatic update */
+    if (update_if_newer && cmd_filec == 0)
+        find_update_files(oafp);
+
+    /* build new archive file */
+    /* cleaning arguments */
+    cleaning_files(&cmd_filec, &cmd_filev);
+    if (cmd_filec == 0) {
+        if (oafp)
+            fclose(oafp);
+        if (!noexec)
+            fclose(nafp);
+        return;
+    }
+
+    for (i = 0; i < cmd_filec; i++) {
+        int j;
 
-       for (i = 0; i < cmd_filec; i++) {
         if (strcmp(cmd_filev[i], archive_name) == 0) {
-            int j;
             /* exclude target archive */
             warning("specified file \"%s\" is the generating archive. skip",
                     cmd_filev[i]);
@@ -526,140 +517,151 @@ cmd_add()
             i--;
             continue;
         }
+
+        /* exclude files specified by -x option */
+        for (j = 0; exclude_files && exclude_files[j]; j++) {
+            if (fnmatch(exclude_files[j], basename(cmd_filev[i]),
+                        FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD) == 0)
+                goto next;
+        }
+
         oafp = append_it(cmd_filev[i], oafp, nafp);
+    next:
+        ;
     }
 
-       if (oafp) {
-               old_header = ftell(oafp);
-               while (get_header(oafp, &ahdr)) {
-                       if (noexec)
-                               fseek(oafp, ahdr.packed_size, SEEK_CUR);
-                       else {
-                               fseek(oafp, old_header, SEEK_SET);
-                               copy_old_one(oafp, nafp, &ahdr);
-                       }
-                       old_header = ftell(oafp);
-               }
-               fclose(oafp);
-       }
-       if (!noexec) {
-               write_archive_tail(nafp);
-               new_archive_size = ftell(nafp);
-               if (nafp != stdout) fclose(nafp);
-       }
-
-       /* build backup archive file */
-       if (old_archive_exist && backup_old_archive)
-               build_backup_file();
-
-       report_archive_name_if_different();
-
-    if (nafp != stdout) {
-        /* copy temporary file to new archive file */
-        if (!noexec && rename(temporary_name, new_archive_name) < 0)
-            temporary_to_new_archive_file(new_archive_size);
+    if (oafp) {
+        old_header = ftello(oafp);
+        while (get_header(oafp, &ahdr)) {
+            if (noexec)
+                fseeko(oafp, ahdr.packed_size, SEEK_CUR);
+            else {
+                fseeko(oafp, old_header, SEEK_SET);
+                copy_old_one(oafp, nafp, &ahdr);
+            }
+            old_header = ftello(oafp);
+        }
+        fclose(oafp);
+    }
+
+    new_archive_size = 0;       /* avoid compiler warnings `uninitialized' */
+    if (!noexec) {
+        off_t tmp;
+
+        write_archive_tail(nafp);
+        tmp = ftello(nafp);
+        if (tmp == -1) {
+            warning("ftello(): %s", strerror(errno));
+            new_archive_size = 0;
+        }
+        else
+            new_archive_size = tmp;
+
+        fclose(nafp);
+    }
+
+    /* build backup archive file */
+    if (old_archive_exist && backup_old_archive)
+        build_backup_file();
+
+    report_archive_name_if_different();
 
-        /* set new archive file mode/group */
-        set_archive_file_mode();
+    /* copy temporary file to new archive file */
+    if (!noexec) {
+        if (strcmp(new_archive_name, "-") == 0 ||
+            rename(temporary_name, new_archive_name) < 0) {
+
+            temporary_to_new_archive_file(new_archive_size);
+        }
     }
-       /* remove archived files */
-       if (delete_after_append)
-               remove_files(cmd_filec, cmd_filev);
 
-       return;
+    /* set new archive file mode/group */
+    set_archive_file_mode();
+
+    /* remove archived files */
+    if (delete_after_append)
+        remove_files(cmd_filec, cmd_filev);
+
+    return;
 }
 
 /* ------------------------------------------------------------------------ */
 void
 cmd_delete()
 {
-       FILE           *oafp, *nafp;
-       long            new_archive_size;
-
-       /* open old archive if exist */
-       if ((oafp = open_old_archive()) == NULL)
-               fatal_error("Cannot open archive file \"%s\"", archive_name);
-
-       /* exit if no operation */
-       if (cmd_filec == 0) {
-               fclose(oafp);
-               warning("No files given in argument, do nothing.");
-               return;
-       }
-
-       if (archive_is_msdos_sfx1(archive_name)) {
-               skip_msdos_sfx1_code(oafp);
-               build_standard_archive_name(new_archive_name_buffer, archive_name);
-               new_archive_name = new_archive_name_buffer;
-       }
-       else {
-               new_archive_name = archive_name;
-       }
-
-       /* build temporary file */
-       if (!noexec)
-               nafp = build_temporary_file();
-
-       /* build new archive file */
-       delete(oafp, nafp);
-       fclose(oafp);
-
-       if (!noexec) {
-               write_archive_tail(nafp);
-               new_archive_size = ftell(nafp);
-               fclose(nafp);
-       }
-
-       /* build backup archive file */
+    FILE *oafp, *nafp;
+    off_t new_archive_size;
+
+    /* open old archive if exist */
+    if ((oafp = open_old_archive()) == NULL)
+        fatal_error("Cannot open archive file \"%s\"", archive_name);
+
+    /* exit if no operation */
+    if (cmd_filec == 0) {
+        fclose(oafp);
+        warning("No files given in argument, do nothing.");
+        return;
+    }
+
+    if (archive_is_msdos_sfx1(archive_name)) {
+        seek_lha_header(oafp);
+        build_standard_archive_name(new_archive_name_buffer,
+                                    archive_name,
+                                    sizeof(new_archive_name_buffer));
+        new_archive_name = new_archive_name_buffer;
+    }
+    else {
+        new_archive_name = archive_name;
+    }
+
+    /* build temporary file */
+    nafp = NULL;                /* avoid compiler warnings `uninitialized' */
+    if (!noexec)
+        nafp = build_temporary_file();
+
+    /* build new archive file */
+    delete(oafp, nafp);
+    fclose(oafp);
+
+    new_archive_size = 0;       /* avoid compiler warnings `uninitialized' */
+    if (!noexec) {
+        off_t tmp;
+
+        write_archive_tail(nafp);
+        tmp = ftello(nafp);
+        if (tmp == -1) {
+            warning("ftello(): %s", strerror(errno));
+            new_archive_size = 0;
+        }
+        else
+            new_archive_size = tmp;
+
+        fclose(nafp);
+    }
+
+    /* build backup archive file */
     if (backup_old_archive)
         build_backup_file();
 
-       /* 1999.5.24 t.oka */
-       if(!noexec && new_archive_size <= 1){
-               unlink(temporary_name);
+    /* 1999.5.24 t.oka */
+    if(!noexec && new_archive_size <= 1){
+        unlink(temporary_name);
         if (!backup_old_archive)
             unlink(archive_name);
-               warning("The archive file \"%s\" was removed because it would be empty.", new_archive_name);
-               return;
-       }
+        warning("The archive file \"%s\" was removed because it would be empty.", new_archive_name);
+        return;
+    }
 
-       report_archive_name_if_different();
+    report_archive_name_if_different();
 
-       /* copy temporary file to new archive file */
-       if (!noexec && rename(temporary_name, new_archive_name) < 0)
-               temporary_to_new_archive_file(new_archive_size);
+    /* copy temporary file to new archive file */
+    if (!noexec) {
+        if (rename(temporary_name, new_archive_name) < 0)
+            temporary_to_new_archive_file(new_archive_size);
+    }
 
-       /* set new archive file mode/group */
-       set_archive_file_mode();
+    /* set new archive file mode/group */
+    set_archive_file_mode();
 
-       return;
+    return;
 }
-
-/* for symbolic link name. t.okamoto 96/2/20 */
-int strcmp_filename( str1, str2 )
-char *str1;
-char *str2;
-{
-       char *p, *q;
-
-       p = str1; q = str2;
-       while (*p != 0 && *q != 0) {
-               if (*p == '|') {
-                       if (*q == 0) return 0;
-                       else if (*q != '|') return -1;
-               } else if (*q == '|') {
-                       if (*p == 0) return 0;
-                       else if (*q != '|') return 1;
-               } else if (*p != *q) break;
-               p++; q++;
-       }
-       return (int)*p-(int)*q;
-}
-
-               
-/* Local Variables: */
-/* mode:c */
-/* tab-width:4 */
-/* compile-command:"gcc -c lhadd.c" */
-/* End: */
-/* vi: set tabstop=4: */