home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / net / vcal.bug < prev    next >
Internet Message Format  |  1987-02-20  |  24KB

  1. From me@pinot Thu Feb 19 21:13:27 1987
  2. Path: beno!seismo!rutgers!lll-lcc!ptsfa!varian!zehntel!me@pinot (Mike Essex)
  3. From: me@pinot (Mike Essex)
  4. Newsgroups: net.sources
  5. Subject: vcal fix Rev. 2.1
  6. Message-ID: <142@zehntel.UUCP>
  7. Date: 20 Feb 87 02:13:27 GMT
  8. Sender: news@zehntel.UUCP
  9. Organization: Zehntel Inc., Walnut Creek CA
  10. Lines: 1327
  11.  
  12. As luck would have it I just posted vcal and friends when a minor
  13. bug in 'vcal' was pointed out to me.  I have fixed it and am sending
  14. 'vcal' by itself.
  15.  
  16.  
  17. --------------------------------- CUT HERE --------------------------
  18.  
  19. /*
  20.  * Module:    vcal.c
  21.  *
  22.  * Purpose:    visual appointment calendar
  23.  *
  24.  * Author:    Mike Essex
  25.  *
  26.  * Date:    Sep. 16, 1986
  27.  *
  28.  * Includes:
  29.  *    time.h, stdio.h, ctype.h, signal.h
  30.  *
  31.  * Discussion:
  32.  *    displays a calendar to the screen for the current or optionally
  33.  *    specified month.  User may move the cursor any day of the month
  34.  *    and view or enter appointments for that date.
  35.  * 
  36.  *
  37.  * Edit History
  38.  * ==== =======
  39.  *
  40.  * Date      Who    What
  41.  * ----      ---    ----------------------------------------------
  42.  *11/25/86   me         added multiple data file capability
  43.  *11/25/86   me         fixed array "home" from *home[80] to home[80]
  44.  *11/25/86   me         fixed "space" and "area" to be global
  45.  *11/26/86   me        changed help message routines
  46.  * 2/06/87   me        changed calendar header from printing a default
  47.  *            NULL for .appointments file to not printing
  48.  *02/19/87   me        reworked terminal handler to make correct use
  49.  *            of termcap(3) functions for greater terminal
  50.  *            portability.  modified so that cursor comes to
  51.  *            current day of month on startup.  Fixed minor
  52.  *                      bugs and changed a few messages.
  53.  *02/19/87   me        lengthened notes line printout
  54.  *
  55.  */
  56.  
  57. #include <stdio.h>
  58. #include <signal.h>
  59. #include <ctype.h>
  60. #include <time.h>
  61. #include <sgtty.h>
  62.  
  63. #define        LF    '\012'
  64. #define        BS    '\010'
  65. #define        ESC    '\033'
  66.  
  67. int        mon[] = {
  68.     0,
  69.     31, 29, 31, 30,
  70.     31, 30, 31, 31,
  71.     30, 31, 30, 31,
  72. };
  73.  
  74. int    tputc();        /* termcap dependent output */
  75. char    space[BUFSIZ];        /* used by area */
  76. char    *area = space;        /* termcap required variable */
  77. char    *BC;            /* backspace string pointer */
  78. char    *backstring = "\b";    /* backspace string */
  79. char    PC;            /* number pad characters */
  80. char    *UP;            /* cursor up string */
  81. extern    short    ospeed;        /* output speed */
  82. char    *CM;            /* cursor motion */
  83. char    *CL;            /* clear screen */
  84. char    *TI;            /* begin cm */
  85. char    *TE;            /* end cm */
  86. char    *SO;            /* standout*/
  87. char    *SE;            /* end standout*/
  88. char    *tgoto();
  89. char    *malloc();
  90. char    tcolumns = 0;        /* terminal columns */
  91. char    tlines = 0;        /* terminal lines */
  92.  
  93. int        xposition[32];        /* calendar x axis position */
  94. int        yposition[32];        /* calendar y axis position */
  95. int        active[33];        /* highlight day array */
  96.  
  97. int        monthdata[1000];    /* month data */
  98. int        daydata[1000];        /* month data */
  99. int        yeardata[1000];    /* month data */
  100. char        *msgdata[1000];    /* message pointers */
  101. char        msghold[80];
  102. int        dayindex[18];        /* index to day's msgs */
  103. int        maxentries;
  104. int        maxmsgs;
  105. int        tmonth,tday,tyear;
  106.  
  107. int        maxchars;
  108. int        notclear;
  109. int        help1,help2;        /* help  message flags */
  110.  
  111. char    dayw[] = {
  112.     "  S    M    T    W    T    F    S   "
  113. };
  114.  
  115. char    *smon[]= {
  116.     "JANUARY   ", "FEBRUARY   ", "MARCH    ", "APRIL    ",
  117.     "MAY    ", "JUNE    ", "JULY    ", "AUGUST    ",
  118.     "SEPTEMBER    ", "OCTOBER    ", "NOVEMBER    ", "DECEMBER    ",
  119. };
  120.  
  121.  
  122.  
  123. /*
  124.  * Procedure:    main(argv[1],argv[2],argv[3])
  125.  *
  126.  * Function:    Front end for calendar program
  127.  *
  128.  * Parameters:
  129.  *    p1    - character pointer - optional month
  130.  *    p2    - character pointer - optional year
  131.  *    p3      - character pointer - optional data file name
  132.  *
  133.  * Discussion:
  134.  *    This module parses command line, intializes variables and calls
  135.  *    init functions.  It then drops into a character interpreter
  136.  *    loop, taking input from standard in.  Each input either changes
  137.  *    cursor position or invokes a function.
  138.  */
  139.  
  140. main (argc,argv)
  141.  
  142.     int        argc;
  143.     char    *argv[];
  144. {
  145.  
  146.     int        month,day,year;
  147.     char    key;
  148.     char    *datafile;
  149.     extern int    abort();
  150.     int i;
  151.  
  152.     datafile = NULL;
  153.     day = 1;
  154.     if (argc == 1) {
  155.     timeset();
  156.     month = tmonth;
  157.     day = tday;
  158.     year = tyear;
  159.     }
  160.     else {
  161.     if (argc == 3) {
  162.         month = atoi(argv[1]);
  163.         year = atoi(argv[2]);
  164.         if (year < 100) year += 1900;
  165.         if (!month || !year) {
  166.         printf("Syntax Error:  non-numeric argument\n");
  167.         abort(1);
  168.         }
  169.     }
  170.     else {
  171.         if (argc == 2) {
  172.         timeset();
  173.         month = tmonth;
  174.         day = tday;
  175.         year = tyear;
  176.         datafile = argv[1];
  177.         }
  178.         else {
  179.         if ( argc == 4) {
  180.             month = atoi(argv[1]);
  181.             year = atoi(argv[2]);
  182.             if (year < 100) year += 1900;
  183.             if (!month || !year) {
  184.             printf("Syntax Error:  non-numeric argument\n");
  185.             abort(1);
  186.             }
  187.             datafile = argv[3];
  188.         }
  189.         else {
  190.             printf("Syntax Error:  incorrect number of arguments\n");
  191.             abort(1);
  192.         }
  193.         }
  194.     }
  195.     }
  196.     signal(2,abort);
  197.     signal(3,abort);
  198.  
  199.     system("stty cbreak -echo");
  200.  
  201.     tinit();
  202.     tputs(TI,1,tputc);
  203.     maxchars = 38;
  204.     maxentries = 1000;
  205.     maxmsgs = 18;
  206.     msghold[0] = NULL;
  207.     help1 = 0;
  208.     help2 = 0;
  209.  
  210.     loaddata(datafile);
  211.     cal(month,day,year,datafile);
  212.     movcur(day);
  213.  
  214.     key = 'a';
  215.     while (key != LF) {
  216.  
  217.     key = getchar();
  218.  
  219.     switch (key) {
  220.  
  221.             case 'H' :
  222.  
  223.         helpcal();
  224.  
  225.             break;
  226.  
  227.         case 'p' :
  228.  
  229.         if (--month < 1) {
  230.             month = 12;
  231.             year--;
  232.         }
  233.         day = 1;
  234.         notclear = 0;
  235.         cal(month,day,year,datafile);
  236.  
  237.         break;
  238.  
  239.         case 'n' :
  240.             
  241.         if (++month == 13) {
  242.             month = 1;
  243.             year++;
  244.         }
  245.         day = 1;
  246.         notclear = 0;
  247.         cal(month,day,year,datafile);
  248.  
  249.         break;
  250.             
  251.         case 'h' :
  252.  
  253.         if (--day <= 0) {
  254.             day = mon[month];
  255.         }
  256.         if (notclear) {
  257.             clearmsgs();
  258.         }
  259.  
  260.         break;
  261.  
  262.         case 'l' :
  263.  
  264.         if (++day > mon[month]) {
  265.             day = 1;
  266.         }
  267.         if (notclear) {
  268.             clearmsgs();
  269.         }
  270.  
  271.         break;
  272.  
  273.         case 'j' :
  274.  
  275.         if ((day += 7) > mon[month]) {
  276.             day = day % 7;
  277.             if (day == 0) {
  278.             day = 7;
  279.             }
  280.         }
  281.         if (notclear) {
  282.             clearmsgs();
  283.         }
  284.  
  285.         break;
  286.  
  287.         case 'k' :
  288.  
  289.         if ((day -= 7) <= 0) {
  290.             day += 35;
  291.             if (day > mon[month]) {
  292.             day -= 7;
  293.             }
  294.         }
  295.         if (notclear) {
  296.             clearmsgs();
  297.         }
  298.  
  299.         break;
  300.  
  301.         case 'e' :
  302.  
  303.         day = mon[month];
  304.         if (notclear) {
  305.             clearmsgs();
  306.         }
  307.  
  308.         break;
  309.  
  310.         case 'b' :
  311.  
  312.         day = 1;
  313.         if (notclear) {
  314.             clearmsgs();
  315.         }
  316.  
  317.         break;
  318.  
  319.         case 'c' :
  320.  
  321.         clearday(month,day,year);
  322.  
  323.         break;
  324.  
  325.         case ' ' :
  326.  
  327.         notes(month,day,year);
  328.  
  329.         break;
  330.  
  331.         case 'm' :
  332.  
  333.         modnotes(month,day,year);
  334.  
  335.         break;
  336.  
  337.  
  338.     }
  339.     movcur(day);
  340.     }
  341.     closefile(datafile);
  342.     tputs(TE,1,tputc);
  343.     system("stty -cbreak echo");
  344.     if (help1 || help2) {
  345.     helpclr();
  346.     }
  347.     mov(1,24);
  348. } /* main */
  349.  
  350.  
  351. /*
  352.  * Procedure:    <routine name>
  353.  *
  354.  * Function:    abort()
  355.  *
  356.  * Discussion:
  357.  *    Reset tty parameters and exits with an error code.
  358.  */
  359.  
  360. abort()
  361.  
  362. {
  363.     system("stty -cbreak echo");
  364.     tputs(SE,1,tputc);
  365.     if (help1 || help2) {
  366.     helpclr();
  367.     }
  368.     mov(1,24);
  369.     tputs(TE,1,tputc);
  370.     exit(1);
  371. } /* abort */
  372.  
  373.  
  374.  
  375. /*
  376.  * Procedure:    cal(month,day,year,datafile)
  377.  *
  378.  * Function:    produces the visual calendar to the screen
  379.  *
  380.  * Parameters:
  381.  *    p1    - int - month
  382.  *    p2    - int - day
  383.  *    p3    - int - year
  384.  *    p4      - char * - datafile name
  385.  *
  386.  * Discussion:
  387.  *    Calculates current months parameters, such as, starting
  388.  *    day of week, number of days and days on which there are
  389.  *    appointments.  This data is then used to draw a calendar
  390.  *    to the screen.
  391.  */
  392.  
  393. cal(month,day,year,datafile)
  394.  
  395.     int        month,day,year;
  396.     char    *datafile;
  397.  
  398. {
  399.     int        i,j,k,d;
  400.  
  401.     tputs(CL,24,tputc);
  402.     if (datafile == NULL) {
  403.     printf("V I S U A L   C A L E N D A R\n");
  404.     }
  405.     else {
  406.     printf("V I S U A L   C A L E N D A R\t\t%s\n",datafile);
  407.     }
  408.     printf("-------------------------------------------------------------------------------\n");
  409.     printf("\t\t\t\t%s%u\n", smon[month-1], year);
  410.     printf("-------------------------------------------------------------------------------\n\n");
  411.     printf("%s\n\n", dayw);
  412.  
  413.  
  414.     d = jan1(year);
  415.     mon[2] = 29;
  416.     mon[9] = 30;
  417.  
  418.  
  419.     i = 1;
  420.     while (i <= 32) {
  421.     active[i++] = 0;
  422.     }
  423.  
  424.     i = 0;
  425.     while (i < maxentries) {
  426.     if ((yeardata[i] == year) && (monthdata[i] == month) ) {
  427.         active[daydata[i]] = 1;
  428.     }
  429.     i++;
  430.     }
  431.  
  432.     switch((jan1(year+1)+7-d)%7) {
  433.  
  434.     /*
  435.      *    non-leap year
  436.      */
  437.     case 1:
  438.         mon[2] = 28;
  439.         break;
  440.  
  441.     /*
  442.      *    1752
  443.      */
  444.     default:
  445.         mon[9] = 19;
  446.         break;
  447.  
  448.     /*
  449.      *    leap year
  450.      */
  451.     case 2:
  452.         ;
  453.     }
  454.  
  455.     /* calculate days from beginning of year */
  456.  
  457.     for(i=1; i<month; i++) {
  458.     d += mon[i];
  459.     }
  460.  
  461.     d %= 7;
  462.     i = 0;
  463.  
  464.     /* inset to first day of week position */
  465.  
  466.     while (i++ < (5*d)) {
  467.     printf(" ");
  468.     }
  469.  
  470.     k = 0;
  471.     i = d;
  472.  
  473.     for (j=1;j<=31;j++) {
  474.     xposition[j] = (i*5) + 2;
  475.     yposition[j] = (k*2) + 7;
  476.     if (++i == 7) {
  477.         i = 0;
  478.         k++;
  479.     }
  480.     }
  481.  
  482.     for(i=1; i<=mon[month]; i++) {
  483.     if(i==3 && mon[month]==19) {
  484.         i += 11;
  485.         mon[month] += 11;
  486.     }
  487.     if (active[i]) {
  488.         if(i > 9) {
  489.         printf(" ");
  490.         tputs(SO,1,tputc);
  491.         printf("%d",i/10);
  492.         tputs(SE,1,tputc);
  493.         }
  494.         else {
  495.         printf(" ");
  496.         tputs(SO,1,tputc);
  497.         printf(" ");
  498.         tputs(SE,1,tputc);
  499.         }
  500.         tputs(SO,1,tputc);
  501.         printf("%d",i%10);
  502.         tputs(SE,1,tputc);
  503.         if (*SO == NULL) {
  504.         printf("* ");
  505.         }
  506.         else {
  507.         printf("  ");
  508.         }
  509.     }
  510.     else {
  511.         if(i > 9) {
  512.         printf(" %d",i/10);
  513.         }
  514.         else {
  515.         printf("  ");
  516.         }
  517.         printf("%d  ",i%10);
  518.     }
  519.  
  520.     if(++d == 7) {
  521.         d = 0;
  522.         printf("  \n\n");
  523.     }
  524.     }
  525.     
  526.     helpclr();
  527.  
  528.     mov(42,5);
  529.     printf ("TIME      MESSAGE");
  530. } /* cal */
  531.  
  532.  
  533. /*
  534.  * Procedure:    jan1(year)
  535.  *
  536.  * Function:    calculates day of week of Jan 1 on specified year
  537.  *
  538.  * Parameters:
  539.  *    p1    - int - year
  540.  *
  541.  * Return Values:
  542.  *    integer representation day of the week
  543.  */
  544.  
  545. jan1(year)
  546.  
  547.     int        year;
  548. {
  549.  
  550.     register y, d;
  551. /*
  552.  *    normal gregorian calendar
  553.  *    one extra day per four years
  554.  */
  555.  
  556.     y = year;
  557.     d = 4+y+(y+3)/4;
  558.  
  559. /*
  560.  *    julian calendar
  561.  *    regular gregorian
  562.  *    less three days per 400
  563.  */
  564.  
  565.     if(y > 1800) {
  566.     d -= (y-1701)/100;
  567.     d += (y-1601)/400;
  568.     }
  569.  
  570. /*
  571.  *    great calendar changeover instant
  572.  */
  573.  
  574.     if(y > 1752)
  575.     d += 3;
  576.  
  577.     return(d%7);
  578. } /* jan1 */
  579.  
  580.  
  581.  
  582. /*
  583.  * Procedure:    movcur(day)
  584.  *
  585.  * Function:    moves the cursor to the specified day's position
  586.  *
  587.  * Parameters:
  588.  *    p1    - int - day
  589.  *
  590.  * Discussion:
  591.  *    uses termcap values to move the cursor to a matrix position
  592.  *    stored in a global array
  593.  */
  594.  
  595. movcur(day)
  596.  
  597.     int    day;
  598. {
  599.     tputs( tgoto( CM, xposition[day],yposition[day]), 1, tputc );
  600. } /* movcur */
  601.  
  602.  
  603. /*
  604.  * Procedure:    setday(day)
  605.  *
  606.  * Function:    places day in calendar display with appointment
  607.  *        days highlighted
  608.  *
  609.  * Parameters:
  610.  *    p1    - int - day
  611.  *
  612.  * Discussion:
  613.  *    Uses day arguement, termcap values and calendar position
  614.  *    matrices to write a day to the screen with days with appointment
  615.  *    days highlighted.
  616.  */
  617.  
  618. setday(day)
  619.  
  620.     int        day;
  621. {
  622.     tputs( tgoto( CM, xposition[day]-1,yposition[day]), 1, tputc );
  623.     if (active[day]) {
  624.     if(day > 9) {
  625.         tputs(SO,1,tputc);
  626.         printf("%d",day/10);
  627.         tputs(SE,1,tputc);
  628.     }
  629.     else {
  630.         tputs(SO,1,tputc);
  631.         printf(" ");
  632.         tputs(SE,1,tputc);
  633.     }
  634.     tputs(SO,1,tputc);
  635.     printf("%d",day%10);
  636.     tputs(SE,1,tputc);
  637.     if (*SO == NULL) {
  638.         printf("*");
  639.     }
  640.     else {
  641.         printf(" ");
  642.     }
  643.     }
  644.     else {
  645.     if(day > 9) {
  646.         printf("%d",day/10);
  647.     }
  648.     else {
  649.         printf(" ");
  650.     }
  651.     printf("%d ",day%10);
  652.     }
  653. } /* setday */
  654.  
  655.  
  656.  
  657. /*
  658.  * Procedure:    tinit()
  659.  *
  660.  * Function:    gets termcap entries
  661.  *
  662.  * Return Values:
  663.  *    loads global variables with termcap parameters
  664.  *
  665.  * Discussion:
  666.  *    Initial various termcap variables so that they can later
  667.  *    be used to move the cursor and highlight certain displays.
  668.  */
  669.  
  670. tinit()    /* termcap initalization */
  671.  
  672. {
  673.     struct    sgttyb speed;
  674.  
  675.     char    term[BUFSIZ];        /* holds termcap entry */
  676.     char    name[16];        /* terminal name */
  677.     char    *np;            /* termcap name pointer */
  678.     char    *NADA = { "\0" };    /* null string */
  679.     char    *tgetstr();
  680.     char    *getenv();
  681.  
  682.     if( (np = getenv( "TERM" )) != NULL ) {
  683.         strncpy( name, np, 16 );
  684.     }
  685.     else {
  686.         printf("TERM environment variable does not exist\n");
  687.         abort();
  688.     }
  689.  
  690.     if( tgetent( term, name ) != 1 ) {
  691.         printf("Termcap for %s does not exist\n",name);
  692.         abort();
  693.     }
  694.  
  695.     /* if a capability does not exist, point it to a null
  696.     *  string not NULL
  697.     */
  698.  
  699.     gtty(stdout,&speed);
  700.     ospeed = speed.sg_ospeed;
  701.  
  702.     tlines = tgetnum( "li" );
  703.     tcolumns = tgetnum( "co" );
  704.  
  705.     if( (CM = tgetstr( "cm", &area )) == NULL) {
  706.     CM = NADA;    
  707.     printf("Error:  No termcap 'cm' entry for this terminal type\n");
  708.     abort();
  709.     }
  710.     if( (CL = tgetstr( "cl", &area )) == NULL)
  711.     CL = NADA;
  712.     if( (UP = tgetstr( "up", &area )) == NULL)
  713.     UP = NADA;
  714.     if( (SO = tgetstr( "so", &area )) == NULL)
  715.     SO = NADA;
  716.     if( (SE = tgetstr( "se", &area )) == NULL)
  717.     SE = NADA;
  718.     if( (TI = tgetstr( "ti", &area)) == NULL)
  719.     TI = NADA;
  720.     if( (TE = tgetstr( "te", &area)) == NULL)
  721.     TE = NADA;
  722.     if( tgetnum( "sg", &area)  > 0)  {
  723.     SO = NADA;
  724.     SE = NADA;
  725.     }
  726.     if ( (BC = tgetstr( "bc", &area)) ==  NULL) {
  727.     BC = backstring;
  728.     }
  729.  
  730. } /* tinit */
  731.  
  732.  
  733.  
  734. /*
  735.  * Procedure:    loaddata(datafile)
  736.  *
  737.  * Function:    loads data file
  738.  *
  739.  * Return Values:
  740.  *    Various global arrays loaded with appointment data
  741.  *
  742.  * Discussion:
  743.  *    Opens user's data file and reads it in, placing
  744.  *    the data in appropriate arrays.
  745.  */
  746.  
  747. loaddata(datafile)
  748.  
  749.     char    *datafile;
  750. {
  751.     char    basedata[80];
  752.     char    tmpbuf[80];
  753.     char    *getenv();
  754.     char    home[80];
  755.     FILE     *fptr;
  756.     int        i,j,k,l,field;
  757.  
  758.     i = 0;
  759.     while (i < maxentries) {
  760.     daydata[i] = 0;
  761.     monthdata[i] = 0;
  762.     yeardata[i] = 0;
  763.     msgdata[i] = 0;
  764.     i++;
  765.     }
  766.  
  767.     if (datafile == NULL) {
  768.     strcpy(home,getenv("HOME"));
  769.     strcat(home,"/.appointments");
  770.     }
  771.     else {
  772.     strcpy(home,datafile);
  773.     }
  774.     if ((fptr = fopen(home,"r")) != NULL) {
  775.     i = 0;
  776.     while((fgets(basedata,80,fptr) != NULL)) {
  777.  
  778.         basedata[strlen(basedata)-1] = NULL;
  779.  
  780.         j = 0;
  781.         k = 0;
  782.         field = 0;
  783.         while (basedata[j] != NULL ) {
  784.                  
  785.                 if (basedata[j] != ',') {
  786.  
  787.             tmpbuf[k++] = basedata[j];
  788.         }
  789.         else {
  790.             switch (field) {
  791.  
  792.             case 0 : {
  793.                 tmpbuf[k] = NULL;
  794.                 monthdata[i] = atoi(tmpbuf);
  795.                 k = 0;
  796.                 break;
  797.             }
  798.             case 1 : {
  799.                 tmpbuf[k] = NULL;
  800.                 daydata[i] = atoi(tmpbuf);
  801.                 k = 0;
  802.                 break;
  803.             }
  804.             case 2 : {
  805.                 tmpbuf[k] = NULL;
  806.                 yeardata[i] = atoi(tmpbuf);
  807.                 k = 0;
  808.                 break;
  809.             }
  810.             case 3 : {
  811.                 tmpbuf[k++] = ' ';
  812.                 tmpbuf[k++] = ' ';
  813.                 break;
  814.             }
  815.             }
  816.             field++;
  817.         }
  818.         j++;
  819.         }
  820.         tmpbuf[k] = NULL;
  821.         msgdata[i] = malloc(80);
  822.         strncpy(msgdata[i],tmpbuf,80);
  823.         msgdata[79] = NULL;
  824.  
  825.         if (i >= maxentries) {
  826.         printf("Warning:  Over 1000 entries in data file.  Data truncated.\n");
  827.         break;
  828.         }
  829.         i++;
  830.     }
  831.     fclose(fptr);
  832.     }
  833. } /* loaddata */
  834.  
  835.  
  836. /*
  837.  * Procedure:    closefile(datafile)
  838.  *
  839.  * Function:    writes appointment data to file
  840.  *
  841.  * Discussion:
  842.  *    Opens the user's designated data file and writes the current
  843.  *    data into it.
  844.  */
  845.  
  846. closefile(datafile)
  847.  
  848. char    *datafile;
  849. {
  850.     FILE    *fptr;
  851.     char    tmpbuf[80];
  852.     int        i;
  853.     char    *getenv();
  854.     char    home[80];
  855.  
  856.     if (datafile == NULL) {
  857.     strcpy(home,getenv("HOME"));
  858.     strcat(home,"/.appointments");
  859.     }
  860.     else {
  861.     strcpy(home,datafile);
  862.     }
  863.     if ((fptr = fopen(home,"w")) == NULL) {
  864.     printf("Error:  Cannot open %s file",datafile);
  865.     abort();
  866.     }    
  867.     i = 0;
  868.     while (i < maxentries) {
  869.     if (daydata[i]) {
  870.         strcpy(tmpbuf,msgdata[i]);
  871.         tmpbuf[4] = NULL;
  872.         fprintf(fptr,"%d,%d,%d,%4.4s,%s\n",monthdata[i],daydata[i],yeardata[i],tmpbuf,&tmpbuf[6]);
  873.     }
  874.     i++;
  875.     }
  876.     fclose(fptr);
  877. } /* closefile */
  878.  
  879.  
  880.  
  881.  
  882. /*
  883.  * Procedure:    notes(month,day,year)
  884.  *
  885.  * Function:    displays the current day's appointments
  886.  *
  887.  * Parameters:
  888.  *    p1    - int - month
  889.  *    p2    - int - day
  890.  *    p3    - int - year
  891.  *
  892.  * Discussion:
  893.  *    Writes to notes section of screen notes for day to
  894.  *    which the cursor was pointing.
  895.  */
  896.  
  897. notes(month,day,year)
  898.  
  899.     int        month,day,year;
  900. {
  901.     int        i,j,k;
  902.  
  903.     if (help1) {
  904.     helpclr();
  905.     help1 = 0;
  906.     }
  907.  
  908.     i = 0;
  909.     while (i < 18) {
  910.     dayindex[i++] = 0;
  911.     }
  912.  
  913.     mov(64,5);
  914.     printf("%2d/%2d/%2d",month,day,year);
  915.  
  916.     i = 0;
  917.     j = 0;
  918.     k = 6;
  919.  
  920.     while (i < maxentries) {
  921.     if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
  922.         dayindex[j++] = i;
  923.         notclear++;
  924.         mov(42,k++);
  925.         printf("%-38.38s",msgdata[i]);
  926.     }
  927.     if (j > maxmsgs) {
  928.         mov(42,24);
  929.         printf("* too many entries to print *");
  930.         break;
  931.     }
  932.     i++;
  933.     }
  934.     i = 0;
  935.     while (i < maxentries) {
  936.     if (daydata[i] == 0) {
  937.         dayindex[j++] = i;
  938.         if (j >= maxmsgs) {
  939.         break;
  940.         }
  941.     }
  942.     i++;
  943.     }
  944. } /* notes */
  945.  
  946.  
  947.  
  948. /*
  949.  * Procedure:    modnotes(month,day,year)
  950.  *
  951.  * Function:    add, delete and modify appointment list
  952.  *
  953.  * Parameters:
  954.  *    p1    - int - month
  955.  *    p2    - int - day
  956.  *    p3    - int - year
  957.  *
  958.  * Return Values:
  959.  *    changes data in global message and date arrays
  960.  *
  961.  * Discussion:
  962.  *    Allows the user to add, delete and modify a specified day's
  963.  *    appointment list.  Routine contains a small character
  964.  *    interpreter which moves the cursor through the notes list
  965.  *    and selects routines to modify the list.
  966.  */
  967.  
  968. modnotes (month,day,year)
  969.  
  970.     int        month,day,year;
  971. {
  972.  
  973.     char    key,c;
  974.     int        xcoord,ycoord;
  975.     int        i,cnt,total;
  976.     char    tmpmsg[39];
  977.  
  978.     notes(month,day,year);
  979.     xcoord = 42;
  980.     ycoord = 6;
  981.     i = 0;
  982.     mov(xcoord,ycoord);
  983.     key = 'a';
  984.  
  985.     while (key != LF) {
  986.  
  987.     key = getchar();
  988.  
  989.     switch (key) {
  990.  
  991.             case 'H' :
  992.  
  993.         helpnotes();
  994.  
  995.             break;
  996.  
  997.         case 'j' :
  998.         i++;
  999.         if (++ycoord > 23) {
  1000.             ycoord = 6;
  1001.             i = 0;
  1002.         }
  1003.         break;
  1004.  
  1005.         case 'k' :
  1006.         i--;
  1007.         if (--ycoord < 6) {
  1008.             ycoord = 23;
  1009.             i = 17;
  1010.         }
  1011.         break;
  1012.  
  1013.         case 'd' :
  1014.  
  1015.         tputs(SO,1,tputc);
  1016.         printf("                                      ");
  1017.         tputs(SE,1,tputc);
  1018.         mov (xcoord,ycoord);
  1019.         monthdata[dayindex[i]] = 0;
  1020.         daydata[dayindex[i]] = 0;
  1021.         yeardata[dayindex[i]] = 0;
  1022.         strcpy(msghold,msgdata[dayindex[i]]);
  1023.         if (msgdata[dayindex[i]]) {
  1024.             free(msgdata[dayindex[i]]);
  1025.             msgdata[dayindex[i]] = 0;
  1026.         }
  1027.         break;
  1028.  
  1029.             case 'y' :
  1030.  
  1031.         strcpy(msghold,msgdata[dayindex[i]]);
  1032.  
  1033.         break;
  1034.  
  1035.             case 'p' :
  1036.  
  1037.             if (msgdata[dayindex[i]] == 0) {
  1038.             msgdata[dayindex[i]] = malloc(80);
  1039.             }
  1040.             strncpy(msgdata[dayindex[i]],msghold,80);
  1041.             yeardata[dayindex[i]] = year;
  1042.             daydata[dayindex[i]] = day;
  1043.             monthdata[dayindex[i]] = month;
  1044.             printf("%s",msgdata[dayindex[i]]);
  1045.  
  1046.         break;
  1047.  
  1048.         case 'i' :
  1049.  
  1050.         tputs(SO,1,tputc);
  1051.         printf("                                      ");
  1052.  
  1053.         mov (xcoord,ycoord);
  1054.  
  1055.         c = '0';
  1056.         cnt = 0;
  1057.         while (c != ESC) {
  1058.             c = getchar();
  1059.             if (c != ESC ) {
  1060.             if (c == BS) {
  1061.                 if (cnt > 0) {
  1062.                 cnt--;
  1063.                 if (cnt == 5) {
  1064.                     cnt = 3;
  1065.                     mov(46,ycoord);
  1066.                 }
  1067.                 printf("%s %s",BC,BC);
  1068.                 }
  1069.             }
  1070.             else {
  1071.                 if (c != LF) {
  1072.                 if ( cnt < maxchars) {
  1073.                     tmpmsg[cnt] = c;
  1074.                     cnt++;
  1075.                     printf("%c",c);
  1076.                 }
  1077.                 if (cnt == 4) {
  1078.                     tmpmsg[4] = ' ';
  1079.                     tmpmsg[5] = ' ';
  1080.                     cnt = 6;
  1081.                     mov(48,ycoord);
  1082.                 }
  1083.                 }
  1084.                 else {
  1085.                 c = ESC;
  1086.                 }
  1087.             }
  1088.             }
  1089.         }
  1090.         tputs(SE,1,tputc);
  1091.         if (cnt) {
  1092.             tmpmsg[cnt] = NULL;
  1093.             if (msgdata[dayindex[i]] == 0) {
  1094.             msgdata[dayindex[i]] = malloc(80);
  1095.             }
  1096.             strncpy(msgdata[dayindex[i]],tmpmsg,80);
  1097.             monthdata[dayindex[i]] = month;
  1098.             daydata[dayindex[i]] = day;
  1099.             yeardata[dayindex[i]] = year;
  1100.         }
  1101.         else {
  1102.             monthdata[dayindex[i]] = 0;
  1103.             daydata[dayindex[i]] = 0;
  1104.             yeardata[dayindex[i]] = 0;
  1105.             if (msgdata[dayindex[i]]) {
  1106.             free(msgdata[dayindex[i]]);
  1107.             msgdata[dayindex[i]] = 0;
  1108.             }
  1109.         }
  1110.  
  1111.         break;
  1112.  
  1113.         default :;
  1114.     }
  1115.     mov (xcoord,ycoord);
  1116.     }
  1117.  
  1118.     active[day] = 0;
  1119.     i = 0;
  1120.     while (i < maxentries) {
  1121.     if ((yeardata[i] == year) && (monthdata[i] == month)) {
  1122.         notclear = 18;
  1123.         active[daydata[i]] = 1;
  1124.     }
  1125.     i++;
  1126.     }
  1127.  
  1128.     notclear = 18;
  1129.     clearmsgs();
  1130.     if (active[day]) {
  1131.     notes(month,day,year);
  1132.     }
  1133.     setday(day);
  1134.     if (help2) {
  1135.     helpclr();
  1136.     help2 = 0;
  1137.     }
  1138. } /* modnotes */
  1139.  
  1140.  
  1141. /*
  1142.  * Procedure:    tputc(character)
  1143.  *
  1144.  * Function:    moves cursor on screen
  1145.  *
  1146.  * Parameters:
  1147.  *    p1    - int - character
  1148.  *
  1149.  * Discussion:
  1150.  *    Outputs a character to crt.  Used as an argument to tputs().
  1151.  */
  1152.  
  1153. tputc(c)
  1154.     int c;
  1155. {
  1156.     putchar(c);
  1157. }
  1158.  
  1159.  
  1160. /*
  1161.  * Procedure:    mov(column,row)
  1162.  *
  1163.  * Function:    moves cursor on screen
  1164.  *
  1165.  * Parameters:
  1166.  *    p1    - int - crt column
  1167.  *    p2    - int - crt row
  1168.  *
  1169.  * Discussion:
  1170.  *    Moves the cursor to specified column and row on screen using
  1171.  *    termcap data.
  1172.  */
  1173.  
  1174. mov(col, row)
  1175.  
  1176. int    col,row;
  1177.  
  1178. {
  1179.     tputs( tgoto( CM, (col - 1),(row - 1)), 1, tputc );
  1180. } /* move */
  1181.  
  1182.  
  1183. /*
  1184.  * Procedure:    clearday(month,day,year)
  1185.  *
  1186.  * Function:    deletes specified day's appointments
  1187.  *
  1188.  * Parameters:
  1189.  *    p1    - int - month
  1190.  *    p2    - int - day
  1191.  *    p2    - int - year
  1192.  *
  1193.  * Return Values:
  1194.  *    changes various global arrays
  1195.  *
  1196.  * Discussion:
  1197.  *    Removes appointment entries for the specified day from
  1198.  *    message and date tables and from the crt
  1199.  */
  1200.  
  1201. clearday (month,day,year)
  1202.  
  1203.     int        month,day,year;
  1204. {
  1205.     int        i;
  1206.  
  1207.     i = 0;
  1208.     while (i < maxentries) {
  1209.     if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
  1210.         active[day] = 0;
  1211.         monthdata[i] = 0;
  1212.         daydata[i] = 0;
  1213.         yeardata[i] = 0;
  1214.         if (msgdata[i])  {
  1215.         free(msgdata[i]);
  1216.         msgdata[i] = 0;
  1217.         }
  1218.     }
  1219.     i++;
  1220.     }
  1221.     clearmsgs();
  1222.     setday(day);
  1223. } /* clearday */
  1224.  
  1225.  
  1226. /*
  1227.  * Procedure:    clearmsgs()
  1228.  *
  1229.  * Function:    clears the notes section of the crt
  1230.  */
  1231.  
  1232. clearmsgs()
  1233.  
  1234. {
  1235.     int        i;
  1236.  
  1237.     mov(64,5);
  1238.     printf("          ");
  1239.  
  1240.     if (notclear > maxmsgs) notclear = maxmsgs;
  1241.  
  1242.     i = 6;
  1243.     while (i < (notclear+6)) {
  1244.     mov(42,i++);
  1245.     printf("                                      ");
  1246.     }
  1247.     mov(42,24);
  1248.     printf("                                   ");
  1249.     notclear = 0;
  1250. } /* clearmsgs */
  1251.  
  1252.  
  1253. /*
  1254.  * Procedure:    helpcal()
  1255.  *
  1256.  * Function:    displays calendar help messages to crt
  1257.  */
  1258.  
  1259. helpcal()
  1260.  
  1261. {
  1262.     mov(1,19);
  1263.     printf("j/k/h/l:  cursor down/up/left/right     \n");
  1264.     printf("b:  first day         e: last day       \n");
  1265.     printf("space: display notes  m: modify notes   \n");
  1266.     printf("c: clear notes        CR: exit program  \n");
  1267.     printf("p: previous month     n: next month     \n");
  1268.     printf("BRK: exit w/o changes                   ");
  1269.     help1++;
  1270. } /* helpcal */
  1271.  
  1272.  
  1273. /*
  1274.  * Procedure:    helpnotes()
  1275.  *
  1276.  * Function:    displays notes help messages to crt
  1277.  */
  1278.  
  1279. helpnotes() 
  1280.  
  1281. {
  1282.     mov(1,19);
  1283.     printf("j/k:  cursor down/up                    \n");
  1284.     printf("i: enter insert      ESC/CR: exit insert\n");
  1285.     printf("d: delete entry      CR: exit notes     \n");
  1286.     printf("y/p: yank/put a line                    \n");
  1287.     printf("                                        \n");
  1288.     printf("                                        ");
  1289.     help2++;
  1290. } /* helpnotes */
  1291.  
  1292.  
  1293. /*
  1294.  * Procedure:    helpclr()
  1295.  *
  1296.  * Function:    clears notes area of screen
  1297.  */
  1298.  
  1299. helpclr ()
  1300. {
  1301.     mov(1,19);
  1302.     printf("                                        \n");
  1303.     printf("                                        \n");
  1304.     printf("                                        \n");
  1305.     printf("                                        \n");
  1306.     printf("    Type 'H' for help                   \n");
  1307.     printf("                                        ");
  1308. } /* helpclr */
  1309.  
  1310.  
  1311. /*
  1312.  * Procedure:    timeset()
  1313.  *
  1314.  * Function:    sets current month, day and year variables
  1315.  *
  1316.  * Return Values:
  1317.  *    tday, tmonth and tyear variables set to current date
  1318.  */
  1319.  
  1320. timeset()
  1321.  
  1322. {
  1323.     struct    tm *localtime();
  1324.  
  1325.     struct tm *tp;        /* time structure */
  1326.     long    tloc;        /* number of seconds since 1970 */
  1327.  
  1328.     time(&tloc);    /* fills tloc */
  1329.  
  1330.     tp = localtime(&tloc);
  1331.  
  1332.     tyear =    tp->tm_year;
  1333.     tmonth =    tp->tm_mon + 1;
  1334.     tday =    tp->tm_mday;
  1335.  
  1336.     tyear += 1900;
  1337.  
  1338. } /* timeset */
  1339.  
  1340.  
  1341.