home *** CD-ROM | disk | FTP | other *** search
/ CP/M / CPM_CDROM.iso / simtel / sigm / vols200 / vol217 / luu.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-07-13  |  17.3 KB  |  766 lines

  1. /*
  2. *********************************************************
  3. *                            *
  4. *           LU for CP/M-86            *
  5. *                            *
  6. *********************************************************
  7.  
  8. This version of LU is mostly just the UNIX LU program
  9. "lar" with a very few modifications to take into
  10. account differences between UNIX and CP/M system
  11. conventions. It is intended for compilation with the
  12. Digital Research C compiler (which really is VERY
  13. syntax compatible with UNIX 7 C code). I would also
  14. think that an PCDOS version of LU would be easy to
  15. generate from this code using the PCDOS version of
  16. the DR C compiler.  
  17.  
  18. This is realy just the first pass through "lar". I hope to
  19. have versions with added features soon. However this version
  20. is perfectly adequate for the basic manipulation of
  21. LBR libraries under in CP/M-86 and Concurrent PCDOS
  22. environments.
  23.  
  24.                 Bill Bolton,
  25.                 Software Tools RCPM,
  26.                 Brisbane, Australia
  27.  
  28.  
  29. VERSION LIST, most recent version first
  30.  
  31. 09/Aug/84 Minor modifications to Stephen Hemmingers UNIX
  32.           "lar" program. DRC always returns command line
  33.       arguments in lower case (how's that for counter
  34.       intuitive, at least to someone who uses CP/M-86
  35.       assembler too!) so that had to be taken into
  36.       account. Version 1.0  Bill Bolton    
  37.  
  38. Original UNIX version documentation follows
  39.  
  40.  - /bin/ncc -O lar.c -o lar
  41. From linus!sch Tue Jul 26 08:07:37 1983
  42. Subject: CP/M Lu library maintainer
  43.  
  44. When transfering files to my personal computer, I often want to transfer
  45. several files at once using the Umodem program.  To do this I wrote
  46. the following small program to combine files for the CP/M LU program.
  47.  
  48. No special treatment necessary, just:
  49.     cc -O lar.c -o lar
  50. to make it.
  51.  
  52. -- 
  53. Stephen Hemminger,  Mitre Corp. Bedford MA 
  54.     {allegra,genrad,ihnp4, utzoo}!linus!sch    (UUCP)
  55.     linus!sch@mitre-bedford            (ARPA)
  56. ----------------- lar.c ----------------------
  57. */
  58.  
  59. /*
  60.  * Lar - LU format library file maintainer
  61.  * by Stephen C. Hemminger
  62.  *    linus!sch    or    sch@Mitre-Bedford
  63.  *
  64.  *  Usage: lar key library [files] ...
  65.  *
  66.  *  Key functions are:
  67.  *    u - Update, add files to library
  68.  *    t - Table of contents
  69.  *    e - Extract files from library
  70.  *    p - Print files in library
  71.  *    d - Delete files in library
  72.  *    r - Reorginize library
  73.  *  Other keys:
  74.  *    v - Verbose
  75.  *
  76.  *  This program is public domain software, no warranty intended or
  77.  *  implied.
  78.  *
  79.  *  DESCRPTION
  80.  *     Lar is a Unix program to manipulate CP/M LU format libraries.
  81.  *     The original CP/M library program LU is the product
  82.  *     of Gary P. Novosielski. The primary use of lar is to combine several
  83.  *     files together for upload/download to a personal computer.
  84.  *
  85.  *  PORTABILITY
  86.  *     The code is modeled after the Software tools archive program,
  87.  *     and is setup for Version 7 Unix.  It does not make any assumptions
  88.  *     about byte ordering, explict and's and shift's are used.
  89.  *     If you have a dumber C compiler, you may have to recode new features
  90.  *     like structure assignment, typedef's and enumerated types.
  91.  *
  92.  *  BUGS/MISFEATURES
  93.  *     The biggest problem is text files, the programs tries to detect
  94.  *     text files vs. binaries by checking for non-Ascii (8th bit set) chars.
  95.  *     If the file is text then it will throw away Control-Z chars which
  96.  *     CP/M puts on the end.  All files in library are padded with Control-Z
  97.  *     at the end to the CP/M sector size if necessary.
  98.  *
  99.  *     No effort is made to handle the difference between CP/M and Unix
  100.  *     end of line chars.  CP/M uses Cr/Lf and Unix just uses Lf.
  101.  *     The solution is just to use the Unix command sed when necessary.
  102.  *
  103.  *  * Unix is a trademark of Bell Labs.
  104.  *  ** CP/M is a trademark of Digital Research.
  105.  */
  106.  
  107. #include <stdio.h>
  108. #include <ctype.h>
  109.  
  110. #define ACTIVE    00
  111. #define UNUSED    0xff
  112. #define DELETED 0xfe
  113. #define CTRLZ    0x1a
  114.  
  115. #define MAXFILES 256
  116. #define SECTOR     128
  117. #define DSIZE    ( sizeof(struct ludir) )
  118. #define SLOTS_SEC (SECTOR/DSIZE)
  119. #define equal(s1, s2) ( strcmp(s1,s2) == 0 )
  120.  
  121. #define VERS 1        /* major revision number */
  122. #define REV 0        /* minor revision number */
  123.  
  124. /* if you don't have void type just define as blank */
  125.  
  126. #define VOID    (void)
  127.  
  128. /* if no enum's then define false as 0 and true as 1 and bool as int */
  129. /* typedef enum {false=0, true=1} bool; */
  130.  
  131. #define false 0
  132. #define true 1
  133. #define bool int
  134.  
  135. /* Globals */
  136.  
  137. char   *fname[MAXFILES];
  138. bool ftouched[MAXFILES];
  139.  
  140. typedef struct {
  141.     char   lobyte;
  142.     char   hibyte;
  143. } word;
  144.  
  145. /* convert word to int */
  146.  
  147. #define wtoi(w) ( (w.hibyte<<8) + w.lobyte)
  148. #define itow(dst,src)    dst.hibyte = (src & 0xff00) >> 8;\
  149.                 dst.lobyte = src & 0xff;
  150.  
  151. struct ludir {            /* Internal library ldir structure */
  152.     char    l_stat;        /*  status of file */
  153.     char    l_name[8];        /*  name */
  154.     char    l_ext[3];        /*  extension */
  155.     word    l_off;        /*  offset in library */
  156.     word    l_len;        /*  lengty of file */
  157.     char    l_fill[16];        /*  pad to 32 bytes */
  158. } ldir[MAXFILES];
  159.  
  160. int     errcnt, nfiles, nslots;
  161. bool    verbose = false;
  162. char    *cmdname;
  163.  
  164. char   *getname(), *sprintf();
  165. int    update(), reorg(), table(), extract(), print(), delete();
  166.  
  167.  
  168.  
  169. main (argc, argv)
  170. int    argc;
  171. char  **argv;
  172. {
  173.     register char *flagp;
  174.     char   *aname;            /* name of library file */
  175.     int       (*function)() = NULL;    /* function to do on library */
  176. /* set the function to be performed, but detect conflicts */
  177. #define setfunc(val)    if(function != NULL) conflict(); else function = val
  178.  
  179. #ifdef UNIX
  180.     cmdname = argv[0];
  181. #else
  182.     cmdname = "LU";
  183.  
  184.     printf ("\n%s - library maintenance utility, CP/M-86 version %d.%d\n\n",
  185.      cmdname,VERS,REV);
  186. #endif /* UNIX */
  187.  
  188.     if (argc < 3)
  189.     help ();
  190.  
  191. #ifdef UNIX
  192.     aname = argv[2];
  193. #else
  194.     ucase (aname,argv[2]);    /* get library name /*
  195. #endif /* UNIX */
  196.  
  197.     filenames (argc, argv);
  198.  
  199.     for(flagp = argv[1]; *flagp; flagp++)
  200.     switch (*flagp) {
  201.     case '-':
  202.         break;
  203.     case 'u': 
  204.         setfunc(update);
  205.         break;
  206.     case 't': 
  207.         setfunc(table);
  208.         break;
  209.     case 'e': 
  210.         setfunc(extract);
  211.         break;
  212.     case 'p': 
  213.         setfunc(print);
  214.         break;
  215.     case 'd': 
  216.         setfunc(delete);
  217.         break;
  218.     case 'r': 
  219.         setfunc(reorg);
  220.         break;
  221.     case 'v':
  222.         verbose = true;
  223.         break;
  224.     default: 
  225.         help ();
  226.     }
  227.  
  228.     if(function == NULL) {
  229.     fprintf(stderr,"No function key letter specified\n");
  230.     help();
  231.     }
  232.  
  233.     (*function)(aname);
  234. }
  235.  
  236. /* print error message and exit */
  237. help () {
  238.     fprintf (stderr, "Usage: %s {utepdr}[v] library [files] ...\n", cmdname);
  239.     fprintf (stderr, "Functions are:\n\tu - Update, add files to library\n");
  240.     fprintf (stderr, "\tt - Table of contents\n");
  241.     fprintf (stderr, "\te - Extract files from library\n");
  242.     fprintf (stderr, "\tp - Print files in library\n");
  243.     fprintf (stderr, "\td - Delete files in library\n");
  244.     fprintf (stderr, "\tr - Reorginize library\n");
  245.  
  246.     fprintf (stderr, "Flags are:\n\tv - Verbose\n");
  247.     exit (1);
  248. }
  249.  
  250. conflict() {
  251.    fprintf(stderr,"Conficting keys\n");
  252.    help();
  253. }
  254.  
  255. error (str)
  256. char   *str;
  257. {
  258.     fprintf (stderr, "%s: %s\n", cmdname, str);
  259.     exit (1);
  260. }
  261.  
  262. cant (name)
  263. char   *name;
  264. {
  265.     extern int  errno;
  266.     extern char *sys_errlist[];
  267.  
  268.     fprintf (stderr, "%s: %s\n", name, sys_errlist[errno]);
  269.     exit (1);
  270. }
  271.  
  272. /* Get file names, check for dups, and initialize */
  273. filenames (ac, av)
  274. char  **av;
  275. {
  276.     register int    i, j;
  277.     register char *cp, *dp;
  278.  
  279.     errcnt = 0;
  280.     for (i = 0; i < ac - 3; i++) {
  281. #ifdef UNIX
  282.     fname[i] = av[i + 3];
  283. #else
  284.     ucase (fname[i],av[i + 3]);
  285. #endif /* UNIX */
  286.  
  287.     ftouched[i] = false;
  288.     if (i == MAXFILES)
  289.         error ("Too many file names.");
  290.     }
  291.     fname[i] = NULL;
  292.     nfiles = i;
  293.     for (i = 0; i < nfiles; i++)
  294.     for (j = i + 1; j < nfiles; j++)
  295.         if (equal (fname[i], fname[j])) {
  296.         fprintf (stderr, "%s", fname[i]);
  297.         error (": duplicate file name");
  298.         }
  299. }
  300.  
  301. table (lib)
  302. char   *lib;
  303. {
  304.     FILE   *lfd;
  305.     register int    i, total;
  306.     int active = 0, unused = 0, deleted = 0;
  307.     char *uname;
  308.  
  309.     if ((lfd = fopenb (lib, "r")) == NULL)
  310.     cant (lib);
  311.  
  312.     getdir (lfd);
  313.     total = wtoi(ldir[0].l_len);
  314.     if(verbose) {
  315.      printf("Name          Index Length\n");
  316.     printf("Directory           %4d\n", total);
  317.     }
  318.  
  319.     for (i = 1; i < nslots; i++)
  320.     switch(ldir[i].l_stat) {
  321.     case ACTIVE:
  322.         active++;
  323.         uname = getname(ldir[i].l_name, ldir[i].l_ext);
  324.         if (filarg (uname))
  325.             if(verbose)
  326.             printf ("%-12s   %4d %4d\n", uname,
  327.                 wtoi (ldir[i].l_off), wtoi (ldir[i].l_len));
  328.             else
  329.             printf ("%s\n", uname);
  330.         total += wtoi(ldir[i].l_len);
  331.         break;
  332.     case UNUSED:
  333.         unused++;
  334.         break;
  335.     default:
  336.         deleted++;
  337.     }
  338.     if(verbose) {
  339.     printf("--------------------------\n");
  340.     printf("Total sectors       %4d\n", total);
  341.     printf("\nLibrary %s has %d slots, %d deleted, %d active, %d unused\n",
  342.         lib, nslots, deleted, active, unused);
  343.     }
  344.  
  345.     VOID fclose (lfd);
  346.     not_found ();
  347. }
  348.  
  349. getdir (f)
  350. FILE *f;
  351. {
  352.  
  353.     rewind(f);
  354.  
  355.     if (fread ((char *) & ldir[0], DSIZE, 1, f) != 1)
  356.     error ("No directory\n");
  357.  
  358.     nslots = wtoi (ldir[0].l_len) * SLOTS_SEC;
  359.  
  360.     if (fread ((char *) & ldir[1], DSIZE, nslots, f) != nslots)
  361.     error ("Can't read directory - is it a library?");
  362. }
  363.  
  364. putdir (f)
  365. FILE *f;
  366. {
  367.  
  368.     rewind(f);
  369.     if (fwrite ((char *) ldir, DSIZE, nslots, f) != nslots)
  370.     error ("Can't write directory - library may be botched");
  371. }
  372.  
  373. initdir (f)
  374. FILE *f;
  375. {
  376.     register int    i;
  377.     int     numsecs;
  378.     char    line[80];
  379.     static struct ludir blankentry = {
  380.     UNUSED,
  381.     "        ",
  382.     "   "
  383.     };
  384.  
  385.     for (;;) {
  386.     printf ("Number of slots to allocate: ");
  387.     if (fgets (line, 80, stdin) == NULL)
  388.         error ("EOF when reading input");
  389.     nslots = atoi (line);
  390.     if (nslots < 1)
  391.         printf ("Must have at least one!\n");
  392.     else if (nslots > MAXFILES)
  393.         printf ("Too many slots\n");
  394.     else
  395.         break;
  396.     }
  397.  
  398.     numsecs = nslots / SLOTS_SEC;
  399.     nslots = numsecs * SLOTS_SEC;
  400.  
  401.     for (i = 0; i < nslots; i++)
  402.     ldir[i] = blankentry;
  403.     ldir[0].l_stat = ACTIVE;
  404.     itow (ldir[0].l_len, numsecs);
  405.  
  406.     putdir (f);
  407. }
  408.  
  409. ucase (ustring,lstring)
  410.  
  411. char *ustring, *lstring;
  412.  
  413. {
  414.     register char *cp, *dp;
  415.  
  416.     for (cp = ustring, dp = lstring; *dp != '\0';)
  417.     {
  418.         *cp++ = islower (*dp) ? toupper (*dp) : *dp;
  419.         ++dp;
  420.     }
  421.     *cp = '\0';
  422. }
  423.  
  424. /* convert nm.ex to a Unix style string */
  425. char   *getname (nm, ex)
  426. char   *nm, *ex;
  427. {
  428.     static char namebuf[14];
  429.     register char  *cp, *dp;
  430.  
  431.     for (cp = namebuf, dp = nm; *dp != ' ' && dp != &nm[8];) {
  432.     *cp++ = islower (*dp) ? toupper (*dp) : *dp;
  433.     ++dp;
  434.     }
  435.     *cp++ = '.';
  436.  
  437.     for (dp = ex; *dp != ' ' && dp != &ex[3];) {
  438.     *cp++ = islower (*dp) ? toupper (*dp) : *dp;
  439.     ++dp;
  440.     }
  441.  
  442.     *cp = '\0';
  443.     return namebuf;
  444. }
  445.  
  446. putname (cpmname, unixname)
  447. char   *cpmname, *unixname;
  448. {
  449.     register char  *p1, *p2;
  450.  
  451.     for (p1 = unixname, p2 = cpmname; *p1; p1++, p2++) {
  452.     while (*p1 == '.') {
  453.         p2 = cpmname + 8;
  454.         p1++;
  455.     }
  456.     if (p2 - cpmname < 11)
  457.         *p2 = islower(*p1) ? toupper(*p1) : *p1;
  458.     else {
  459.         fprintf (stderr, "%s: name truncated\n", unixname);
  460.         break;
  461.     }
  462.     }
  463.     while (p2 - cpmname < 11)
  464.     *p2++ = ' ';
  465. }
  466.  
  467. /* filarg - check if name matches argument list */
  468. filarg (name)
  469. char   *name;
  470. {
  471.     register int    i;
  472.  
  473.     if (nfiles <= 0)
  474.     return 1;
  475.  
  476.     for (i = 0; i < nfiles; i++)
  477.     if (equal (name, fname[i])) {
  478.         ftouched[i] = true;
  479.         return 1;
  480.     }
  481.  
  482.     return 0;
  483. }
  484.  
  485. not_found () {
  486.     register int    i;
  487.  
  488.     for (i = 0; i < nfiles; i++)
  489.     if (!ftouched[i]) {
  490.         fprintf (stderr, "%s: not in library.\n", fname[i]);
  491.         errcnt++;
  492.     }
  493. }
  494.  
  495. extract(name)
  496. char *name;
  497. {
  498.     getfiles(name, false);
  499. }
  500.  
  501. print(name)
  502. char *name;
  503. {
  504.     getfiles(name, true);
  505. }
  506.  
  507. getfiles (name, pflag)
  508. char   *name;
  509. bool    pflag;
  510. {
  511.     FILE *lfd, *ofd;
  512.     register int    i;
  513.     char   *unixname;
  514.  
  515.     if ((lfd = fopenb (name, "r"))  == NULL)
  516.     cant (name);
  517.  
  518.     ofd = pflag ? stdout : NULL;
  519.     getdir (lfd);
  520.  
  521.     for (i = 1; i < nslots; i++) {
  522.     if(ldir[i].l_stat != ACTIVE)
  523.         continue;
  524.     unixname = getname (ldir[i].l_name, ldir[i].l_ext);
  525.     if (!filarg (unixname))
  526.         continue;
  527.     fprintf(stderr,"%s", unixname);
  528.     if (ofd != stdout)
  529.         ofd = fopenb (unixname, "w");
  530.     if (ofd == NULL) {
  531.         fprintf (stderr, "  - can't create");
  532.         errcnt++;
  533.     }
  534.     else {
  535.         VOID fseek (lfd, (long) wtoi (ldir[i].l_off) * SECTOR, 0);
  536.         acopy (lfd, ofd, wtoi (ldir[i].l_len));
  537.         if (ofd != stdout)
  538.         VOID fclose (ofd);
  539.     }
  540.     putc('\n', stderr);
  541.     }
  542.     VOID fclose (lfd);
  543.     not_found ();
  544. }
  545.  
  546. acopy (fdi, fdo, nsecs)
  547. FILE *fdi, *fdo;
  548. register unsigned int nsecs;
  549. {
  550.     register int    i, c;
  551.     int        textfile = 1;
  552.  
  553.     while( nsecs-- != 0) 
  554.     for(i=0; i<SECTOR; i++) {
  555.         c = getc(fdi);
  556.         if( feof(fdi) ) 
  557.             error("Premature EOF\n");
  558.         if( ferror(fdi) )
  559.             error ("Can't read");
  560.         if( !isascii(c) )
  561.             textfile = 0;
  562.         if( nsecs != 0 || !textfile || c != CTRLZ) {
  563.             putc(c, fdo);
  564.             if ( ferror(fdo) )
  565.                 error ("write error");
  566.         }
  567.      }
  568. }
  569.  
  570. update (name)
  571. char   *name;
  572. {
  573.     FILE *lfd;
  574.     register int    i;
  575.  
  576.     if ((lfd = fopenb (name, "r+")) == NULL) {
  577.     if ((lfd = fopenb (name, "w+")) == NULL)
  578.         cant (name);
  579.     initdir (lfd);
  580.     }
  581.     else
  582.     getdir (lfd);        /* read old directory */
  583.  
  584.     if(verbose)
  585.         fprintf (stderr,"Updating files:\n");
  586.     for (i = 0; i < nfiles; i++)
  587.     addfil (fname[i], lfd);
  588.     if (errcnt == 0)
  589.     putdir (lfd);
  590.     else
  591.     fprintf (stderr, "fatal errors - library not changed\n");
  592.     VOID fclose (lfd);
  593. }
  594.  
  595. addfil (name, lfd)
  596. char   *name;
  597. FILE *lfd;
  598. {
  599.     FILE    *ifd;
  600.     register int secoffs, numsecs;
  601.     register int i;
  602.  
  603.     if ((ifd = fopenb (name, "r")) == NULL) {
  604.     fprintf (stderr, "%s: can't find to add\n",name);
  605.     errcnt++;
  606.     return;
  607.     }
  608.     if(verbose)
  609.         fprintf(stderr, "%s\n", name);
  610.     for (i = 0; i < nslots; i++) {
  611.     if (equal( getname (ldir[i].l_name, ldir[i].l_ext), name) ) /* update */
  612.         break;
  613.     if (ldir[i].l_stat != ACTIVE)
  614.         break;
  615.     }
  616.     if (i >= nslots) {
  617.     fprintf (stderr, "%s: can't add library is full\n",name);
  618.     errcnt++;
  619.     return;
  620.     }
  621.  
  622.     ldir[i].l_stat = ACTIVE;
  623.     putname (ldir[i].l_name, name);
  624.     VOID fseek(lfd, 0L, 2);        /* append to end */
  625.     secoffs = ftell(lfd) / SECTOR;
  626.  
  627.     itow (ldir[i].l_off, secoffs);
  628.     numsecs = fcopy (ifd, lfd);
  629.     itow (ldir[i].l_len, numsecs);
  630.     VOID fclose (ifd);
  631. }
  632.  
  633. fcopy (ifd, ofd)
  634. FILE *ifd, *ofd;
  635. {
  636.     register int total = 0;
  637.     register int i, n;
  638.     char sectorbuf[SECTOR];
  639.  
  640.  
  641.     while ( (n = fread( sectorbuf, 1, SECTOR, ifd)) != 0) {
  642.     if (n != SECTOR)
  643.         for (i = n; i < SECTOR; i++)
  644.         sectorbuf[i] = CTRLZ;
  645.     if (fwrite( sectorbuf, 1, SECTOR, ofd ) != SECTOR)
  646.         error("write error");
  647.     ++total;
  648.     }
  649.     return total;
  650. }
  651.  
  652. delete (lname)
  653. char   *lname;
  654. {
  655.     FILE *f;
  656.     register int    i;
  657.  
  658.     if ((f = fopenb (lname, "r+")) == NULL)
  659.     cant (lname);
  660.  
  661.     if (nfiles <= 0)
  662.     error("delete by name only");
  663.  
  664.     getdir (f);
  665.     for (i = 0; i < nslots; i++) {
  666.     if (!filarg ( getname (ldir[i].l_name, ldir[i].l_ext)))
  667.         continue;
  668.     ldir[i].l_stat = DELETED;
  669.     }
  670.  
  671.     not_found();
  672.     if (errcnt > 0)
  673.     fprintf (stderr, "errors - library not updated\n");
  674.     else
  675.     putdir (f);
  676.     VOID fclose (f);
  677. }
  678.  
  679. reorg (name)
  680. char  *name;
  681. {
  682.     FILE *olib, *nlib;
  683.     int oldsize;
  684.     register int i, j;
  685.     struct ludir odir[MAXFILES];
  686.     char tmpname[SECTOR];
  687.  
  688.     VOID sprintf(tmpname,"%-10.10s.TMP", name);
  689.  
  690.     if( (olib = fopenb(name,"r")) == NULL)
  691.     cant(name);
  692.  
  693.     if( (nlib = fopenb(tmpname, "w")) == NULL)
  694.     cant(tmpname);
  695.  
  696.     getdir(olib);
  697.     printf("Old library has %d slots\n", oldsize = nslots);
  698.     for(i = 0; i < nslots ; i++)
  699.         copymem( (char *) &odir[i], (char *) &ldir[i],
  700.             sizeof(struct ludir));
  701.     initdir(nlib);
  702.     errcnt = 0;
  703.  
  704.     for (i = j = 1; i < oldsize; i++)
  705.     if( odir[i].l_stat == ACTIVE ) {
  706.         if(verbose)
  707.         fprintf(stderr, "Copying: %-8.8s.%3.3s\n",
  708.             odir[i].l_name, odir[i].l_ext);
  709.         copyentry( &odir[i], olib,  &ldir[j], nlib);
  710.         if (++j >= nslots) {
  711.         errcnt++;
  712.         fprintf(stderr, "Not enough room in new library\n");
  713.         break;
  714.         }
  715.         }
  716.  
  717.     VOID fclose(olib);
  718.     putdir(nlib);
  719.     VOID fclose (nlib);
  720.  
  721.     if(errcnt == 0) {
  722.     if ( unlink(name) < 0 || rename(tmpname, name) < 0) {
  723.         VOID unlink(tmpname);
  724.         cant(name);
  725.         }
  726.     }
  727.     else
  728.     fprintf(stderr,"Errors, library not updated\n");
  729.     VOID unlink(tmpname);
  730.  
  731. }
  732.  
  733. copyentry( old, of, new, nf )
  734. struct ludir *old, *new;
  735. FILE *of, *nf;
  736. {
  737.     register int secoffs, numsecs;
  738.     char buf[SECTOR];
  739.  
  740.     new->l_stat = ACTIVE;
  741.     copymem(new->l_name, old->l_name, 8);
  742.     copymem(new->l_ext, old->l_ext, 3);
  743.     VOID fseek(of, (long) wtoi(old->l_off)*SECTOR, 0);
  744.     VOID fseek(nf, 0L, 2);
  745.     secoffs = ftell(nf) / SECTOR;
  746.  
  747.     itow (new->l_off, secoffs);
  748.     numsecs = wtoi(old->l_len);
  749.     itow (new->l_len, numsecs);
  750.  
  751.     while(numsecs-- != 0) {
  752.     if( fread( buf, 1, SECTOR, of) != SECTOR)
  753.         error("read error");
  754.     if( fwrite( buf, 1, SECTOR, nf) != SECTOR)
  755.         error("write error");
  756.     }
  757. }
  758.  
  759. copymem(dst, src, n)
  760. register char *dst, *src;
  761. register unsigned int n;
  762. {
  763.     while(n-- != 0)
  764.         *dst++ = *src++;
  765. }
  766.