home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / x / volume13 / xcal / part02 / scott_brim / xcshow.c < prev   
C/C++ Source or Header  |  1991-05-12  |  7KB  |  314 lines

  1. /*
  2.  * Announce xcal appointment entries.  Typical use is to announce a few 
  3.  * days' worth.  Also possible to dump every entry in "calendar" format.
  4.  *
  5.  *    Options: <date> - date to start at - mm/dd[/yy[yy]]
  6.  *         -d <RootDirectory> - of diary (default ~/Calendar)
  7.  *         -n <n> - where <n> is number of days to display
  8.  *         -c    - dump everything in "calendar" format;
  9.  *                 ignores <date> and -n.
  10.  */
  11.  
  12.  
  13. #include <stdio.h>
  14. #include <time.h>
  15. #include <utmp.h>
  16. #include <pwd.h>
  17. #include <dirent.h>
  18. #include <errno.h>
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21.  
  22. #define FALSE 0
  23. #define TRUE  1
  24.  
  25. void usage();
  26.  
  27. struct tm *tm;            /* hold times    */
  28. char rootdir[256];        /* build directory name here    */
  29. FILE *fd;            /* read file descriptor    */
  30. char filename[256];        /* to build filename in    */
  31. char *months[] = {
  32.     "Jan", "Feb", "Mar", "Apr",
  33.     "May", "Jun", "Jul", "Aug",
  34.     "Sep", "Oct", "Nov", "Dec"
  35.     };
  36. int days_in_months[] = { 
  37.     31, 28, 31, 30,
  38.     31, 30, 31, 31,
  39.     30, 31, 30, 31,
  40. };
  41.  
  42.  
  43. main(argc, argv)
  44. unsigned int argc;
  45. char **argv;
  46. {
  47.     int ndays;            /* number of days to announce    */
  48.     char c, *s;            /* reading and writing    */
  49.     char *dirname;        /* root directory name    */
  50.     struct passwd *pwd;
  51.     long ti;
  52.     int cdump = 0;        /* dump into calendar?    */
  53.     int i;
  54.  
  55.  
  56.     /* defaults    */
  57.     ti = time(0);        /* default to today    */
  58.     tm = localtime(&ti);
  59.     tm->tm_year += 1900;
  60.  
  61.     ndays = 1;            /* and to printing just one day    */
  62.  
  63.     if ((pwd = getpwuid(getuid())) == NULL) {
  64.     fprintf(stderr, "Who are you?\n");
  65.     exit(42);
  66.     };                         
  67.     strcpy(rootdir, pwd->pw_dir);    /* default to home directory    */
  68.     endpwent();
  69.     strcat(rootdir, "/Calendar");
  70.     dirname = rootdir;
  71.  
  72.  
  73.     /* check options    */
  74.     argc--, argv++;
  75.     while (argc > 0) {
  76.  
  77.     if (isdigit(argv[0][0])) {
  78.         if ((sscanf(argv[0], "%d/%d/%d", &tm->tm_mon,
  79.             &tm->tm_mday, &tm->tm_year)) < 2) { 
  80.         usage();
  81.         exit(1);
  82.         }
  83.         else {
  84.         tm->tm_mon--;    /* internal month # is 0-11    */
  85.         if (valid_date() != 0) {     /* user-supplied date    */
  86.                          /* must make sense    */
  87.             usage();
  88.             exit(2);
  89.         }
  90.         }
  91.  
  92.     }            /* end if first character is digit    */
  93.     else if (argv[0][0] == '-') {
  94.         switch(argv[0][1]) {
  95.         case 'd':        /* dirname    */
  96.         if (--argc <=0) {
  97.             usage();    /* nothing there    */
  98.             exit(3);
  99.         }
  100.         dirname = (++argv)[0];
  101.         break;
  102.         case 'n':        /* number of days    */
  103.         if (--argc <= 0) {
  104.             usage();    /* nothing there    */
  105.             exit(4);
  106.         }
  107.         if ((sscanf((++argv)[0], "%d", &ndays)) != 1) {
  108.             usage();    /* nothing there    */
  109.             exit(5);
  110.         }
  111.         break;
  112.         case 'c':
  113.         cdump = 1;
  114.         break;
  115.         default:
  116.         usage();
  117.         exit(6);
  118.         }
  119.     }
  120.     argc--, argv++;
  121.     }
  122.  
  123.     if (cdump) {        /* a dump?    */
  124.     return(dumpit(dirname));    /* go do so    */
  125.     }
  126.  
  127.     while (ndays--) {    /* otherwise loop, for each day requested    */
  128.  
  129.     valid_date();    /* Make current m, d, y make sense    */
  130.  
  131.     /* build filename -- e.g. "/mu/swb/Calendar/xy1990/xc1Oct1990"    */
  132.     sprintf(filename, "%s/xy%04d/xc%d%s%d",
  133.         dirname, tm->tm_year, tm->tm_mday,
  134.         months[tm->tm_mon], tm->tm_year); 
  135.  
  136.     /* Read from file, if it exists, and print.    */
  137.     if (fd = fopen(filename, "r")) {
  138.         fprintf(stdout, "%02d %s %d:\n------------\n",
  139.             tm->tm_mday, months[tm->tm_mon], tm->tm_year);
  140.         while ((c = getc(fd)) != EOF) putc(c, stdout);
  141.         fclose(fd);
  142.         fprintf(stdout, "\n");
  143.     }
  144.  
  145.     tm->tm_mday++;        /* do the next day    */
  146.     }
  147.     exit(0);
  148. }
  149.  
  150. /*
  151.  * valid_date takes the (external) date and makes it reasonable.  First
  152.  * it increments the month until the day given is within a month (as
  153.  * opposed to, say, 3/47/91).  Then it increments the year until the
  154.  * month is valid.  Right now it doesn't know anything about leap
  155.  * years. 
  156.  */
  157.  
  158. valid_date()
  159. {
  160.     int rc;
  161.  
  162.     rc = 0;
  163.     days_in_months[1] = 28;    /* default */
  164.     if (leap_year(tm->tm_year)) days_in_months[1] = 29;
  165.  
  166.     while (tm->tm_mday > days_in_months[tm->tm_mon]) {
  167.     tm->tm_mday -= days_in_months[tm->tm_mon];
  168.     tm->tm_mon++;
  169.     rc++;
  170.     }
  171.  
  172.     while (tm->tm_mon >= 12) {    /* month should be 0-11    */
  173.     tm->tm_mon -= 12;
  174.     tm->tm_year++;
  175.     rc++;
  176.     }
  177.  
  178.     return(rc);
  179. }
  180.  
  181. /*
  182.  * leap year?
  183.  */
  184. int leap_year(year)
  185. int year;
  186. {
  187.  
  188.     if (year%4000 == 0) return FALSE;
  189.     else if (year%400 == 0) return TRUE;
  190.     else if (year%100 == 0) return FALSE;
  191.     else if (year%4 == 0) return TRUE;
  192.     else return FALSE;
  193.  
  194. }
  195.  
  196.  
  197.  
  198. /*
  199.  * explain usage
  200.  */
  201. void
  202. usage()
  203. {
  204.     fprintf(stderr, "Usage: [date] [-d directory] [-n ndays] [-c]\n");
  205.     fprintf(stderr, "         -c dumps all entries in calendar(1) format.\n");
  206. }
  207.  
  208. /*
  209.  * dumpit dumps every single xcal entry pre-ambled with monthname,
  210.  * day, and year.
  211.  */
  212. dumpit(dirname)
  213.     char *dirname;
  214. {
  215.     DIR    *Cdirp, *ydirp;
  216.     struct dirent    *Centp, *yentp;
  217.     struct stat    statbuf;
  218.     char    *Cpathend, *ypathend;    /* loc for fname in filepath    */
  219.     char    *year;        /* ascii year            */
  220.     char    prebuf[14];    /* "calendar" preamble space    */
  221.     char    inbuf[1024];
  222.     int i;
  223.  
  224.     if ((Cdirp = opendir(dirname)) == NULL) {    /* top xcal dir    */    
  225.     perror(dirname);
  226.     return(errno);
  227.     }
  228.  
  229.     strcpy(filename, dirname);    /* initialize file path    */
  230.     strcat(filename, "/");
  231.     Cpathend = filename + strlen(filename);    /* put year dir here    */
  232.     
  233.  
  234.     /* for each year directory    */
  235.     while ((Centp = readdir(Cdirp)) != NULL) {    /* foreach year dir    */
  236.     
  237.     if (Centp->d_name[0] == '.') continue;    /* no ., ..    */    
  238.  
  239.     /* check each year directory    */
  240.     strcpy(Cpathend, Centp->d_name);    /* build filename    */
  241.     if ((i = stat(filename, &statbuf)) != 0) {
  242.         perror(filename);
  243.         return(errno);
  244.     }
  245.     if (!S_ISDIR(statbuf.st_mode)) {
  246. /*        fprintf(stderr, "%s not a directory, ignoring ... \n",    */
  247. /*            filename);                        */
  248.         continue;
  249.     }
  250.  
  251.     if ((ydirp = opendir(filename)) == NULL) {
  252.         perror(filename);
  253.         return(errno);
  254.     }
  255.     strcat(filename, "/");    /* path to open data files        */
  256.     year = Centp->d_name + 2;    /* use year in preamble        */
  257.     ypathend = filename + strlen(filename);    /* where to put fnames    */
  258.  
  259.  
  260.     /* for each day file in year dir    */
  261.     while ((yentp = readdir(ydirp)) != NULL) {
  262.     
  263.         if (yentp->d_name[0] == '.') continue;
  264.         strcpy(ypathend, yentp->d_name);
  265.         if ((i = stat(filename, &statbuf)) != 0) {
  266.         perror(filename);
  267.         return(errno);
  268.         }
  269.         if (!S_ISREG(statbuf.st_mode)) {
  270. /*        fprintf(stderr,                        */
  271. /*            "%s not a regular file, ignoring ... \n",    */
  272. /*               filename);                    */
  273.         continue;
  274.         }
  275.  
  276.         /* build what to dump in front of info    */
  277.         sscanf( &(yentp->d_name[2]), "%d%3c", &i, prebuf);
  278.         *(prebuf+3) = '.'; sprintf(prebuf+4, " %02d ", i);
  279.         strncpy(prebuf+8, year, 4);
  280.         *(prebuf+12) = '\0';
  281.  
  282.         /* open file and put each line in stdout, prepended    */
  283.         /* with the contents of prebuf and a tab.        */
  284.         
  285.         if (!(fd = fopen(filename, "r"))) {
  286.         fprintf(stderr,
  287.             "Error %d opening %s, ignoring ... \n", errno,
  288.                filename);
  289.         continue;    /* the foreach file loop    */
  290.         }
  291.         
  292.         while (fgets(inbuf, sizeof(inbuf), fd)) {
  293.         printf("%s\t%s", prebuf, inbuf);
  294.         if (*(inbuf + strlen(inbuf) - 1) != '\n')
  295.             printf("\n");
  296.         }
  297.         fclose(fd);
  298.  
  299.     }            /* end for each day file    */
  300.     
  301.     if ((closedir(ydirp)) != 0) {
  302.         *(ypathend-1) = '\0';    /* reinit to just dirname    */
  303.         perror(filename);
  304.     }
  305.     }                /* end for each year    */
  306.  
  307.     if ((closedir(Cdirp)) != 0) {
  308.     perror(dirname);
  309.     return(errno);
  310.     }
  311.  
  312.     return(0);
  313. }
  314.