home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume1 / bed < prev    next >
Internet Message Format  |  1986-11-30  |  20KB

  1. From: "Stephen J. Muir" <decvax!mcvax!stephen@lancs.comp>
  2. Date: Tue, 4 Jun 85 02:41:16 bst
  3. Newsgroups: mod.sources
  4. Subject: Bed version 1.0 (editor for binary files).
  5. Reply-To: "Stephen J. Muir" <stephen@dcl-cs.UUCP>
  6. Organization: Department of Computing at Lancaster University.
  7.  
  8. #!/bin/sh
  9. echo 'Start of pack.out, part 01 of 01:'
  10. echo 'x - Makefile'
  11. sed 's/^X//' > Makefile << '/'
  12. XDESTBIN=/usr/local
  13. XDESTMAN=/usr/man/mann/bed.n
  14. XCFLAGS=-O
  15. XOBJECTS=bed.o getcom.o quest.o
  16. X# The type whose width is 1 byte.
  17. XW8=char
  18. X# The type whose width is 2 bytes.
  19. XW16=short
  20. X# The type whose width is 4 bytes.
  21. XW32=int
  22. X# The default editor.
  23. XEDITOR=/usr/ucb/vi
  24. X
  25. Xbed:    ${OBJECTS}
  26. X    cc ${OBJECTS} -o $@
  27. X
  28. Xbed.o:    bed.c
  29. X    cc -c ${CFLAGS} -DW8=${W8} -DW16=${W16} -DW32=${W32} \
  30. X    -DEDITOR=\"${EDITOR}\" bed.c
  31. X
  32. Xinstall:bed
  33. X    install -s bed ${DESTBIN}
  34. X    cp bed.n ${DESTMAN}
  35. X
  36. Xclean:
  37. X    rm -f bed *.o
  38. /
  39. echo 'x - bed.c'
  40. sed 's/^X//' > bed.c << '/'
  41. X/* Written by Stephen J. Muir, Computing Dept., Lancaster University */
  42. X
  43. X# include <sys/types.h>
  44. X# include <sys/stat.h>
  45. X# include <sys/file.h>
  46. X# include <stdio.h>
  47. X# include <signal.h>
  48. X
  49. Xextern char    *rindex (), *mktemp (), *getenv (), *getcom (), *getpar ();
  50. X
  51. Xchar    *version = "Bed version 1.0\n";
  52. X
  53. Xchar    *filename, *editor, *ap, abuf [32],
  54. X    *tempdata = "DbedXXXXXX", *temptext = "TbedXXXXXX";
  55. X
  56. Xshort    ascii, dirty;
  57. X
  58. Xint    bits, base, width, i, count, reclen, ofd, dfd;
  59. X
  60. Xint    (*outfunc) (), (*infunc) ();
  61. X
  62. Xunsigned W32    buf    [512];
  63. X
  64. Xtime_t    t_mtime;
  65. X
  66. XFILE    *tfd;
  67. X
  68. Xstruct stat    status;
  69. X
  70. Xsyserr (name)
  71. Xchar    *name;
  72. X    { perror (name);
  73. X      unlink (tempdata);
  74. X      exit (1);
  75. X    }
  76. X
  77. Xisdigit (c)
  78. X    char    c;
  79. X    { return ('0' <= c && c <= '9');
  80. X    }
  81. X
  82. Xhexin (c)
  83. X    char    c;
  84. X    { if ('0' <= c && c <= '9')
  85. X        return (c - '0');
  86. X      c |= 040;
  87. X      if ('a' <= c && c <= 'f')
  88. X        return (10 + c - 'a');
  89. X      return (-1);
  90. X    }
  91. X
  92. Xchar
  93. Xhexout (num)
  94. X    unsigned W32    num;
  95. X    { if (num <= 9)
  96. X        return ('0' + num);
  97. X      return ('a' + num - 10);
  98. X    }
  99. X
  100. Xin8 ()
  101. X    { unsigned W8    u, *cp = (unsigned W8 *)(&buf [0]);
  102. X      char        c;
  103. X      do
  104. X      { while ((i = fgetc (tfd)) != EOF &&
  105. X           ((c = i & 0377) == ' ' || c == '\n')
  106. X          )
  107. X        if (i != EOF && hexin (c) == -1)
  108. X        return (1);
  109. X        u = hexin (c);
  110. X        while ((i = fgetc (tfd)) != EOF && hexin (c = i & 0377) != -1)
  111. X        u = u * base + hexin (c);
  112. X        if (i != EOF)
  113. X        { if (c != ' ' && c != '\n')
  114. X        return (1);
  115. X          *cp++ = u;
  116. X        }
  117. X        if (cp == ((unsigned W8 *)(&buf [0])) + reclen)
  118. X        { if (write (dfd, (char *)buf, reclen) != reclen)
  119. X        return (-1);
  120. X          cp = (unsigned W8 *)(&buf [0]);
  121. X        }
  122. X      }
  123. X      while (i != EOF);
  124. X      if ((i = cp - (unsigned W8 *)(&buf [0])) &&
  125. X          write (dfd, (char *)buf, i) != i
  126. X         )
  127. X        return (-1);
  128. X      return (0);
  129. X    }
  130. X
  131. Xout8 ()
  132. X    { unsigned W8    u = 0377, *cp;
  133. X      do
  134. X        ++width;
  135. X      while (u /= base);
  136. X      while ((i = count = read (dfd,
  137. X                    (char *)(cp = (unsigned W8 *)buf),
  138. X                    reclen
  139. X                   )
  140. X         ) > 0
  141. X        )
  142. X      { while (i)
  143. X        { if (i-- != count && fputc (' ', tfd) == EOF)
  144. X        return (-1);
  145. X          u = *cp++;
  146. X          ap = &abuf [width];
  147. X          do
  148. X          { *--ap = hexout ((unsigned W32)(u % base));
  149. X        u /= base;
  150. X          }
  151. X          while (ap != &abuf [0]);
  152. X          if (fwrite (abuf, sizeof (W8), width, tfd) == 0)
  153. X        return (-1);
  154. X        }
  155. X        if (fputc ('\n', tfd) == EOF)
  156. X        return (-1);
  157. X      }
  158. X      if (fflush (tfd) == EOF)
  159. X        return (-1);
  160. X      return (0);
  161. X    }
  162. X
  163. Xin16 ()
  164. X    { unsigned W16    u, *cp = (unsigned W16 *)(&buf [0]);
  165. X      char        c;
  166. X      do
  167. X      { while ((i = fgetc (tfd)) != EOF &&
  168. X           ((c = i & 0377) == ' ' || c == '\n')
  169. X          )
  170. X        if (i != EOF && hexin (c) == -1)
  171. X        return (1);
  172. X        u = hexin (c);
  173. X        while ((i = fgetc (tfd)) != EOF && hexin (c = i & 0377) != -1)
  174. X        u = u * base + hexin (c);
  175. X        if (i != EOF)
  176. X        { if (c != ' ' && c != '\n')
  177. X        return (1);
  178. X          *cp++ = u;
  179. X        }
  180. X        if (cp == ((unsigned W16 *)(&buf [0])) + (reclen >> 1))
  181. X        { if (write (dfd, (char *)buf, reclen) != reclen)
  182. X        return (-1);
  183. X          cp = (unsigned W16 *)(&buf [0]);
  184. X        }
  185. X      }
  186. X      while (i != EOF);
  187. X      if ((i = cp - (unsigned W16 *)(&buf [0])) &&
  188. X          write (dfd, (char *)buf, i << 1) != i << 1
  189. X         )
  190. X        return (-1);
  191. X      return (0);
  192. X    }
  193. X
  194. Xout16 ()
  195. X    { unsigned W16    u = 0177777, *cp;
  196. X      if (status.st_size & 1)
  197. X      { fprintf (stderr, "filesize is not multiple of 2\n");
  198. X        return (1);
  199. X      }
  200. X      do
  201. X        ++width;
  202. X      while (u /= base);
  203. X      while ((count = read (dfd,
  204. X                (char *)(cp = (unsigned W16 *)buf),
  205. X                reclen
  206. X                   )
  207. X         ) > 0
  208. X        )
  209. X      { if (count & 1)
  210. X        { fprintf (stderr, "read error\n");
  211. X          return (1);
  212. X        }
  213. X        i = (count >>= 1);
  214. X        while (i)
  215. X        { if (i-- != count && fputc (' ', tfd) == EOF)
  216. X        return (-1);
  217. X          u = *cp++;
  218. X          ap = &abuf [width];
  219. X          do
  220. X          { *--ap = hexout ((unsigned W32)(u % base));
  221. X        u /= base;
  222. X          }
  223. X          while (ap != &abuf [0]);
  224. X          if (fwrite (abuf, sizeof (W8), width, tfd) == 0)
  225. X        return (-1);
  226. X        }
  227. X        if (fputc ('\n', tfd) == EOF)
  228. X        return (-1);
  229. X      }
  230. X      if (fflush (tfd) == EOF)
  231. X        return (-1);
  232. X      return (0);
  233. X    }
  234. X
  235. Xin32 ()
  236. X    { unsigned W32    u, *cp = &buf [0];
  237. X      char        c;
  238. X      do
  239. X      { while ((i = fgetc (tfd)) != EOF &&
  240. X           ((c = i & 0377) == ' ' || c == '\n')
  241. X          )
  242. X        if (i != EOF && hexin (c) == -1)
  243. X        return (1);
  244. X        u = hexin (c);
  245. X        while ((i = fgetc (tfd)) != EOF && hexin (c = i & 0377) != -1)
  246. X        u = u * base + hexin (c);
  247. X        if (i != EOF)
  248. X        { if (c != ' ' && c != '\n')
  249. X        return (1);
  250. X          *cp++ = u;
  251. X        }
  252. X        if (cp == &buf [0] + (reclen >> 2))
  253. X        { if (write (dfd, (char *)buf, reclen) != reclen)
  254. X        return (-1);
  255. X          cp = &buf [0];
  256. X        }
  257. X      }
  258. X      while (i != EOF);
  259. X      if ((i = cp - &buf [0]) && write (dfd, (char *)buf, i << 2) != i << 2)
  260. X        return (-1);
  261. X      return (0);
  262. X    }
  263. X
  264. Xout32 ()
  265. X    { unsigned W32    u = 037777777777, *cp;
  266. X      if (status.st_size & 3)
  267. X      { fprintf (stderr, "filesize is not multiple of 4\n");
  268. X        return (1);
  269. X      }
  270. X      do
  271. X        ++width;
  272. X      while (u /= base);
  273. X      while ((count = read (dfd,
  274. X                (char *)(cp = (unsigned W32 *)buf),
  275. X                reclen
  276. X                   )
  277. X         ) > 0
  278. X        )
  279. X      { if (count & 3)
  280. X        { fprintf (stderr, "read error\n");
  281. X          return (1);
  282. X        }
  283. X        i = (count >>= 2);
  284. X        while (i)
  285. X        { if (i-- != count && fputc (' ', tfd) == EOF)
  286. X        return (-1);
  287. X          u = *cp++;
  288. X          ap = &abuf [width];
  289. X          do
  290. X          { *--ap = hexout (u % base);
  291. X        u /= base;
  292. X          }
  293. X          while (ap != &abuf [0]);
  294. X          if (fwrite (abuf, sizeof (W8), width, tfd) == 0)
  295. X        return (-1);
  296. X        }
  297. X        if (fputc ('\n', tfd) == EOF)
  298. X        return (-1);
  299. X      }
  300. X      if (fflush (tfd) == EOF)
  301. X        return (-1);
  302. X      return (0);
  303. X    }
  304. X
  305. Xoutasc ()
  306. X    { char    c, *cp;
  307. X      while ((i = count = read (dfd, cp = (char *)buf, reclen)) > 0)
  308. X      { while (i--)
  309. X        { if (' ' <= (c = *cp++) && c <= '~' && c != '\\')
  310. X          { if (fputc (c, tfd) == EOF)
  311. X            return (-1);
  312. X          }
  313. X          else
  314. X          { if (fputc ('\\', tfd) == EOF)
  315. X            return (-1);
  316. X        switch (c)
  317. X        { case '\b':
  318. X            c = 'b';
  319. X            break;
  320. X          case '\t':
  321. X            c = 't';
  322. X            break;
  323. X          case '\f':
  324. X            c = 'f';
  325. X            break;
  326. X          case '\n':
  327. X            c = 'n';
  328. X            break;
  329. X          case '\r':
  330. X            c = 'r';
  331. X            break;
  332. X          case '\\':
  333. X            break;
  334. X          default:
  335. X            if (fputc ('0' + ((c >> 6) & 3), tfd) == EOF ||
  336. X            fputc ('0' + ((c >> 3) & 7), tfd) == EOF
  337. X               )
  338. X            return (-1);
  339. X            c = '0' + (c & 7);
  340. X            break;
  341. X        }
  342. X        if (fputc (c, tfd) == EOF)
  343. X            return (-1);
  344. X          }
  345. X        }
  346. X        if (fputc ('\n', tfd) == EOF)
  347. X        return (-1);
  348. X      }
  349. X      if (fflush (tfd) == EOF)
  350. X        return (-1);
  351. X      return (0);
  352. X    }
  353. X
  354. Xinasc ()
  355. X    { char    c, newc;
  356. X      int    ret = 0;
  357. X      FILE    *mydfd;
  358. X      if ((mydfd = fdopen (dfd, "r+")) == NULL)
  359. X        return (-1);
  360. X      while ((i = fgetc (tfd)) != EOF)
  361. X      { c = i & 0377;
  362. X        if (c == '\n')
  363. X        continue;
  364. X        if (' ' <= c && c <= '~' && c != '\\')
  365. X        { if (fputc (c, mydfd) == EOF)
  366. X        goto sysfail;
  367. X          continue;
  368. X        }
  369. X        if (c != '\\' || (i = fgetc (tfd)) == EOF)
  370. X        goto fail;
  371. X        switch (c = i & 0377)
  372. X        { case 'b':
  373. X        c = '\b';
  374. X        break;
  375. X          case 't':
  376. X        c = '\t';
  377. X        break;
  378. X          case 'f':
  379. X        c = '\f';
  380. X        break;
  381. X          case 'n':
  382. X        c = '\n';
  383. X        break;
  384. X          case 'r':
  385. X        c = '\r';
  386. X        break;
  387. X          case '\\':
  388. X        break;
  389. X          default:
  390. X        if (c < '0' || c > '3')
  391. X            goto fail;
  392. X        newc = (c - '0') << 6;
  393. X        if ((i = fgetc (tfd)) == EOF || (c = i & 0377) < '0' || c > '7')
  394. X            goto fail;
  395. X        newc |= (c - '0') << 3;
  396. X        if ((i = fgetc (tfd)) == EOF || (c = i & 0377) < '0' || c > '7')
  397. X            goto fail;
  398. X        c = newc | (c - '0');
  399. X        break;
  400. X        }
  401. X        fputc (c, mydfd);
  402. X        if (ferror (mydfd))
  403. X        goto sysfail;
  404. X      }
  405. X      goto out;
  406. Xsysfail:  --ret;
  407. X      goto out;
  408. Xfail:      ++ret;
  409. Xout:      dfd = dup (dfd);
  410. X      if (fclose (mydfd) == EOF)
  411. X        return (-1);
  412. X      return (ret);
  413. X    }
  414. X
  415. Xcopyorig ()
  416. X    { lseek (ofd, 0, 0);
  417. X      lseek (dfd, 0, 0);
  418. X      ftruncate (dfd, 0);
  419. X      while ((count = read (ofd, (char *)buf, sizeof (buf))) > 0)
  420. X        if (write (dfd, (char *)buf, count) != count)
  421. X            syserr (tempdata);
  422. X      if (count < 0)
  423. X        syserr (filename);
  424. X      dirty = 0;
  425. X    }
  426. X
  427. Xedit ()
  428. X    { int    pid;
  429. X      if (base < 2 || base > 16)
  430. X      { printf ("Radix must be between 2 and 16 inclusive.\n");
  431. X        return;
  432. X      }
  433. X      switch (bits)
  434. X      { case 8:
  435. X          outfunc = out8;
  436. X          infunc = in8;
  437. X          break;
  438. X        case 16:
  439. X          outfunc = out16;
  440. X          infunc = in16;
  441. X          break;
  442. X        case 32:
  443. X          outfunc = out32;
  444. X          infunc = in32;
  445. X          break;
  446. X        default:
  447. X          printf ("This program can only manage 8, 16 or 32 bit formats\n");
  448. X          return;
  449. X      }
  450. X      if (ascii)
  451. X      { outfunc = outasc;
  452. X        infunc = inasc;
  453. X      }
  454. X      else if (reclen % (bits >> 3))
  455. X      { printf ("Record length is not a multiple of %d.\n", bits >> 3);
  456. X        return;
  457. X      }
  458. X      if (reclen < 1)
  459. X      { printf ("Record length is too small.\n");
  460. X        return;
  461. X      }
  462. X      if ((tfd = fopen (temptext, "w+")) == NULL)
  463. X        syserr (temptext);
  464. X      lseek (dfd, 0, 0);
  465. X      width = 0;
  466. X      fstat (dfd, &status);
  467. X      printf ("Preparing for edit.\n");
  468. X      if ((i = (*outfunc) ()) < 0)
  469. X        perror (temptext);
  470. X      if (i)
  471. X        goto out;
  472. X      fstat (fileno (tfd), &status);
  473. X      t_mtime = status.st_mtime;
  474. X      while ((pid = fork ()) == -1);
  475. X      if (pid == 0)
  476. X      { execlp (editor, editor, temptext, 0);
  477. X        perror (editor);
  478. X        exit (1);
  479. X      }
  480. X      wait (0);
  481. X      fstat (fileno (tfd), &status);
  482. X      if (status.st_mtime != t_mtime)
  483. X      { fseek (tfd, 0, 0);
  484. X        lseek (dfd, 0, 0);
  485. X        ftruncate (dfd, 0);
  486. X        printf ("Copying back changes.\n");
  487. X        if ((i = (*infunc) ()) < 0)
  488. X        { perror (tempdata);
  489. X          goto out;
  490. X        }
  491. X        if (i)
  492. X        { printf ("%s: bad format - original file restored\n", temptext);
  493. X          copyorig ();
  494. X        }
  495. X        else
  496. X        ++dirty;
  497. X      }
  498. Xout:      fclose (tfd);
  499. X      unlink (temptext);
  500. X    }
  501. X
  502. X/*ARGSUSED*/
  503. Xmain (argc, argv, envp)
  504. X    char    *argv [], *envp [];
  505. X    { char    *command;
  506. X      if (!isatty (0))
  507. X      { fprintf (stderr, "Standard input is not a tty.\n");
  508. X        exit (1);
  509. X      }
  510. X      while (--argc && **++argv == '-' && *(*argv + 1))
  511. X      { ++*argv;
  512. X        while (**argv)
  513. X        { switch (*(*argv)++)
  514. X          { case 'c':
  515. X        case 'a':
  516. X          if (ascii++)
  517. X            goto usage;
  518. X          break;
  519. X        case 'r':
  520. X          if (base)
  521. X            goto usage;
  522. X          while (isdigit (**argv))
  523. X            base = base * 10 + *(*argv)++ - '0';
  524. X          break;
  525. X        case 'b':
  526. X          if (bits)
  527. X            goto usage;
  528. X          while (isdigit (**argv))
  529. X            bits = bits * 10 + *(*argv)++ - '0';
  530. X          break;
  531. X        case 'l':
  532. X          if (reclen)
  533. X            goto usage;
  534. X          while (isdigit (**argv))
  535. X            reclen = reclen * 10 + *(*argv)++ - '0';
  536. X          break;
  537. X        default:
  538. Xusage:          fprintf (stderr,
  539. X               "usage: bed [-c] [-r#] [-b#] [-l#] file\n"
  540. X              );
  541. X          exit (1);
  542. X          }
  543. X        }
  544. X      }
  545. X      if (bits == 0)
  546. X        bits = 16;
  547. X      if (reclen == 0)
  548. X        reclen = 16;
  549. X      if (base == 0)
  550. X        base = 8;
  551. X      if (argc != 1)
  552. X        goto usage;
  553. X      if (filename = rindex (*argv, '/'))
  554. X      { *filename = '\0';
  555. X        if (*(ap = *argv) == '\0')
  556. X        ap = "/";
  557. X        if (chdir (ap) == -1)
  558. X        syserr (ap);
  559. X        *filename++ = '/';
  560. X      }
  561. X      else
  562. X        filename = *argv;
  563. X      if ((ofd = open (filename, O_RDWR, 0)) == -1)
  564. X        syserr (*argv);
  565. X      if (flock (ofd, LOCK_EX | LOCK_NB) == -1)
  566. X      { fprintf (stderr, "%s: waiting for lock to be released\n", *argv);
  567. X        flock (ofd, LOCK_EX);
  568. X      }
  569. X      fstat (ofd, &status);
  570. X      if ((status.st_mode & S_IFMT) != S_IFREG)
  571. X      { printf ("%s: not regular file\n", *argv);
  572. X        exit (1);
  573. X      }
  574. X      signal (SIGINT, SIG_IGN);
  575. X      umask (0);
  576. X      mktemp (tempdata);
  577. X      mktemp (temptext);
  578. X      if ((dfd = open (tempdata, O_RDWR | O_CREAT, status.st_mode)) == -1)
  579. X        syserr (tempdata);
  580. X      if ((editor = getenv ("VISUAL")) == 0 &&
  581. X          (editor = getenv ("EDITOR")) == 0
  582. X         )
  583. X        editor = EDITOR;
  584. X      copyorig ();
  585. X      for (;;)
  586. X      { while ((command = getcom ("command: ")) == 0);
  587. X        switch (*command)
  588. X        { case 'w':
  589. X        if (!dirty &&
  590. X            !quest ("File has not been modified; are you sure? ")
  591. X           )
  592. X            break;
  593. X        if (rename (tempdata, filename) == -1)
  594. X        { perror ("rename()");
  595. X          fprintf (stderr, "new file is in \"%s\"\n", tempdata);
  596. X          exit (1);
  597. X        }
  598. X        exit (0);
  599. X          case 'q':
  600. X        if (dirty && !quest ("File has been modified; are you sure? "))
  601. X            break;
  602. X        unlink (tempdata);
  603. X        exit (0);
  604. X          case 'e':
  605. X        edit ();
  606. X        break;
  607. X          case 'c':
  608. X          case 'a':
  609. X        printf ("%sow in ascii mode.\n",
  610. X            (ascii = !ascii) ? "N" : "Not n"
  611. X               );
  612. X        break;
  613. X          case 'r':
  614. X        printf ("Radix is now %d.\n", base = atoi (getpar ("radix? ")));
  615. X        break;
  616. X          case 'b':
  617. X        printf ("Word size is now %d bits.\n",
  618. X            bits = atoi (getpar ("bits? "))
  619. X               );
  620. X        break;
  621. X          case 'l':
  622. X        printf ("Record length is now %d bytes.\n",
  623. X            reclen = atoi (getpar ("record length? "))
  624. X               );
  625. X        break;
  626. X          case 'h':
  627. X          case '?':
  628. X        printf ("The following commands are available:\n");
  629. X        printf ("h - print out help\n");
  630. X        printf ("? - print out help\n");
  631. X        printf ("a - ascii toggle\n");
  632. X        printf ("c - ascii toggle\n");
  633. X        printf ("r - set radix\n");
  634. X        printf ("b - set number of bits in word\n");
  635. X        printf ("l - set record length\n");
  636. X        printf ("e - edit\n");
  637. X        printf ("w - write out file and quit\n");
  638. X        printf ("q - quit\n");
  639. X        printf ("radix = %d, bits = %d,", base, bits);
  640. X        printf (" length of record = %d bytes%s.\n",
  641. X            reclen,
  642. X            ascii ? ", ascii mode" : ""
  643. X               );
  644. X        break;
  645. X          default:
  646. X        printf ("Invalid command -- type 'h' for help.\n");
  647. X        break;
  648. X        }
  649. X      }
  650. X    }
  651. /
  652. echo 'x - bed.n'
  653. sed 's/^X//' > bed.n << '/'
  654. X.TH BED 1 "4 June 1985"
  655. X.SH NAME
  656. Xbed \- an editor for binary files
  657. X.SH SYNOPSIS
  658. X.B bed [-c] [-r#] [-b#] [-l#] file
  659. X.SH DESCRIPTION
  660. X.B Bed
  661. Xis an editor for binary files.
  662. XIt converts the binary file to a textual format,
  663. Xallows the user to edit that textual format,
  664. Xthen converts the textual format back into binary format.
  665. X.SH OPTIONS
  666. X.PP
  667. XThe following options are recognised, and may be run together,
  668. Xe.g. "bed -l120 -c" and "bed -l120c" are equivalent:
  669. X.TP 8
  670. X-c
  671. XSet initial mode to ascii.
  672. X.TP 8
  673. X-a
  674. XSame as above.
  675. X.TP 8
  676. X-r#
  677. XSet initial radix to #.
  678. X.TP 8
  679. X-b#
  680. XSet initial word size to # bits.
  681. X.TP 8
  682. X-l#
  683. XSet initial record length (in bytes) to #.
  684. X.SH COMMANDS
  685. X.PP
  686. XOnce
  687. X.B bed
  688. Xhas validated everything,
  689. Xit takes a copy of the data file and enters command mode.
  690. XThe following commands are recognised:
  691. X.TP 8
  692. Xh
  693. XPrint out help and current modes.
  694. X.TP 8
  695. X?
  696. XSame as above.
  697. X.TP 8
  698. Xc
  699. XToggle ascii mode.
  700. X.TP 8
  701. Xa
  702. XSame as above.
  703. X.TP 8
  704. Xr #
  705. XSet radix to #.
  706. X.TP 8
  707. Xb #
  708. XSet word size to # bits.
  709. X.TP 8
  710. Xl #
  711. XSet record length (in bytes) to #.
  712. X.TP 8
  713. Xe
  714. XConverts the data file to text format and calls up an editor on the text file.
  715. XWhen the editor terminates and, if the file has been modified,
  716. X.B bed
  717. Xwill convert the text file back into the temporary copy of the binary.
  718. X.TP 8
  719. Xw
  720. XUpdates the original binary file from the copy and exits.
  721. X.TP 8
  722. Xq
  723. XExits without updating the original.
  724. X.SH NOTES
  725. XThe user must have read/write access to the original file
  726. X.I and
  727. Xits parent directory.
  728. XThis is because a "rename" system call is used to update the original
  729. X(for atomicity).
  730. XSpaces in the text file given to the editor (even at the end of lines)
  731. Xare significant.
  732. XEach line in the text file format contains the number of characters which
  733. Xcorrespond to the
  734. X.I record
  735. Xsize.
  736. X.PP
  737. XThe following escape sequences are used in ascii mode:
  738. X.nf
  739. X
  740. X\\b    backspace
  741. X\\t    horizontal tab
  742. X\\f    form feed
  743. X\\n    newline
  744. X\\r    carriage return
  745. X\\\\    '\\' character
  746. X\\nnn    the ascii character whose code is given (in octal)
  747. X.fi
  748. X.SH ENVIRONMENT
  749. X.TP 8
  750. XVISUAL
  751. XThe editor to be used.
  752. X.TP 8
  753. XEDITOR
  754. XThe editor to be used if VISUAL is not defined.
  755. X.PP
  756. XIf neither of these are defined, a default editor will be used.
  757. X.SH BUGS
  758. X.PP
  759. XThe
  760. X.I word size
  761. Xcan only have values of 8, 16 or 32.
  762. XThe
  763. X.I radix
  764. Xcan only have values between 2 and 16 inclusive.
  765. X.PP
  766. XMail bugs to "dcl-cs!stephen".
  767. X.SH FILES
  768. X.nf
  769. XDbed??????    working copy of original data file
  770. XTbed??????    as above but in text format
  771. X.fi
  772. X.SH AUTHOR
  773. XStephen J. Muir, University of Lancaster, U.K.
  774. /
  775. echo 'x - getcom.c'
  776. sed 's/^X//' > getcom.c << '/'
  777. X# include <stdio.h>
  778. X
  779. X# define LINESIZE 82
  780. X
  781. Xchar    *parptr, comline [LINESIZE];
  782. X
  783. Xcomerr ()
  784. X    { fprintf (stderr, "getcom(): bad input\n");
  785. X    }
  786. X
  787. Xchar    *
  788. Xgetcom (prompt)
  789. X    char    *prompt;
  790. X    { register char    *old, *new;
  791. X      register short    count;
  792. X      parptr = (char *)0;
  793. X      if (prompt != (char *)0)
  794. X        fprintf (stderr, prompt);
  795. X      if ((count = read (0, comline, LINESIZE - 1)) < 0)
  796. X      { perror ("getcom()");
  797. X        return ((char *)0);
  798. X      }
  799. X      if (count == 0)
  800. X        return ((char *)0);
  801. X      if (comline [--count] != '\n')
  802. X      { comerr ();
  803. X        return ((char *)0);
  804. X      }
  805. X      comline [count] = '\0';
  806. X      if (count == 0)
  807. X        return (comline);
  808. X      for (old = new = &comline [0]; *old != '\0'; ++old)
  809. X      { if (*old == '!')
  810. X        return (old);
  811. X        if (*old != ' ' && *old != '\t')
  812. X        break;
  813. X      }
  814. X      while (*old != '\0')
  815. X      { while (*old != '\0' && *old != ' ' && *old != '\t')
  816. X        *new++ = *old++;
  817. X        while (*old == ' ' || *old == '\t')
  818. X        ++old;
  819. X        *new++ = '\0';
  820. X        if (parptr == (char *)0)
  821. X        parptr = new;
  822. X      }
  823. X      *new = '\0';
  824. X      if (*parptr == '\0')
  825. X        parptr = (char *)0;
  826. X      if (old != &comline [count])
  827. X      { comerr ();
  828. X        return ((char *)0);
  829. X      }
  830. X      return (comline);
  831. X    }
  832. X
  833. Xchar    *
  834. Xgetpar (prompt)
  835. X    char    *prompt;
  836. X    { register char    *old;
  837. X      register short    count;
  838. X      if (parptr != (char *)0)
  839. X      { old = parptr;
  840. X        while (*parptr++ != '\0');
  841. X        if (*parptr == '\0')
  842. X        parptr = (char *)0;
  843. X        return (old);
  844. X      }
  845. X      if (prompt != (char *)0)
  846. X        fprintf (stderr, prompt);
  847. X      if ((count = read (0, comline, LINESIZE - 1)) < 0)
  848. X      { perror ("getpar()");
  849. X        return ((char *)0);
  850. X      }
  851. X      if (count == 0)
  852. X        return ((char *)0);
  853. X      if (comline [--count] != '\n')
  854. X      { fprintf (stderr, "getpar(): bad input\n");
  855. X        return ((char *)0);
  856. X      }
  857. X      comline [count] = '\0';
  858. X      return (comline);
  859. X    }
  860. /
  861. echo 'x - quest.c'
  862. sed 's/^X//' > quest.c << '/'
  863. Xextern char    *getpar ();
  864. X
  865. Xquest (prompt)
  866. X    char    *prompt;
  867. X    { char    *reply;
  868. X      return ((reply = getpar (prompt)) ? ((*reply | 040) == 'y') : 0);
  869. X    }
  870. /
  871. echo 'Part 01 of pack.out complete.'
  872. exit
  873. -- 
  874. NAME:    Stephen J. Muir            Project:Alvey ECLIPSE Distribution
  875. JANET:    stephen@uk.ac.lancs.comp    DARPA:    stephen%lancs.comp@ucl-cs
  876. UUCP:    ...!ukc!icdoc!dcl-cs!stephen    PHONE:    +44 524 65201 Ext. 4599
  877. POST:    Department of Computing, University of Lancaster, Bailrigg, Lancaster.
  878.     LA1 4YR
  879.  
  880.