home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume11 / lharc / part01 next >
Encoding:
Text File  |  1990-03-10  |  52.9 KB  |  2,260 lines

  1. Newsgroups: comp.sources.misc
  2. From: <rommel@lan.informatik.tu-muenchen.dbp.de>
  3. Message-Id: <9002281326.AA26940@gssiegert1.informatik.tu-muenchen.de>
  4. Subject: v11i017: LHarc 1/2
  5. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  6.  
  7. Posting-number: Volume 11, Issue 17
  8. Submitted-by: <rommel@lan.informatik.tu-muenchen.dbp.de>
  9. Archive-name: lharc/part01
  10.  
  11. #!/bin/sh
  12. # shar:    Shell Archiver  (v1.23)
  13. #
  14. # This is part 1 of a multipart archive                                    
  15. # do not concatenate these parts, unpack them in order with /bin/sh        
  16. #
  17. #    Run the following text with /bin/sh to create:
  18. #      Makefile
  19. #      README
  20. #      clharc.cs
  21. #      clharc.def
  22. #      dir.h
  23. #      dir_dos.c
  24. #      dir_os2.c
  25. #      lharc.c
  26. #      lharc.doc
  27. #      lhio.c
  28. #      lhio.h
  29. #      lzhuf.c
  30. #      mktemp.c
  31. #      pipes.c
  32. #
  33. if test -r s2_seq_.tmp
  34. then echo "Must unpack archives in sequence!"
  35.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  36.      exit 1; fi
  37. echo "x - extracting Makefile (Text)"
  38. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  39. X# Makefile for LHArc UNIX
  40. X#    Copyright(C) MCMLXXXIX  Yooichi.Tagawa
  41. X# V0.01  Alpha Version                1989.05.28  Y.Tagawa
  42. X# V0.02  Alpha Version R2            1989.05.29  Y.Tagawa
  43. X# V0.03  Release #3  Beta Version        1989.07.02  Y.Tagawa
  44. X
  45. X#-----------------------------------------------------------------------
  46. X# DIRECTORY ACCESS DEPENDENDS...
  47. X#  The default (no need swtich) is your machine has
  48. X#  opendir(),readdir(),closedir() library and 'direct' structure used.
  49. X#  If your machine has no opendir (), readdir (), closedir ()
  50. X#    -DNONSYSTEM_DIR_LIBRARY
  51. X#  and add lhdir.o into OBJS macro (see bellow)
  52. X#  If your machine are 'dirent' (not 'direct') structure used,
  53. X#    -DSYSV_SYSTEM_DIR
  54. X#  Otherwise "Give up!"
  55. X#    -DNODIRECTORY
  56. X#
  57. X#-----------------------------------------------------------------------
  58. X# MEMORY ACCESS STUFF
  59. X#  Your machine has no BSTRING library (bcmp,bcopy,bzero).
  60. X#    -DNOBSTRING
  61. X#
  62. X#-----------------------------------------------------------------------
  63. X# TIME STUFF
  64. X#  Your include file '<sys/time.h>' has no 'struct tm',  define this.
  65. X#    -DSYSTIME_HAS_NO_TM
  66. X#
  67. X
  68. X# most of 4.[23]BSD
  69. X#    - vax 4.[23]BSD, SONY NEWS 4.[23]BSD etc.
  70. XSWITCHIES    =
  71. XOBJS        = lharc.o lzhuf.o lhio.o
  72. X
  73. X# sample of System-V
  74. X#    - NEC EWS4800
  75. X#SWITCHIES    = -DNONSYSTEM_DIR_LIBRARY -DSYSTIME_HAS_NO_TM
  76. X#OBJS        = lharc.o lzhuf.o lhio.o lhdir.o
  77. X
  78. XCC        = gcc
  79. XCFLAGS        = $(SWITCHIES)
  80. XLDFLAGS        = -s
  81. X
  82. X#    Xlharc is test binary.  Please rename to lharc at install.
  83. X#    (see install target)
  84. Xall:    xlharc
  85. X
  86. Xxlharc    : $(OBJS)
  87. X    $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS)
  88. X
  89. X#    For Debugging LzHuff module.
  90. Xlzhuf    : lzhuf.c
  91. X    $(CC) $(CFLAGS) -DSELFMAIN -o $* $*.c
  92. X
  93. Xlzhuf.o    lhio.o    : lhio.h
  94. X
  95. Xclean:
  96. X    rm -f core lharc.o lzhuf.o lhdir.o lhio.o lharc.tar lharc.tar.Z
  97. SHAR_EOF
  98. chmod 0666 Makefile || echo "restore of Makefile fails"
  99. echo "x - extracting README (Text)"
  100. sed 's/^X//' << 'SHAR_EOF' > README &&
  101. X                                -*- Text -*-
  102. X
  103. XLHarc UNIX V0.03 Release #3  Beta Version
  104. X
  105. X    This is FREEWARE.  But it's BETA-VERSION.
  106. X
  107. X    Please reply to me.
  108. X
  109. X    Sorry, lharc.doc file are written in JAPANESE (Shift-JIS KANJI)
  110. X
  111. X                        Thank you.
  112. X
  113. X                        Yooichi.Tagawa
  114. X                        Nikkei-MIX ID: y.tagawa
  115. X------------------------------------------------------------------------
  116. X
  117. XHOW TO USE:
  118. X    lharc {axevludmcp}[qnft] archive_file [files or directories...]
  119. X
  120. XCOMMAND:
  121. X    KEY    MEANS                Like as (UNIX ar command)
  122. X    --- ------------------------------    ------------------------------
  123. X    a    Append to archive.              ar r AFILE files...
  124. X    x,e  EXtract from archive.          ar x AFILE [files...]
  125. X    v,l  View/List archive contents.      ar t AFILE [files...]
  126. X    u    append newer files to archive.      ar ru AFILE files...
  127. X    d    Delete from archive.          ar d AFILE files...
  128. X    m    Move to archive.              ar m AFILE files...
  129. X    c    re-construct new archive file.      rm AFILE; ar r AFILE files...
  130. X    p    Print to STANDARD-OUTPUT          ar p AFILE [files...]
  131. X
  132. X
  133. XOPTIONS:
  134. X    q    quiet
  135. X    n    no execute (debugging option)
  136. X    f    force (over write at extract)
  137. X    t    text-mode (this is provisional option)
  138. X
  139. X------------------------------------------------------------------------------
  140. SHAR_EOF
  141. chmod 0666 README || echo "restore of README fails"
  142. echo "x - extracting clharc.cs (Text)"
  143. sed 's/^X//' << 'SHAR_EOF' > clharc.cs &&
  144. X(-W1 lharc.c lhio.c dir_os2.c mktemp.c pipes.c)
  145. X(-W1 -Ox lzhuf.c)
  146. Xsetargv.obj
  147. Xclharc.def
  148. Xclharc.exe
  149. X-as -lb -s0x2000
  150. SHAR_EOF
  151. chmod 0666 clharc.cs || echo "restore of clharc.cs fails"
  152. echo "x - extracting clharc.def (Text)"
  153. sed 's/^X//' << 'SHAR_EOF' > clharc.def &&
  154. XNAME CLHARC WINDOWCOMPAT
  155. XDESCRIPTION 'C-LHarc 1.00 - for MS-DOS and OS/2'
  156. SHAR_EOF
  157. chmod 0666 clharc.def || echo "restore of clharc.def fails"
  158. echo "x - extracting dir.h (Text)"
  159. sed 's/^X//' << 'SHAR_EOF' > dir.h &&
  160. X/*
  161. X * @(#) dir.h 1.4 87/11/06   Public Domain.
  162. X *
  163. X *  A public domain implementation of BSD directory routines for
  164. X *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  165. X *  August 1897
  166. X *  Ported to OS/2 by Kai Uwe Rommel and added scandir prototype
  167. X *  December 1989
  168. X */
  169. X
  170. X#define    rewinddir(dirp)    seekdir(dirp, 0L)
  171. X
  172. X#define    MAXNAMLEN    12
  173. X
  174. Xstruct direct
  175. X{
  176. X    ino_t    d_ino;            /* a bit of a farce */
  177. X    int    d_reclen;        /* more farce */
  178. X    int    d_namlen;        /* length of d_name */
  179. X        char    d_name[MAXNAMLEN + 1];  /* garentee null termination */
  180. X};
  181. X
  182. Xstruct _dircontents
  183. X{
  184. X    char    *_d_entry;
  185. X    struct _dircontents    *_d_next;
  186. X};
  187. X
  188. Xtypedef struct _dirdesc
  189. X{
  190. X    int        dd_id;    /* uniquely identify each open directory */
  191. X    long        dd_loc;    /* where we are in directory entry is this */
  192. X    struct _dircontents    *dd_contents;    /* pointer to contents of dir */
  193. X    struct _dircontents    *dd_cp;    /* pointer to current position */
  194. X} DIR;
  195. X
  196. Xextern  DIR            *opendir(char *);
  197. Xextern  struct direct  *readdir(DIR *);
  198. Xextern  void            seekdir(DIR *, long);
  199. Xextern  long            telldir(DIR *);
  200. Xextern  void            closedir(DIR *);
  201. X
  202. Xextern  int             scandir(char *, struct direct ***,
  203. X                                int (*)(struct direct *), int (*)());
  204. SHAR_EOF
  205. chmod 0666 dir.h || echo "restore of dir.h fails"
  206. echo "x - extracting dir_dos.c (Text)"
  207. sed 's/^X//' << 'SHAR_EOF' > dir_dos.c &&
  208. X/*
  209. X * @(#)dir.c 1.4 87/11/06    Public Domain.
  210. X *
  211. X *  A public domain implementation of BSD directory routines for
  212. X *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  213. X *  August 1897
  214. X *  Modified to use modern MS C library functions by Kai Uwe Rommel
  215. X *  December 1989
  216. X */
  217. X
  218. X#include    <sys/types.h>
  219. X#include    <sys/stat.h>
  220. X#include    <sys/dir.h>
  221. X#include    <malloc.h>
  222. X#include    <string.h>
  223. X
  224. X#include        <dos.h>
  225. X
  226. X#ifndef    NULL
  227. X# define    NULL    0
  228. X#endif    /* NULL */
  229. X
  230. X#ifndef    MAXPATHLEN
  231. X# define    MAXPATHLEN    255
  232. X#endif    /* MAXPATHLEN */
  233. X
  234. X/* attribute stuff */
  235. X#define    A_RONLY        0x01
  236. X#define    A_HIDDEN    0x02
  237. X#define    A_SYSTEM    0x04
  238. X#define    A_LABEL        0x08
  239. X#define    A_DIR        0x10
  240. X#define    A_ARCHIVE    0x20
  241. X
  242. X
  243. X#define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  244. X
  245. X#define ATTRIBUTES      (A_DIR)
  246. X/* #define ATTRIBUTES      (A_DIR | A_HIDDEN | A_SYSTEM) */
  247. X/* #define ATTRIBUTES      (A_RONLY | A_SYSTEM | A_DIR) */
  248. X
  249. Xstatic  char    *getdirent(char *);
  250. Xstatic    void    free_dircontents(struct _dircontents *);
  251. X
  252. Xstatic struct find_t find;
  253. X
  254. X
  255. XDIR    *
  256. Xopendir(name)
  257. X    char    *name;
  258. X{
  259. X    struct    stat        statb;
  260. X    DIR            *dirp;
  261. X    char            c;
  262. X    char            *s;
  263. X    struct _dircontents    *dp;
  264. X    char            nbuf[MAXPATHLEN + 1];
  265. X
  266. X    if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  267. X        return (DIR *) NULL;
  268. X    if (Newisnull(dirp, DIR))
  269. X        return (DIR *) NULL;
  270. X    if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  271. X        (void) strcat(strcpy(nbuf, name), "\\*.*");
  272. X    else
  273. X        (void) strcat(strcpy(nbuf, name), "*.*");
  274. X    dirp->dd_loc = 0;
  275. X        dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  276. X
  277. X    if ((s = getdirent(nbuf)) == (char *) NULL)
  278. X        return dirp;
  279. X    do {
  280. X        if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  281. X            malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  282. X        {
  283. X            if (dp)
  284. X                free((char *) dp);
  285. X            free_dircontents(dirp->dd_contents);
  286. X            return (DIR *) NULL;
  287. X        }
  288. X        if (dirp->dd_contents)
  289. X            dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  290. X        else
  291. X            dirp->dd_contents = dirp->dd_cp = dp;
  292. X        (void) strcpy(dp->_d_entry, s);
  293. X        dp->_d_next = (struct _dircontents *) NULL;
  294. X        } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  295. X
  296. X    dirp->dd_cp = dirp->dd_contents;
  297. X
  298. X    return dirp;
  299. X}
  300. X
  301. Xvoid
  302. Xclosedir(dirp)
  303. X    DIR    *dirp;
  304. X{
  305. X    free_dircontents(dirp->dd_contents);
  306. X    free((char *) dirp);
  307. X}
  308. X
  309. Xstruct direct    *
  310. Xreaddir(dirp)
  311. X    DIR    *dirp;
  312. X{
  313. X    static    struct direct    dp;
  314. X
  315. X    if (dirp->dd_cp == (struct _dircontents *) NULL)
  316. X        return (struct direct *) NULL;
  317. X    dp.d_namlen = dp.d_reclen =
  318. X        strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  319. X    strlwr(dp.d_name);        /* JF */
  320. X    dp.d_ino = 0;
  321. X    dirp->dd_cp = dirp->dd_cp->_d_next;
  322. X    dirp->dd_loc++;
  323. X
  324. X    return &dp;
  325. X}
  326. X
  327. Xvoid
  328. Xseekdir(dirp, off)
  329. X    DIR    *dirp;
  330. X    long    off;
  331. X{
  332. X    long            i = off;
  333. X    struct _dircontents    *dp;
  334. X
  335. X    if (off < 0)
  336. X        return;
  337. X    for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  338. X        ;
  339. X    dirp->dd_loc = off - (i + 1);
  340. X    dirp->dd_cp = dp;
  341. X}
  342. X
  343. Xlong
  344. Xtelldir(dirp)
  345. X    DIR    *dirp;
  346. X{
  347. X    return dirp->dd_loc;
  348. X}
  349. X
  350. Xstatic    void
  351. Xfree_dircontents(dp)
  352. X    struct    _dircontents    *dp;
  353. X{
  354. X    struct _dircontents    *odp;
  355. X
  356. X    while (dp) {
  357. X        if (dp->_d_entry)
  358. X            free(dp->_d_entry);
  359. X        dp = (odp = dp)->_d_next;
  360. X        free((char *) odp);
  361. X    }
  362. X}
  363. X
  364. Xstatic char *getdirent(dir)
  365. Xchar *dir;
  366. X{
  367. X  int done;
  368. X
  369. X  if (dir != (char *) NULL)
  370. X    done = _dos_findfirst(dir, ATTRIBUTES, &find);
  371. X  else                                  /* get next entry */
  372. X    done = _dos_findnext(&find);
  373. X
  374. X  if (done==0)
  375. X    return find.name;
  376. X  else
  377. X    return (char *) NULL;
  378. X}
  379. X
  380. X
  381. Xsetfilemode(char *name, unsigned attr)
  382. X{
  383. X  _dos_setfileattr(name, attr);
  384. X}
  385. X
  386. Xgetfilemode(char *name, unsigned *attr)
  387. X{
  388. X  _dos_getfileattr(name, attr);
  389. X}
  390. SHAR_EOF
  391. chmod 0666 dir_dos.c || echo "restore of dir_dos.c fails"
  392. echo "x - extracting dir_os2.c (Text)"
  393. sed 's/^X//' << 'SHAR_EOF' > dir_os2.c &&
  394. X/*
  395. X * @(#)dir.c 1.4 87/11/06    Public Domain.
  396. X *
  397. X *  A public domain implementation of BSD directory routines for
  398. X *  MS-DOS.  Written by Michael Rendell ({uunet,utai}michael@garfield),
  399. X *  August 1897
  400. X *  Ported to OS/2 by Kai Uwe Rommel
  401. X *  December 1989
  402. X */
  403. X
  404. X#include    <sys/types.h>
  405. X#include    <sys/stat.h>
  406. X#include    <sys/dir.h>
  407. X#include    <malloc.h>
  408. X#include    <string.h>
  409. X
  410. X#define INCL_NOPM
  411. X#include <os2.h>
  412. X
  413. X#ifndef    NULL
  414. X# define    NULL    0
  415. X#endif    /* NULL */
  416. X
  417. X#ifndef    MAXPATHLEN
  418. X# define    MAXPATHLEN    255
  419. X#endif    /* MAXPATHLEN */
  420. X
  421. X/* attribute stuff */
  422. X#define    A_RONLY        0x01
  423. X#define    A_HIDDEN    0x02
  424. X#define    A_SYSTEM    0x04
  425. X#define    A_LABEL        0x08
  426. X#define    A_DIR        0x10
  427. X#define    A_ARCHIVE    0x20
  428. X
  429. X
  430. X#define Newisnull(a, t) ((a = (t *) malloc(sizeof(t))) == (t *) NULL)
  431. X
  432. X#define ATTRIBUTES      (A_DIR)
  433. X/* #define ATTRIBUTES      (A_DIR | A_HIDDEN | A_SYSTEM) */
  434. X/* #define ATTRIBUTES      (A_RONLY | A_SYSTEM | A_DIR) */
  435. X
  436. Xstatic  char    *getdirent(char *);
  437. Xstatic    void    free_dircontents(struct _dircontents *);
  438. X
  439. Xstatic HDIR hdir;
  440. Xstatic USHORT count;
  441. Xstatic FILEFINDBUF find;
  442. X
  443. X
  444. XDIR    *
  445. Xopendir(name)
  446. X    char    *name;
  447. X{
  448. X    struct    stat        statb;
  449. X    DIR            *dirp;
  450. X    char            c;
  451. X    char            *s;
  452. X    struct _dircontents    *dp;
  453. X    char            nbuf[MAXPATHLEN + 1];
  454. X
  455. X    if (stat(name, &statb) < 0 || (statb.st_mode & S_IFMT) != S_IFDIR)
  456. X        return (DIR *) NULL;
  457. X    if (Newisnull(dirp, DIR))
  458. X        return (DIR *) NULL;
  459. X    if (*name && (c = name[strlen(name) - 1]) != '\\' && c != '/')
  460. X        (void) strcat(strcpy(nbuf, name), "\\*.*");
  461. X    else
  462. X        (void) strcat(strcpy(nbuf, name), "*.*");
  463. X    dirp->dd_loc = 0;
  464. X        dirp->dd_contents = dirp->dd_cp = (struct _dircontents *) NULL;
  465. X
  466. X    if ((s = getdirent(nbuf)) == (char *) NULL)
  467. X        return dirp;
  468. X    do {
  469. X        if (Newisnull(dp, struct _dircontents) || (dp->_d_entry =
  470. X            malloc((unsigned) (strlen(s) + 1))) == (char *) NULL)
  471. X        {
  472. X            if (dp)
  473. X                free((char *) dp);
  474. X            free_dircontents(dirp->dd_contents);
  475. X            return (DIR *) NULL;
  476. X        }
  477. X        if (dirp->dd_contents)
  478. X            dirp->dd_cp = dirp->dd_cp->_d_next = dp;
  479. X        else
  480. X            dirp->dd_contents = dirp->dd_cp = dp;
  481. X        (void) strcpy(dp->_d_entry, s);
  482. X        dp->_d_next = (struct _dircontents *) NULL;
  483. X        } while ((s = getdirent((char *) NULL)) != (char *) NULL);
  484. X
  485. X    dirp->dd_cp = dirp->dd_contents;
  486. X
  487. X    return dirp;
  488. X}
  489. X
  490. Xvoid
  491. Xclosedir(dirp)
  492. X    DIR    *dirp;
  493. X{
  494. X    free_dircontents(dirp->dd_contents);
  495. X    free((char *) dirp);
  496. X}
  497. X
  498. Xstruct direct    *
  499. Xreaddir(dirp)
  500. X    DIR    *dirp;
  501. X{
  502. X    static    struct direct    dp;
  503. X
  504. X    if (dirp->dd_cp == (struct _dircontents *) NULL)
  505. X        return (struct direct *) NULL;
  506. X    dp.d_namlen = dp.d_reclen =
  507. X        strlen(strcpy(dp.d_name, dirp->dd_cp->_d_entry));
  508. X    strlwr(dp.d_name);        /* JF */
  509. X    dp.d_ino = 0;
  510. X    dirp->dd_cp = dirp->dd_cp->_d_next;
  511. X    dirp->dd_loc++;
  512. X
  513. X    return &dp;
  514. X}
  515. X
  516. Xvoid
  517. Xseekdir(dirp, off)
  518. X    DIR    *dirp;
  519. X    long    off;
  520. X{
  521. X    long            i = off;
  522. X    struct _dircontents    *dp;
  523. X
  524. X    if (off < 0)
  525. X        return;
  526. X    for (dp = dirp->dd_contents ; --i >= 0 && dp ; dp = dp->_d_next)
  527. X        ;
  528. X    dirp->dd_loc = off - (i + 1);
  529. X    dirp->dd_cp = dp;
  530. X}
  531. X
  532. Xlong
  533. Xtelldir(dirp)
  534. X    DIR    *dirp;
  535. X{
  536. X    return dirp->dd_loc;
  537. X}
  538. X
  539. Xstatic    void
  540. Xfree_dircontents(dp)
  541. X    struct    _dircontents    *dp;
  542. X{
  543. X    struct _dircontents    *odp;
  544. X
  545. X    while (dp) {
  546. X        if (dp->_d_entry)
  547. X            free(dp->_d_entry);
  548. X        dp = (odp = dp)->_d_next;
  549. X        free((char *) odp);
  550. X    }
  551. X}
  552. X
  553. Xstatic char *getdirent(dir)
  554. Xchar *dir;
  555. X{
  556. X  int done;
  557. X
  558. X  if (dir != (char *) NULL)
  559. X  {                                     /* get first entry */
  560. X    hdir = HDIR_CREATE;
  561. X    count = 1;
  562. X    done = DosFindFirst(dir, &hdir, ATTRIBUTES,
  563. X                        &find, sizeof(find), &count, 0L);
  564. X  }
  565. X  else                                  /* get next entry */
  566. X    done = DosFindNext(hdir, &find, sizeof(find), &count);
  567. X
  568. X  if (done==0)
  569. X    return find.achName;
  570. X  else
  571. X  {
  572. X    DosFindClose(hdir);
  573. X    return (char *) NULL;
  574. X  }
  575. X}
  576. X
  577. X
  578. Xsetfilemode(char *name, unsigned attr)
  579. X{
  580. X  DosSetFileMode(name, attr, 0L);
  581. X}
  582. X
  583. Xgetfilemode(char *name, unsigned *attr)
  584. X{
  585. X  DosQFileMode(name, (PUSHORT) attr, 0L);
  586. X}
  587. SHAR_EOF
  588. chmod 0666 dir_os2.c || echo "restore of dir_os2.c fails"
  589. echo "x - extracting lharc.c (Text)"
  590. sed 's/^X//' << 'SHAR_EOF' > lharc.c &&
  591. X/*----------------------------------------------------------------------*/
  592. X/*        LHarc Archiver Driver for UNIX                */
  593. X/*                                    */
  594. X/*        Copyright(C) MCMLXXXIX  Yooichi.Tagawa            */
  595. X/*        Thanks to H.Yoshizaki. (MS-DOS LHarc)            */
  596. X/*                                    */
  597. X/*  V0.00  Original                1988.05.23  Y.Tagawa    */
  598. X/*  V0.01  Alpha Version (for 4.2BSD)        1989.05.28  Y.Tagawa    */
  599. X/*  V0.02  Alpha Version Rel.2            1989.05.29  Y.Tagawa    */
  600. X/*  V0.03  Release #3  Beta Version        1989.07.02  Y.Tagawa    */
  601. X/*  V0.03a Fix few bug                          1989.07.03  Y.Tagawa    */
  602. X/*  V0.04  A lot of bugs fixed, strict mode     1990.01.13  Kai Uwe Rommel */
  603. X/*  V1.00  f and t commands, v option added     1990.01.27  Kai Uwe Rommel */
  604. X/*----------------------------------------------------------------------*/
  605. X
  606. X
  607. X#include <stdio.h>
  608. X#include <ctype.h>
  609. X#include <signal.h>
  610. X#include <sys/types.h>
  611. X#include <sys/stat.h>
  612. X
  613. X#ifdef PROF
  614. X#include <profile.h>
  615. X#endif
  616. X
  617. X#define STRICT
  618. X#define FASTCOPY
  619. X
  620. X#ifdef MSDOS
  621. X#include <fcntl.h>
  622. Xextern unsigned char _osmode;
  623. Xextern FILE *popen();
  624. Xextern pclose();
  625. X#define ftruncate chsize
  626. X#define mktemp Mktemp
  627. X#define SYSTIME_HAS_NO_TM
  628. X#define NOBSTRING
  629. X#define SYSNAME (_osmode ? "OS/2" : "MS-DOS")
  630. X#define OUR_EXTEND (_osmode ? EXTEND_OS2 : EXTEND_MSDOS)
  631. X#define FILENAME_LENGTH 128
  632. X#define NULLFILE "nul"
  633. X#define TMP_FILENAME_TEMPLATE "lhXXXXXX"
  634. X#define NOT_COMPATIBLE_MODE
  635. X#define RMODE "rb"
  636. X#define WMODE "wb"
  637. X#else
  638. X#include <sys/file.h>
  639. X#include <sys/time.h>
  640. X#define SYSNAME "UNIX"
  641. X#define OUR_EXTEND EXTEND_UNIX
  642. X#define FILENAME_LENGTH    1024
  643. X#define NULLFILE "/dev/null"
  644. X#define RMODE "r"
  645. X#define WMODE "w"
  646. X#endif
  647. X
  648. X#ifdef SYSTIME_HAS_NO_TM
  649. X/* most of System V,  define SYSTIME_HAS_NO_TM */
  650. X#include <time.h>
  651. X#endif
  652. X
  653. X/* #include <strings.h> */
  654. X#include <string.h>
  655. X
  656. X
  657. X/*----------------------------------------------------------------------*/
  658. X/*            DIRECTORY ACCESS STUFF                */
  659. X/*----------------------------------------------------------------------*/
  660. X#ifndef NODIRECTORY
  661. X#ifdef SYSV_SYSTEM_DIR
  662. X
  663. X#include <dirent.h>
  664. X#define DIRENTRY    struct dirent
  665. X#define NAMREN(p)    strlen (p->d_name)
  666. X
  667. X#else    /* not SYSV_SYSTEM_DIR */
  668. X
  669. X#ifdef NONSYSTEM_DIR_LIBRARY
  670. X#include "lhdir.h"
  671. X#else    /* not NONSYSTEM_DIR_LIBRARY */
  672. X#include <sys/dir.h>
  673. X#endif    /* not NONSYSTEM_DIR_LIBRARY */
  674. X
  675. X#define DIRENTRY    struct direct
  676. X#define NAMLEN(p)    p->d_namlen
  677. X
  678. Xextern DIR *opendir ();
  679. Xextern struct direct *readdir ();
  680. X
  681. X#endif    /* not SYSV_SYSTEM_DIR */
  682. X#endif
  683. X
  684. X/*----------------------------------------------------------------------*/
  685. X/*            FILE ATTRIBUTES                    */
  686. X/*----------------------------------------------------------------------*/
  687. X
  688. X/* If file mode is not compatible between your Machine/OS and
  689. X   LHarc standard UNIX file mode.
  690. X   (See UNIX Manual stat(1), <sys/stat.h>,
  691. X   and/or below UNIX_* difinitions. ) */
  692. X/* #define NOT_COMPATIBLE_MODE */
  693. X
  694. X
  695. X/*----------------------------------------------------------------------*/
  696. X/*            MEMORY FUNCTIONS                 */
  697. X/*----------------------------------------------------------------------*/
  698. X
  699. X#ifdef NOBSTRING
  700. X#ifdef __ANSI__
  701. X#include "mem.h"
  702. X#define bcmp(a,b,n) memcmp ((a),(b),(n))
  703. X#define bcopy(s,d,n) memmove((d),(s),(n))
  704. X#define bzero(d,n) memset((d),0,(n))
  705. X#else    /* not __ANSI__ */
  706. X#include "memory.h"
  707. X#define bcmp(a,b,n) memcmp ((a),(b),(n))
  708. X#define bcopy(s,d,n) memcpy ((d),(s),(n))    /* movmem((s),(d),(n)) */
  709. X#define bzero(d,n) memset((d),0,(n))
  710. X#endif    /* not __ANSI__ */
  711. X#endif    /* NOBSTRING */
  712. X
  713. X
  714. X/*----------------------------------------------------------------------*/
  715. X/*            YOUR CUSTOMIZIES                */
  716. X/*----------------------------------------------------------------------*/
  717. X/* These difinitions are changable to you like. */
  718. X/* #define ARCHIVENAME_EXTENTION    ".LZH"        */
  719. X/* #define TMP_FILENAME_TEMPLATE    "/tmp/lhXXXXXX"    */
  720. X/* #define BACKUPNAME_EXTENTION        ".BAK"        */
  721. X/* #define MULTIBYTE_CHAR                */
  722. X
  723. X
  724. X
  725. X#define SJC_FIRST_P(c)            \
  726. X  (((unsigned char)(c) >= 0x80) &&    \
  727. X   (((unsigned char)(c) < 0xa0) ||    \
  728. X    ((unsigned char)(c) >= 0xe0) &&    \
  729. X    ((unsigned char)(c) < 0xfd)))
  730. X#define SJC_SECOND_P(c)            \
  731. X  (((unsigned char)(c) >= 0x40) &&    \
  732. X   ((unsigned char)(c) < 0xfd) &&    \
  733. X   ((ungigned char)(c) != 0x7f))
  734. X
  735. X#ifdef MULTIBYTE_CHAR
  736. X#define MULTIBYTE_FIRST_P    SJC_FIRST_P
  737. X#define MULTIBYTE_SECOND_P    SJC_SECOND_P
  738. X#endif
  739. X
  740. X/*----------------------------------------------------------------------*/
  741. X/*            OTHER DIFINITIONS                */
  742. X/*----------------------------------------------------------------------*/
  743. X
  744. X#ifndef SEEK_SET
  745. X#define SEEK_SET    0
  746. X#define SEEK_CUR    1
  747. X#define SEEK_END    2
  748. X#endif
  749. X
  750. X
  751. X/* non-integral functions */
  752. Xextern struct tm *localtime ();
  753. Xextern char *getenv ();
  754. Xextern char *malloc ();
  755. Xextern char *realloc ();
  756. X
  757. Xextern int rson[];
  758. X
  759. X/* external variables */
  760. Xextern int errno;
  761. X
  762. X
  763. X#define    FALSE    0
  764. X#define TRUE    1
  765. Xtypedef int boolean;
  766. X
  767. X
  768. X/*----------------------------------------------------------------------*/
  769. X/*        LHarc FILE DIFINITIONS                    */
  770. X/*----------------------------------------------------------------------*/
  771. X#define METHOD_TYPE_STRAGE    5
  772. X#define LZHUFF0_METHOD        "-lh0-"
  773. X#define LZHUFF1_METHOD        "-lh1-"
  774. X#define LARC4_METHOD        "-lz4-"
  775. X#define LARC5_METHOD        "-lz5-"
  776. X
  777. X#define I_HEADER_SIZE            0
  778. X#define I_HEADER_CHECKSUM        1
  779. X#define I_METHOD            2
  780. X#define I_PACKED_SIZE            7
  781. X#define I_ORIGINAL_SIZE            11
  782. X#define I_LAST_MODIFIED_STAMP        15
  783. X#define I_ATTRIBUTE            19
  784. X#define I_NAME_LENGTH            21
  785. X#define I_NAME                22
  786. X
  787. X#define I_CRC                22 /* + name_length */
  788. X#define I_EXTEND_TYPE            24 /* + name_length */
  789. X#define I_MINOR_VERSION            25 /* + name_length */
  790. X#define I_UNIX_LAST_MODIFIED_STAMP    26 /* + name_length */
  791. X#define I_UNIX_MODE            30 /* + name_length */
  792. X#define I_UNIX_UID            32 /* + name_length */
  793. X#define I_UNIX_GID            34 /* + name_length */
  794. X#define I_UNIX_EXTEND_BOTTOM        36 /* + name_length */
  795. X
  796. X
  797. X
  798. X#define EXTEND_GENERIC  0
  799. X#define EXTEND_UNIX    'U'
  800. X#define EXTEND_MSDOS    'M'
  801. X#define EXTEND_MACOS    'm'
  802. X#define EXTEND_OS9    '9'
  803. X#define EXTEND_OS2    '2'
  804. X#define EXTEND_OS68K    'K'
  805. X#define EXTEND_OS386    '3'
  806. X#define EXTEND_HUMAN    'H'
  807. X#define EXTEND_CPM    'C'
  808. X#define EXTEND_FLEX    'F'
  809. X
  810. X#define GENERIC_ATTRIBUTE        0x20
  811. X#define GENERIC_DIRECTORY_ATTRIBUTE    0x10
  812. X
  813. X#define CURRENT_UNIX_MINOR_VERSION    0x00
  814. X
  815. X
  816. X
  817. Xtypedef struct LzHeader {
  818. X  unsigned char        header_size;
  819. X  char            method[METHOD_TYPE_STRAGE];
  820. X  long            packed_size;
  821. X  long            original_size;
  822. X  long            last_modified_stamp;
  823. X  unsigned short    attribute;
  824. X  char            name[256];
  825. X  unsigned short    crc;
  826. X  boolean        has_crc;
  827. X  unsigned char        extend_type;
  828. X  unsigned char        minor_version;
  829. X  /*  extend_type == EXTEND_UNIX  and convert from other type. */
  830. X  time_t        unix_last_modified_stamp;
  831. X  unsigned short    unix_mode;
  832. X  unsigned short    unix_uid;
  833. X  unsigned short    unix_gid;
  834. X} LzHeader;
  835. X
  836. X#define UNIX_FILE_TYPEMASK    0170000
  837. X#define UNIX_FILE_REGULAR    0100000
  838. X#define UNIX_FILE_DIRECTORY    0040000
  839. X#define UNIX_SETUID        0004000
  840. X#define UNIX_SETGID        0002000
  841. X#define UNIX_STYCKYBIT        0001000
  842. X#define UNIX_OWNER_READ_PERM    0000400
  843. X#define UNIX_OWNER_WRITE_PERM    0000200
  844. X#define UNIX_OWNER_EXEC_PERM    0000100
  845. X#define UNIX_GROUP_READ_PERM    0000040
  846. X#define UNIX_GROUP_WRITE_PERM    0000020
  847. X#define UNIX_GROUP_EXEC_PERM    0000010
  848. X#define UNIX_OTHER_READ_PERM    0000004
  849. X#define UNIX_OTHER_WRITE_PERM    0000002
  850. X#define UNIX_OTHER_EXEC_PERM    0000001
  851. X#define UNIX_RW_RW_RW        0000666
  852. X
  853. X#define LZHEADER_STRAGE        256
  854. X
  855. X/*----------------------------------------------------------------------*/
  856. X/*        PROGRAM                         */
  857. X/*----------------------------------------------------------------------*/
  858. X
  859. X
  860. X#define CMD_UNKNOWN    0
  861. X#define CMD_EXTRACT    1
  862. X#define CMD_APPEND    2
  863. X#define CMD_VIEW    3
  864. X
  865. Xint      cmd = CMD_UNKNOWN;
  866. Xchar     **cmd_filev;
  867. Xint      cmd_filec;
  868. Xchar     *archive_name;
  869. X
  870. Xchar     expanded_archive_name[FILENAME_LENGTH];
  871. Xchar     temporary_name[FILENAME_LENGTH];
  872. Xchar     pager[FILENAME_LENGTH];
  873. X
  874. X
  875. X/* options */
  876. Xboolean    quiet = FALSE;
  877. Xboolean    text_mode = FALSE;
  878. X/*boolean  verbose = FALSE; */
  879. Xboolean  noexec = FALSE; /* debugging option */
  880. Xboolean  force = FALSE;
  881. Xboolean  prof = FALSE;
  882. X
  883. X
  884. X/* view flags */
  885. Xboolean  long_format_listing = FALSE;
  886. X
  887. X/* extract flags */
  888. Xboolean  output_to_test = FALSE;
  889. Xboolean  output_to_stdout = FALSE;
  890. X
  891. X/* append flags */
  892. Xboolean  new_archive = FALSE;
  893. Xboolean  update_if_newer = FALSE;
  894. Xboolean  update_freshen = FALSE;
  895. Xboolean  delete_after_append = FALSE;
  896. Xboolean  delete_from_archive = FALSE;
  897. X
  898. Xboolean  remove_temporary_at_error = FALSE;
  899. X
  900. X
  901. X/*----------------------------------------------------------------------*/
  902. X/* NOTES :    Text File Format                    */
  903. X/*    GENERATOR        NewLine                    */
  904. X/*    [generic]        0D 0A                    */
  905. X/*    [MS-DOS]        0D 0A                    */
  906. X/*    [MacOS]            0D                    */
  907. X/*    [UNIX]            0A                    */
  908. X/*----------------------------------------------------------------------*/
  909. X
  910. Xchar *myname;
  911. X
  912. X
  913. Xvoid userbreak(void)
  914. X{
  915. X    error("Interrupt.");
  916. X}
  917. X
  918. X
  919. Xmain (argc, argv)
  920. X     int argc;
  921. X     char *argv[];
  922. X{
  923. X  char *p;
  924. X
  925. X  myname = argv[0];
  926. X  signal(SIGINT, userbreak);
  927. X
  928. X#ifdef PROF
  929. X  PROFINIT(PT_USER|PT_USEKP, NULL);
  930. X  PROFCLEAR(PT_USER);
  931. X  PROFON(PT_USER);
  932. X#endif
  933. X
  934. X  if (argc < 3)
  935. X    print_tiny_usage_and_exit ();
  936. X
  937. X  /* commands */
  938. X#ifdef MSDOS
  939. X  switch (tolower(argv[1][0]))
  940. X#else
  941. X  switch (argv[1][0])
  942. X#endif
  943. X    {
  944. X    case 'x':
  945. X    case 'e':
  946. X      cmd = CMD_EXTRACT;
  947. X      break;
  948. X
  949. X    case 't':
  950. X      output_to_test = TRUE;
  951. X      cmd = CMD_EXTRACT;
  952. X      break;
  953. X
  954. X    case 'p':
  955. X      output_to_stdout = TRUE;
  956. X      cmd = CMD_EXTRACT;
  957. X      break;
  958. X
  959. X    case 'c':
  960. X      new_archive = TRUE;
  961. X      cmd = CMD_APPEND;
  962. X      break;
  963. X
  964. X    case 'a':
  965. X      cmd = CMD_APPEND;
  966. X      break;
  967. X
  968. X    case 'd':
  969. X      delete_from_archive = TRUE;
  970. X      cmd = CMD_APPEND;
  971. X      break;
  972. X
  973. X    case 'u':
  974. X      update_if_newer = TRUE;
  975. X      cmd = CMD_APPEND;
  976. X      break;
  977. X
  978. X    case 'f':
  979. X      update_if_newer = update_freshen = TRUE;
  980. X      cmd = CMD_APPEND;
  981. X      break;
  982. X
  983. X    case 'm':
  984. X      delete_after_append = TRUE;
  985. X      cmd = CMD_APPEND;
  986. X      break;
  987. X
  988. X    case 'v':
  989. X      cmd = CMD_VIEW;
  990. X      break;
  991. X
  992. X    case 'l':
  993. X      long_format_listing = TRUE;
  994. X      cmd = CMD_VIEW;
  995. X      break;
  996. X
  997. X    case 'h':
  998. X    default:
  999. X      print_tiny_usage_and_exit ();
  1000. X    }
  1001. X
  1002. X  /* options */
  1003. X  p = &argv[1][1];
  1004. X  for (p = &argv[1][1]; *p; p++)
  1005. X    {
  1006. X#ifdef MSDOS
  1007. X      switch (tolower(*p))
  1008. X#else
  1009. X      switch (*p)
  1010. X#endif
  1011. X    {
  1012. X    case 'q':    quiet = TRUE; break;
  1013. X    case 'f':    force = TRUE; break;
  1014. X/*      case 'p':       prof = TRUE; break; */
  1015. X/*      case 'v':       verbose = TRUE; break; */
  1016. X        case 'v':       strcpy(pager, p + 1); *(p + 1) = 0; break;
  1017. X    case 't':    text_mode = TRUE; break;
  1018. X    case 'n':    noexec = TRUE; break;
  1019. X
  1020. X    default:
  1021. X          fprintf (stderr, "unknown option '%c'.\n", *p);
  1022. X      exit (1);
  1023. X        }
  1024. X    }
  1025. X
  1026. X  /* archive file name */
  1027. X  archive_name = argv[2];
  1028. X
  1029. X  /* target file name */
  1030. X  cmd_filec = argc - 3;
  1031. X  cmd_filev = argv + 3;
  1032. X  sort_files ();
  1033. X
  1034. X  switch (cmd)
  1035. X    {
  1036. X    case CMD_EXTRACT:    cmd_extract ();    break;
  1037. X    case CMD_APPEND:    cmd_append ();    break;
  1038. X    case CMD_VIEW:    cmd_view ();    break;
  1039. X    }
  1040. X
  1041. X#ifdef PROF
  1042. X  PROFOFF(PT_USER);
  1043. X  PROFDUMP(PT_USER, "profile.out");
  1044. X  PROFFREE(PT_USER);
  1045. X#endif
  1046. X
  1047. X  exit (0);
  1048. X}
  1049. X
  1050. Xprint_tiny_usage_and_exit ()
  1051. X{
  1052. X  printf("\nC-LHarc for %s Version 1.00   (C) 1989-1990 Y.Tagawa, Kai Uwe Rommel\n"
  1053. X         "\nUsage: %s {axevlufdmctp}[qnftv] archive_file [files or directories...]\n",
  1054. X         SYSNAME, myname);
  1055. X  printf("\nCommands:                    Options:\n"
  1056. X         "  a   Append                   q   quiet\n"
  1057. X         "  x,e EXtract                  n   no execute\n"
  1058. X         "  v,l View/List                f   force (over write at extract)\n"
  1059. X         "  u   Update                   t   files are TEXT files\n"
  1060. X         "  f   Freshen                  v<pager>  use file pager for p command\n"
  1061. X         "  d   Delete\n"
  1062. X         "  m   Move\n"
  1063. X         "  c   re-Construct new archive\n"
  1064. X         "  t   Test archive\n"
  1065. X         "  p   Print to STDOUT\n");
  1066. X  exit (1);
  1067. X}
  1068. X
  1069. Xmessage (title, msg)
  1070. X     char *title, *msg;
  1071. X{
  1072. X  fprintf (stderr, "%s ", myname);
  1073. X  if (errno == 0)
  1074. X    fprintf (stderr, "%s %s\n", title, msg);
  1075. X  else
  1076. X    perror (msg);
  1077. X}
  1078. X
  1079. Xwarning (msg)
  1080. X     char *msg;
  1081. X{
  1082. X  message ("Warning:", msg);
  1083. X}
  1084. X
  1085. Xerror (msg)
  1086. X     char *msg;
  1087. X{
  1088. X  message ("Error:", msg);
  1089. X
  1090. X  if (remove_temporary_at_error)
  1091. X  {
  1092. X#ifdef MSDOS
  1093. X    fcloseall();
  1094. X#endif
  1095. X    unlink (temporary_name);
  1096. X  }
  1097. X
  1098. X  exit (1);
  1099. X}
  1100. X
  1101. Xchar *writting_filename;
  1102. Xchar *reading_filename;
  1103. X
  1104. Xwrite_error ()
  1105. X{
  1106. X  error (writting_filename);
  1107. X}
  1108. X
  1109. Xread_error ()
  1110. X{
  1111. X  error (reading_filename);
  1112. X}
  1113. X
  1114. X
  1115. X
  1116. X/*----------------------------------------------------------------------*/
  1117. X/*                                    */
  1118. X/*----------------------------------------------------------------------*/
  1119. X
  1120. Xboolean expand_archive_name (dst, src)
  1121. X     char *dst, *src;
  1122. X{
  1123. X  register char *p, *dot;
  1124. X
  1125. X  strcpy (dst, src);
  1126. X
  1127. X  for (p = dst, dot = (char*)0; *p; p++)
  1128. X    if (*p == '.')
  1129. X      dot = p;
  1130. X    else if (*p == '/' || *p == '\\')
  1131. X      dot = (char*)0;
  1132. X
  1133. X  if (dot)
  1134. X    p = dot;
  1135. X
  1136. X#ifdef ARCHIVENAME_EXTENTION
  1137. X  strcpy (p, ARCHIVENAME_EXTENTION);
  1138. X#else
  1139. X  strcpy (p, ".lzh");
  1140. X#endif
  1141. X  return (strcmp (dst, src) != 0);
  1142. X}
  1143. X
  1144. X#ifdef MSDOS
  1145. X#define STRING_COMPARE(a,b) stricmp((a),(b))
  1146. X#else
  1147. X#define STRING_COMPARE(a,b) strcmp((a),(b))
  1148. X#endif
  1149. X
  1150. Xint sort_by_ascii (a, b)
  1151. X     char **a, **b;
  1152. X{
  1153. X  return STRING_COMPARE (*a, *b);
  1154. X}
  1155. X
  1156. Xsort_files ()
  1157. X{
  1158. X  qsort (cmd_filev, cmd_filec, sizeof (char*), sort_by_ascii);
  1159. X}
  1160. X
  1161. X#ifndef MSDOS
  1162. Xchar *strdup (string)
  1163. X     char *string;
  1164. X{
  1165. X  int    len = strlen (string) + 1;
  1166. X  char    *p = malloc (len);
  1167. X  bcopy (string, p, len);
  1168. X  return p;
  1169. X}
  1170. X#endif
  1171. X
  1172. X#ifdef NODIRECTORY
  1173. X/* please need your imprementation */
  1174. Xboolean find_files (name, v_filec, v_filev)
  1175. X     char    *name;
  1176. X     int    *v_filec;
  1177. X     char    ***v_filev;
  1178. X{
  1179. X  return FALSE;            /* DUMMY */
  1180. X}
  1181. X#else
  1182. Xboolean find_files (name, v_filec, v_filev)
  1183. X     char    *name;
  1184. X     int    *v_filec;
  1185. X     char    ***v_filev;
  1186. X{
  1187. X  char        newname[FILENAME_LENGTH];
  1188. X  int         len, n;
  1189. X  DIR        *dirp;
  1190. X  DIRENTRY    *dp;
  1191. X  int           alloc_size = 64; /* any (^_^) */
  1192. X  char        **filev;
  1193. X  int        filec = 0;
  1194. X
  1195. X  if ( strcmp(name, ".") == 0 )
  1196. X    newname[0] = 0;
  1197. X  else
  1198. X    strcpy (newname, name);
  1199. X
  1200. X  len = strlen (newname);
  1201. X  dirp = opendir (name);
  1202. X
  1203. X  if (dirp)
  1204. X    {
  1205. X      filev = (char**)malloc (alloc_size * sizeof(char *));
  1206. X      if (!filev)
  1207. X    error ("not enough memory");
  1208. X
  1209. X      for (dp = readdir (dirp); dp != NULL; dp = readdir (dirp))
  1210. X    {
  1211. X      n = NAMLEN (dp);
  1212. X          if (
  1213. X#ifndef MSDOS
  1214. X              (dp->d_ino != 0) &&
  1215. X#endif
  1216. X              ((dp->d_name[0] != '.') ||
  1217. X                 ((n != 1) &&
  1218. X                 ((dp->d_name[1] != '.') ||
  1219. X         (n != 2)))) &&            /* exclude '.' and '..' */
  1220. X          (strcmp (dp->d_name, temporary_name) != 0) &&
  1221. X          (strcmp (dp->d_name, archive_name) != 0))
  1222. X        {
  1223. X              if ((len != 0) && (newname[len-1] != '/') && (newname[len-1] != '\\'))
  1224. X                {
  1225. X#ifdef MSDOS
  1226. X                  newname[len] = '\\';
  1227. X#else
  1228. X                  newname[len] = '/';
  1229. X#endif
  1230. X          strncpy (newname+len+1, dp->d_name, n);
  1231. X          newname[len+n+1] = '\0';
  1232. X        }
  1233. X          else
  1234. X        {
  1235. X          strncpy (newname+len, dp->d_name, n);
  1236. X          newname[len+n] = '\0';
  1237. X        }
  1238. X
  1239. X          filev[filec++] = strdup (newname);
  1240. X          if (filec == alloc_size)
  1241. X        {
  1242. X                  alloc_size += 64;
  1243. X                  filev = (char**)realloc (filev, alloc_size * sizeof(char *));
  1244. X        }
  1245. X        }
  1246. X    }
  1247. X      closedir (dirp);
  1248. X    }
  1249. X
  1250. X  *v_filev = filev;
  1251. X  *v_filec = filec;
  1252. X  if (dirp)
  1253. X    {
  1254. X      qsort (filev, filec, sizeof (char*), sort_by_ascii);
  1255. X      return TRUE;
  1256. X    }
  1257. X  else
  1258. X    return FALSE;
  1259. X}
  1260. X#endif
  1261. X
  1262. Xfree_files (filec, filev)
  1263. X     int    filec;
  1264. X     char    **filev;
  1265. X{
  1266. X  int        i;
  1267. X
  1268. X  for (i = 0; i < filec; i ++)
  1269. X    free (filev[i]);
  1270. X
  1271. X  free (filev);
  1272. X}
  1273. X
  1274. X
  1275. X/*----------------------------------------------------------------------*/
  1276. X/*                                    */
  1277. X/*----------------------------------------------------------------------*/
  1278. X
  1279. Xint calc_sum (p, len)
  1280. X     register char *p;
  1281. X     register int len;
  1282. X{
  1283. X  register int sum;
  1284. X
  1285. X  for (sum = 0; len; len--)
  1286. X    sum += *p++;
  1287. X
  1288. X  return sum & 0xff;
  1289. X}
  1290. X
  1291. Xunsigned char *get_ptr;
  1292. X#define setup_get(PTR) get_ptr = (unsigned char*)(PTR)
  1293. X#define get_byte() (*get_ptr++)
  1294. X#define put_ptr    get_ptr
  1295. X#define setup_put(PTR) put_ptr = (unsigned char*)(PTR)
  1296. X#define put_byte(c) *put_ptr++ = (unsigned char)(c)
  1297. X
  1298. Xunsigned short get_word ()
  1299. X{
  1300. X  int b0, b1;
  1301. X
  1302. X  b0 = get_byte ();
  1303. X  b1 = get_byte ();
  1304. X  return (b1 << 8) + b0;
  1305. X}
  1306. X
  1307. Xput_word (v)
  1308. X     unsigned int    v;
  1309. X{
  1310. X  put_byte (v);
  1311. X  put_byte (v >> 8);
  1312. X}
  1313. X
  1314. Xlong get_longword ()
  1315. X{
  1316. X  long b0, b1, b2, b3;
  1317. X
  1318. X  b0 = get_byte ();
  1319. X  b1 = get_byte ();
  1320. X  b2 = get_byte ();
  1321. X  b3 = get_byte ();
  1322. X  return (b3 << 24) + (b2 << 16) + (b1 << 8) + b0;
  1323. X}
  1324. X
  1325. Xput_longword (v)
  1326. X     long v;
  1327. X{
  1328. X  put_byte (v);
  1329. X  put_byte (v >> 8);
  1330. X  put_byte (v >> 16);
  1331. X  put_byte (v >> 24);
  1332. X}
  1333. X
  1334. X
  1335. Xmsdos_to_unix_filename (name, len)
  1336. X     register char *name;
  1337. X     register int len;
  1338. X{
  1339. X  register int i;
  1340. X
  1341. X#ifdef MULTIBYTE_CHAR
  1342. X  for (i = 0; i < len; i ++)
  1343. X    {
  1344. X      if (MULTIBYTE_FIRST_P (name[i]) &&
  1345. X      MULTIBYTE_SECOND_P (name[i+1]))
  1346. X        i ++;
  1347. X#ifndef MSDOS
  1348. X      else if (name[i] == '\\')
  1349. X        name[i] = '/';
  1350. X#endif
  1351. X      else if (isupper (name[i]))
  1352. X    name[i] = tolower (name[i]);
  1353. X    }
  1354. X#else
  1355. X  for (i = 0; i < len; i ++)
  1356. X    {
  1357. X#ifndef MSDOS
  1358. X      if (name[i] == '\\')
  1359. X    name[i] = '/';
  1360. X      else
  1361. X#endif
  1362. X        if (isupper (name[i]))
  1363. X          name[i] = tolower (name[i]);
  1364. X    }
  1365. X#endif
  1366. X}
  1367. X
  1368. Xgeneric_to_unix_filename (name, len)
  1369. X     register char *name;
  1370. X     register int len;
  1371. X{
  1372. X  register int i;
  1373. X  boolean    lower_case_used = FALSE;
  1374. X
  1375. X#ifdef MULTIBYTE_CHAR
  1376. X  for (i = 0; i < len; i ++)
  1377. X    {
  1378. X      if (MULTIBYTE_FIRST_P (name[i]) &&
  1379. X      MULTIBYTE_SECOND_P (name[i+1]))
  1380. X    i ++;
  1381. X      else if (islower (name[i]))
  1382. X    {
  1383. X      lower_case_used = TRUE;
  1384. X      break;
  1385. X    }
  1386. X    }
  1387. X  for (i = 0; i < len; i ++)
  1388. X    {
  1389. X      if (MULTIBYTE_FIRST_P (name[i]) &&
  1390. X      MULTIBYTE_SECOND_P (name[i+1]))
  1391. X        i ++;
  1392. X#ifndef MSDOS
  1393. X      else if (name[i] == '\\')
  1394. X        name[i] = '/';
  1395. X#endif
  1396. X      else if (!lower_case_used && isupper (name[i]))
  1397. X    name[i] = tolower (name[i]);
  1398. X    }
  1399. X#else
  1400. X  for (i = 0; i < len; i ++)
  1401. X    if (islower (name[i]))
  1402. X      {
  1403. X    lower_case_used = TRUE;
  1404. X    break;
  1405. X      }
  1406. X  for (i = 0; i < len; i ++)
  1407. X    {
  1408. X#ifndef MSDOS
  1409. X      if (name[i] == '\\')
  1410. X    name[i] = '/';
  1411. X      else
  1412. X#endif
  1413. X        if (!lower_case_used && isupper (name[i]))
  1414. X          name[i] = tolower (name[i]);
  1415. X    }
  1416. X#endif
  1417. X}
  1418. X
  1419. Xmacos_to_unix_filename (name, len)
  1420. X     register char *name;
  1421. X     register int len;
  1422. X{
  1423. X  register int i;
  1424. X
  1425. X  for (i = 0; i < len; i ++)
  1426. X    {
  1427. X      if (name[i] == ':')
  1428. X    name[i] = '/';
  1429. X      else if (name[i] == '/')
  1430. X    name[i] = ':';
  1431. X    }
  1432. X}
  1433. X
  1434. X/*----------------------------------------------------------------------*/
  1435. X/*                                    */
  1436. X/*    Generic stamp format:                        */
  1437. X/*                                    */
  1438. X/*     31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16        */
  1439. X/*    |<-------- year ------->|<- month ->|<-- day -->|        */
  1440. X/*                                    */
  1441. X/*     15 14 13 12 11 10  9  8  7  6  5  4  3  2  1  0        */
  1442. X/*    |<--- hour --->|<---- minute --->|<- second*2 ->|        */
  1443. X/*                                    */
  1444. X/*----------------------------------------------------------------------*/
  1445. X
  1446. X
  1447. Xlong gettz ()
  1448. X{
  1449. X#ifdef MSDOS
  1450. X   return timezone;
  1451. X#else
  1452. X   struct timeval    tp;
  1453. X   struct timezone    tzp;
  1454. X   gettimeofday (&tp, &tzp);    /* specific to 4.3BSD */
  1455. X/* return (tzp.tz_minuteswest * 60 + (tzp.tz_dsttime != 0 ? 60L * 60L : 0));*/
  1456. X   return (tzp.tz_minuteswest * 60);
  1457. X#endif
  1458. X}
  1459. X
  1460. X#ifdef NOT_USED
  1461. Xstruct tm *msdos_to_unix_stamp_tm (a)
  1462. X     long a;
  1463. X{
  1464. X  static struct tm t;
  1465. X  t.tm_sec    = ( a          & 0x1f) * 2;
  1466. X  t.tm_min    =  (a >>    5) & 0x3f;
  1467. X  t.tm_hour    =  (a >>   11) & 0x1f;
  1468. X  t.tm_mday    =  (a >>   16) & 0x1f;
  1469. X  t.tm_mon    =  (a >> 16+5) & 0x0f - 1;
  1470. X  t.tm_year    = ((a >> 16+9) & 0x7f) + 80;
  1471. X  return &t;
  1472. X}
  1473. X#endif
  1474. X
  1475. Xtime_t generic_to_unix_stamp (t)
  1476. X     long t;
  1477. X{
  1478. X  struct tm tm;
  1479. X  long longtime;
  1480. X  static unsigned int dsboy[12] =
  1481. X    { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334};
  1482. X  unsigned long days;
  1483. X
  1484. X  tm.tm_year =  ((int)(t >> 25) & 0x7f) + 80;
  1485. X  tm.tm_mon  =  ((int)(t >> 21) & 0x0f) - 1;     /* 0..11 means Jan..Dec */
  1486. X  tm.tm_mday =  (int)(t >> 16) & 0x1f;         /* 1..31 means 1st,...31st */
  1487. X
  1488. X  tm.tm_hour =  ((int)t >> 11) & 0x1f;
  1489. X  tm.tm_min  =  ((int)t >> 5)  & 0x3f;
  1490. X  tm.tm_sec  =  ((int)t        & 0x1f) * 2;
  1491. X
  1492. X#ifdef MSDOS
  1493. X  longtime = mktime(&tm);
  1494. X#else
  1495. X                                      /* Calculate days since 1970.01.01 */
  1496. X  days = (365 * (tm.tm_year - 70) +   /* days due to whole years */
  1497. X          (tm.tm_year - 70 + 1) / 4 + /* days due to leap years */
  1498. X          dsboy[tm.tm_mon] +          /* days since beginning of this year */
  1499. X          tm.tm_mday-1);              /* days since beginning of month */
  1500. X
  1501. X  if ((tm.tm_year % 4 == 0) &&
  1502. X      (tm.tm_year % 400 != 0) &&
  1503. X      (tm.tm_mon >= 2))         /* if this is a leap year and month */
  1504. X    days++;            /* is March or later, add a day */
  1505. X
  1506. X  /* Knowing the days, we can find seconds */
  1507. X  longtime = (((days * 24) + tm.tm_hour) * 60 + tm.tm_min) * 60 + tm.tm_sec;
  1508. X  longtime += gettz ();      /* adjust for timezone */
  1509. X#endif
  1510. X
  1511. X  /* special case:  if MSDOS format date and time were zero, then we set
  1512. X     time to be zero here too. */
  1513. X  if (t == 0)
  1514. X    longtime = 0;
  1515. X
  1516. X  /* LONGTIME is now the time in seconds, since 1970/01/01 00:00:00.  */
  1517. X  return (time_t)longtime;
  1518. X}
  1519. X
  1520. Xlong unix_to_generic_stamp (t)
  1521. X     time_t t;
  1522. X{
  1523. X  struct tm *tm = localtime (&t);
  1524. X  unsigned long stamp;
  1525. X
  1526. X  stamp =  ( ((long)(tm->tm_year - 80)) << 25 );
  1527. X  stamp += ( ((long)(tm->tm_mon + 1))   << 21 );
  1528. X  stamp += ( ((long)(tm->tm_mday))      << 16 );
  1529. X  stamp += ( ((long)(tm->tm_hour))      << 11 );
  1530. X  stamp += ( ((long)(tm->tm_min))       << 5 );
  1531. X  stamp += ( ((long)(tm->tm_sec))       >> 1 );
  1532. X
  1533. X  return stamp;
  1534. X}
  1535. X
  1536. X/*----------------------------------------------------------------------*/
  1537. X/*                                    */
  1538. X/*----------------------------------------------------------------------*/
  1539. X
  1540. Xboolean get_header (fp, hdr)
  1541. X     FILE *fp;
  1542. X     register LzHeader *hdr;
  1543. X{
  1544. X  int        header_size;
  1545. X  int        name_length;
  1546. X  char        data[LZHEADER_STRAGE];
  1547. X  int        checksum;
  1548. X  int        i;
  1549. X
  1550. X  bzero (hdr, sizeof (LzHeader));
  1551. X
  1552. X  if (((header_size = getc (fp)) == EOF) || (header_size == 0))
  1553. X    {
  1554. X      return FALSE;        /* finish */
  1555. X    }
  1556. X
  1557. X  if (fread (data + I_HEADER_CHECKSUM,
  1558. X          sizeof (char), header_size + 1, fp) < header_size + 1)
  1559. X    {
  1560. X      error ("Invalid header (LHarc file ?)\a");
  1561. X      return FALSE;        /* finish */
  1562. X    }
  1563. X
  1564. X  setup_get (data + I_HEADER_CHECKSUM);
  1565. X  checksum = calc_sum (data + I_METHOD, header_size);
  1566. X  if (get_byte () != checksum)
  1567. X    warning ("Checksum error (LHarc file?)\a");
  1568. X
  1569. X  hdr->header_size = header_size;
  1570. X  bcopy (data + I_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  1571. X#ifdef OLD
  1572. X  if ((bcmp (hdr->method, LZHUFF1_METHOD, METHOD_TYPE_STRAGE) != 0) &&
  1573. X      (bcmp (hdr->method, LZHUFF0_METHOD, METHOD_TYPE_STRAGE) != 0) &&
  1574. X      (bcmp (hdr->method, LARC5_METHOD, METHOD_TYPE_STRAGE) != 0) &&
  1575. X      (bcmp (hdr->method, LARC4_METHOD, METHOD_TYPE_STRAGE) != 0))
  1576. X    {
  1577. X      warning ("Unknown method (LHarc file ?)");
  1578. X      return FALSE;        /* invalid method */
  1579. X    }
  1580. X#endif
  1581. X  setup_get (data + I_PACKED_SIZE);
  1582. X  hdr->packed_size    = get_longword ();
  1583. X  hdr->original_size    = get_longword ();
  1584. X  hdr->last_modified_stamp = get_longword ();
  1585. X  hdr->attribute    = get_word ();
  1586. X  name_length        = get_byte ();
  1587. X  for (i = 0; i < name_length; i ++)
  1588. X    hdr->name[i] =(char)get_byte ();
  1589. X  hdr->name[name_length] = '\0';
  1590. X
  1591. X  /* defaults for other type */
  1592. X  hdr->unix_mode    = UNIX_FILE_REGULAR | UNIX_RW_RW_RW;
  1593. X  hdr->unix_gid     = 0;
  1594. X  hdr->unix_uid        = 0;
  1595. X
  1596. X  if (header_size - name_length >= 24)
  1597. X    {                /* EXTEND FORMAT */
  1598. X      hdr->crc                = get_word ();
  1599. X      hdr->extend_type            = get_byte ();
  1600. X      hdr->minor_version        = get_byte ();
  1601. X      hdr->has_crc = TRUE;
  1602. X    }
  1603. X  else if (header_size - name_length == 22)
  1604. X    {                /* Generic with CRC */
  1605. X      hdr->crc                = get_word ();
  1606. X      hdr->extend_type            = EXTEND_GENERIC;
  1607. X      hdr->has_crc = TRUE;
  1608. X    }
  1609. X  else if (header_size - name_length == 20)
  1610. X    {                /* Generic no CRC */
  1611. X      hdr->extend_type            = EXTEND_GENERIC;
  1612. X      hdr->has_crc = FALSE;
  1613. X    }
  1614. X  else
  1615. X    {
  1616. X      warning ("Unknown header (LHarc file ?)");
  1617. X      return FALSE;
  1618. X    }
  1619. X
  1620. X  switch (hdr->extend_type)
  1621. X    {
  1622. X    case EXTEND_MSDOS:
  1623. X      msdos_to_unix_filename (hdr->name, name_length);
  1624. X      hdr->unix_last_modified_stamp    =
  1625. X    generic_to_unix_stamp (hdr->last_modified_stamp);
  1626. X      break;
  1627. X
  1628. X    case EXTEND_UNIX:
  1629. X      hdr->unix_last_modified_stamp    = (time_t)get_longword ();
  1630. X      hdr->unix_mode            = get_word ();
  1631. X      hdr->unix_uid            = get_word ();
  1632. X      hdr->unix_gid            = get_word ();
  1633. X      break;
  1634. X
  1635. X    case EXTEND_MACOS:
  1636. X      macos_to_unix_filename (hdr->name, name_length);
  1637. X      hdr->unix_last_modified_stamp    =
  1638. X    generic_to_unix_stamp (hdr->last_modified_stamp);
  1639. X      break;
  1640. X
  1641. X    default:
  1642. X      generic_to_unix_filename (hdr->name, name_length);
  1643. X      hdr->unix_last_modified_stamp    =
  1644. X    generic_to_unix_stamp (hdr->last_modified_stamp);
  1645. X    }
  1646. X
  1647. X  return TRUE;
  1648. X}
  1649. X
  1650. Xinit_header (name, v_stat, hdr)
  1651. X     char *name;
  1652. X     struct stat *v_stat;
  1653. X     LzHeader *hdr;
  1654. X{
  1655. X  bcopy (LZHUFF1_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  1656. X  hdr->packed_size        = 0;
  1657. X  hdr->original_size        = v_stat->st_size;
  1658. X  hdr->last_modified_stamp      = unix_to_generic_stamp (v_stat->st_mtime);
  1659. X#ifdef MSDOS
  1660. X  getfilemode(name, &(hdr->attribute));
  1661. X#else
  1662. X  hdr->attribute                = GENERIC_ATTRIBUTE;
  1663. X#endif
  1664. X  strcpy (hdr->name, name);
  1665. X  hdr->crc            = 0x0000;
  1666. X  hdr->extend_type              = OUR_EXTEND;
  1667. X  hdr->unix_last_modified_stamp    = v_stat->st_mtime;
  1668. X                /* 00:00:00 since JAN.1.1970 */
  1669. X#ifdef NOT_COMPATIBLE_MODE
  1670. X  hdr->unix_mode        = v_stat->st_mode;
  1671. X#else
  1672. X  hdr->unix_mode        = v_stat->st_mode;
  1673. X#endif
  1674. X
  1675. X  hdr->unix_uid            = v_stat->st_uid;
  1676. X  hdr->unix_gid            = v_stat->st_gid;
  1677. X
  1678. X  if ((v_stat->st_mode & S_IFMT) == S_IFDIR)
  1679. X    {
  1680. X      bcopy (LZHUFF0_METHOD, hdr->method, METHOD_TYPE_STRAGE);
  1681. X      hdr->attribute = GENERIC_DIRECTORY_ATTRIBUTE;
  1682. X      hdr->original_size = 0;
  1683. X      strcat (hdr->name, "/");
  1684. X    }
  1685. X}
  1686. X
  1687. X/* Write only unix extended header. */
  1688. Xwrite_header (nafp, hdr)
  1689. X     FILE *nafp;
  1690. X     LzHeader *hdr;
  1691. X{
  1692. X  int        header_size;
  1693. X  int        name_length;
  1694. X  char          data[LZHEADER_STRAGE], *ptr;
  1695. X  int           cnt;
  1696. X
  1697. X  bzero (data, LZHEADER_STRAGE);
  1698. X  bcopy (hdr->method, data + I_METHOD, METHOD_TYPE_STRAGE);
  1699. X  setup_put (data + I_PACKED_SIZE);
  1700. X  put_longword (hdr->packed_size);
  1701. X  put_longword (hdr->original_size);
  1702. X  put_longword (hdr->last_modified_stamp);
  1703. X  put_word (hdr->attribute);
  1704. X  
  1705. X#ifdef STRICT
  1706. X
  1707. X  if ( hdr->name[1] == ':' )
  1708. X  {
  1709. X    name_length = strlen(hdr->name + 2);
  1710. X    put_byte (name_length);
  1711. X    bcopy (hdr->name + 2, data + I_NAME, name_length);
  1712. X  }
  1713. X  else
  1714. X  {
  1715. X    name_length = strlen(hdr->name);
  1716. X    put_byte (name_length);
  1717. X    bcopy (hdr->name, data + I_NAME, name_length);
  1718. X  }
  1719. X  
  1720. X  for ( ptr = data + I_NAME, cnt = 0; cnt < name_length; ptr++, cnt++ )
  1721. X  {
  1722. X    *ptr = toupper(*ptr);
  1723. X
  1724. X    if ( *ptr == '/' )
  1725. X      *ptr = '\\';
  1726. X  }
  1727. X#else
  1728. X  name_length = strlen (hdr->name);
  1729. X  put_byte (name_length);
  1730. X  bcopy (hdr->name, data + I_NAME, name_length);
  1731. X#endif
  1732. X  
  1733. X  setup_put (data + I_NAME + name_length);
  1734. X  put_word (hdr->crc);
  1735. X#ifdef STRICT
  1736. X  header_size = I_EXTEND_TYPE - 2 + name_length;
  1737. X#else
  1738. X  put_byte (OUR_EXTEND);
  1739. X  put_byte (CURRENT_UNIX_MINOR_VERSION);
  1740. X  put_longword ((long)hdr->unix_last_modified_stamp);
  1741. X  put_word (hdr->unix_mode);
  1742. X  put_word (hdr->unix_uid);
  1743. X  put_word (hdr->unix_gid);
  1744. X  header_size = I_UNIX_EXTEND_BOTTOM - 2 + name_length;
  1745. X#endif
  1746. X  data[I_HEADER_SIZE] = header_size;
  1747. X  data[I_HEADER_CHECKSUM] = calc_sum (data + I_METHOD, header_size);
  1748. X
  1749. X  if (fwrite (data, sizeof (char), header_size + 2, nafp) == NULL)
  1750. X    error ("cannot write to temporary file");
  1751. X}
  1752. X
  1753. Xboolean archive_is_msdos_sfx1 (name)
  1754. X     char *name;
  1755. X{
  1756. X  int    len = strlen (name);
  1757. X  return ((len >= 4) &&
  1758. X      (strcmp (name + len - 4, ".com") == 0 ||
  1759. X       strcmp (name + len - 4, ".exe") == 0));
  1760. X}
  1761. X
  1762. Xboolean skip_msdos_sfx1_code (fp)
  1763. X     FILE *fp;
  1764. X{
  1765. X  unsigned char buffer[2048];
  1766. X  unsigned char *p, *q;
  1767. X  int    n;
  1768. X
  1769. X  n = fread (buffer, sizeof (char), 2048, fp);
  1770. X
  1771. X  for (p = buffer + 2, q = buffer + n - 5; p < q; p ++)
  1772. X    {
  1773. X      /* found "-l??-" keyword (as METHOD type string) */
  1774. X      if (p[0] == '-' && p[1] == 'l' && p[4] == '-')
  1775. X    {
  1776. X      /* size and checksum validate check */
  1777. X      if (p[-2] > 20 && p[-1] == calc_sum (p, p[-2]))
  1778. X        {
  1779. X              fseek (fp, (long) ((p - 2) - buffer) - n, SEEK_CUR);
  1780. X          return TRUE;
  1781. X        }
  1782. X    }
  1783. X    }
  1784. X
  1785. X  fseek (fp, (long) -n, SEEK_CUR);
  1786. X  return FALSE;
  1787. X}
  1788. X
  1789. X
  1790. X/*----------------------------------------------------------------------*/
  1791. X/*                                    */
  1792. X/*----------------------------------------------------------------------*/
  1793. X
  1794. Xmake_tmp_name (original, name)
  1795. X     char *original;
  1796. X     char *name;
  1797. X{
  1798. X#ifdef TMP_FILENAME_TEMPLATE
  1799. X  /* "/tmp/lhXXXXXX" etc. */
  1800. X  strcpy (name, TMP_FILENAME_TEMPLATE);
  1801. X#else
  1802. X  char *p, *s;
  1803. X
  1804. X  strcpy (name, original);
  1805. X  for (p = name, s = (char*)0; *p; p++)
  1806. X    if (*p == '/' || *p == '\\')
  1807. X      s = p;
  1808. X
  1809. X  strcpy ((s ? s+1 : name), "lhXXXXXX");
  1810. X#endif
  1811. X
  1812. X  mktemp (name);
  1813. X}
  1814. X
  1815. Xmake_backup_name (name, orginal)
  1816. X     char *name;
  1817. X     char *orginal;
  1818. X{
  1819. X  register char *p, *dot;
  1820. X
  1821. X  strcpy (name, orginal);
  1822. X  for (p = name, dot = (char*)0; *p; p ++)
  1823. X    {
  1824. X      if (*p == '.')
  1825. X    dot = p;
  1826. X      else if (*p == '/' || *p == '\\')
  1827. X    dot = (char*)0;
  1828. X    }
  1829. X
  1830. X  if (dot)
  1831. X    p = dot;
  1832. X
  1833. X#ifdef BACKUPNAME_EXTENTION
  1834. X  strcpy (p, BACKUPNAME_EXTENTION)
  1835. X#else
  1836. X  strcpy (p, ".bak");
  1837. X#endif
  1838. X}
  1839. X
  1840. Xmake_standard_archive_name (name, orginal)
  1841. X     char *name;
  1842. X     char *orginal;
  1843. X{
  1844. X  register char *p, *dot;
  1845. X
  1846. X  strcpy (name, orginal);
  1847. X  for (p = name, dot = (char*)0; *p; p ++)
  1848. X    {
  1849. X      if (*p == '.')
  1850. X    dot = p;
  1851. X      else if (*p == '/' || *p == '\\')
  1852. X    dot = (char*)0;
  1853. X    }
  1854. X
  1855. X  if (dot)
  1856. X    p = dot;
  1857. X
  1858. X#ifdef ARCHIVENAME_EXTENTION
  1859. X  strcpy (p, ARCHIVENAME_EXTENTION);
  1860. X#else
  1861. X  strcpy (p, ".lzh");
  1862. X#endif
  1863. X}
  1864. X
  1865. X/*----------------------------------------------------------------------*/
  1866. X/*                                    */
  1867. X/*----------------------------------------------------------------------*/
  1868. X
  1869. X
  1870. Xboolean need_file (name)
  1871. X     char *name;
  1872. X{
  1873. X  int    i;
  1874. X
  1875. X  if (cmd_filec == 0)
  1876. X    return TRUE;
  1877. X
  1878. X  for (i = 0; i < cmd_filec; i ++)
  1879. X    {
  1880. X      if (STRING_COMPARE (cmd_filev[i], name) == 0)
  1881. X    return TRUE;
  1882. X    }
  1883. X
  1884. X  return FALSE;
  1885. X}
  1886. X
  1887. XFILE *xfopen (name, mode)
  1888. X     char *name, *mode;
  1889. X{
  1890. X  FILE *fp;
  1891. X
  1892. X  if ((fp = fopen (name, mode)) == NULL)
  1893. X    error (name);
  1894. X
  1895. X  return fp;
  1896. X}
  1897. X
  1898. X
  1899. X/*----------------------------------------------------------------------*/
  1900. X/*        Listing Stuff                        */
  1901. X/*----------------------------------------------------------------------*/
  1902. X
  1903. X/* need 14 or 22 (when long_format_listing is TRUE) column spaces */
  1904. Xprint_size (packed_size, original_size)
  1905. X     long packed_size, original_size;
  1906. X{
  1907. X  if (long_format_listing)
  1908. X    printf ("%7ld ", packed_size);
  1909. X
  1910. X  printf ("%7ld ", original_size);
  1911. X
  1912. X  if (original_size == 0L)
  1913. X    printf ("******");
  1914. X  else
  1915. X    printf ("%3d.%1d%%",
  1916. X        (int)((packed_size * 100L) / original_size),
  1917. X        (int)((packed_size * 1000L) / original_size) % 10);
  1918. X}
  1919. X
  1920. X/* need 12 or 17 (when long_format_listing is TRUE) column spaces */
  1921. Xprint_stamp (t)
  1922. X     time_t t;
  1923. X{
  1924. X  static boolean    got_now = FALSE;
  1925. X  static time_t        now;
  1926. X  static unsigned int    threshold;
  1927. X  static char   t_month[12*3+1] = "JanFebMarAprMayJunJulAugSepOctNovDec";
  1928. X  struct tm        *p;
  1929. X
  1930. X  if (t == 0)
  1931. X    {
  1932. X      if (long_format_listing)
  1933. X    printf ("                 "); /* 17 spaces */
  1934. X      else
  1935. X    printf ("            ");    /* 12 spaces */
  1936. X
  1937. X      return;
  1938. X    }
  1939. X
  1940. X  if (!got_now)
  1941. X    {
  1942. X      time (&now);
  1943. X      p = localtime (&now);
  1944. X      threshold = p->tm_year * 12 + p->tm_mon - 6;
  1945. X      got_now = TRUE;
  1946. X    }
  1947. X
  1948. X  p = localtime (&t);
  1949. X
  1950. X  if (long_format_listing)
  1951. X    printf ("%.3s %2d %02d:%02d %04d",
  1952. X        &t_month[p->tm_mon * 3], p->tm_mday,
  1953. X        p->tm_hour, p->tm_min, p->tm_year + 1900);
  1954. X  else
  1955. X    if (p->tm_year * 12 + p->tm_mon > threshold)
  1956. X      printf ("%.3s %2d %02d:%02d",
  1957. X          &t_month[p->tm_mon * 3], p->tm_mday, p->tm_hour, p->tm_min);
  1958. X    else
  1959. X      printf ("%.3s %2d  %04d",
  1960. X          &t_month[p->tm_mon * 3], p->tm_mday, p->tm_year + 1900);
  1961. X}
  1962. X
  1963. Xprint_bar ()
  1964. X{
  1965. X  /* 17+1+(0 or 7+1)+7+1+6+1+(0 or 1+4)+(12 or 17)+1+20 */
  1966. X  /*       12345678901234567_  1234567_123456  _123456789012   1234      */
  1967. X  if (long_format_listing)
  1968. X#ifdef STRICT
  1969. X    printf ("------- ------- ------ ---- ----------------- -------------\n");
  1970. X#else
  1971. X    printf ("----------------- ------- ------- ------ ---- ----------------- -------------\n");
  1972. X#endif
  1973. X  else
  1974. X#ifdef STRICT
  1975. X    printf ("------- ------ ------------ --------------------\n");
  1976. X#else
  1977. X    printf ("----------------- ------- ------ ------------ --------------------\n");
  1978. X#endif
  1979. X}
  1980. X
  1981. X
  1982. X/*
  1983. X  view
  1984. X */
  1985. Xcmd_view ()
  1986. X{
  1987. X  FILE        *fp;
  1988. X  LzHeader    hdr;
  1989. X  register char    *p;
  1990. X  long        a_packed_size = 0L;
  1991. X  long        a_original_size = 0L;
  1992. X  int        n_files = 0;
  1993. X  struct stat    v_stat;
  1994. X
  1995. X  if ((fp = fopen (archive_name, RMODE)) == NULL)
  1996. X    if (!expand_archive_name (expanded_archive_name, archive_name))
  1997. X      error (archive_name);
  1998. X    else
  1999. X      {
  2000. X    errno = 0;
  2001. X        fp = xfopen (expanded_archive_name, RMODE);
  2002. X    archive_name = expanded_archive_name;
  2003. X      }
  2004. X
  2005. X  if (archive_is_msdos_sfx1 (archive_name))
  2006. X    {
  2007. X      skip_msdos_sfx1_code (fp);
  2008. X    }
  2009. X
  2010. X  if (!quiet)
  2011. X    {
  2012. X      /*       12345678901234567_  1234567_123456  _  123456789012  1234 */
  2013. X#ifdef STRICT
  2014. X      printf ("%s   SIZE  RATIO%s %s    STAMP   %s NAME\n",
  2015. X#else
  2016. X      printf (" PERMSSN  UID GID %s   SIZE  RATIO%s %s    STAMP   %s NAME\n",
  2017. X#endif
  2018. X          long_format_listing ? " PACKED " : "", /* 8,0 */
  2019. X          long_format_listing ? "  CRC" : "", /* 5,0 */
  2020. X          long_format_listing ? "  " : "", /* 2,0 */
  2021. X          long_format_listing ? "   " : ""); /* 3,0 */
  2022. X      print_bar ();
  2023. X    }
  2024. X
  2025. X  while (get_header (fp, &hdr))
  2026. X    {
  2027. X      if (need_file (hdr.name))
  2028. X    {
  2029. X      if (hdr.extend_type == EXTEND_UNIX)
  2030. X            {
  2031. X#ifndef STRICT
  2032. X              printf ("%c%c%c%c%c%c%c%c%c%4d/%-4d",
  2033. X          ((hdr.unix_mode & UNIX_OWNER_READ_PERM)  ? 'r' : '-'),
  2034. X          ((hdr.unix_mode & UNIX_OWNER_WRITE_PERM) ? 'w' : '-'),
  2035. X          ((hdr.unix_mode & UNIX_OWNER_EXEC_PERM)  ? 'x' : '-'),
  2036. X          ((hdr.unix_mode & UNIX_GROUP_READ_PERM)  ? 'r' : '-'),
  2037. X          ((hdr.unix_mode & UNIX_GROUP_WRITE_PERM) ? 'w' : '-'),
  2038. X          ((hdr.unix_mode & UNIX_GROUP_EXEC_PERM)  ? 'x' : '-'),
  2039. X          ((hdr.unix_mode & UNIX_OTHER_READ_PERM)  ? 'r' : '-'),
  2040. X          ((hdr.unix_mode & UNIX_OTHER_WRITE_PERM) ? 'w' : '-'),
  2041. X          ((hdr.unix_mode & UNIX_OTHER_EXEC_PERM)  ? 'x' : '-'),
  2042. X          hdr.unix_uid, hdr.unix_gid);
  2043. X#endif
  2044. X        }
  2045. X      else
  2046. X        {
  2047. X          switch (hdr.extend_type)
  2048. X        {            /* max 18 characters */
  2049. X                case EXTEND_GENERIC:    p = "[Generic]"; break;
  2050. X
  2051. X        case EXTEND_CPM:    p = "[CP/M]"; break;
  2052. X
  2053. X          /* OS-9 and FLEX's CPU is MC-6809. I like it. :-)  */
  2054. X        case EXTEND_FLEX:    p = "[FLEX]"; break;
  2055. X
  2056. X        case EXTEND_OS9:    p = "[OS-9]"; break;
  2057. X
  2058. X          /* I guessed from this ID.  Is this right? */
  2059. X        case EXTEND_OS68K:    p = "[OS-9/68K]"; break;
  2060. X
  2061. X        case EXTEND_MSDOS:    p = "[MS-DOS]"; break;
  2062. X
  2063. X          /* I have Macintosh. :-)  */
  2064. X        case EXTEND_MACOS:    p = "[Mac OS]"; break;
  2065. X
  2066. X        case EXTEND_OS2:    p = "[OS/2]"; break;
  2067. X
  2068. X        case EXTEND_HUMAN:    p = "[Human68K]"; break;
  2069. X
  2070. X        case EXTEND_OS386:    p = "[OS-386]"; break;
  2071. X
  2072. X#ifdef EXTEND_TOWNSOS
  2073. X          /* This ID isn't fixed */
  2074. X        case EXTEND_TOWNSOS:    p = "[TownsOS]"; break;
  2075. X#endif
  2076. X
  2077. X          /* Ouch!  Please customize it's ID.  */
  2078. X                default:                p = "[Unknown]"; break;
  2079. X                }
  2080. X#ifndef STRICT
  2081. X              printf ("%-18.18s", p);
  2082. X#endif
  2083. X        }
  2084. X
  2085. X      print_size (hdr.packed_size, hdr.original_size);
  2086. X
  2087. X      if (long_format_listing)
  2088. X        if (hdr.has_crc)
  2089. X          printf (" %04x", hdr.crc);
  2090. X        else
  2091. X          printf (" ****");
  2092. X
  2093. X      printf (" ");
  2094. X      print_stamp (hdr.unix_last_modified_stamp);
  2095. X      printf (" %s\n", hdr.name);
  2096. X      n_files ++;
  2097. X      a_packed_size += hdr.packed_size;
  2098. X      a_original_size += hdr.original_size;
  2099. X    }
  2100. X      fseek (fp, hdr.packed_size, SEEK_CUR);
  2101. X    }
  2102. X
  2103. X  fclose (fp);
  2104. X  if (!quiet)
  2105. X    {
  2106. X      print_bar ();
  2107. X
  2108. X#ifndef STRICT
  2109. X      printf (" Total %4d file%c ",
  2110. X          n_files, (n_files == 1) ? ' ' : 's');
  2111. X#endif
  2112. X      print_size (a_packed_size, a_original_size);
  2113. X      printf (" ");
  2114. X
  2115. X      if (long_format_listing)
  2116. X    printf ("     ");
  2117. X
  2118. X      if (stat (archive_name, &v_stat) < 0)
  2119. X    print_stamp ((time_t)0);
  2120. X      else
  2121. X    print_stamp (v_stat.st_mtime);
  2122. X
  2123. X#ifdef STRICT
  2124. X      printf (" %4d file%c ",
  2125. X          n_files, (n_files == 1) ? ' ' : 's');
  2126. X#endif
  2127. X      printf ("\n");
  2128. X    }
  2129. X
  2130. X  return;
  2131. X}
  2132. X
  2133. X
  2134. Xboolean make_parent_path (name)
  2135. X     char *name;
  2136. X{
  2137. X  char        path[FILENAME_LENGTH];
  2138. X  struct stat    v_stat;
  2139. X  register char    *p;
  2140. X
  2141. X /* make parent directory name into PATH for recursive call */
  2142. X  strcpy (path, name);
  2143. X  for (p = path + strlen (path); p > path; p --)
  2144. X    if (p[-1] == '/' || p[-1] == '\\')
  2145. X      {
  2146. X    p[-1] = '\0';
  2147. X    break;
  2148. X      }
  2149. X
  2150. X  if (p == path)
  2151. X    return FALSE;        /* no more parent. */
  2152. X
  2153. X  if (stat (path, &v_stat) >= 0)
  2154. X    {
  2155. X      if ((v_stat.st_mode & S_IFMT) != S_IFDIR)
  2156. X    return FALSE;        /* already exist. but it isn't directory. */
  2157. X      return TRUE;        /* already exist its directory. */
  2158. X    }
  2159. X
  2160. X  errno = 0;
  2161. X
  2162. X  if (!quiet)
  2163. X    message ("Making Directory", path);
  2164. X
  2165. X  if (mkdir (path, 0777) >= 0)    /* try */
  2166. X    return TRUE;        /* successful done. */
  2167. X
  2168. X  errno = 0;
  2169. X
  2170. X  if (!make_parent_path (path))
  2171. X    return FALSE;
  2172. X
  2173. X  if (mkdir (path, 0777) < 0)        /* try again */
  2174. X    return FALSE;
  2175. X
  2176. X  return TRUE;
  2177. X}
  2178. X
  2179. XFILE *open_with_make_path (name)
  2180. X     char *name;
  2181. X{
  2182. X  FILE        *fp;
  2183. X  struct stat    v_stat;
  2184. X  char        buffer[1024];
  2185. X
  2186. X  if (stat (name, &v_stat) >= 0)
  2187. X    {
  2188. X      if ((v_stat.st_mode & S_IFMT) != S_IFREG)
  2189. X    return NULL;
  2190. X
  2191. X      if (!force)
  2192. X    {
  2193. X      for (;;)
  2194. X        {
  2195. X          fprintf (stderr, "%s OverWrite ?(Yes/No/All) ", name);
  2196. X          fflush (stderr);
  2197. X          gets (buffer);
  2198. X          if (buffer[0] == 'N' || buffer[0] == 'n')
  2199. X        return NULL;
  2200. X          if (buffer[0] == 'Y' || buffer[0] == 'y')
  2201. X        break;
  2202. X          if (buffer[0] == 'A' || buffer[0] == 'a')
  2203. X        {
  2204. X          force = TRUE;
  2205. X          break;
  2206. X        }
  2207. X        }
  2208. X    }
  2209. X    }
  2210. X
  2211. X  fp = fopen (name, WMODE);
  2212. X  if (!fp)
  2213. X    {
  2214. X      errno = 0;
  2215. X      if (!make_parent_path (name))
  2216. X    return NULL;
  2217. X
  2218. X      fp = fopen (name, WMODE);
  2219. X      if (!fp)
  2220. X        message ("Error:", name);
  2221. X    }
  2222. X  return fp;
  2223. X}
  2224. X
  2225. X#ifdef MSDOS
  2226. Xvoid dosname(char *name)
  2227. X{
  2228. X  char *ptr, *first = NULL, *last = NULL;
  2229. X  char temp[8];
  2230. X
  2231. X  for ( ptr = strchr(name, 0); ptr >= name; ptr-- )
  2232. X    if ( *ptr == '.' )
  2233. X    {
  2234. X      if ( last == NULL )
  2235. X        last = ptr;
  2236. X    }
  2237. X    else if ( (*ptr == '/') || (*ptr == '\\') )
  2238. X    {
  2239. X      first = ptr + 1;
  2240. X      break;
  2241. X    }
  2242. X
  2243. X  if ( first == NULL )
  2244. X    first = name;
  2245. X  if ( last == NULL )
  2246. X    last = strchr(name, 0);
  2247. X
  2248. X  for ( ptr = first; ptr < last; ptr++ )
  2249. X    if ( *ptr == '.' )
  2250. X      *ptr = '_';
  2251. X
  2252. SHAR_EOF
  2253. echo "End of part 1"
  2254. echo "File lharc.c is continued in part 2"
  2255. echo "2" > s2_seq_.tmp
  2256. exit 0
  2257.  
  2258.  
  2259.  
  2260.