home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2217 < prev    next >
Internet Message Format  |  1990-12-28  |  59KB

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