home *** CD-ROM | disk | FTP | other *** search
/ Network PC / Network PC.iso / amiga utilities / communication / bbs / termv4.6 / extras / source / term-source.lha / TimeDate.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-03-18  |  13.5 KB  |  654 lines

  1. /*
  2. **    TimeDate.c
  3. **
  4. **    Phone rate calculation support routines
  5. **
  6. **    Copyright © 1990-1996 by Olaf `Olsen' Barthel
  7. **        All Rights Reserved
  8. **
  9. ** :ts=4
  10. */
  11.  
  12. #ifndef _GLOBAL_H
  13. #include "Global.h"
  14. #endif
  15.  
  16.     /* SelectTime():
  17.      *
  18.      *    Searches for the correct unit/pay conversion values.
  19.      */
  20.  
  21. VOID
  22. SelectTime(struct PhoneEntry *SomeEntry,struct List *List,struct timeval *TimeVal)
  23. {
  24.     struct TimeDateNode    *TimeDateNode;
  25.     struct ClockData     ClockData;
  26.     LONG                 Time;
  27.     BOOL                 FoundOne = FALSE;
  28.     LONG                 i,Last;
  29.  
  30.         /* If we get a specific time of day, use it. */
  31.  
  32.     if(TimeVal)
  33.         Amiga2Date(TimeVal->tv_secs,&ClockData);
  34.     else
  35.     {
  36.         struct timeval Now;
  37.  
  38.             /* Obtain current time and date. */
  39.  
  40.         GetSysTime(&Now);
  41.  
  42.             /* Convert into a more suitable form (note: seconds are
  43.              * required as an input value, ice is extra).
  44.              */
  45.  
  46.         Amiga2Date(Now.tv_secs,&ClockData);
  47.     }
  48.  
  49.         /* Apparently, in the US of A the week starts with Sunday, we'll
  50.          * wrap the week around to let it start with Monday.
  51.          */
  52.  
  53.     if(ClockData . wday)
  54.         ClockData . wday--;
  55.     else
  56.         ClockData . wday = 6;
  57.  
  58.         /* Change the month, too... */
  59.  
  60.     ClockData . month--;
  61.  
  62.     if(List)
  63.     {
  64.         if(!List->lh_Head->ln_Succ)
  65.             List = NULL;
  66.     }
  67.  
  68.         /* If no special list to search is given use the phonebook entry. */
  69.  
  70.     if(!List)
  71.     {
  72.         if(SomeEntry && !SomeEntry->Header->NoRates)
  73.             List = (struct List *)&SomeEntry->TimeDateList;
  74.         else
  75.         {
  76.             PayPerUnit[DT_FIRST_UNIT]    = 0;
  77.             PayPerUnit[DT_NEXT_UNIT]    = 0;
  78.             SecPerUnit[DT_FIRST_UNIT]    = 0;
  79.             SecPerUnit[DT_NEXT_UNIT]    = 0;
  80.  
  81.             return;
  82.         }
  83.     }
  84.  
  85.     if(!List->lh_Head->ln_Succ)
  86.     {
  87.         PayPerUnit[DT_FIRST_UNIT]    = 0;
  88.         PayPerUnit[DT_NEXT_UNIT]    = 0;
  89.         SecPerUnit[DT_FIRST_UNIT]    = 0;
  90.         SecPerUnit[DT_NEXT_UNIT]    = 0;
  91.  
  92.         return;
  93.     }
  94.  
  95.         /* First step: search for current day. */
  96.  
  97.     TimeDateNode = (struct TimeDateNode *)List->lh_Head;
  98.  
  99.         /* Skip first entry. */
  100.  
  101.     TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
  102.  
  103.         /* First step: search for date settings. */
  104.  
  105.     while(TimeDateNode->VanillaNode . ln_Succ)
  106.     {
  107.             /* Does it match a specific date? */
  108.  
  109.         if(TimeDateNode->Header . Month == ClockData . month && TimeDateNode->Header . Day == ClockData . mday)
  110.         {
  111.             FoundOne = TRUE;
  112.  
  113.             break;
  114.         }
  115.  
  116.         TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
  117.     }
  118.  
  119.         /* Second step: search for week day settings. */
  120.  
  121.     if(!FoundOne)
  122.     {
  123.         TimeDateNode = (struct TimeDateNode *)List->lh_Head;
  124.  
  125.             /* Skip first entry. */
  126.  
  127.         TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
  128.  
  129.         while(TimeDateNode->VanillaNode . ln_Succ)
  130.         {
  131.                 /* Does it match a specific day? */
  132.  
  133.             if(TimeDateNode->Header . Month == -1 && (TimeDateNode->Header . Day & (1L << ClockData . wday)))
  134.             {
  135.                 FoundOne = TRUE;
  136.  
  137.                 break;
  138.             }
  139.  
  140.             TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ;
  141.         }
  142.     }
  143.  
  144.         /* Third step: use default settings. */
  145.  
  146.     if(!FoundOne)
  147.         TimeDateNode = (struct TimeDateNode *)List->lh_Head;
  148.  
  149.         /* Convert current time to packed format. */
  150.  
  151.     Time = DT_GET_TIME(ClockData . hour,ClockData . min);
  152.  
  153.         /* Start with a blank. */
  154.  
  155.     Last = -1;
  156.  
  157.         /* Look for fitting time. */
  158.  
  159.     for(i = 0 ; i < TimeDateNode->Table[0] . Count ; i++)
  160.     {
  161.             /* The time we are looking for must be >= the
  162.              * current time.
  163.              */
  164.  
  165.         if(TimeDateNode->Table[i] . Time > Time)
  166.         {
  167.             if(i == 0)
  168.                 break;
  169.             else
  170.             {
  171.                 Last = i - 1;
  172.                 break;
  173.             }
  174.         }
  175.         else
  176.             continue;
  177.     }
  178.  
  179.         /* If none is found, take the last one in the list.
  180.          * Note that this requires the list to be sorted in
  181.          * ascending order.
  182.          */
  183.  
  184.     if(Last == -1)
  185.         Last = TimeDateNode->Table[0] . Count - 1;
  186.  
  187.         /* Fill in the remaining data. */
  188.  
  189.     PayPerUnit[DT_FIRST_UNIT]    = TimeDateNode->Table[Last] . PayPerUnit[DT_FIRST_UNIT];
  190.     PayPerUnit[DT_NEXT_UNIT]    = TimeDateNode->Table[Last] . PayPerUnit[DT_NEXT_UNIT];
  191.     SecPerUnit[DT_FIRST_UNIT]    = TimeDateNode->Table[Last] . SecPerUnit[DT_FIRST_UNIT];
  192.     SecPerUnit[DT_NEXT_UNIT]    = TimeDateNode->Table[Last] . SecPerUnit[DT_NEXT_UNIT];
  193. }
  194.  
  195. struct List *
  196. FindTimeDate(struct List *Patterns,STRPTR Number)
  197. {
  198.     struct PatternNode    *Node;
  199.     UBYTE                 Dst[516];
  200.  
  201.     if(Kick30)
  202.     {
  203.         for(Node = (struct PatternNode *)Patterns->lh_Head ; Node->Node . ln_Succ ; Node = (struct PatternNode *)Node->Node . ln_Succ)
  204.         {
  205.             if(ParsePatternNoCase(Node->Pattern,Dst,516) != -1)
  206.             {
  207.                 if(MatchPatternNoCase(Dst,Number))
  208.                     return(&Node->List);
  209.             }
  210.         }
  211.     }
  212.     else
  213.     {
  214.         UBYTE    Src[256];
  215.         STRPTR    Index;
  216.  
  217.         for(Node = (struct PatternNode *)Patterns->lh_Head ; Node->Node . ln_Succ ; Node = (struct PatternNode *)Node->Node . ln_Succ)
  218.         {
  219.             strcpy(Index = Src,Node->Pattern);
  220.  
  221.             while(*Index)
  222.             {
  223.                 *Index = ToUpper(*Index);
  224.  
  225.                 Index++;
  226.             }
  227.  
  228.             if(ParsePatternNoCase(Src,Dst,516) != -1)
  229.             {
  230.                 if(MatchPatternNoCase(Dst,Number))
  231.                     return(&Node->List);
  232.             }
  233.         }
  234.     }
  235.  
  236.     return(NULL);
  237. }
  238.  
  239. VOID
  240. DeletePatternNode(struct PatternNode *Pattern)
  241. {
  242.     if(Pattern)
  243.     {
  244.         struct TimeDateNode    *Node,
  245.                             *NextNode;
  246.  
  247.         for(Node = (struct TimeDateNode *)Pattern->List . lh_Head ; NextNode = (struct TimeDateNode *)Node->VanillaNode . ln_Succ ; Node = NextNode)
  248.             FreeTimeDateNode(Node);
  249.  
  250.         FreeVecPooled(Pattern);
  251.     }
  252. }
  253.  
  254. struct PatternNode *
  255. CreatePatternNode(STRPTR Comment)
  256. {
  257.     struct PatternNode *Node;
  258.  
  259.     if(Node = (struct PatternNode *)AllocVecPooled(sizeof(struct PatternNode),MEMF_ANY | MEMF_CLEAR))
  260.     {
  261.         struct TimeDateNode *TimeDateNode;
  262.  
  263.         Node->Node . ln_Name = Node->Comment;
  264.  
  265.         strcpy(Node->Comment,Comment);
  266.  
  267.         NewList(&Node->List);
  268.  
  269.         if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
  270.         {
  271.             AddTail(&Node->List,&TimeDateNode->VanillaNode);
  272.  
  273.             return(Node);
  274.         }
  275.  
  276.         FreeVecPooled(Node);
  277.     }
  278.  
  279.     return(NULL);
  280. }
  281.  
  282. VOID
  283. DeletePatternList(struct List *List)
  284. {
  285.     if(List)
  286.     {
  287.         FreePatternList(List);
  288.  
  289.         FreeVecPooled(List);
  290.     }
  291. }
  292.  
  293. VOID
  294. FreePatternList(struct List *List)
  295. {
  296.     if(List)
  297.     {
  298.         struct PatternNode    *Pattern,
  299.                             *NextPattern;
  300.  
  301.         for(Pattern = (struct PatternNode *)List->lh_Head ; NextPattern = (struct PatternNode *)Pattern->Node . ln_Succ ; Pattern = NextPattern)
  302.             DeletePatternNode(Pattern);
  303.  
  304.         NewList(List);
  305.     }
  306. }
  307.  
  308. VOID
  309. ConvertTimeDate(struct TimeDateOld *Old,struct TimeDate *New)
  310. {
  311.     memset(New,0,sizeof(struct TimeDate));
  312.  
  313.     New->Count            = Old->Count;
  314.     New->PayPerUnit[0]    = ((ULONG)Old->PayPerUnit[0]) * 10000;
  315.     New->PayPerUnit[1]    = ((ULONG)Old->PayPerUnit[1]) * 10000;
  316.     New->SecPerUnit[0]    = ((ULONG)Old->SecPerUnit[0]) * 10000;
  317.     New->SecPerUnit[1]    = ((ULONG)Old->SecPerUnit[1]) * 10000;
  318.     New->Time            = Old->Time;
  319.     New->Mark            = FALSE;
  320. }
  321.  
  322. struct List *
  323. LoadTimeDateList(STRPTR Name,LONG *Error)
  324. {
  325.     struct IFFHandle    *Handle;
  326.     struct List            *List = NULL;
  327.  
  328.     *Error = 0;
  329.  
  330.     if(Handle = (struct IFFHandle *)AllocIFF())
  331.     {
  332.         if(Handle->iff_Stream = Open(Name,MODE_OLDFILE))
  333.         {
  334.             InitIFFasDOS(Handle);
  335.  
  336.             if(!(*Error = OpenIFF(Handle,IFFF_READ)))
  337.             {
  338.                 STATIC LONG Stops[4 * 2] =
  339.                 {
  340.                     ID_TERM, ID_VERS,
  341.                     ID_TERM, ID_NAME,
  342.                     ID_TERM, ID_DAT2,
  343.                     ID_TERM, ID_DATE
  344.                 };
  345.  
  346.                 struct ContextNode *Chunk;
  347.  
  348.                 if(!(*Error = StopChunks(Handle,Stops,4)))
  349.                 {
  350.                     if(List = (struct List *)AllocVecPooled(sizeof(struct MinList),MEMF_ANY))
  351.                     {
  352.                         struct PatternNode *Pattern = NULL;
  353.  
  354.                         NewList(List);
  355.  
  356.                         while(!ParseIFF(Handle,IFFPARSE_SCAN))
  357.                         {
  358.                             Chunk = CurrentChunk(Handle);
  359.  
  360.                             if(Chunk->cn_ID == ID_NAME)
  361.                             {
  362.                                 if(Pattern = (struct PatternNode *)AllocVecPooled(sizeof(struct PatternNode),MEMF_ANY | MEMF_CLEAR))
  363.                                 {
  364.                                     if(ReadChunkBytes(Handle,Pattern->Pattern,Chunk->cn_Size) == Chunk->cn_Size)
  365.                                     {
  366.                                         NewList(&Pattern->List);
  367.  
  368.                                         Pattern->Node . ln_Name = Pattern->Comment;
  369.  
  370.                                         AddTail(List,Pattern);
  371.                                     }
  372.                                     else
  373.                                     {
  374.                                         *Error = IoErr();
  375.  
  376.                                         FreeVecPooled(Pattern);
  377.  
  378.                                         break;
  379.                                     }
  380.                                 }
  381.                                 else
  382.                                 {
  383.                                     *Error = ERR_NO_MEM;
  384.  
  385.                                     break;
  386.                                 }
  387.                             }
  388.  
  389.                             if(Chunk->cn_ID == ID_DATE)
  390.                             {
  391.                                 struct TimeDateNode    *Node;
  392.                                 LONG                 Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDateOld);
  393.  
  394.                                 if(!Pattern)
  395.                                 {
  396.                                     *Error = IFFERR_MANGLED;
  397.  
  398.                                     break;
  399.                                 }
  400.  
  401.                                 if(Node = CreateTimeDateNode(-1,-1,"",Count))
  402.                                 {
  403.                                     struct TimeDateOld *Old;
  404.  
  405.                                     if(Old = (struct TimeDateOld *)AllocVecPooled(sizeof(struct TimeDateOld) * Count,MEMF_ANY))
  406.                                     {
  407.                                         if(ReadChunkBytes(Handle,&Node->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
  408.                                         {
  409.                                             if(ReadChunkRecords(Handle,Old,sizeof(struct TimeDateOld),Count) == Count)
  410.                                             {
  411.                                                 LONG i;
  412.  
  413.                                                 for(i = 0 ; i < Count ; i++)
  414.                                                     ConvertTimeDate(&Old[i],&Node->Table[i]);
  415.  
  416.                                                 AdaptTimeDateNode(Node);
  417.  
  418.                                                 AddTail(&Pattern->List,&Node->VanillaNode);
  419.  
  420.                                                 FreeVecPooled(Old);
  421.                                             }
  422.                                             else
  423.                                             {
  424.                                                 *Error = IoErr();
  425.  
  426.                                                 FreeTimeDateNode(Node);
  427.                                                 FreeVecPooled(Old);
  428.  
  429.                                                 break;
  430.                                             }
  431.                                         }
  432.                                         else
  433.                                         {
  434.                                             *Error = IoErr();
  435.  
  436.                                             FreeTimeDateNode(Node);
  437.                                             FreeVecPooled(Old);
  438.  
  439.                                             break;
  440.                                         }
  441.                                     }
  442.                                 }
  443.                                 else
  444.                                 {
  445.                                     *Error = ERROR_NO_FREE_STORE;
  446.                                     break;
  447.                                 }
  448.                             }
  449.  
  450.                             if(Chunk->cn_ID == ID_DAT2)
  451.                             {
  452.                                 struct TimeDateNode    *Node;
  453.                                 LONG                 Count = (Chunk->cn_Size - sizeof(struct TimeDateHeader)) / sizeof(struct TimeDate);
  454.  
  455.                                 if(!Pattern)
  456.                                 {
  457.                                     *Error = IFFERR_MANGLED;
  458.  
  459.                                     break;
  460.                                 }
  461.  
  462.                                 if(Node = CreateTimeDateNode(-1,-1,"",Count))
  463.                                 {
  464.                                     if(ReadChunkBytes(Handle,&Node->Header,sizeof(struct TimeDateHeader)) == sizeof(struct TimeDateHeader))
  465.                                     {
  466.                                         if(ReadChunkRecords(Handle,Node->Table,sizeof(struct TimeDate),Count) == Count)
  467.                                         {
  468.                                             AdaptTimeDateNode(Node);
  469.  
  470.                                             AddTail(&Pattern->List,&Node->VanillaNode);
  471.                                         }
  472.                                         else
  473.                                         {
  474.                                             *Error = IoErr();
  475.  
  476.                                             FreeTimeDateNode(Node);
  477.  
  478.                                             break;
  479.                                         }
  480.                                     }
  481.                                     else
  482.                                     {
  483.                                         *Error = IoErr();
  484.  
  485.                                         FreeTimeDateNode(Node);
  486.  
  487.                                         break;
  488.                                     }
  489.                                 }
  490.                                 else
  491.                                 {
  492.                                     *Error = ERROR_NO_FREE_STORE;
  493.                                     break;
  494.                                 }
  495.                             }
  496.                         }
  497.                     }
  498.                 }
  499.  
  500.                 CloseIFF(Handle);
  501.             }
  502.  
  503.             Close(Handle->iff_Stream);
  504.         }
  505.         else
  506.             *Error = IoErr();
  507.  
  508.         FreeIFF(Handle);
  509.     }
  510.     else
  511.         *Error = ERR_NO_MEM;
  512.  
  513.     if(*Error)
  514.     {
  515.         DeletePatternList(List);
  516.  
  517.         return(NULL);
  518.     }
  519.     else
  520.         return(List);
  521. }
  522.  
  523. BOOL
  524. SaveTimeDateList(STRPTR Name,struct List *List,LONG *Error)
  525. {
  526.     *Error = 0;
  527.  
  528. #ifdef BETA
  529.     if(ShowRequest(Window,
  530.         "ONE WAY TICKET WARNING!\n\n"
  531.         "The file format written by this `term' beta test release\n"
  532.         "cannot be read by older program releases. And just as it\n"
  533.         "happens, not even the author of these lines can guarantee\n"
  534.         "you that this very program will be able to read the files\n"
  535.         "back it writes.",
  536.     "Uh oh...|I know what I'm doing"))
  537.         return(TRUE);
  538. #endif
  539.  
  540.     if(List->lh_Head->ln_Succ)
  541.     {
  542.         struct IFFHandle *Handle;
  543.  
  544.         if(Handle = (struct IFFHandle *)AllocIFF())
  545.         {
  546.             BOOL Created;
  547.  
  548.             if(Handle->iff_Stream = Open(Name,MODE_NEWFILE))
  549.             {
  550.                 Created = TRUE;
  551.  
  552.                 InitIFFasDOS(Handle);
  553.  
  554.                 if(!(*Error = OpenIFF(Handle,IFFF_WRITE)))
  555.                 {
  556.                     if(!(*Error = PushChunk(Handle,ID_TERM,ID_FORM,IFFSIZE_UNKNOWN)))
  557.                     {
  558.                         if(!(*Error = PushChunk(Handle,0,ID_VERS,IFFSIZE_UNKNOWN)))
  559.                         {
  560.                             struct TermInfo TermInfo;
  561.  
  562.                             TermInfo . Version    = CONFIG_FILE_VERSION;
  563.                             TermInfo . Revision    = CONFIG_FILE_REVISION;
  564.  
  565.                             if(WriteChunkRecords(Handle,&TermInfo,sizeof(struct TermInfo),1) == 1)
  566.                             {
  567.                                 if(!(*Error = PopChunk(Handle)))
  568.                                 {
  569.                                     struct PatternNode *Node;
  570.  
  571.                                     for(Node = (struct PatternNode *)List->lh_Head ; !(*Error) && Node->Node . ln_Succ ; Node = (struct PatternNode *)Node->Node . ln_Succ)
  572.                                     {
  573.                                         if(!(*Error = PushChunk(Handle,0,ID_NAME,296)))
  574.                                         {
  575.                                             if(WriteChunkBytes(Handle,Node->Pattern,296) == 296)
  576.                                             {
  577.                                                 if(!(*Error = PopChunk(Handle)))
  578.                                                 {
  579.                                                     struct TimeDateNode *TimeDateNode;
  580.  
  581.                                                     for(TimeDateNode = (struct TimeDateNode *)Node->List . lh_Head ; TimeDateNode->VanillaNode . ln_Succ ; TimeDateNode = (struct TimeDateNode *)TimeDateNode->VanillaNode . ln_Succ)
  582.                                                     {
  583.                                                         if(!(*Error = PushChunk(Handle,0,ID_DAT2,sizeof(struct TimeDateHeader) + TimeDateNode->Table[0] . Count * sizeof(struct TimeDate))))
  584.                                                         {
  585.                                                             if(WriteChunkBytes(Handle,&TimeDateNode->Header,sizeof(struct TimeDateHeader)) != sizeof(struct TimeDateHeader))
  586.                                                             {
  587.                                                                 *Error = IoErr();
  588.  
  589.                                                                 break;
  590.                                                             }
  591.                                                             else
  592.                                                             {
  593.                                                                 if(WriteChunkBytes(Handle,TimeDateNode->Table,TimeDateNode->Table[0] . Count * sizeof(struct TimeDate)) != TimeDateNode->Table[0] . Count * sizeof(struct TimeDate))
  594.                                                                 {
  595.                                                                     *Error = IoErr();
  596.  
  597.                                                                     break;
  598.                                                                 }
  599.                                                                 else
  600.                                                                 {
  601.                                                                     if(*Error = PopChunk(Handle))
  602.                                                                         break;
  603.                                                                 }
  604.                                                             }
  605.                                                         }
  606.                                                         else
  607.                                                             break;
  608.                                                     }
  609.                                                 }
  610.                                             }
  611.                                             else
  612.                                                 *Error = IoErr();
  613.                                         }
  614.                                     }
  615.                                 }
  616.                             }
  617.                         }
  618.  
  619.                         if(!(*Error))
  620.                             *Error = PopChunk(Handle);
  621.                     }
  622.  
  623.                     CloseIFF(Handle);
  624.                 }
  625.  
  626.                 Close(Handle->iff_Stream);
  627.             }
  628.             else
  629.             {
  630.                 *Error = IoErr();
  631.  
  632.                 Created = FALSE;
  633.             }
  634.  
  635.             if(Created)
  636.             {
  637.                 if(*Error)
  638.                     DeleteFile(Name);
  639.                 else
  640.                     AddProtection(Name,FIBF_EXECUTE);
  641.             }
  642.  
  643.             FreeIFF(Handle);
  644.         }
  645.         else
  646.             *Error = ERR_NO_MEM;
  647.     }
  648.  
  649.     if(*Error)
  650.         return(FALSE);
  651.     else
  652.         return(TRUE);
  653. }
  654.