home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume10 / cbw / part07 / dblock.c next >
Encoding:
C/C++ Source or Header  |  1987-06-17  |  18.0 KB  |  912 lines

  1. /*
  2.  * Decrytion block and its label.
  3.  *
  4.  * Robert W. Baldwin, December 1984.
  5.  */
  6.  
  7.  
  8. #include    <stdio.h>
  9. #include    "window.h"
  10. #include    "terminal.h"
  11. #include    "layout.h"
  12. #include    "specs.h"
  13.  
  14.  
  15. /* Relative layout constants. */
  16.  
  17. #define    TOPROW        2        /* First non-blank row. */
  18. #define    BOTROW        (TOPROW+2*(NLINES-1))    /* First non-blank row. */
  19. #define DBSHELP    \
  20.     "^G: undo, ^T: tryall, ^W: wrdsrch, F2 F1: next prev block"
  21. #define WIREWIDTH    23    /* Number of chars from WIREFORMAT */
  22. #define WIREFORMAT    "Know %3d of 128 wires  "
  23. #define    WIRECOL        (LINELEN - WIREWIDTH + 1)  /* Starting column. */
  24. #define    BLOCKFORMAT    "Block - %d"
  25.  
  26. /* Keystroke handler for decryption block storage. */
  27.  
  28. extern    dbsup(), dbsdown(), dbsleft(), dbsright();
  29. extern    dbskey();
  30. extern    dbsundo();
  31. extern    dbsdelf();
  32. extern    dbsdelb();
  33. extern    dbsnxtblk();
  34. extern    dbsprvblk();
  35. extern    dbstryall();
  36. extern    dbswrdsrch();
  37.  
  38. keyer    dbsktab[] = {
  39.         {CTRYALL, dbstryall},
  40.         {CWRDSRCH, dbswrdsrch},
  41.         {CNEXTBLOCK, dbsnxtblk},
  42.         {CPREVBLOCK, dbsprvblk},
  43.         {CGO_UP, dbsup},
  44.         {CGO_DOWN, dbsdown},
  45.         {CGO_LEFT, dbsleft},
  46.         {CGO_RIGHT, dbsright},
  47.         {CUNDO, dbsundo},
  48.         {CDELF, dbsdelf},
  49.         {CDELB, dbsdelb},
  50.         {CINSERT, dbskey},
  51.         {CRETURN, dbskey},    /* Special case return key. */
  52.         {0, NULL},
  53.         };
  54.  
  55.  
  56.  
  57. /* Private data for the decryption block storage. */
  58.  
  59. #include     "dblock.h"
  60.  
  61. char    mcbuf[BLOCKSIZE+1];        /* Static buffer for now. */
  62. int    mpbuf[BLOCKSIZE+1];        /* Static buffer for now. */
  63. int    moperm[BLOCKSIZE+1];        /* Static buffer for now. */
  64. char    mmbuf[BLOCKSIZE+1];        /* Static buffer for now. */
  65. int    mcmdbuf[BLOCKSIZE+1];        /* Static buffer for now. */
  66.  
  67. dbsinfo dbsprivate;
  68.  
  69.  
  70.  
  71. /* Window for the decryption block label. */
  72.  
  73. displine    dblline1 = {
  74.         DBLROW,1,        /* Origin. */
  75.         1,DBWIDTH,        /* Height and width. */
  76.         1,1,            /* Init (relative) cursor position */
  77.         NULL,            /* No private data. */
  78.         wl_setcur,        /* Firstime = restore cursor pos. */
  79.         wl_noop,        /* Lasttime = do nothing. */
  80.         wl_dldraw,        /* Default dispaly line draw routine */
  81.         dokey,            /* Default keystroke handler. */
  82.         arwktab,        /* Basic arrow keystroke handler. */
  83.         1,DBWIDTH,        /* Min and Max col for cursor. */
  84. };
  85.  
  86. displine    *dbllines[] = {
  87.         &dblline1,        /* List of lines for the label. */
  88.         NULL,
  89. };
  90.  
  91. twindow        dblabel = {
  92.         DBLROW,1,        /* Origin. */
  93.         1,DBWIDTH,        /* Height and width. */
  94.         1,1,            /* Init (relative) cursor position */
  95.         NULL,            /* No private info. */
  96.         wl_setcur,        /* Firstime = restore cursor pos. */
  97.         wl_noop,        /* Lasttime = do nothing. */
  98.         wl_twdraw,        /* Simple draw routine. */
  99.         dokey,            /* Default keystroke handler. */
  100.         arwktab,        /* Basic arrow keystroke handler. */
  101.         dbllines,
  102. };
  103.  
  104.  
  105. /* Window for the decrytion block. */
  106.  
  107. extern    int    dbsdraw();
  108. extern    int    dbsfirst();
  109. extern    int    dbslast();
  110.  
  111. gwindow        dbstore = {
  112.         DBSROW,1,        /* Origin. */
  113.         DBHEIGHT,DBWIDTH,    /* Height and width. */
  114.         TOPROW,1,        /* Initial cursor position */
  115.         ((char *)&dbsprivate),    /* Info about current block. */
  116.         dbsfirst,        /* Firstime */
  117.         dbslast,        /* Lasttime */
  118.         dbsdraw,        /* Draw routine. */
  119.         dokey,            /* Default keystroke handler. */
  120.         dbsktab,        /* Arrow keystroke handler. */
  121. };
  122.  
  123.  
  124.  
  125. /* Initialize the decrypted block label, and return a ptr to it.
  126.  */
  127. gwindow    *(idblabel())
  128. {
  129.     displine    *line;
  130.  
  131.     line = dblabel.dlines[0];
  132.     clrdline(line);
  133.     return ((gwindow *) &dblabel);
  134. }
  135.  
  136.  
  137. /* Set the block number in the label.
  138.  * The argument, num, is displayed as it, it is not zero adjusted.
  139.  * The cursor is not moved, and the window is redisplayed.
  140.  */
  141. dblbnum(label, num)
  142. twindow    *label;
  143. int    num;
  144. {
  145.     int    row,col;
  146.  
  147.     row = rowcursor();
  148.     col = colcursor();
  149.  
  150.     sprintf(statmsg, BLOCKFORMAT, num);
  151.     setrange(label->dlines[0], statmsg, 1, WIRECOL-1);
  152.     wl_dldraw(label->dlines[0]);
  153.     setcursor(row, col);
  154. }
  155.  
  156.  
  157. /* Set the known wire number in the label.
  158.  * The argument, num, is displayed as it, it is not zero adjusted.
  159.  * The cursor is not moved, and the window is redisplayed.
  160.  */
  161. dblpcount(label, num)
  162. twindow    *label;
  163. int    num;
  164. {
  165.     int    row,col;
  166.  
  167.     row = rowcursor();
  168.     col = colcursor();
  169.  
  170.     sprintf(statmsg, WIREFORMAT, num);
  171.     setnadline(label->dlines[0], statmsg, WIRECOL);
  172.     wl_dldraw(label->dlines[0]);
  173.     setcursor(row, col);
  174. }
  175.  
  176.  
  177.  
  178. /* Initialize the decryption block storage, and return a ptr to it.
  179.  * Reads in cipher block from the file named by cipherfile.
  180.  * If errors occur, a message is put in the status area.
  181.  */
  182. gwindow    *(idbstore())
  183. {
  184.     gwindow        *dbs;
  185.     dbsinfo        *dbsi;
  186.     FILE        *fd;
  187.  
  188.     dbs = &dbstore;
  189.     dbsi = ((dbsinfo *) dbs->wprivate);
  190.  
  191.     dbsi->cbuf = mcbuf;
  192.     dbsi->blknum = 0;
  193.     fillcbuf(dbsi->blknum, dbsi->cbuf);
  194.     dbsi->perm = refperm(dbsi->blknum);
  195.     dbsi->pbuf = mpbuf;
  196.     dbsi->mbuf = mmbuf;
  197.     dbsi->cmdbuf = mcmdbuf;
  198.     dbsi->operm = moperm;
  199.  
  200.     dbsinit(dbsi);
  201.  
  202.     return (dbs);
  203. }
  204.  
  205.  
  206. /* Initialize the private data.
  207.  * Requires that the cipherblock and permutation have already been loaded.
  208.  * The plaintext is decoded from the ciphertext and permutation.
  209.  * Updates the label display.
  210.  */
  211. dbsinit(dbsi)
  212. dbsinfo    *dbsi;
  213. {
  214.     int        i;
  215.  
  216.     dbsi->wirecnt = permwcount(dbsi->perm);
  217.     dbsi->cmdloc = 0;
  218.     dbsi->cmdnext = 0;
  219.     dbsi->cmdbuf[0] = 0;
  220.     dblbnum(&dblabel, dbsi->blknum);
  221.     dblpcount(&dblabel, dbsi->wirecnt);
  222.  
  223.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  224.         dbsi->operm[i] = dbsi->perm[i];
  225.         dbsi->mbuf[i] = FALSE;
  226.         }
  227.  
  228.     decode(dbsi->cbuf, dbsi->pbuf, dbsi->perm);
  229. }
  230.  
  231.  
  232.  
  233. /* Atomically merge the given permutation into the current one.
  234.  * The current one is not changed if any conflicts are detected.
  235.  * Updates the display and plaintext buffer.
  236.  * Does setup to allow an undo.
  237.  * Return TRUE if suceesful.
  238.  */
  239. int    dbsmerge(dbs, perm)
  240. gwindow    *dbs;        /* Ptr to dbstore */
  241. int    perm[];        /* Permutation */
  242. {
  243.     int    i;
  244.     dbsinfo    *dbsi;
  245.     dbsi = ((dbsinfo *) dbs->wprivate);
  246.  
  247.     /* Check for conflicts, display msg if so. */
  248.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  249.         if (perm[i] != NONE  &&  dbsi->perm[i] != NONE
  250.          && perm[i] != dbsi->perm[i]) {
  251.             sprintf(statmsg, "Guess conflicts with current plaintext!");
  252.             usrstatus(&user, statmsg);
  253.             return(FALSE);
  254.             }
  255.         }
  256.  
  257.     /* Use dbssperm to set the guess.  Save old perm for undo. */
  258.     dbsi->cmdnext = 0;
  259.     dbsi->cmdloc = dbsrc2pos(dbs->wcur_row, dbs->wcur_col);
  260.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  261.         dbsi->operm[i] = dbsi->perm[i];
  262.         }
  263.  
  264.     dbsrmarks(dbs);
  265.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  266.         if (perm[i] != NONE  &&  perm[i] > i  &&  dbsi->perm[i] == NONE) {
  267.             dbsswire(dbs, i, perm[i]);
  268.             }
  269.         }
  270.  
  271.     sprintf(statmsg, "Sucessful merge.");
  272.     usrstatus(&user, statmsg);
  273.     dbsi->wirecnt = permwcount(dbsi->perm);
  274.     dblpcount(&dblabel, dbsi->wirecnt);
  275.     return(TRUE);
  276. }
  277.  
  278.  
  279. /* Undo the last command.
  280.  * Copy the old permutation into the current one,
  281.  * recompute the plaintext, and update the display.
  282.  * Move the cursor back to where it was.
  283.  */
  284. dbsundo(dbs)
  285. gwindow    *dbs;
  286. {
  287.     int    i;
  288.     dbsinfo    *dbsi;
  289.     dbsi = ((dbsinfo *) dbs->wprivate);
  290.  
  291.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  292.         dbsi->mbuf[i] = FALSE;
  293.         dbsi->perm[i] = dbsi->operm[i];
  294.         }
  295.     decode(dbsi->cbuf, dbsi->pbuf, dbsi->perm);
  296.     dbsdraw(dbs);
  297.  
  298.     dbsi->wirecnt = permwcount(dbsi->perm);
  299.     dblpcount(&dblabel, dbsi->wirecnt);
  300.     usrstatus(&user, "Command undone.");
  301.     wl_setcur(dbs, dbsp2row(dbsi->cmdloc), dbsp2col(dbsi->cmdloc));
  302. }
  303.  
  304.  
  305.  
  306. /* (re)Draw the window.
  307.  */
  308. dbsdraw(dbs)
  309. gwindow    *dbs;
  310. {
  311.     int    i;
  312.     int    row, col;
  313.     dbsinfo    *dbsi;
  314.  
  315.     dbsi = ((dbsinfo *) dbs->wprivate);
  316.     row = dbs->wcur_row;
  317.     col = dbs->wcur_col;
  318.  
  319.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  320.         if (i%LINELEN == 0) {
  321.             wl_setcur(dbs, dbsp2row(i), dbsp2col(i));
  322.             }
  323.         plnchars(1, char2sym(dbsi->pbuf[i]));
  324.         }
  325.  
  326.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  327.         if (i%LINELEN == 0) {
  328.             wl_setcur(dbs, dbsp2row(i)+1, dbsp2col(i));
  329.             }
  330.         if (dbsi->mbuf[i]) {
  331.             plnchars(1, SUNDERLINE);
  332.             }
  333.         else  {
  334.             plnchars(1, ' ');
  335.             }
  336.         }
  337.  
  338.     for (i = dbsp2row(BLOCKSIZE) ; i <= DBHEIGHT ; i++) {
  339.         wl_setcur(dbs, i, 1);
  340.         plnchars(LINELEN, ' ');
  341.         }
  342.     for (i = 1 ; i < dbsp2row(0) ; i++) {
  343.         wl_setcur(dbs, i, 1);
  344.         plnchars(LINELEN, ' ');
  345.         }
  346.  
  347.     for (i = 1 ; i <= DBHEIGHT ; i++) {
  348.         wl_setcur(dbs, i, LINELEN+1);
  349.         plnchars(dbs->wwidth - LINELEN, ' ');
  350.         }
  351.  
  352.     wl_setcur(dbs, row, col);
  353.  
  354. }
  355.  
  356.  
  357.  
  358. /* Draw the plaintext characters on the screen.
  359.  * Does not change the cursor position.
  360.  */
  361. dbsdpbuf(dbs)
  362. gwindow    *dbs;
  363. {
  364.     int    i;
  365.     dbsinfo    *dbsi;
  366.  
  367.     dbsi = ((dbsinfo *) dbs->wprivate);
  368.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  369.         dbsdpchar(dbs, i, dbsi->pbuf[i]);
  370.         }
  371. }
  372.  
  373.  
  374. /* Display the given plaintext character at the given cipher block position.
  375.  * Cipher block positions are zero-based.
  376.  * Handles mapping of block positions to window coordinates.
  377.  * It does not move the cursor.
  378.  * It does set pbuf.
  379.  */
  380. dbsdpchar(dbs, pos, pchar)
  381. gwindow    *dbs;
  382. int        pos;
  383. int        pchar;                /* -1 means no char. */
  384. {
  385.     int    row, col;            /* Original position. */
  386.     dbsinfo    *dbsi;
  387.  
  388.     dbsi = ((dbsinfo *) dbs->wprivate);
  389.     row = dbs->wcur_row;
  390.     col = dbs->wcur_col;
  391.  
  392.     wl_setcur(dbs, dbsp2row(pos), dbsp2col(pos));
  393.     plnchars(1, char2sym(pchar));
  394.     dbsi->pbuf[pos] = pchar;
  395.     wl_setcur(dbs, row, col);
  396. }
  397.  
  398.  
  399.  
  400. /* Convert cipher block position to window row coordinate.
  401.  */
  402. dbsp2row(pos)
  403. int        pos;
  404. {
  405.     return(TOPROW + 2*(pos/LINELEN));
  406. }
  407.  
  408.  
  409. /* Convert cipher block position to window column coordinate.
  410.  */
  411. dbsp2col(pos)
  412. int        pos;
  413. {
  414.     return(1 + (pos%LINELEN));
  415. }
  416.  
  417.  
  418. /* Convert window row and column positions into a  cipher block position.
  419.  */
  420. int    dbsrc2pos(row, col)
  421. int        row, col;
  422. {
  423.     return( ((row-TOPROW)/2)*LINELEN  +  (col-1) );
  424. }
  425.  
  426.  
  427.  
  428. /* Reset all the character marks that are set and update the display.
  429.  */
  430. dbsrmarks(dbs)
  431. gwindow    *dbs;
  432. {
  433.     int    i;
  434.     dbsinfo    *dbsi;
  435.  
  436.     dbsi = ((dbsinfo *) dbs->wprivate);
  437.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  438.         if (dbsi->mbuf[i])  dbscmark(dbs, i);
  439.         }
  440. }
  441.  
  442.  
  443. /* (re)Draw all the set character marks.
  444.  * Assumes that the window has been erased.
  445.  * Cursor restored to its original place.
  446.  */
  447. dbsdmarks(dbs)
  448. gwindow    *dbs;
  449. {
  450.     int    i;
  451.     dbsinfo    *dbsi;
  452.  
  453.     dbsi = ((dbsinfo *) dbs->wprivate);
  454.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  455.         if (dbsi->mbuf[i])  {
  456.             dbssmark(dbs, i);
  457.             }
  458.         }
  459. }
  460.  
  461.  
  462. /* Set a mark under the given cipher block position and
  463.  * update the mark flags.
  464.  * Doesn't change the cursor position.
  465.  */
  466. dbssmark(dbs, pos)
  467. gwindow    *dbs;
  468. {
  469.     int    row, col;            /* Original position. */
  470.     dbsinfo    *dbsi;
  471.  
  472.     dbsi = ((dbsinfo *) dbs->wprivate);
  473.     row = dbs->wcur_row;
  474.     col = dbs->wcur_col;
  475.  
  476.     wl_setcur(dbs, 1+dbsp2row(pos), dbsp2col(pos));
  477.     plnchars(1, SUNDERLINE);
  478.     dbsi->mbuf[pos] = TRUE;
  479.  
  480.     wl_setcur(dbs, row, col);
  481. }
  482.  
  483.  
  484. /* Clear the mark under the given cipher block position and
  485.  * update the mark flags.
  486.  * Doesn't change the cursor position.
  487.  */
  488. dbscmark(dbs, pos)
  489. gwindow    *dbs;
  490. {
  491.     int    row, col;            /* Original position. */
  492.     dbsinfo    *dbsi;
  493.  
  494.     dbsi = ((dbsinfo *) dbs->wprivate);
  495.     row = dbs->wcur_row;
  496.     col = dbs->wcur_col;
  497.  
  498.     wl_setcur(dbs, 1+dbsp2row(pos), dbsp2col(pos));
  499.     plnchars(1,' ');
  500.     dbsi->mbuf[pos] = FALSE;
  501.  
  502.     wl_setcur(dbs, row, col);
  503. }
  504.  
  505.  
  506.  
  507. /* Set the permutation to reflect the fact that the
  508.  * character at pos is pchar.
  509.  * Update the display to reflect the changes.
  510.  * Highlight all changes.
  511.  * Add the character to the command string, clearing the old
  512.  * marks if this is the first command character.
  513.  * By setting pchar to NONE, this can be used to clear the permutation.
  514.  * The cursor position is not changed.
  515.  */
  516. dbssperm(dbs, pos, pchar)
  517. gwindow    *dbs;
  518. int    pos;
  519. int    pchar;
  520. {
  521.     int    i;
  522. reg    dbsinfo    *dbsi;
  523.     char    *p;
  524.     int    x;        /* Shifted up cipher text character. */
  525.     int    y;        /* Shifted up plain text character. */
  526.  
  527.     dbsi = ((dbsinfo *) dbs->wprivate);
  528.  
  529.     if (dbsi->cmdnext == 0)  {        /* Starting new command. */
  530.         dbsrmarks(dbs);
  531.         for (i = 0 ; i < BLOCKSIZE ; i++)  {
  532.             dbsi->operm[i] = dbsi->perm[i];
  533.             }
  534.         dbsi->cmdloc = pos;
  535.         }
  536.     dbsi->cmdbuf[dbsi->cmdnext++] = pchar;
  537.  
  538.     if (pchar == NONE) {        /* Just clear the permutation. */
  539.         x = (dbsi->cbuf[pos] + pos) & MODMASK;
  540.         y = dbsi->perm[x];
  541.         if (y != NONE)  dbscwire(dbs, x, y&MODMASK);
  542.         return;
  543.         }
  544.  
  545.     x = (dbsi->cbuf[pos] + pos) & MODMASK;
  546.     y = (pchar + pos) & MODMASK;
  547.     dbsswire(dbs, x, y);
  548. }
  549.  
  550.  
  551. /* Clear the wiring for perm[x] equals y and update the display.
  552.  * Requires that x be in fact wired to y.
  553.  */
  554. dbscwire(dbs, x, y)
  555. gwindow    *dbs;
  556. int    x, y;
  557. {
  558.     int    i;
  559.     dbsinfo    *dbsi;
  560.     char    *p;
  561.  
  562.     dbsi = ((dbsinfo *) dbs->wprivate);
  563.     if (dbsi->perm[x] != y  ||  x == NONE)  return;
  564.     if (y != NONE)  dbsi->wirecnt--;
  565.  
  566.     permchgflg = TRUE;
  567.     x = x&MODMASK;
  568.     y = y&MODMASK;
  569.     dbsi->perm[x] = NONE;
  570.     dbsi->perm[y] = NONE;
  571.  
  572.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  573.         if ( ((((dbsi->cbuf[i])+i)&MODMASK) == x)
  574.           || ((((dbsi->cbuf[i])+i)&MODMASK) == y) ) {
  575.             dbsdpchar(dbs, i, NONE);
  576.             dbscmark(dbs, i);
  577.             }
  578.         }
  579.  
  580. }
  581.  
  582.  
  583. /* Set the wiring for perm[x] equals y and update the display.
  584.  * Clear any wiring that was set.
  585.  * Requires x and y not be NONE.
  586.  */
  587. dbsswire(dbs, x, y)
  588. gwindow    *dbs;
  589. int    x, y;
  590. {
  591.     int    i;
  592.     char    *p;
  593.     dbsinfo    *dbsi;
  594.     dbsi = ((dbsinfo *) dbs->wprivate);
  595.  
  596.     if (x == NONE  ||  y == NONE)  return;
  597.     x = x&MODMASK;
  598.     y = y&MODMASK;
  599.     permchgflg = TRUE;
  600.  
  601.     if (dbsi->perm[x] != y)  {
  602.         if (dbsi->perm[x] != NONE)  dbscwire(dbs, x, dbsi->perm[x]);
  603.         if (dbsi->perm[y] != NONE)  dbscwire(dbs, y, dbsi->perm[y]);
  604.         }
  605.     if (dbsi->perm[x] == NONE)  dbsi->wirecnt++;
  606.     dbsi->perm[x] = y;
  607.     dbsi->perm[y] = x;
  608.  
  609.     for (i = 0 ; i < BLOCKSIZE ; i++)  {
  610.         if ((((dbsi->cbuf[i])+i)&MODMASK) == x)  {
  611.             dbsi->pbuf[i] = (y - i) & MODMASK;
  612.             }
  613.         else if ((((dbsi->cbuf[i])+i)&MODMASK) == y)  {
  614.             dbsi->pbuf[i] = (x - i) & MODMASK;
  615.             }
  616.         else  {continue;}
  617.         dbsdpchar(dbs, i, dbsi->pbuf[i]);    /* Found one. */
  618.         dbssmark(dbs, i);
  619.         }
  620. }
  621.  
  622.  
  623.  
  624. /* Behavior when cursor enters the window.
  625.  * Indicate that we are at the beginning of a command.
  626.  * Put up help message.
  627.  */
  628. dbsfirst(dbs, row, col)
  629. gwindow    *dbs;
  630. int    row, col;        /* Relative to window's origin. */
  631. {
  632.     dbsinfo    *dbsi;
  633.  
  634.     dbsi = ((dbsinfo *) dbs->wprivate);
  635.     dbsi->cmdnext = 0;
  636.     usrhelp(&user, DBSHELP);
  637.     wl_setcur(dbs, dbs->wcur_row, col);
  638. }
  639.  
  640.  
  641. /* Behavior when cursor leaves the window.
  642.  * Complete the command and give it to the history window.
  643.  */
  644. dbslast(dbs)
  645. gwindow    *dbs;
  646. {
  647.     dbscmddone(dbs);
  648. }
  649.  
  650.  
  651. /* A command may be done, if so, send it to the history window.
  652.  * Setup for undo.
  653.  */
  654. dbscmddone(dbs)
  655. gwindow    *dbs;
  656. {
  657.     int        i;
  658.     dbsinfo    *dbsi;
  659.  
  660.     dbsi = ((dbsinfo *) dbs->wprivate);
  661.     if (dbsi->cmdnext != 0)  {
  662.         dbsi->cmdbuf[dbsi->cmdnext++] = 0;
  663. /*        hstadd(&history, dbsi->cmdbuf);
  664. */
  665.         dbsi->cmdnext = 0;
  666.         }
  667. }
  668.  
  669.  
  670.  
  671. /* Cursor movement commands.
  672.  * Keep the cursor on the pchar lines.
  673.  * Moving off the end of a line advances to the next or previous line.
  674.  * Moving the cursor also terminates any command that might
  675.  * have been entered.
  676.  */
  677. dbsup(dbs, k)
  678. gwindow    *dbs;
  679. {
  680.     int    row, col;        /* Current relative cursor position. */
  681.     
  682.     row = dbs->wcur_row;
  683.     col = dbs->wcur_col;
  684.     
  685.     if (row <= TOPROW)  {
  686.         wl_setcur(dbs, 1, col);
  687.         dbs->wcur_row = TOPROW;
  688.         jogcursor(1);
  689.         if (wl_hascur(dbs))
  690.               wl_rcursor(dbs);
  691.     }
  692.     else {
  693.         jogup(dbs, k);
  694.         jogup(dbs, k);
  695.     }
  696.     dbscmddone(dbs);
  697. }
  698.  
  699. dbsdown(dbs, k)
  700. gwindow    *dbs;
  701. {
  702.     int    row, col;        /* Current relative cursor position. */
  703.     
  704.     row = dbs->wcur_row;
  705.     col = dbs->wcur_col;
  706.     
  707.     if (row >= BOTROW)  {
  708.         wl_setcur(dbs, DBHEIGHT, col);
  709.         dbs->wcur_row = BOTROW;
  710.         jogcursor(2);
  711.         if (wl_hascur(dbs))
  712.               wl_rcursor(dbs);
  713.         }
  714.     else {
  715.         jogdown(dbs, k);
  716.         jogdown(dbs, k);
  717.         }
  718.     dbscmddone(dbs);
  719. }
  720.  
  721. dbsleft(dbs, k)
  722. gwindow    *dbs;
  723. {
  724.     int    row, col;        /* Current relative cursor position. */
  725.     
  726.     row = dbs->wcur_row;
  727.     col = dbs->wcur_col;
  728.     
  729.     dbsprev(dbs);
  730.     dbscmddone(dbs);
  731. }
  732.  
  733. dbsright(dbs, k)
  734. gwindow    *dbs;
  735. {
  736.     int    row, col;        /* Current relative cursor position. */
  737.     
  738.     row = dbs->wcur_row;
  739.     col = dbs->wcur_col;
  740.     
  741.     dbsnext(dbs);
  742.     dbscmddone(dbs);
  743. }
  744.  
  745.  
  746. /* Backup the cursor to the previous position without terminating
  747.  * a command.
  748.  */
  749. dbsprev(dbs)
  750. gwindow    *dbs;
  751. {
  752.     int    row, col;        /* Current relative cursor position. */
  753.  
  754.     row = dbs->wcur_row;
  755.     col = dbs->wcur_col;
  756.  
  757.     if (col <= 1  &&  row <= TOPROW)  {
  758.         }
  759.     else if (col <= 1)  {
  760.         wl_setcur(dbs, row-2, LINELEN);
  761.         }
  762.     else {
  763.         jogleft(dbs);
  764.         }
  765. }
  766.  
  767.  
  768. /* Advance the cursor to the next position without terminating
  769.  * a command.
  770.  */
  771. dbsnext(dbs)
  772. gwindow    *dbs;
  773. {
  774.     int    row, col;        /* Current relative cursor position. */
  775.  
  776.     row = dbs->wcur_row;
  777.     col = dbs->wcur_col;
  778.  
  779.     if (col >= LINELEN  &&  row >= BOTROW)  {
  780.         }
  781.     else if (col >= LINELEN)  {
  782.         wl_setcur(dbs, row+2, 1);
  783.         }
  784.     else {
  785.         jogright(dbs);
  786.         }
  787. }
  788.  
  789.  
  790.  
  791. /* Add the character to the permutation.
  792.  */
  793. dbskey(dbs, k)
  794. gwindow    *dbs;
  795. int    k;
  796. {
  797.     int    pos;        /* plaintext block position. */
  798.     dbsinfo    *dbsi;
  799.  
  800.     dbsi = ((dbsinfo *) dbs->wprivate);
  801.     pos = dbsrc2pos(dbs->wcur_row, dbs->wcur_col);
  802.     dbssperm(dbs, pos, k & CHARM);
  803.     dbsnext(dbs);
  804.     dblpcount(&dblabel, dbsi->wirecnt);
  805. }
  806.  
  807.  
  808.  
  809. /* Delete forward.
  810.  * Clear the wiring due to the character at the current position,
  811.  * and update the display.
  812.  * The cursor moves forward one position.
  813.  */
  814. dbsdelf(dbs)
  815. gwindow    *dbs;
  816. {
  817.     int    pos;        /* plaintext block position. */
  818.     dbsinfo    *dbsi;
  819.  
  820.     dbsi = ((dbsinfo *) dbs->wprivate);
  821.     pos = dbsrc2pos(dbs->wcur_row, dbs->wcur_col);
  822.  
  823.     dbssperm(dbs, pos, NONE);
  824.     dbsnext(dbs);
  825.     dblpcount(&dblabel, dbsi->wirecnt);
  826. }
  827.  
  828.  
  829.  
  830. /* Delete backwards.
  831.  * Clear the wiring due to the character at the previous position,
  832.  * and update the display.
  833.  * The cursor moves backwards one position.
  834.  */
  835. dbsdelb(dbs)
  836. gwindow    *dbs;
  837. {
  838.     int    pos;        /* plaintext block position. */
  839.     dbsinfo    *dbsi;
  840.  
  841.     dbsi = ((dbsinfo *) dbs->wprivate);
  842.     pos = dbsrc2pos(dbs->wcur_row, dbs->wcur_col);
  843.     if (pos == 0)  return;
  844.     pos = pos - 1;
  845.  
  846.     dbssperm(dbs, pos, NONE);
  847.     dbsprev(dbs);
  848.     dblpcount(&dblabel, dbsi->wirecnt);
  849. }
  850.  
  851.  
  852.  
  853. /* Advance to the next cipher text block (if any).
  854.  */
  855. dbsnxtblk(dbs)
  856. gwindow    *dbs;
  857. {
  858.     dbsinfo    *dbsi;
  859.     dbsi = ((dbsinfo *) dbs->wprivate);
  860.  
  861.     dbssetblk(dbs, dbsi->blknum + 1);
  862. }
  863.  
  864.  
  865. /* Backup to the previous cipher text block (if any).
  866.  */
  867. dbsprvblk(dbs)
  868. gwindow    *dbs;
  869. {
  870.     dbsinfo    *dbsi;
  871.     dbsi = ((dbsinfo *) dbs->wprivate);
  872.  
  873.     dbssetblk(dbs, dbsi->blknum - 1);
  874. }
  875.  
  876.  
  877. /* Jump to a particular block number.
  878.  * Get a new permutation and update the display.
  879.  * Even if the block number hasn't change, the permutation may have,
  880.  * so we must re-decode the block.
  881.  */
  882. dbssetblk(dbs, blocknum)
  883. gwindow    *dbs;
  884. int    blocknum;
  885. {
  886.     dbsinfo    *dbsi;
  887.     dbsi = ((dbsinfo *) dbs->wprivate);
  888.  
  889.     if (fillcbuf(blocknum, dbsi->cbuf)
  890.      && (dbsi->perm = refperm(blocknum))) {
  891.         dbsi->blknum = blocknum;
  892.         dbsinit(dbsi);
  893.         dbsdraw(dbs);
  894.         usrstatus(&user, "Ready.");
  895.         }
  896.     else {
  897.         usrstatus(&user, "Block number is out of range.");
  898.         }
  899. }
  900.  
  901.  
  902. /* Return the number of the current block.
  903.  */
  904. dbsgetblk(dbs)
  905. gwindow    *dbs;
  906. {
  907.     dbsinfo    *dbsi;
  908.     dbsi = ((dbsinfo *) dbs->wprivate);
  909.  
  910.     return(dbsi->blknum);
  911. }
  912.