/*

  This is a part of the Project Frontier's Source code.

  Copyright (C) 1997-98 Francis Gastellu
                    aka Lone Runner/Aegis

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

*/

/*

Misc functions

*/
#include <dir.h>
#include <stdio.h>
#include <stdlib.h>
#include <dos.h>
#include <share.h>
#include <alloc.h>
#include <ctype.h>
#include <string.h>
#include <spawno.h>
#include <process.h>
#include <time.h>
#include <sys/types.h>
#include "..\com\keywatch.h"
#include "..\lang\ppl.h"
#include "..\lang\fortify.h"
#include "..\com\pcbdat.h"
#include "..\com\system.h"
#include "..\com\rs232.h"
#include "..\com\async2.h"
#include "..\com\vio.h"
#include "..\com\msgs.h"
#include "..\com\detect.h"
#include "..\com\tpa.h"
#include "..\lang\pcbvar.h"
#include "..\com\sharing.h"
#include "..\com\closeup.h"

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

char far tmpStr[2312];
char far tmpStr2[2312];
char far tmpDrive[MAXDRIVE];
char far tmpDir[MAXDIR];
char far tmpFile[MAXPATH];
char far tmpExt[MAXEXT];
char emptyStr[2]={0,0};
char far scrbuf[23][400];
int scrX, scrY, scrC;
char col[3];

char *connectString=(char*)&emptyStr;
int curColor=0x0F;
signed char curiso[5] = "\xFF\xFF\xFF\xFF";
int CFcount=0;
char kbdString[260]="";
long carrierSpeed=0;
char linesCounting=1;
int currentUserNum=-1;
int userLoggedNum=-1;
int globalNoDisplay=0;
int pageFlag=0;
char langExt[5]=".";
int langChanged=1;
char far systemPath[260];
char far tokenStr[260]="";
char yes='Y', no = 'N', currency = '$', dot = '.';
int validDate, validTime;
int abortScroll=0;
int ansiSeparator;
int debugScreen=0;
int barStatus=0;
int curConf=-1;
int totalUsers; // --! a updater -> nombre de users
MessageBaseType curConfMb;
long nConfs;
int screenCleared=0;
char wrap[85]="";
int maxnode=999;
int errorcorrect=0;
int savescreenindex=0;
int cmdError=0;
pplvar ppeReturnValue = {7, 0, 0, 0, 0, 0, 0};
int far macrosInterpretation=1;
int far aSuspend=0;
char far nodeFilename[256];
int far CDchecking=1;
int far disableHotkeys=0;
volatile long lastKey=0;
int screenState=1;
int printerState=0;
int pagebellState=1;
int callerAlarmState=0;
char sysopFlag = ' ';
char grafMode = 'G';
char far pageText[51]="";
int far sc_day, sc_month, sc_year;
int userMinsAllowed=60;
int userKbAllowed=32767;
int eventOn=0;
int langNum=0;
FILE *logFile;
int userTimeLog=0;
long userDateLog=0;
int userTimeLeft=0;
int userMinsOn=0;

#ifdef FORTIFY
extern long totalAllocated;
#else
long totalAllocated;
int st_Disabled=0;
#endif

// CMD.LST list
CMDlstEntry far CMD[512];
int nCMDlist=0;

userType user;
char far userAlias[26]="";

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

