184 lines
5.1 KiB
C
184 lines
5.1 KiB
C
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
|
*
|
|
* The contents of this file are subject to the Netscape Public
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.mozilla.org/NPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
* implied. See the License for the specific language governing
|
|
* rights and limitations under the License.
|
|
*
|
|
* The Original Code is mozilla.org code.
|
|
*
|
|
* The Initial Developer of the Original Code is Netscape
|
|
* Communications Corporation. Portions created by Netscape are
|
|
* Copyright (C) 1998 Netscape Communications Corporation. All
|
|
* Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
*/
|
|
/*
|
|
passwd.c --- reading passwords with Motif text fields.
|
|
Created: Jamie Zawinski <jwz@netscape.com>, 21-Jul-94.
|
|
*/
|
|
|
|
|
|
#include "mozilla.h"
|
|
#include "xfe.h"
|
|
|
|
typedef struct {
|
|
Boolean isTextField;
|
|
char plaintext[1]; /* Actually allocated with variable length; conceptually,
|
|
* it's as if it were "char plaintext[maxLength*2]".
|
|
* See the malloc() in newPasswdUserData() below.
|
|
*/
|
|
} PasswdUserData;
|
|
|
|
PasswdUserData* newPasswdUserData(int maxLength)
|
|
{
|
|
PasswdUserData* res=(PasswdUserData*)malloc( sizeof(PasswdUserData)
|
|
+(maxLength*2)
|
|
);
|
|
if (res)
|
|
{
|
|
res->isTextField=0;
|
|
memset(res->plaintext,0,maxLength*2);
|
|
}
|
|
|
|
return res;
|
|
}
|
|
|
|
static void
|
|
passwd_modify_cb (Widget text, XtPointer client_data, XtPointer call_data)
|
|
{
|
|
|
|
if ( fe_isTextModifyVerifyCallbackInhibited()
|
|
|| (!fe_IsPasswdTextFormElement(text))
|
|
)
|
|
{
|
|
XmTextVerifyCallbackStruct *vcb = (XmTextVerifyCallbackStruct *) call_data;
|
|
PasswdUserData* passwdUserData=(PasswdUserData*)client_data;
|
|
char *plaintext = passwdUserData->plaintext;
|
|
int deletion_length = vcb->endPos - vcb->startPos;
|
|
int insertion_length = vcb->text->length;
|
|
int L = strlen (plaintext);
|
|
int i;
|
|
|
|
if (vcb->reason != XmCR_MODIFYING_TEXT_VALUE)
|
|
return;
|
|
|
|
/* If a deletion occurred, clone it. */
|
|
if (deletion_length > 0)
|
|
{
|
|
for (i = 0; i < (L + 1 - deletion_length); i++)
|
|
{
|
|
plaintext [vcb->startPos+i] = plaintext[vcb->endPos+i];
|
|
if (! plaintext [vcb->startPos+i])
|
|
/* If we copied a null, we're done. */
|
|
break;
|
|
}
|
|
L -= deletion_length;
|
|
}
|
|
|
|
/* If an insertion occurred, open up space for it. */
|
|
if (insertion_length > 0)
|
|
{
|
|
for (i = 0; i <= (L - vcb->startPos); i++)
|
|
plaintext [L + insertion_length - i] = plaintext [L - i];
|
|
L += insertion_length;
|
|
|
|
/* Now fill in the opened gap. */
|
|
for (i = 0; i < insertion_length; i++)
|
|
plaintext [vcb->startPos + i] = vcb->text->ptr [i];
|
|
}
|
|
|
|
/* Now modify the text to insert stars. */
|
|
for (i = 0; i < insertion_length; i++)
|
|
vcb->text->ptr [i] = '*';
|
|
}
|
|
|
|
}
|
|
|
|
static void
|
|
passwd_destroy_cb (Widget text_field, XtPointer closure, XtPointer call_data)
|
|
{
|
|
PasswdUserData* passwdUserData=0;
|
|
char *plaintext = 0;
|
|
int i;
|
|
XtVaGetValues (text_field, XmNuserData, &passwdUserData, 0);
|
|
if (!passwdUserData) return;
|
|
XtVaSetValues (text_field, XmNuserData, 0, 0);
|
|
plaintext = passwdUserData->plaintext;
|
|
i = strlen (plaintext);
|
|
while (i--) plaintext [i] = 0; /* paranoia about core files */
|
|
free (passwdUserData);
|
|
}
|
|
|
|
void
|
|
fe_MarkPasswdTextAsFormElement(Widget text_field)
|
|
{
|
|
PasswdUserData* passwdUserData=0;
|
|
XtVaGetValues (text_field,
|
|
XmNuserData, &passwdUserData,
|
|
0);
|
|
if (passwdUserData)
|
|
passwdUserData->isTextField=1;
|
|
}
|
|
|
|
Boolean
|
|
fe_IsPasswdTextFormElement(Widget text_field)
|
|
{
|
|
PasswdUserData* passwdUserData=0;
|
|
|
|
XtVaGetValues (text_field,
|
|
XmNuserData, &passwdUserData,
|
|
0);
|
|
return ( passwdUserData
|
|
? ((passwdUserData->isTextField)!=0)
|
|
: 0
|
|
);
|
|
}
|
|
|
|
void
|
|
fe_SetupPasswdText (Widget text_field, int max_length)
|
|
{
|
|
PasswdUserData* passwdUserData=0;
|
|
if (max_length <= 0) abort ();
|
|
XtVaGetValues (text_field, XmNuserData, &passwdUserData, 0);
|
|
if (passwdUserData) return; /* already initialized? */
|
|
passwdUserData=newPasswdUserData(max_length);
|
|
XtAddCallback (text_field, XmNmodifyVerifyCallback, passwd_modify_cb,
|
|
passwdUserData);
|
|
XtAddCallback (text_field, XtNdestroyCallback, passwd_destroy_cb, 0);
|
|
XtVaSetValues (text_field,
|
|
XmNuserData, passwdUserData,
|
|
XmNmaxLength, max_length,
|
|
0);
|
|
|
|
/*
|
|
* make sure the international input method does not come up for this
|
|
* widget, since we want to hide the password
|
|
*/
|
|
XmImUnregister (text_field);
|
|
}
|
|
|
|
char *
|
|
fe_GetPasswdText (Widget text_field)
|
|
{
|
|
PasswdUserData* passwdUserData=0;
|
|
XtVaGetValues (text_field, XmNuserData, &passwdUserData, 0);
|
|
/* Return a copy to be analagous with GetValues of XmNvalue.
|
|
The internal copy will be freed when the widget is destroyed. */
|
|
|
|
/* passwdUserData->plaintext can't be null in the current declaration
|
|
* of the struct, 'cause it's declared as an array, but let's
|
|
* be careful.
|
|
*/
|
|
return XP_STRDUP ( (passwdUserData && passwdUserData->plaintext)
|
|
? passwdUserData->plaintext
|
|
: ""
|
|
);
|
|
}
|