home *** CD-ROM | disk | FTP | other *** search
/ GEMini Atari / GEMini_Atari_CD-ROM_Walnut_Creek_December_1993.iso / zip / telecomm / zmdm.zoo / phone.c < prev    next >
C/C++ Source or Header  |  1991-04-27  |  16KB  |  940 lines

  1. /*
  2.  * Phone dialing Module (from XMDM)
  3.  *
  4.  *
  5.  *    Jwahar Bammi
  6.  *     bang:   {any internet host}!dsrgsun.ces.CWRU.edu!bammi
  7.  *     domain: bammi@dsrgsun.ces.CWRU.edu
  8.  *    GEnie:    J.Bammi
  9.  */
  10.  
  11. #include "config.h"
  12.  
  13. #ifndef STANDALONE
  14. #ifdef PHONES
  15.  
  16. #include "zmdm.h"
  17.  
  18. typedef int WORD;
  19. typedef long LONG;
  20.  
  21.  
  22. #define sendchar(c)    Bconout(1, c);
  23. #define clear_screen()  Bconws("\033H\033J")
  24. #define inv()        EscSeq('p')
  25. #define normal()    EscSeq('q')
  26. #define mvto(r,c)    EscSeq('Y');Bconout(2, r+040);Bconout(2, c+040)
  27. #define ceol()        EscSeq('K')
  28. #define show_cursor()    EscSeq('e')
  29. #define hide_cursor()    EscSeq('f')
  30.  
  31. typedef struct _dir {        /* The Directory type */
  32.     char    *name;        /* Name (11 chars max) */
  33.     char     *number;    /* Phone # (24 chars max) */
  34.     WORD    baud;        /* baud Rate         */
  35.     struct _dir *next;    /* Ptr to next entry */
  36. } *DIR;
  37.  
  38.  
  39.      /* External Variables */
  40. extern WORD speed;        /* Current Baud Rate */
  41. extern WORD Baudrate;
  42. extern BAUDS vbauds[];
  43. WORD dchanged = 0;            /* Has the directory been updated */
  44. extern char *PhoneFile;
  45.  
  46.      /* Globals */
  47. static WORD ndir = 0;            /* # of entries in phone directory   */
  48. static DIR directory = (DIR)NULL;    /* The phone directory           */
  49. static DIR lastdir   = (DIR)NULL;     /* Pointer to last entry         */
  50. static char *dirfile = (char *)NULL;    /* Name of file conatining directory */
  51. static WORD rflag = 0;            /* Read directory as yet??          */
  52. static WORD firstTime = 1;        /* first time around              */
  53.  
  54. #if defined(__STDC__) || defined(__cplusplus)
  55. # define P_(s) s
  56. #else
  57. # define P_(s) ()
  58. #endif
  59.  
  60. static WORD readdir P_((void));
  61. static void freedir P_((DIR dir));
  62. static WORD showdir P_((void));
  63. static void putdir P_((WORD first, WORD last));
  64. static void putstr P_((char *s, WORD l));
  65. static DIR nth P_((WORD n));
  66. static void addir P_((void));
  67. static WORD tobaud P_((char *s));
  68. static void opendir P_((void));
  69. static void delentry P_((void));
  70. static WORD jbaud P_((WORD bd));
  71. static char *preadl P_((void));
  72. void dial P_((void));
  73. void redial P_((void));
  74.  
  75. #undef P_
  76.  
  77. /*
  78.  * Read the Telephone directory
  79.  *  returns -2 on read error
  80.  *        -1 if cancelled
  81.  *        -3 if file not found
  82.  *        -4 if env var PHONE not avail or phone file given as arg not accs.
  83.  *         n # of entries  otherwise
  84.  */
  85. static WORD readdir()
  86. {
  87.     register char *filename;
  88.     register WORD handle;
  89.     register WORD nentries;
  90.     register DIR last;
  91.     register DIR present;
  92.     extern char *preadl();
  93. #ifdef __GNUC__
  94.     extern void *malloc(size_t);
  95. #else
  96.     extern char *malloc();
  97. #endif
  98.     extern char *getenv();
  99.     
  100.     if(firstTime == 1)
  101.     {
  102.         firstTime = 0;
  103.         filename = (char *)NULL;
  104.         if(PhoneFile != (char *)NULL)
  105.         {
  106.             filename = PhoneFile;
  107.             if((handle = Fopen(filename, 0)) < 0)
  108.                 filename = (char *)NULL;
  109.             else
  110.                 Fclose(handle);
  111.         }
  112.         if(filename == (char *)NULL)    
  113.             if((filename = getenv("PHONE")) == (char *)NULL)
  114.                 return -4;
  115.     }
  116.     else
  117.     {
  118.       Bconws("Enter Filename of Phone Directory or <CR> to Cancel: ");
  119.  
  120.       if((filename = preadl()) == (char *)NULL)
  121.         /* Cancelled */
  122.         return -1;
  123.     }
  124.     if((dirfile = malloc(strlen(filename)+1)) == (char *)NULL)
  125.     {
  126.         /* Out of memory */
  127.         Bconws("Out of Memory\r\n");
  128.         return 0;
  129.     }
  130.     strcpy(dirfile,filename);
  131.  
  132.     if((handle = Fopen(filename,0)) < 0)
  133.         /* File does not exist */
  134.         return -3;
  135.     
  136.     /* Read in the file */
  137.     if(Fread(handle, 2L, &ndir) != 2L)
  138.     {
  139.         Bconws("Error Reading ");
  140.         Bconws(filename);
  141.         Bconws("\r\n");
  142.         Fclose(handle);
  143.         return -2;
  144.     }
  145.  
  146.     /* Read in the directory */
  147.     last = (DIR)NULL;
  148.     directory = (DIR)NULL;
  149.     lastdir = (DIR)NULL;
  150.     rflag = 1;
  151.     
  152.     for(nentries = 0; nentries < ndir; nentries++)
  153.     {
  154.         /* Allocate an entry */
  155.         if((present = (DIR)malloc(sizeof(struct _dir))) == (DIR)NULL)
  156.         {
  157.             /* Out of memory */
  158.             Bconws("Out of Memory\r\n");
  159.             Fclose(handle);
  160.             return nentries;
  161.         }
  162.         
  163. #ifdef __GNUC__
  164.         if((present->name = malloc((size_t)12)) == (char *)NULL)
  165. #else
  166.         if((present->name = malloc(12)) == (char *)NULL)
  167. #endif
  168.         {
  169.             /* Out of memory */
  170.             Bconws("Out of Memory\r\n");
  171.             Fclose(handle);
  172.             return nentries;
  173.         }
  174.  
  175. #ifdef __GNUC__
  176.         if((present->number = malloc((size_t)25)) == (char *)NULL)
  177. #else
  178.         if((present->number = malloc(25)) == (char *)NULL)
  179. #endif
  180.         {
  181.             /* Out of memory */
  182.             Bconws("Out of Memory\r\n");
  183.             Fclose(handle);
  184.             return nentries;
  185.         }
  186.  
  187.         present->next = (DIR)NULL;
  188.         
  189.         /* Read in the entry */
  190.         if(Fread(handle,11L,present->name) != 11L)
  191.         {
  192.             Bconws("Error Reading ");
  193.             Bconws(filename);
  194.             Bconws("\r\n");
  195.             Fclose(handle);
  196.             rflag = 0;
  197.             freedir(directory);
  198.             return -2;
  199.  
  200.         }
  201.  
  202.         if(Fread(handle,24L,present->number) != 24L)
  203.         {
  204.             Bconws("Error Reading ");
  205.             Bconws(filename);
  206.             Bconws("\r\n");
  207.             Fclose(handle);
  208.             rflag = 0;
  209.             freedir(directory);
  210.             return -2;
  211.         }
  212.  
  213.         if(Fread(handle,2L,&(present->baud)) != 2L)
  214.         {
  215.             Bconws("Error Reading ");
  216.             Bconws(filename);
  217.             Bconws("\r\n");
  218.             Fclose(handle);
  219.             rflag = 0;
  220.             freedir(directory);
  221.             return -2;
  222.         }
  223.         
  224.  
  225.         present->name[11] = '\0';
  226.         present->number[24] = '\0';
  227.  
  228.         /* Link it on with the directory */
  229.         if(last == (DIR)NULL)
  230.             /* first entry */
  231.             directory = present;
  232.         else
  233.             last->next = present;
  234.         
  235.         last = present;
  236.     }
  237.     lastdir = last;
  238.     
  239.     return nentries;    
  240. }
  241.  
  242. /*
  243.  * Free space allocated to a phone directory
  244.  *
  245.  */
  246. static void freedir(dir)
  247. register DIR dir;
  248. {
  249.     register DIR next;
  250.     register DIR present;
  251.  
  252.     for(present = dir; present != (DIR)NULL; present = next)
  253.     {
  254.         next = present->next;
  255.         free(present->name);
  256.         free(present->number);
  257.         free(present);
  258.     }
  259.     
  260.     if(dirfile != (char *)NULL)
  261.     {
  262.         free(dirfile);
  263.         dirfile   = (char *)NULL;
  264.     }
  265.     
  266.     directory = (DIR)NULL;
  267.     lastdir      = (DIR)NULL;
  268.     ndir      = 0;
  269.     rflag      = 0;
  270. }
  271.  
  272. /*
  273.  * Write out the phone directory
  274.  *  -returns 0 on success 1 otherwise
  275.  *
  276.  */
  277. int writedir()
  278. {
  279.     register DIR dir;
  280.     register WORD fd;
  281.     
  282.     if((rflag == 0) || (dirfile == (char *)NULL) || (dchanged == 0))
  283.         /* Nothing to Save */
  284.         return 0;
  285.  
  286.     /* Create/Open file for write - overwrite if it exists */
  287.     if ((fd = Fcreate(dirfile,0)) < 0) /* Will fail if file is present */
  288.     {
  289.         /* Overwrite existing file */
  290.         if((fd = Fopen(dirfile,1)) < 0)
  291.         {
  292.             Bconws("Cannot Open ");
  293.             Bconws(dirfile);
  294.             Bconws("\r\n");
  295.             return 1;
  296.         }
  297.     }
  298.  
  299.     if(Fwrite(fd,2L,&ndir) != 2L)
  300.     {
  301.         Bconws("Error Writing ");
  302.         Bconws(dirfile);
  303.         Bconws("\r\n");
  304.         Fclose(fd);
  305.         return 1;
  306.     }
  307.     
  308.     for(dir = directory; dir != (DIR)NULL; dir = dir->next)
  309.     {
  310.         if(Fwrite(fd,11L,dir->name) != 11L)
  311.         {
  312.             Bconws("Error Writing ");
  313.             Bconws(dirfile);
  314.             Bconws("\r\n");
  315.             Fclose(fd);
  316.             return 1;
  317.         }
  318.  
  319.         if(Fwrite(fd,24L,dir->number) != 24L)
  320.         {
  321.             Bconws("Error Writing ");
  322.             Bconws(dirfile);
  323.             Bconws("\r\n");
  324.             Fclose(fd);
  325.             return 1;
  326.         }
  327.  
  328.         if(Fwrite(fd,2L,&(dir->baud)) != 2L)
  329.         {
  330.             Bconws("Error Writing ");
  331.             Bconws(dirfile);
  332.             Bconws("\r\n");
  333.             Fclose(fd);
  334.             return 1;
  335.         }
  336.     }
  337.     
  338.     Fclose(fd);
  339.     return 0;
  340. }
  341.  
  342. /*
  343.  * Show the phone directory
  344.  * return the entry # or -1 if cancelled
  345.  *
  346.  */
  347. static WORD showdir()
  348. {
  349.     register WORD first, last;
  350.     register WORD n;
  351.     register char *line;
  352.     extern WORD atoi();
  353.     extern char *preadl();
  354.     
  355.     first = 0;
  356.  
  357.     while(1)
  358.     {
  359.         again:
  360.         clear_screen();
  361.  
  362.         mvto(0,19);
  363.         Bconws("Phone Directory: ");
  364.         Bconws(dirfile);
  365.         Bconws("  ");
  366.         printf("%d",ndir); fflush(stdout);
  367.         Bconws(" Entry(s)");
  368.  
  369.         last = (ndir < (first + 44)) ? ndir : first + 44;
  370.         putdir(first,last);
  371.         
  372.         /* mvto(25,0); */
  373.         Bconws("\r\n");
  374.         inv();
  375.         Bconws("Enter a # or <SPACE><RETURN> for Next Page or <RETURN> to Cancel:");
  376.         normal();
  377.         Bconout(2, ' ');
  378.         if((line = preadl()) == (char *)NULL)
  379.         {
  380.             return -1;
  381.         }
  382.         
  383.         if(isdigit(*line))
  384.         {
  385.             if((n = atoi(line)) >= ndir)
  386.             {
  387.                 Bconws("Invalid Number ");
  388.                 hit_key();
  389.                 goto again;
  390.             }
  391.             
  392.             return n;
  393.         }
  394.  
  395.         if(last == ndir)
  396.             first = 0;
  397.         else
  398.             first += 44;
  399.     }
  400. }
  401.  
  402. /*
  403.  * Put up directory entries on the screen
  404.  *
  405.  */
  406. static void putdir(first,last)
  407. register WORD first;
  408. register WORD last;
  409. {
  410.     register DIR dir;
  411.     register WORD row;
  412.     extern DIR nth();
  413.     
  414.     /* Find the first entry */
  415.     dir = nth(first);
  416.     row = (first % 44) + 1;
  417.  
  418.     hide_cursor();
  419.     inv();
  420.     for(; first < last; first++)
  421.     {
  422.         mvto(row,((first & 1)?41:0));
  423.         if(first < 10)
  424.             Bconout(2, ' ');
  425.         printf("%d",first); fflush(stdout);
  426.         Bconout(2, '|');
  427.         putstr(dir->name,11);
  428.         Bconout(2, '|');
  429.         putstr(dir->number,24);
  430.         dir = dir->next;
  431.         if(first & 1)
  432.             row++;
  433.     }
  434.  
  435.     if(first & 1)
  436.     {
  437.         mvto(row,41);
  438.         Bconws("  |           |                        ");
  439.         row++;
  440.     }
  441.  
  442.     for(; row < 23; row++)
  443.     {
  444.         Bconws("  |           |                        ");
  445.         mvto(row,41);
  446.         Bconws("  |           |                        ");
  447.     }
  448.  
  449.     normal();
  450.     show_cursor();
  451. }
  452.  
  453. /*
  454.  * Put a string padding to len on screen
  455.  */
  456. static void putstr(s,l)
  457. register char *s;
  458. register WORD l;
  459. {
  460.     register WORD pad;
  461.  
  462.     Bconws(s);
  463.     if((pad = l - (int)strlen(s)) <= 0)
  464.         return;
  465.     for(; pad > 0; pad--)
  466.         Bconout(2, ' ');
  467. }
  468.  
  469.  
  470. /*
  471.  * Return the nth entry in the phone directory
  472.  *
  473.  */
  474. static DIR nth(n)
  475. register WORD n;
  476. {
  477.     register WORD i;
  478.     register DIR dir;
  479.     
  480.     for(i = 0, dir = directory; (dir != (DIR)NULL) & (i < n);
  481.         i++, dir = dir->next)
  482.         /* Skip */;
  483.     return(dir);
  484. }
  485.  
  486. /*
  487.  * Add a entry in the phonebook
  488.  */
  489. static void addir()
  490. {
  491.     register DIR dir;
  492.     register char *s;
  493. #ifdef __GNUC__
  494.     extern void *malloc(size_t);
  495. #else
  496.     extern char *malloc();
  497. #endif
  498.     extern char *preadl();
  499.     
  500.     /* If a directory file already exists add, else read or create */
  501.     if(rflag == 0)
  502.     {
  503.         switch(readdir())
  504.         {
  505.             case -3:
  506.             /* Doesnt exist, but we will create it when we
  507.                write out the directory */
  508.             rflag = 1;
  509.             break;
  510.             
  511.             case 0:
  512.             case -2:
  513.             case -1:
  514.             hit_key();
  515.             return;
  516.             
  517.             default:
  518.             rflag = 1;
  519.             break;
  520.         }
  521.     }
  522.     
  523.     /* Allocate space for the new entry */
  524.     if((dir = (DIR)malloc(sizeof(struct _dir))) == (DIR)NULL)
  525.     {
  526.         Bconws("Out of Memory\r\n");
  527.         hit_key();
  528.         return;
  529.     }
  530.     
  531.     if((dir->name = malloc(12)) == (char *)NULL)
  532.     {
  533.         /* Out of memory */
  534.         Bconws("Out of Memory\r\n");
  535.         hit_key();
  536.         return;
  537.     }
  538.  
  539.     if((dir->number = malloc(25)) == (char *)NULL)
  540.     {
  541.         /* Out of memory */
  542.         Bconws("Out of Memory\r\n");
  543.         hit_key();
  544.         return;
  545.     }
  546.  
  547.         
  548.     /* Get the entry */
  549.     
  550.     do {
  551.         Bconws("Name: ");
  552.         s = preadl();
  553.     } while(s == (char *)NULL);
  554.     
  555.     strncpy(dir->name,s,11);
  556.     
  557.     do {
  558.         Bconws("Number: ");
  559.         s = preadl();
  560.     } while(s == (char *)NULL);
  561.     
  562.     strncpy(dir->number,s,24);
  563.     
  564.     do {
  565.         Bconws("Baud Rate: ");
  566.         s = preadl();
  567.     } while((s == (char *)NULL) || ((dir->baud = tobaud(s)) == -1));
  568.     
  569.     dir->next = (DIR)NULL;
  570.     
  571.     if(directory == (DIR)NULL)
  572.         directory = dir;
  573.     else
  574.         lastdir->next = dir;
  575.  
  576.     lastdir = dir;
  577.     dchanged = 1;
  578.     ndir++;
  579. }
  580.  
  581.  
  582.  
  583. /*
  584.  * Convert a string to a baud rate
  585.  * return int or -1 if invalid
  586.  */
  587. static WORD tobaud(s)
  588. register char *s;
  589. {
  590.     register WORD i;
  591.     
  592.     for(i = 0; vbauds[i].sbaud != (char *)NULL; i++)
  593.     {
  594.         if(strcmp(vbauds[i].sbaud,s) == 0)
  595.             return vbauds[i].ibaud;
  596.     }
  597.  
  598.     Bconws(s);
  599.     Bconws(": Invalid Baud Rate\r\nValid Baud Rates are:\r\n");
  600.     for(i = 0; vbauds[i].sbaud != (char *)NULL; i++)
  601.     {
  602.         Bconout(2, '\t');
  603.         if((i != 0) && (vbauds[i].ibaud != vbauds[i-1].ibaud))
  604.         {
  605.             Bconws(vbauds[i].sbaud);
  606.             Bconws("\r\n");
  607.         }
  608.     }
  609.         
  610.     return -1;
  611. }
  612.  
  613. /*
  614.  * Dial a number 
  615.  */
  616. static void dial()
  617. {
  618.     register WORD n;
  619.     register DIR dir;
  620.     extern DIR nth();
  621.     
  622.     /* Has the directory been read so far */
  623.     if(rflag == 0)
  624.     {
  625.         /* Go read it */
  626.         switch(readdir())
  627.         {
  628.             case -1:
  629.             case -2:
  630.             case -3:
  631.             case -4:
  632.             case 0:
  633.             rflag = 0;
  634.             hit_key();
  635.             his_screen();
  636.             return;
  637.             default:
  638.             break;
  639.         }
  640.     }
  641.     
  642.     if((n = showdir()) == -1)
  643.     {
  644.         /* Cancelled */
  645.         hit_key();
  646.         his_screen();
  647.         return;
  648.     }
  649.     
  650.     his_screen();
  651.     dir = nth(n);
  652.     if(dir->baud != speed)
  653.     {
  654.         speed = dir->baud;
  655.         Baudrate = jbaud(speed);
  656.         Rsconf(speed, -1, -1, -1, -1, -1);
  657.         sendchar('\r');
  658.         flushinput();
  659.     }
  660.     write_modem(PREDIAL, (int)strlen(PREDIAL));
  661.     write_modem(dir->number,(int)strlen(dir->number));
  662.     sendchar('\r');
  663. }
  664.  
  665.  
  666. /*
  667.  * Re-dial the previous number
  668.  *
  669.  *    Does it cheaply, by sending the modem its Re-dial
  670.  *    sequence, instead of remembering the last number dialed etc.
  671.  *
  672.  */
  673. static void redial()
  674. {
  675.     his_screen();
  676.     write_modem(REDIAL ,(int)strlen(REDIAL));
  677. }
  678.  
  679.  
  680. /*
  681.  * Open a phone directory 
  682.  *
  683.  */
  684. static void opendir()
  685. {
  686.     /* if one is open, save it if changed, then deallocate memory
  687.       * and then open a new directory
  688.      */
  689.     register int i;
  690.  
  691.     if(rflag)
  692.     {
  693.         if(dchanged)
  694.         {
  695.             if(writedir() == 1)
  696.             {
  697.                 hit_key();
  698.                 return;
  699.             }
  700.             dchanged = 0;
  701.         }
  702.         freedir(directory);
  703.     }
  704.     
  705.     if((i = readdir()) <= 0)
  706.     {
  707.         if(i == (-4))
  708.             return;
  709.         hit_key();
  710.         return;
  711.     }
  712. }
  713.  
  714. /*
  715.  * Delete an entry.
  716.  */
  717. static void delentry()
  718. {
  719.     register DIR dir, del;
  720.     register WORD n;
  721.     extern DIR nth();
  722.     
  723.     if(rflag == 0)
  724.     {
  725.         Bconws("Nothing to delete\r\n");
  726.         hit_key();
  727.         return;
  728.     }
  729.     
  730.     if((n = showdir()) == -1)
  731.     {
  732.         /* Cancelled */
  733.         hit_key();
  734.         return;
  735.     }
  736.     
  737.     if(ndir == 1)
  738.     {
  739.         del = directory;
  740.         directory = (DIR)NULL;
  741.         lastdir = (DIR)NULL;
  742.     }
  743.     else
  744.     {
  745.         if(n == 0)
  746.         {
  747.             del = directory;
  748.             dir = directory->next;
  749.             directory = dir;
  750.         }
  751.         else
  752.         {
  753.             dir = nth(n-1);
  754.             del = dir->next;
  755.             dir->next = del->next;
  756.             if(lastdir == del)
  757.                 lastdir = dir;
  758.         }
  759.     }
  760.     
  761.     free(del->name);
  762.     free(del->number);
  763.     free(del);
  764.     ndir--;
  765.     dchanged = 1;
  766.     
  767. }
  768.  
  769.     
  770. /*
  771.  * Phone services - top level
  772.  *
  773.  */
  774. void phone()
  775. {
  776.     register LONG conin;
  777.     
  778.     if(firstTime == 1)
  779.         opendir();
  780.  
  781.     while(1)
  782.     {
  783.         clear_screen();
  784.         mvto(2,32);
  785.         inv();
  786.         Bconws("Phone  Services");
  787.         normal();
  788.  
  789.         mvto(5,0);
  790.         
  791.         if(rflag)
  792.         {
  793.             Bconws("\tThe Phone Directory \"");
  794.             Bconws(dirfile);
  795.             Bconws("\" containing ");
  796.             printf("%d", ndir); fflush(stdout);
  797.             Bconws(" Entry(s) is Currently Open.\r\n\n");
  798.         }
  799.         else
  800.             Bconws("\tNo Phone Directory is Currently Open.\r\n\n");
  801.         
  802.         
  803.         /* Put up menu */
  804.         Bconws("\r\n\t");
  805.         EscSeq('p');        /* reverse video */
  806.         Bconws("Undo");
  807.         EscSeq('q');        /* quit reverse video */
  808.         Bconws(" to exit the emulator.\r\n");
  809.         
  810.         Bconws("\t");
  811.         EscSeq('p');        /* reverse video */
  812.         Bconws("d");
  813.         EscSeq('q');        /* quit reverse video */
  814.         Bconws(" to dial a number.\r\n");
  815.         
  816.         Bconws("\t");
  817.         EscSeq('p');        /* reverse video */
  818.         Bconws("a");
  819.         EscSeq('q');        /* quit reverse video */
  820.         Bconws(" to add an entry to the phone directory.\r\n");
  821.         
  822.         Bconws("\t");
  823.         EscSeq('p');        /* reverse video */
  824.         Bconws("D");
  825.         EscSeq('q');        /* quit reverse video */
  826.         Bconws(" to delete an entry from the phone directory.\r\n");
  827.         
  828.         Bconws("\t");
  829.         EscSeq('p');        /* reverse video */
  830.         Bconws("o");
  831.         EscSeq('q');        /* quit reverse video */
  832.         Bconws(" to open another phone directory.\r\n");
  833.  
  834.         Bconws("\t");
  835.         EscSeq('p');        /* reverse video */
  836.         Bconws("r");
  837.         EscSeq('q');        /* quit reverse video */
  838.         Bconws(" to re-dial last number.\r\n");
  839.         
  840.         Bconws("\t");
  841.         EscSeq('p');        /* reverse video */
  842.         Bconws("Return");
  843.         EscSeq('q');        /* quit reverse video */
  844.         Bconws(" to return to the emulator.\r\n\n\n\n");
  845.         
  846.         /* get response */
  847.         conin = Bconin(2);
  848.         
  849.         if ((conin & 0x00FF0000L) == 0x610000L)
  850.         {
  851.             /* He hit <UNDO> */
  852.             his_screen();
  853.             ResetIoBuf();
  854.             finish();
  855.         }
  856.         
  857.         switch((WORD)(conin & 0x7f))
  858.         {
  859.             case 'd':
  860.             /* Dial a number */
  861.             dial();
  862.             return;
  863.             
  864.             case 'D':
  865.             /* Delete an entry */
  866.             delentry();
  867.             break;
  868.             
  869.             case 'a':
  870.             /* Add an entry */
  871.             addir();
  872.             break;
  873.             
  874.             case 'o':
  875.             /* Open another phone directory */
  876.             opendir();
  877.             break;
  878.             
  879.  
  880.             case 'r':
  881.             /* Re-Dial # */
  882.             redial();
  883.             return;
  884.             
  885.             case '\r':
  886.             his_screen();
  887.             return;
  888.             
  889.             default:
  890.             break;
  891.         }
  892.         
  893.     }
  894.     
  895. }
  896.  
  897. /*
  898.  * Convert a baud rate to its int
  899.  * return int or -1 if invalid
  900.  */
  901. static WORD jbaud(bd)
  902. register WORD bd;
  903. {
  904.     register WORD i;
  905.     
  906.     for(i = 0; vbauds[i].sbaud != (char *)NULL; i++)
  907.     {
  908.         if(vbauds[i].ibaud == bd)
  909.             return vbauds[i].jbaud;
  910.     }
  911.     return -1;
  912. }
  913.  
  914. static char scrth[80];
  915. /*
  916.  * Read a line from Standard Input and return a 
  917.  * NULL terminated pointer to it
  918.  */
  919. static char *preadl()
  920. {
  921.     /* Use the scrth bufr for storage */
  922.     scrth[0] = 80;
  923.     Cconrs(scrth);
  924.     Bconws("\r\n");
  925.     if(scrth[1] == 0)
  926.     {
  927.         /* User Cancelled */
  928.         Bconws("Cancelled\r\n");
  929.         return((char *)NULL);
  930.     }
  931.     /* Terminate string that starts at scrth[2] */
  932.     scrth[scrth[1]+2] = '\0';
  933.     return(&scrth[2]);
  934. }    
  935.  
  936. #endif /* PHONES */
  937. #endif /* STANDALONE */
  938.  
  939. /* -eof - */
  940.