home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / mush6.0 / part03 / dates.c < prev    next >
Encoding:
C/C++ Source or Header  |  1988-04-12  |  7.3 KB  |  256 lines

  1. /* @(#)dates.c    1.1    (c) copyright 10/15/86 (Dan Heller) */
  2.  
  3. #include "mush.h"
  4.  
  5. char *day_names[] = {
  6.     "Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"
  7. };
  8. char *month_names[] = {     /* imported in pick.c */
  9.     "Jan", "Feb", "Mar", "Apr", "May", "Jun",
  10.     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
  11. };
  12.  
  13. /* Time() returns a string according to criteria:
  14.  *   if "now" is 0, then the current time is gotten and used.
  15.  *       else, use the time described by now
  16.  *   opts points to a string of args which is parsed until an unknown
  17.  *       arg is found and opts will point to that upon return.
  18.  *   valid args are T (time of day), D (day of week), M (month), Y (year),
  19.  *       N (number of day in month -- couldn't think of a better letter).
  20.  */
  21. char *
  22. Time(opts, now)
  23. register char *opts;
  24. long now;
  25. {
  26.     static char time_buf[30];
  27.     struct tm       *T;
  28.     register char *p = time_buf;
  29.     long      x;
  30.  
  31.     if (!opts)
  32.     return NULL;
  33.     if (now)
  34.     x = now;
  35.     else
  36.     (void) time(&x);
  37.     T = localtime(&x);
  38.     for (;; opts++) {
  39.     switch(*opts) {
  40.         case 'T':
  41.         if (ison(glob_flags, MIL_TIME))
  42.             (void) sprintf(p, "%2d:%02d", T->tm_hour, T->tm_min);
  43.         else
  44.             (void) sprintf(p, "%d:%02d", (T->tm_hour) ?
  45.               ((T->tm_hour <= 12) ? T->tm_hour : T->tm_hour - 12) :
  46.               12, T->tm_min);
  47.         when 'D': (void) strcpy(p, day_names[T->tm_wday]);
  48.         when 'M': (void) strcpy(p, month_names[T->tm_mon]);
  49.         when 'Y': (void) sprintf(p, "%d", T->tm_year);
  50.         when 'N': (void) sprintf(p, "%d", T->tm_mday);
  51.         otherwise: *--p = 0; return time_buf;
  52.     }
  53.     p += strlen(p);
  54.     *p++ = ' ';
  55.     }
  56. }
  57.  
  58. /* find the date of a message and return a string of the same form
  59.  * described by parse_date() below.
  60.  */
  61. char *
  62. msg_date(n)
  63. register int n;
  64. {
  65.     register char *p, *p2 = NULL;
  66.     char line[BUFSIZ];
  67.  
  68.     /* not in use */
  69.     /* try the easy way out first -- This is potentially a serious kludge
  70.      * because not all message-id lines are right. -- most of the time,
  71.      * this is correct.  it's not correct from messages from strange
  72.      * mailers (non-sendmail) they do a different format in message-id.
  73.     if ((p = header_field(n, "message-id")) && (p2 = index(p, '<'))) {
  74.     p = p2+1;
  75.     if (p2 = index(p, '.')) {
  76.         *p2 = 0;
  77.         return p;
  78.     }
  79.     }
  80.      */
  81.  
  82.     /* else, get the "date" line, if that fails, get the date in "From" line */
  83.     if ((p = header_field(n, "date")) && (p2 = parse_date(p)))
  84.     return p2;
  85.  
  86.     (void) fseek(tmpf, msg[n].m_offset, L_SET);
  87.     (void) fgets(line, BUFSIZ, tmpf);
  88.     if (!(p = index(line, ' ')) || !(p2 = index(p+1, ' ')))
  89.     return NULL;
  90.     p = p2;
  91.  
  92.     if (!(p2 = parse_date(p)))
  93.     print("Message %d has bad date: %s\n", n+1, p);
  94.     return p2;
  95. }
  96.  
  97. /* parse date and return a string that looks like
  98.  *    "%2d%2d%2d%2d%2d", yr,mo,date,hrs,mins
  99.  */
  100. char *
  101. parse_date(p)
  102. register char *p;
  103. {
  104.     /* If it's not a month, it can get _long_.  this is also the static
  105.      * buffer whose address we return.
  106.      */
  107.     static char month[64];
  108.     int Month = 0, Day = 0, Year = 0, Hours = -1, Mins = -1;
  109.  
  110.     skipspaces(0);
  111.  
  112.     /* Possible combinations that we could have:
  113.      *   day_number month_name year_number time timezone ...
  114.      *   day_name month_name day_number time year_number
  115.      *   day_name month_name day_number year_number time
  116.      *   day_name day_number month_name year_number time
  117.      *   day_number month_name year_number time
  118.      *   day_number month_name year_number time-timezone (day)
  119.      *                                       ^no colon separator
  120.      *   day_name month_name day_number time timezone year_number
  121.      *   day_number-month_name-year time
  122.      *   day_name, day_number-month_name-year time
  123.      *   day_number month_name year_number, time "-"
  124.      */
  125.     /* programmer's note -- there are too many scanfs here for some compilers
  126.      * to put them all into one if statement.  Use goto's :-(
  127.      */
  128.     if (sscanf(p, "%*s %s %d %d %d:%d", month,&Day,&Year,&Hours,&Mins) == 5)
  129.     goto gotit;
  130.     if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  131.     goto gotit;
  132.     if (sscanf(p, "%*s %s %d %d:%d:%*d %d", month,&Day,&Hours,&Mins,&Year) == 5)
  133.     goto gotit;
  134.     if (sscanf(p, "%*s %d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  135.     goto gotit;
  136.     if (sscanf(p, "%d %s %d %d:%d", &Day,month,&Year,&Hours,&Mins) == 5)
  137.     goto gotit;
  138.     if (sscanf(p, "%d %s %d %2d%2d", &Day,month,&Year,&Hours,&Mins) == 5)
  139.     goto gotit;
  140.     if (sscanf(p, "%*s %s %d %d:%d:%*d %*s %d",
  141.                     month, &Day, &Hours, &Mins, &Year) == 5)
  142.     goto gotit;
  143.     if (sscanf(p, "%*s %s %d %d:%d %*s %d",
  144.                     month, &Day, &Hours, &Mins, &Year) == 5)
  145.     goto gotit;
  146.     if (sscanf(p,"%d-%[^-]-%d %d:%d", &Day, month, &Year, &Hours, &Mins) == 5)
  147.     goto gotit;
  148.     if (sscanf(p,"%d %s %d, %d:%d:%*d -",&Day, month, &Year, &Hours, &Mins)== 5)
  149.     goto gotit;
  150.     if (sscanf(p,"%*s %d-%[^-]-%d %d:%d",&Day, month, &Year, &Hours, &Mins)== 5)
  151.     goto gotit;
  152.     goto didnt_getit;
  153. gotit:
  154.     if (Year > 1900)
  155.     Year -= 1900;
  156.     if ((Month = month_to_n(month)) == -1) {
  157.     print("bad month: %s\n", p);
  158.     return NULL;
  159.     }
  160.     return sprintf(month, "%02d%02d%02d%02d%02d", Year,Month,Day,Hours,Mins);
  161. didnt_getit:
  162.     if (ison(glob_flags, WARNING))
  163.     print("Unknown date format: %s\n", p);
  164.     return NULL;
  165. }
  166.  
  167. /* pass a string in the form described above, put into string.
  168.  * return values in buffers provided they are not null.
  169.  */
  170. char *
  171. date_to_string(Date, Yr, Mon, Day, Wkday, Tm, ret_buf)
  172. char *Date, *Yr, *Mon, *Day, *Wkday, *Tm, *ret_buf;
  173. {
  174.  
  175.     static int mtbl[]={0,31,59,90,120,151,181,212,243,273,304,334};
  176.     unsigned int days_ctr;
  177.     int yr, mon, day, hr, mins;
  178.     char a_or_p, *p = ret_buf;
  179.  
  180.     (void) sscanf(Date, "%2d%2d%2d%2d%02d", &yr, &mon, &day, &hr, &mins);
  181.     a_or_p = (hr < 12)? 'a': 'p';
  182.  
  183.     if (Wkday) {
  184.         days_ctr = ((yr * 365) + ((yr + 3) / 4) + mtbl[mon-1] + day + 6);
  185.         if (mon > 2 && (yr % 4 == 0))
  186.         days_ctr++;
  187.         (void) (sprintf(Wkday, "%.3s", day_names[days_ctr % 7]));
  188.     }
  189.     if (Yr)
  190.     (void) sprintf(Yr, "19%d", yr);
  191.     if (Day)
  192.     (void) sprintf(Day, "%d", day);
  193.     if (Mon)
  194.     (void) strcpy(Mon, month_names[mon-1]);
  195.     p += strlen(sprintf(p, "%s %2.d, ", month_names[mon-1], day));
  196.     if (ison(glob_flags, MIL_TIME))
  197.     (void) sprintf(p, "%2d:%02d",hr,mins);
  198.     else
  199.     (void) sprintf(p, "%2.d:%02d%cm",
  200.           (hr)? (hr <= 12)? hr: hr - 12: 12, mins, a_or_p);
  201.     if (Tm)
  202.     (void) strcpy(Tm, p);
  203.     return ret_buf;
  204. }
  205.  
  206. #define JAN    1
  207. #define FEB    2
  208. #define MAR    3
  209. #define APR    4
  210. #define MAY    5
  211. #define JUN    6
  212. #define JUL    7
  213. #define AUG    8
  214. #define SEP    9
  215. #define OCT    10
  216. #define NOV    11
  217. #define DEC    12
  218.  
  219. /* stolen direct from ELM */
  220. month_to_n(name)
  221. register char *name;
  222. {
  223.     /** return the month number given the month name... **/
  224.  
  225.     register char ch;
  226.  
  227.     switch (lower(*name)) {
  228.     case 'a' : if ((ch = lower(name[1])) == 'p')
  229.                return(APR);
  230.            else if (ch == 'u')
  231.                return(AUG);
  232.            else return(-1);    /* error! */
  233.     case 'd' : return(DEC);
  234.     case 'f' : return(FEB);
  235.     case 'j' : if ((ch = lower(name[1])) == 'a')
  236.                return(JAN);
  237.            else if (ch == 'u') {
  238.              if ((ch = lower(name[2])) == 'n')
  239.              return(JUN);
  240.              else if (ch == 'l')
  241.              return(JUL);
  242.              else return(-1);        /* error! */
  243.            }
  244.            else return(-1);        /* error */
  245.     case 'm' : if ((ch = lower(name[2])) == 'r')
  246.                return(MAR);
  247.            else if (ch == 'y')
  248.                return(MAY);
  249.            else return(-1);        /* error! */
  250.     case 'n' : return(NOV);
  251.     case 'o' : return(OCT);
  252.     case 's' : return(SEP);
  253.     default  : return(-1);
  254.     }
  255. }
  256.