home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Elysian Archive
/
AmigaElysianArchive.iso
/
comm
/
term23_2.lha
/
Source_Code
/
termSource
/
termPhone.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-08-18
|
38KB
|
1,699 lines
/*
** $Id: termPhone.c,v 1.11 92/08/18 16:12:51 olsen Sta Locker: olsen $
** $Revision: 1.11 $
** $Date: 92/08/18 16:12:51 $
**
** Phonebook support routines
**
** Copyright © 1990-1992 by Olaf `Olsen' Barthel & MXM
** All Rights Reserved
*/
#include "termGlobal.h"
/* Size of a phonebook entry in the list. */
#define RAWSIZE (sizeof(struct PhoneEntry) - offsetof(struct PhoneEntry,Name))
#define DATEHEADERSIZE 24
/* Obsolete TimeDate structure. */
struct TimeDateOld
{
WORD PayPerUnit[2],
SecPerUnit[2],
TimeOfDay[2];
BYTE Month,
Day;
UBYTE Comment[22];
};
/* Are we using the new includes? */
#ifdef ASLSM_FilterFunc
/* Undefine the following symbols, the preferences header file
* will use the same names and the same values.
*/
#undef PARITY_NONE
#undef PARITY_EVEN
#undef PARITY_ODD
#undef PARITY_MARK
#undef PARITY_SPACE
/* Include the preferences header files. */
#include <prefs/prefhdr.h>
#include <prefs/serial.h>
/* Serial preferences data. */
STATIC BYTE SerialPrefsRead = FALSE,
SerialPrefsReadFailed = FALSE;
STATIC struct SerialPrefs SerialPrefs;
/* ReadSerialPrefs():
*
* Reads the default serial preferences settings.
*/
STATIC BYTE
ReadSerialPrefs()
{
struct IFFHandle *Handle;
/* Allocate an IFF handle. */
if(Handle = AllocIFF())
{
/* Open the preferences settings file. */
if(Handle -> iff_Stream = Open("ENV:sys/serial.prefs",MODE_OLDFILE))
{
/* Make it known as a DOS file handle. */
InitIFFasDOS(Handle);
/* Open the file for reading. */
if(!OpenIFF(Handle,IFFF_READ))
{
/* Stop at the `body' chunk. */
if(!StopChunk(Handle,ID_PREF,ID_SERL))
{
/* Look for it... */
if(!ParseIFF(Handle,IFFPARSE_SCAN))
{
/* Read the data. */
if(ReadChunkBytes(Handle,&SerialPrefs,sizeof(struct SerialPrefs)) == sizeof(struct SerialPrefs))
SerialPrefsRead = TRUE;
}
}
/* Close the handle. */
CloseIFF(Handle);
}
/* Release the handle. */
Close(Handle -> iff_Stream);
}
/* Clean up. */
FreeIFF(Handle);
}
/* Return sucess/failure. */
return(SerialPrefsRead);
}
#endif /* ASLSM_FilterFunc */
/* SetPrefToDefaults():
*
* Initialize configuration with default values.
*/
VOID
SetPrefToDefaults(struct Configuration *Config,UBYTE *PathBuffer)
{
if(!PathBuffer)
PathBuffer = "TERM:config";
strcpy(Config -> DefaultStorage,PathBuffer);
#ifdef ASLSM_FilterFunc
/* The program will only try to read the preferences
* settings once; if the first access failed, no
* other accesses will be made.
*/
if(!SerialPrefsRead && !SerialPrefsReadFailed)
SerialPrefsReadFailed = ReadSerialPrefs() ^ TRUE;
/* Did we succeed in reading the file? */
if(!SerialPrefsRead)
{
Config -> BaudRate = 2400;
Config -> BitsPerChar = 8;
Config -> Parity = PARITY_NONE;
Config -> StopBits = 1;
Config -> Handshaking = 42;
Config -> HandshakingProtocol = HANDSHAKING_NONE;
Config -> xONxOFF = TRUE;
Config -> SerBuffSize = 32768;
}
else
{
/* Fill in the common data. */
Config -> BaudRate = SerialPrefs . sp_BaudRate;
Config -> SerBuffSize = SerialPrefs . sp_InputBuffer;
Config -> BitsPerChar = SerialPrefs . sp_BitsPerChar;
Config -> StopBits = SerialPrefs . sp_StopBits;
Config -> Handshaking = 42;
/* Convert the handshaking mode. */
switch(SerialPrefs . sp_InputHandshake)
{
case HSHAKE_NONE: Config -> HandshakingProtocol = HANDSHAKING_NONE;
Config -> xONxOFF = FALSE;
break;
case HSHAKE_RTS: Config -> HandshakingProtocol = HANDSHAKING_RTSCTS;
Config -> xONxOFF = FALSE;
break;
default: Config -> HandshakingProtocol = HANDSHAKING_NONE;
Config -> xONxOFF = TRUE;
break;
}
/* Convert the parity settings. */
if(SerialPrefs . sp_Parity <= PARITY_SPACE)
Config -> Parity = SerialPrefs . sp_Parity;
else
Config -> Parity = PARITY_NONE;
}
#else
Config -> BaudRate = 2400;
Config -> BitsPerChar = 8;
Config -> Parity = PARITY_NONE;
Config -> StopBits = 1;
Config -> Handshaking = HANDSHAKING_XONXOFF;
Config -> SerBuffSize = 32768;
#endif /* ASLSM_FilterFunc */
strcpy(Config -> SerialDevice,SERIALNAME);
Config -> Duplex = DUPLEX_FULL;
Config -> HighSpeed = FALSE;
Config -> BreakLength = 250000;
Config -> UnitNumber = 0;
/* Modem Preferences. */
Config -> RedialDelay = 2;
Config -> DialRetries = 10;
Config -> DialTimeout = 60;
Config -> ConnectAutoBaud = FALSE;
strcpy(Config -> ModemInit, "ATZ\\r");
strcpy(Config -> ModemExit, "");
strcpy(Config -> ModemHangup, "~~~~~~~~+++\\r~~~~~~ATH0\\r");
strcpy(Config -> DialPrefix, "~~ATDP");
strcpy(Config -> NoCarrier, "NO CARRIER");
strcpy(Config -> Connect, "CONNECT");
strcpy(Config -> Voice, "VOICE");
strcpy(Config -> Ring, "RING");
strcpy(Config -> Busy, "BUSY");
/* Transfer Preferences. */
strcpy(Config -> Protocol,"xprzmodem.library");
/* Macro Preferences. */
if(!LastMacros[0])
{
strcpy(LastMacros,PathBuffer);
AddPart(LastMacros,"macros.prefs",256);
}
strcpy(Config -> MacroFile,LastMacros);
/* Screen Preferences. */
Config -> DisplayMode = DEFAULT_MONITOR_ID|HIRES_KEY;
Config -> MakeScreenPublic = TRUE;
/* Terminal Preferences. */
Config -> CaptureFilter = TRUE;
Config -> DestructiveBackspace = FALSE;
Config -> AudibleBell = TRUE;
Config -> VisibleBell = FALSE;
Config -> EightyColumns = FALSE;
Config -> SendCR = CR_ASCR;
Config -> SendLF = LF_ASLF;
Config -> ColourMode = COLOUR_AMIGA;
Config -> Emulation = EMULATION_ANSIVT100;
Config -> Font = FONT_TOPAZ;
Config -> SwapBSDelete = FALSE;
Config -> StripBit8 = FALSE;
Config -> RasterEnabled = TRUE;
Config -> EmulationName[0] = 0;
Config -> StartupMacro[0] = 0;
Config -> UploadMacro[0] = 0;
Config -> DownloadMacro[0] = 0;
Config -> LogoffMacro[0] = 0;
if(!LastFastMacros[0])
{
strcpy(LastFastMacros,PathBuffer);
AddPart(LastFastMacros,"fastmacros.prefs",256);
}
strcpy(Config -> FastMacroFile,LastFastMacros);
Config -> Priority = 0;
Config -> OverridePath = TRUE;
Config -> BackupConfig = FALSE;
Config -> AutoUpload = TRUE;
strcpy(Config -> NoDialTone,"NO DIALTONE");
Config -> TitleBar = TRUE;
Config -> StatusLine = TRUE;
Config -> DropDTR = FALSE;
Config -> MaxLogBuffSize = 0;
Config -> BufferEnabled = TRUE;
Config -> ReceiveCR = CR_ASCR;
Config -> ReceiveLF = LF_ASLF;
Config -> SetArchivedBit = FALSE;
Config -> KeyMapName[0] = 0;
Config -> OpenFastMacroPanel = FALSE;
Config -> PassThrough = FALSE;
Config -> SystemBeep = FALSE;
Config -> Alert = ALERT_BEEP_SCREEN;
Config -> AnswerBack[0] = 0;
Config -> ClipboardUnit = 0;
strcpy(Config -> FontName,"topaz.font");
Config -> FontHeight = 8;
strcpy(Config -> TextFontName,"topaz.font");
Config -> TextFontHeight = 8;
Config -> NCommLog = FALSE;
Config -> PrinterEnabled = TRUE;
Config -> Pad = 0;
strcpy(Config -> DialSuffix,"\\r");
Config -> LineDelay = 0;
Config -> CharDelay = 0;
}
/* UpdatePrefs(struct Configuration *Config):
*
* Patch existing preferences entry to
* use new flags and definitions.
*/
VOID
UpdatePrefs(struct Configuration *Config)
{
enum { OLDHANDSHAKING_XONXOFF,OLDHANDSHAKING_RTSCTS,OLDHANDSHAKING_NONE,OLDHANDSHAKING_RTSCTS_DSR };
switch(Config -> Handshaking)
{
case OLDHANDSHAKING_XONXOFF: Config -> HandshakingProtocol = HANDSHAKING_NONE;
Config -> xONxOFF = TRUE;
break;
case OLDHANDSHAKING_RTSCTS: Config -> HandshakingProtocol = HANDSHAKING_RTSCTS;
Config -> xONxOFF = FALSE;
break;
case OLDHANDSHAKING_NONE: Config -> HandshakingProtocol = HANDSHAKING_NONE;
Config -> xONxOFF = FALSE;
break;
case OLDHANDSHAKING_RTSCTS_DSR: Config -> HandshakingProtocol = HANDSHAKING_RTSCTS_DSR;
Config -> xONxOFF = FALSE;
break;
}
Config -> Handshaking = 42;
if(Config -> EmulationName[0])
{
WORD i;
for(i = 0 ; i < strlen(Config -> EmulationName) ; i++)
Config -> EmulationName[i] = ToLower(Config -> EmulationName[i]);
}
if(Config -> HighSpeed & ~SERIAL_SHARED)
{
Config -> BitsPerChar = 8;
Config -> StopBits = 1;
Config -> Parity = PARITY_NONE;
}
}
VOID
RemoveDialEntry(LONG Entry)
{
LONG Count = Phonebook[Entry] -> Count,i;
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(Phonebook[i] -> Count > Count)
SPrintf(Phonebook[i] -> Node -> LocalName,"%3ld - %s",Phonebook[i] -> Count--,Phonebook[i] -> Name);
}
Phonebook[Entry] -> Count = -1;
SPrintf(Phonebook[Entry] -> Node -> LocalName," %s",Phonebook[Entry] -> Name);
}
VOID
RemoveDialNode(struct PhoneNode *Node)
{
LONG Count = Node -> Entry -> Count,i;
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(Phonebook[i] -> Count > Count)
SPrintf(Phonebook[i] -> Node -> LocalName,"%3ld - %s",Phonebook[i] -> Count--,Phonebook[i] -> Name);
}
Node -> Entry -> Count = -1;
SPrintf(Node -> LocalName," %s",Node -> Entry -> Name);
}
VOID
SortToList(struct PhoneNode *PhoneNode)
{
if(!DialList)
{
if(DialList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
NewList(DialList);
}
if(DialList)
{
struct PhoneNode *Node = (struct PhoneNode *)DialList -> lh_Head,*NewNode;
if(NewNode = (struct PhoneNode *)AllocVec(sizeof(struct PhoneNode),MEMF_ANY))
{
CopyMem(PhoneNode,NewNode,sizeof(struct PhoneNode));
while(Node -> VanillaNode . ln_Succ)
{
if(Node -> Entry -> Count > NewNode -> Entry -> Count)
{
if(Node == (struct NewNode *)DialList -> lh_Head)
AddHead(DialList,&NewNode -> VanillaNode);
else
Insert(DialList,&NewNode -> VanillaNode,Node -> VanillaNode . ln_Pred);
return;
}
Node = (struct PhoneNode *)Node -> VanillaNode . ln_Succ;
}
AddTail(DialList,&NewNode -> VanillaNode);
}
}
}
VOID
FreeDialList()
{
if(DialList)
{
struct PhoneNode *NextNode,*SubNode;
SubNode = (struct PhoneNode *)DialList -> lh_Head;
while(SubNode -> VanillaNode . ln_Succ)
{
NextNode = (struct PhoneNode *)SubNode -> VanillaNode . ln_Succ;
FreeVec(SubNode);
SubNode = NextNode;
}
FreeVec(DialList);
DialList = NULL;
}
}
/* CreatePhoneList():
*
* Turn the array of pointers to phonebook entries into
* a linked standard Amiga List (gadtools needs this).
*/
struct List *
CreatePhoneList()
{
struct List *PhoneList;
struct PhoneNode *PhoneNode;
LONG i;
if(Phonebook && NumPhoneEntries)
{
if(PhoneList = (struct List *)AllocVec(sizeof(struct List) + NumPhoneEntries * sizeof(struct PhoneNode),MEMF_ANY|MEMF_CLEAR))
{
NewList(PhoneList);
PhoneNode = (struct PhoneNode *)(PhoneList + 1);
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(Phonebook[i] -> Count != -1)
SPrintf(PhoneNode[i] . LocalName,"%3ld - %s",Phonebook[i] -> Count + 1,Phonebook[i] -> Name);
else
SPrintf(PhoneNode[i] . LocalName," %s",Phonebook[i] -> Name);
PhoneNode[i] . VanillaNode . ln_Name = PhoneNode[i] . LocalName;
Phonebook[i] -> Node = &PhoneNode[i];
PhoneNode[i] . Entry = Phonebook[i];
AddTail(PhoneList,&PhoneNode[i]);
}
return(PhoneList);
}
}
else
{
if(PhoneList = (struct List *)AllocVec(sizeof(struct List),MEMF_ANY|MEMF_CLEAR))
{
NewList(PhoneList);
return(PhoneList);
}
}
return(NULL);
}
/* DeletePhoneList(struct List *PhoneList):
*
* Delete the entries listed in the Amiga List
* created by the routine above.
*/
VOID
DeletePhoneList(struct List *PhoneList)
{
if(PhoneList)
{
FreeVec(PhoneList);
PhoneList = NULL;
}
}
/* Compare(struct PhoneEntry **A,struct PhoneEntry **B):
*
* Comparison subroutine required by the QuickSort
* call below.
*/
STATIC LONG __stdargs
Compare(struct PhoneEntry **A,struct PhoneEntry **B)
{
/* Has entry A been selected? */
if((*A) -> Count == -1)
{
/* If entry B isn't selected either, compare the
* names lexically, else entry B is supposed
* to be `smaller' than entry A.
*/
if((*B) -> Count == -1)
return(Stricmp((*A) -> Name,(*B) -> Name));
else
return(1);
}
else
{
/* If entry B isn't selected, entry A is supposed
* to be `smaller' than entry B, else return
* the difference between both entries.
*/
if((*B) -> Count == -1)
return(-1);
else
return((*A) -> Count - (*B) -> Count);
}
}
/* SortPhoneEntries():
*
* Sorts the current phone list array in ascending order.
*/
VOID
SortPhoneEntries()
{
qsort(Phonebook,NumPhoneEntries,sizeof(struct PhoneEntry *),Compare);
}
/* FreeTimeDateNode(struct TimeDateNode *Node):
*
* Free the memory allocated for a TimeDateNode and
* the associated data table.
*/
VOID __regargs
FreeTimeDateNode(struct TimeDateNode *Node)
{
FreeVec(Node -> Table);
FreeVec(Node);
}
/* FreeTimeDateList(struct List *List):
*
* Free a list of TimeDateNodes.
*/
VOID
FreeTimeDateList(struct List *List)
{
struct Node *Node,*NextNode;
Node = List -> lh_Head;
while(NextNode = Node -> ln_Succ)
{
Remove(Node);
FreeTimeDateNode((struct TimeDateNode *)Node);
Node = NextNode;
}
}
/* CopyTimeDateList(struct List *From,struct List *To,BYTE SkipFirst):
*
* Copies the TimeDateNode list from one location into
* another.
*/
VOID
CopyTimeDateList(struct List *From,struct List *To,BYTE SkipFirst)
{
struct TimeDateNode *FromNode,*ToNode;
FromNode = (struct TimeDateNode *)From -> lh_Head;
if(SkipFirst)
FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
while(FromNode -> VanillaNode . ln_Succ)
{
if(ToNode = (struct TimeDateNode *)AllocVec(sizeof(struct TimeDateNode),MEMF_ANY))
{
CopyMem(FromNode,ToNode,sizeof(struct TimeDateNode));
ToNode -> VanillaNode . ln_Name = ToNode -> Buffer;
if(ToNode -> Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * FromNode -> Table[0] . Count,MEMF_ANY))
{
CopyMem(FromNode -> Table,ToNode -> Table,sizeof(struct TimeDate) * FromNode -> Table[0] . Count);
AddTail(To,&ToNode -> VanillaNode);
}
else
FreeVec(ToNode);
}
FromNode = (struct TimeDateNode *)FromNode -> VanillaNode . ln_Succ;
}
}
/* AdaptTimeDateNode(struct TimeDateNode *Node):
*
* Adapt the title and comment of a TimeDateNode.
*/
VOID
AdaptTimeDateNode(struct TimeDateNode *Node)
{
UBYTE *Comment = Node -> Comment[0] ? Node -> Comment : LocaleString(MSG_TERMPHONE_NO_COMMENT_TXT);
if(Node -> Month == -1)
{
if(Node -> Day == -1)
strcpy(Node -> Buffer,LocaleString(MSG_TERMPHONE_STANDARD_SETTINGS_TXT));
else
SPrintf(Node -> Buffer,LocaleString(MSG_TERMPHONE_DAYS_TXT),Comment);
}
else
SPrintf(Node -> Buffer,"%2ld %s » %s",Node -> Day,LocaleString(MSG_TERMPHONE_JAN_TXT + Node -> Month),Comment);
}
/* TimeCompare(struct TimeDate *A,struct TimeDate *B):
*
* Comparison routine required by SortTimeTable().
*/
STATIC LONG __stdargs
TimeCompare(struct TimeDate *A,struct TimeDate *B)
{
return(((LONG)A -> Time) - ((LONG)B -> Time));
}
/* SortTimeTable(struct TimeDateNode *Node):
*
* Sort the time table associated with a
* TimeDateNode in ascending order.
*/
VOID
SortTimeTable(struct TimeDateNode *Node)
{
qsort(Node -> Table,Node -> Table[0] . Count,sizeof(struct TimeDate),TimeCompare);
}
/* BuildTimeList(struct TimeDateNode *Node):
*
* Build a read-to-display time table list from a TimeDateNode.
*/
struct List *
BuildTimeList(struct TimeDateNode *Node)
{
struct List *List;
if(List = (struct List *)AllocVec(sizeof(struct List) + Node -> Table[0] . Count * sizeof(struct TimeNode),MEMF_ANY|MEMF_CLEAR))
{
struct TimeNode *Time = (struct TimeNode *)(List + 1);
LONG i;
NewList(List);
for(i = 0 ; i < Node -> Table[0] . Count ; i++)
{
Time[i] . VanillaNode . ln_Name = Time[i] . Name;
Time[i] . Time = Node -> Table[i] . Time;
SPrintf(Time[i] . Name,"%2ld:%ld0",Time[i] . Time / 6,Time[i] . Time % 6);
AddTail(List,&Time[i]);
}
}
return(List);
}
/* ResizeTimeDateNode(struct TimeDateNode *Node,LONG Count,UBYTE Time):
*
* Resize the time table associated with a TimeDateNode.
*/
BYTE
ResizeTimeDateNode(struct TimeDateNode *Node,LONG Count,UBYTE Time)
{
if(Count != Node -> Table[0] . Count)
{
struct TimeDate *Table;
if(Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * Count,MEMF_ANY|MEMF_CLEAR))
{
LONG i;
CopyMem(Node -> Table,Table,sizeof(struct TimeDate) * Count);
if(Count > Node -> Table[0] . Count)
{
for(i = Node -> Table[0] . Count ; i < Count ; i++)
{
CopyMem(&Node -> Table[0],&Table[i],sizeof(struct TimeDate));
Table[i] . Time = Time;
}
}
for(i = 0 ; i < Count ; i++)
Table[i] . Count = Count;
FreeVec(Node -> Table);
Node -> Table = Table;
return(TRUE);
}
else
return(FALSE);
}
else
return(TRUE);
}
/* DeleteTimeDateNode(struct TimeDateNode *Node,LONG Index):
*
* Delete a single timetable entry from a TimeDateNode.
*/
BYTE
DeleteTimeDateNode(struct TimeDateNode *Node,LONG Index)
{
struct TimeDate *Table;
LONG Count = Node -> Table[0] . Count - 1;
if(Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * Count,MEMF_ANY|MEMF_CLEAR))
{
LONG i,j;
for(i = j = 0 ; i < Node -> Table[0] . Count ; i++)
{
if(i != Index)
{
CopyMem(&Node -> Table[i],&Table[j],sizeof(struct TimeDate));
Table[j++] . Count = Count;
}
}
FreeVec(Node -> Table);
Node -> Table = Table;
return(TRUE);
}
else
return(FALSE);
}
/* CreateTimeDateNode(BYTE Month,BYTE Day,UBYTE *Comment,LONG Count):
*
* Create a new TimeDateNode including time table entries.
*/
struct TimeDateNode *
CreateTimeDateNode(BYTE Month,BYTE Day,UBYTE *Comment,LONG Count)
{
struct TimeDateNode *Node;
if(Node = (struct TimeDateNode *)AllocVec(sizeof(struct TimeDateNode),MEMF_ANY|MEMF_CLEAR))
{
if(Node -> Table = (struct TimeDate *)AllocVec(sizeof(struct TimeDate) * Count,MEMF_ANY|MEMF_CLEAR))
{
Node -> VanillaNode . ln_Name = Node -> Buffer;
Node -> Month = Month;
Node -> Day = Day;
Node -> Table[0] . PayPerUnit[DT_FIRST_UNIT] = 23;
Node -> Table[0] . SecPerUnit[DT_FIRST_UNIT] = 6 * 60;
Node -> Table[0] . PayPerUnit[DT_NEXT_UNIT] = 23;
Node -> Table[0] . SecPerUnit[DT_NEXT_UNIT] = 6 * 60;
Node -> Table[0] . Time = DT_GET_TIME( 8,0);
Node -> Table[0] . Count = Count;
if(Count > 1)
{
Node -> Table[1] . PayPerUnit[DT_FIRST_UNIT] = 23;
Node -> Table[1] . SecPerUnit[DT_FIRST_UNIT] = 12 * 60;
Node -> Table[1] . PayPerUnit[DT_NEXT_UNIT] = 23;
Node -> Table[1] . SecPerUnit[DT_NEXT_UNIT] = 12 * 60;
Node -> Table[1] . Time = DT_GET_TIME(18,0);
Node -> Table[1] . Count = Count;
}
strcpy(Node -> Comment,Comment);
AdaptTimeDateNode(Node);
return(Node);
}
else
FreeVec(Node);
}
return(NULL);
}
/* RemPhoneEntry(LONG Num):
*
* Remove a given entry from the phone book.
*/
VOID
RemPhoneEntry(LONG Num)
{
struct PhoneEntry *Entry;
LONG i;
Entry = Phonebook[Num];
for(i = Num ; i < NumPhoneEntries ; i++)
Phonebook[i] = Phonebook[i + 1];
Phonebook[NumPhoneEntries--] = NULL;
FreeTimeDateList((struct List *)&Entry -> TimeDateList);
FreeVec(Entry);
}
/* NewPhoneEntry():
*
* Create a new phone book entry with default values and
* add it to the array. Expand the phone book if necessary.
*/
BYTE
NewPhoneEntry()
{
struct PhoneEntry **PrivatePhonebook;
LONG PrivatePhoneSize;
LONG i;
/* The phone book is filled `to the brim', so let's expand
* it.
*/
if(NumPhoneEntries + 1 > PhoneSize)
{
/* Allocate another phone book. */
if(PrivatePhonebook = CreatePhonebook(PhoneSize + 1,&PrivatePhoneSize,FALSE))
{
/* Copy the data. */
if(Phonebook && PhoneSize)
{
for(i = 0 ; i < PhoneSize ; i++)
PrivatePhonebook[i] = Phonebook[i];
/* Remove the old phonebook. */
DeletePhonebook(Phonebook,PhoneSize,FALSE);
}
/* Assign the new pointers. */
Phonebook = PrivatePhonebook;
PhoneSize = PrivatePhoneSize;
}
else
return(FALSE);
}
/* Allocate another entry and add it to the phone book. */
if(Phonebook[NumPhoneEntries] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry),MEMF_ANY|MEMF_CLEAR))
{
struct TimeDateNode *TimeDateNode;
strcpy(Phonebook[NumPhoneEntries] -> Name,LocaleString(MSG_TERMPHONE_UNUSED_ENTRY_TXT));
CopyMem(&Config,&Phonebook[NumPhoneEntries] -> Config,sizeof(struct Configuration));
Phonebook[NumPhoneEntries] -> Count = -1;
NewList((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList);
if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
AddTail((struct List *)&Phonebook[NumPhoneEntries] -> TimeDateList,&TimeDateNode -> VanillaNode);
NumPhoneEntries++;
return(TRUE);
}
return(FALSE);
}
/* CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries):
*
* Create a new phone entry array (so-called phone book).
*/
struct PhoneEntry **
CreatePhonebook(LONG Size,LONG *AllocSize,BYTE CreateEntries)
{
struct PhoneEntry **PhoneEntry = NULL;
if(Size)
{
/* Round the number of phone entries to a
* multiple of eight.
*/
*AllocSize = (((Size + 7) >> 3) << 3);
/* Create the list of pointers. */
if(PhoneEntry = (struct PhoneEntry **)AllocVec(*AllocSize * sizeof(struct PhoneEntry *),MEMF_ANY|MEMF_CLEAR))
{
/* And create some entries if necessary. */
if(CreateEntries)
{
LONG i;
for(i = 0 ; i < Size ; i++)
{
if(!(PhoneEntry[i] = (struct PhoneEntry *)AllocVec(sizeof(struct PhoneEntry),MEMF_ANY|MEMF_CLEAR)))
{
LONG j;
for(j = 0 ; j < i ; j++)
FreeVec(PhoneEntry[j]);
FreeVec(PhoneEntry);
return(NULL);
}
else
NewList((struct List *)&PhoneEntry[i] -> TimeDateList);
}
}
}
}
return(PhoneEntry);
}
/* DeletePhonebook(struct PhoneEntry **PhoneBook,LONG Size,BYTE FreeEntries):
*
* Deallocates a given phone book and its entries if necessary.
*/
VOID
DeletePhonebook(struct PhoneEntry **Phonebook,LONG Size,BYTE FreeEntries)
{
if(FreeEntries)
{
LONG i;
for(i = 0 ; i < Size ; i++)
{
if(Phonebook[i])
{
FreeTimeDateList((struct List *)&Phonebook[i] -> TimeDateList);
FreeVec(Phonebook[i]);
}
}
}
FreeVec(Phonebook);
}
/* SavePhonebook(UBYTE *Name):
*
* Save the current phone book to a disk file.
*/
BYTE
SavePhonebook(UBYTE *Name)
{
struct IFFHandle *Handle;
BYTE Success = FALSE;
if(Phonebook && NumPhoneEntries)
{
if(Handle = (struct IFFHandle *)AllocIFF())
{
if(Handle -> iff_Stream = Open(Name,MODE_NEWFILE))
{
InitIFFasDOS(Handle);
if(!OpenIFF(Handle,IFFF_WRITE))
{
if(!PushChunk(Handle,'TERM',ID_CAT,IFFSIZE_UNKNOWN))
{
if(!PushChunk(Handle,'TERM',ID_FORM,IFFSIZE_UNKNOWN))
{
if(!PushChunk(Handle,0,'VERS',IFFSIZE_UNKNOWN))
{
struct TermInfo TermInfo;
TermInfo . Version = TermVersion;
TermInfo . Revision = TermRevision;
if(WriteChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
{
if(PopChunk(Handle))
Success = FALSE;
else
{
UBYTE *TempBuffer = NULL;
if(PhonePasswordUsed)
{
if(!PushChunk(Handle,0,'PSWD',20))
{
Success = TRUE;
if(WriteChunkBytes(Handle,PhonePassword,20) != 20)
Success = FALSE;
if(PopChunk(Handle))
Success = FALSE;
if(Success)
{
if(!(TempBuffer = AllocVec(RAWSIZE,MEMF_ANY)))
Success = FALSE;
}
}
}
else
Success = TRUE;
if(Success)
{
Success = FALSE;
if(!PushChunk(Handle,0,'DIAL',IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(Handle,&NumPhoneEntries,sizeof(LONG)) == sizeof(LONG))
{
if(PopChunk(Handle))
Success = FALSE;
else
{
if(PopChunk(Handle))
Success = FALSE;
else
{
LONG i;
for(i = 0 ; i < NumPhoneEntries ; i++)
{
if(!PushChunk(Handle,'TERM',ID_FORM,IFFSIZE_UNKNOWN))
{
if(!PushChunk(Handle,0,'PREF',IFFSIZE_UNKNOWN))
{
if(TempBuffer)
{
Encrypt((UBYTE *)Phonebook[i] -> Name,RAWSIZE,TempBuffer,PhonePassword,20,TRUE);
if(WriteChunkBytes(Handle,TempBuffer,RAWSIZE) != RAWSIZE)
{
Success = FALSE;
break;
}
else
Success = TRUE;
}
else
{
if(WriteChunkBytes(Handle,Phonebook[i] -> Name,RAWSIZE) != RAWSIZE)
{
Success = FALSE;
break;
}
else
Success = TRUE;
}
if(PopChunk(Handle))
{
Success = FALSE;
break;
}
}
if(Success)
{
struct TimeDateNode *TimeDateNode;
TimeDateNode = (struct TimeDateNode *)Phonebook[i] -> TimeDateList . mlh_Head;
while(TimeDateNode -> VanillaNode . ln_Succ)
{
if(!PushChunk(Handle,0,'DATE',IFFSIZE_UNKNOWN))
{
if(WriteChunkBytes(Handle,TimeDateNode -> Comment,DATEHEADERSIZE) != DATEHEADERSIZE)
{
Success = FALSE;
break;
}
else
{
if(WriteChunkBytes(Handle,TimeDateNode -> Table,TimeDateNode -> Table[0] . Count * sizeof(struct TimeDate)) != TimeDateNode -> Table[0] . Count * sizeof(struct TimeDate))
{
Success = FALSE;
break;
}
}
if(PopChunk(Handle))
{
Success = FALSE;
break;
}
TimeDateNode = (struct TimeDateNode *)TimeDateNode -> VanillaNode . ln_Succ;
}
}
}
if(PopChunk(Handle))
{
Success = FALSE;
break;
}
}
}
}
}
}
}
if(TempBuffer)
FreeVec(TempBuffer);
}
}
}
}
}
if(PopChunk(Handle))
Success = FALSE;
}
CloseIFF(Handle);
}
Close(Handle -> iff_Stream);
}
FreeIFF(Handle);
}
if(Success)
SetProtection(Name,FIBF_EXECUTE);
else
DeleteFile(Name);
}
return(Success);
}
/* OldLoadPhonebook(UBYTE *Name):
*
* Restore a phone book from a disk file (old version).
*/
STATIC BYTE __regargs
OldLoadPhonebook(UBYTE *Name)
{
struct PhoneEntry **PrivatePhonebook;
LONG PrivatePhoneSize;
LONG Size,i;
struct IFFHandle *Handle;
BYTE Success = FALSE;
struct StoredProperty *Prop;
struct TermInfo *TermInfo;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
{
InitIFFasDOS(Handle);
if(!OpenIFF(Handle,IFFF_READ))
{
if(!PropChunks(Handle,&VersionProps[0],1))
{
if(!StopChunk(Handle,'TERM','DIAL'))
{
if(!ParseIFF(Handle,IFFPARSE_SCAN))
{
if(Prop = FindProp(Handle,'TERM','VERS'))
{
TermInfo = (struct TermInfo *)Prop -> sp_Data;
if(TermInfo -> Version == 1 && TermInfo -> Revision >= 6)
{
if(ReadChunkRecords(Handle,&Size,sizeof(LONG),1))
{
if(Size)
{
if(PrivatePhonebook = CreatePhonebook(Size,&PrivatePhoneSize,TRUE))
{
struct ContextNode *Chunk;
LONG ItemSize;
struct TimeDateNode *TimeDateNode;
Chunk = CurrentChunk(Handle);
ItemSize = Chunk -> cn_Size / Size;
for(i = 0 ; i < Size ; i++)
{
SetPrefToDefaults(&PrivatePhonebook[i] -> Config,NULL);
if(ReadChunkRecords(Handle,PrivatePhonebook[i] -> Name,ItemSize,1))
{
UpdatePrefs(&PrivatePhonebook[i] -> Config);
PrivatePhonebook[i] -> Count = -1;
if(strlen(PrivatePhonebook[i] -> Password) > 19)
{
PrivatePhonebook[i] -> Password[19] = 0;
PrivatePhonebook[i] -> UserName[ 0] = 0;
}
if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
AddTail((struct List *)&PrivatePhonebook[i] -> TimeDateList,&TimeDateNode -> VanillaNode);
}
else
{
if(i)
Size = i - 1;
else
Size = 0;
break;
}
}
if(Size)
{
if(Phonebook)
DeletePhonebook(Phonebook,PhoneSize,TRUE);
Phonebook = PrivatePhonebook;
PhoneSize = PrivatePhoneSize;
NumPhoneEntries = Size;
Success = TRUE;
}
else
{
DeletePhonebook(PrivatePhonebook,PrivatePhoneSize,TRUE);
Success = FALSE;
}
FreeDialList();
}
}
}
}
}
}
}
}
CloseIFF(Handle);
}
Close(Handle -> iff_Stream);
}
FreeIFF(Handle);
}
return(Success);
}
/* LoadPhonebook(UBYTE *Name):
*
* Restore a phone book from a disk file.
*/
BYTE
LoadPhonebook(UBYTE *Name)
{
STATIC ULONG Stops[2 * 7] =
{
'TERM','VERS',
'TERM','DIAL',
'TERM','PREF',
'TERM','DATE',
'TERM','TIME',
'TERM','PASS',
'TERM','PSWD'
};
struct PhoneEntry **PrivatePhonebook;
LONG PrivatePhoneSize = 0;
LONG Size = 0,i,j,Last = -1;
struct IFFHandle *Handle;
BYTE Success = FALSE;
struct ContextNode *Chunk;
BYTE UseOld = FALSE,
LastHadTime = TRUE,
HadPassword = FALSE,
NewStyle = TRUE;
struct TimeDateNode *TimeDateNode;
if(Handle = AllocIFF())
{
if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
{
InitIFFasDOS(Handle);
if(!OpenIFF(Handle,IFFF_READ))
{
if(!StopChunks(Handle,&Stops[0],7))
{
while(!ParseIFF(Handle,IFFPARSE_SCAN))
{
Chunk = CurrentChunk(Handle);
if(Chunk -> cn_ID == 'VERS')
{
struct TermInfo TermInfo;
if(ReadChunkBytes(Handle,&TermInfo,sizeof(struct TermInfo)) == sizeof(struct TermInfo))
{
if(TermInfo . Version == 1 && TermInfo . Revision < 9)
{
UseOld = TRUE;
break;
}
if((TermInfo . Version > TermVersion) || (TermInfo . Version == TermVersion && TermInfo . Revision > TermRevision) || (TermInfo . Version == 1 && TermInfo . Revision < 6))
break;
}
else
break;
}
if(Chunk -> cn_ID == 'PASS')
{
UBYTE DummyBuffer[20];
HadPassword = TRUE;
if(ReadChunkBytes(Handle,DummyBuffer,20) == 20)
{
if(PhonePasswordUsed)
{
if(!memcmp(PhonePassword,DummyBuffer,20))
continue;
}
memset(SharedBuffer,0,20);
if(CryptPanel(SharedBuffer))
{
UBYTE AnotherBuffer[20];
Encrypt(SharedBuffer,20,AnotherBuffer,SharedBuffer,20,NewStyle = FALSE);
if(!memcmp(DummyBuffer,AnotherBuffer,20))
{
memcpy(PhonePassword,DummyBuffer,20);
PhonePasswordUsed = TRUE;
continue;
}
else
{
MyEasyRequest(Window,LocaleString(MSG_TERMPHONE_WRONG_PASSWORD_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Name);
break;
}
}
else
break;
}
else
break;
}
if(Chunk -> cn_ID == 'PSWD')
{
UBYTE DummyBuffer[20];
HadPassword = TRUE;
if(ReadChunkBytes(Handle,DummyBuffer,20) == 20)
{
if(PhonePasswordUsed)
{
if(!memcmp(PhonePassword,DummyBuffer,20))
continue;
}
memset(SharedBuffer,0,20);
if(CryptPanel(SharedBuffer))
{
UBYTE AnotherBuffer[20];
Encrypt(SharedBuffer,20,AnotherBuffer,SharedBuffer,strlen(SharedBuffer),NewStyle = TRUE);
if(!memcmp(DummyBuffer,AnotherBuffer,20))
{
memcpy(PhonePassword,DummyBuffer,20);
PhonePasswordUsed = TRUE;
continue;
}
else
{
MyEasyRequest(Window,LocaleString(MSG_TERMPHONE_WRONG_PASSWORD_TXT),LocaleString(MSG_GLOBAL_CONTINUE_TXT),Name);
break;
}
}
else
break;
}
else
break;
}
if(Chunk -> cn_ID == 'DIAL')
{
if(ReadChunkBytes(Handle,&Size,sizeof(LONG)) == sizeof(LONG))
{
i = 0;
if(!(PrivatePhonebook = CreatePhonebook(Size,&PrivatePhoneSize,TRUE)))
break;
}
else
break;
}
if(Chunk -> cn_ID == 'PREF')
{
if(Last != -1)
{
if(strlen(PrivatePhonebook[i] -> Password) > 19)
{
PrivatePhonebook[i] -> Password[19] = 0;
PrivatePhonebook[i] -> UserName[ 0] = 0;
}
if(!LastHadTime)
{
if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
AddTail((struct List *)&PrivatePhonebook[Last] -> TimeDateList,&TimeDateNode -> VanillaNode);
}
}
if(Size && i < Size)
{
WORD LastSize = sizeof(struct PhoneEntry);
PhonePasswordUsed = HadPassword;
if(Chunk -> cn_Size < LastSize)
LastSize = Chunk -> cn_Size;
SetPrefToDefaults(&PrivatePhonebook[i] -> Config,NULL);
if(ReadChunkBytes(Handle,PrivatePhonebook[i] -> Name,LastSize) == LastSize)
{
UpdatePrefs(&PrivatePhonebook[i] -> Config);
if(PhonePasswordUsed)
Decrypt((UBYTE *)PrivatePhonebook[i] -> Name,LastSize,PrivatePhonebook[i] -> Name,PhonePassword,20,NewStyle);
Last = i;
PrivatePhonebook[i] -> Count = -1;
i++;
LastHadTime = FALSE;
}
else
{
if(i)
Size = i - 1;
else
Size = 0;
break;
}
}
}
if(Chunk -> cn_ID == 'TIME')
{
if(Last != -1)
{
struct TimeDateOld TimeDateOld;
for(j = 0 ; j < Chunk -> cn_Size / sizeof(struct TimeDateOld) ; j++)
{
if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
{
if(ReadChunkBytes(Handle,&TimeDateOld,sizeof(struct TimeDateOld)) == sizeof(struct TimeDateOld))
{
if(PhonePasswordUsed)
Decrypt((UBYTE *)&TimeDateOld,sizeof(struct TimeDateOld),(UBYTE *)&TimeDateOld,PhonePassword,20,NewStyle);
strcpy(TimeDateNode -> Comment,TimeDateOld . Comment);
TimeDateNode -> Month = TimeDateOld . Month;
TimeDateNode -> Day = TimeDateOld . Day;
TimeDateNode -> Table[0] . PayPerUnit[0] = TimeDateOld . PayPerUnit[0];
TimeDateNode -> Table[0] . SecPerUnit[0] = TimeDateOld . SecPerUnit[0];
TimeDateNode -> Table[0] . PayPerUnit[1] = TimeDateOld . PayPerUnit[0];
TimeDateNode -> Table[0] . SecPerUnit[1] = TimeDateOld . SecPerUnit[0];
TimeDateNode -> Table[0] . Time = TimeDateOld . TimeOfDay[0];
TimeDateNode -> Table[1] . PayPerUnit[0] = TimeDateOld . PayPerUnit[1];
TimeDateNode -> Table[1] . SecPerUnit[0] = TimeDateOld . SecPerUnit[1];
TimeDateNode -> Table[1] . PayPerUnit[1] = TimeDateOld . PayPerUnit[1];
TimeDateNode -> Table[1] . SecPerUnit[1] = TimeDateOld . SecPerUnit[1];
TimeDateNode -> Table[1] . Time = TimeDateOld . TimeOfDay[1];
AdaptTimeDateNode(TimeDateNode);
AddTail((struct List *)&PrivatePhonebook[Last] -> TimeDateList,&TimeDateNode -> VanillaNode);
LastHadTime = TRUE;
}
}
}
}
}
if(Chunk -> cn_ID == 'DATE')
{
if(Last != -1)
{
WORD Count = (Chunk -> cn_Size - DATEHEADERSIZE) / sizeof(struct TimeDate);
if(TimeDateNode = CreateTimeDateNode(-1,-1,"",Count))
{
if(ReadChunkBytes(Handle,TimeDateNode -> Comment,DATEHEADERSIZE) == DATEHEADERSIZE)
{
if(ReadChunkBytes(Handle,TimeDateNode -> Table,sizeof(struct TimeDate) * Count) == sizeof(struct TimeDate) * Count)
{
AdaptTimeDateNode(TimeDateNode);
AddTail((struct List *)&PrivatePhonebook[Last] -> TimeDateList,&TimeDateNode -> VanillaNode);
LastHadTime = TRUE;
}
else
FreeTimeDateNode(TimeDateNode);
}
else
FreeTimeDateNode(TimeDateNode);
}
}
}
}
if(Size)
{
if(!LastHadTime && Last != -1)
{
if(TimeDateNode = CreateTimeDateNode(-1,-1,"",2))
AddTail((struct List *)&PrivatePhonebook[Last] -> TimeDateList,&TimeDateNode -> VanillaNode);
}
if(Phonebook)
DeletePhonebook(Phonebook,PhoneSize,TRUE);
Phonebook = PrivatePhonebook;
PhoneSize = PrivatePhoneSize;
NumPhoneEntries = Size;
Success = TRUE;
}
else
{
if(PrivatePhoneSize)
{
DeletePhonebook(PrivatePhonebook,PrivatePhoneSize,TRUE);
Success = FALSE;
}
}
FreeDialList();
}
CloseIFF(Handle);
}
Close(Handle -> iff_Stream);
}
FreeIFF(Handle);
}
if(UseOld)
Success = OldLoadPhonebook(Name);
return(Success);
}