home *** CD-ROM | disk | FTP | other *** search
- /*
-
- todo
- ====
-
- remove LIBCountListItems(), replace with HBBS_NodesInList() :-)
-
- */
-
- #define HBBSCOMMON
- #define MAIN
-
- #include <ctype.h>
- #include <time.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include <exec/exec.h>
- #include <exec/types.h>
-
- #include <dos/dos.h>
- #include <dos/dostags.h>
- #include <dos/filehandler.h>
- #include <dos/dosextens.h>
-
- #include <libraries/reqtools.h>
-
-
- #include <clib/exec_protos.h>
- #include <clib/dos_protos.h>
- #include <clib/alib_protos.h>
- #include <clib/reqtools_protos.h>
-
- #include <pragmas/exec_pragmas.h>
- #include <pragmas/dos_pragmas.h>
- #include <pragmas/reqtools.h>
-
-
- #include "/common/types.h"
- #include "/common/errors.h"
- #include "/common/defines.h"
- #include "/common/structures.h"
- #include "/common/strings.h"
- #include "/common/files.h"
-
- // some forward defines
-
- void __asm __saveds LIBstrNcpy(register __a0 UBYTE *dest,register __a1 UBYTE *source,register __d0 int chars);
- void __asm __saveds LIBHBBS_rterror(register __a0 char *str);
- BOOL __asm __saveds LIBAssignOK(register __a0 char *checkme );
- BOOL __asm __saveds LIBHBBS_AddCfgItem(register __a0 struct CfgFileData *cfgfile,register __a1 UBYTE *itemname,register __a2 UBYTE *params);
- struct List __asm __saveds *LIBHBBS_CreateList( void );
- void __asm __saveds LIBHBBS_DateStrFromTM(register __a0 UBYTE *datestr, register __a1 struct tm *timestruct);
- V_BOOL __asm __saveds LIBHBBS_AddCfgItemQuick(register __a0 struct CfgFileData *cfgfile,register __a1 char *ItemName, register __a2 char *Params);
- void __asm __saveds LIBHBBS_FlushConfig(register __a0 struct CfgFileData *cfgfile);
- BOOL __asm __saveds LIBPathOK(register __a0 char *str);
-
- // needed libs..
-
- struct DosLibrary *DOSBase=NULL;
- struct ExecBase *SysBase=NULL;
- struct ReqToolsBase *ReqToolsBase=NULL;
-
- // global variables.. (keep to a minimum..)
-
- struct BBSGlobalData *BBSGlobal=NULL;
-
- UBYTE *OPT_PRIV_LastUserNum="LastUserNum";
-
- char monthstr[12][4]={"JAN","FEB","MAR","APR","MAY","JUN","JUL","AUG","SEP","OCT","NOV","DEC"};
-
-
- // actual functions..
-
- void __asm __saveds LIBFreeStr(register __a0 char *str)
- {
- if (str) FreeVec(str);
- }
-
- char __asm __saveds *LIBDupStr(register __a0 char *str)
- {
- char *newstr=NULL;
- if (str)
- {
- if (newstr=(char *)AllocVec(strlen(str)+1,MEMF_PUBLIC))
- {
- newstr[0]=0;
- strcpy(newstr,str);
- }
- }
- return(newstr);
- }
-
- char __asm __saveds *LIBFreeAndSet(register __a0 char **varname,register __a1 char *newstr)
- {
- // this routines frees memory allocated to strings using strdup or
- // and duplicates the string in newstr and sets varname to the newly allocated str
-
- if (*varname!=NULL)
- {
- LIBFreeStr(*varname);
- *varname=NULL;
- }
-
- if (newstr)
- {
- *varname=LIBDupStr(newstr);
- }
- return(*varname); // return varname if you want to test result..
- }
-
-
- V_BOOL __asm __saveds LIBCheckBoolean(register __a0 char *str)
- {
- if (stricmp(str,"TRUE")==0 || stricmp(str,"ON")==0 || stricmp(str,"YES")==0)
- return(TRUE);
- else
- return(FALSE);
- }
-
-
- // creates a new node with ln_Name set to a copy of str, and appends it to the list specified
-
- V_ERROR __asm __saveds LIBNewStrNode(register __a0 char *str,register __a1 struct List *list)
- {
- struct Node *NewNode;
- V_ERROR retval=TYPE_MEMORY;
-
- if (NewNode=AllocVec(sizeof(struct Node),MEMF_PUBLIC))
- {
- if (NewNode->ln_Name=LIBDupStr(str))
- {
- AddTail(list,NewNode);
- retval=ERR_NO_ERROR;
- }
- else
- {
- FreeVec(NewNode);
- }
- }
- return(retval);
- }
-
- void __asm __saveds LIBUpperCase(register __a0 char *str)
- {
- // converts str into uppercase
-
- short loop;
-
- for (loop=0;str[loop];loop++) str[loop]=toupper(str[loop]);
- }
-
- char __asm __saveds *LIBupcase(register __a0 char *str)
- {
- // converts str into uppercase and returns a pointer to a new
- // string.
- // returns NULL if it fails.
-
- // dont forget to FreeStr() the output!
-
- char *outstr=NULL;
- short loop;
-
- if (outstr=LIBDupStr(str))
- {
- for (loop=0;str[loop];loop++) outstr[loop]=toupper(str[loop]);
- }
- return(outstr);
- }
-
- short __asm __saveds LIBposition(register __a0 char *substr,register __a1 char *str)
- {
- // returns an character offset of a substring in a string
- // this version is CASE SENSITIVE
- // returns -1 if substring not found in the string
-
- char *whstr;
- return((short)((whstr=strstr(str,substr)) ? (short)((LONG)whstr-(LONG)str) : -1));
- }
-
- short __asm __saveds LIBiposition(register __a0 char *substr,register __a1 char *str)
- {
- // returns an character offset of a substring in a string
- // this version is CASE INSENSITIVE
- // returns -1 if substring not found in the string
- // or -2 if memory allocation error
-
- short where=-2;
- char *isubstr,*istr;
-
- if (isubstr=LIBupcase(substr))
- {
- if (istr=LIBupcase(str))
- {
- where=LIBposition(isubstr,istr);
- LIBFreeStr(istr);
- }
- LIBFreeStr(isubstr);
- }
- return(where);
- }
-
- void __asm __saveds LIBstrfcpy(register __a0 char *dest,register __a1 char *source,register __d0 int from)
- {
- /*
- copy all chars from "source" to "dest" starting at offset "from"
- (kinda the reverse from strncpy() )
- */
- int loop=from,pos=0;
- if (from<=strlen(source)-1)
- {
- while (source[loop])
- {
- dest[pos]=source[loop];
- loop++;
- pos++;
- }
- }
- dest[pos]=0;
- }
-
- void __asm __saveds LIBstripcr(register __a0 char *s)
- {
- /* New Optimized Version 04-JAN-1996 */
-
- LONG Len;
- if (s)
- {
- Len=strlen(s)-1; // set to point to last char in string 's'
-
- while (Len>=0 && (s[Len]=='\r' || s[Len]=='\n'))
- {
- s[Len--]=0; // string is now 1 char smaller, and overwrite the \r or \n with a null terminator
- }
- }
- }
-
- /* old version, had problems with small strings!
- void __asm __saveds LIBstripcr(register __a0 char *s)
- {
- // caters for \n or \r or \r\n or \n\r :-)
-
- short sl;
- sl=strlen(s);
- if (s[sl-1]==10 || s[sl-1]==13) s[sl-1]=0;
- sl=strlen(s);
- if (s[sl-1]==10 || s[sl-1]==13) s[sl-1]=0;
- // hmm ? how about a for next loop there ? nah, bigger.. slower...
- }
- */
-
-
- UBYTE __asm __saveds *LIBStripComments(register __a0 char *s)
- {
- /* New Optimized Version 04-JAN-1996 */
-
- // returns a pointer to the start of the comments too..
-
- UBYTE *strptr;
-
- if (strptr=strchr(s,';'))
- {
- *strptr=0;
- strptr++; //we've just killed the ';' so point to next char..
- }
- return(strptr);
- }
-
- /* older version. allocated memory!!
- UBYTE __asm __saveds *LIBStripComments(register __a0 char *s)
- {
- // returns a pointer to the start of the comments too..
- int where;
-
- if ((where=LIBposition(";",s))>=0)
- {
- s[where]='\0';
- return(&s[where+1]); // return pointer to character after the ; in the string
- }
- return(NULL);
- }
- */
-
- void __asm __saveds LIBStripSpaces(register __a0 char *s)
- {
- /* New Optimized Version 04-JAN-1996 */
- /* this version only parses the string once, much nicer.. */
-
- LONG len=strlen(s)-1;
-
- // while the last char is a ' ', set it to a 0
- while (len>=0 && s[len]==' ') s[len--]=0; // cooler Kompakt coding! :-)
- }
-
- /* old version, too slow, keeps parsing strings..
- void __asm __saveds LIBStripSpaces(register __a0 char *s)
- {
- // while the last char is a ' ', set it to a 0
- while (s[strlen(s)-1]==' ') s[strlen(s)-1]=0; // Kompakt coding! :-)
- }
- */
- void __asm __saveds LIBreplace(register __a0 char *dest,register __a1 char *compare,register __a2 char *from,register __a3 char *to)
- {
-
- /*
- replace all occurences of "from" in "compare" with "to" and store result in "dest"
- (note: this is dead usefull!!!)
- */
- int where;
- char *mystring;
-
- if (mystring=LIBDupStr(compare))
- {
- strcpy(dest,"");
- do
- {
- where=LIBposition(from,mystring);
- if (where!=-1)
- {
- strncat(dest,mystring,where); /* copy first part of string */
- strcat(dest,to); /* add repeaced chars */
- LIBstrfcpy(mystring,mystring,where+strlen(from)); /* copy rest of string so we find first position of from */
- }
- } while (where!=-1); /* keep doing until "from" is not found */
- strcat(dest,mystring); /* add the rest of the string */
- LIBFreeStr(mystring);
- }
- }
-
-
- BOOL __asm __saveds LIBGetParams(register __a0 char *dest,register __a1 char *source)
- {
- UBYTE *strptr=NULL;
-
- dest[0]=0;
-
- if (strptr=strchr(source,'='))
- {
- strcpy(dest,strptr+1);
- return(TRUE);
- }
- return(FALSE);
- }
-
- /* old version, shite...
- BOOL __asm __saveds LIBGetParams(register __a0 char *dest,register __a1 char *source)
- {
- int where;
-
- dest[0]=0;
-
- // if ( ((where=LIBposition("=",source))!=-1) && (where!=(strlen(source)-1)) )
-
- if ((where=LIBposition("=",source))>=0)
- {
- LIBstrfcpy(dest,source,where+1);
- return(TRUE);
- }
- return(FALSE);
- }
- */
-
-
- BOOL __asm __saveds LIBGetItem(register __a0 char *dest,register __a1 char *source)
- {
- int loop=0;
-
- // increment start counter until we encounter a character that's not a space or tab
-
- while (source[loop]==' ' || source[loop]==8) loop++;
-
- while (source[loop] && source[loop]!='=') // not end of string && '=' ?
- {
- dest[loop]=source[loop];
- loop++;
- }
- dest[loop]='\0';
- if (dest[0]!=0) return(TRUE);
-
- return(FALSE);
- }
-
- void __asm __saveds LIBGetNumber(register __a0 int *num,register __a1 char *item)
- {
- int where;
- char numstr[5];
- for (where=strlen(item);isdigit(item[where-1]);where--);
-
- LIBstrfcpy(numstr,item,where);
- *num=atoi(numstr);
- }
-
-
- ULONG __asm __saveds LIBSafePutToPort(register __a0 struct Message *message, register __a1 STRPTR portname)
- {
- struct MsgPort *port;
- Forbid();
- if (port=FindPort(portname))
- {
- PutMsg(port,message);
- }
- Permit();
- return((ULONG)port);
- }
-
- // new: if message you are sending has a reply port, it'll return a pointer to the replied
- // message, other wise it'll return 1.
- // it will ALWAYS return NULL if it fails to send the message tho..
-
- struct Message __asm __saveds *LIBSendMessage(register __a0 struct Message *Msg,register __a1 char *MPortName)
- {
- // BOOL waitforreply=(Msg->mn_ReplyPort) ? TRUE : FALSE;
-
- if (LIBSafePutToPort(Msg,MPortName))
- {
- // if (waitforreply)
- if (Msg->mn_ReplyPort)
- {
- if (1L << Msg->mn_ReplyPort->mp_SigBit==Wait(1L << Msg->mn_ReplyPort->mp_SigBit))
- {
- return(GetMsg(Msg->mn_ReplyPort));
- }
- }
- else return((struct Message *)1L);
- }
- return(NULL);
- }
-
- V_BIGNUM __asm __saveds LIBCountListItems( register __a0 struct List *list)
- {
- V_BIGNUM retval=0;
- struct Node *node;
-
- if (list)
- {
- for (node = list->lh_Head ; node->ln_Succ ; node =node->ln_Succ)
- {
- retval++;
- }
- }
- return(retval);
- }
-
- void __asm __saveds LIBFreeStrList(register __a0 V_STRINGLIST strlist)
- {
- // free all strings in a list and remove all nodes from the list.
- // then free the nodes and the list itself..
-
- struct Node *node;
- if (strlist)
- {
- while (strlist->lh_Head->ln_Succ)
- {
- node=strlist->lh_Head;
- LIBFreeStr(node->ln_Name);
- Remove(node);
- FreeVec(node);
- }
- FreeVec(strlist);
- }
- }
-
- struct BBSGlobalData __asm __saveds *LIBHBBS_GimmeBBS( void )
- {
- return(BBSGlobal);
- }
-
- void __asm __saveds LIBHBBS_SetBBS(register __a0 struct BBSGlobalData *B)
- {
- BBSGlobal=B;
- }
-
- struct Node __asm __saveds *LIBGetNode(register __a0 struct List *lh,register __d0 UWORD n)
- { // starts from 0, 0 being the first node in the list..
- // thanks to the author of YAK for this and the next function..
- struct Node *ln;
-
- for (ln = lh->lh_Head; n--; ln = ln->ln_Succ);
- return ln;
- }
-
- UWORD __asm __saveds LIBGetNodeNum(register __a0 struct List *lh,register __a1 struct Node *node)
- {
- struct Node *ln;
- UWORD i;
-
- for (i = 0, ln = lh->lh_Head; ln != node; ln = ln->ln_Succ, i++);
- return i;
- }
-
- struct NodeData __asm __saveds *LIBHBBS_NodeDataPtr(register __d0 short nodenum)
- {
- struct NodeData *nd;
-
- for (nd = (struct NodeData *)BBSGlobal->NodeList->lh_Head ; nd->node.ln_Succ ; nd =(struct NodeData *) nd->node.ln_Succ)
- {
- if (nd->NodeNum==nodenum) return(nd);
- }
- return(NULL);
- }
-
-
- V_ERROR __asm __saveds LIBHBBS_LogError(register __a0 V_STRING filename,register __d0 V_ERROR errnum,register __a1 V_STRING string,register __d1 V_ERROR errtype)
- {
- // this function returns the parameter errnum supplied and unmodified.
- BPTR FH;
- V_STRING errstr;
- struct tm *tp;
- long t;
-
- if (filename)
- {
- if (FH=Open(filename,MODE_READWRITE))
- {
- Seek(FH,0,OFFSET_END);
- if (errstr=AllocVec(BIG_STR,MEMF_PUBLIC))
- {
- time(&t);
- tp=localtime(&t);
- sprintf(errstr,"%s Error\n"
- "%s"
- "Details:\n",TYPE_STR[errtype],asctime(tp));
-
- Write(FH,errstr,strlen(errstr)); // don't care if it fails.. (could be diskfull :-)
-
- switch(errnum)
- {
- case ERR_ERROR_OPENING:
- sprintf(errstr,"Error opening the file -> %s",string);
- break;
- case ERR_ERROR_READING:
- sprintf(errstr,"Error reading the file -> %s",string);
- break;
- case ERR_ERROR_WRITING:
- sprintf(errstr,"Error writing the file -> %s",string);
- break;
- case ERR_NODESETTINGS:
- strcpy(errstr,"NodeLocal File Error");
- break;
- case ERR_GENERAL:
- strcpy(errstr,string);
- break;
- case ERR_DOORTIMEOUT:
- sprintf(errstr,"Timout Occured When Loading Door -> %s",string);
- break;
- default:
- sprintf(errstr,"Unknown Error!\n");
- break;
- }
- Write(FH,errstr,strlen(errstr));
-
- Write(FH,"\n***\n",5);
-
- FreeVec(errstr);
- }
- Close(FH);
- }
- }
- return(errnum);
- }
-
- /*
-
- // lets play spot the bug that cuases this routine to crash the system..
- // 5 quid goes to the person the finds the problem!!
-
- struct CfgFileData __asm __saveds *LIBHBBS_LoadConfig(register __a0 UBYTE *filename,register __d0 ULONG Flags)
- {
- // New Optimized Version 04-JAN-1996
-
- BPTR FH;
- LONG found=0;
- UBYTE buffer[BIG_STR+1];
- UBYTE ItemName[BIG_STR+1];
- UBYTE Params[BIG_STR+1];
- struct CfgFileData *cfgfile=NULL;
- struct CfgItemData *node=NULL;
- if (LIBPathOK(filename))
- {
- // create and init our CfgFileData structure..
-
- if (cfgfile=AllocVec(sizeof(struct CfgFileData),MEMF_PUBLIC|MEMF_CLEAR))
- {
- cfgfile->filename=LIBDupStr(filename);
-
- if (cfgfile->ItemsList=LIBHBBS_CreateList())
- {
- if (FH=Open(filename,MODE_OLDFILE))
- {
- while (FGets(FH,buffer,BIG_STR))
- {
- LIBstripcr(buffer);
- ItemName[0]=0;
- Params[0]=0;
-
- LIBStripComments(buffer);
-
- LIBStripSpaces(buffer);
-
- if (LIBGetItem(ItemName,buffer))
- {
- if (LIBGetParams(Params,buffer))
- {
-
- if (node=AllocVec(sizeof(struct CfgItemData),MEMF_PUBLIC))
- {
- node->node.ln_Name=LIBDupStr(ItemName); // *C* add errorchecking..
- node->Params=LIBDupStr(Params);
- AddTail(cfgfile->ItemsList,(struct Node*)node);
- found++;
- }
-
- // if (LIBHBBS_AddCfgItemQuick(cfgfile,ItemName,Params))
- // {
- // found++;
- // }
- }
- }
- }
- Close(FH);
- }
- }
- if (!found)
- {
- LIBHBBS_FlushConfig(cfgfile);
- cfgfile=NULL;
- }
- }
- }
-
-
- return(cfgfile);
- }
- */
-
- struct CfgFileData __asm __saveds *LIBHBBS_LoadConfig(register __a0 UBYTE *filename,register __d0 ULONG Flags)
- {
- BPTR FH;
- struct FileInfoBlock *FIB=NULL;
- LONG nr;
- UBYTE *Data;
- ULONG Length;
-
- V_BIGNUM linenum=0;
- V_BOOL done,nearlydone;
- LONG filepos=0,bufferpos,found=0;
- V_STRING buffer;
- V_STRING ItemName;
- V_STRING Params;
- struct CfgItemData *node=NULL;
- struct CfgFileData *cfgfile=NULL;
-
- if (FH=Open(filename,MODE_OLDFILE))
- {
- if (cfgfile=AllocVec(sizeof(struct CfgFileData),MEMF_PUBLIC|MEMF_CLEAR))
- {
-
- if (FIB=(struct FileInfoBlock *)AllocVec(sizeof(struct FileInfoBlock),MEMF_PUBLIC))
- {
- ExamineFH(FH,FIB);
- Length=FIB->fib_Size;
- if (Data=AllocVec(Length,MEMF_PUBLIC))
- {
- if ((nr=Read(FH,Data,Length))!=Length)
- {
- LIBHBBS_LogError(BBSGlobal->ErrorLogFile,ERR_ERROR_READING,filename,TYPE_CRITICAL);
- }
- else
- {
- if (cfgfile->ItemsList=LIBHBBS_CreateList())
- {
- // if (cfgfile->ItemsList=(struct List *)AllocVec(sizeof(struct List ),MEMF_PUBLIC))
- // {
- // NewList(cfgfile->ItemsList);
-
- buffer=AllocVec(BIG_STR,MEMF_PUBLIC);
- ItemName=AllocVec(BIG_STR,MEMF_PUBLIC);
- Params=AllocVec(BIG_STR,MEMF_PUBLIC);
- if (buffer && ItemName && Params)
- {
- do
- {
- bufferpos=0;
- done=FALSE;
- nearlydone=FALSE; // :-) love those variable names! :-)
- do
- {
- if (Data[filepos]=='\r' || Data[filepos]=='\n')
- {
- nearlydone=TRUE;
- filepos++;
- }
- else
- {
- if (nearlydone)
- {
- done=TRUE;
- }
- else
- {
- buffer[bufferpos]=Data[filepos];
- filepos++;
- bufferpos++;
- }
- }
- } while (filepos<Length && !done && bufferpos<BIG_STR-2); // 1 for null and 1 more cos we still have to add the null
- buffer[bufferpos]=0;
-
- linenum++;
- ItemName[0]=0; // null terminate both strings..
- Params[0]=0;
-
- if (!(Flags & LCFG_NOSTRIPCOMMENTS)) LIBStripComments(buffer);
- if (!(Flags & LCFG_NOSTRIPSPACES)) LIBStripSpaces(buffer);
-
- if (LIBGetItem(ItemName,buffer))
- {
- if (LIBGetParams(Params,buffer))
- {
- // if (Params[0])
- // {
- // Commented out cos it's WAY too slow like this...
- // if (LIBHBBS_AddCfgItem(cfgfile,ItemName,Params))
- // {
- // found++;
- // }
- //
- if (node=AllocVec(sizeof(struct CfgItemData),MEMF_PUBLIC))
- {
- node->node.ln_Name=LIBDupStr(ItemName); // *C* add errorchecking..
- node->Params=LIBDupStr(Params);
- AddTail(cfgfile->ItemsList,(struct Node*)node);
- found++;
- }
-
- // }
- }
- }
- } while (filepos<Length);
- }
- if (Params) FreeVec(Params);
- if (ItemName) FreeVec(ItemName);
- if (buffer) FreeVec(buffer);
- }
- }
- FreeVec(Data);
- }
- FreeVec(FIB);
- }
- if (found)
- {
- cfgfile->filename=LIBDupStr(filename);
- }
- else
- {
- LIBHBBS_FlushConfig(cfgfile);
- cfgfile=NULL; // just to make sure.. *C* ?? needed ?
- }
- }
- Close(FH);
- }
- // else
- // {
- // LIBHBBS_LogError(BBSGlobal->ErrorLogFile,ERR_ERROR_OPENING,filename,TYPE_FATAL);
- // }
- return(cfgfile);
- }
-
- void __asm __saveds LIBHBBS_FlushConfig(register __a0 struct CfgFileData *cfgfile)
- {
- struct CfgItemData *node;
- if (cfgfile)
- {
- while ((cfgfile->ItemsList) && (cfgfile->ItemsList->lh_Head->ln_Succ))
- {
- node=(struct CfgItemData *)cfgfile->ItemsList->lh_Head;
-
- LIBFreeStr(node->node.ln_Name);
- LIBFreeStr(node->Params);
- Remove((struct Node *)node);
- FreeVec(node);
- }
- FreeVec(cfgfile->ItemsList);
- LIBFreeStr(cfgfile->filename);
- FreeVec(cfgfile);
- }
- }
-
- V_BOOL __asm __saveds LIBHBBS_SaveConfig(register __a0 struct CfgFileData *cfgfile)
- {
- BPTR FH;
- struct CfgItemData *node;
- char outstr[BIG_STR];
-
- if (LIBAssignOK(cfgfile->filename))
- {
- if (FH=Open(cfgfile->filename,MODE_NEWFILE))
- {
- for (node = (struct CfgItemData*)cfgfile->ItemsList->lh_Head ; node->node.ln_Succ ; node =(struct CfgItemData *)node->node.ln_Succ)
- {
- sprintf(outstr,"%s=%s\n",node->node.ln_Name,node->Params);
- Write(FH,outstr,strlen(outstr));
- }
- Close(FH);
- return(TRUE);
- }
- }
- return(FALSE);
- }
-
- struct CfgItemData __asm __saveds *LIBHBBS_GetCfgNode(register __a0 struct CfgFileData *cfgfile,register __a1 V_STRING optionstr)
- {
-
- struct CfgItemData *Item;
-
- for (Item = (struct CfgItemData *)cfgfile->ItemsList->lh_Head ; Item->node.ln_Succ ; Item =(struct CfgItemData *) Item->node.ln_Succ)
- {
- if (stricmp(optionstr,Item->node.ln_Name)==0)
- {
- return(Item);
- }
- }
- return(NULL);
- }
-
- V_SMALLNUM __asm __saveds LIBHBBS_GetSetting(register __a0 struct CfgFileData *cfgfile,register __a1 void **result,register __d0 V_FLAGS optiontype,register __a2 V_STRING optionstr,register __d1 V_BOOL multi)
- {
-
- V_SMALLNUM found=0;
- V_STRING CompareStr;
- struct Node *node;
- struct CfgItemData *Item;
-
- // allocate a big string for comparing the strings..
- if (CompareStr=AllocVec(BIG_STR,MEMF_PUBLIC))
- {
- // parse list..
- for (Item = (struct CfgItemData *)cfgfile->ItemsList->lh_Head ; Item->node.ln_Succ ; Item =(struct CfgItemData *) Item->node.ln_Succ)
- {
- if (multi==OPT_MULTI)
- {
- sprintf(CompareStr,"%s_%d",optionstr,found+1);
- }
-
- if ((multi==OPT_SINGLE) && (stricmp(optionstr,Item->node.ln_Name)==0) ||
- (multi==OPT_MULTI) && (stricmp(CompareStr,Item->node.ln_Name)==0))
- {
- switch(optiontype)
- {
- case VTYPE_STRING:
- case VTYPE_DATE:
- if (*result!=NULL) LIBFreeStr(*result);
- *result=(V_STRING *)LIBDupStr(Item->Params);
- found++;
- break;
- case VTYPE_PATH:
- if (*result!=NULL) LIBFreeStr(*result);
- if (*result=(V_STRING)AllocVec(strlen(Item->Params)+1,MEMF_CLEAR|MEMF_PUBLIC))
- {
- strcpy((V_STRING)*result,Item->Params);
- if ((Item->Params[strlen(Item->Params)-1]!='/') && (Item->Params[strlen(Item->Params)-1]!=':'))
- {
- strcat((V_STRING)*result,"/");
- }
- found++;
-
- }
- break;
- case VTYPE_BOOL:
- *result=(V_BOOL *)LIBCheckBoolean(Item->Params);
- found++;
- break;
- case VTYPE_BIGNUM:
- *result=(V_BIGNUM *)atoi(Item->Params);
- found++;
- break;
- case VTYPE_WORD:
- *result=(WORD *)atoi(Item->Params);
- found++;
- break;
- case VTYPE_SMALLNUM:
- *result=(V_SMALLNUM *)atoi(Item->Params);
- found++;
- break;
- case VTYPE_STRINGLIST:
- case VTYPE_PATHLIST:
- // free existing stringlist if present
-
- if ((found==0) && (*result))
- {
- LIBFreeStrList((V_STRINGLIST)*result);
- }
- if (!(*result))
- {
- if(*result=AllocVec(sizeof (struct List),MEMF_PUBLIC))
- {
- NewList((struct List*)*result);
- }
- }
- if (*result) // allocated new list ok ?
- {
- if (node=AllocVec(sizeof(struct Node),MEMF_PUBLIC))
- {
- if (optiontype==VTYPE_PATHLIST)
- {
- if (node->ln_Name=AllocVec(strlen(Item->Params)+1,MEMF_CLEAR|MEMF_PUBLIC))
- {
- strcpy(node->ln_Name,Item->Params);
- if ((node->ln_Name[strlen(node->ln_Name)-1]!=':') && (node->ln_Name[strlen(node->ln_Name)-1]!='/'))
- {
- strcat(node->ln_Name,"/");
- }
- }
- }
- else
- {
- node->ln_Name=LIBDupStr(Item->Params);
- }
-
- if (!(node->ln_Name))
- {
- FreeVec(node);
- }
- else
- {
- AddTail((struct List *)*result,node);
-
- found++;
-
- // go to start of list again or we might miss out something..
- Item = (struct CfgItemData *)cfgfile->ItemsList->lh_Head;
- }
-
- }
- }
- }
- }
- }
- FreeVec(CompareStr);
- }
- return(found);
- }
-
- struct CfgFileData __asm __saveds *LIBHBBS_CreateConfig(register __a0 UBYTE *filename)
- {
- struct CfgFileData *newcfg;
-
- if (newcfg=(struct CfgFileData *)AllocVec(sizeof(struct CfgFileData),MEMF_PUBLIC|MEMF_CLEAR))
- {
- if (newcfg->ItemsList=(struct List *)AllocVec(sizeof(struct List ),MEMF_PUBLIC))
- {
- NewList(newcfg->ItemsList);
- newcfg->filename=LIBDupStr(filename); // *C* add errorchecking..
- }
- else
- {
- FreeVec(newcfg);
- newcfg=NULL;
- }
- }
- return(newcfg);
- }
-
- BOOL __asm __saveds LIBHBBS_RemoveCfgItem(register __a0 struct CfgFileData *cfgfile,register __a1 UBYTE *itemname)
- {
- struct CfgItemData *node;
- BOOL Removed=FALSE;
- char *match;
-
- if (match=AllocVec((strlen(itemname)*2)+2,MEMF_PUBLIC))
- {
- if (cfgfile && cfgfile->ItemsList)
- {
- for (node = (struct CfgItemData*)cfgfile->ItemsList->lh_Head ;(node->node.ln_Succ) ; node =(struct CfgItemData *)node->node.ln_Succ)
- {
- ParsePatternNoCase(itemname,match,(strlen(itemname)*2)+2);
- if (MatchPatternNoCase(match,node->node.ln_Name))
- {
- Remove((struct Node*)node);
- LIBFreeStr(node->Params);
- LIBFreeStr(node->node.ln_Name);
- FreeVec(node);
- // go to start of list again..
- node=node = (struct CfgItemData*)cfgfile->ItemsList->lh_Head;
- Removed=TRUE;
- }
- }
- }
- FreeVec(match);
- }
- return(Removed);
- }
-
- BOOL __asm __saveds LIBHBBS_AddCfgItem(register __a0 struct CfgFileData *cfgfile,register __a1 UBYTE *itemname,register __a2 UBYTE *params)
- {
- struct CfgItemData *node;
- BOOL Done=FALSE;
-
- /*
- char *offset,*remstr;
- short loop;
- */
- if (cfgfile && cfgfile->ItemsList)
- {
- // check to see if itemname is already there..
-
- LIBHBBS_RemoveCfgItem(cfgfile,itemname);
-
- /*
- * Unsed bit of usefull code, was origonally going to make it so that when you start
- * adding items of a list to a config items list it removed all the parts of the old
- * list first.. but decided not to do it this way (at all) but left this bit of code
- * cos it might be usefull.. :-)
- *
- if (offset=strrchr(itemname,'_'))
- {
- offset++;
- if (offset[0]!=0)
- {
- if (isdigit(offset[0]))
- {
- loop=1;
- while (isdigit(offset[loop]))
- {
- loop++;
- }
-
- if (offset[loop]==0)
- {
- if (remstr=AllocVec(strlen(itemname)+2,MEMF_PUBLIC))
- {
- LIBstrNcpy(remstr,itemname,offset-itemname);
- strcat(remstr,"#?");
-
- LIBHBBS_RemoveCfgItem(cfgfile,remstr);
-
- FreeVec(remstr);
- }
- }
- }
- }
- }
- */
-
- if (node=AllocVec(sizeof(struct CfgItemData),MEMF_PUBLIC))
- {
- node->node.ln_Name=LIBDupStr(itemname); // *C* add errorchecking..
- node->Params=LIBDupStr(params);
- AddTail(cfgfile->ItemsList,(struct Node*)node);
- Done=TRUE;
- }
- }
- return(Done);
- }
-
- void __asm __saveds LIBHBBS_ResetNodeData(register __a0 struct NodeData *node)
- {
- // this function is called a) when a node is initialised
- // and b) when a node shuts down. (everything is freed first tho..
-
- node->LoginType=LOGIN_NONE;
- node->OnlineStatus=OS_OFFLINE; // node program sets this to ONLINE or OFFLINE
- // this shot be used in all door programs to determine
- // carrier status (even for local logins..)
- node->User.Valid=FALSE;
- node->NodeFlags=0L;
- node->Status=STAT_CLOSED;
- node->NodePort=NULL;
- node->SettingsOpen=FALSE;
- node->InformationOpen=FALSE;
- node->ConOK=FALSE;
- node->SerOK=FALSE;
- node->SerOPEN=FALSE;
- node->SerWaiting=FALSE;
- node->ConWaiting=FALSE;
- node->ReplyPort=NULL;
- node->RequestShutdown=FALSE;
- node->ActiveDoor=NULL;
- node->DoorsRunning=0;
- node->DoorReturn[0]=0;
- node->CurrentLine[0]=0;
- node->TransferringFile=FALSE;
- node->TaggedFiles=0;
- node->AllowLogins=TRUE;
- strcpy(node->Action,"Initialising!"); // max 29 chars!
- node->ConnectBaud[0]=0; // max 8 chars..
-
- node->Current_Last_Callers=0;
- node->Current_Last_Uploads=0;
- node->Current_Last_Downloads=0;
- node->Current_Last_PWFails=0;
- node->Current_Last_Carrier=0;
- node->Current_Last_Pagers=0;
-
- // *C* make sysop definable..
- node->Max_Last_Callers=10;
- node->Max_Last_Uploads=10;
- node->Max_Last_Downloads=10;
- node->Max_Last_PWFails=10;
- node->Max_Last_Carrier=10;
- node->Max_Last_Pagers=10;
- }
-
- void __asm __saveds LIBHBBS_rterror(register __a0 char *str)
- {
- rtEZRequestTags(str,str_OK,NULL,NULL,RTGS_Flags, GSREQF_CENTERTEXT,TAG_END);
- }
-
-
- LONG __asm __saveds LIBHBBS_RunDOSCMD(register __a0 char *command,register __d0 BOOL ASYNC)
- {
- LONG retval=-1;
- static ULONG sysargs[] =
- {
- SYS_Input,NULL,
- SYS_Output,NULL,
- SYS_Asynch,TRUE,
- SYS_UserShell,TRUE,
- NP_Priority,0L,
- TAG_DONE
- };
- BPTR outputfile;
- sysargs[5]=ASYNC;
-
- if (outputfile = Open(str_CONSOLE,MODE_OLDFILE))
- {
- sysargs[1]=(ULONG)outputfile;
- LIBreplace(command,command,"@S@",str_CtrlScrnName);
- retval=SystemTagList(command,(struct TagItem *)sysargs);
- if (!ASYNC) Close(outputfile); // close window if not async
- }
- return(retval);
-
- // *C* perhaps add a routine to close async'ed windows after 5 mins ??
- }
-
- void __asm __saveds LIBHBBS_DoErrorMessage(register __d0 ULONG num,register __d1 ULONG node,register __a0 char *errstr)
- {
- char *str;
- int len=20; // 20 extra chars should be ok for the numbers
-
- if (errstr) len+=strlen(errstr);
-
- if (str=AllocVec(len+strlen(PRG_ERRORMESSAGE),MEMF_PUBLIC))
- {
- sprintf(str,"%s %d %d ",PRG_ERRORMESSAGE,num,node);
- if (errstr) strcat(str,errstr);
- LIBHBBS_RunDOSCMD(str,TRUE); // *C* false ?
- FreeVec(str);
- }
- }
-
- void __asm __saveds LIBcvtucase(register __a0 char *str)
- {
- int loop;
- for (loop=0;str[loop]!=0;loop++)
- {
- str[loop]=toupper(str[loop]);
- }
- }
-
- BOOL __asm __saveds LIBAssignOK(register __a0 char *checkme )
- {
- struct DosList *DosList;
- struct DeviceNode *DevNode;
- UBYTE *Pointer;
- char string[32]="",cmpstring[32]="";
- int loop;
- BOOL found=FALSE;
-
- for (loop = 0 ; checkme[loop]!=0 && checkme[loop]!=':' && checkme[loop]!='/' ; loop++);
- LIBstrNcpy(cmpstring,checkme,loop);// +1); // +1 cos we WANT the ':'
- LIBcvtucase(cmpstring);
- DosList = LockDosList(LDF_ALL|LDF_READ);
- while((DosList = NextDosEntry(DosList,LDF_ALL|LDF_READ)) && !found)
- {
- DevNode = (struct DeviceNode *)DosList;
-
- // assign or volume ?
- if (DevNode->dn_Type==DLT_DIRECTORY || DevNode->dn_Type==DLT_DEVICE || DevNode->dn_Type==DLT_VOLUME)
- {
- Pointer = (UBYTE *)BADDR(DevNode -> dn_Name);
- if (Pointer[0])
- {
- for(loop = 0 ; loop < Pointer[0] ; loop++)
- string[loop] = Pointer[loop + 1];
-
- string[Pointer[0]] = 0; /* terminate string */
- // strcat(string,":");
- LIBcvtucase(string);
- if (strcmp(cmpstring,string)==0) found=TRUE;
- }
- }
- }
- UnLockDosList(LDF_ALL|LDF_READ);
- return(found);
- }
-
- BOOL __asm __saveds LIBHBBS_InitCommon( void )
- {
- SysBase = *(struct ExecBase **) 4L;
- if (DOSBase = (struct DosLibrary *) OpenLibrary ("dos.library", 0))
- {
- if (ReqToolsBase = (struct ReqToolsBase *) OpenLibrary (REQTOOLSNAME, REQTOOLSVERSION))
- return(TRUE);
- }
- return(FALSE);
- }
-
- void __asm __saveds LIBHBBS_CleanUpCommon( void )
- {
- if (ReqToolsBase) CloseLibrary ((struct Library *)ReqToolsBase);
- if (DOSBase) CloseLibrary ((struct Library *) DOSBase);
- }
-
- struct TimerData __asm __saveds *LIBSubmitTimer(register __a0 struct TimerSetupData *TSD, register __d0 ULONG Seconds,register __d1 ULONG MicroSeconds )
- {
- struct TimerData *TD=NULL;
-
- if (TSD)
- {
- if (TD=(struct TimerData*)AllocVec(sizeof(struct TimerData),MEMF_PUBLIC))
- {
- // copy fields accross from our blank timer IO request
- // that was initialised by InitTimer();
-
- // Source Dest Size
- CopyMem(TSD->BlankTimerIO,&TD->TR,sizeof(struct timerequest));
-
- TD->TR.tr_time.tv_secs = Seconds;
- TD->TR.tr_time.tv_micro = MicroSeconds;
- AddHead(TSD->TimerList,(struct Node*)TD);
-
- SendIO((struct IORequest *)&TD->TR);
- }
- }
- return(TD);
- }
-
- void __asm __saveds LIBAbortTimer(register __a0 struct TimerSetupData *TSD, register __a1 struct TimerData *CTD)
- {
- struct TimerData *TD=NULL;
-
- if (CTD)
- {
- for (TD = (struct TimerData *)TSD->TimerList->lh_Head ; TD->node.ln_Succ ; TD =(struct TimerData *) TD->node.ln_Succ)
- {
- if (TD==CTD)
- {
- AbortIO((struct IORequest *)&CTD->TR);
- WaitIO((struct IORequest *)&CTD->TR);
- Remove((struct Node*)CTD);
- FreeVec(CTD);
- // TD is now null so we dont wat to reference it again so return from the func..
- return;
- }
- }
- }
- }
-
- BOOL __asm __saveds LIBCheckTimer(register __a0 struct TimerSetupData *TSD, register __a1 struct TimerData *CTD)
- {
- struct TimerData *TD=NULL;
-
- for (TD = (struct TimerData *)TSD->TimerList->lh_Head ; TD->node.ln_Succ ; TD =(struct TimerData *) TD->node.ln_Succ)
- {
- if (TD==CTD)
- {
- if (CheckIO((struct IORequest *)&CTD->TR))
- {
- WaitIO((struct IORequest *)&CTD->TR);
- Remove((struct Node*)CTD);
- FreeVec(CTD);
- return(TRUE);
- }
- }
- }
- return(FALSE);
- }
-
- void __asm __saveds LIBCleanupTimer( register __a0 struct TimerSetupData *TSD )
- {
- struct TimerData *TD=NULL;
-
- if (TSD)
- {
- if (TSD->TimerPort)
- {
- if (TSD->BlankTimerIO)
- {
- if (TSD->TimerOpen)
- {
- if (TSD->TimerList)
- {
- // remove all outstanding io requests..
- while ((struct TimerData *)TSD->TimerList->lh_Head->ln_Succ)
- {
- TD=(struct TimerData *)TSD->TimerList->lh_Head;
- AbortIO((struct IORequest *)&TD->TR);
- WaitIO((struct IORequest *)&TD->TR);
- Remove((struct Node*)TD);
- FreeVec(TD);
- }
- FreeVec(TSD->TimerList);
- }
- CloseDevice((struct IORequest *) TSD->BlankTimerIO);
- TSD->TimerOpen=FALSE;
- }
- DeleteExtIO((struct IORequest *) TSD->BlankTimerIO);
- }
- DeleteMsgPort(TSD->TimerPort);
- }
- FreeVec(TSD);
- }
- }
-
- struct TimerSetupData __asm __saveds *LIBInitTimer( void )
- {
- struct TimerSetupData *TSD;
-
- if (TSD=AllocVec(sizeof(struct TimerSetupData),MEMF_PUBLIC))
- {
- TSD->TimerOpen=FALSE;
- if (TSD->TimerPort = CreateMsgPort())
- {
- if (TSD->BlankTimerIO = (struct timerequest *) CreateExtIO(TSD->TimerPort,sizeof(struct timerequest)) )
- {
- if (OpenDevice( TIMERNAME, UNIT_VBLANK,(struct IORequest *) TSD->BlankTimerIO, 0L)==0) // success ?
- {
- TSD->TimerOpen=TRUE;
- TSD->BlankTimerIO->tr_node.io_Command = TR_ADDREQUEST;
- if (TSD->TimerList=AllocVec(sizeof(struct List),MEMF_PUBLIC))
- {
- NewList((struct List *)TSD->TimerList);
- return(TSD);
- }
- }
- }
- }
- LIBCleanupTimer(TSD);
- }
- return(NULL);
- }
-
- BOOL __asm __saveds LIBPathOK(register __a0 char *str)
- {
- BPTR FL;
-
- if (LIBAssignOK(str))
- {
- if (FL=Lock(str,ACCESS_READ))
- {
- UnLock(FL);
- return(TRUE);
- }
- }
- return(FALSE);
- }
-
- BOOL __asm __saveds LIBHBBS_LoadUser(register __d0 V_BIGNUM ID,register __a0 char *handle,register __a1 char *realname,register __a2 struct UserData *user)
- {
- // specify only one of ID,handle or realname
- // "user" should already be allocated..
-
- BPTR FH;
- BPTR FL;
- V_BOOL Found=FALSE;
-
- if(user)
- {
- if (ID>0)
- {
- // keep trying..
- while (!(FL=Lock(BBSGlobal->UserDataFileName,ACCESS_READ)));
- if (FH=OpenFromLock(FL))
- {
- if (Seek(FH,(ID-1)*sizeof(struct UserData),OFFSET_BEGINNING)!=-1)
- {
- if (Read(FH,user,sizeof(struct UserData))==sizeof(struct UserData))
- {
- Found=TRUE;
- }
- // else puts("Short Read!");
- }
- Close(FH);
- }
- // else puts("Error Opening Userdata file");
- if (Found) return(TRUE);
- }
- else
- {
- if (handle!=NULL)
- {
- // printf("Searching for user with a handle of %s\n",handle);
- }
- else
- {
- if (realname!=NULL)
- {
- // printf("Searching for user with a realname of %s\n",realname);
- }
- }
- }
- }
- return(FALSE);
- }
-
- V_BOOL __asm __saveds LIBHBBS_ValidUserHandle(register __a0 char *userhandle, register __a1 struct UserData *FillUser)
- {
-
- // Small routing to see if a user name does exist, if the user does
- // exist and FillUser points an allocated data structure the size of
- // sizeof(struct UserData) then the uses info that was found will be copied
- // to there.
-
- V_BIGNUM CurrentUserNum=0;
- V_BOOL Found=FALSE;
- struct UserData User;
-
- if (BBSGlobal->TotalUsers>=0) // spose we better check this :-)
- {
- while (!Found && CurrentUserNum<BBSGlobal->TotalUsers)
- {
- CurrentUserNum++;
- // printf("Searching %d For User \"%s\"\n",CurrentUserNum,userhandle);
- if (LIBHBBS_LoadUser(CurrentUserNum,NULL,NULL,&User))
- {
- // *C* insert pattern matching routine here..
- // or not ? perhps add an "Interactive Y/N" parameter.
-
- if (stricmp(userhandle,User.Handle)==0)
- {
- Found=TRUE;
- }
- }
- // else puts("Failed To Load User");
- }
- }
- if (Found && FillUser)
- {
-
- CopyMem(&User,FillUser,sizeof (struct UserData));
- }
- return(Found);
- }
-
- V_BIGNUM __asm __saveds LIBHBBS_FindTotalUsers( void )
- {
- BPTR FL;
- struct FileInfoBlock FB;
-
- BBSGlobal->TotalUsers=-1;
-
- // keep trying!
-
- while (!(FL=Lock(BBSGlobal->UserDataFileName,ACCESS_READ)));
- if (Examine(FL,&FB));
- {
- BBSGlobal->TotalUsers=(V_BIGNUM)(FB.fib_Size / sizeof(struct UserData));
- }
- UnLock(FL);
-
- return(BBSGlobal->TotalUsers);
- }
-
- BOOL __asm __saveds LIBLoadPrivateData( void )
- {
- struct CfgFileData *PrivateCFG;
- BOOL retval=FALSE;
-
- if (PrivateCFG=LIBHBBS_LoadConfig(FILE_PRIVATEDATA,LCFG_NONE))
- {
- if (LIBHBBS_GetSetting(PrivateCFG,(void *)&BBSGlobal->LastUserNum,VTYPE_BIGNUM,OPT_PRIV_LastUserNum,OPT_SINGLE))
- {
- retval=TRUE;
- }
- LIBHBBS_FlushConfig(PrivateCFG);
- }
-
- return(retval);
- }
-
- void __asm __saveds LIBUpdatePrivateData ( void )
- {
- struct CfgFileData *PrivateCFG;
- char str[BIG_STR];
-
- if (PrivateCFG=LIBHBBS_CreateConfig(FILE_PRIVATEDATA))
- {
- sprintf(str,"%d",BBSGlobal->LastUserNum);
-
- LIBHBBS_AddCfgItemQuick(PrivateCFG,OPT_PRIV_LastUserNum,str);
- LIBHBBS_SaveConfig(PrivateCFG);
- LIBHBBS_FlushConfig(PrivateCFG);
- }
- }
-
- BOOL __asm __saveds LIBHBBS_AddUser(register __a0 struct UserData *user)
- {
- // *C* need to add some checking/locking of file for multinode operation..
-
- BPTR FH;
- BPTR FL;
-
- BOOL Saved=FALSE;
-
- // *C* need to check to see if file exists... (or get setup program to create..)
-
- // get exclusive access to userdata file when writing..
-
- while (!(FL=Lock(BBSGlobal->UserDataFileName,ACCESS_WRITE))); // keep trying..
-
- if (FH=OpenFromLock(FL)) //(BBSGlobal->UserDataFileName,MODE_OLDFILE))
- {
- if (Seek(FH,0,OFFSET_END)!=-1)
- {
- BBSGlobal->LastUserNum++;
- user->UserID=BBSGlobal->LastUserNum;
- if (Write(FH,user,sizeof(struct UserData))==sizeof(struct UserData))
- {
- LIBUpdatePrivateData();
-
-
- Saved=TRUE;
- }
- else
- {
- // puts("Error Adding Data To File, Truncating..");
- if (SetFileSize(FH,OFFSET_BEGINNING,BBSGlobal->TotalUsers * sizeof(struct UserData))==-1)
- {
- // puts("Cound Not Truncate File!");
- }
- }
- } // else puts("Seek() Failed!");
- Close(FH);
- }
- else UnLock(FL);
-
- LIBHBBS_FindTotalUsers();
- return(Saved);
- }
-
- void __asm __saveds LIBHBBS_InitUserData(register __a0 struct UserData *User)
- {
- User->Status=USER_NEW;
- User->Access=BBSGlobal->NewUserAccessLevel;
- User->Handle[0]=0;
- User->RealName[0]=0;
- User->Group[0]=0;
- User->GeoLocation[0]=0;
- User->Country[0]=0;
- User->PhoneNumber[0]=0;
- User->Password[0]=0;
- User->ComputerType[0]=0;
- User->ConfAccDataFile[0]=0;
- User->LeechAccDataFile[0]=0;
- User->UploadBytes=0;
- User->UploadFiles=0;
- User->DownloadBytes=0;
- User->DownloadFiles=0;
- User->ActualUploadBytes=0;
- User->ActualUploadFiles=0;
- User->ActualDownloadBytes=0;
- User->ActualDownloadFiles=0;
- User->LastUploadDate=0; // *C* add HBBS_Todate() ?
- User->LastCalledDate=0;
- User->BestCPSUp=0;
- User->BestCPSDown=0;
- User->CallsMade=0;
- User->PagesMade=0;
- User->MessagesWritten=0;
- User->FilesRatio=3;
- User->BytesRatio=3;
- User->LastConf=1;
- User->PreferedConf=0;
- User->LinesPerScreen=24;
- User->Protocol=0; // ASK
- User->Editor=0; // ASK
- User->TimeAccessFile[0]=0;
- User->ExtraTimeLimit=0;
- User->ExtraBytesLimit=0;
- User->ExtraCallsLimit=0;
- User->ExtraChatLimit=0;
- User->TimeUsed=0;
- User->BytesUsed=0;
- User->CallsUsed=0;
- User->ChatUsed=0;
- User->BytesAllowed=0;
- User->TimeAllowed=0;
- User->CallsAllowed=0;
- User->ChatAllowed=0;
- User->UserType=USERTYPE_NORMAL;
- User->Language=0; // .TXT or the first one in the list..
- }
-
- void __asm __saveds LIBstrNcpy(register __a0 UBYTE *dest,register __a1 UBYTE *source,register __d0 int chars)
- {
- int count=0;
-
- while ((dest[count]=source[count]) && count<chars-1) count++;
- dest[count+1]=0;
- }
-
- char __asm __saveds *LIBHBBS_ListName(register __a0 V_STRINGLIST ListName,register __d0 V_SMALLNUM ItemNum)
- { //starts from offset 0, 0 being the first node in the list..
- struct Node *node;
-
- if(node=LIBGetNode(ListName,ItemNum))
- {
- return(node->ln_Name);
- }
- return(NULL);
- }
-
- void __asm __saveds LIBFreeFileTags( register __a0 struct NodeData *N_ND )
- {
- struct TaggedFile *tfnode;
- while ((N_ND->TaggedFileList) && (N_ND->TaggedFileList->lh_Head->ln_Succ))
- {
- tfnode=(struct TaggedFile *)N_ND->TaggedFileList->lh_Head;
- LIBFreeStr(tfnode->node.ln_Name);
- Remove((struct Node*)tfnode);
- FreeVec(tfnode);
- }
- N_ND->TaggedFiles=0;
- }
-
- /*
-
-
- struct List __asm __saveds *LIBHBBS_LoadFile(register __a0 char *filename)
- {
- BPTR FL,FH;
- LONG bufferpos;
- BOOL done;
- struct FileInfoBlock FB;
- UBYTE *Data=NULL;
- LONG Length=0,filepos=0;
- UBYTE buffer[bufflen];
- struct List *FileList=NULL;
-
- if (FL=Lock(filename,ACCESS_READ))
- {
- if (Examine(FL,&FB))
- {
- if (FB.fib_Size)
- {
- if (Data=AllocVec(FB.fib_Size,MEMF_PUBLIC))
- {
- if (FH=OpenFromLock(FL))
- {
- Length=Read(FH,Data,FB.fib_Size);
- Close(FH);
- }
- }
- }
- }
- UnLock(FL);
-
- if ((Data) && (Length>0))
- {
- if (FileList=LIBHBBS_CreateList())
- {
-
- do
- {
- bufferpos=0;
- done=FALSE;
- do
- {
-
- if (Data[filepos]==13) //cr
- {
- if ((filepos+1<Length) && (Data[filepos+1]==10)) // cr followed by lf ?
- {
- done=TRUE;
- filepos++;//skip the lf too.
- }
- else
- {
- done=TRUE;
- }
- filepos++; //skip the cr
- }
- else
- {
- if (Data[filepos]==10) //lf
- {
- done=TRUE;
- filepos++;
- }
- else
- {
- buffer[bufferpos]=Data[filepos];
- filepos++;
- bufferpos++;
- }
- }
- } while (filepos<Length && !done && bufferpos<bufflen-2); // 1 for null and 1 more cos we still have to add the null
- buffer[bufferpos]=0;
-
- LIBNewStrNode(buffer,FileList);
-
- } while (filepos<Length);
- }
- }
- if (Data) FreeVec(Data);
- }
- return(FileList);
- }
- */
-
-
- #define bufflen 1024
-
- struct List __asm __saveds *LIBHBBS_LoadFile(register __a0 char *filename)
- {
- /* New Optimized Version: 4-JAN-1996 */
-
- BPTR FH;
- UBYTE buffer[bufflen];
- struct List *FileList=NULL;
- BOOL error=FALSE;
-
- if (LIBPathOK(filename))
- {
- if (FH=Open(filename,MODE_OLDFILE))
- {
- if (FileList=LIBHBBS_CreateList())
- {
- while (FGets(FH,buffer,bufflen) && !error)
- {
- LIBstripcr(buffer);
- if (LIBNewStrNode(buffer,FileList))
- {
- error=TRUE;
- }
- }
- }
- Close(FH);
- }
- }
- if (error)
- {
- LIBFreeStrList(FileList);
- FileList=NULL;
- }
- return(FileList);
- }
-
-
- BOOL __asm __saveds LIBHBBS_SaveFile( register __a0 char *file_name, register __a1 struct List *list)
- {
- BPTR FH;
- struct Node *node;
-
- if (FH=Open(file_name,MODE_NEWFILE))
- {
- for (node = list->lh_Head ; node->ln_Succ ; node =node->ln_Succ)
- {
- Write(FH,node->ln_Name,strlen(node->ln_Name));
- Write(FH,"\n",1); //add cr+lf
- }
- Close(FH);
- }
- return((BOOL)(FH ? TRUE : FALSE));
- }
-
- struct List __asm __saveds *LIBHBBS_CreateList( void )
- {
- struct List *NList;
- if (NList=AllocVec(sizeof(struct List),MEMF_PUBLIC))
- {
- NewList(NList);
- }
- return(NList);
- }
-
- void __asm __saveds LIBstrftcpy(register __a0 char *dest,register __a1 char *source,register __d0 int from,register __d1 int topos)
- {
- int loop=from,pos=0;
- if (from<=strlen(source)-1)
- {
- while (source[loop] && loop<=topos)
- {
- dest[pos]=source[loop];
- loop++;
- pos++;
- }
- }
- dest[pos]=0;
- }
-
- void __asm __saveds LIBRemoveSpaces(register __a0 char *string)
- {
- // removes spaces from the start end end of strings
- ULONG start,end,len;
-
- if (string)
- {
- len=strlen(string);
- for (start=0;string[start]==' ';start++);
- for (end=len-1;string[end]==' ';end--);
- LIBstrftcpy(string,string,start,end);
- }
- }
-
-
- void __asm __saveds LIBHBBS_SaveUserData(register __a0 struct UserData *User)
- {
- // *C* here we should save the data in N_ND->User.NormalData
- // back to the user file..
-
- BPTR FH,FL;
- BOOL Found,ReadError=FALSE;
- struct UserData OldUser;
-
- while (!(FL=Lock(BBSGlobal->UserDataFileName,ACCESS_WRITE)));
- if (FH=OpenFromLock(FL))
- {
- Found=FALSE;
- while (!Found && !ReadError)
- {
- // keep going until the end of the file or we get a read error..
- ReadError=((Read(FH,&OldUser,sizeof(struct UserData))==sizeof(struct UserData)) ? FALSE : TRUE );
-
- if (!ReadError)
- {
- if (OldUser.UserID==User->UserID)
- {
- Found=TRUE;
- }
- }
- }
- if (Found)
- {
- // *C* if error on next to commands then loop until it works ?
-
- // seek to start of record.
- Seek(FH,0-sizeof(struct UserData),OFFSET_CURRENT);
- Write(FH,User,sizeof(struct UserData));
- }
- Close(FH);
- }
- else UnLock(FL);
- }
-
- void __asm __saveds LIBHBBS_GetDate(register __a0 char *datestr)
- {
- struct tm *timestruct;
- long t;
- if (datestr)
- {
- time(&t);
- timestruct=localtime(&t);
-
- LIBHBBS_DateStrFromTM(datestr,timestruct);
-
- /*
- sprintf(datestr,"%s%d-%s-%-04d",(timestruct->tm_mday < 10) ? "0" : "",timestruct->tm_mday,monthstr[timestruct->tm_mon],timestruct->tm_year + 1900);
- */
- }
- free(timestruct);
- }
-
- V_BOOL __asm __saveds LIBHBBS_AddCfgItemQuick(register __a0 struct CfgFileData *cfgfile,register __a1 char *ItemName, register __a2 char *Params)
- {
- struct CfgItemData *node;
- V_BOOL retval=FALSE;
-
- if (cfgfile && ItemName && Params)
- {
- if (node=AllocVec(sizeof(struct CfgItemData),MEMF_PUBLIC))
- {
- node->node.ln_Name=LIBDupStr(ItemName); // *C* error check me! (or not ?)
- node->Params=LIBDupStr(Params);
- AddTail(cfgfile->ItemsList,(struct Node*)node);
- retval=TRUE;
- }
- }
- return(retval);
- }
-
- void __asm __saveds LIBHBBS_SaveCallsData( void )
- {
- struct CfgFileData *CfgFile;
- struct NodeData *nd;
- UBYTE tmpstr[200],optionstr[200];
-
-
- if (CfgFile=LIBHBBS_CreateConfig("HBBS:System/Data/Calls.CFG"))
- {
- LIBHBBS_GetDate(tmpstr);
- LIBHBBS_AddCfgItemQuick(CfgFile,"Today",tmpstr);
-
- sprintf(tmpstr,"%d",BBSGlobal->CallsToday);
- LIBHBBS_AddCfgItemQuick(CfgFile,"TotalCalls",tmpstr);
-
- for (nd=(struct NodeData *)BBSGlobal->NodeList->lh_Head;nd->node.ln_Succ;nd=(struct NodeData *)nd->node.ln_Succ)
- {
- sprintf(optionstr,"Node_%d_Calls",nd->NodeNum);
- sprintf(tmpstr,"%d",nd->CallsToday);
- LIBHBBS_AddCfgItemQuick(CfgFile,optionstr,tmpstr);
- }
- LIBHBBS_SaveConfig(CfgFile);
- LIBHBBS_FlushConfig(CfgFile);
- }
-
- }
-
- void __asm __saveds LIBHBBS_LoadCallsData( void )
- {
- struct CfgFileData *CfgFile;
- BOOL Loaded=FALSE;
- V_STRING TodayStr=NULL;
- UBYTE tmpstr[200];
- struct NodeData *nd;
-
- LIBHBBS_GetDate(tmpstr);
-
- if (CfgFile=LIBHBBS_LoadConfig("HBBS:System/Data/Calls.CFG",LCFG_NONE))
- {
- if (LIBHBBS_GetSetting(CfgFile,(void *)&TodayStr,VTYPE_STRING,"Today",OPT_SINGLE))
- {
- if (stricmp(TodayStr,tmpstr)==0) // same day ???
- {
- if (LIBHBBS_GetSetting(CfgFile,(void *)&BBSGlobal->CallsToday,VTYPE_BIGNUM,"TotalCalls",OPT_SINGLE))
- {
- for (nd=(struct NodeData *)BBSGlobal->NodeList->lh_Head;nd->node.ln_Succ;nd=(struct NodeData *)nd->node.ln_Succ)
- {
- sprintf(tmpstr,"Node_%d_Calls",nd->NodeNum);
- if (!LIBHBBS_GetSetting(CfgFile,(void *)&nd->CallsToday,VTYPE_BIGNUM,tmpstr,OPT_SINGLE))
- {
- nd->CallsToday=0;
- }
- }
- Loaded=TRUE;
- }
- }
- }
- }
- if (!Loaded)
- {
- BBSGlobal->CallsToday=0;
-
- for (nd=(struct NodeData *)BBSGlobal->NodeList->lh_Head;nd->node.ln_Succ;nd=(struct NodeData *)nd->node.ln_Succ)
- {
- nd->CallsToday=0;
- }
- LIBHBBS_SaveCallsData();
- }
- if (TodayStr) LIBFreeStr(TodayStr);
- }
-
- void __asm __saveds LIBHBBS_GetTime(register __a0 char *timestr)
- {
- struct tm *timestruct;
- long t;
-
- if (timestr)
- {
- time(&t);
- timestruct=localtime(&t);
-
- sprintf(timestr,"%s%d:%s%d:%s%d",(timestruct->tm_hour < 10) ? "0" : "",timestruct->tm_hour,
- (timestruct->tm_min < 10) ? "0" : "",timestruct->tm_min,
- (timestruct->tm_sec < 10) ? "0" : "",timestruct->tm_sec);
- }
- free(timestruct);
- }
-
- void __asm __saveds LIBHBBS_GetDateStr(register __a0 char *datestr,register __d0 long t)
- {
- long tt=t;
- struct tm *timestruct;
- if (datestr)
- {
- timestruct=localtime(&tt);
-
- /*
- if (timestruct->tm_mday<0)
- {
- strcpy(datestr,"01-JAN-1970"); // date limit!
- }
- else
- {
- sprintf(datestr,"%s%d-%s-%-04d",(timestruct->tm_mday < 10) ? "0" : "",timestruct->tm_mday,monthstr[timestruct->tm_mon],timestruct->tm_year+1900);
- }
- */
- LIBHBBS_DateStrFromTM(datestr,timestruct);
- free(timestruct);
- }
- }
-
- void __asm __saveds LIBHBBS_DateStrFromTM(register __a0 UBYTE *datestr, register __a1 struct tm *timestruct)
- {
- if (datestr && timestruct)
- {
- if (timestruct->tm_mday<0)
- {
- strcpy(datestr,"01-JAN-1970"); // date limit!
- }
- else
- {
- sprintf(datestr,"%s%d-%s-%-04d",(timestruct->tm_mday < 10) ? "0" : "",timestruct->tm_mday,monthstr[timestruct->tm_mon],timestruct->tm_year+1900);
- }
- }
-
- }
-
- V_BOOL __asm __saveds LIBHBBS_DateStrToTM(register __a0 UBYTE *datestr, register __a1 struct tm *timestruct)
- {
- UBYTE tmpstr[5];
- LONG tday,tmon=-1,tyear,loop;
-
- LIBstrNcpy(tmpstr,datestr,2);
- if (sscanf(tmpstr,"%ld",&tday))
- {
- LIBstrftcpy(tmpstr,datestr,3,5);
- for (loop=0;loop<=12 && tmon==-1;loop++)
- {
- if (stricmp(tmpstr,monthstr[loop])==0)
- {
- tmon=loop;
- }
- }
- if (tmon>=0)
- {
- LIBstrftcpy(tmpstr,datestr,7,10);
- if (sscanf(tmpstr,"%ld",&
- tyear))
- {
- tyear-=1900;
- if ((tyear>=70) && (tmon>=0) && (tmon<12) && (tday>=1) && (tday<=31))
- {
- // all data is ok, so opy it to the timestruct!
- timestruct->tm_mday=tday;
- timestruct->tm_year=tyear;
- timestruct->tm_mon=tmon;
- return(TRUE);
- }
- }
- }
- }
- return(FALSE);
- }
-
- void *AllocBuffer(ULONG *BufferSize,ULONG Flags) // min 10 bytes!
- {
- void *retval=NULL;
-
- if (*BufferSize)
- {
- if (*BufferSize<10) *BufferSize=10;
- while ((*BufferSize>10) && ((retval=AllocVec(*BufferSize,Flags))==NULL))
- {
- *BufferSize/=2; // divide buffersize by 2!
- }
-
- }
- return(retval);
- }
-
- V_BOOL __asm __saveds LIBHBBS_CopyFile(register __a0 char *fromfile, register __a1 char *tofile,register __d0 ULONG BufSize)
- {
- BOOL retval=FALSE;
- BPTR FL,FromFH,ToFH;
- struct FileInfoBlock FB;
- BOOL error=TRUE;
- ULONG nr,nw,total=0;
- UBYTE *Buffer;
- ULONG MyBufSize=BufSize;
-
- if (MyBufSize==0) MyBufSize=BBSGlobal->CopyBufferSize; // *C* user selectable!
-
- if (FL=Lock(fromfile,ACCESS_READ))
- {
- if (Examine(FL,&FB))
- {
- if (FromFH=OpenFromLock(FL))
- {
- if (ToFH=Open(tofile,MODE_NEWFILE))
- {
- if (FB.fib_Size>0)
- {
- if (MyBufSize>FB.fib_Size) MyBufSize=FB.fib_Size; // no sense allocating to much mem
- if (Buffer=AllocBuffer(&MyBufSize,MEMF_PUBLIC))
- {
- do
- {
- error=FALSE;
- if (nr=Read(FromFH,Buffer,MyBufSize-1))
- {
- if (nr==(nw=Write(ToFH,Buffer,nr)))
- {
- total+=nw;
- } else error=TRUE;
- } else error=TRUE;
- } while (!error);
- if (error && total>=FB.fib_Size) error=FALSE; //end of file rather than error...
-
- FreeVec(Buffer);
- }
- }
- else
- {
- error=FALSE;
- }
- Close(ToFH);
- SetComment(tofile,FB.fib_Comment);
- SetProtection(tofile,FB.fib_Protection);
- }
- Close(FromFH);
- FL=NULL;
- }
- }
- if (FL) UnLock(FL);
- }
- if (!error)
- {
- retval=TRUE;
- // if (FL=Lock(tofile,ACCESS_READ)) // is the new file the same as the old one ?
- // {
- // total=FB.fib_Size;
- // if (Examine(FL,&FB) && total==FB.fib_Size) retval=TRUE;
- // UnLock(FL);
- // }
- }
-
- if (!retval) // if the old file is different then delete it..
- {
- DeleteFile(tofile);
- }
- return(retval);
- }
-
- ULONG __asm __saveds LIBHBBS_NodesInList(register __a0 struct List *list)
- {
- struct Node *node;
- ULONG Nodes=0;
- if (list)
- {
- for (node=list->lh_Head;node->ln_Succ;node=node->ln_Succ)
- {
- Nodes++;
- }
- return(Nodes);
- }
- return(0);
- }
-
- V_BOOL __asm __saveds LIBHBBS_AppendStrToFile(register __a0 UBYTE *FileName, register __a1 UBYTE *String)
- {
- BPTR FH;
- V_BOOL retval=FALSE;
-
- if (LIBAssignOK(FileName))
- {
- if (FH=Open(FileName,MODE_READWRITE))
- {
- Seek(FH,0,OFFSET_END);
- if (Write(FH,String,strlen(String))==strlen(String)) retval=TRUE;
-
- Close(FH);
- }
- }
- return(retval);
- }
-
-
- /*
- HBBS_CreateNode() creates a node and returns a pointer to it.
-
- if namestr is not NULL then the a new string will be allocated and
- placed the ln_Name field.
-
- if you specify 0 for the nodesize, then the size of the node allocated
- will be the sizeof(struct Node), otherwise it'll allocate however many bytes
- you specify.
-
- All the data will be zero'd, so all your other fields will be intialized to NULL
- or 0!
-
- */
-
- struct Node __asm __saveds *LIBHBBS_CreateNode(register __a0 char *namestr,register __d0 ULONG nodesize)
- {
- struct Node *newnode;
-
- if (nodesize==0) nodesize=sizeof(struct Node);
-
- if (newnode=AllocVec(nodesize,MEMF_CLEAR|MEMF_PUBLIC))
- {
- if (namestr)
- {
- if (!(newnode->ln_Name=LIBDupStr(namestr)))
- {
- FreeVec(newnode);
- newnode=NULL; // failed!
- }
- }
- }
- return(newnode); // NULL if not enough mem, or pointer to node otherwise..
- }
-
- void __asm __saveds LIBHBBS_FreeNode(register __a0 struct Node *node,register __d0 V_BOOL RemoveIt)
- {
- if (node)
- {
- if (RemoveIt) Remove(node);
- if (node->ln_Name) LIBFreeStr(node->ln_Name);
- FreeVec(node);
- }
- }
-
- void __asm __saveds LIBHBBS_FreeListNodes(register __a0 struct List *list)
- {
- // free all ln_Names of each node in a list and remove all nodes from the list!
- // but we DON't free the list itself, we just leave it empty
-
- struct Node *node;
- if (list)
- {
- while (list->lh_Head->ln_Succ)
- {
- node=list->lh_Head;
- LIBFreeStr(node->ln_Name);
- Remove(node);
- FreeVec(node);
- }
- }
- }
-
- V_BOOL __asm __saveds LIBHBBS_SendOLM(register __d0 V_SMALLNUM FromNode,register __a0 UBYTE *FromPRG,register __d1 V_SMALLNUM ToNode,register __a1 UBYTE *Message,register __d2 BYTE Pri)
- {
- // frommnode should be 0 if something other than a door is sending the OLM
- // otheriwse fromnode should be set to your node number plus 1
- // e.g. N_ND->NodeNum+1, if fromnode
-
-
- V_BOOL retval=FALSE;
- struct OLMNode *NewOLM;
- struct NodeData *nd=NULL;
- struct NodeData *fnd;
- struct Message *NewMsg=NULL;
-
- // lets see if we can send an eall, node must be open and initalised with
- // a user loggined in and the status must be online
- if ((Message) &&
- (FromNode>=0 ) && (FromNode<=BBSGlobal->BBSNodes) &&
- (nd=LIBHBBS_NodeDataPtr(ToNode)) &&
- (nd->Status==STAT_ONLINE) &&
- (nd->OLMList) &&
- (nd->LoginType!=LOGIN_NONE) &&
- (nd->OnlineStatus==OS_ONLINE))
- {
- if (NewOLM=(struct OLMNode *)LIBHBBS_CreateNode(Message,sizeof(struct OLMNode)))
- {
- if (NewOLM->node.ln_Name=LIBDupStr(Message))
- {
- NewOLM->node.ln_Pri=Pri;
- LIBHBBS_GetTime(NewOLM->Time);
- LIBHBBS_GetDate(NewOLM->Date);
- NewOLM->FromNode=FromNode;
- if ((FromNode) && (fnd=LIBHBBS_NodeDataPtr(FromNode-1)))
- {
- if (fnd->User.Valid) // NewOLD has already been blanked by CreateNode() so the string is already null terminated..
- {
- LIBstrNcpy(NewOLM->Handle,fnd->User.CallData.Handle,LEN_HANDLE);
- }
- }
- if (FromPRG)
- {
- LIBstrNcpy(NewOLM->FromPRG,FromPRG,LEN_HANDLE);
- }
-
- // *C* add semaphore checking!
- Enqueue(nd->OLMList,(struct Node*)NewOLM);
- nd->OLMCount++;
- if (!(nd->NodeFlags & NFLG_OLMSWAITING)) nd->NodeFlags+=NFLG_OLMSWAITING;
-
- if (nd->OLMPort)
- {
- if (NewMsg=AllocVec(sizeof (struct Message),MEMF_PUBLIC|MEMF_CLEAR))
- {
- NewMsg->mn_Node.ln_Type = NT_MESSAGE;
- NewMsg->mn_ReplyPort=NULL;
- NewMsg->mn_Length=sizeof(struct Message);
-
- PutMsg(nd->OLMPort,NewMsg);
- }
- }
- retval=TRUE;
- }
- }
- }
- return(retval);
- }
-
- BOOL __asm __saveds LIBFGetsR(register __a0 BPTR FH,register __a1 UBYTE *Buffer,register __d0 LONG BufferLen)
- {
-
- // fucking amazing routine to read a file line by line but BACKWARDS from the current
- // position!! Whay!!
-
- LONG nr,startpos,where,back,foundpos=0;
- BOOL retval=TRUE,sof=FALSE,error=FALSE;
-
- UBYTE *strptr=NULL;
-
-
- Buffer[0]=0;
- BufferLen--;
-
- where=Seek(FH,0,OFFSET_CURRENT); // start of file already ?
- if (where<=0) //start of file or error
- {
- retval=FALSE;
- }
- else
- {
- startpos=where; // make a note of where we started from.
- do
- {
- back=255;
- if (where<255) back=where;
-
- if (back>BufferLen) back=BufferLen;
-
- if ((where=Seek(FH,0-back,OFFSET_CURRENT))!=-1)
- {
- where-=back;
-
- if (nr=Read(FH,Buffer,back))
- {
- Buffer[nr]=0;
- if (strptr=strrchr(Buffer,'\n'))
- {
- foundpos=where+(strptr-Buffer);
- if (Seek(FH,foundpos+1,OFFSET_BEGINNING)==-1)
- {
- error=TRUE;
- }
- }
- else
- {
- if (where==0)
- {
- if (Seek(FH,0,OFFSET_BEGINNING)==-1)
- {
- error=TRUE;
- }
- else
- {
- sof=TRUE;
- foundpos=1;
- }
- }
- else
- {
-
- if (Seek(FH,0-nr,OFFSET_CURRENT)!=-1)
- {
- where-=nr;
- }
- else
- {
- error=TRUE;
- }
- }
-
- }
- }
- else
- {
- error=TRUE;
- }
-
- }
- } while (strptr==NULL && !error && !sof);
-
- Buffer[0]=0;
- if (strptr || sof )
- {
- FGets(FH,Buffer,BufferLen);
- Seek(FH,foundpos ? foundpos-1 : 0,OFFSET_BEGINNING);
- }
- }
-
- return(retval);
-
- }
-