home *** CD-ROM | disk | FTP | other *** search
/ PC Online 1997 August / PCO0897.ISO / filesbbs / os2 / plnk065.arj / PLNK065.ZIP / pilot-link.0.6.5 / libsock / datebook.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-05-23  |  7.2 KB  |  311 lines

  1. /* datebook.c:  Translate Pilot datebook data formats
  2.  *
  3.  * Copyright (c) 1996, Kenneth Albanowski
  4.  *
  5.  * This is free software, licensed under the GNU Public License V2.
  6.  * See the file COPYING for details.
  7.  */
  8.  
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <string.h>
  12. #include "pi-source.h"
  13. #include "pi-socket.h"
  14. #include "pi-dlp.h"
  15. #include "pi-datebook.h"
  16.  
  17. /* dom1stSun = REM Sun 1  
  18.  dom1stMon = Rem Mon 1 
  19.  dom2ndSun = REM Sun 8 
  20.  domLastSun = REM Sun 1 -7*/
  21.  
  22. void free_Appointment(struct Appointment * a) {
  23.   if(a->exception)
  24.     free(a->exception);
  25.   if(a->description)
  26.     free(a->description);
  27.   if(a->note)
  28.     free(a->note);
  29. }
  30.  
  31. void unpack_Appointment(struct Appointment * a, unsigned char * buffer, int len) {
  32.   int iflags;
  33.   unsigned char * p2;
  34.   unsigned long d;
  35.   int j;
  36.   
  37.   /* Note: There are possible timezone conversion problems related to the
  38.            use of the begin, end, repeatEnd, and exception[] members of a
  39.            struct Appointment. As they are kept in local (wall) time in
  40.            struct tm's, the timezone of the Pilot is irrelevant, _assuming_
  41.            that any UNIX program keeping time in time_t's converts them to
  42.            the correct local time. If the Pilot is in a different timezone
  43.            than the UNIX box, it may not be simple to deduce that correct
  44.            (desired) timezone.
  45.            
  46.            The easiest solution is to keep apointments in struct tm's, and
  47.            out of time_t's. Of course, this might not actually be a help if
  48.            you are constantly darting across timezones and trying to keep
  49.            appointments.
  50.                                                                     -- KJA
  51.            */
  52.   
  53.   a->begin.tm_hour = get_byte(buffer);
  54.   a->begin.tm_min = get_byte(buffer+1);
  55.   a->begin.tm_sec = 0;
  56.   d = (unsigned short int)get_short(buffer+4);
  57.   a->begin.tm_year = (d >> 9) + 4;
  58.   a->begin.tm_mon = ((d >> 5) & 15) - 1;
  59.   a->begin.tm_mday = d & 31;
  60.   a->begin.tm_isdst = -1;
  61.   a->end = a->begin;
  62.  
  63.   a->end.tm_hour = get_byte(buffer+2);
  64.   a->end.tm_min = get_byte(buffer+3);
  65.     
  66.   if(get_short(buffer) == 0xffff) {
  67.     a->event = 1;
  68.     a->begin.tm_hour = 0;
  69.     a->begin.tm_min = 0;
  70.     a->end.tm_hour = 0;
  71.     a->end.tm_min = 0;
  72.   } else {
  73.     a->event = 0;
  74.   }
  75.   
  76.   mktime(&a->begin);
  77.   mktime(&a->end);
  78.       
  79.   iflags = get_byte(buffer+6);
  80.  
  81.   /* buffer+7 is gapfil */
  82.     
  83.     p2 = (char*)buffer+8;
  84.     
  85. #define alarmFlag 64
  86. #define repeatFlag 32
  87. #define noteFlag 16
  88. #define exceptFlag 8
  89. #define descFlag 4
  90.     
  91.     if (iflags & alarmFlag) 
  92.         {
  93.         a->alarm = 1;
  94.         a->advance = get_byte(p2);
  95.         p2+=1;
  96.         a->advanceUnits = get_byte(p2);
  97.         p2+=1;
  98.         
  99.         }
  100.     else {
  101.         a->alarm = 0;
  102.         a->advance = 0;
  103.         a->advanceUnits = 0;
  104.     }
  105.         
  106.     if (iflags & repeatFlag)
  107.         {
  108.         a->repeatType = get_byte(p2); p2+=2;
  109.         d = (unsigned short int)get_short(p2); p2+=2;
  110.         if(d==0xffff)
  111.             a->repeatForever=1; /* repeatEnd is invalid */
  112.         else {
  113.             a->repeatEnd.tm_year = (d >> 9) + 4;
  114.             a->repeatEnd.tm_mon = ((d >> 5) & 15) - 1;
  115.             a->repeatEnd.tm_mday = d & 31;
  116.             a->repeatEnd.tm_min = 0;
  117.             a->repeatEnd.tm_hour = 0;
  118.             a->repeatEnd.tm_sec = 0;
  119.             a->repeatEnd.tm_isdst = -1;
  120.             mktime(&a->repeatEnd);
  121.             a->repeatForever = 0;
  122.         }
  123.         a->repeatFreq = get_byte(p2); p2++;
  124.         a->repeatOn = get_byte(p2); p2++;
  125.         a->repeatWeekstart = get_byte(p2); p2++;
  126.         p2++;
  127.         }
  128.     else {
  129.         a->repeatType = 0;
  130.         a->repeatForever = 1; /* repeatEnd is invalid */
  131.         a->repeatFreq = 0;
  132.         a->repeatOn = 0;
  133.         a->repeatWeekstart = 0;
  134.     }
  135.  
  136.     if (iflags & exceptFlag)
  137.         {
  138.         a->exceptions = get_short(p2);p2+=2;
  139.         a->exception = malloc(sizeof(struct tm)*a->exceptions);
  140.         
  141.         for(j=0;j<a->exceptions;j++,p2+=2) {
  142.             d = (unsigned short int)get_short(p2);
  143.             a->exception[j].tm_year = (d >> 9) + 4;
  144.             a->exception[j].tm_mon = ((d >> 5) & 15) - 1;
  145.             a->exception[j].tm_mday = d & 31;
  146.             a->exception[j].tm_hour = 0;
  147.             a->exception[j].tm_min = 0;
  148.             a->exception[j].tm_sec = 0;
  149.             a->exception[j].tm_isdst = -1;
  150.             mktime(&a->exception[j]);
  151.         }
  152.         
  153.         }
  154.     else  {
  155.         a->exceptions = 0;
  156.         a->exception = 0;
  157.     }
  158.  
  159.     if (iflags & descFlag)
  160.     {
  161.         a->description = strdup(p2);
  162.         p2 += strlen(p2) + 1;
  163.     } else
  164.         a->description = 0;
  165.  
  166.     if (iflags & noteFlag)
  167.     {
  168.         a->note = strdup(p2);
  169.         p2 += strlen(p2) + 1;
  170.     }
  171.     else {
  172.         a->note = 0;
  173.     }
  174.   
  175. }
  176.  
  177. void pack_Appointment(struct Appointment *a,
  178.                       unsigned char *buf,
  179.                       int *len)
  180. {
  181.     int iflags;
  182.     char *pos;
  183.  
  184.     set_byte(buf, a->begin.tm_hour);
  185.     set_byte(buf+1, a->begin.tm_min);
  186.     set_byte(buf+2, a->end.tm_hour);
  187.     set_byte(buf+3, a->end.tm_min);
  188.     set_short(buf+4, ((a->begin.tm_year - 4) << 9) |
  189.               ((a->begin.tm_mon  + 1) << 5) |
  190.               a->begin.tm_mday);
  191.     
  192.     if (a->event)
  193.     {
  194.         set_long(buf, 0xffffffff);
  195.     }
  196.  
  197. #define alarmFlag 64
  198. #define repeatFlag 32
  199. #define noteFlag 16
  200. #define exceptFlag 8
  201. #define descFlag 4
  202.  
  203.     iflags = 0;
  204.     
  205.     pos = (char *)buf + 8;
  206.  
  207.     if (a->alarm)
  208.     {
  209.         iflags |= alarmFlag;
  210.         
  211.         set_byte(pos, a->advance);
  212.         set_byte(pos+1, a->advanceUnits);
  213.         pos+=2;
  214.     }
  215.     
  216.     if (a->repeatType) {
  217.  
  218.         iflags |= repeatFlag;
  219.  
  220.         set_byte(pos, a->repeatType);
  221.         set_byte(pos+1, 0);
  222.         pos+=2;
  223.         
  224.         if (a->repeatForever)
  225.             set_short(pos, 0xffff);
  226.         else
  227.             set_short(pos, ((a->repeatEnd.tm_year - 4) << 9) |
  228.                 ((a->repeatEnd.tm_mon  + 1) << 5) |
  229.                 a->repeatEnd.tm_mday);
  230.         
  231.         pos+=2;
  232.         
  233.         set_byte(pos, a->repeatFreq); pos++;
  234.         set_byte(pos, a->repeatOn); pos++;
  235.         set_byte(pos, a->repeatWeekstart); pos++;
  236.         set_byte(pos, 0); pos++;
  237.     }
  238.     
  239.     if (a->exceptions) {
  240.         int i;
  241.         
  242.         iflags |= exceptFlag;
  243.         
  244.         set_short(pos, a->exceptions); pos+=2;
  245.         
  246.         for(i=0;i<a->exceptions;i++,pos+=2)
  247.             set_short(pos, ((a->exception[i].tm_year - 4) << 9) |
  248.                 ((a->exception[i].tm_mon  + 1) << 5) |
  249.                 a->exception[i].tm_mday);
  250.     }
  251.  
  252.     if (a->description != NULL)
  253.     {
  254.         iflags |= descFlag;
  255.         
  256.         strcpy(pos, a->description);
  257.         pos += strlen(pos) + 1;
  258.     }
  259.     
  260.     if (a->note != NULL)
  261.     {
  262.         iflags |= noteFlag;
  263.         
  264.         strcpy(pos, a->note);
  265.         pos += strlen(pos) + 1;
  266.     }
  267.  
  268.     set_byte(buf+6, iflags);
  269.  
  270.     *len = ((long)pos - (long)buf);
  271. }
  272.  
  273.                   
  274. void unpack_AppointmentAppInfo(struct AppointmentAppInfo * ai, unsigned char * record, int len) {
  275.   int i;
  276.   ai->renamedcategories = get_short(record);
  277.   record+=2;
  278.   for(i=0;i<16;i++) {
  279.     memcpy(ai->CategoryName[i], record, 16);
  280.     record += 16;
  281.   }
  282.   memcpy(ai->CategoryID, record, 16);
  283.   record += 16;
  284.   ai->lastUniqueID = get_byte(record);
  285.   record += 4;
  286.   ai->startOfWeek = get_byte(record);
  287. }
  288.  
  289. void pack_AppointmentAppInfo(struct AppointmentAppInfo * ai, unsigned char * record, int * len) {
  290.   int i;
  291.   unsigned char * start = record;
  292.   
  293.   set_short(record, ai->renamedcategories);
  294.   record += 2;
  295.   for(i=0;i<16;i++) {
  296.     memcpy(record, ai->CategoryName[i], 16);
  297.     record += 16;
  298.   }
  299.   memcpy(record, ai->CategoryID, 16);
  300.   record += 16;
  301.   set_byte(record, ai->lastUniqueID);
  302.   record ++;
  303.   set_byte(record, 0); /* gapfil */
  304.   set_short(record+1, 0); /* gapfil */
  305.   set_byte(record+3, ai->startOfWeek);
  306.   record+=4;
  307.   
  308.   if (len)
  309.     *len = (record-start);
  310. }
  311.