home *** CD-ROM | disk | FTP | other *** search
- #ifndef XPKMASTER_PASSWORD_C
- #define XPKMASTER_PASSWORD_C
-
- /* Routinesheader
-
- Name: password.c
- Main: xpkmaster
- Versionstring: $VER: password.c 1.13 (27.03.1998)
- Author: SDI
- Distribution: Freeware
- Description: password requester related things
-
- 1.0 27.12.96 : first version
- 1.1 28.12.96 : starting to code the stuff
- 1.2 29.12.96 : optimized and removed bugs
- 1.3 02.01.97 : corrected return handling
- 1.4 01.03.97 : fixed tag parsing error
- 1.5 10.04.97 : now old screen comes to front after Request
- 1.6 15.10.97 : TimeOut now uses timer.device
- 1.7 07.11.97 : timout of 0 again means no timeout
- 1.8 27.12.97 : added title line to passrequest
- 1.9 09.01.98 : gadget uses gadtools now
- 1.10 18.01.98 : added 5 position tags
- 1.11 21.01.98 : added verification mode
- 1.12 21.02.98 : uses new style register definition
- 1.13 27.03.98 : some optimizations
- */
-
- #include <proto/intuition.h>
- #include <proto/exec.h>
- #include <proto/utility.h>
- #include <proto/gadtools.h>
- #include <exec/memory.h>
- #include <exec/errors.h>
- #include <intuition/sghooks.h>
- #include <intuition/intuitionbase.h>
- #include <intuition/gadgetclass.h>
- #include <xpk/xpk.h>
- #include <xpk/xpkprefs.h>
- #include "texts.h"
- #include "xpkmaster.h"
-
- #define TESTSIZE 13
-
- #define VERIFY_OFF 0
- #define VERIFY_ON 1
- #define VERIFY_ACTIVE 2
- #define VERIFY_DONE 3
-
- static const struct PassCharData {
- ULONG Flag;
- UBYTE Lower;
- UBYTE Upper;
- } TestField[TESTSIZE] = {
- {XPKPASSFF_30x39,0x30,0x39}, {XPKPASSFF_41x46,0x41,0x46},
- {XPKPASSFF_61x66,0x61,0x66}, {XPKPASSFF_47x5A,0x47,0x5A},
- {XPKPASSFF_67x7A,0x67,0x7A}, {XPKPASSFF_20, 0x20,0x20},
- {XPKPASSFF_SPECIAL7BIT,0x21,0x2F},
- {XPKPASSFF_SPECIAL7BIT,0x3A,0x40},
- {XPKPASSFF_SPECIAL7BIT,0x5B,0x60},
- {XPKPASSFF_SPECIAL7BIT,0x7B,0x7E},
- {XPKPASSFF_C0xDE,0xC0,0xDE}, {XPKPASSFF_DFxFF,0xDF,0xFF},
- {XPKPASSFF_SPECIAL8BIT,0xA0,0xBF},
- };
-
- /* this is no public structure !! */
- struct RequestData {
- ULONG rd_Time;
- ULONG rd_GadgFlags;
- ULONG rd_BufSize;
- WORD rd_WinLeft;
- WORD rd_WinTop;
- WORD rd_WinWidth;
- WORD rd_WinHeight;
- UWORD rd_WinCenter;
- UWORD rd_Verify;
- STRPTR rd_Title;
- STRPTR rd_GivenBuffer;
- struct Window * rd_Window;
- struct Screen * rd_GivenScreen;
- struct Screen * rd_FirstScreen;
- struct timerequest * rd_TimeRequest;
- STRPTR rd_PassBuffer;
- UBYTE rd_ScreenTitle[80];
- UBYTE rd_KeyBuffer[9];
- };
-
- static void SendTimerReq(struct RequestData *rd)
- {
- rd->rd_TimeRequest->tr_node.io_Command = TR_ADDREQUEST;
- rd->rd_TimeRequest->tr_time.tv_secs = rd->rd_Time;
- SendIO((struct IORequest *) rd->rd_TimeRequest);
- }
-
- static ASM(ULONG) PassHookFunc(REG(a0, struct Hook *hook),
- REG(a2, struct SGWork *sgw), REG(a1, ULONG *msg))
- {
- struct RequestData *rd;
-
- rd = (struct RequestData *) sgw->Gadget->UserData;
-
- if(rd->rd_Time)
- AbortIO((struct IORequest *) rd->rd_TimeRequest);
-
- if(*msg == SGH_KEY)
- {
- STRPTR passbuf = rd->rd_PassBuffer;
- ULONG bufpos = sgw->BufferPos-1;
- STRPTR wbuf = sgw->WorkBuffer;
-
- switch(sgw->EditOp)
- {
- case EO_INSERTCHAR:
- {
- register UBYTE c = sgw->Code;
-
- if(rd->rd_Verify == VERIFY_ACTIVE)
- {
- if(c != passbuf[bufpos])
- {
- sgw->Actions |= SGA_BEEP; /* let the screen beep */
- sgw->Actions &= ~SGA_USE; /* do not use char */
- }
- else
- wbuf[bufpos] = '*';
- }
- else
- {
- register ULONG i;
- for(i = 0; i < TESTSIZE; ++i)
- {
- if((rd->rd_GadgFlags & TestField[i].Flag) &&
- (c >= TestField[i].Lower) && (c <= TestField[i].Upper))
- break;
- }
- if(i == TESTSIZE)
- {
- sgw->Actions |= SGA_BEEP; /* let the screen beep */
- sgw->Actions &= ~SGA_USE; /* do not use char */
- }
- else
- {
- passbuf[bufpos] = c;
- passbuf[sgw->NumChars] = 0;
- wbuf[bufpos] = '*';
- }
- }
- }
- break;
- case EO_CLEAR:
- if(rd->rd_Verify != VERIFY_ACTIVE)
- *passbuf = 0;
- *wbuf = 0;
- sgw->NumChars = sgw->BufferPos = 0;
- sgw->EditOp = EO_BIGCHANGE;
- break;
- case EO_DELBACKWARD:
- if(rd->rd_Verify != VERIFY_ACTIVE)
- passbuf[sgw->NumChars] = 0;
- break;
- case EO_ENTER:
- if(rd->rd_Verify == VERIFY_ON && sgw->NumChars)
- {
- SetWindowTitles(rd->rd_Window, strings[TXT_VERIFY_PASS], (STRPTR) ~0);
- rd->rd_Verify = VERIFY_ACTIVE;
- *wbuf = 0;
- sgw->NumChars = sgw->BufferPos = 0;
- sgw->EditOp = EO_BIGCHANGE;
- sgw->Actions &= ~SGA_END;
- }
- else if(rd->rd_Verify == VERIFY_ACTIVE && !passbuf[sgw->NumChars])
- rd->rd_Verify = VERIFY_DONE;
- case EO_NOOP:
- break;
- /* prevent to complicated edit operations, like cursor move */
- default:
- sgw->Actions &= ~SGA_USE;
- sgw->Actions |= SGA_BEEP;
- break;
- } /* switch */
- return ~0;
- }
- else if(*msg == SGH_CLICK) /* on click set last character */
- {
- sgw->BufferPos = sgw->NumChars;
- sgw->EditOp = EO_BIGCHANGE;
- }
- else
- return 0;
- }
-
- static struct Hook PassHook = { {0}, (ULONG (*) ()) PassHookFunc, 0, 0};
-
- /* returns XPKERR codes */
- static LONG DoRequest(struct RequestData *rd)
- {
- struct Screen *scr;
- struct MsgPort *MsgPort = 0;
- LONG err = XPKERR_UNKNOWN;
-
- if(rd->rd_GivenScreen)
- scr = rd->rd_GivenScreen;
- else if(!(scr = LockPubScreen(0)))
- return XPKERR_UNKNOWN;
-
- *rd->rd_PassBuffer = 0;
-
- if(!rd->rd_Time || (MsgPort = CreateMsgPort()))
- {
- ULONG tflag = rd->rd_Time ? 1 << MsgPort->mp_SigBit : 0;
-
- if(!tflag || (rd->rd_TimeRequest = (struct timerequest *)
- CreateIORequest(MsgPort, sizeof(struct timerequest))))
- {
- if(!tflag || !OpenDevice("timer.device",UNIT_VBLANK,
- (struct IORequest *) rd->rd_TimeRequest,0))
- {
- APTR vi;
-
- if((vi = GetVisualInfoA(scr, 0)))
- {
- struct Gadget *gadg, *gl = 0;
- struct NewGadget ng;
- ULONG i;
-
- i = 4 + scr->WBorLeft + scr->WBorRight;
-
- if(rd->rd_WinWidth < i + 50)
- rd->rd_WinWidth = scr->Width >> 1;
- if(rd->rd_WinWidth > scr->Width)
- rd->rd_WinWidth = scr->Width;
- ng.ng_Width = rd->rd_WinWidth - i;
-
- i = 4 + scr->WBorTop + scr->Font->ta_YSize + 1 + scr->WBorBottom;
-
- if(rd->rd_WinHeight < i + scr->Font->ta_YSize + 6)
- rd->rd_WinHeight = i + scr->Font->ta_YSize + 6;
- if(rd->rd_WinHeight > scr->Height)
- rd->rd_WinHeight = scr->Height;
- ng.ng_Height = rd->rd_WinHeight - i;
-
- ng.ng_TopEdge = scr->WBorTop + scr->Font->ta_YSize + 1 + 2;
- ng.ng_LeftEdge = scr->WBorLeft + 2;
- ng.ng_GadgetText = 0;
- ng.ng_TextAttr = scr->Font;
- /* ng.ng_GadgetID is not used --> not initialized */
- ng.ng_Flags = 0;
- ng.ng_VisualInfo = vi;
- ng.ng_UserData = rd;
-
- if(rd->rd_WinLeft < 0)
- rd->rd_WinLeft = (scr->Width - rd->rd_WinWidth) >> 1;
- else if(rd->rd_WinCenter)
- rd->rd_WinLeft -= (rd->rd_WinWidth >> 1);
-
- if(rd->rd_WinTop < 0)
- rd->rd_WinTop = (scr->Height - rd->rd_WinHeight) >> 1;
- else if(rd->rd_WinCenter)
- rd->rd_WinTop -= (rd->rd_WinHeight >> 1);
-
- if(rd->rd_WinTop < 0)
- rd->rd_WinTop = 0;
- if(rd->rd_WinLeft < 0)
- rd->rd_WinLeft = 0;
-
- if((gadg = CreateContext(&gl)) && (gadg = CreateGadget(
- STRING_KIND, gadg, &ng,
- GTST_EditHook, &PassHook,
- STRINGA_Justification, GACT_STRINGCENTER,
- GTST_MaxChars, rd->rd_BufSize-1,
- TAG_DONE)))
- {
- struct Window *window;
-
- if((rd->rd_Window = window = OpenWindowTags(0,
- WA_Left, rd->rd_WinLeft,
- WA_Top, rd->rd_WinTop,
- WA_Height, rd->rd_WinHeight,
- WA_Width, rd->rd_WinWidth,
- WA_Gadgets, gl,
- WA_IDCMP, IDCMP_GADGETUP|IDCMP_ACTIVEWINDOW|IDCMP_CLOSEWINDOW,
- WA_Flags, WFLG_DRAGBAR|WFLG_DEPTHGADGET|WFLG_ACTIVATE|
- WFLG_RMBTRAP|WFLG_CLOSEGADGET,
- WA_Title, rd->rd_Title,
- WA_PubScreen, scr,
- WA_AutoAdjust, TRUE,
- WA_PubScreenFallBack, TRUE, TAG_DONE)))
- {
- struct IntuiMessage *msg;
- BOOL stop = 0;
-
- rd->rd_FirstScreen = IntuitionBase->FirstScreen;
- ScreenToFront(scr);
- if(tflag)
- SendTimerReq(rd);
-
- while(!stop)
- {
- if((i = Wait((1<<window->UserPort->mp_SigBit)|tflag)) & tflag)
- { /* when tflag is zero, this is never reached */
- if(rd->rd_TimeRequest->tr_node.io_Error == IOERR_ABORTED)
- SendTimerReq(rd); /* got aborted, resend */
- else
- stop = 20;
- }
-
- if(i & (1 << window->UserPort->mp_SigBit))
- {
- while(!stop && (msg = (struct IntuiMessage *)
- GetMsg(window->UserPort)))
- {
- if(msg->Class == IDCMP_ACTIVEWINDOW)
- ActivateGadget(gadg, window, 0);
- else if(msg->Class == IDCMP_CLOSEWINDOW)
- stop = 10;
- else /* if(msg->Class == IDCMP_GADGETUP) */
- stop = 1;
- ReplyMsg((struct Message *) msg);
- }
- }
- }
- if(stop >= 20)
- err = XPKERR_REQTIMEOUT;
- else if(rd->rd_Verify == VERIFY_ACTIVE)
- err = XPKERR_WRONGPW;
- else if(stop >= 10 || !*rd->rd_PassBuffer)
- err = XPKERR_ABORTED;
- else
- err = XPKERR_OK;
-
- if(tflag)
- {
- AbortIO((struct IORequest *) rd->rd_TimeRequest);
- WaitIO((struct IORequest *) rd->rd_TimeRequest);
- }
- }
- CloseWindow(window);
- if(rd->rd_FirstScreen != scr) /* possibly dangerous routine */
- {
- struct Screen *sc;
- Forbid();
- sc = IntuitionBase->FirstScreen;
- while((sc = sc->NextScreen) && sc != rd->rd_FirstScreen)
- ;
- if(sc)
- ScreenToFront(sc);
- Permit();
- }
- }
- if(gl)
- FreeGadgets(gl);
- FreeVisualInfo(vi);
- }
-
- if(tflag)
- CloseDevice((struct IORequest *) rd->rd_TimeRequest);
- }
- if(rd->rd_TimeRequest)
- DeleteIORequest(rd->rd_TimeRequest);
- }
- if(MsgPort)
- DeleteMsgPort(MsgPort);
- }
-
- if(!rd->rd_GivenScreen)
- UnlockPubScreen(0, scr);
-
- return err;
- }
-
- ASM(LONG) LIBXpkPassRequest(REG(a0, struct TagItem *ti))
- {
- register struct RequestData *rd;
- LONG mode = 0, useprefs = 1;
- struct TagItem *tags = ti;
-
- #ifdef DEBUG
- DebugTagList("XpkPassRequest", tags);
- #endif
-
- if(!(rd = (struct RequestData *) AllocMem(sizeof(struct RequestData),
- MEMF_PUBLIC|MEMF_CLEAR)))
- return XPKERR_NOMEM;
-
- /* set defaults */
- rd->rd_Time = 120;
- rd->rd_GadgFlags = XPKPASSFLG_PRINTABLE;
- rd->rd_WinLeft = rd->rd_WinTop = -1;
-
- while((ti = NextTagItem(&tags)))
- {
- switch(ti->ti_Tag)
- {
- case XPK_PassChars: rd->rd_GadgFlags = ti->ti_Data; break;
- case XPK_PasswordBuf:
- rd->rd_GivenBuffer = (STRPTR) ti->ti_Data; mode += 10; break;
- case XPK_PassBufSize: rd->rd_BufSize = ti->ti_Data; break;
- case XPK_Key16BitPtr:
- rd->rd_GivenBuffer = (STRPTR) ti->ti_Data; mode += 11; break;
- case XPK_Key32BitPtr:
- rd->rd_GivenBuffer = (STRPTR) ti->ti_Data; mode += 12; break;
- case XPK_PubScreen: rd->rd_GivenScreen = (struct Screen *) ti->ti_Data; break;
- case XPK_PassTitle: rd->rd_Title = ti->ti_Data ? (STRPTR) ti->ti_Data : ""; break;
- case XPK_TimeOut: useprefs = 0; rd->rd_Time = ti->ti_Data; break;
- case XPK_Preferences: if(!ti->ti_Data) useprefs = 0; break;
- case XPK_PassWinLeft: rd->rd_WinLeft = ti->ti_Data; break;
- case XPK_PassWinTop: rd->rd_WinTop = ti->ti_Data; break;
- case XPK_PassWinWidth: rd->rd_WinWidth = ti->ti_Data; break;
- case XPK_PassWinHeight: rd->rd_WinHeight = ti->ti_Data; break;
- case XPK_PassCenter: rd->rd_WinCenter = ti->ti_Data; break;
- case XPK_PassVerify:
- rd->rd_Verify = (ti->ti_Data ? VERIFY_ON : VERIFY_OFF); break;
- };
- }
-
- if(!mode || (mode > 12) || (mode == 10 && !rd->rd_BufSize) ||
- !rd->rd_GivenBuffer)
- {
- FreeMem(rd, sizeof(struct RequestData));
- return XPKERR_BADPARAMS;
- }
-
- if(useprefs) /* call the preferences */
- {
- struct XpkPrefsSemaphore *sem;
-
- if((sem = GetPrefsSem()))
- {
- if(sem->xps_MainPrefs)
- rd->rd_Time = sem->xps_MainPrefs->xmp_Timeout;
- ReleaseSemaphore((struct SignalSemaphore *) sem);
- }
- }
-
- if(!rd->rd_Title) /* create title text */
- {
- if(mode == 10)
- rd->rd_Title = strings[TXT_REQ_PASSWORD];
- else
- {
- rd->rd_Title = rd->rd_ScreenTitle;
- sprintf(rd->rd_ScreenTitle, strings[TXT_REQ_KEY], (mode == 11 ? 16 : 32));
- }
- }
-
- if(mode > 10)
- {
- rd->rd_BufSize = (mode == 11 ? 5 : 9);
- rd->rd_PassBuffer = rd->rd_KeyBuffer;
- rd->rd_GadgFlags = XPKPASSFLG_HEXADECIMAL;
- }
- else
- rd->rd_PassBuffer = rd->rd_GivenBuffer;
-
- if(!(useprefs = DoRequest(rd)))
- {
- if(mode == 11)
- *((UWORD *) rd->rd_GivenBuffer) = strtoul(rd->rd_PassBuffer, 0, 16);
- else if(mode == 12)
- *((ULONG *) rd->rd_GivenBuffer) = strtoul(rd->rd_PassBuffer, 0, 16);
- }
-
- FreeMem(rd, sizeof(struct RequestData));
-
- return useprefs;
- }
-
- #endif /* XPKMASTER_PASSWORD_C */
-