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

  1. From me@pinot Thu Jan 29 20:34:50 1987
  2. Path: beno!seismo!rutgers!sri-spam!ames!lll-lcc!ptsfa!varian!zehntel!me@pinot (Mike Essex)
  3. From: me@pinot (Mike Essex)
  4. Newsgroups: net.sources
  5. Subject: visual calendar and activities programs, part 2
  6. Message-ID: <137@zehntel.UUCP>
  7. Date: 30 Jan 87 01:34:50 GMT
  8. Sender: news@zehntel.UUCP
  9. Organization: Zehntel Inc., Walnut Creek CA
  10. Lines: 2080
  11.  
  12.  
  13. echo x - README
  14. sed 's/^X//' >README <<'*-*-END-of-README-*-*'
  15. X            VCAL AND FRIENDS                  1/29/87
  16. X
  17. Xdef.:  a set of calendar and appointment utility programs to replace
  18. X       the traditional paper calendar.
  19. X       
  20. XVcal and friends allow the user to view a calendar, enter dates and
  21. Xtimes of activities, set times for prompts to the CRT and to produce
  22. Xlists of a month's activities.  Multiple data files may be used to
  23. Xallow the user to have one calendar for personal activities, one for
  24. Xbusiness activities, one for project milestones, etc.
  25. X
  26. XThese programs are written in 'C' and run under UNIX.  To date they
  27. Xhave been compiled and execute on the following systems:
  28. X
  29. XDEC PDP 11/70    UNIX Version 7
  30. XDEC VAX 11/750    UNIX BSD 4.2 and 4.3
  31. XSun 2/170    UNIX BSD 4.2
  32. XSun 3/160    UNIX BSD 4.2
  33. XSun 3/260     UNIX BSD 4.2
  34. X
  35. XIncluded in this package are six source files, six manual files, a
  36. Xmakefile and this introduction.  The makefile is for use with the
  37. Xstandard "make" utility on a VAX 11/750 under BSD 4.3.  For use with
  38. Xa PDP 11/70 BSD Version 7 change the makefile library entry from
  39. X"termlib" to "termcap".
  40. X
  41. XAll the "vcal" files have been combined here with the "shar" script.
  42. XSince the combined size of the files are greater than 65,000
  43. Xcharacters they have been broken into two parts for transmission.
  44. XPart 1 contains makefile, appts.c, autocall.c and callme.c along
  45. Xwith the manual pages for these.  Part 2 contains eappts.c, lcal.c
  46. Xand vcal.c and their manual pages.
  47. X
  48. XSynopsis of files:
  49. X
  50. Xappts        displays the current or specified day's activities
  51. X
  52. Xautocall    starts background reminder processes for each of the
  53. X        current day's activities
  54. X
  55. Xcallme        starts a background reminder process for a specified
  56. X        time and activity
  57. X
  58. Xeappts        allows activities to be entered into a data file from
  59. X        the command line
  60. X
  61. Xlcal        produces a tabular listing of the current or specified
  62. X        month's activities
  63. X
  64. Xvcal        visual calendar displaying the current or specified
  65. X        month's activities; allows entries to be added, changed
  66. X        or deleted
  67. X
  68. Xmakefile    makefile for all of the "vcal" programs
  69. X
  70. Xmanual pages:    appts.l autocall.l callme.l eappts.l lcal.l vcal.l
  71. X
  72. XComments and suggestions will be appreciated and considered.
  73. X
  74. XMike Essex  (~me)
  75. X
  76. X     ....!ucbvax!zehntel!me
  77. X     ....!decvax!sytek!zehntel!me
  78. X     ...."zehntel!me"@BERKELEY
  79. *-*-END-of-README-*-*
  80. echo x - eappts.c
  81. sed 's/^X//' >eappts.c <<'*-*-END-of-eappts.c-*-*'
  82. X/*
  83. X * Module:    eappts.c
  84. X *
  85. X * Purpose:    enters data into appointments file
  86. X *
  87. X * Author:    Mike Essex
  88. X *
  89. X * Date:    Sep. 16, 1986
  90. X *
  91. X * Includes:
  92. X *    stdio.h
  93. X * Discussion:
  94. X *    Inputs data from standard input and writes it to ~/.appointments
  95. X *    file
  96. X * 
  97. X *
  98. X * Edit History
  99. X * ==== =======
  100. X *
  101. X * Date      Who    What
  102. X * ----      ---    ----------------------------------------------
  103. X * 12/1/86   me        added multifile capability
  104. X * 12/1/86   me        changed 'home' from *home[80] to home[80]
  105. X *
  106. X */
  107. X
  108. X#include <stdio.h>
  109. X#define        NL    '\010'
  110. X
  111. X
  112. X/*
  113. X * Procedure:    main
  114. X *
  115. X * Function:    inputs data and writes to users .appointments file
  116. X *
  117. X * Discussion:
  118. X *    Prompts users for required appointment information, inputs
  119. X *    that info and then appends it to ~/.appointments file.
  120. X */
  121. X
  122. Xmain(argc,argv)
  123. X
  124. Xint    argc;
  125. Xchar    *argv[];
  126. X
  127. X{
  128. X    FILE    *fptr;
  129. X    char    tmpbuf[80];
  130. X    int        i,j;
  131. X    char    *getenv();
  132. X    char    home[80];
  133. X    char    datedata[20];
  134. X    char    timedata[20];
  135. X    char    msgdata[40];
  136. X    int        month,day,year,time;
  137. X    int        index[5];
  138. X
  139. X    if (argc == 2) {
  140. X    strcpy(home,argv[1]);
  141. X    }
  142. X    else {
  143. X    strcpy(home,getenv("HOME"));
  144. X    strcat(home,"/.appointments");
  145. X    }
  146. X
  147. X    fptr = fopen(home,"a");
  148. X    if (fptr) {
  149. X    printf("What is the date of appointment?  (mm dd yyyy)  ");
  150. X    fgets(datedata,20,stdin);
  151. X    i = 0;
  152. X    j = 0;
  153. X    while(i < 20) {
  154. X        while ((i < 20) && (datedata[i] == ' ')) i++;
  155. X        index[j++] = i;
  156. X        while ((i < 20) && (datedata[i] != ' ')) i++;
  157. X    }
  158. X    month = atoi(&datedata[index[0]]);
  159. X    day = atoi(&datedata[index[1]]);
  160. X    year = atoi(&datedata[index[2]]);
  161. X    if (year < 100) year += 1900;
  162. X
  163. X    printf("What time (24 hour time) is the appointment?  (tttt)  ");
  164. X    fgets(timedata,20,stdin);
  165. X    time = atoi(timedata);
  166. X    printf("What is the message?  (32 characters max)  ");
  167. X    fgets(msgdata,34,stdin);
  168. X    msgdata[strlen(msgdata)-1] = NULL;
  169. X    fprintf(fptr,"%d,%d,%d,%4d,%s\n",month,day,year,time,msgdata);
  170. X    }
  171. X    else {
  172. X    printf("Error:  Cannot open %s file",argv[1]);
  173. X    abort();
  174. X    }
  175. X    fclose(fptr);
  176. X} /* main */
  177. *-*-END-of-eappts.c-*-*
  178. echo x - lcal.c
  179. sed 's/^X//' >lcal.c <<'*-*-END-of-lcal.c-*-*'
  180. X/*
  181. X * Module:    lcal.c
  182. X *
  183. X * Purpose:    print month's appointments
  184. X *
  185. X * Author:    Mike Essex
  186. X *
  187. X * Date:    Sep. 16, 1986
  188. X *
  189. X * Includes:
  190. X *    time.h, stdio.h, ctype.h, signal.h
  191. X *
  192. X * Discussion:
  193. X *    Reads data from ~/.appointments and/or designated file and
  194. X *      writes to standard *    out any appoinments which fall in
  195. X *      the current or optionally specified month.
  196. X * 
  197. X *
  198. X * Edit History
  199. X * ==== =======
  200. X *
  201. X * Date      Who    What
  202. X * ----      ---    ----------------------------------------------
  203. X *
  204. X */
  205. X
  206. X#include <stdio.h>
  207. X#include <signal.h>
  208. X#include <ctype.h>
  209. X#include <time.h>
  210. X
  211. X
  212. Xchar    *malloc();
  213. X
  214. Xint        monthdata[1000];    /* month data */
  215. Xint        daydata[1000];        /* month data */
  216. Xint        yeardata[1000];    /* month data */
  217. Xchar        *msgdata[1000];    /* message pointers */
  218. Xchar        msghold[40];
  219. Xint        maxentries;
  220. Xint        maxmsgs;
  221. Xint        cmonth,cday,cyear;
  222. Xint        argvindex;
  223. X
  224. X
  225. X
  226. X/*
  227. X * Procedure:    main()
  228. X *
  229. X * Function:    prints out listing of appointments
  230. X *
  231. X * Discussion:
  232. X *    Parses command line for optional month and year, initializes
  233. X *    varialbes, calls required funtions.
  234. X */
  235. X
  236. Xmain (argc,argv)
  237. X
  238. X    int        argc;
  239. X    char    *argv[];
  240. X{
  241. X
  242. X    int        month,day,year;
  243. X    int        i;
  244. X    int        tempmonth,tempyear;
  245. X    int        atoi();
  246. X    int        maxindex;
  247. X    extern int    abort();
  248. X
  249. X    timeset();
  250. X    year = cyear;
  251. X    month = cmonth;
  252. X    day = cday;
  253. X
  254. X    if (argc > 2) {
  255. X    tempmonth = atoi(argv[1]);
  256. X    tempyear = atoi(argv[2]);
  257. X    if (tempmonth && tempyear){
  258. X        month = tempmonth;
  259. X        year = tempyear;
  260. X        if (year < 100) year += 1900;
  261. X        if (argc > 3) {
  262. X        argvindex = 3;
  263. X        maxindex = argc;
  264. X        }
  265. X        else {
  266. X        argvindex = 0;
  267. X        maxindex = 1;
  268. X        }
  269. X    }
  270. X    else {
  271. X        if (tempmonth || tempyear) {
  272. X        printf("Syntax error:  Incorrect date arguments\n");
  273. X        exit(1);
  274. X        }
  275. X        else {
  276. X        argvindex = 1;
  277. X        maxindex = argc;
  278. X        }
  279. X    }
  280. X    }
  281. X    else {
  282. X        if (argc == 1) {
  283. X        argvindex = 0;
  284. X        maxindex = argc;
  285. X    }
  286. X    else {
  287. X        argvindex = 1;
  288. X        maxindex = argc;
  289. X    }
  290. X    }
  291. X
  292. X    
  293. X    signal(2,abort);
  294. X    signal(3,abort);
  295. X
  296. X    day = 1;
  297. X    maxentries = 1000;
  298. X    maxmsgs = 18;
  299. X    msghold[0] = NULL;
  300. X
  301. X    printf("                            C A L E N D A R   L I S T\n");
  302. X    while (argvindex < maxindex) {
  303. X    loaddata(argv[argvindex]);
  304. X    table(month,day,year,argv[argvindex]);
  305. X    argvindex++;
  306. X    }
  307. X
  308. X    printf("------------------------------------------------------------------------------\n");
  309. X} /* main */
  310. X
  311. X
  312. X/*
  313. X * Procedure:    abort()
  314. X *
  315. X * Function:    error exit routine
  316. X */
  317. X
  318. Xabort()
  319. X
  320. X{
  321. X    exit(1);
  322. X} /* abort */
  323. X
  324. X
  325. X/*
  326. X * Procedure:    table(month,day,year)
  327. X *
  328. X * Function:    outputs appointments in tabular format
  329. X *
  330. X * Parameters:
  331. X *    p1    - int - month
  332. X *    p2    - int - day
  333. X *    p3    - int - year
  334. X *      p3      - char * - file name
  335. X *
  336. X * Discussion:
  337. X *    Searches data arrays for appointments in the specified
  338. X *    month and year and outputs them in tabular form to standard out.
  339. X */
  340. X
  341. Xtable(month,day,year,filename)
  342. X
  343. X    int        month,day,year;
  344. X    char    *filename;
  345. X
  346. X{
  347. X    int        i,j,k,d,dow,monthday,searchcnt,first;
  348. X    int        getdow();
  349. X
  350. X    static char    *dayw[]= {
  351. X    "Sat   ","Sun   ","Mon   ", "Tue   ",
  352. X    "Wed    ", "Thu    ", "Fri    "
  353. X    };
  354. X
  355. X    static char    *smon[]= {
  356. X    "JANUARY   ", "FEBRUARY   ", "MARCH    ", "APRIL    ",
  357. X    "MAY    ", "JUNE    ", "JULY    ", "AUGUST    ",
  358. X    "SEPTEMBER    ", "OCTOBER    ", "NOVEMBER    ", "DECEMBER    "
  359. X    };
  360. X
  361. X    printf("------------------------------------------------------------------------------\n");
  362. X    if (argvindex) {
  363. X    printf("|  %-10.10s%u                       %30.30s       |\n", smon[month-1], year,filename);
  364. X    }
  365. X    else {
  366. X    printf("|  %-10.10s%u                                                            |\n", smon[month-1], year);
  367. X    }
  368. X    monthday = 0;
  369. X    while (++monthday <= 31) {
  370. X    searchcnt = 0;
  371. X    first = 1;
  372. X    while (searchcnt <= maxentries) {
  373. X        if ((yeardata[searchcnt] == year) &&
  374. X          (monthdata[searchcnt] == month) &&
  375. X          (daydata[searchcnt] == monthday)) {
  376. X        if (first) {
  377. X            dow = getdow(month,monthday,year);
  378. X            first = 0;
  379. X            /* printf("|----------------------------------------------------------------------------|\n"); */
  380. X             printf("|                                                                            |\n"); 
  381. X            printf("| %-7.7s%2d  %-64.64s|\n",dayw[dow],monthday,msgdata[searchcnt]);
  382. X        }
  383. X        else {
  384. X            printf("|            %-64.64s|\n",msgdata[searchcnt]);
  385. X        }
  386. X        }
  387. X        searchcnt++;
  388. X    }
  389. X    }
  390. X} /* table */
  391. X
  392. X
  393. X/*
  394. X * Procedure:    getdow(tmonth,tday,tyear)
  395. X *
  396. X * Function:    calculates day of week
  397. X *
  398. X * Parameters:
  399. X *    p1    - int - month
  400. X *    p2    - int - day
  401. X *    p3    - int - year
  402. X *
  403. X * Return Values:
  404. X *    interger value of day of week, sat=0, . . ., etc
  405. X *
  406. X * Discussion:
  407. X *    calculates number of days from 1,1,1979 and determines dow
  408. X */
  409. X
  410. Xgetdow(tmonth,tday,tyear)
  411. X
  412. X    int        tmonth,tday,tyear;
  413. X{
  414. X
  415. X    static    int    mdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
  416. X    int    month,day,year,mcnt;
  417. X    long   days;
  418. X    int    tdow;
  419. X
  420. X    month = 1;
  421. X    day = 1;
  422. X    year = 79;
  423. X
  424. X    if ((tmonth == month) && (tyear == year)) {
  425. X    days = abs(day - tday);
  426. X    }
  427. X    else {
  428. X        days = mdays[month] - day;
  429. X        if (tyear == year) {
  430. X            while (++month < tmonth) {
  431. X            days += mdays[month];
  432. X            if ((month == 2) && ((year % 4) == 0)) days++;
  433. X        }
  434. X        }
  435. X        else {
  436. X            while (++month < 13) {
  437. X            days += mdays[month];
  438. X                if ((month == 2) && ((year % 4) == 0)) days++;
  439. X            }
  440. X        while (++year < tyear) {
  441. X            days += 365;
  442. X            if ((year % 4) == 0 ) days ++;
  443. X            }
  444. X    
  445. X        mcnt = 0;
  446. X            while (++mcnt < tmonth) {
  447. X            days += mdays[mcnt];
  448. X            if ((mcnt == 2) && ((tyear % 4) == 0)) days++;
  449. X        }
  450. X        }
  451. X        days += tday;
  452. X    }
  453. X
  454. X    tdow = (days%7);
  455. X
  456. X    return(tdow);
  457. X} /* get dow */
  458. X
  459. X
  460. X/*
  461. X * Procedure:    loaddata()
  462. X *
  463. X * Function:    loads appointment data from ~/.appointments file
  464. X *
  465. X * Return Values:
  466. X *    various global arrays loaded with appointment data
  467. X *
  468. X */
  469. X
  470. Xloaddata(filename)
  471. X
  472. Xchar    *filename;
  473. X
  474. X{
  475. X    char    basedata[80];
  476. X    char    tmpbuf[80];
  477. X    char    *getenv();
  478. X    char    home[80];
  479. X    FILE     *fptr;
  480. X    int        i,j,k,l,field;
  481. X
  482. X    i = 0;
  483. X    while (i < maxentries) {
  484. X    daydata[i] = 0;
  485. X    monthdata[i] = 0;
  486. X    yeardata[i] = 0;
  487. X    msgdata[i] = 0;
  488. X    i++;
  489. X    }
  490. X
  491. X    
  492. X    if (argvindex == 0) {
  493. X    strcpy(home,getenv("HOME"));
  494. X    strcat(home,"/.appointments");
  495. X    }
  496. X    else {
  497. X    strcpy(home,filename);
  498. X    }
  499. X    if ((fptr = fopen(home,"r")) != NULL) {
  500. X    i = 0;
  501. X    while((fgets(basedata,80,fptr) != NULL)) {
  502. X
  503. X        basedata[strlen(basedata)-1] = NULL;
  504. X
  505. X        j = 0;
  506. X        k = 0;
  507. X        field = 0;
  508. X        while (basedata[j] != NULL ) {
  509. X                 
  510. X                if (basedata[j] != ',') {
  511. X
  512. X            tmpbuf[k++] = basedata[j];
  513. X        }
  514. X        else {
  515. X            switch (field) {
  516. X
  517. X            case 0 : {
  518. X                tmpbuf[k] = NULL;
  519. X                monthdata[i] = atoi(tmpbuf);
  520. X                k = 0;
  521. X                break;
  522. X            }
  523. X            case 1 : {
  524. X                tmpbuf[k] = NULL;
  525. X                daydata[i] = atoi(tmpbuf);
  526. X                k = 0;
  527. X                break;
  528. X            }
  529. X            case 2 : {
  530. X                tmpbuf[k] = NULL;
  531. X                yeardata[i] = atoi(tmpbuf);
  532. X                k = 0;
  533. X                break;
  534. X            }
  535. X            case 3 : {
  536. X                tmpbuf[k++] = ' ';
  537. X                tmpbuf[k++] = ' ';
  538. X                break;
  539. X            }
  540. X            }
  541. X            field++;
  542. X        }
  543. X        j++;
  544. X        }
  545. X        tmpbuf[k] = '\0';
  546. X        msgdata[i] = malloc(40);
  547. X        strcpy(msgdata[i],tmpbuf);
  548. X
  549. X        if (i >= maxentries) {
  550. X        printf("Warning:  Over 1000 entries in %s file.  Data truncated.\n",filename);
  551. X        break;
  552. X        }
  553. X        i++;
  554. X    }
  555. X    fclose(fptr);
  556. X    }
  557. X    else {
  558. X    printf("Error:  Cannot open %s file.\n",filename);
  559. X    }
  560. X} /* loaddata */
  561. X
  562. X
  563. X/*
  564. X * Procedure:    timeset()
  565. X *
  566. X * Function:    Gets current time and date
  567. X *
  568. X * Return Values:
  569. X *    loads time and date info into global variables
  570. X *
  571. X */
  572. X
  573. Xtimeset()
  574. X
  575. X{
  576. X    struct    tm *localtime();
  577. X
  578. X    struct tm *tp;        /* time structure */
  579. X    long    tloc;        /* number of seconds since 1970 */
  580. X
  581. X    time(&tloc);    /* fills tloc */
  582. X
  583. X    tp = localtime(&tloc);
  584. X
  585. X    cyear =    tp->tm_year;
  586. X    cmonth =    tp->tm_mon + 1;
  587. X    cday =    tp->tm_mday;
  588. X
  589. X    cyear += 1900;
  590. X
  591. X} /* timeset */
  592. *-*-END-of-lcal.c-*-*
  593. echo x - vcal.c
  594. sed 's/^X//' >vcal.c <<'*-*-END-of-vcal.c-*-*'
  595. X/*
  596. X * Module:    vcal.c
  597. X *
  598. X * Purpose:    visual appointment calendar
  599. X *
  600. X * Author:    Mike Essex
  601. X *
  602. X * Date:    Sep. 16, 1986
  603. X *
  604. X * Includes:
  605. X *    time.h, stdio.h, ctype.h, signal.h
  606. X *
  607. X * Discussion:
  608. X *    displays a calendar to the screen for the current or optionally
  609. X *    specified month.  User may move the cursor any day of the month
  610. X *    and view or enter appointments for that date.
  611. X * 
  612. X *
  613. X * Edit History
  614. X * ==== =======
  615. X *
  616. X * Date      Who    What
  617. X * ----      ---    ----------------------------------------------
  618. X *11/25/86   me         added multiple data file capability
  619. X *11/25/86   me         fixed array "home" from *home[80] to home[80]
  620. X *11/25/86   me         fixed "space" and "area" to be global
  621. X *11/26/86   me        changed help message routines
  622. X *
  623. X */
  624. X
  625. X#include <stdio.h>
  626. X#include <signal.h>
  627. X#include <ctype.h>
  628. X#include <time.h>
  629. X
  630. X#define        CR  '\012'
  631. X#define        BS  '\010'
  632. X#define        ESC  '\033'
  633. X
  634. Xint        mon[] = {
  635. X    0,
  636. X    31, 29, 31, 30,
  637. X    31, 30, 31, 31,
  638. X    30, 31, 30, 31,
  639. X};
  640. X
  641. Xchar    space[BUFSIZ];        /* used by area */
  642. Xchar    *area = space;        /* termcap required variable */
  643. Xchar    *CM;            /* cursor motion */
  644. Xchar    *CL;            /* clear screen */
  645. Xchar    *TI;            /* begin cm */
  646. Xchar    *TE;            /* end cm */
  647. Xchar    *SO;            /* standout*/
  648. Xchar    *SE;            /* end standout*/
  649. Xchar    *UP;            /* up doda */
  650. Xint    SG;
  651. Xchar    * tgoto();
  652. Xchar    *malloc();
  653. Xchar    tcolumns = 0;        /* terminal columns */
  654. Xchar    tlines = 0;        /* terminal lines */
  655. X
  656. Xint        xposition[32];        /* calendar x axis position */
  657. Xint        yposition[32];        /* calendar y axis position */
  658. Xint        active[33];        /* highlight day array */
  659. X
  660. Xint        monthdata[1000];    /* month data */
  661. Xint        daydata[1000];        /* month data */
  662. Xint        yeardata[1000];    /* month data */
  663. Xchar        *msgdata[1000];    /* message pointers */
  664. Xchar        msghold[40];
  665. Xint        dayindex[18];        /* index to day's msgs */
  666. Xint        maxentries;
  667. Xint        maxmsgs;
  668. Xint        tmonth,tday,tyear;
  669. X
  670. Xint        maxchars;
  671. Xint        notclear;
  672. Xint        help1,help2;        /* help  message flags */
  673. X
  674. Xchar    dayw[] = {
  675. X    "  S    M    T    W    T    F    S   "
  676. X};
  677. X
  678. Xchar    *smon[]= {
  679. X    "JANUARY   ", "FEBRUARY   ", "MARCH    ", "APRIL    ",
  680. X    "MAY    ", "JUNE    ", "JULY    ", "AUGUST    ",
  681. X    "SEPTEMBER    ", "OCTOBER    ", "NOVEMBER    ", "DECEMBER    ",
  682. X};
  683. X
  684. X
  685. X
  686. X/*
  687. X * Procedure:    main(argv[1],argv[2],argv[3])
  688. X *
  689. X * Function:    Front end for calendar program
  690. X *
  691. X * Parameters:
  692. X *    p1    - character pointer - optional month
  693. X *    p2    - character pointer - optional year
  694. X *    p3      - character pointer - optional data file name
  695. X *
  696. X * Discussion:
  697. X *    This module parses command line, intializes variables and calls
  698. X *    init functions.  It then drops into a character interpreter
  699. X *    loop, taking input from standard in.  Each input either changes
  700. X *    cursor position or invokes a function.
  701. X */
  702. X
  703. Xmain (argc,argv)
  704. X
  705. X    int        argc;
  706. X    char    *argv[];
  707. X{
  708. X
  709. X    int        month,day,year;
  710. X    char    key;
  711. X    char    *datafile;
  712. X    extern int    abort();
  713. X    int i;
  714. X
  715. X    datafile = NULL;
  716. X    if (argc == 1) {
  717. X    timeset();
  718. X    month = tmonth;
  719. X    day = tday;
  720. X    year = tyear;
  721. X    }
  722. X    else {
  723. X    if (argc == 3) {
  724. X        month = atoi(argv[1]);
  725. X        year = atoi(argv[2]);
  726. X        if (year < 100) year += 1900;
  727. X        if (!month || !year) {
  728. X        printf("Syntax Error:  non-numeric argument\n");
  729. X        abort(1);
  730. X        }
  731. X    }
  732. X    else {
  733. X        if (argc == 2) {
  734. X        timeset();
  735. X        month = tmonth;
  736. X        day = tday;
  737. X        year = tyear;
  738. X        datafile = argv[1];
  739. X        }
  740. X        else {
  741. X        if ( argc == 4) {
  742. X            month = atoi(argv[1]);
  743. X            year = atoi(argv[2]);
  744. X            if (year < 100) year += 1900;
  745. X            if (!month || !year) {
  746. X            printf("Syntax Error:  non-numeric argument\n");
  747. X            abort(1);
  748. X            }
  749. X            datafile = argv[3];
  750. X        }
  751. X        else {
  752. X            printf("Syntax Error:  incorrect number of arguments\n");
  753. X            abort(1);
  754. X        }
  755. X        }
  756. X    }
  757. X    }
  758. X    signal(2,abort);
  759. X    signal(3,abort);
  760. X
  761. X    system("stty cbreak -echo");
  762. X
  763. X    tinit();
  764. X    fputs(TI,stdout);
  765. X    day = 1;
  766. X    maxchars = 38;
  767. X    maxentries = 1000;
  768. X    maxmsgs = 18;
  769. X    msghold[0] = NULL;
  770. X    help1 = 0;
  771. X    help2 = 0;
  772. X
  773. X    loaddata(datafile);
  774. X    cal(month,day,year,datafile);
  775. X    movcur(day);
  776. X
  777. X    key = 'a';
  778. X    while (key != CR) {
  779. X
  780. X    key = getchar();
  781. X
  782. X    switch (key) {
  783. X
  784. X            case 'H' :
  785. X
  786. X        helpcal();
  787. X
  788. X            break;
  789. X
  790. X        case 'p' :
  791. X
  792. X        if (--month < 1) {
  793. X            month = 12;
  794. X            year--;
  795. X        }
  796. X        day = 1;
  797. X        notclear = 0;
  798. X        cal(month,day,year,datafile);
  799. X
  800. X        break;
  801. X
  802. X        case 'n' :
  803. X            
  804. X        if (++month == 13) {
  805. X            month = 1;
  806. X            year++;
  807. X        }
  808. X        day = 1;
  809. X        notclear = 0;
  810. X        cal(month,day,year,datafile);
  811. X
  812. X        break;
  813. X            
  814. X        case 'h' :
  815. X
  816. X        if (--day <= 0) {
  817. X            day = mon[month];
  818. X        }
  819. X        if (notclear) {
  820. X            clearmsgs();
  821. X        }
  822. X
  823. X        break;
  824. X
  825. X        case 'l' :
  826. X
  827. X        if (++day > mon[month]) {
  828. X            day = 1;
  829. X        }
  830. X        if (notclear) {
  831. X            clearmsgs();
  832. X        }
  833. X
  834. X        break;
  835. X
  836. X        case 'j' :
  837. X
  838. X        if ((day += 7) > mon[month]) {
  839. X            day = day % 7;
  840. X            if (day == 0) {
  841. X            day = 7;
  842. X            }
  843. X        }
  844. X        if (notclear) {
  845. X            clearmsgs();
  846. X        }
  847. X
  848. X        break;
  849. X
  850. X        case 'k' :
  851. X
  852. X        if ((day -= 7) <= 0) {
  853. X            day += 35;
  854. X            if (day > mon[month]) {
  855. X            day -= 7;
  856. X            }
  857. X        }
  858. X        if (notclear) {
  859. X            clearmsgs();
  860. X        }
  861. X
  862. X        break;
  863. X
  864. X        case 'e' :
  865. X
  866. X        day = mon[month];
  867. X        if (notclear) {
  868. X            clearmsgs();
  869. X        }
  870. X
  871. X        break;
  872. X
  873. X        case 'b' :
  874. X
  875. X        day = 1;
  876. X        if (notclear) {
  877. X            clearmsgs();
  878. X        }
  879. X
  880. X        break;
  881. X
  882. X        case 'c' :
  883. X
  884. X        clearday(month,day,year);
  885. X
  886. X        break;
  887. X
  888. X        case ' ' :
  889. X
  890. X        notes(month,day,year);
  891. X
  892. X        break;
  893. X
  894. X        case 'm' :
  895. X
  896. X        modnotes(month,day,year);
  897. X
  898. X        break;
  899. X
  900. X
  901. X    }
  902. X    movcur(day);
  903. X    }
  904. X    closefile(datafile);
  905. X    fputs(TE,stdout);
  906. X    system("stty -cbreak echo");
  907. X    if (help1 || help2) {
  908. X    helpclr();
  909. X    }
  910. X    mov(1,24);
  911. X} /* main */
  912. X
  913. X
  914. X/*
  915. X * Procedure:    <routine name>
  916. X *
  917. X * Function:    abort()
  918. X *
  919. X * Discussion:
  920. X *    Reset tty parameters and exits with an error code.
  921. X */
  922. X
  923. Xabort()
  924. X
  925. X{
  926. X    system("stty -cbreak echo");
  927. X    if (help1 || help2) {
  928. X    helpclr();
  929. X    }
  930. X    mov(1,24);
  931. X    fputs(TE,stdout);
  932. X    exit(1);
  933. X} /* abort */
  934. X
  935. X
  936. X
  937. X/*
  938. X * Procedure:    cal(month,day,year,datafile)
  939. X *
  940. X * Function:    produces the visual calendar to the screen
  941. X *
  942. X * Parameters:
  943. X *    p1    - int - month
  944. X *    p2    - int - day
  945. X *    p3    - int - year
  946. X *    p4      - char * - datafile name
  947. X *
  948. X * Discussion:
  949. X *    Calculates current months parameters, such as, starting
  950. X *    day of week, number of days and days on which there are
  951. X *    appointments.  This data is then used to draw a calendar
  952. X *    to the screen.
  953. X */
  954. X
  955. Xcal(month,day,year,datafile)
  956. X
  957. X    int        month,day,year;
  958. X    char    *datafile;
  959. X
  960. X{
  961. X    int        i,j,k,d;
  962. X
  963. X    fputs(CL,stdout);
  964. X    printf("V I S U A L   C A L E N D A R\t\t%s\n",datafile);
  965. X    printf("-------------------------------------------------------------------------------\n");
  966. X    printf("\t\t\t\t%s%u\n", smon[month-1], year);
  967. X    printf("-------------------------------------------------------------------------------\n\n");
  968. X    printf("%s\n\n", dayw);
  969. X
  970. X
  971. X    d = jan1(year);
  972. X    mon[2] = 29;
  973. X    mon[9] = 30;
  974. X
  975. X
  976. X    i = 1;
  977. X    while (i <= 32) {
  978. X    active[i++] = 0;
  979. X    }
  980. X
  981. X    i = 0;
  982. X    while (i < maxentries) {
  983. X    if ((yeardata[i] == year) && (monthdata[i] == month) ) {
  984. X        active[daydata[i]] = 1;
  985. X    }
  986. X    i++;
  987. X    }
  988. X
  989. X    switch((jan1(year+1)+7-d)%7) {
  990. X
  991. X    /*
  992. X     *    non-leap year
  993. X     */
  994. X    case 1:
  995. X        mon[2] = 28;
  996. X        break;
  997. X
  998. X    /*
  999. X     *    1752
  1000. X     */
  1001. X    default:
  1002. X        mon[9] = 19;
  1003. X        break;
  1004. X
  1005. X    /*
  1006. X     *    leap year
  1007. X     */
  1008. X    case 2:
  1009. X        ;
  1010. X    }
  1011. X
  1012. X    /* calculate days from beginning of year */
  1013. X
  1014. X    for(i=1; i<month; i++) {
  1015. X    d += mon[i];
  1016. X    }
  1017. X
  1018. X    d %= 7;
  1019. X    i = 0;
  1020. X
  1021. X    /* inset to first day of week position */
  1022. X
  1023. X    while (i++ < (5*d)) {
  1024. X    printf(" ");
  1025. X    }
  1026. X
  1027. X    k = 0;
  1028. X    i = d;
  1029. X
  1030. X    for (j=1;j<=31;j++) {
  1031. X    xposition[j] = (i*5) + 2;
  1032. X    yposition[j] = (k*2) + 7;
  1033. X    if (++i == 7) {
  1034. X        i = 0;
  1035. X        k++;
  1036. X    }
  1037. X    }
  1038. X
  1039. X    for(i=1; i<=mon[month]; i++) {
  1040. X    if(i==3 && mon[month]==19) {
  1041. X        i += 11;
  1042. X        mon[month] += 11;
  1043. X    }
  1044. X    if (active[i]) {
  1045. X        if(i > 9) {
  1046. X        printf(" ");
  1047. X        printf("%s%d%s",SO,i/10,SE);
  1048. X        }
  1049. X        else {
  1050. X        printf(" ");
  1051. X        printf("%s %s",SO,SE);
  1052. X        }
  1053. X        printf("%s%d%s",SO,i%10,SE);
  1054. X        if (*SO == NULL) {
  1055. X        printf("* ");
  1056. X        }
  1057. X        else {
  1058. X        printf("  ");
  1059. X        }
  1060. X    }
  1061. X    else {
  1062. X        if(i > 9) {
  1063. X        printf(" %d",i/10);
  1064. X        }
  1065. X        else {
  1066. X        printf("  ");
  1067. X        }
  1068. X        printf("%d  ",i%10);
  1069. X    }
  1070. X
  1071. X    if(++d == 7) {
  1072. X        d = 0;
  1073. X        printf("  \n\n");
  1074. X    }
  1075. X    }
  1076. X    
  1077. X    helpclr();
  1078. X
  1079. X    mov(42,5);
  1080. X    printf ("TIME      MESSAGE");
  1081. X} /* cal */
  1082. X
  1083. X
  1084. X/*
  1085. X * Procedure:    jan1(year)
  1086. X *
  1087. X * Function:    calculates day of week of Jan 1 on specified year
  1088. X *
  1089. X * Parameters:
  1090. X *    p1    - int - year
  1091. X *
  1092. X * Return Values:
  1093. X *    integer representation day of the week
  1094. X */
  1095. X
  1096. Xjan1(year)
  1097. X
  1098. X    int        year;
  1099. X{
  1100. X
  1101. X    register y, d;
  1102. X/*
  1103. X *    normal gregorian calendar
  1104. X *    one extra day per four years
  1105. X */
  1106. X
  1107. X    y = year;
  1108. X    d = 4+y+(y+3)/4;
  1109. X
  1110. X/*
  1111. X *    julian calendar
  1112. X *    regular gregorian
  1113. X *    less three days per 400
  1114. X */
  1115. X
  1116. X    if(y > 1800) {
  1117. X    d -= (y-1701)/100;
  1118. X    d += (y-1601)/400;
  1119. X    }
  1120. X
  1121. X/*
  1122. X *    great calendar changeover instant
  1123. X */
  1124. X
  1125. X    if(y > 1752)
  1126. X    d += 3;
  1127. X
  1128. X    return(d%7);
  1129. X} /* jan1 */
  1130. X
  1131. X
  1132. X
  1133. X/*
  1134. X * Procedure:    movcur(day)
  1135. X *
  1136. X * Function:    moves the cursor to the specified day's position
  1137. X *
  1138. X * Parameters:
  1139. X *    p1    - int - day
  1140. X *
  1141. X * Discussion:
  1142. X *    uses termcap values to move the cursor to a matrix position
  1143. X *    stored in a global array
  1144. X */
  1145. X
  1146. Xmovcur(day)
  1147. X
  1148. X    int    day;
  1149. X{
  1150. X    printf("%s",tgoto(CM,xposition[day],yposition[day]));
  1151. X} /* movcur */
  1152. X
  1153. X
  1154. X/*
  1155. X * Procedure:    setday(day)
  1156. X *
  1157. X * Function:    places day in calendar display with appointment
  1158. X *        days highlighted
  1159. X *
  1160. X * Parameters:
  1161. X *    p1    - int - day
  1162. X *
  1163. X * Discussion:
  1164. X *    Uses day arguement, termcap values and calendar position
  1165. X *    matrices to write a day to the screen with days with appointment
  1166. X *    days highlighted.
  1167. X */
  1168. X
  1169. Xsetday(day)
  1170. X
  1171. X    int        day;
  1172. X{
  1173. X    printf("%s",tgoto(CM,(xposition[day]-1),yposition[day]));
  1174. X    if (active[day]) {
  1175. X    if(day > 9) {
  1176. X        printf("%s%d%s",SO,day/10,SE);
  1177. X    }
  1178. X    else {
  1179. X        printf("%s %s",SO,SE);
  1180. X    }
  1181. X    printf("%s%d%s",SO,day%10,SE);
  1182. X    if (*SO == NULL) {
  1183. X        printf("*");
  1184. X    }
  1185. X    else {
  1186. X        printf(" ");
  1187. X    }
  1188. X    }
  1189. X    else {
  1190. X    if(day > 9) {
  1191. X        printf("%d",day/10);
  1192. X    }
  1193. X    else {
  1194. X        printf(" ");
  1195. X    }
  1196. X    printf("%d ",day%10);
  1197. X    }
  1198. X} /* setday */
  1199. X
  1200. X
  1201. X
  1202. X/*
  1203. X * Procedure:    tinit()
  1204. X *
  1205. X * Function:    gets termcap entries
  1206. X *
  1207. X * Return Values:
  1208. X *    loads global variables with termcap parameters
  1209. X *
  1210. X * Discussion:
  1211. X *    Initial various termcap variables so that they can later
  1212. X *    be used to move the cursor and highlight certain displays.
  1213. X */
  1214. X
  1215. Xtinit()    /* termcap initalization */
  1216. X
  1217. X{
  1218. X    char    term[BUFSIZ];        /* holds termcap entry */
  1219. X    char    name[16];        /* terminal name */
  1220. X    char    *np;            /* termcap name pointer */
  1221. X    char    *NADA = { "\0" };    /* null string */
  1222. X    char    *tgetstr();
  1223. X    char    *getenv();
  1224. X
  1225. X    if( (np = getenv( "TERM" )) != NULL ) {
  1226. X        strncpy( name, np, 16 );
  1227. X    }
  1228. X    else {
  1229. X        printf("getenv( \"TERM\" ) failed\n");
  1230. X        abort();
  1231. X    }
  1232. X
  1233. X    if( tgetent( term, name ) != 1 ) {
  1234. X        printf("tgetent( %x, %s ) failed\n", term, name);
  1235. X        abort();
  1236. X    }
  1237. X
  1238. X    /* if a capability does not exist, point it to a null string not NULL
  1239. X    */
  1240. X    tlines = tgetnum( "li" );
  1241. X    tcolumns = tgetnum( "co" );
  1242. X
  1243. X    if( (CM = tgetstr( "cm", &area )) == NULL) {
  1244. X    CM = NADA;    
  1245. X    printf("Error:  vcal will not work with this terminal type\n");
  1246. X    abort();
  1247. X    }
  1248. X    if( (CL = tgetstr( "cl", &area )) == NULL)
  1249. X    CL = NADA;
  1250. X    if( (UP = tgetstr( "up", &area )) == NULL)
  1251. X    UP = NADA;
  1252. X    if( (SO = tgetstr( "so", &area )) == NULL)
  1253. X    SO = NADA;
  1254. X    if( (SE = tgetstr( "se", &area )) == NULL)
  1255. X    SE = NADA;
  1256. X    if( (TI = tgetstr( "ti", &area)) == NULL)
  1257. X    TI = NADA;
  1258. X    if( (TE = tgetstr( "te", &area)) == NULL)
  1259. X    TE = NADA;
  1260. X    if( (SG = tgetnum( "sg", &area))  > 0)  {
  1261. X        SO = NADA;
  1262. X        SE = NADA;
  1263. X    }
  1264. X} /* tinit */
  1265. X
  1266. X
  1267. X
  1268. X/*
  1269. X * Procedure:    loaddata(datafile)
  1270. X *
  1271. X * Function:    loads data file
  1272. X *
  1273. X * Return Values:
  1274. X *    Various global arrays loaded with appointment data
  1275. X *
  1276. X * Discussion:
  1277. X *    Opens user's data file and reads it in, placing
  1278. X *    the data in appropriate arrays.
  1279. X */
  1280. X
  1281. Xloaddata(datafile)
  1282. X
  1283. X    char    *datafile;
  1284. X{
  1285. X    char    basedata[80];
  1286. X    char    tmpbuf[80];
  1287. X    char    *getenv();
  1288. X    char    home[80];
  1289. X    FILE     *fptr;
  1290. X    int        i,j,k,l,field;
  1291. X
  1292. X    i = 0;
  1293. X    while (i < maxentries) {
  1294. X    daydata[i] = 0;
  1295. X    monthdata[i] = 0;
  1296. X    yeardata[i] = 0;
  1297. X    msgdata[i] = 0;
  1298. X    i++;
  1299. X    }
  1300. X
  1301. X    if (datafile == NULL) {
  1302. X    strcpy(home,getenv("HOME"));
  1303. X    strcat(home,"/.appointments");
  1304. X    }
  1305. X    else {
  1306. X    strcpy(home,datafile);
  1307. X    }
  1308. X    if ((fptr = fopen(home,"r")) != NULL) {
  1309. X    i = 0;
  1310. X    while((fgets(basedata,80,fptr) != NULL)) {
  1311. X
  1312. X        basedata[strlen(basedata)-1] = NULL;
  1313. X
  1314. X        j = 0;
  1315. X        k = 0;
  1316. X        field = 0;
  1317. X        while (basedata[j] != NULL ) {
  1318. X                 
  1319. X                if (basedata[j] != ',') {
  1320. X
  1321. X            tmpbuf[k++] = basedata[j];
  1322. X        }
  1323. X        else {
  1324. X            switch (field) {
  1325. X
  1326. X            case 0 : {
  1327. X                tmpbuf[k] = NULL;
  1328. X                monthdata[i] = atoi(tmpbuf);
  1329. X                k = 0;
  1330. X                break;
  1331. X            }
  1332. X            case 1 : {
  1333. X                tmpbuf[k] = NULL;
  1334. X                daydata[i] = atoi(tmpbuf);
  1335. X                k = 0;
  1336. X                break;
  1337. X            }
  1338. X            case 2 : {
  1339. X                tmpbuf[k] = NULL;
  1340. X                yeardata[i] = atoi(tmpbuf);
  1341. X                k = 0;
  1342. X                break;
  1343. X            }
  1344. X            case 3 : {
  1345. X                tmpbuf[k++] = ' ';
  1346. X                tmpbuf[k++] = ' ';
  1347. X                break;
  1348. X            }
  1349. X            }
  1350. X            field++;
  1351. X        }
  1352. X        j++;
  1353. X        }
  1354. X        tmpbuf[k] = NULL;
  1355. X        msgdata[i] = malloc(40);
  1356. X        strcpy(msgdata[i],tmpbuf);
  1357. X
  1358. X        if (i >= maxentries) {
  1359. X        printf("Warning:  Over 1000 entries in data file.  Data truncated.\n");
  1360. X        break;
  1361. X        }
  1362. X        i++;
  1363. X    }
  1364. X    fclose(fptr);
  1365. X    }
  1366. X} /* loaddata */
  1367. X
  1368. X
  1369. X/*
  1370. X * Procedure:    closefile(datafile)
  1371. X *
  1372. X * Function:    writes appointment data to file
  1373. X *
  1374. X * Discussion:
  1375. X *    Opens the user's designated data file and writes the current
  1376. X *    data into it.
  1377. X */
  1378. X
  1379. Xclosefile(datafile)
  1380. X
  1381. Xchar    *datafile;
  1382. X{
  1383. X    FILE    *fptr;
  1384. X    char    tmpbuf[80];
  1385. X    int        i;
  1386. X    char    *getenv();
  1387. X    char    home[80];
  1388. X
  1389. X    if (datafile == NULL) {
  1390. X    strcpy(home,getenv("HOME"));
  1391. X    strcat(home,"/.appointments");
  1392. X    }
  1393. X    else {
  1394. X    strcpy(home,datafile);
  1395. X    }
  1396. X    if ((fptr = fopen(home,"w")) == NULL) {
  1397. X    printf("Error:  Cannot open %s file",datafile);
  1398. X    abort();
  1399. X    }    
  1400. X    i = 0;
  1401. X    while (i < maxentries) {
  1402. X    if (daydata[i]) {
  1403. X        strcpy(tmpbuf,msgdata[i]);
  1404. X        tmpbuf[4] = NULL;
  1405. X        fprintf(fptr,"%d,%d,%d,%4.4s,%s\n",monthdata[i],daydata[i],yeardata[i],tmpbuf,&tmpbuf[6]);
  1406. X    }
  1407. X    i++;
  1408. X    }
  1409. X    fclose(fptr);
  1410. X} /* closefile */
  1411. X
  1412. X
  1413. X
  1414. X
  1415. X/*
  1416. X * Procedure:    notes(month,day,year)
  1417. X *
  1418. X * Function:    displays the current day's appointments
  1419. X *
  1420. X * Parameters:
  1421. X *    p1    - int - month
  1422. X *    p2    - int - day
  1423. X *    p3    - int - year
  1424. X *
  1425. X * Discussion:
  1426. X *    Writes to notes section of screen notes for day to
  1427. X *    which the cursor was pointing.
  1428. X */
  1429. X
  1430. Xnotes(month,day,year)
  1431. X
  1432. X    int        month,day,year;
  1433. X{
  1434. X    int        i,j,k;
  1435. X
  1436. X    if (help1) {
  1437. X    helpclr();
  1438. X    help1 = 0;
  1439. X    }
  1440. X
  1441. X    i = 0;
  1442. X    while (i < 18) {
  1443. X    dayindex[i++] = 0;
  1444. X    }
  1445. X
  1446. X    mov(64,5);
  1447. X    printf("%2d/%2d/%2d",month,day,year);
  1448. X
  1449. X    i = 0;
  1450. X    j = 0;
  1451. X    k = 6;
  1452. X
  1453. X    while (i < maxentries) {
  1454. X    if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
  1455. X        dayindex[j++] = i;
  1456. X        notclear++;
  1457. X        mov(42,k++);
  1458. X        printf("%s",msgdata[i]);
  1459. X    }
  1460. X    if (j > maxmsgs) {
  1461. X        mov(42,24);
  1462. X        printf("* too many entries to print *");
  1463. X        break;
  1464. X    }
  1465. X    i++;
  1466. X    }
  1467. X    i = 0;
  1468. X    while (i < maxentries) {
  1469. X    if (daydata[i] == 0) {
  1470. X        dayindex[j++] = i;
  1471. X        if (j >= maxmsgs) {
  1472. X        break;
  1473. X        }
  1474. X    }
  1475. X    i++;
  1476. X    }
  1477. X} /* notes */
  1478. X
  1479. X
  1480. X
  1481. X/*
  1482. X * Procedure:    modnotes(month,day,year)
  1483. X *
  1484. X * Function:    add, delete and modify appointment list
  1485. X *
  1486. X * Parameters:
  1487. X *    p1    - int - month
  1488. X *    p2    - int - day
  1489. X *    p3    - int - year
  1490. X *
  1491. X * Return Values:
  1492. X *    changes data in global message and date arrays
  1493. X *
  1494. X * Discussion:
  1495. X *    Allows the user to add, delete and modify a specified day's
  1496. X *    appointment list.  Routine contains a small character
  1497. X *    interpreter which moves the cursor through the notes list
  1498. X *    and selects routines to modify the list.
  1499. X */
  1500. X
  1501. Xmodnotes (month,day,year)
  1502. X
  1503. X    int        month,day,year;
  1504. X{
  1505. X
  1506. X    char    key,c;
  1507. X    int        xcoord,ycoord;
  1508. X    int        i,cnt,total;
  1509. X    char    tmpmsg[39];
  1510. X
  1511. X    notes(month,day,year);
  1512. X    xcoord = 42;
  1513. X    ycoord = 6;
  1514. X    i = 0;
  1515. X    mov(xcoord,ycoord);
  1516. X    key = 'a';
  1517. X
  1518. X    while (key != CR) {
  1519. X
  1520. X    key = getchar();
  1521. X
  1522. X    switch (key) {
  1523. X
  1524. X            case 'H' :
  1525. X
  1526. X        helpnotes();
  1527. X
  1528. X            break;
  1529. X
  1530. X        case 'j' :
  1531. X        i++;
  1532. X        if (++ycoord > 23) {
  1533. X            ycoord = 6;
  1534. X            i = 0;
  1535. X        }
  1536. X        break;
  1537. X
  1538. X        case 'k' :
  1539. X        i--;
  1540. X        if (--ycoord < 6) {
  1541. X            ycoord = 23;
  1542. X            i = 17;
  1543. X        }
  1544. X        break;
  1545. X
  1546. X        case 'd' :
  1547. X
  1548. X        fputs(SO,stdout);
  1549. X        printf("                                      ");
  1550. X        fputs(SE,stdout);
  1551. X        mov (xcoord,ycoord);
  1552. X        monthdata[dayindex[i]] = 0;
  1553. X        daydata[dayindex[i]] = 0;
  1554. X        yeardata[dayindex[i]] = 0;
  1555. X        strcpy(msghold,msgdata[dayindex[i]]);
  1556. X        if (msgdata[dayindex[i]]) {
  1557. X            free(msgdata[dayindex[i]]);
  1558. X            msgdata[dayindex[i]] = 0;
  1559. X        }
  1560. X        break;
  1561. X
  1562. X            case 'y' :
  1563. X
  1564. X        strcpy(msghold,msgdata[dayindex[i]]);
  1565. X
  1566. X        break;
  1567. X
  1568. X            case 'p' :
  1569. X
  1570. X            if (msgdata[dayindex[i]] == 0) {
  1571. X            msgdata[dayindex[i]] = malloc(40);
  1572. X            }
  1573. X            strcpy(msgdata[dayindex[i]],msghold);
  1574. X            yeardata[dayindex[i]] = year;
  1575. X            daydata[dayindex[i]] = day;
  1576. X            monthdata[dayindex[i]] = month;
  1577. X            printf("%s",msgdata[dayindex[i]]);
  1578. X
  1579. X        break;
  1580. X
  1581. X        case 'i' :
  1582. X
  1583. X        fputs(SO,stdout);
  1584. X        printf("                                      ");
  1585. X
  1586. X        mov (xcoord,ycoord);
  1587. X
  1588. X        c = '0';
  1589. X        cnt = 0;
  1590. X        while (c != ESC) {
  1591. X            c = getchar();
  1592. X            if (c != ESC ) {
  1593. X            if (c == BS) {
  1594. X                if (cnt > 0) {
  1595. X                cnt--;
  1596. X                if (cnt == 5) {
  1597. X                    cnt = 3;
  1598. X                    mov(46,ycoord);
  1599. X                }
  1600. X                printf("%c %c",c,c);
  1601. X                }
  1602. X            }
  1603. X            else {
  1604. X                if (c != CR) {
  1605. X                if ( cnt < maxchars) {
  1606. X                    tmpmsg[cnt] = c;
  1607. X                    cnt++;
  1608. X                    printf("%c",c);
  1609. X                }
  1610. X                if (cnt == 4) {
  1611. X                    tmpmsg[4] = ' ';
  1612. X                    tmpmsg[5] = ' ';
  1613. X                    cnt = 6;
  1614. X                    mov(48,ycoord);
  1615. X                }
  1616. X                }
  1617. X                else {
  1618. X                c = ESC;
  1619. X                }
  1620. X            }
  1621. X            }
  1622. X        }
  1623. X        fputs(SE,stdout);
  1624. X        if (cnt) {
  1625. X            tmpmsg[cnt] = NULL;
  1626. X            if (msgdata[dayindex[i]] == 0) {
  1627. X            msgdata[dayindex[i]] = malloc(40);
  1628. X            }
  1629. X            strcpy(msgdata[dayindex[i]],tmpmsg);
  1630. X            monthdata[dayindex[i]] = month;
  1631. X            daydata[dayindex[i]] = day;
  1632. X            yeardata[dayindex[i]] = year;
  1633. X        }
  1634. X        else {
  1635. X            monthdata[dayindex[i]] = 0;
  1636. X            daydata[dayindex[i]] = 0;
  1637. X            yeardata[dayindex[i]] = 0;
  1638. X            if (msgdata[dayindex[i]]) {
  1639. X            free(msgdata[dayindex[i]]);
  1640. X            msgdata[dayindex[i]] = 0;
  1641. X            }
  1642. X        }
  1643. X
  1644. X        break;
  1645. X
  1646. X        default :;
  1647. X    }
  1648. X    mov (xcoord,ycoord);
  1649. X    }
  1650. X
  1651. X    active[day] = 0;
  1652. X    i = 0;
  1653. X    while (i < maxentries) {
  1654. X    if ((yeardata[i] == year) && (monthdata[i] == month)) {
  1655. X        notclear = 18;
  1656. X        active[daydata[i]] = 1;
  1657. X    }
  1658. X    i++;
  1659. X    }
  1660. X
  1661. X    notclear = 18;
  1662. X    clearmsgs();
  1663. X    if (active[day]) {
  1664. X    notes(month,day,year);
  1665. X    }
  1666. X    setday(day);
  1667. X    if (help2) {
  1668. X    helpclr();
  1669. X    help2 = 0;
  1670. X    }
  1671. X} /* modnotes */
  1672. X
  1673. X
  1674. X/*
  1675. X * Procedure:    mov(column,row)
  1676. X *
  1677. X * Function:    moves cursor on screen
  1678. X *
  1679. X * Parameters:
  1680. X *    p1    - int - crt column
  1681. X *    p2    - int - crt row
  1682. X *
  1683. X * Discussion:
  1684. X *    Moves the cursor to specified column and row on screen using
  1685. X *    termcap data.
  1686. X */
  1687. X
  1688. Xmov(col, row)
  1689. X
  1690. Xint    col,row;
  1691. X
  1692. X{
  1693. X    printf("%s",tgoto(CM,(col - 1),(row - 1)));
  1694. X} /* move */
  1695. X
  1696. X
  1697. X/*
  1698. X * Procedure:    clearday(month,day,year)
  1699. X *
  1700. X * Function:    deletes specified day's appointments
  1701. X *
  1702. X * Parameters:
  1703. X *    p1    - int - month
  1704. X *    p2    - int - day
  1705. X *    p2    - int - year
  1706. X *
  1707. X * Return Values:
  1708. X *    changes various global arrays
  1709. X *
  1710. X * Discussion:
  1711. X *    Removes appointment entries for the specified day from
  1712. X *    message and date tables and from the crt
  1713. X */
  1714. X
  1715. Xclearday (month,day,year)
  1716. X
  1717. X    int        month,day,year;
  1718. X{
  1719. X    int        i;
  1720. X
  1721. X    i = 0;
  1722. X    while (i < maxentries) {
  1723. X    if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
  1724. X        active[day] = 0;
  1725. X        monthdata[i] = 0;
  1726. X        daydata[i] = 0;
  1727. X        yeardata[i] = 0;
  1728. X        if (msgdata[i])  {
  1729. X        free(msgdata[i]);
  1730. X        msgdata[i] = 0;
  1731. X        }
  1732. X    }
  1733. X    i++;
  1734. X    }
  1735. X    clearmsgs();
  1736. X    setday(day);
  1737. X} /* clearday */
  1738. X
  1739. X
  1740. X/*
  1741. X * Procedure:    clearmsgs()
  1742. X *
  1743. X * Function:    clears the notes section of the crt
  1744. X */
  1745. X
  1746. Xclearmsgs()
  1747. X
  1748. X{
  1749. X    int        i;
  1750. X
  1751. X    mov(64,5);
  1752. X    printf("          ");
  1753. X
  1754. X    if (notclear > maxmsgs) notclear = maxmsgs;
  1755. X
  1756. X    i = 6;
  1757. X    while (i < (notclear+6)) {
  1758. X    mov(42,i++);
  1759. X    printf("                                      ");
  1760. X    }
  1761. X    mov(42,24);
  1762. X    printf("                                   ");
  1763. X    notclear = 0;
  1764. X} /* clearmsgs */
  1765. X
  1766. X
  1767. X/*
  1768. X * Procedure:    helpcal()
  1769. X *
  1770. X * Function:    displays calendar help messages to crt
  1771. X */
  1772. X
  1773. Xhelpcal()
  1774. X
  1775. X{
  1776. X    mov(1,19);
  1777. X    printf("j/k/h/l:  cursor down/up/left/right     \n");
  1778. X    printf("b:  first day         e: last day       \n");
  1779. X    printf("space: display notes  m: modify notes   \n");
  1780. X    printf("c: clear notes        CR: exit program  \n");
  1781. X    printf("p: previous month     n: next month     \n");
  1782. X    printf("BRK: exit w/o changes                   ");
  1783. X    help1++;
  1784. X} /* helpcal */
  1785. X
  1786. X
  1787. X/*
  1788. X * Procedure:    helpnotes()
  1789. X *
  1790. X * Function:    displays notes help messages to crt
  1791. X */
  1792. X
  1793. Xhelpnotes() 
  1794. X
  1795. X{
  1796. X    mov(1,19);
  1797. X    printf("j/k:  cursor down/up                    \n");
  1798. X    printf("i: enter insert      ESC/CR: exit insert\n");
  1799. X    printf("d: delete entry      CR: exit notes     \n");
  1800. X    printf("y/p: yank/put a line                    \n");
  1801. X    printf("                                        \n");
  1802. X    printf("                                        ");
  1803. X    help2++;
  1804. X} /* helpnotes */
  1805. X
  1806. X
  1807. X/*
  1808. X * Procedure:    helpclr()
  1809. X *
  1810. X * Function:    clears notes area of screen
  1811. X */
  1812. X
  1813. Xhelpclr ()
  1814. X{
  1815. X    mov(1,19);
  1816. X    printf("                                        \n");
  1817. X    printf("                                        \n");
  1818. X    printf("                                        \n");
  1819. X    printf("                                        \n");
  1820. X    printf("    Type 'H' for help                   \n");
  1821. X    printf("                                        ");
  1822. X} /* helpclr */
  1823. X
  1824. X
  1825. X/*
  1826. X * Procedure:    timeset()
  1827. X *
  1828. X * Function:    sets current month, day and year variables
  1829. X *
  1830. X * Return Values:
  1831. X *    tday, tmonth and tyear variables set to current date
  1832. X */
  1833. X
  1834. Xtimeset()
  1835. X
  1836. X{
  1837. X    struct    tm *localtime();
  1838. X
  1839. X    struct tm *tp;        /* time structure */
  1840. X    long    tloc;        /* number of seconds since 1970 */
  1841. X
  1842. X    time(&tloc);    /* fills tloc */
  1843. X
  1844. X    tp = localtime(&tloc);
  1845. X
  1846. X    tyear =    tp->tm_year;
  1847. X    tmonth =    tp->tm_mon + 1;
  1848. X    tday =    tp->tm_mday;
  1849. X
  1850. X    tyear += 1900;
  1851. X
  1852. X} /* timeset */
  1853. *-*-END-of-vcal.c-*-*
  1854. echo x - eappts.l
  1855. sed 's/^X//' >eappts.l <<'*-*-END-of-eappts.l-*-*'
  1856. X.TH EAPPTS 1 
  1857. X.SH NAME
  1858. Xeappts \- enter appointments
  1859. X.SH SYNOPSIS
  1860. X.B eappts [ filename ]
  1861. X.SH DESCRIPTION
  1862. X.I Eappts
  1863. Xis a program which is used to enter appointment data into the user's
  1864. X~/.appointments file by default or the file specified in the optional
  1865. Xfilename argument.
  1866. X.PP
  1867. XThe user is prompted for a date, time and message.
  1868. XThe date is entered as three numeric values separated by spaces.
  1869. XA two or four digit year value should be used.
  1870. X.PP
  1871. XData entered using
  1872. X.I eappts
  1873. Xmay be used by four companion programs.
  1874. XThese are:
  1875. X.br
  1876. X.sp
  1877. X.nf
  1878. Xvcal            calendar and notes program
  1879. Xappts           displays current or seleted day's appoinments
  1880. Xautocall        set appointment reminders for the current day
  1881. Xlcal            displays the month's appointments in tabular form
  1882. X.fi
  1883. X.sp
  1884. XFor further information on these, reference the appropriate "man"
  1885. Xentries.
  1886. X.SH AUTHOR
  1887. XMike Essex
  1888. X.SH FILES
  1889. Xeappts
  1890. X.br
  1891. X~/.appointments
  1892. X.br
  1893. X.SH "SEE ALSO"
  1894. Xvcal(1), appts(1), autocall(1), lcal(1), callme(1)
  1895. X.SH BUGS
  1896. XThere are year 2000 time bombs.
  1897. *-*-END-of-eappts.l-*-*
  1898. echo x - lcal.l
  1899. sed 's/^X//' >lcal.l <<'*-*-END-of-lcal.l-*-*'
  1900. X.TH LCAL 1 
  1901. X.SH NAME
  1902. Xlcal \- display current or selected month's appointments
  1903. X.SH SYNOPSIS
  1904. X.B lcal 
  1905. X[ month year ] [ filename(s) ]
  1906. X.sp
  1907. Xwhere
  1908. X.I month
  1909. Xis a numeric value between 1 and 12,
  1910. X.I year
  1911. Xis a numeric four digit value and
  1912. X.I filename(s)
  1913. Xare the data files to be searched.
  1914. X.SH DESCRIPTION
  1915. X.I Lcal
  1916. Xis a program which uses the data stored by "vcal" or "eappts" to
  1917. Xdisplay the user's appointments to standard out.
  1918. X.PP
  1919. XWhen an argument is present,
  1920. X.I lcal
  1921. Xwill display appointments for the requested month and year.
  1922. XThe default argument values are the current month and year.
  1923. XIf no filename is specified ~/.appointments will be searched.
  1924. XIf one or more filenames arguments are used those files will
  1925. Xbe searched.
  1926. X.SH AUTHOR
  1927. XMike Essex
  1928. X.SH FILES
  1929. Xlcal
  1930. X.br
  1931. X~/.appointments
  1932. X.br
  1933. X.SH "SEE ALSO"
  1934. Xvcal(1), appts(1), eappts(1), autocall(1), callme(1)
  1935. X.SH BUGS
  1936. XThere are year 2000 time bombs.
  1937. *-*-END-of-lcal.l-*-*
  1938. echo x - vcal.l
  1939. sed 's/^X//' >vcal.l <<'*-*-END-of-vcal.l-*-*'
  1940. X.TH VCAL 1 
  1941. X.SH NAME
  1942. Xvcal \- visual calendar and notes program
  1943. X.SH SYNOPSIS
  1944. X.B vcal 
  1945. X[ month year ] [ filename ]
  1946. X.sp
  1947. Xwhere
  1948. X.I month
  1949. Xis a numeric value between 1 and 12,
  1950. X.I year
  1951. Xis a numeric four digit value and
  1952. X.I filename
  1953. Xis the data file to be accessed.
  1954. X.SH DESCRIPTION
  1955. X.I Vcal 
  1956. Xis a visual calendar program which allows the user to enter notes
  1957. Xand appointments for each day of the month.  It can be used to
  1958. Xreplace the "paper" desk or wall calendar with an electronic one
  1959. Xwhich can be accessed from any terminal or modem connected to the
  1960. Xcomputer system.
  1961. X.PP
  1962. XWhen a date argument is present,
  1963. X.I vcal
  1964. Xwill display the requested month and year.  The default argument values
  1965. Xare the current month and year.  When a filename argument is used
  1966. X.I vcal
  1967. Xwill uses that file instead of the default ~/.appointments file.
  1968. XIf ~/.appointments is not used the filename of the current file
  1969. Xwill appear at the top of the
  1970. X.I vcal
  1971. Xcalendar.
  1972. X.SH OPERATION
  1973. X.I Vcal
  1974. Xis entered from UNIX by typing the
  1975. Xcommand followed by an optional month and year value.  A calendar
  1976. Xwill be displayed on the screen with the cursor located on the first
  1977. Xday of the month.  The cursor may be moved to different days
  1978. Xin the following manner.
  1979. X.br
  1980. X.sp
  1981. X.nf
  1982. Xkey             function
  1983. X---             --------
  1984. Xj               move cursor down
  1985. Xk               move cursor up
  1986. Xl               move cursor to the next day
  1987. Xh               move cursor to the previous day
  1988. Xb               move cursor to the beginning of the month
  1989. Xe               move cursor to the end of the month
  1990. X.sp
  1991. X.fi
  1992. X.PP
  1993. XPrevious and following months may also be accessed.
  1994. X.br
  1995. X.sp
  1996. X.nf
  1997. Xkey             function
  1998. X---             --------
  1999. Xp               previous month
  2000. Xn               next month
  2001. X.sp
  2002. X.fi
  2003. X.PP
  2004. XUp to eighteen appointments may be entered on each day of the month.
  2005. XThese may be displayed, modified or cleared in with the following keys.
  2006. XThey will operate on the day selected by the current cursor position.
  2007. X.br
  2008. X.sp 4
  2009. X.nf
  2010. Xkey             function
  2011. X---             --------
  2012. Xspace           display appointments for the selected day
  2013. Xm               enter or modify appointments
  2014. Xc               clear all appointments for the selected day
  2015. X.sp
  2016. X.fi
  2017. X.PP
  2018. XWhen the 'm' is pressed
  2019. X.I vcal
  2020. Xenters notes mode.  While in this mode notes may be added, modified,
  2021. Xdeleted, yanked or put.
  2022. X.br
  2023. X.sp
  2024. X.nf
  2025. Xkey             function
  2026. X---             --------
  2027. Xj               move cursor down
  2028. Xk               move cursor up
  2029. Xi               begin data insertion
  2030. XESC/CR          end data insertion (only while in insert)
  2031. Xd               delete the selected line
  2032. Xy               hold the current line
  2033. Xp               insert the held message
  2034. XCR              exit notes mode and return to the calendar
  2035. X.sp
  2036. X.fi
  2037. XData must begin with the appointment time in 24 hour format
  2038. X(no ':' should be used).  Entering new data will erase the current
  2039. Xmessage on that line.  A held line will be available to insert until
  2040. Xit is changed or the user exits
  2041. X.I vcal.
  2042. XA line which is deleted using the 'd' key will be placed in the hold
  2043. Xbuffer.
  2044. X.PP
  2045. XWhen the cursor is on the calendar a carriage return will cause the
  2046. Xthe appointment data to be saved and
  2047. X.I vcal
  2048. Xto exit.  Break or delete will cause
  2049. X.I vcal
  2050. Xto exit without updating the ~/.appointments file.
  2051. X.PP
  2052. XA 'H' will display help messages.  A calendar help message
  2053. Xwill be printed when
  2054. Xthe cursor is on calendar days.  A notes help message
  2055. Xis printed when the cursor is in the notes area.
  2056. X.PP
  2057. XFive companion programs are available to use with the
  2058. X.I vcal
  2059. Xprogram.  These are:
  2060. X.br
  2061. X.sp
  2062. X.nf
  2063. Xappts           display current or selected days appointments
  2064. Xeappts          enter appointments from the UNIX command line
  2065. Xautocall        set appointment reminders for the current day
  2066. Xlcal            displays month's appointments in tabular form
  2067. Xcallme          sets appointment reminders
  2068. X.fi
  2069. X.sp
  2070. XFor further information on these, reference the appropriate "man"
  2071. Xentries.
  2072. X.SH AUTHOR
  2073. XMike Essex
  2074. X.SH FILES
  2075. Xvcal
  2076. X.br
  2077. X/etc/termcap
  2078. X.br
  2079. X~/.appointments
  2080. X.br
  2081. X.SH "SEE ALSO"
  2082. Xappts(1), eappts(1), autocall(1), lcal(1), callme(1)
  2083. X.SH BUGS
  2084. X.I Vcal
  2085. Xmay not work with extremely brain damaged terminals.  There must be
  2086. Xa 'CM' entry in the termcap for 
  2087. X.I vcal
  2088. Xto draw the screen.  There are year 2000 time bombs.
  2089. X.br
  2090. *-*-END-of-vcal.l-*-*
  2091. exit
  2092.  
  2093.  
  2094. From me@pinot Thu Feb 19 20:21:00 1987
  2095. Path: beno!seismo!lll-lcc!ptsfa!varian!zehntel!me@pinot (Mike Essex)
  2096. From: me@pinot (Mike Essex)
  2097. Newsgroups: net.sources
  2098. Subject: vcal and friends  Rev 2.0  Part 2
  2099. Message-ID: <141@zehntel.UUCP>
  2100. Date: 20 Feb 87 01:21:00 GMT
  2101. Sender: news@zehntel.UUCP
  2102. Organization: Zehntel Inc., Walnut Creek CA
  2103. Lines: 2171
  2104.  
  2105.  
  2106. echo x - README.new
  2107. sed 's/^X//' >README.new <<'*-*-END-of-README.new-*-*'
  2108. X            VCAL AND FRIENDS                  2/19/87
  2109. X
  2110. X-------------------------------------------------------------------
  2111. XThis is the second release of vcal and friends.
  2112. XIt has fixed a number of problems and incorporated some suggestions
  2113. XI recieved in your responses.  For the most part I have received
  2114. Xenthusiastic replies and I thank you for the responses.  There
  2115. Xwere a number of sites who didn't recieve both pieces and some
  2116. Xwho had pieces truncated.  Hopefully, this release will get through
  2117. Xto all.
  2118. X
  2119. XChanges include:
  2120. X
  2121. Xvcal - Changed terminal handler routines to take advantage of 
  2122. X       termcap(3) capabilites allow vcal to be used with a greater
  2123. X       number of terminal types.  Changed start up cursor position
  2124. X       to current date.  Fixed several minor bugs.
  2125. X
  2126. Xautocall - Fixed a loop bug which was causing core dumps in some
  2127. X       instances.  Changed message buffer size.
  2128. X
  2129. Xcallme - No change.
  2130. X
  2131. Xappts.c - Changed message size so that long messages from a manually
  2132. X          edited data file does not cause a core dump.
  2133. X
  2134. Xeappts - Changed message buffer size.
  2135. X
  2136. Xlcal - Changed message buffer size.
  2137. X-------------------------------------------------------------------
  2138. Xdef.:  a set of calendar and appointment utility programs to replace
  2139. X       the traditional paper calendar.
  2140. X       
  2141. XVcal and friends allow the user to view a calendar, enter dates and
  2142. Xtimes of activities, set times for prompts to the CRT and to produce
  2143. Xlists of a month's activities.  Multiple data files may be used to
  2144. Xallow the user to have one calendar for personal activities, one for
  2145. Xbusiness activities, one for project milestones, etc.
  2146. X
  2147. XThese programs are written in 'C' and run under UNIX.  To date they
  2148. Xhave been compiled and execute on the following systems:
  2149. X
  2150. XDEC PDP 11/70    UNIX Version 7
  2151. XDEC VAX 11/750    UNIX BSD 4.2 and 4.3
  2152. XSun 2/170    UNIX BSD 4.2
  2153. XSun 3/160    UNIX BSD 4.2
  2154. XSun 3/260     UNIX BSD 4.2
  2155. XDEC MicroVAX    ULTRIX
  2156. X
  2157. XIncluded in this package are six source files, six manual files, a
  2158. Xmakefile and this introduction.  The makefile is for use with the
  2159. Xstandard "make" utility on a VAX 11/750 under BSD 4.3.  For use with
  2160. Xa PDP 11/70 BSD Version 7 change the makefile library entry from
  2161. X"termlib" to "termcap".
  2162. X
  2163. XAll the "vcal" files have been combined here with the "shar" script.
  2164. XSince the combined size of the files are greater than 65,000
  2165. Xcharacters they have been broken into two parts for transmission.
  2166. XPart 1 contains makefile, appts.c, autocall.c and callme.c along
  2167. Xwith the manual pages for these.  Part 2 contains eappts.c, lcal.c
  2168. Xand vcal.c and their manual pages.
  2169. X
  2170. XSynopsis of files:
  2171. X
  2172. Xappts        displays the current or specified day's activities
  2173. X
  2174. Xautocall    starts background reminder processes for each of the
  2175. X        current day's activities
  2176. X
  2177. Xcallme        starts a background reminder process for a specified
  2178. X        time and activity
  2179. X
  2180. Xeappts        allows activities to be entered into a data file from
  2181. X        the command line
  2182. X
  2183. Xlcal        produces a tabular listing of the current or specified
  2184. X        month's activities
  2185. X
  2186. Xvcal        visual calendar displaying the current or specified
  2187. X        month's activities; allows entries to be added, changed
  2188. X        or deleted
  2189. X
  2190. Xmakefile    makefile for all of the "vcal" programs
  2191. X
  2192. Xmanual pages:    appts.l autocall.l callme.l eappts.l lcal.l vcal.l
  2193. X
  2194. XComments and suggestions will be appreciated and considered.
  2195. X
  2196. XMike Essex  (~me)
  2197. X
  2198. X     ....!ucbvax!zehntel!me
  2199. X     ....!decvax!sytek!zehntel!me
  2200. X     ...."zehntel!me"@BERKELEY
  2201. *-*-END-of-README.new-*-*
  2202. echo x - eappts.c
  2203. sed 's/^X//' >eappts.c <<'*-*-END-of-eappts.c-*-*'
  2204. X/*
  2205. X * Module:    eappts.c
  2206. X *
  2207. X * Purpose:    enters data into appointments file
  2208. X *
  2209. X * Author:    Mike Essex
  2210. X *
  2211. X * Date:    Sep. 16, 1986
  2212. X *
  2213. X * Includes:
  2214. X *    stdio.h
  2215. X * Discussion:
  2216. X *    Inputs data from standard input and writes it to ~/.appointments
  2217. X *    file
  2218. X * 
  2219. X *
  2220. X * Edit History
  2221. X * ==== =======
  2222. X *
  2223. X * Date      Who    What
  2224. X * ----      ---    ----------------------------------------------
  2225. X * 12/1/86   me        added multifile capability
  2226. X * 12/1/86   me        changed 'home' from *home[80] to home[80]
  2227. X *
  2228. X */
  2229. X
  2230. X#include <stdio.h>
  2231. X#define        NL    '\010'
  2232. X
  2233. X
  2234. X/*
  2235. X * Procedure:    main
  2236. X *
  2237. X * Function:    inputs data and writes to users .appointments file
  2238. X *
  2239. X * Discussion:
  2240. X *    Prompts users for required appointment information, inputs
  2241. X *    that info and then appends it to ~/.appointments file.
  2242. X */
  2243. X
  2244. Xmain(argc,argv)
  2245. X
  2246. Xint    argc;
  2247. Xchar    *argv[];
  2248. X
  2249. X{
  2250. X    FILE    *fptr;
  2251. X    char    tmpbuf[80];
  2252. X    int        i,j;
  2253. X    char    *getenv();
  2254. X    char    home[80];
  2255. X    char    datedata[20];
  2256. X    char    timedata[20];
  2257. X    char    msgdata[40];
  2258. X    int        month,day,year,time;
  2259. X    int        index[5];
  2260. X
  2261. X    if (argc == 2) {
  2262. X    strcpy(home,argv[1]);
  2263. X    }
  2264. X    else {
  2265. X    strcpy(home,getenv("HOME"));
  2266. X    strcat(home,"/.appointments");
  2267. X    }
  2268. X
  2269. X    fptr = fopen(home,"a");
  2270. X    if (fptr) {
  2271. X    printf("What is the date of appointment?  (mm dd yyyy)  ");
  2272. X    fgets(datedata,20,stdin);
  2273. X    i = 0;
  2274. X    j = 0;
  2275. X    while(i < 20) {
  2276. X        while ((i < 20) && (datedata[i] == ' ')) i++;
  2277. X        index[j++] = i;
  2278. X        while ((i < 20) && (datedata[i] != ' ')) i++;
  2279. X    }
  2280. X    month = atoi(&datedata[index[0]]);
  2281. X    day = atoi(&datedata[index[1]]);
  2282. X    year = atoi(&datedata[index[2]]);
  2283. X    if (year < 100) year += 1900;
  2284. X
  2285. X    printf("What time (24 hour time) is the appointment?  (tttt)  ");
  2286. X    fgets(timedata,20,stdin);
  2287. X    time = atoi(timedata);
  2288. X    printf("What is the message?  ");
  2289. X    fgets(msgdata,79,stdin);
  2290. X    msgdata[strlen(msgdata)-1] = NULL;
  2291. X    fprintf(fptr,"%d,%d,%d,%4d,%s\n",month,day,year,time,msgdata);
  2292. X    }
  2293. X    else {
  2294. X    printf("Error:  Cannot open %s file",argv[1]);
  2295. X    abort();
  2296. X    }
  2297. X    fclose(fptr);
  2298. X} /* main */
  2299. *-*-END-of-eappts.c-*-*
  2300. echo x - eappts.l
  2301. sed 's/^X//' >eappts.l <<'*-*-END-of-eappts.l-*-*'
  2302. X.TH EAPPTS 1 
  2303. X.SH NAME
  2304. Xeappts \- enter appointments
  2305. X.SH SYNOPSIS
  2306. X.B eappts [ filename ]
  2307. X.SH DESCRIPTION
  2308. X.I Eappts
  2309. Xis a program which is used to enter appointment data into the user's
  2310. X~/.appointments file by default or the file specified in the optional
  2311. Xfilename argument.
  2312. X.PP
  2313. XThe user is prompted for a date, time and message.
  2314. XThe date is entered as three numeric values separated by spaces.
  2315. XA two or four digit year value should be used.
  2316. X.PP
  2317. XData entered using
  2318. X.I eappts
  2319. Xmay be used by four companion programs.
  2320. XThese are:
  2321. X.br
  2322. X.sp
  2323. X.nf
  2324. Xvcal            calendar and notes program
  2325. Xappts           displays current or seleted day's appoinments
  2326. Xautocall        set appointment reminders for the current day
  2327. Xlcal            displays the month's appointments in tabular form
  2328. X.fi
  2329. X.sp
  2330. XFor further information on these, reference the appropriate "man"
  2331. Xentries.
  2332. X.SH AUTHOR
  2333. XMike Essex
  2334. X.SH FILES
  2335. Xeappts
  2336. X.br
  2337. X~/.appointments
  2338. X.br
  2339. X.SH "SEE ALSO"
  2340. Xvcal(1), appts(1), autocall(1), lcal(1), callme(1)
  2341. X.SH BUGS
  2342. XThere are year 2000 time bombs.
  2343. *-*-END-of-eappts.l-*-*
  2344. echo x - lcal.c
  2345. sed 's/^X//' >lcal.c <<'*-*-END-of-lcal.c-*-*'
  2346. X/*
  2347. X * Module:    lcal.c
  2348. X *
  2349. X * Purpose:    print month's appointments
  2350. X *
  2351. X * Author:    Mike Essex
  2352. X *
  2353. X * Date:    Sep. 16, 1986
  2354. X *
  2355. X * Includes:
  2356. X *    time.h, stdio.h, ctype.h, signal.h
  2357. X *
  2358. X * Discussion:
  2359. X *    Reads data from ~/.appointments and/or designated file and
  2360. X *      writes to standard *    out any appoinments which fall in
  2361. X *      the current or optionally specified month.
  2362. X * 
  2363. X *
  2364. X * Edit History
  2365. X * ==== =======
  2366. X *
  2367. X * Date      Who    What
  2368. X * ----      ---    ----------------------------------------------
  2369. X *
  2370. X */
  2371. X
  2372. X#include <stdio.h>
  2373. X#include <signal.h>
  2374. X#include <ctype.h>
  2375. X#include <time.h>
  2376. X
  2377. X
  2378. Xchar    *malloc();
  2379. X
  2380. Xint        monthdata[1000];    /* month data */
  2381. Xint        daydata[1000];        /* month data */
  2382. Xint        yeardata[1000];    /* month data */
  2383. Xchar        *msgdata[1000];    /* message pointers */
  2384. Xchar        msghold[40];
  2385. Xint        maxentries;
  2386. Xint        maxmsgs;
  2387. Xint        cmonth,cday,cyear;
  2388. Xint        argvindex;
  2389. X
  2390. X
  2391. X
  2392. X/*
  2393. X * Procedure:    main()
  2394. X *
  2395. X * Function:    prints out listing of appointments
  2396. X *
  2397. X * Discussion:
  2398. X *    Parses command line for optional month and year, initializes
  2399. X *    varialbes, calls required funtions.
  2400. X */
  2401. X
  2402. Xmain (argc,argv)
  2403. X
  2404. X    int        argc;
  2405. X    char    *argv[];
  2406. X{
  2407. X
  2408. X    int        month,day,year;
  2409. X    int        i;
  2410. X    int        tempmonth,tempyear;
  2411. X    int        atoi();
  2412. X    int        maxindex;
  2413. X    extern int    abort();
  2414. X
  2415. X    timeset();
  2416. X    year = cyear;
  2417. X    month = cmonth;
  2418. X    day = cday;
  2419. X
  2420. X    if (argc > 2) {
  2421. X    tempmonth = atoi(argv[1]);
  2422. X    tempyear = atoi(argv[2]);
  2423. X    if (tempmonth && tempyear){
  2424. X        month = tempmonth;
  2425. X        year = tempyear;
  2426. X        if (year < 100) year += 1900;
  2427. X        if (argc > 3) {
  2428. X        argvindex = 3;
  2429. X        maxindex = argc;
  2430. X        }
  2431. X        else {
  2432. X        argvindex = 0;
  2433. X        maxindex = 1;
  2434. X        }
  2435. X    }
  2436. X    else {
  2437. X        if (tempmonth || tempyear) {
  2438. X        printf("Syntax error:  Incorrect date arguments\n");
  2439. X        exit(1);
  2440. X        }
  2441. X        else {
  2442. X        argvindex = 1;
  2443. X        maxindex = argc;
  2444. X        }
  2445. X    }
  2446. X    }
  2447. X    else {
  2448. X        if (argc == 1) {
  2449. X        argvindex = 0;
  2450. X        maxindex = argc;
  2451. X    }
  2452. X    else {
  2453. X        argvindex = 1;
  2454. X        maxindex = argc;
  2455. X    }
  2456. X    }
  2457. X
  2458. X    
  2459. X    signal(2,abort);
  2460. X    signal(3,abort);
  2461. X
  2462. X    day = 1;
  2463. X    maxentries = 1000;
  2464. X    maxmsgs = 18;
  2465. X    msghold[0] = NULL;
  2466. X
  2467. X    printf("                            C A L E N D A R   L I S T\n");
  2468. X    while (argvindex < maxindex) {
  2469. X    loaddata(argv[argvindex]);
  2470. X    table(month,day,year,argv[argvindex]);
  2471. X    argvindex++;
  2472. X    }
  2473. X
  2474. X    printf("------------------------------------------------------------------------------\n");
  2475. X} /* main */
  2476. X
  2477. X
  2478. X/*
  2479. X * Procedure:    abort()
  2480. X *
  2481. X * Function:    error exit routine
  2482. X */
  2483. X
  2484. Xabort()
  2485. X
  2486. X{
  2487. X    exit(1);
  2488. X} /* abort */
  2489. X
  2490. X
  2491. X/*
  2492. X * Procedure:    table(month,day,year)
  2493. X *
  2494. X * Function:    outputs appointments in tabular format
  2495. X *
  2496. X * Parameters:
  2497. X *    p1    - int - month
  2498. X *    p2    - int - day
  2499. X *    p3    - int - year
  2500. X *      p3      - char * - file name
  2501. X *
  2502. X * Discussion:
  2503. X *    Searches data arrays for appointments in the specified
  2504. X *    month and year and outputs them in tabular form to standard out.
  2505. X */
  2506. X
  2507. Xtable(month,day,year,filename)
  2508. X
  2509. X    int        month,day,year;
  2510. X    char    *filename;
  2511. X
  2512. X{
  2513. X    int        i,j,k,d,dow,monthday,searchcnt,first;
  2514. X    int        getdow();
  2515. X
  2516. X    static char    *dayw[]= {
  2517. X    "Sat   ","Sun   ","Mon   ", "Tue   ",
  2518. X    "Wed    ", "Thu    ", "Fri    "
  2519. X    };
  2520. X
  2521. X    static char    *smon[]= {
  2522. X    "JANUARY   ", "FEBRUARY   ", "MARCH    ", "APRIL    ",
  2523. X    "MAY    ", "JUNE    ", "JULY    ", "AUGUST    ",
  2524. X    "SEPTEMBER    ", "OCTOBER    ", "NOVEMBER    ", "DECEMBER    "
  2525. X    };
  2526. X
  2527. X    printf("------------------------------------------------------------------------------\n");
  2528. X    if (argvindex) {
  2529. X    printf("|  %-10.10s%u                       %30.30s       |\n", smon[month-1], year,filename);
  2530. X    }
  2531. X    else {
  2532. X    printf("|  %-10.10s%u                                                            |\n", smon[month-1], year);
  2533. X    }
  2534. X    monthday = 0;
  2535. X    while (++monthday <= 31) {
  2536. X    searchcnt = 0;
  2537. X    first = 1;
  2538. X    while (searchcnt <= maxentries) {
  2539. X        if ((yeardata[searchcnt] == year) &&
  2540. X          (monthdata[searchcnt] == month) &&
  2541. X          (daydata[searchcnt] == monthday)) {
  2542. X        if (first) {
  2543. X            dow = getdow(month,monthday,year);
  2544. X            first = 0;
  2545. X            /* printf("|----------------------------------------------------------------------------|\n"); */
  2546. X             printf("|                                                                            |\n"); 
  2547. X            printf("| %-7.7s%2d  %-64.64s|\n",dayw[dow],monthday,msgdata[searchcnt]);
  2548. X        }
  2549. X        else {
  2550. X            printf("|            %-64.64s|\n",msgdata[searchcnt]);
  2551. X        }
  2552. X        }
  2553. X        searchcnt++;
  2554. X    }
  2555. X    }
  2556. X} /* table */
  2557. X
  2558. X
  2559. X/*
  2560. X * Procedure:    getdow(tmonth,tday,tyear)
  2561. X *
  2562. X * Function:    calculates day of week
  2563. X *
  2564. X * Parameters:
  2565. X *    p1    - int - month
  2566. X *    p2    - int - day
  2567. X *    p3    - int - year
  2568. X *
  2569. X * Return Values:
  2570. X *    interger value of day of week, sat=0, . . ., etc
  2571. X *
  2572. X * Discussion:
  2573. X *    calculates number of days from 1,1,1979 and determines dow
  2574. X */
  2575. X
  2576. Xgetdow(tmonth,tday,tyear)
  2577. X
  2578. X    int        tmonth,tday,tyear;
  2579. X{
  2580. X
  2581. X    static    int    mdays[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
  2582. X    int    month,day,year,mcnt;
  2583. X    long   days;
  2584. X    int    tdow;
  2585. X
  2586. X    month = 1;
  2587. X    day = 1;
  2588. X    year = 79;
  2589. X
  2590. X    if ((tmonth == month) && (tyear == year)) {
  2591. X    days = abs(day - tday);
  2592. X    }
  2593. X    else {
  2594. X        days = mdays[month] - day;
  2595. X        if (tyear == year) {
  2596. X            while (++month < tmonth) {
  2597. X            days += mdays[month];
  2598. X            if ((month == 2) && ((year % 4) == 0)) days++;
  2599. X        }
  2600. X        }
  2601. X        else {
  2602. X            while (++month < 13) {
  2603. X            days += mdays[month];
  2604. X                if ((month == 2) && ((year % 4) == 0)) days++;
  2605. X            }
  2606. X        while (++year < tyear) {
  2607. X            days += 365;
  2608. X            if ((year % 4) == 0 ) days ++;
  2609. X            }
  2610. X    
  2611. X        mcnt = 0;
  2612. X            while (++mcnt < tmonth) {
  2613. X            days += mdays[mcnt];
  2614. X            if ((mcnt == 2) && ((tyear % 4) == 0)) days++;
  2615. X        }
  2616. X        }
  2617. X        days += tday;
  2618. X    }
  2619. X
  2620. X    tdow = (days%7);
  2621. X
  2622. X    return(tdow);
  2623. X} /* get dow */
  2624. X
  2625. X
  2626. X/*
  2627. X * Procedure:    loaddata()
  2628. X *
  2629. X * Function:    loads appointment data from ~/.appointments file
  2630. X *
  2631. X * Return Values:
  2632. X *    various global arrays loaded with appointment data
  2633. X *
  2634. X */
  2635. X
  2636. Xloaddata(filename)
  2637. X
  2638. Xchar    *filename;
  2639. X
  2640. X{
  2641. X    char    basedata[80];
  2642. X    char    tmpbuf[80];
  2643. X    char    *getenv();
  2644. X    char    home[80];
  2645. X    FILE     *fptr;
  2646. X    int        i,j,k,l,field;
  2647. X
  2648. X    i = 0;
  2649. X    while (i < maxentries) {
  2650. X    daydata[i] = 0;
  2651. X    monthdata[i] = 0;
  2652. X    yeardata[i] = 0;
  2653. X    msgdata[i] = 0;
  2654. X    i++;
  2655. X    }
  2656. X
  2657. X    
  2658. X    if (argvindex == 0) {
  2659. X    strcpy(home,getenv("HOME"));
  2660. X    strcat(home,"/.appointments");
  2661. X    }
  2662. X    else {
  2663. X    strcpy(home,filename);
  2664. X    }
  2665. X    if ((fptr = fopen(home,"r")) != NULL) {
  2666. X    i = 0;
  2667. X    while((fgets(basedata,80,fptr) != NULL)) {
  2668. X
  2669. X        basedata[strlen(basedata)-1] = NULL;
  2670. X
  2671. X        j = 0;
  2672. X        k = 0;
  2673. X        field = 0;
  2674. X        while (basedata[j] != NULL ) {
  2675. X                 
  2676. X                if (basedata[j] != ',') {
  2677. X
  2678. X            tmpbuf[k++] = basedata[j];
  2679. X        }
  2680. X        else {
  2681. X            switch (field) {
  2682. X
  2683. X            case 0 : {
  2684. X                tmpbuf[k] = NULL;
  2685. X                monthdata[i] = atoi(tmpbuf);
  2686. X                k = 0;
  2687. X                break;
  2688. X            }
  2689. X            case 1 : {
  2690. X                tmpbuf[k] = NULL;
  2691. X                daydata[i] = atoi(tmpbuf);
  2692. X                k = 0;
  2693. X                break;
  2694. X            }
  2695. X            case 2 : {
  2696. X                tmpbuf[k] = NULL;
  2697. X                yeardata[i] = atoi(tmpbuf);
  2698. X                k = 0;
  2699. X                break;
  2700. X            }
  2701. X            case 3 : {
  2702. X                tmpbuf[k++] = ' ';
  2703. X                tmpbuf[k++] = ' ';
  2704. X                break;
  2705. X            }
  2706. X            }
  2707. X            field++;
  2708. X        }
  2709. X        j++;
  2710. X        }
  2711. X        tmpbuf[k] = '\0';
  2712. X        msgdata[i] = malloc(80);
  2713. X        strncpy(msgdata[i],tmpbuf,80);
  2714. X        msgdata[79] = NULL;
  2715. X
  2716. X        if (i >= maxentries) {
  2717. X        printf("Warning:  Over 1000 entries in %s file.  Data truncated.\n",filename);
  2718. X        break;
  2719. X        }
  2720. X        i++;
  2721. X    }
  2722. X    fclose(fptr);
  2723. X    }
  2724. X    else {
  2725. X    printf("Error:  Cannot open %s file.\n",filename);
  2726. X    }
  2727. X} /* loaddata */
  2728. X
  2729. X
  2730. X/*
  2731. X * Procedure:    timeset()
  2732. X *
  2733. X * Function:    Gets current time and date
  2734. X *
  2735. X * Return Values:
  2736. X *    loads time and date info into global variables
  2737. X *
  2738. X */
  2739. X
  2740. Xtimeset()
  2741. X
  2742. X{
  2743. X    struct    tm *localtime();
  2744. X
  2745. X    struct tm *tp;        /* time structure */
  2746. X    long    tloc;        /* number of seconds since 1970 */
  2747. X
  2748. X    time(&tloc);    /* fills tloc */
  2749. X
  2750. X    tp = localtime(&tloc);
  2751. X
  2752. X    cyear =    tp->tm_year;
  2753. X    cmonth =    tp->tm_mon + 1;
  2754. X    cday =    tp->tm_mday;
  2755. X
  2756. X    cyear += 1900;
  2757. X
  2758. X} /* timeset */
  2759. *-*-END-of-lcal.c-*-*
  2760. echo x - lcal.l
  2761. sed 's/^X//' >lcal.l <<'*-*-END-of-lcal.l-*-*'
  2762. X.TH LCAL 1 
  2763. X.SH NAME
  2764. Xlcal \- display current or selected month's appointments
  2765. X.SH SYNOPSIS
  2766. X.B lcal 
  2767. X[ month year ] [ filename(s) ]
  2768. X.sp
  2769. Xwhere
  2770. X.I month
  2771. Xis a numeric value between 1 and 12,
  2772. X.I year
  2773. Xis a numeric four digit value and
  2774. X.I filename(s)
  2775. Xare the data files to be searched.
  2776. X.SH DESCRIPTION
  2777. X.I Lcal
  2778. Xis a program which uses the data stored by "vcal" or "eappts" to
  2779. Xdisplay the user's appointments to standard out.
  2780. X.PP
  2781. XWhen an argument is present,
  2782. X.I lcal
  2783. Xwill display appointments for the requested month and year.
  2784. XThe default argument values are the current month and year.
  2785. XIf no filename is specified ~/.appointments will be searched.
  2786. XIf one or more filenames arguments are used those files will
  2787. Xbe searched.
  2788. X.SH AUTHOR
  2789. XMike Essex
  2790. X.SH FILES
  2791. Xlcal
  2792. X.br
  2793. X~/.appointments
  2794. X.br
  2795. X.SH "SEE ALSO"
  2796. Xvcal(1), appts(1), eappts(1), autocall(1), callme(1)
  2797. X.SH BUGS
  2798. XThere are year 2000 time bombs.
  2799. *-*-END-of-lcal.l-*-*
  2800. echo x - vcal.c
  2801. sed 's/^X//' >vcal.c <<'*-*-END-of-vcal.c-*-*'
  2802. X/*
  2803. X * Module:    vcal.c
  2804. X *
  2805. X * Purpose:    visual appointment calendar
  2806. X *
  2807. X * Author:    Mike Essex
  2808. X *
  2809. X * Date:    Sep. 16, 1986
  2810. X *
  2811. X * Includes:
  2812. X *    time.h, stdio.h, ctype.h, signal.h
  2813. X *
  2814. X * Discussion:
  2815. X *    displays a calendar to the screen for the current or optionally
  2816. X *    specified month.  User may move the cursor any day of the month
  2817. X *    and view or enter appointments for that date.
  2818. X * 
  2819. X *
  2820. X * Edit History
  2821. X * ==== =======
  2822. X *
  2823. X * Date      Who    What
  2824. X * ----      ---    ----------------------------------------------
  2825. X *11/25/86   me         added multiple data file capability
  2826. X *11/25/86   me         fixed array "home" from *home[80] to home[80]
  2827. X *11/25/86   me         fixed "space" and "area" to be global
  2828. X *11/26/86   me        changed help message routines
  2829. X * 2/06/86   me        changed calendar header from printing a default
  2830. X *            NULL for .appointments file to not printing
  2831. X *02/19/86   me        reworked terminal handler to make correct use
  2832. X *            of termcap(3) functions for greater terminal
  2833. X *            portability.  modified so that cursor comes to
  2834. X *            current day of month on startup.  Fixed minor
  2835. X *                      bugs and changed a few messages.
  2836. X *
  2837. X */
  2838. X
  2839. X#include <stdio.h>
  2840. X#include <signal.h>
  2841. X#include <ctype.h>
  2842. X#include <time.h>
  2843. X#include <sgtty.h>
  2844. X
  2845. X#define        LF    '\012'
  2846. X#define        BS    '\010'
  2847. X#define        ESC    '\033'
  2848. X
  2849. Xint        mon[] = {
  2850. X    0,
  2851. X    31, 29, 31, 30,
  2852. X    31, 30, 31, 31,
  2853. X    30, 31, 30, 31,
  2854. X};
  2855. X
  2856. Xint    tputc();        /* termcap dependent output */
  2857. Xchar    space[BUFSIZ];        /* used by area */
  2858. Xchar    *area = space;        /* termcap required variable */
  2859. Xchar    *BC;            /* backspace string pointer */
  2860. Xchar    *backstring = "\b";    /* backspace string */
  2861. Xchar    PC;            /* number pad characters */
  2862. Xchar    *UP;            /* cursor up string */
  2863. Xextern    short    ospeed;        /* output speed */
  2864. Xchar    *CM;            /* cursor motion */
  2865. Xchar    *CL;            /* clear screen */
  2866. Xchar    *TI;            /* begin cm */
  2867. Xchar    *TE;            /* end cm */
  2868. Xchar    *SO;            /* standout*/
  2869. Xchar    *SE;            /* end standout*/
  2870. Xchar    *tgoto();
  2871. Xchar    *malloc();
  2872. Xchar    tcolumns = 0;        /* terminal columns */
  2873. Xchar    tlines = 0;        /* terminal lines */
  2874. X
  2875. Xint        xposition[32];        /* calendar x axis position */
  2876. Xint        yposition[32];        /* calendar y axis position */
  2877. Xint        active[33];        /* highlight day array */
  2878. X
  2879. Xint        monthdata[1000];    /* month data */
  2880. Xint        daydata[1000];        /* month data */
  2881. Xint        yeardata[1000];    /* month data */
  2882. Xchar        *msgdata[1000];    /* message pointers */
  2883. Xchar        msghold[80];
  2884. Xint        dayindex[18];        /* index to day's msgs */
  2885. Xint        maxentries;
  2886. Xint        maxmsgs;
  2887. Xint        tmonth,tday,tyear;
  2888. X
  2889. Xint        maxchars;
  2890. Xint        notclear;
  2891. Xint        help1,help2;        /* help  message flags */
  2892. X
  2893. Xchar    dayw[] = {
  2894. X    "  S    M    T    W    T    F    S   "
  2895. X};
  2896. X
  2897. Xchar    *smon[]= {
  2898. X    "JANUARY   ", "FEBRUARY   ", "MARCH    ", "APRIL    ",
  2899. X    "MAY    ", "JUNE    ", "JULY    ", "AUGUST    ",
  2900. X    "SEPTEMBER    ", "OCTOBER    ", "NOVEMBER    ", "DECEMBER    ",
  2901. X};
  2902. X
  2903. X
  2904. X
  2905. X/*
  2906. X * Procedure:    main(argv[1],argv[2],argv[3])
  2907. X *
  2908. X * Function:    Front end for calendar program
  2909. X *
  2910. X * Parameters:
  2911. X *    p1    - character pointer - optional month
  2912. X *    p2    - character pointer - optional year
  2913. X *    p3      - character pointer - optional data file name
  2914. X *
  2915. X * Discussion:
  2916. X *    This module parses command line, intializes variables and calls
  2917. X *    init functions.  It then drops into a character interpreter
  2918. X *    loop, taking input from standard in.  Each input either changes
  2919. X *    cursor position or invokes a function.
  2920. X */
  2921. X
  2922. Xmain (argc,argv)
  2923. X
  2924. X    int        argc;
  2925. X    char    *argv[];
  2926. X{
  2927. X
  2928. X    int        month,day,year;
  2929. X    char    key;
  2930. X    char    *datafile;
  2931. X    extern int    abort();
  2932. X    int i;
  2933. X
  2934. X    datafile = NULL;
  2935. X    day = 1;
  2936. X    if (argc == 1) {
  2937. X    timeset();
  2938. X    month = tmonth;
  2939. X    day = tday;
  2940. X    year = tyear;
  2941. X    }
  2942. X    else {
  2943. X    if (argc == 3) {
  2944. X        month = atoi(argv[1]);
  2945. X        year = atoi(argv[2]);
  2946. X        if (year < 100) year += 1900;
  2947. X        if (!month || !year) {
  2948. X        printf("Syntax Error:  non-numeric argument\n");
  2949. X        abort(1);
  2950. X        }
  2951. X    }
  2952. X    else {
  2953. X        if (argc == 2) {
  2954. X        timeset();
  2955. X        month = tmonth;
  2956. X        day = tday;
  2957. X        year = tyear;
  2958. X        datafile = argv[1];
  2959. X        }
  2960. X        else {
  2961. X        if ( argc == 4) {
  2962. X            month = atoi(argv[1]);
  2963. X            year = atoi(argv[2]);
  2964. X            if (year < 100) year += 1900;
  2965. X            if (!month || !year) {
  2966. X            printf("Syntax Error:  non-numeric argument\n");
  2967. X            abort(1);
  2968. X            }
  2969. X            datafile = argv[3];
  2970. X        }
  2971. X        else {
  2972. X            printf("Syntax Error:  incorrect number of arguments\n");
  2973. X            abort(1);
  2974. X        }
  2975. X        }
  2976. X    }
  2977. X    }
  2978. X    signal(2,abort);
  2979. X    signal(3,abort);
  2980. X
  2981. X    system("stty cbreak -echo");
  2982. X
  2983. X    tinit();
  2984. X    tputs(TI,1,tputc);
  2985. X    maxchars = 38;
  2986. X    maxentries = 1000;
  2987. X    maxmsgs = 18;
  2988. X    msghold[0] = NULL;
  2989. X    help1 = 0;
  2990. X    help2 = 0;
  2991. X
  2992. X    loaddata(datafile);
  2993. X    cal(month,day,year,datafile);
  2994. X    movcur(day);
  2995. X
  2996. X    key = 'a';
  2997. X    while (key != LF) {
  2998. X
  2999. X    key = getchar();
  3000. X
  3001. X    switch (key) {
  3002. X
  3003. X            case 'H' :
  3004. X
  3005. X        helpcal();
  3006. X
  3007. X            break;
  3008. X
  3009. X        case 'p' :
  3010. X
  3011. X        if (--month < 1) {
  3012. X            month = 12;
  3013. X            year--;
  3014. X        }
  3015. X        day = 1;
  3016. X        notclear = 0;
  3017. X        cal(month,day,year,datafile);
  3018. X
  3019. X        break;
  3020. X
  3021. X        case 'n' :
  3022. X            
  3023. X        if (++month == 13) {
  3024. X            month = 1;
  3025. X            year++;
  3026. X        }
  3027. X        day = 1;
  3028. X        notclear = 0;
  3029. X        cal(month,day,year,datafile);
  3030. X
  3031. X        break;
  3032. X            
  3033. X        case 'h' :
  3034. X
  3035. X        if (--day <= 0) {
  3036. X            day = mon[month];
  3037. X        }
  3038. X        if (notclear) {
  3039. X            clearmsgs();
  3040. X        }
  3041. X
  3042. X        break;
  3043. X
  3044. X        case 'l' :
  3045. X
  3046. X        if (++day > mon[month]) {
  3047. X            day = 1;
  3048. X        }
  3049. X        if (notclear) {
  3050. X            clearmsgs();
  3051. X        }
  3052. X
  3053. X        break;
  3054. X
  3055. X        case 'j' :
  3056. X
  3057. X        if ((day += 7) > mon[month]) {
  3058. X            day = day % 7;
  3059. X            if (day == 0) {
  3060. X            day = 7;
  3061. X            }
  3062. X        }
  3063. X        if (notclear) {
  3064. X            clearmsgs();
  3065. X        }
  3066. X
  3067. X        break;
  3068. X
  3069. X        case 'k' :
  3070. X
  3071. X        if ((day -= 7) <= 0) {
  3072. X            day += 35;
  3073. X            if (day > mon[month]) {
  3074. X            day -= 7;
  3075. X            }
  3076. X        }
  3077. X        if (notclear) {
  3078. X            clearmsgs();
  3079. X        }
  3080. X
  3081. X        break;
  3082. X
  3083. X        case 'e' :
  3084. X
  3085. X        day = mon[month];
  3086. X        if (notclear) {
  3087. X            clearmsgs();
  3088. X        }
  3089. X
  3090. X        break;
  3091. X
  3092. X        case 'b' :
  3093. X
  3094. X        day = 1;
  3095. X        if (notclear) {
  3096. X            clearmsgs();
  3097. X        }
  3098. X
  3099. X        break;
  3100. X
  3101. X        case 'c' :
  3102. X
  3103. X        clearday(month,day,year);
  3104. X
  3105. X        break;
  3106. X
  3107. X        case ' ' :
  3108. X
  3109. X        notes(month,day,year);
  3110. X
  3111. X        break;
  3112. X
  3113. X        case 'm' :
  3114. X
  3115. X        modnotes(month,day,year);
  3116. X
  3117. X        break;
  3118. X
  3119. X
  3120. X    }
  3121. X    movcur(day);
  3122. X    }
  3123. X    closefile(datafile);
  3124. X    tputs(TE,1,tputc);
  3125. X    system("stty -cbreak echo");
  3126. X    if (help1 || help2) {
  3127. X    helpclr();
  3128. X    }
  3129. X    mov(1,24);
  3130. X} /* main */
  3131. X
  3132. X
  3133. X/*
  3134. X * Procedure:    <routine name>
  3135. X *
  3136. X * Function:    abort()
  3137. X *
  3138. X * Discussion:
  3139. X *    Reset tty parameters and exits with an error code.
  3140. X */
  3141. X
  3142. Xabort()
  3143. X
  3144. X{
  3145. X    system("stty -cbreak echo");
  3146. X    tputs(SE,1,tputc);
  3147. X    if (help1 || help2) {
  3148. X    helpclr();
  3149. X    }
  3150. X    mov(1,24);
  3151. X    tputs(TE,1,tputc);
  3152. X    exit(1);
  3153. X} /* abort */
  3154. X
  3155. X
  3156. X
  3157. X/*
  3158. X * Procedure:    cal(month,day,year,datafile)
  3159. X *
  3160. X * Function:    produces the visual calendar to the screen
  3161. X *
  3162. X * Parameters:
  3163. X *    p1    - int - month
  3164. X *    p2    - int - day
  3165. X *    p3    - int - year
  3166. X *    p4      - char * - datafile name
  3167. X *
  3168. X * Discussion:
  3169. X *    Calculates current months parameters, such as, starting
  3170. X *    day of week, number of days and days on which there are
  3171. X *    appointments.  This data is then used to draw a calendar
  3172. X *    to the screen.
  3173. X */
  3174. X
  3175. Xcal(month,day,year,datafile)
  3176. X
  3177. X    int        month,day,year;
  3178. X    char    *datafile;
  3179. X
  3180. X{
  3181. X    int        i,j,k,d;
  3182. X
  3183. X    tputs(CL,24,tputc);
  3184. X    if (datafile == NULL) {
  3185. X    printf("V I S U A L   C A L E N D A R\n");
  3186. X    }
  3187. X    else {
  3188. X    printf("V I S U A L   C A L E N D A R\t\t%s\n",datafile);
  3189. X    }
  3190. X    printf("-------------------------------------------------------------------------------\n");
  3191. X    printf("\t\t\t\t%s%u\n", smon[month-1], year);
  3192. X    printf("-------------------------------------------------------------------------------\n\n");
  3193. X    printf("%s\n\n", dayw);
  3194. X
  3195. X
  3196. X    d = jan1(year);
  3197. X    mon[2] = 29;
  3198. X    mon[9] = 30;
  3199. X
  3200. X
  3201. X    i = 1;
  3202. X    while (i <= 32) {
  3203. X    active[i++] = 0;
  3204. X    }
  3205. X
  3206. X    i = 0;
  3207. X    while (i < maxentries) {
  3208. X    if ((yeardata[i] == year) && (monthdata[i] == month) ) {
  3209. X        active[daydata[i]] = 1;
  3210. X    }
  3211. X    i++;
  3212. X    }
  3213. X
  3214. X    switch((jan1(year+1)+7-d)%7) {
  3215. X
  3216. X    /*
  3217. X     *    non-leap year
  3218. X     */
  3219. X    case 1:
  3220. X        mon[2] = 28;
  3221. X        break;
  3222. X
  3223. X    /*
  3224. X     *    1752
  3225. X     */
  3226. X    default:
  3227. X        mon[9] = 19;
  3228. X        break;
  3229. X
  3230. X    /*
  3231. X     *    leap year
  3232. X     */
  3233. X    case 2:
  3234. X        ;
  3235. X    }
  3236. X
  3237. X    /* calculate days from beginning of year */
  3238. X
  3239. X    for(i=1; i<month; i++) {
  3240. X    d += mon[i];
  3241. X    }
  3242. X
  3243. X    d %= 7;
  3244. X    i = 0;
  3245. X
  3246. X    /* inset to first day of week position */
  3247. X
  3248. X    while (i++ < (5*d)) {
  3249. X    printf(" ");
  3250. X    }
  3251. X
  3252. X    k = 0;
  3253. X    i = d;
  3254. X
  3255. X    for (j=1;j<=31;j++) {
  3256. X    xposition[j] = (i*5) + 2;
  3257. X    yposition[j] = (k*2) + 7;
  3258. X    if (++i == 7) {
  3259. X        i = 0;
  3260. X        k++;
  3261. X    }
  3262. X    }
  3263. X
  3264. X    for(i=1; i<=mon[month]; i++) {
  3265. X    if(i==3 && mon[month]==19) {
  3266. X        i += 11;
  3267. X        mon[month] += 11;
  3268. X    }
  3269. X    if (active[i]) {
  3270. X        if(i > 9) {
  3271. X        printf(" ");
  3272. X        tputs(SO,1,tputc);
  3273. X        printf("%d",i/10);
  3274. X        tputs(SE,1,tputc);
  3275. X        }
  3276. X        else {
  3277. X        printf(" ");
  3278. X        tputs(SO,1,tputc);
  3279. X        printf(" ");
  3280. X        tputs(SE,1,tputc);
  3281. X        }
  3282. X        tputs(SO,1,tputc);
  3283. X        printf("%d",i%10);
  3284. X        tputs(SE,1,tputc);
  3285. X        if (*SO == NULL) {
  3286. X        printf("* ");
  3287. X        }
  3288. X        else {
  3289. X        printf("  ");
  3290. X        }
  3291. X    }
  3292. X    else {
  3293. X        if(i > 9) {
  3294. X        printf(" %d",i/10);
  3295. X        }
  3296. X        else {
  3297. X        printf("  ");
  3298. X        }
  3299. X        printf("%d  ",i%10);
  3300. X    }
  3301. X
  3302. X    if(++d == 7) {
  3303. X        d = 0;
  3304. X        printf("  \n\n");
  3305. X    }
  3306. X    }
  3307. X    
  3308. X    helpclr();
  3309. X
  3310. X    mov(42,5);
  3311. X    printf ("TIME      MESSAGE");
  3312. X} /* cal */
  3313. X
  3314. X
  3315. X/*
  3316. X * Procedure:    jan1(year)
  3317. X *
  3318. X * Function:    calculates day of week of Jan 1 on specified year
  3319. X *
  3320. X * Parameters:
  3321. X *    p1    - int - year
  3322. X *
  3323. X * Return Values:
  3324. X *    integer representation day of the week
  3325. X */
  3326. X
  3327. Xjan1(year)
  3328. X
  3329. X    int        year;
  3330. X{
  3331. X
  3332. X    register y, d;
  3333. X/*
  3334. X *    normal gregorian calendar
  3335. X *    one extra day per four years
  3336. X */
  3337. X
  3338. X    y = year;
  3339. X    d = 4+y+(y+3)/4;
  3340. X
  3341. X/*
  3342. X *    julian calendar
  3343. X *    regular gregorian
  3344. X *    less three days per 400
  3345. X */
  3346. X
  3347. X    if(y > 1800) {
  3348. X    d -= (y-1701)/100;
  3349. X    d += (y-1601)/400;
  3350. X    }
  3351. X
  3352. X/*
  3353. X *    great calendar changeover instant
  3354. X */
  3355. X
  3356. X    if(y > 1752)
  3357. X    d += 3;
  3358. X
  3359. X    return(d%7);
  3360. X} /* jan1 */
  3361. X
  3362. X
  3363. X
  3364. X/*
  3365. X * Procedure:    movcur(day)
  3366. X *
  3367. X * Function:    moves the cursor to the specified day's position
  3368. X *
  3369. X * Parameters:
  3370. X *    p1    - int - day
  3371. X *
  3372. X * Discussion:
  3373. X *    uses termcap values to move the cursor to a matrix position
  3374. X *    stored in a global array
  3375. X */
  3376. X
  3377. Xmovcur(day)
  3378. X
  3379. X    int    day;
  3380. X{
  3381. X    tputs( tgoto( CM, xposition[day],yposition[day]), 1, tputc );
  3382. X} /* movcur */
  3383. X
  3384. X
  3385. X/*
  3386. X * Procedure:    setday(day)
  3387. X *
  3388. X * Function:    places day in calendar display with appointment
  3389. X *        days highlighted
  3390. X *
  3391. X * Parameters:
  3392. X *    p1    - int - day
  3393. X *
  3394. X * Discussion:
  3395. X *    Uses day arguement, termcap values and calendar position
  3396. X *    matrices to write a day to the screen with days with appointment
  3397. X *    days highlighted.
  3398. X */
  3399. X
  3400. Xsetday(day)
  3401. X
  3402. X    int        day;
  3403. X{
  3404. X    tputs( tgoto( CM, xposition[day]-1,yposition[day]), 1, tputc );
  3405. X    if (active[day]) {
  3406. X    if(day > 9) {
  3407. X        tputs(SO,1,tputc);
  3408. X        printf("%d",day/10);
  3409. X        tputs(SE,1,tputc);
  3410. X    }
  3411. X    else {
  3412. X        tputs(SO,1,tputc);
  3413. X        printf(" ");
  3414. X        tputs(SE,1,tputc);
  3415. X    }
  3416. X    tputs(SO,1,tputc);
  3417. X    printf("%d",day%10);
  3418. X    tputs(SE,1,tputc);
  3419. X    if (*SO == NULL) {
  3420. X        printf("*");
  3421. X    }
  3422. X    else {
  3423. X        printf(" ");
  3424. X    }
  3425. X    }
  3426. X    else {
  3427. X    if(day > 9) {
  3428. X        printf("%d",day/10);
  3429. X    }
  3430. X    else {
  3431. X        printf(" ");
  3432. X    }
  3433. X    printf("%d ",day%10);
  3434. X    }
  3435. X} /* setday */
  3436. X
  3437. X
  3438. X
  3439. X/*
  3440. X * Procedure:    tinit()
  3441. X *
  3442. X * Function:    gets termcap entries
  3443. X *
  3444. X * Return Values:
  3445. X *    loads global variables with termcap parameters
  3446. X *
  3447. X * Discussion:
  3448. X *    Initial various termcap variables so that they can later
  3449. X *    be used to move the cursor and highlight certain displays.
  3450. X */
  3451. X
  3452. Xtinit()    /* termcap initalization */
  3453. X
  3454. X{
  3455. X    struct    sgttyb speed;
  3456. X
  3457. X    char    term[BUFSIZ];        /* holds termcap entry */
  3458. X    char    name[16];        /* terminal name */
  3459. X    char    *np;            /* termcap name pointer */
  3460. X    char    *NADA = { "\0" };    /* null string */
  3461. X    char    *tgetstr();
  3462. X    char    *getenv();
  3463. X
  3464. X    if( (np = getenv( "TERM" )) != NULL ) {
  3465. X        strncpy( name, np, 16 );
  3466. X    }
  3467. X    else {
  3468. X        printf("TERM environment variable does not exist\n");
  3469. X        abort();
  3470. X    }
  3471. X
  3472. X    if( tgetent( term, name ) != 1 ) {
  3473. X        printf("Termcap for %s does not exist\n",name);
  3474. X        abort();
  3475. X    }
  3476. X
  3477. X    /* if a capability does not exist, point it to a null
  3478. X    *  string not NULL
  3479. X    */
  3480. X
  3481. X    gtty(stdout,&speed);
  3482. X    ospeed = speed.sg_ospeed;
  3483. X
  3484. X    tlines = tgetnum( "li" );
  3485. X    tcolumns = tgetnum( "co" );
  3486. X
  3487. X    if( (CM = tgetstr( "cm", &area )) == NULL) {
  3488. X    CM = NADA;    
  3489. X    printf("Error:  No termcap 'cm' entry for this terminal type\n");
  3490. X    abort();
  3491. X    }
  3492. X    if( (CL = tgetstr( "cl", &area )) == NULL)
  3493. X    CL = NADA;
  3494. X    if( (UP = tgetstr( "up", &area )) == NULL)
  3495. X    UP = NADA;
  3496. X    if( (SO = tgetstr( "so", &area )) == NULL)
  3497. X    SO = NADA;
  3498. X    if( (SE = tgetstr( "se", &area )) == NULL)
  3499. X    SE = NADA;
  3500. X    if( (TI = tgetstr( "ti", &area)) == NULL)
  3501. X    TI = NADA;
  3502. X    if( (TE = tgetstr( "te", &area)) == NULL)
  3503. X    TE = NADA;
  3504. X    if( tgetnum( "sg", &area)  > 0)  {
  3505. X    SO = NADA;
  3506. X    SE = NADA;
  3507. X    }
  3508. X    if ( (BC = tgetstr( "bc", &area)) ==  NULL) {
  3509. X    BC = backstring;
  3510. X    }
  3511. X
  3512. X} /* tinit */
  3513. X
  3514. X
  3515. X
  3516. X/*
  3517. X * Procedure:    loaddata(datafile)
  3518. X *
  3519. X * Function:    loads data file
  3520. X *
  3521. X * Return Values:
  3522. X *    Various global arrays loaded with appointment data
  3523. X *
  3524. X * Discussion:
  3525. X *    Opens user's data file and reads it in, placing
  3526. X *    the data in appropriate arrays.
  3527. X */
  3528. X
  3529. Xloaddata(datafile)
  3530. X
  3531. X    char    *datafile;
  3532. X{
  3533. X    char    basedata[80];
  3534. X    char    tmpbuf[80];
  3535. X    char    *getenv();
  3536. X    char    home[80];
  3537. X    FILE     *fptr;
  3538. X    int        i,j,k,l,field;
  3539. X
  3540. X    i = 0;
  3541. X    while (i < maxentries) {
  3542. X    daydata[i] = 0;
  3543. X    monthdata[i] = 0;
  3544. X    yeardata[i] = 0;
  3545. X    msgdata[i] = 0;
  3546. X    i++;
  3547. X    }
  3548. X
  3549. X    if (datafile == NULL) {
  3550. X    strcpy(home,getenv("HOME"));
  3551. X    strcat(home,"/.appointments");
  3552. X    }
  3553. X    else {
  3554. X    strcpy(home,datafile);
  3555. X    }
  3556. X    if ((fptr = fopen(home,"r")) != NULL) {
  3557. X    i = 0;
  3558. X    while((fgets(basedata,80,fptr) != NULL)) {
  3559. X
  3560. X        basedata[strlen(basedata)-1] = NULL;
  3561. X
  3562. X        j = 0;
  3563. X        k = 0;
  3564. X        field = 0;
  3565. X        while (basedata[j] != NULL ) {
  3566. X                 
  3567. X                if (basedata[j] != ',') {
  3568. X
  3569. X            tmpbuf[k++] = basedata[j];
  3570. X        }
  3571. X        else {
  3572. X            switch (field) {
  3573. X
  3574. X            case 0 : {
  3575. X                tmpbuf[k] = NULL;
  3576. X                monthdata[i] = atoi(tmpbuf);
  3577. X                k = 0;
  3578. X                break;
  3579. X            }
  3580. X            case 1 : {
  3581. X                tmpbuf[k] = NULL;
  3582. X                daydata[i] = atoi(tmpbuf);
  3583. X                k = 0;
  3584. X                break;
  3585. X            }
  3586. X            case 2 : {
  3587. X                tmpbuf[k] = NULL;
  3588. X                yeardata[i] = atoi(tmpbuf);
  3589. X                k = 0;
  3590. X                break;
  3591. X            }
  3592. X            case 3 : {
  3593. X                tmpbuf[k++] = ' ';
  3594. X                tmpbuf[k++] = ' ';
  3595. X                break;
  3596. X            }
  3597. X            }
  3598. X            field++;
  3599. X        }
  3600. X        j++;
  3601. X        }
  3602. X        tmpbuf[k] = NULL;
  3603. X        msgdata[i] = malloc(80);
  3604. X        strncpy(msgdata[i],tmpbuf,80);
  3605. X        msgdata[79] = NULL;
  3606. X
  3607. X        if (i >= maxentries) {
  3608. X        printf("Warning:  Over 1000 entries in data file.  Data truncated.\n");
  3609. X        break;
  3610. X        }
  3611. X        i++;
  3612. X    }
  3613. X    fclose(fptr);
  3614. X    }
  3615. X} /* loaddata */
  3616. X
  3617. X
  3618. X/*
  3619. X * Procedure:    closefile(datafile)
  3620. X *
  3621. X * Function:    writes appointment data to file
  3622. X *
  3623. X * Discussion:
  3624. X *    Opens the user's designated data file and writes the current
  3625. X *    data into it.
  3626. X */
  3627. X
  3628. Xclosefile(datafile)
  3629. X
  3630. Xchar    *datafile;
  3631. X{
  3632. X    FILE    *fptr;
  3633. X    char    tmpbuf[80];
  3634. X    int        i;
  3635. X    char    *getenv();
  3636. X    char    home[80];
  3637. X
  3638. X    if (datafile == NULL) {
  3639. X    strcpy(home,getenv("HOME"));
  3640. X    strcat(home,"/.appointments");
  3641. X    }
  3642. X    else {
  3643. X    strcpy(home,datafile);
  3644. X    }
  3645. X    if ((fptr = fopen(home,"w")) == NULL) {
  3646. X    printf("Error:  Cannot open %s file",datafile);
  3647. X    abort();
  3648. X    }    
  3649. X    i = 0;
  3650. X    while (i < maxentries) {
  3651. X    if (daydata[i]) {
  3652. X        strcpy(tmpbuf,msgdata[i]);
  3653. X        tmpbuf[4] = NULL;
  3654. X        fprintf(fptr,"%d,%d,%d,%4.4s,%s\n",monthdata[i],daydata[i],yeardata[i],tmpbuf,&tmpbuf[6]);
  3655. X    }
  3656. X    i++;
  3657. X    }
  3658. X    fclose(fptr);
  3659. X} /* closefile */
  3660. X
  3661. X
  3662. X
  3663. X
  3664. X/*
  3665. X * Procedure:    notes(month,day,year)
  3666. X *
  3667. X * Function:    displays the current day's appointments
  3668. X *
  3669. X * Parameters:
  3670. X *    p1    - int - month
  3671. X *    p2    - int - day
  3672. X *    p3    - int - year
  3673. X *
  3674. X * Discussion:
  3675. X *    Writes to notes section of screen notes for day to
  3676. X *    which the cursor was pointing.
  3677. X */
  3678. X
  3679. Xnotes(month,day,year)
  3680. X
  3681. X    int        month,day,year;
  3682. X{
  3683. X    int        i,j,k;
  3684. X
  3685. X    if (help1) {
  3686. X    helpclr();
  3687. X    help1 = 0;
  3688. X    }
  3689. X
  3690. X    i = 0;
  3691. X    while (i < 18) {
  3692. X    dayindex[i++] = 0;
  3693. X    }
  3694. X
  3695. X    mov(64,5);
  3696. X    printf("%2d/%2d/%2d",month,day,year);
  3697. X
  3698. X    i = 0;
  3699. X    j = 0;
  3700. X    k = 6;
  3701. X
  3702. X    while (i < maxentries) {
  3703. X    if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
  3704. X        dayindex[j++] = i;
  3705. X        notclear++;
  3706. X        mov(42,k++);
  3707. X        printf("%-32.32s",msgdata[i]);
  3708. X    }
  3709. X    if (j > maxmsgs) {
  3710. X        mov(42,24);
  3711. X        printf("* too many entries to print *");
  3712. X        break;
  3713. X    }
  3714. X    i++;
  3715. X    }
  3716. X    i = 0;
  3717. X    while (i < maxentries) {
  3718. X    if (daydata[i] == 0) {
  3719. X        dayindex[j++] = i;
  3720. X        if (j >= maxmsgs) {
  3721. X        break;
  3722. X        }
  3723. X    }
  3724. X    i++;
  3725. X    }
  3726. X} /* notes */
  3727. X
  3728. X
  3729. X
  3730. X/*
  3731. X * Procedure:    modnotes(month,day,year)
  3732. X *
  3733. X * Function:    add, delete and modify appointment list
  3734. X *
  3735. X * Parameters:
  3736. X *    p1    - int - month
  3737. X *    p2    - int - day
  3738. X *    p3    - int - year
  3739. X *
  3740. X * Return Values:
  3741. X *    changes data in global message and date arrays
  3742. X *
  3743. X * Discussion:
  3744. X *    Allows the user to add, delete and modify a specified day's
  3745. X *    appointment list.  Routine contains a small character
  3746. X *    interpreter which moves the cursor through the notes list
  3747. X *    and selects routines to modify the list.
  3748. X */
  3749. X
  3750. Xmodnotes (month,day,year)
  3751. X
  3752. X    int        month,day,year;
  3753. X{
  3754. X
  3755. X    char    key,c;
  3756. X    int        xcoord,ycoord;
  3757. X    int        i,cnt,total;
  3758. X    char    tmpmsg[39];
  3759. X
  3760. X    notes(month,day,year);
  3761. X    xcoord = 42;
  3762. X    ycoord = 6;
  3763. X    i = 0;
  3764. X    mov(xcoord,ycoord);
  3765. X    key = 'a';
  3766. X
  3767. X    while (key != LF) {
  3768. X
  3769. X    key = getchar();
  3770. X
  3771. X    switch (key) {
  3772. X
  3773. X            case 'H' :
  3774. X
  3775. X        helpnotes();
  3776. X
  3777. X            break;
  3778. X
  3779. X        case 'j' :
  3780. X        i++;
  3781. X        if (++ycoord > 23) {
  3782. X            ycoord = 6;
  3783. X            i = 0;
  3784. X        }
  3785. X        break;
  3786. X
  3787. X        case 'k' :
  3788. X        i--;
  3789. X        if (--ycoord < 6) {
  3790. X            ycoord = 23;
  3791. X            i = 17;
  3792. X        }
  3793. X        break;
  3794. X
  3795. X        case 'd' :
  3796. X
  3797. X        tputs(SO,1,tputc);
  3798. X        printf("                                      ");
  3799. X        tputs(SE,1,tputc);
  3800. X        mov (xcoord,ycoord);
  3801. X        monthdata[dayindex[i]] = 0;
  3802. X        daydata[dayindex[i]] = 0;
  3803. X        yeardata[dayindex[i]] = 0;
  3804. X        strcpy(msghold,msgdata[dayindex[i]]);
  3805. X        if (msgdata[dayindex[i]]) {
  3806. X            free(msgdata[dayindex[i]]);
  3807. X            msgdata[dayindex[i]] = 0;
  3808. X        }
  3809. X        break;
  3810. X
  3811. X            case 'y' :
  3812. X
  3813. X        strcpy(msghold,msgdata[dayindex[i]]);
  3814. X
  3815. X        break;
  3816. X
  3817. X            case 'p' :
  3818. X
  3819. X            if (msgdata[dayindex[i]] == 0) {
  3820. X            msgdata[dayindex[i]] = malloc(80);
  3821. X            }
  3822. X            strncpy(msgdata[dayindex[i]],msghold,80);
  3823. X            yeardata[dayindex[i]] = year;
  3824. X            daydata[dayindex[i]] = day;
  3825. X            monthdata[dayindex[i]] = month;
  3826. X            printf("%s",msgdata[dayindex[i]]);
  3827. X
  3828. X        break;
  3829. X
  3830. X        case 'i' :
  3831. X
  3832. X        tputs(SO,1,tputc);
  3833. X        printf("                                      ");
  3834. X
  3835. X        mov (xcoord,ycoord);
  3836. X
  3837. X        c = '0';
  3838. X        cnt = 0;
  3839. X        while (c != ESC) {
  3840. X            c = getchar();
  3841. X            if (c != ESC ) {
  3842. X            if (c == BS) {
  3843. X                if (cnt > 0) {
  3844. X                cnt--;
  3845. X                if (cnt == 5) {
  3846. X                    cnt = 3;
  3847. X                    mov(46,ycoord);
  3848. X                }
  3849. X                printf("%s %s",BC,BC);
  3850. X                }
  3851. X            }
  3852. X            else {
  3853. X                if (c != LF) {
  3854. X                if ( cnt < maxchars) {
  3855. X                    tmpmsg[cnt] = c;
  3856. X                    cnt++;
  3857. X                    printf("%c",c);
  3858. X                }
  3859. X                if (cnt == 4) {
  3860. X                    tmpmsg[4] = ' ';
  3861. X                    tmpmsg[5] = ' ';
  3862. X                    cnt = 6;
  3863. X                    mov(48,ycoord);
  3864. X                }
  3865. X                }
  3866. X                else {
  3867. X                c = ESC;
  3868. X                }
  3869. X            }
  3870. X            }
  3871. X        }
  3872. X        tputs(SE,1,tputc);
  3873. X        if (cnt) {
  3874. X            tmpmsg[cnt] = NULL;
  3875. X            if (msgdata[dayindex[i]] == 0) {
  3876. X            msgdata[dayindex[i]] = malloc(80);
  3877. X            }
  3878. X            strncpy(msgdata[dayindex[i]],tmpmsg,80);
  3879. X            monthdata[dayindex[i]] = month;
  3880. X            daydata[dayindex[i]] = day;
  3881. X            yeardata[dayindex[i]] = year;
  3882. X        }
  3883. X        else {
  3884. X            monthdata[dayindex[i]] = 0;
  3885. X            daydata[dayindex[i]] = 0;
  3886. X            yeardata[dayindex[i]] = 0;
  3887. X            if (msgdata[dayindex[i]]) {
  3888. X            free(msgdata[dayindex[i]]);
  3889. X            msgdata[dayindex[i]] = 0;
  3890. X            }
  3891. X        }
  3892. X
  3893. X        break;
  3894. X
  3895. X        default :;
  3896. X    }
  3897. X    mov (xcoord,ycoord);
  3898. X    }
  3899. X
  3900. X    active[day] = 0;
  3901. X    i = 0;
  3902. X    while (i < maxentries) {
  3903. X    if ((yeardata[i] == year) && (monthdata[i] == month)) {
  3904. X        notclear = 18;
  3905. X        active[daydata[i]] = 1;
  3906. X    }
  3907. X    i++;
  3908. X    }
  3909. X
  3910. X    notclear = 18;
  3911. X    clearmsgs();
  3912. X    if (active[day]) {
  3913. X    notes(month,day,year);
  3914. X    }
  3915. X    setday(day);
  3916. X    if (help2) {
  3917. X    helpclr();
  3918. X    help2 = 0;
  3919. X    }
  3920. X} /* modnotes */
  3921. X
  3922. X
  3923. X/*
  3924. X * Procedure:    tputc(character)
  3925. X *
  3926. X * Function:    moves cursor on screen
  3927. X *
  3928. X * Parameters:
  3929. X *    p1    - int - character
  3930. X *
  3931. X * Discussion:
  3932. X *    Outputs a character to crt.  Used as an argument to tputs().
  3933. X */
  3934. X
  3935. Xtputc(c)
  3936. X    int c;
  3937. X{
  3938. X    putchar(c);
  3939. X}
  3940. X
  3941. X
  3942. X/*
  3943. X * Procedure:    mov(column,row)
  3944. X *
  3945. X * Function:    moves cursor on screen
  3946. X *
  3947. X * Parameters:
  3948. X *    p1    - int - crt column
  3949. X *    p2    - int - crt row
  3950. X *
  3951. X * Discussion:
  3952. X *    Moves the cursor to specified column and row on screen using
  3953. X *    termcap data.
  3954. X */
  3955. X
  3956. Xmov(col, row)
  3957. X
  3958. Xint    col,row;
  3959. X
  3960. X{
  3961. X    tputs( tgoto( CM, (col - 1),(row - 1)), 1, tputc );
  3962. X} /* move */
  3963. X
  3964. X
  3965. X/*
  3966. X * Procedure:    clearday(month,day,year)
  3967. X *
  3968. X * Function:    deletes specified day's appointments
  3969. X *
  3970. X * Parameters:
  3971. X *    p1    - int - month
  3972. X *    p2    - int - day
  3973. X *    p2    - int - year
  3974. X *
  3975. X * Return Values:
  3976. X *    changes various global arrays
  3977. X *
  3978. X * Discussion:
  3979. X *    Removes appointment entries for the specified day from
  3980. X *    message and date tables and from the crt
  3981. X */
  3982. X
  3983. Xclearday (month,day,year)
  3984. X
  3985. X    int        month,day,year;
  3986. X{
  3987. X    int        i;
  3988. X
  3989. X    i = 0;
  3990. X    while (i < maxentries) {
  3991. X    if ((yeardata[i] == year) && (monthdata[i] == month) && (daydata[i] == day)) {
  3992. X        active[day] = 0;
  3993. X        monthdata[i] = 0;
  3994. X        daydata[i] = 0;
  3995. X        yeardata[i] = 0;
  3996. X        if (msgdata[i])  {
  3997. X        free(msgdata[i]);
  3998. X        msgdata[i] = 0;
  3999. X        }
  4000. X    }
  4001. X    i++;
  4002. X    }
  4003. X    clearmsgs();
  4004. X    setday(day);
  4005. X} /* clearday */
  4006. X
  4007. X
  4008. X/*
  4009. X * Procedure:    clearmsgs()
  4010. X *
  4011. X * Function:    clears the notes section of the crt
  4012. X */
  4013. X
  4014. Xclearmsgs()
  4015. X
  4016. X{
  4017. X    int        i;
  4018. X
  4019. X    mov(64,5);
  4020. X    printf("          ");
  4021. X
  4022. X    if (notclear > maxmsgs) notclear = maxmsgs;
  4023. X
  4024. X    i = 6;
  4025. X    while (i < (notclear+6)) {
  4026. X    mov(42,i++);
  4027. X    printf("                                      ");
  4028. X    }
  4029. X    mov(42,24);
  4030. X    printf("                                   ");
  4031. X    notclear = 0;
  4032. X} /* clearmsgs */
  4033. X
  4034. X
  4035. X/*
  4036. X * Procedure:    helpcal()
  4037. X *
  4038. X * Function:    displays calendar help messages to crt
  4039. X */
  4040. X
  4041. Xhelpcal()
  4042. X
  4043. X{
  4044. X    mov(1,19);
  4045. X    printf("j/k/h/l:  cursor down/up/left/right     \n");
  4046. X    printf("b:  first day         e: last day       \n");
  4047. X    printf("space: display notes  m: modify notes   \n");
  4048. X    printf("c: clear notes        CR: exit program  \n");
  4049. X    printf("p: previous month     n: next month     \n");
  4050. X    printf("BRK: exit w/o changes                   ");
  4051. X    help1++;
  4052. X} /* helpcal */
  4053. X
  4054. X
  4055. X/*
  4056. X * Procedure:    helpnotes()
  4057. X *
  4058. X * Function:    displays notes help messages to crt
  4059. X */
  4060. X
  4061. Xhelpnotes() 
  4062. X
  4063. X{
  4064. X    mov(1,19);
  4065. X    printf("j/k:  cursor down/up                    \n");
  4066. X    printf("i: enter insert      ESC/CR: exit insert\n");
  4067. X    printf("d: delete entry      CR: exit notes     \n");
  4068. X    printf("y/p: yank/put a line                    \n");
  4069. X    printf("                                        \n");
  4070. X    printf("                                        ");
  4071. X    help2++;
  4072. X} /* helpnotes */
  4073. X
  4074. X
  4075. X/*
  4076. X * Procedure:    helpclr()
  4077. X *
  4078. X * Function:    clears notes area of screen
  4079. X */
  4080. X
  4081. Xhelpclr ()
  4082. X{
  4083. X    mov(1,19);
  4084. X    printf("                                        \n");
  4085. X    printf("                                        \n");
  4086. X    printf("                                        \n");
  4087. X    printf("                                        \n");
  4088. X    printf("    Type 'H' for help                   \n");
  4089. X    printf("                                        ");
  4090. X} /* helpclr */
  4091. X
  4092. X
  4093. X/*
  4094. X * Procedure:    timeset()
  4095. X *
  4096. X * Function:    sets current month, day and year variables
  4097. X *
  4098. X * Return Values:
  4099. X *    tday, tmonth and tyear variables set to current date
  4100. X */
  4101. X
  4102. Xtimeset()
  4103. X
  4104. X{
  4105. X    struct    tm *localtime();
  4106. X
  4107. X    struct tm *tp;        /* time structure */
  4108. X    long    tloc;        /* number of seconds since 1970 */
  4109. X
  4110. X    time(&tloc);    /* fills tloc */
  4111. X
  4112. X    tp = localtime(&tloc);
  4113. X
  4114. X    tyear =    tp->tm_year;
  4115. X    tmonth =    tp->tm_mon + 1;
  4116. X    tday =    tp->tm_mday;
  4117. X
  4118. X    tyear += 1900;
  4119. X
  4120. X} /* timeset */
  4121. *-*-END-of-vcal.c-*-*
  4122. echo x - vcal.l
  4123. sed 's/^X//' >vcal.l <<'*-*-END-of-vcal.l-*-*'
  4124. X.TH VCAL 1 
  4125. X.SH NAME
  4126. Xvcal \- visual calendar and notes program
  4127. X.SH SYNOPSIS
  4128. X.B vcal 
  4129. X[ month year ] [ filename ]
  4130. X.sp
  4131. Xwhere
  4132. X.I month
  4133. Xis a numeric value between 1 and 12,
  4134. X.I year
  4135. Xis a numeric four digit value and
  4136. X.I filename
  4137. Xis the data file to be accessed.
  4138. X.SH DESCRIPTION
  4139. X.I Vcal 
  4140. Xis a visual calendar program which allows the user to enter notes
  4141. Xand appointments for each day of the month.  It can be used to
  4142. Xreplace the "paper" desk or wall calendar with an electronic one
  4143. Xwhich can be accessed from any terminal or modem connected to the
  4144. Xcomputer system.
  4145. X.PP
  4146. XWhen a date argument is present,
  4147. X.I vcal
  4148. Xwill display the requested month and year.  The default argument values
  4149. Xare the current month and year.  When a filename argument is used
  4150. X.I vcal
  4151. Xwill uses that file instead of the default ~/.appointments file.
  4152. XIf ~/.appointments is not used the filename of the current file
  4153. Xwill appear at the top of the
  4154. X.I vcal
  4155. Xcalendar.
  4156. X.SH OPERATION
  4157. X.I Vcal
  4158. Xis entered from UNIX by typing the
  4159. Xcommand followed by an optional month and year value.  A calendar
  4160. Xwill be displayed on the screen with the cursor located on the first
  4161. Xday of the month.  The cursor may be moved to different days
  4162. Xin the following manner.
  4163. X.br
  4164. X.sp
  4165. X.nf
  4166. Xkey             function
  4167. X---             --------
  4168. Xj               move cursor down
  4169. Xk               move cursor up
  4170. Xl               move cursor to the next day
  4171. Xh               move cursor to the previous day
  4172. Xb               move cursor to the beginning of the month
  4173. Xe               move cursor to the end of the month
  4174. X.sp
  4175. X.fi
  4176. X.PP
  4177. XPrevious and following months may also be accessed.
  4178. X.br
  4179. X.sp
  4180. X.nf
  4181. Xkey             function
  4182. X---             --------
  4183. Xp               previous month
  4184. Xn               next month
  4185. X.sp
  4186. X.fi
  4187. X.PP
  4188. XUp to eighteen appointments may be entered on each day of the month.
  4189. XThese may be displayed, modified or cleared in with the following keys.
  4190. XThey will operate on the day selected by the current cursor position.
  4191. X.br
  4192. X.sp 4
  4193. X.nf
  4194. Xkey             function
  4195. X---             --------
  4196. Xspace           display appointments for the selected day
  4197. Xm               enter or modify appointments
  4198. Xc               clear all appointments for the selected day
  4199. X.sp
  4200. X.fi
  4201. X.PP
  4202. XWhen the 'm' is pressed
  4203. X.I vcal
  4204. Xenters notes mode.  While in this mode notes may be added, modified,
  4205. Xdeleted, yanked or put.
  4206. X.br
  4207. X.sp
  4208. X.nf
  4209. Xkey             function
  4210. X---             --------
  4211. Xj               move cursor down
  4212. Xk               move cursor up
  4213. Xi               begin data insertion
  4214. XESC/CR          end data insertion (only while in insert)
  4215. Xd               delete the selected line
  4216. Xy               hold the current line
  4217. Xp               insert the held message
  4218. XCR              exit notes mode and return to the calendar
  4219. X.sp
  4220. X.fi
  4221. XData must begin with the appointment time in 24 hour format
  4222. X(no ':' should be used).  Entering new data will erase the current
  4223. Xmessage on that line.  A held line will be available to insert until
  4224. Xit is changed or the user exits
  4225. X.I vcal.
  4226. XA line which is deleted using the 'd' key will be placed in the hold
  4227. Xbuffer.
  4228. X.PP
  4229. XWhen the cursor is on the calendar a carriage return will cause the
  4230. Xthe appointment data to be saved and
  4231. X.I vcal
  4232. Xto exit.  Break or delete will cause
  4233. X.I vcal
  4234. Xto exit without updating the ~/.appointments file.
  4235. X.PP
  4236. XA 'H' will display help messages.  A calendar help message
  4237. Xwill be printed when
  4238. Xthe cursor is on calendar days.  A notes help message
  4239. Xis printed when the cursor is in the notes area.
  4240. X.PP
  4241. XFive companion programs are available to use with the
  4242. X.I vcal
  4243. Xprogram.  These are:
  4244. X.br
  4245. X.sp
  4246. X.nf
  4247. Xappts           display current or selected days appointments
  4248. Xeappts          enter appointments from the UNIX command line
  4249. Xautocall        set appointment reminders for the current day
  4250. Xlcal            displays month's appointments in tabular form
  4251. Xcallme          sets appointment reminders
  4252. X.fi
  4253. X.sp
  4254. XFor further information on these, reference the appropriate "man"
  4255. Xentries.
  4256. X.SH AUTHOR
  4257. XMike Essex
  4258. X.SH FILES
  4259. Xvcal
  4260. X.br
  4261. X/etc/termcap
  4262. X.br
  4263. X~/.appointments
  4264. X.br
  4265. X.SH "SEE ALSO"
  4266. Xappts(1), eappts(1), autocall(1), lcal(1), callme(1)
  4267. X.SH BUGS
  4268. X.I Vcal
  4269. Xmay not work with extremely brain damaged terminals.  There must be
  4270. Xa 'CM' entry in the termcap for 
  4271. X.I vcal
  4272. Xto draw the screen.  There are year 2000 time bombs.
  4273. X.br
  4274. *-*-END-of-vcal.l-*-*
  4275. exit
  4276.  
  4277.  
  4278.