char far thisConfPath[50];

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void output(char *str, int to)
{
int a=-1,b,c,d,f,g,h,i, autoLoop;
char *e,*j,*k;
char newiso[4];
char var[256];
char sep;

if (globalNoDisplay)
	return;

col[2]=0;

/*if (initCode <= 0 && (to & MASK_USER))
	to &= ~MASK_USER;*/

if (str[0] == '!' || str[0] == '%')
	if (tryToExec(str))
    	return;

//if (!( (to & MASK_USER) && !(to & MASK_SYSOP) )) goto remotecolor;
strcpy(curiso, "\xFF\xFF\xFF\xFF");
start:
for (;;)
	{
    a++;
    switch (str[a])
    	{
        case 0 :
        	goto endStr;

        case 9 :
            for(d=0;d<7;d++)
            	{
            	putch(' ');
                AsyncPut(' ');
                }
            break;

        case '\n' :
        	if (to & MASK_SYSOP)
            	{
				putch('\r');
				putch('\n');
                }
            if (to & MASK_USER)
            	{
                AsyncPut('\r');
                AsyncPut('\n');
                }
        	lineCounter();
            break;

        case '@' :
        	if (macrosInterpretation)
            	{
    		    if (str[a+1] == 'X' && isHex(str[a+2]) && isHex(str[a+3]))
				    {
    	    	    strncpy(col, &str[a+2], 2);
                    b=strtol(col,&e,16);
                    curColor=b;
                    if (to & MASK_SYSOP);
		    	        {
					    //textattr(b);
                        VIOsetfore(b & 0xF);
                        VIOsetback((b & 0xF0) >> 4);
                        }
    //                remotecolor:
		            if (to & MASK_USER)
                        {
                        ansiSeparator=0;
        		        newiso[3] = isoBack(curColor);
        		        newiso[2] = isoFore(curColor);
			    	    newiso[1] = isoStyle(curColor);
				        newiso[0] = isoBlink(curColor);
					    for (b=0;b<4;b++)
	                        if (curiso[b] != newiso[b])
    	                	    sendAnsiColor(newiso[b]);
                        for (b=0;b<4;b++)
                            curiso[b] = newiso[b];
                        closeAnsiColor();
                        }
    //                if (a == -1) goto start;
		            a+=3;
		            continue;
				    }
                autoLoop=0;
                for (h=0;h<MAXPCBVAR;h++)
            	    {
                    sep = str[a+1+strlen(pcbVar[h])];
                    if (!strncmp(&str[a+1], pcbVar[h], strlen(pcbVar[h])) && (sep == '@' || sep == ':' || sep == 0 || sep == '='))
                	    {
                        i = 0;
                        f = strlen(pcbVar[h]);
                        if ((&str[a+1])[f] == ':')
                    	    {
                            g = strtol(&(&str[a+1])[f+1], &j, 10);
                            switch (*j)
                        	    {
                                case '@':
                            	    break;
                                case 'C':
                            	    i = 1;
                                    j++;
                                    break;
                                case 'R':
                            	    i = 2;
                                    j++;
                                    break;
                                case 'L':
                            	    i = 0;
                                    j++;
                                    break;
                                default:
                            	    break;
                                }
                            }
	                        else
                        	    {
    	                	    j = &(&str[a+1])[f];
                                g = 0;
                                }
                        *var=0;
                        if (*j == '=')
							{
                            k = strchr(j, '@');
                            if (k)
                            	j = k;
							}
                        if (*j == '@')
                    	    {
                    	    replacePcbVar(var, h, g, i, &str[a+1]);
                            a+= (j - (&str[a]));
                            if (*var != 0)
                        	    output(var, to);
                            autoLoop=1;
                            break;
                            }
                        }
                    }
                if (autoLoop)
                    continue;
            }

        default :
        	if (to & MASK_SYSOP)
			    putch(str[a]);
            if (to & MASK_USER)
                AsyncPut(str[a]);
        }
    }
endStr:
checkHotkeys();
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±± FUNCTION OR STATEMENT NO YET IMPLEMENTED ±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

pplvar *notImplemented(char *symb)
{
printf("\nERROR! \"%s\" is not yet implemented\n", symb);
endPPE=1;
return &emptyVar;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void lineCounter(void)
{
int a;

if (user.PageLen == 0)
	a = 24;
else
	a = user.PageLen;

if (!linesCounting)
	return;
if (++CFcount == a-1)
	more();
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int isoBack(unsigned char c)
{
c = (c & 0x70) >> 4;
return isoColor(c)+10;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int isoFore(unsigned char c)
{
c = (c & 0x7);
return isoColor(c);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int isoColor(unsigned char c)
{
switch (c)
	{
    case 0: return 30;
    case 4: return 31;
    case 2: return 32;
    case 6: return 33;
    case 1: return 34;
    case 5: return 35;
    case 3: return 36;
    case 7: return 37;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int isoStyle(unsigned char c)
{
if ((c & 0xF) >= 0x8)
	return 1;
return 0;
}

int isoBlink(unsigned char c)
{
if (c == 0 || c >= 0x80)
	return 5;
return 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int isHex(char c)
{
return ((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'));
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int tryToExec(char *str)
{
char file[MAXPATH];
int a;

strcpy(file, &str[1]);
for (a=0;a<MAXPATH;a++)
	if (file[a] == ' ')
    	{
		file[a]=0;
        break;
        }

switch(str[0])
   	{
    case '%':
    	getExistingDisplayFile(tmpStr, file, 7);
       	dispfile(tmpStr);
        break;
    case '!':
	if (!access(file, 0))
    	{
		fppe_runPPE(file);
	    return 1;
        }
    }

return 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void dispfile(char *file)
{
FILE *disp;
int _execStrings = execStrings;
execStrings = 1;
if ((disp = fopen_share(file, "rt", SH_DENYNONE)) == NULL)
	{
    return;
	}

while (!feof(disp))
	{
    *tmpStr=0;
    fgets(tmpStr, 2048, disp);
    output(tmpStr, MASK_USER|MASK_SYSOP);
    }
fclose(disp);
execStrings = _execStrings;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int isSigned(pplvar *s)
{
int a;
a = s->type;
return (a == 0xB || a == 6 || a == 8 || a == 4 || a == 0x11 || a == 5 || a == 0xE || a == 0xF || a == 0x10 || a == 0xC);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void getKey(char *s, int from)
{
int c=0;
char comp[12]="";
char d[2]="X";
clock_t quit;

if (*kbdString != 0)
	{
    c = *kbdString;
    strcpy(kbdString, kbdString+1);
	*(char *)s = c;
    s[1] = 0;
    return;
    }

if ((from & MASK_SYSOP) && !(from & MASK_USER) && !bioskey(1))
	return;

if (!(from & MASK_SYSOP) && (from & MASK_USER) && InStat()==0)
	return;

if ((from & MASK_SYSOP) && (from & MASK_USER) && InStat()==0 && !bioskey(1))
	return;

if (from & MASK_SYSOP && bioskey(1))
	c = bioskey(0);

if (from & MASK_USER)
	{
    if ((from & MASK_SYSOP && !c) || !(from & MASK_SYSOP))
		c = AsyncGet();
    if (c == 27)
    	{
        quit = clock() + 10;
        *comp=0;
        while (strlen(comp) < 9 && clock() <= quit)
        	{
	        d[0]=c;
	        strcat(comp, d);
            if (!strcmpi(comp, "[A")) goto _up;
   	        if (!strcmpi(comp, "[B")) goto _down;
            if (!strcmpi(comp, "[C")) goto _right;
            if (!strcmpi(comp, "[D")) goto _left;
            if (!strcmpi(comp, "[K")) goto _end;
            if (!strcmpi(comp, "OP")) goto _f1;
            if (!strcmpi(comp, "OQ")) goto _f2;
            if (!strcmpi(comp, "Ow")) goto _f3;
            if (!strcmpi(comp, "Ox")) goto _f4;
            if (!strcmpi(comp, "Ot")) goto _f5;
            if (!strcmpi(comp, "Ou")) goto _f6;
            if (!strcmpi(comp, "Oq")) goto _f7;
            if (!strcmpi(comp, "Or")) goto _f8;
            if (!strcmpi(comp, "Op")) goto _f10;
            if (!strcmpi(comp, "[L")) goto _chome;
            if (!strcmpi(comp, "[M")) goto _cpgup;
	        if (!strcmpi(comp, "[H")) goto _home;
//        if (!strcmpi(comp, "[H[2J")) goto _cpgdn;
            c = AsyncGet();
            if (c == -1) c = 0;
	        if (comp[1] == 0 && (c == '[' || c == 'O' || c == 'H')) quit = clock() + 10;
            }
        if (strlen(comp) > 1)
	        goto _badkey;
        c = 27;
        }
    }

if ((c & 0xFF) == 0)
	switch ((c & 0xFF00) >> 8)
		{
        case 'u':
        	_cend:
        	strcpy(s, "CTRL END");
            break;
        case 'w':
        	_chome:
        	strcpy(s, "CTRL HOME");
            break;
        case '„':
        	_cpgup:
        	strcpy(s, "CTRL PGUP");
            break;
        case 'v':
        	_cpgdn:
        	strcpy(s, "CTRL PGDN");
            break;
        case 'H':
            _up:
        	strcpy(s, "UP");
            break;
        case 'P':
            _down:
        	strcpy(s, "DOWN");
            break;
        case 'M':
            _right:
        	strcpy(s, "RIGHT");
            break;
        case 'K':
            _left:
        	strcpy(s, "LEFT");
            break;
        case 116:
        	_cright:
            strcpy(s, "CTRL LEFT");
            break;
        case 115:
        	_cleft:
            strcpy(s, "CTRL RIGHT");
            break;
        case 'G':
            _home:
        	strcpy(s, "HOME");
            break;
        case 'O':
            _end:
        	strcpy(s, "END");
            break;
        case 'I':
            _pgup:
        	strcpy(s, "PGUP");
            break;
        case 'Q':
            _pgdn:
        	strcpy(s, "PGDN");
            break;
        case 'R':
            _ins:
        	strcpy(s, "INS");
            break;
        case 'S':
            _del:
        	strcpy(s, "DEL");
            break;
        case ';':
            _f1:
        	strcpy(s, "F1");
            break;
        case '<':
            _f2:
        	strcpy(s, "F2");
            break;
        case '=':
            _f3:
        	strcpy(s, "F3");
            break;
        case '>':
            _f4:
        	strcpy(s, "F4");
            break;
        case '?':
            _f5:
        	strcpy(s, "F5");
            break;
        case '@':
            _f6:
        	strcpy(s, "F6");
            break;
        case 'A':
            _f7:
        	strcpy(s, "F7");
            break;
        case 'B':
            _f8:
        	strcpy(s, "F8");
            break;
        case 'C':
            _f9:
        	strcpy(s, "F9");
            break;
        case 'D':
            _f10:
        	strcpy(s, "F10");
            break;
        case '…':
            _f11:
        	strcpy(s, "F11");
            break;
        case '†':
            _f12:
        	strcpy(s, "F12");
            break;
        case 104:
            _af1:
        	strcpy(s, "ALT F1");
            break;
        case 105:
            _af2:
        	strcpy(s, "ALT F2");
            break;
        case 106:
            _af3:
        	strcpy(s, "ALT F3");
            break;
        case 107:
            _af4:
        	strcpy(s, "ALT F4");
            break;
        case 108:
            _af5:
        	strcpy(s, "ALT F5");
            break;
        case 109:
            _af6:
        	strcpy(s, "ALT F6");
            break;
        case 110:
            _af7:
        	strcpy(s, "ALT F7");
            break;
        case 111:
            _af8:
        	strcpy(s, "ALT F8");
            break;
        case 112:
            _af9:
        	strcpy(s, "ALT F9");
            break;
        case 113:
            _af10:
        	strcpy(s, "ALT F10");
            break;
        case 139:
            _af11:
        	strcpy(s, "ALT F11");
            break;
        case 140:
            _af12:
        	strcpy(s, "ALT F12");
            break;
        case 94:
            _cf1:
        	strcpy(s, "CTRL F1");
            break;
        case 95:
            _cf2:
        	strcpy(s, "CTRL F2");
            break;
        case 96:
            _cf3:
        	strcpy(s, "CTRL F3");
            break;
        case 97:
            _cf4:
        	strcpy(s, "CTRL F4");
            break;
        case 98:
            _cf5:
        	strcpy(s, "CTRL F5");
            break;
        case 99:
            _cf6:
        	strcpy(s, "CTRL F6");
            break;
        case 100:
            _cf7:
        	strcpy(s, "CTRL F7");
            break;
        case 101:
            _cf8:
        	strcpy(s, "CTRL F8");
            break;
        case 102:
            _cf9:
        	strcpy(s, "CTRL F9");
            break;
        case 103:
            _cf10:
        	strcpy(s, "CTRL F10");
            break;
        case 137:
            _cf11:
        	strcpy(s, "CTRL F11");
            break;
        case 138:
            _cf12:
        	strcpy(s, "CTRL F12");
            break;
        case 0:
        	break;
        default :
            _badkey:
//        	strcpy(s, "BADKEY");
/*            if (*comp != 0)
            	{
            	strcat(s, ":");
            	strcat(s, comp);
                }*/
            break;
        }
else
	{
    if (c == '')
    	{
       	strcpy(s, "DEL");
        return;
    	}
	*(char *)s = c & 0xFF;
    s[1] = 0;
    }

}


/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

pplvar *pplGetKey(int from)
{
pplvar *s;

s = fppe_newvar(7, 0, s->dim);

tmpStr[0]=0;
getKey(tmpStr, from);
fppe_strcpy(s, tmpStr);
return s;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void localCls(void)
{
VIOsetfore(curColor & 0xF);
VIOsetback((curColor & 0xF0) >> 4);

VIOclear(0, 0, 79, 23);
VIOgotoxy(0,0);
updateStatusBar();
}

void remoteCls(void)
{
//textattr(curColor);
if (user.Expert != 'Y')
	screenCleared=1;

CFcount=0;
if (connected())
    AsyncPutStr("[2J");
}

void cls(void)
{
localCls();
remoteCls();
}

int connected(void)
{
return(initCode > 0 && Carrier());
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void clrEol(void)
{
int xo, yo;
//textattr(curColor);
xo = VIOwherex();
yo = VIOwherey();
VIOsetfore(curColor & 0xF);
VIOsetback((curColor & 0xF0) >> 4);
memset(tmpStr, 0, 81);
memset(tmpStr, ' ', 80-VIOwherex());
puts_blind(tmpStr);
VIOgotoxy_blind(xo,yo);

if (connected())
    AsyncPutStr("[K");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ansiPos(int c, int l)
{
//gotoxy(c, l);
VIOgotoxy(c-1,l-1);

if (connected())
	{
    sprintf(tmpStr, "[%d;%dH", l, c);
    AsyncPutStr(tmpStr);
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void chat(void)
{
static int chatActive=0;
if (chatActive)
	return;
chatActive=1;
//savescrn();
//print("\n@X0FChat mode entered\n");
if (!runSystemPPE("CHAT.PPE"))
	internal_chat();
//print("\n@X0FChat mode ended\n");
//delay(6);
//restscrn();
chatActive=0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void internal_chat(void)
{
int a,b;
char k[2][15];
int top[2] = {2, 13};
int curl[2] = {2, 13};
int curc[2] = {1, 1};
int cursSide=0;
int quit=0;
char *m;
int oldlc = linesCounting;

linesCounting = 0;

curColor = 7;
cls();

for (a=1;a<=23;a+=11)
	{
	ansiPos(1, a);
	print("@X0FÄ@X0BÄ@X03Ä@X08ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ@X03Ä@X0BÄ@X0FÄ");
    }

ansiPos(curc[0], curl[0]);

*k[0]=0;
*k[1]=0;

while (!quit)
	{
    getKey(k[0], MASK_SYSOP);
    getKey(k[1], MASK_USER);

    for (a=0;a<2;a++)
	    {
	    if (*k[a] != 0 && strlen(k[a]) == 1)
		    {
            hdlt:
            switch (*k[0])
            	{
                case 27:
                	if (a == 0) quit = 1;
                    break;
                case 8:
		            if (cursSide != a)
        	            {
        	            ansiPos(curc[a], curl[a]);
                        cursSide = a;
                        }
                    if (curc[a] > 1)
						{
						curc[a]--;
        	            ansiPos(curc[a], curl[a]);
                        print(" ");
        	            ansiPos(curc[a], curl[a]);
                        }
                    *k[a] = 0;
                    break;
                default:
		            if (cursSide != a)
        	            {
        	            ansiPos(curc[a], curl[a]);
                        cursSide = a;
                        }
                    print(k[a]);
                    curc[a]++;
                	if (curc[a] > 77 || *k[a] == 10)
                    	{
                        curc[a] = 1;
                        curl[a]++;
                        if (curl[a] > top[a] + 9)
                            {
                            m = (char *)malloc(256);
							for (b=5;b<10;b++)
                            	{
	                            m[0]=0;
                                scrtext(m, 1, top[a]+b, 79, 1);
                                ansiPos(1, top[a]+b);
                                clrEol();
                                ansiPos(1, top[a]+b-5);
                                clrEol();
                                rtrim(m);
                                print(m);
                                }
                            free(m);
	                        curl[a] = top[a]+5;
                            }
        	            ansiPos(curc[a], curl[a]);
                        cursSide = a;
                        }
                    if (*k[a] == 13)
                    	{
                        *k[a]=10;
                        goto hdlt;
                        }
                    *k[a] = 0;
                }
            }
        }
    }
linesCounting = oldlc;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void print(char *str)
{
output(str, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void print_saved(char *str)
{
int savedColor = curColor;
output(str, MASK_BOTH);
curColor = savedColor;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void scrtext(char *s, int col, int lig, int len, int code)
{
unsigned char *temp;
int x,l;
char color[5] = "@Xnn";
char ch[2]="X";
int lastColor=0;

*s = 0;

temp = (char *)malloc((len+1)*2);
//gettext(col, lig, col+len-1, lig, temp);
VIOgetra(col-1, lig-1, (col+len-1)-1, lig-1, (int *)temp);

for (x=0,l=0;x<len*2 && l<255;x+=2)
	{
    if (code && temp[x+1] != lastColor)
    	{
        if (l > 250)
        	break;
        sprintf(&color[2], "%02X", temp[x+1]);
        strcat(s, color);
        lastColor = temp[x+1];
        l+=4;
        }
    ch[0] = temp[x];
    strcat(s, ch);
    l++;
    }
free(temp);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void rtrim(char *s)
{
while (s[strlen(s)-1] == 32)
	s[strlen(s)-1] = 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void savescrn(void)
{
int a;
FILE *o;

fnsplit(tempFilesPath, tmpDrive, tmpDir, NULL, NULL);
sprintf(tmpExt, ".%03d", node);
sprintf(tmpFile, "SCR%05d", ++savescreenindex);
fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, tmpExt);
o = fopen_share(tmpStr, "wt", SH_DENYRW);
fprintf(o, "%d\n%d\n%d\n", VIOwherex()+1,VIOwherey()+1,curColor);
/*for (a=0;a<=wherey()-1;a++)
    scrtext(scrbuf[a], 1, a+1, 80, 1);
*scrbuf[a] = 0;*/
for (a=0;a<=23;a++)
    {
	scrtext(scrbuf[a], 1, a+1, 80, 1);
	fputs(scrbuf[a], o);
	fputc('\n', o);
    }
fclose(o);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void restscrn(void)
{
int a,x,y,c;
FILE *o;

cls();

fnsplit(tempFilesPath, tmpDrive, tmpDir, NULL, NULL);
sprintf(tmpExt, ".%03d", node);
sprintf(tmpFile, "SCR%05d", savescreenindex);
fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, tmpExt);
o = fopen_share(tmpStr, "rt", SH_DENYWR);

fscanf(o, "%d", &x);
fscanf(o, "%d", &y);
fscanf(o, "%d", &c);
fgets(tmpStr, 2, o);
//for (a=0;*scrbuf[a]!=0;a++)
for (a=0;a<=23;a++)
    {
    ansiPos(1, a+1);
    fgets(tmpStr, 1024, o);
    if (tmpStr[strlen(tmpStr)-1] == '\n') tmpStr[strlen(tmpStr)-1] = 0;
    /*rtrim(scrbuf[a]);
	print(scrbuf[a]);*/
	rtrim(tmpStr);
	print(tmpStr);
    }
ansiPos(x, y);
color(c);
fclose(o);

fnsplit(tempFilesPath, tmpDrive, tmpDir, NULL, NULL);
sprintf(tmpExt, ".%03d", node);
sprintf(tmpFile, "SCR%05d", savescreenindex--);
fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, tmpExt);
unlink(tmpStr);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void color(int c)
{
char newiso[4];
int b;

ansiSeparator=0;
curColor = c;

VIOsetfore(curColor & 0xF);
VIOsetback((curColor & 0xF0) >> 4);

newiso[3] = isoBack(curColor);
newiso[2] = isoFore(curColor);
newiso[1] = isoStyle(curColor);
newiso[0] = isoBlink(curColor);
for (b=0;b<4;b++)
	sendAnsiColor(newiso[b]);
closeAnsiColor();
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void readString(char *s, int max, FILE *f)
{
fgets(s, max, f);
if (s[strlen(s)-1] != '\n')
	while (!feof(f) && fgetc(f) != '\n');
else
	s[strlen(s)-1] = 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

bool readBool(FILE *f)
{
char val[3];
readString(val, 3, f);
if (strcmp(val, "0"))
	return -1;
return 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

long readLong(FILE *f)
{
char val[34];
readString(val, 33, f);
return atol(val);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

long readLongHex(FILE *f)
{
char val[34];
char *endptr;
readString(val, 33, f);
return strtol(val, &endptr, 16);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void reduceString(char *str, int len)
{
int a;
int zeroFlag=0;

if (strlen(str) >= len)
	zeroFlag = 1;

for (a=len;a>0;a--)
	{
    if (!zeroFlag && str[a-1] != 0)
		continue;
	else
		zeroFlag = 1;
    if (str[a-1] == ' ')
   		str[a-1] = 0;
    else
   	break;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void getUser(int userNum, userType *u)
{
TPArec *tpa;
FILE *usr;
unsigned int max;
struct date d_date;
struct time d_time;
long a, b;

if ((usr = fopen_share(usersFile, "rb", SH_DENYWR)) == NULL)
    return;

fseek(usr, 0, SEEK_END);
max = ftell(usr)/400;

if (userNum > max || userNum <= 0) // if user out of range, get logged user
	if (userLoggedNum == -1) // if no logged user for now
    	userNum = 1; // get sysop
    else
	    userNum = userLoggedNum;

if (u != &user) // change currentUserNum only if we are getting user from PPE and not from a GetSystemUser
	currentUserNum = userNum;
else
	userLoggedNum = userNum; // else change userloggednum

fseek(usr, 400*(long)(userNum-1), SEEK_SET);

u->Index = userNum;
fread(u, sizeof(userType)-20, 1, usr);

u->DirtyFlag = 0;
u->ClearScreen = 0;
u->MailFlag = 0;
u->NoAskFSEditor = 0;
u->FSEditor = 0;
u->ScrollMsgBody = 0;
u->ShortMsgHdr = 0;
u->WideEditor = 0;
u->ChatStatus = 0;
u->Reserved1 = 0;
u->Reserved2 = 0;
u->Reserved3 = 0;
u->Reserved4 = 0;
u->Reserved5 = 0;
u->Reserved6 = 0;
u->Reserved7 = 0;

if (u->FlagsBitmap & 1)
	u->DirtyFlag = -1;
if (u->FlagsBitmap & 2)
	u->ClearScreen = -1;
if (u->FlagsBitmap & 4)
	u->MailFlag = -1;
if (u->FlagsBitmap & 8)
	u->NoAskFSEditor = -1;
if (u->FlagsBitmap & 16)
	u->FSEditor = -1;
if (u->FlagsBitmap & 32)
	u->ScrollMsgBody = -1;
if (u->FlagsBitmap & 64)
	u->ShortMsgHdr = -1;
if (u->FlagsBitmap & 128)
	u->WideEditor = -1;
if (u->Flags2Bitmap & 1)
	u->ChatStatus = -1;
if (u->Flags2Bitmap & 2)
	u->Reserved1 = -1;
if (u->Flags2Bitmap & 4)
	u->Reserved2 = -1;
if (u->Flags2Bitmap & 8)
	u->Reserved3 = -1;
if (u->Flags2Bitmap & 16)
	u->Reserved4 = -1;
if (u->Flags2Bitmap & 32)
	u->Reserved5 = -1;
if (u->Flags2Bitmap & 64)
	u->Reserved6 = -1;
if (u->Flags2Bitmap & 128)
	u->Reserved7 = -1;

reduceString(u->FullName,25);
reduceString(u->City,24);
reduceString(u->Password,12);
reduceString(u->DataPhone,13);
reduceString(u->VoicePhone,13);
reduceString(u->LastDateOn,6);
reduceString(u->LastTimeOn,5);
reduceString(u->LastDir,6);
reduceString(u->Comment1,30);
reduceString(u->Comment2,30);
reduceString(u->RegExpDate,6);

getdate(&d_date);
d_time.ti_min=0;
d_time.ti_hour=0;
d_time.ti_hund=0;
d_time.ti_sec=0;

a = 25568 + DosToUnix(&d_date, &d_time) / 86400;
strnzcpy(tmpStr, u->LastDateOn, 6);
b = sysCharDateToPPLDate(tmpStr);

// A = Date today in PPL Date Type
// B = User Last Date On

if (u == &user)
	{
    if (a != b)
    	{
		Double2BdReal(u->BytesDownloadedToday, 0);
    	u->TimeOn=0;
    	}
    updateNodeFile();
	tpa = openTPA("UALIAS");
	if (tpa != NULL)
	    {
		getTPA(tpa, tmpStr, 25, curConf, 0, userLoggedNum);
	    reduceString(tmpStr, 25);
	    closeTPA(tpa);
	    strncpy(userAlias, tmpStr, 25);
    	}
    }

fclose(usr);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void getStr(char *s, size_t size, size_t n, FILE *f)
{
fread(s, size, n, f);
s[size]=0;
rtrim(s);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int userRecNr(char *u)
{
char b = *u;
FILE *usr;
unsigned int n;
char name[26];
char *user;

user = strdup(u);
rtrim(user);

if (b==0)
	return -1;

b = toupper(b);
if (b < 'A') b = 'A';
if (b > 'Z') b = 'Z';

fnsplit(userIndexFilesPath, tmpDrive, tmpDir, NULL, NULL);
sprintf(tmpExt, ".%c", b);
fnmerge(tmpStr, tmpDrive, tmpDir, "PCBNDX", tmpExt);

if ((usr = fopen_share(tmpStr, "rb", SH_DENYWR)) == NULL)
	{
    farfree(user);
    fclose(usr);
    return -1;
    }

while (!feof(usr))
	{
	fread(&n, 2, 1, usr);
	getStr(name, 25, 1, usr);
    rtrim(name);
	if (!stricmp(name, u))
    	break;
	}

farfree(user);

if (!feof(usr))
	{
    fclose(usr);
	return n;
    }

fclose(usr);
return -1;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void wait(void)
{
runSystemPPE("WAIT.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void pause(void)
{
runSystemPPE("PAUSE.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void who(void)
{
runSystemPPE("WHO.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

unsigned long charDateToPPLDate(char *d, int forceEnglish)
{
int a,b=0;
long p[3];
char *base, *endptr;
char ac[3][5];
unsigned long n;
struct time d_time;
struct date d_date;
unsigned long nr=0;
int _d, m, y;

if (forceEnglish) { m = 0; _d = 1; y = 2; } else { m = monthPart(); _d = dayPart(); y = yearPart(); }

validDate=0;

d_time.ti_min = 0;
d_time.ti_hour = 0;
d_time.ti_hund = 0;
d_time.ti_sec = 0;

base = d;
for (a=0;a<3;a++)
	{
	if (*(base-1) == 0 && !(a==0)) break;
    p[a] = strtol(base, &endptr, 10);
	base = endptr+1;
    b++;
    }

if (b < 3)
	{
	strncpy(ac[0], d, 2);
	strncpy(ac[1], d+2, 2);
	strncpy(ac[2], d+4, 4);
	ac[0][2]=0;
	ac[1][2]=0;
	ac[2][4]=0;
	d_date.da_year = atoi(ac[y]);
	d_date.da_mon = atoi(ac[m]);
	d_date.da_day = atoi(ac[_d]);
    }
else
	{
    d_date.da_year = p[y];
    d_date.da_mon = p[m];
    d_date.da_day = p[_d];
    }

if (d_date.da_day == 0 && d_date.da_mon == 0 && d_date.da_year == 0)
    d_date.da_year = 79;
if (d_date.da_day == 0)
	d_date.da_day = 1;
if (d_date.da_mon == 0)
	d_date.da_mon = 1;

if (inRange(d_date.da_mon, 1, 12) && inRange(d_date.da_day, 1, 31) && inRange(d_date.da_year, 0, 99))
	validDate=1;

if (d_date.da_year < 100)
	if (d_date.da_year < 79)
		d_date.da_year += 2000;
	else
		d_date.da_year += 1900;

nr = DosToUnix(&d_date, &d_time);
return 25568 + nr / 86400;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

unsigned long sysCharDateToPPLDate(char *d)
{
char a[3], b[3], c[3];
struct time d_time;
struct date d_date;

strncpy(a, d, 2);
strncpy(b, d+2, 2);
strncpy(c, d+4, 2);
a[2]=0;
b[2]=0;
c[2]=0;
d_date.da_year = atoi(a);
d_date.da_mon = atoi(b);
d_date.da_day = atoi(c);

if (d_date.da_day == 0 && d_date.da_mon == 0 && d_date.da_year == 0)
    d_date.da_year = 79;
if (d_date.da_day == 0)
	d_date.da_day = 1;
if (d_date.da_mon == 0)
	d_date.da_mon = 1;

if (d_date.da_year < 79)
	d_date.da_year += 2000;
else
	d_date.da_year += 1900;

d_time.ti_min = 0;
d_time.ti_hour = 0;
d_time.ti_hund = 0;
d_time.ti_sec = 0;

sc_day = d_date.da_day;
sc_month = d_date.da_mon;
sc_year = d_date.da_year;

return 25568 + DosToUnix(&d_date, &d_time) / 86400;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

unsigned long charDDateToPPLDate(char *d)
{
char a[5], b[3], c[3];
struct time d_time;
struct date d_date;

strncpy(a, d, 4);
strncpy(b, d+4, 2);
strncpy(c, d+6, 2);
a[4]=0;
b[2]=0;
c[2]=0;
d_date.da_year = atoi(a);
d_date.da_mon = atoi(b);
d_date.da_day = atoi(c);

if (d_date.da_day == 0 && d_date.da_mon == 0 && d_date.da_year == 0)
    d_date.da_year = 79;
if (d_date.da_day == 0)
	d_date.da_day = 1;
if (d_date.da_mon == 0)
	d_date.da_mon = 1;

d_time.ti_min = 0;
d_time.ti_hour = 0;
d_time.ti_hund = 0;
d_time.ti_sec = 0;

return 25568 + DosToUnix(&d_date, &d_time) / 86400;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int dayPart(void)
{
return 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int monthPart(void)
{
return 1;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int yearPart(void)
{
return 2;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int inRange(unsigned long value, unsigned long min, unsigned long max)
{
return (value >= min && value <= max);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void UnixToDos(unsigned long DateVal, struct date *d, struct time *t)
{
int annee;
int mois;
int jour;
int heure;
int minute;
unsigned long seconde;

seconde = DateVal % 86400;
DateVal /= 86400;

annee = (DateVal / 365)+2;

jour = DateVal % 365 - (annee-2)/4;

if (!(annee & 3))
	{
    if (inRange(jour, 1, 31))
			mois = 1;
    else if (inRange(jour, 32, 60)) {
			mois = 2;
			jour -= 31; }
    else if (inRange(jour, 61, 91)) {
			mois = 3;
			jour -= 60; }
	else if (inRange(jour, 92, 121)) {
			mois = 4;
			jour -= 91; }
    else if (inRange(jour, 122, 152)) {
			mois = 5;
			jour -= 121; }
    else if (inRange(jour, 153, 182)) {
			mois = 6;
			jour -= 152; }
    else if (inRange(jour, 183, 213)) {
			mois = 7;
			jour -= 182; }
    else if (inRange(jour, 214, 244)) {
			mois = 8;
			jour -= 213; }
	else if (inRange(jour, 245, 274)) {
			mois = 9;
			jour -= 244; }
	else if (inRange(jour, 275, 305)) {
			mois = 10;
			jour -= 274; }
	else if (inRange(jour, 306, 335)) {
			mois = 11;
			jour -= 305; }
	else if (inRange(jour, 336, 366)) {
			mois = 12;
			jour -= 335; }
    }
else
	{
	if (inRange(jour, 1, 31))
			mois = 1;
    else if (inRange(jour, 32, 59)) {
			mois = 2;
			jour -= 31; }
	else if (inRange(jour, 60, 90)) {
			mois = 3;
			jour -= 59; }
	else if (inRange(jour, 91, 120)) {
			mois = 4;
			jour -= 90; }
	else if (inRange(jour, 121, 151)) {
			mois = 5;
			jour -= 120; }
	else if (inRange(jour, 152, 181)) {
			mois = 6;
			jour -= 151; }
    else if (inRange(jour, 182, 212)) {
			mois = 7;
			jour -= 181; }
    else if (inRange(jour, 213, 243)) {
			mois = 8;
			jour -= 212; }
    else if (inRange(jour, 244, 273)) {
			mois = 9;
			jour -= 243; }
    else if (inRange(jour, 274, 304)) {
			mois = 10;
			jour -= 273; }
    else if (inRange(jour, 305, 334)) {
			mois = 11;
			jour -= 304; }
    else if (inRange(jour, 335, 365)) {
			mois = 12;
			jour -= 334; }
    }

heure = seconde/3600;
minute = seconde/60 - heure*60;
seconde = seconde % 60;

d->da_year = annee+1968;
d->da_mon = mois;
d->da_day = jour;
t->ti_hour = heure;
t->ti_min = minute;
t->ti_sec = seconde;
t->ti_hund = 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

unsigned long charTimeToPPLTime(char *d)
{
int a,b=0;
long p[3]={0,0,0};
char *base, *endptr;
char ac[3];
unsigned long n;
int pm=0;

validTime=0;

base = d;
for (a=0;a<3;a++)
	{
	if (*(base-1) == 0 && !(a==0)) break;
    p[a] = strtol(base, &endptr, 10);
	base = endptr+1;
    b++;
    }

strncpy(ac, &d[strlen(d)-2], 2);
ac[2]=0;
if (!stricmp(ac, "pm"))
	pm = 1;

if (pm && p[0] <= 12)
	p[0] += 12;

if (inRange(p[0], 0, 23) && inRange(p[1], 0, 59) && inRange(p[2], 0, 59))
	validTime=1;

return p[0] * 3600 + p[1] * 60 + p[2];
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int militaryTime(void)
{
return 1;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

char boolean(char val)
{
if (val == 0 || val == 'N') return 0;
return 1;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void waitEnter(void)
{
char k[15]="";
while (*k != 13)
	getKey(k, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void tokenize(char *s, char *dest)
{
Ctokenize(s, ' ', dest);
}

void Ctokenize(char *s, char c, char *dest)
{
int a;
int prev;

strncpy(dest, s, 255);
dest[strlen(s) & 0xFF] = 0;
prev = -1;
for (a=0;a<strlen(dest);a++)
	{
    if (dest[a] == c)
		{
    	if (dest[a] == prev)
			{
			prev = dest[a];
	    	strcpy(&dest[a], &dest[a+1]);
            a--;
            }
        else
			{
			prev = dest[a];
            if (a!=0)
	        	dest[a] = ';';
            else
            	a--;
            }
        }
    else
	    prev = dest[a];
    }
}

void strcrpl(char *s, char a, char b)
{
int c=0;
while (s[c] != 0)
    {
	if (s[c] == a)
    	s[c] = b;
    c++;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void getToken(char *s, char *src)
{
int a=0;
*s=0;
while (src[a] != ';')
	{
    s[a] = src[a];
    if (s[a] == 0) break;
    a++;
    }
if (src[a] == 0)
	*src=0;
else
	strcpy(src, &src[a+1]);
s[a] = 0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int tokCount(char *src)
{
int a=0,b=0;
if (*src == 0)
	return 0;
while (src[a] != 0)
	{
	if (src[a] == ';')
    	b++;
    a++;
    }
if (src[a-1] != ';')
	b++;
return b;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void strcsup(char *s, char a)
{
int c=0;
while (s[c] != 0)
    {
	if (s[c] == a)
    	{
		strcpy(&s[c], &s[c+1]);
        continue;
        }
    c++;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void strsrpl(char *s, char *a, char *b)
{
int c=0;
while (s[c] != 0)
    {
	if (!strncmp(&s[c], a, strlen(a)))
    	{
        strcpy(tmpStr2, &s[c+strlen(a)]);
        s[c]=0;
        strncat(s, b, 2048);
        s[c+strlen(b)]=0;
        strncat(s, tmpStr2, 2048);
        c+=strlen(b);
        continue;
        }
    c++;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void strssup(char *s, char *a)
{
int c=0;
while (s[c] != 0)
    {
	if (!strncmp(&s[c], a, strlen(a)))
    	{
        strcpy(&s[c], &s[c+strlen(a)]);
        c-=strlen(a);
        continue;
        }
    c++;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void more(void)
{
runSystemPPE("MORE.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void bye(void)
{
runSystemPPE("BYE.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void hangup(void)
{
runSystemPPE("HANGUP.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void goodbye(void)
{
runSystemPPE("GOODBYE.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void inputText(char *s, char *allowed, int len)
{
char k[15];

*s=0;
while (1)
	{
    *k=0;
	getKey(k, MASK_BOTH);
    if (strlen(k) == 1)
    	{
        if (strchr(allowed, *k) || *k == 8 || *k == 13)
        	{
            switch (*k)
            	{
                case 8:
                	if (strlen(s) > 0)
                    	{
	                	output(k, MASK_BOTH);
   		                output(" ", MASK_BOTH);
       		        	output(k, MASK_BOTH);
            	        s[strlen(s)-1] = 0;
                        }
                    break;
                case 13:
                	return;
                default:
		            if (strlen(s) < len)
			            {
						output(k, MASK_BOTH);
                        strcat(s, k);
                        }
                    break;
                }
            }
        }
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey1(void)
{
output(functionKey1, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey2(void)
{
output(functionKey2, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey3(void)
{
output(functionKey3, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey4(void)
{
output(functionKey4, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey5(void)
{
output(functionKey5, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey6(void)
{
output(functionKey6, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey7(void)
{
output(functionKey7, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey8(void)
{
output(functionKey8, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey9(void)
{
output(functionKey9, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey10(void)
{
output(functionKey10, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey11(void)
{
output(functionKey11, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void ShiftKey12(void)
{
output(functionKey12, MASK_BOTH);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

/*void shell(void)
{
    int save;
    char *commandcom;

    savescrn();
    print("\n@X0FSysop is out to DOS, please wait...");
    clrscr();
    save = getdisk();
	tmpStr2[0] = '\\';
    getcurdir(0,&tmpStr2[1]);
	printf("Type EXIT to return...\n");
    commandcom = getenv( "COMSPEC");

	unInstallAPIHandler();
#ifndef DEBUG
	remkeyboardisr();
#endif
	suspendCom();
//	setEnvironment();
	*(unsigned int *)0x0040001AL = *(unsigned int *)0x0040001CL; // Flush keyboard

	spawnlpeo("", commandcom, commandcom,NULL,environ);

//	removeEnvironment();
    setdisk(save);
    chdir(tmpStr2);
    updateStatusBar();
    restoreCom();
	installAPIHandler();
#ifndef DEBUG
	keyboardisr();
#endif
    restscrn();
    k = 0; kf = 0; lastKey = *(long*)0x0040006CL;

}*/

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int runSystemPPE(char *ppename)
{
int rtn;
char *q, *p;
int pos;

p = ppename;
q = strchr(p, ' '); // Are there arguments ?
if (q != NULL)
	{
    pos = q - p;
    p[pos] = 0; // separate ppe & args
    strcpy(tmpStr, q+1);
    tokenize(tmpStr, tokenStr); // tokenize args
    }
fnsplit(systemPPEPath, tmpDrive, tmpDir, NULL, NULL);
fnsplit(ppename, NULL, NULL, tmpFile, tmpExt);
fnmerge(tmpStr, tmpDrive, tmpDir, tmpFile, tmpExt);
rtn = !fppe_runPPE(tmpStr);
if (!rtn)
	{
    sprintf(tmpStr, "System PPE \"%s\" is missing", ppename);
    fppe_runtimeError(tmpStr);
    }
return rtn;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void lang(void)
{
//runSystemPPE("LANG.PPE");
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void closeAnsiColor(void)
{
if (ansiSeparator > 0)
	AsyncPut('m');
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void sendAnsiColor(int colorCode)
{
char cv[3];

AsyncPutStr(++ansiSeparator == 1 ? "[" : ";");
itoa(colorCode, cv, 10);
AsyncPutStr(cv);
if (!colorCode)
	{
	curiso[1] = 0;
	curiso[2] = 0;
	curiso[3] = 0;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int putch(int c)
{
char x;
char y;

x = VIOwherex();
y = VIOwherey();

switch (c)
	{
    case 13:
    	VIOgotoxy(0, y);
        x=0;
        break;
    case 10:
        if (y == 23)
            scroll();
        else
	    	VIOgotoxy(x, ++y);
        break;
    case 8:
        if (x>0)
			VIOgotoxy(--x, y);
        break;
    default:
        if (x == 79)
        	{
			VIOputc(c);
            x=0;
            y++;
            if (y == 24)
            	{
				scroll();
                y--;
                }
			VIOgotoxy(x, y);
            }
        else
			{
			VIOputc(c);
            x++;
            }
        break;
    }

asm mov ax, 0x0200
asm mov dh, y
asm mov dl, x
asm xor bh, bh
asm int 0x10
return c;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void scroll(void)
{
int a;
char *p = MK_FP(VIOsegment(), 0);
memmove(&p[0], &p[160],23*160);
for (a=0;a<160;a+=2)
	{
	p[23*160+a] = 32;
    p[23*160+a+1] = curColor;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void dispOff(void)
{
struct REGPACK reg;
if (screenState)
    {
	reg.r_ax = 0x0501;
	intr(0x10, &reg);
    reg.r_ax = 0x0100;
    reg.r_cx = 0x1400;
    intr(0x10, &reg);
    screenState=0;
    }
}

void dispOn(void)
{
struct REGPACK reg;
if (!screenState)
	{
	reg.r_ax = 0x0500;
	intr(0x10, &reg);
    reg.r_ax = 0x0100;
    reg.r_cx = 0x0607;
    intr(0x10, &reg);
    screenState=1;
    }
}

void checkHotkeys(void)
{
static int kk=0;
static int globalOff=0;
unsigned long tick;
static long last=0;

#ifdef DEBUG

char fc[80];
static long lastUpdate=0;

if (disableHotkeys)
	return;

if (clock() - lastUpdate > 2)
    if (debugScreen)
	    {
        ltoa(farcoreleft(), fc, 10);
        debug_gotoxy(0, 1);
        debug_puts("Free memory: ");
        debug_puts(fc);
	    debug_puts("    ");
#ifdef FORTIFY
        debug_gotoxy(0, 2);
        ltoa(totalAllocated, fc, 10);
        debug_puts("Total allocated: ");
        debug_puts(fc);
	    debug_puts("    ");
        debug_gotoxy(0, 3);
#else
        debug_gotoxy(0, 2);
#endif
        if( heapcheck() == _HEAPCORRUPT )
          debug_puts( "Heap is corrupted.\n" );
        else
          debug_puts( "Heap is OK.\n" );

        lastUpdate = clock();
        }
#else

if (clock() - last > 18)
	{
	last = clock();
	updateStatusBar();
    }

if (disableHotkeys)
	return;

#endif

checkCarrier();

if (autoReleaseTime)
	{
	if (kk++ > 30) kk = 0;
	if (!kk) KillTime();
    }

#ifndef DEBUG

if (keyPressed)
	{

    keyPressed=0;
	lastKey = *(long*)0x0040006CL;
    if (!kf) // Simple keys
        {
	    if (k==0x3F)
        	{
        	k = 0;
            shellKey();
            }
	    if (k==0x44)
        	{
        	k = 0;
			chat();
            }
        if (k==0x43)
        	{
        	k = 0;
            if (screenState)
	            {
				dispOff();
	            globalOff=1;
                }
    	    else
            	{
        		dispOn();
	            globalOff=0;
                }
            }
        }
    if (kf == 1) // SHIFT keys
        {
        if (k==0x3B)
        	{
        	k = 0;
		    ShiftKey1();
            }
        if (k==0x3C)
        	{
        	k = 0;
		    ShiftKey2();
            }
        if (k==0x3D)
        	{
        	k = 0;
		    ShiftKey3();
            }
        if (k==0x3E)
        	{
        	k = 0;
		    ShiftKey4();
            }
        if (k==0x3F)
        	{
        	k = 0;
		    ShiftKey5();
            }
        if (k==0x40)
        	{
        	k = 0;
		    ShiftKey6();
            }
        if (k==0x41)
        	{
        	k = 0;
		    ShiftKey7();
            }
        if (k==0x42)
        	{
        	k = 0;
		    ShiftKey8();
            }
        if (k==0x43)
        	{
        	k = 0;
		    ShiftKey9();
            }
        if (k==0x44)
        	{
        	k = 0;
		    ShiftKey10();
            }
        if (k==0x57)
        	{
        	k = 0;
		    ShiftKey11();
            }
        if (k==0x58)
        	{
        	k = 0;
		    ShiftKey12();
            }
        }
    if (kf == 4) // ALT keys
        {
        if (k==0x23)
            {
        	k = 0;
		    barStatus++;
			barStatus %= 2;
		    updateStatusBar();
            }
        if (k==0x3B)
            {
        	k = 0;
            userTimeLeft -= userTimeLeft > 5 ? 5 : 1;
		    updateStatusBar();
            }
        if (k==0x3C)
            {
        	k = 0;
            userTimeLeft += userTimeLeft > 5 ? 5 : 1;
		    updateStatusBar();
            }
        }
    if (kf == 2) // CTRL keys
      {
      }

    if (kf == 6) // CTRL-ALT keys
        {
        if (k==0x2e)
            {
        	k = 0;
       	    breakPPE = 1;
            }
        }
    }

    do {
		if (disableScrSaveCarrier && initCode > 0 && Carrier())
        	break;
	    tick = *(long*)0x0040006CL;
        if (tick < lastKey) tick += 1572480L;

	    if (tick > lastKey + (minScrClear * 18.2))
            dispOff();
		else
        	if (!globalOff)
			   	dispOn();
        } while (0);

#endif
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void updateStatusBar(void)
{
int ox, oy, oc, i;
char t[80]="";
struct time t2;
long timeNow;
static long lastTime=0;

ox = VIOwherex();
oy = VIOwherey();
oc = curColor;

#ifndef DEBUGGER
#ifndef RUNTIME
if (userLoggedNum != -1)
	{
	gettime(&t2);
    if (!lastTime)
    	{
		lastTime = t2.ti_hour*3600+t2.ti_min*60+t2.ti_sec;
        if (userTimeLeft == secondWarning || userTimeLeft == firstWarning || userTimeLeft <= 0)
        	{
            sprintf(tmpStr2, "TIMEHOOK.PPE %d", userTimeLeft >= 0 ? userTimeLeft : 0);
	        runSystemPPE(tmpStr2);
            }
        }
    else
    	{
        timeNow = t2.ti_hour*3600+t2.ti_min*60+t2.ti_sec;
        if (timeNow < lastTime) timeNow += 86400;
        if (timeNow > lastTime + 60)
	        {
	        lastTime = timeNow;
            user.TimeOn++;
            userMinsOn++;
            userTimeLeft--;
            if (userTimeLeft == secondWarning || userTimeLeft == firstWarning || userTimeLeft <= 0)
            	{
                sprintf(tmpStr2, "TIMEHOOK.PPE %d", userTimeLeft >= 0 ? userTimeLeft : 0);
		        runSystemPPE(tmpStr2);
                }
	        }
        }
    }
#endif
#endif

switch (barStatus)
	{
    case 0:

		VIOgotoxy_blind(0, 24);
		VIOsetback(7);
		VIOsetfore(0);
		puts_blind("                                                                                 ");

        // node
        if (node != 0)
        	{
            VIOsetback(4);
            VIOsetfore(0xE);
            itoa(node, t, 10);
		    VIOgotoxy_blind(0, 24);
            puts_blind(t);
            }
        else
        	{
            VIOsetback(7);
            VIOsetfore(0);
		    VIOgotoxy_blind(0, 24);
            puts_blind("   ");
            }

        // speed
        VIOsetback(7);
        VIOsetfore(0);
        if (initCode <= 0 || !carrierSpeed)
	        strcpy(t, "(Local) ");
        else
	        sprintf(t, "(%5ld) ", carrierSpeed);
        VIOgotoxy_blind(3, 24);
        puts_blind(t);

        // UserName/City
        if (userLoggedNum > 0)
	        {
	        strncpy(t, user.FullName, 25);
	        strcat(t, " - ");
	        strncat(t, user.City, 24);
	        for (i=strlen(t);i<50;i++) t[i]=' ';
	        t[50]=0;
	        VIOgotoxy_blind(11, 24);
    	    puts_blind(t);
            }

        // Next
        VIOgotoxy_blind(61, 24);
        puts_blind("³ALT-H=Next³");

        // page
        VIOgotoxy_blind(73, 24);
       	VIOsetback(0xF);
       	VIOsetfore(0);
        if (pageFlag)
            puts_blind("p");

        if (userTimeLog != 0)
        	{
            // MinOn
            VIOsetback(3);
            VIOsetfore(14);
            VIOgotoxy_blind(74, 24);
            sprintf(t, "%3d", userMinsOn >= 0 ? userMinsOn : 0);
	        puts_blind(t);

            // MinLeft
            VIOsetback(1);
            VIOsetfore(15);
            VIOgotoxy_blind(77, 24);
            sprintf(t, "%3d", userTimeLeft >= 0 ? userTimeLeft : 0);
	        puts_blind(t);
        	}


        break;

    case 1:

		VIOgotoxy_blind(0, 24);
		VIOsetback(7);
		VIOsetfore(0);
		puts_blind("                                                                                 ");

        VIOgotoxy_blind(1, 24);
       	VIOsetback(0xF);
       	VIOsetfore(0);
        if (pageFlag)
            puts_blind("p");

	    VIOgotoxy_blind(2, 24);
        strncpy(t, pageText, 50);
        for (i=strlen(t);i<50;i++) t[i]=' ';
        VIOsetback(7);
        VIOsetfore(0);
   	    puts_blind("³");
   	    puts_blind(t);
   	    puts_blind("³");

        sprintf(t, "%3d", farcoreleft()/1024);
	    VIOgotoxy_blind(77, 24);
		VIOsetback(4);
		VIOsetfore(0xE);
        puts_blind(t);
        break;
	}

VIOgotoxy_blind(ox, oy);
VIOsetfore(oc&0xF);
VIOsetback((oc&0xF0) >> 4);
curColor = oc;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int puts_blind(char *c)
{
char *p=c;
int n;

while (*p)
    {
	switch (*p)
    	{
        case 8:
        	backup(1);
            break;
        case 9:
        	for (n=0;n<8;n++)
				VIOputc(' ');
            break;
        default:
			VIOputc(*p);
        }
    p++;
    }
}

int puts_blindn(char *c, int max)
{
char *p=c;
int n, l=0;

while (*p && l<max)
    {
	switch (*p)
    	{
        case 8:
        	backup(1);
            l--;
            break;
        case 9:
        	for (n=0;n<7 && l<max;n++)
				{
				VIOputc(' ');
                l++;
                }
            break;
        default:
			VIOputc(*p);
            l++;
            break;
        }
    p++;
    }
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void join(int confNum)
{
char cmd[20];
sprintf(cmd, "JOIN.PPE %d", confNum);
runSystemPPE(cmd);
}

void loadConf(int confNum)
{
getMessageBase(confNum, thisConfPath);
curConf = confNum;

initMessageBase(&curConfMb, thisConfPath);
openMessageBase(&curConfMb);
closeMessageBase(&curConfMb);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void getMessageBase(int confNum, char *confpath)
{
FILE *in;
sprintf(tmpStr, "Conf%d", confNum);
getProfileString(tmpStr, "MessageBase", "MSGS", confpath, 50, iniFile);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void registerCommand(char *command, char *keystrokes, int minlevel)
{
st_Disabled=1;
CMD[nCMDlist].command = (char *)malloc(strlen(command)+1);
CMD[nCMDlist].keystroke = (char *)malloc(strlen(keystrokes)+1);
strcpy(CMD[nCMDlist].command, command);
CMD[nCMDlist].level = minlevel;
strcpy(CMD[nCMDlist].keystroke, keystrokes);
nCMDlist++;
st_Disabled=0;
}

void invalidCommands(void)
{
st_Disabled=1;
while (nCMDlist)
	{
	free(CMD[nCMDlist-1].command);
	free(CMD[nCMDlist-1].keystroke);
    nCMDlist--;
    }
st_Disabled=0;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void execCommand(char *command)
{
int c;
int a,b;
char *p,*p2;
int n;
char cmd[256]="";

memset(cmd, 0, 256);
strncpy(cmd, command, 255);
strcrpl(cmd, ';', ' ');
if (strchr(cmd, ' '))
	n = strchr(cmd, ' ') - cmd;
else
	n = strlen(cmd);

c = -1;
for (a=0;a<nCMDlist;a++)
	{
    if (CMD[a].level > user.Security)
    	continue;
    b = strcmpicount(CMD[a].command, cmd);
    if (b == n)
    	{
        c = a;
       	break;
        }
    }
if (c == -1)
	{
    if (++cmdError == 15) runSystemPPE("TOOBAD.PPE");
    runSystemPPE("BADCMD.PPE");
    return;
    }

cmdError = 0;
strcpy(tmpStr,CMD[c].keystroke);
p2 = strchr(tmpStr, ' ');

if (strchr(cmd, ' '))
	p = strchr(cmd, ' ')+1;
else
	p = NULL;

*tmpStr2 = 0;
if (p2 != NULL)
	{
	n = p2 - (char *)&tmpStr;
    tmpStr[n] = 0;
    p2++;
    strcpy(tmpStr2, p2);
    if (p != NULL)
    	{
	    strcat(tmpStr2, " ");
    	strcat(tmpStr2, p);
        }
    }
else
    if (p != NULL)
	    strcpy(tmpStr2, p);

if (!strcmpi(&tmpStr[strlen(tmpStr)-4], ".PPE"))
	{
    tokenize(tmpStr2, tokenStr);
	fppe_runPPE(CMD[c].keystroke);
    }
else
	print(CMD[c].keystroke);
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

int strcmpicount(char *s1, char *s2)
{
int a=0;
while (toupper(s1[a]) == toupper(s2[a]) && s2[a] != 0)
	a++;
return a;
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void kbdFlush(void)
{
kbdString[0]=0;
*(unsigned int *)0x0040001AL = *(unsigned int *)0x0040001CL; // Flush keyboard
}

/*
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±±
ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ
*/

void addUser(char *userName)
{
userType *u;
FILE *usr;
unsigned int max;
struct date d_date;
struct time d_time;
long a, b;
long userNum;

u = malloc(sizeof(userType));
if (u == NULL)
	return;

if (strlen(userName) > 25) userName[25]=0;

if ((usr = fopen_share(usersFile, "r+b", SH_DENYRW)) == NULL)
	{
    free(u);
    return;
    }

fseek(usr, 0, SEEK_END);
max = ftell(usr)/400;

userNum = max+1;
if (!addUserRecNr(userName, userNum))
	{
    fppe_runtimeError("Could not add user");
    fclose(usr);
    free(u);
    return;
    }

fseek(usr, 0, SEEK_END);

getdate(&d_date);
sprintf(tmpStr, "%02d%02d%02d", d_date.da_year <= 1999 ? d_date.da_year - 1900 : d_date.da_year - 2000, d_date.da_mon, d_date.da_day);

makeSpaceString(u->FullName, userName, 25, 1);
makeSpaceString(u->City, "", 24, 0);
makeSpaceString(u->Password, "", 12, 1);
makeSpaceString(u->DataPhone, "", 13, 0);
makeSpaceString(u->VoicePhone, "", 13, 0);
strncpy(u->LastDateOn, tmpStr, 6);
strncpy(u->LastTimeOn, "00:00", 5);
u->Expert='N';
u->Protocol='N';
u->FlagsBitmap = 0;
strncpy(u->LastDir, tmpStr, 6);
u->Security=levelUserAgree;
u->TimesOn=0;
u->PageLen=24;
u->FilesUploaded=0;
u->FilesDownloaded=0;
Double2BdReal(u->BytesDownloadedToday, 0);
makeSpaceString(u->Comment1, "", 30, 0);
makeSpaceString(u->Comment2, "", 30, 0);
u->TimeOn=0;
makeSpaceString(u->RegExpDate, "010179", 6, 1);
u->ExpSecurity=expiredSecurity;
u->Compatibility1=0;
memset(&u->ConfRegBitmap, 0, 5);
memset(&u->ExpConfBitmap, 0, 5);
memset(&u->SelConfBitmap, 0, 5);
Double2BdReal(u->BytesDownloaded, 0);
Double2BdReal(u->BytesUploaded, 0);
u->DeletedFlag='N';
memset(&u->LastMsgRd, 0, 40*sizeof(bsreal));
u->RecNum=userNum;
u->Flags2Bitmap=0;
memset(&u->Reserved8, 0, 8);
u->LastConfIn=0;
u->Index = userNum;
u->ChatStatus = -1;
mapFlags(u);

fwrite(u, sizeof(userType)-20, 1, usr);
fclose(usr);
free(u);

createAllTPANewEntry(userNum);
}

int addUserRecNr(char *u, int userNum)
{
char b = *u;
FILE *usr;
unsigned int n;
char name[26];
char *user;

user = strdup(u);
rtrim(user);

if (b==0)
	return 0;

b = toupper(b);
if (b < 'A') b = 'A';
if (b > 'Z') b = 'Z';

fnsplit(userIndexFilesPath, tmpDrive, tmpDir, NULL, NULL);
sprintf(tmpExt, ".%c", b);
fnmerge(tmpStr, tmpDrive, tmpDir, "PCBNDX", tmpExt);

if ((usr = fopen_share(tmpStr, "r+b", SH_DENYRW)) == NULL)
	{
    farfree(user);
    fclose(usr);
    return 0;
    }

while (!feof(usr))
	{
	fread(&n, 2, 1, usr);
	getStr(name, 25, 1, usr);
    rtrim(name);
	if (!stricmp(name, u))
    	break;
	}

farfree(user);

if (!feof(usr))
	{
    fclose(usr);
	return 0;
    }

makeSpaceString(name, u, 25, 1);
fwrite(&userNum, 2, 1, usr);
fwrite(name, 25, 1, usr);

fclose(usr);
return -1;
}

int invalidUserRecNr(char *u)
{
char b = *u;
FILE *usr;
unsigned int n;
char *user;
char name[26];

user = strdup(u);
rtrim(user);

if (b==0)
	return 0;

b = toupper(b);
if (b < 'A') b = 'A';
if (b > 'Z') b = 'Z';

fnsplit(userIndexFilesPath, tmpDrive, tmpDir, NULL, NULL);
sprintf(tmpExt, ".%c", b);
fnmerge(tmpStr, tmpDrive, tmpDir, "PCBNDX", tmpExt);

if ((usr = fopen_share(tmpStr, "r+b", SH_DENYRW)) == NULL)
	{
    farfree(user);
    fclose(usr);
    return 0;
    }

while (!feof(usr))
	{
	fread(&n, 2, 1, usr);
	getStr(name, 25, 1, usr);
    rtrim(name);
	if (!stricmp(name, u))
    	{
        fseek(usr, -27, SEEK_CUR);
        n = 0;
		fwrite(&n, 2, 1, usr);
        memset(name, ' ', 25);
        fwrite(name, 25, 1, usr);
    	break;
        }
	}

farfree(user);

if (feof(usr))
	{
    fclose(usr);
	return 0;
    }

fclose(usr);
return -1;
}


void makeSpaceString(char *dest, char*src, int size, int maj)
{
int zeroFlag=0;
int a;

for (a=0;a<size;a++)
	{
    if (src[a]==0)
    	zeroFlag=1;
    if (!zeroFlag)
	    dest[a] = maj ? toupper(src[a]) : src[a];
    else
    	dest[a] = ' ';
    }
//dest[size]=0;
}

void mapFlags(userType *u)
{
u->FlagsBitmap = 0;
u->Flags2Bitmap = 0;
if (u->DirtyFlag)
	u->FlagsBitmap |= 1;
if (u->ClearScreen)
	u->FlagsBitmap |= 2;
if (u->MailFlag)
    u->FlagsBitmap |= 4;
if (u->NoAskFSEditor)
	u->FlagsBitmap |= 8;
if (u->FSEditor)
	u->FlagsBitmap |= 16;
if (u->ScrollMsgBody)
	u->FlagsBitmap |= 32;
if (u->ShortMsgHdr)
	u->FlagsBitmap |= 64;
if (u->WideEditor)
	u->FlagsBitmap |= 128;
if (u->ChatStatus)
	u->Flags2Bitmap |= 1;
if (u->Reserved1)
	u->Flags2Bitmap |= 2;
if (u->Reserved2)
	u->Flags2Bitmap |= 4;
if (u->Reserved3)
	u->Flags2Bitmap |= 8;
if (u->Reserved4)
	u->Flags2Bitmap |= 16;
if (u->Reserved5)
	u->Flags2Bitmap |= 32;
if (u->Reserved6)
	u->Flags2Bitmap |= 64;
if (u->Reserved7)
	u->Flags2Bitmap |= 128;
}

void putUser(userType *uo)
{
userType *u;
long userNum;
FILE *usr;
unsigned int max;
struct date d_date;
struct time d_time;
long a, b;
TPArec *tpa;

u = malloc(sizeof(userType));
if (u == NULL)
	return;

userNum = uo->Index;
if (userNum == -1)
	{
    free(u);
	return;
    }

if ((usr = fopen_share(usersFile, "r+b", SH_DENYRW)) == NULL)
	{
    free(u);
    return;
    }

fseek(usr, 400*(userNum-1), SEEK_SET);

makeSpaceString(u->FullName, uo->FullName, 25, 1);
makeSpaceString(u->City, uo->City, 24, 0);
makeSpaceString(u->Password, uo->Password, 12, 1);
makeSpaceString(u->DataPhone, uo->DataPhone, 13, 0);
makeSpaceString(u->VoicePhone, uo->VoicePhone, 13, 0);
makeSpaceString(u->LastDateOn, uo->LastDateOn, 6, 1);
makeSpaceString(u->LastTimeOn, uo->LastTimeOn, 5, 1);
u->Expert=uo->Expert;
u->Protocol=uo->Protocol;
u->FlagsBitmap = uo->FlagsBitmap;
makeSpaceString(u->LastDir, uo->LastDir, 6, 1);
u->Security=uo->Security;
u->TimesOn=uo->TimesOn;
u->PageLen=uo->PageLen;
u->FilesUploaded=uo->FilesUploaded;
u->FilesDownloaded=uo->FilesDownloaded;
memcpy(&u->BytesDownloadedToday, &uo->BytesDownloadedToday, 8);
makeSpaceString(u->Comment1, uo->Comment1, 30, 0);
makeSpaceString(u->Comment2, uo->Comment2, 30, 0);
u->TimeOn=uo->TimeOn;
makeSpaceString(u->RegExpDate, uo->RegExpDate, 6, 1);
u->ExpSecurity=uo->ExpSecurity;
u->Compatibility1=uo->Compatibility1;
memset(&u->ConfRegBitmap, 0, 5);
memset(&u->ExpConfBitmap, 0, 5);
memset(&u->SelConfBitmap, 0, 5);
memcpy(&u->BytesDownloaded, &uo->BytesDownloaded, 8);
memcpy(&u->BytesUploaded, &uo->BytesUploaded, 8);
u->DeletedFlag=uo->DeletedFlag;
memset(&u->LastMsgRd, 0, 40*sizeof(bsreal));
u->RecNum=uo->RecNum;
u->Flags2Bitmap=uo->Flags2Bitmap;
memset(&u->Reserved8, 0, 8);
u->LastConfIn=uo->LastConfIn;
u->Index = uo->Index;
u->ChatStatus = uo->ChatStatus;
mapFlags(uo);
u->FlagsBitmap = uo->FlagsBitmap;
u->Flags2Bitmap = uo->Flags2Bitmap;

fwrite(u, sizeof(userType)-20, 1, usr);
free(u);
fclose(usr);

if (uo->Index == user.Index && !closing)
	getUser(uo->Index, &user);
}

void PPLDateToSysCharDate(char *chardate, unsigned long ppldate)
{
struct date dt;
struct time tm;
time_t t;

t = (ppldate - 25568) * 86400;
UnixToDos(t, &dt, &tm);
sprintf(tmpStr, "%02d%02d%02d", dt.da_year <= 1999 ? dt.da_year - 1900 : dt.da_year - 2000, dt.da_mon, dt.da_day);
strncpy(chardate, tmpStr, 6);
chardate[6]=0;
}

void PPLDateToCharDate(char *chardate, unsigned long ppldate, int forceEnglish)
{
struct date dt;
struct time tm;
time_t t;
int d;

t = (ppldate - 25568) * 86400;
UnixToDos(t, &dt, &tm);
if (forceEnglish) d = 1; else d = dayPart();
sprintf(tmpStr, "%02d/%02d/%02d", d == 0 ? dt.da_day : dt.da_mon, d == 0 ? dt.da_mon : dt.da_day, dt.da_year <= 1999 ? dt.da_year - 1900 : dt.da_year - 2000);
strncpy(chardate, tmpStr, 8);
chardate[8]=0;
}

void setConfFlags(int conf, unsigned char flags, int u)
{
TPArec *tpa;

tpa = openTPA("UCNFFLAG");
putTPA(tpa, &flags, 1, conf, 1, u);
closeTPA(tpa);
}

unsigned char confFlags(unsigned int conf)
{
unsigned char c;
TPArec *tpa;

tpa = openTPA("UCNFFLAG");
getTPA(tpa, &c, 1, conf, 1, currentUserNum);
closeTPA(tpa);
return c;
}

void setLmr(long confNum, long msgNum, long u)
{
TPArec *tpa;
long hi, lo;
long m;

if (confNum < 0) confNum = 0;
if (confNum > nConfs-1) confNum = nConfs-1;

hi = HiMsgNum(confNum);
lo = LoMsgNum(confNum);

if (msgNum < lo) msgNum = lo;
if (msgNum > hi) msgNum = hi;

m = msgNum;

tpa = openTPA("LASTREAD");
putTPA(tpa, &m, 4, confNum, 1, u);
closeTPA(tpa);
}

long HiMsgNum(long confNum)
{
MessageBaseType Mb;
long hi;

getMessageBase(confNum, thisConfPath);
initMessageBase(&Mb, thisConfPath);
openMessageBase(&Mb);

hi = BsReal2Long(Mb.Header.HiMsg);

closeMessageBase(&Mb);
return hi;
}

long LoMsgNum(long confNum)
{
MessageBaseType Mb;
long lo;

getMessageBase(confNum, thisConfPath);
initMessageBase(&Mb, thisConfPath);
openMessageBase(&Mb);

lo = BsReal2Long(Mb.Header.LoMsg);

closeMessageBase(&Mb);
return lo;
}

long getLmr(long confNum, long u)
{
TPArec *tpa;
long m;

tpa = openTPA("LASTREAD");
getTPA(tpa, &m, 4, confNum, 1, u);
closeTPA(tpa);
return m;
}

void backup(int n)
{
int x,a;

if (n<=0) return;

x = VIOwherex()+1;
for (a=0;a<n && x>1;a++)
    x--;
//gotoxy(x, wherey());
VIOgotoxy(x-1,VIOwherey());

if (connected())
	{
    sprintf(tmpStr, "[%dD", n);
    AsyncPutStr(tmpStr);
    }
}

void forward(int n)
{
int x,a;

x = VIOwherex()+1;
for (a=0;a<n && x<80;a++)
    x++;
//gotoxy(x, wherey());
VIOgotoxy(x-1,VIOwherey());

if (connected())
	{
    sprintf(tmpStr, "[%dC", n);
    AsyncPutStr(tmpStr);
    }

}

char *strrstr(char *s1, char *s2)
{
char *p;

for (p = (char *)(s1 + strlen(s1)-1);p >= s1;p--)
	{
    if (!strncmp(p, s2, strlen(s2)))
    	return p;
    }
return NULL;
}

char *strnchr(char *str, char c,int len)
{
int i;

for(i=0;i<len;i++)
	if (str[i] == c) return(str+i);

return(NULL);
}

void suspendCom(void)
{               
if (initCode > 0)
	{
	aSuspend=1;
    rs_modctrl(RS_WRTMCR,RS_MCRRTS,RS_LINOFF);
	rs_close();
	initCode=0;
    }
}

void restoreCom(void)
{
if (aSuspend)
	{
	comInit();
    aSuspend=0;
    }
}

long DosToUnix(struct date *d, struct time *t)
{
int annee, jour, mois, decal=0;

jour = d->da_day;
mois = d->da_mon;
annee = d->da_year-1968;

if (annee % 4) decal = 1;

switch (mois)
	{
	case 2:
		jour += 31;
        break;
	case 3:
		jour += 60 - decal;
        break;
	case 4:
		jour += 91 - decal;
        break;
	case 5:
		jour += 121 - decal;
        break;
	case 6:
		jour += 152 - decal;
        break;
	case 7:
		jour += 182 - decal;
        break;
	case 8:
		jour += 213 - decal;
        break;
	case 9:
		jour += 244 - decal;
        break;
	case 10:
		jour += 274 - decal;
        break;
	case 11:
		jour += 305 - decal;
        break;
	case 12:
		jour += 335 - decal;
        break;
	}

return jour * 86400 + (annee - 2) * 365 * 86400 + ((annee-2)/4)*86400 + (t->ti_min*60 + t->ti_hour*3600 + t->ti_sec);
}

char *stristr(char *s1, char *s2)
{
char *p;
for (p=s1;*p;p++)
    if (!strncmpi(p, s2, strlen(s2)))
    	return p;
return NULL;
}

void getExistingDisplayFile(char *dest, char *base, int flag)
{
if (flag & DISP_SEC && flag & DISP_GRAPH && flag & DISP_LANG)
	{
    fnsplit(base, tmpDrive, tmpDir, tmpFile, tmpExt);
    sprintf(tmpStr2, "%s%d%c", tmpFile, user.Security, grafMode);
    strcpy(tmpExt, langExt);
    fnmerge(dest, tmpDrive, tmpDir, tmpStr2, tmpExt);
    if (!access(dest, 0))
	    return;
	}

if (flag & DISP_SEC && flag & DISP_GRAPH)
	{
	sprintf(tmpStr2, "%s%d", tmpFile, user.Security);
	strcpy(tmpExt, langExt);
	fnmerge(dest, tmpDrive, tmpDir, tmpStr2, tmpExt);
	if (!access(dest, 0))
		return;
    }

if (flag & DISP_SEC)
	{
	sprintf(tmpStr2, "%s%c", tmpFile, grafMode);
	strcpy(tmpExt, langExt);
	fnmerge(dest, tmpDrive, tmpDir, tmpStr2, tmpExt);
	if (!access(dest, 0))
		return;
    }

if (flag & DISP_SEC && flag & DISP_GRAPH)
	{
	fnsplit(base, NULL, NULL, NULL, tmpExt);
	sprintf(tmpStr2, "%s%d%c", tmpFile, user.Security, grafMode);
	fnmerge(dest, tmpDrive, tmpDir, tmpStr2, tmpExt);
	if (!access(dest, 0))
		return;
    }

if (flag & DISP_SEC)
	{
	sprintf(tmpStr2, "%s%d", tmpFile, user.Security);
	fnmerge(dest, tmpDrive, tmpDir, tmpStr2, tmpExt);
	if (!access(dest, 0))
		return;
	}

if (flag & DISP_GRAPH)
	{
	sprintf(tmpStr2, "%s%c", tmpFile, grafMode);
	fnmerge(dest, tmpDrive, tmpDir, tmpStr2, tmpExt);
	if (!access(dest, 0))
		return;
    }

strcpy(dest, base);
}

int psa(int v)
{
TPArec *tpa;
/*       Valid values for var:   1 = Alias Support Enabled
                                 2 = Verify Support Enabled
                                 3 = Address Support Enabled
                                 4 = Password Support Enabled
                                 5 = Statistics Support Enabled
                                 6 = Notes Support Enabled*/
switch (v)
	{
    case 1:
		tpa = openTPA("UALIAS");
		if (tpa != NULL) { closeTPA(tpa); return 1; }
    case 2:
		tpa = openTPA("UVERIF");
		if (tpa != NULL) { closeTPA(tpa); return 1; }
    case 3:
		tpa = openTPA("UADDRESS");
		if (tpa != NULL) { closeTPA(tpa); return 1; }
    case 4:
		tpa = openTPA("UPWDEXP");
		if (tpa != NULL) { closeTPA(tpa); return 1; }
    case 5:
		tpa = openTPA("USTATS");
		if (tpa != NULL) { closeTPA(tpa); return 1; }
    case 6:
		tpa = openTPA("NOTES");
		if (tpa != NULL) { closeTPA(tpa); return 1; }
    }
return 0;
}

char *strnzcpy(char *a, char *b, int n)
{
a[n]=0;
return strncpy(a, b, n);
}

void shellKey(void)
{
runSystemPPE("SHELL.PPE");
}
