pjs/lib/libmocha/lm_dial.c

506 строки
10 KiB
C

/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* The contents of this file are subject to the Netscape Public License
* Version 1.0 (the "NPL"); you may not use this file except in
* compliance with the NPL. You may obtain a copy of the NPL at
* http://www.mozilla.org/NPL/
*
* Software distributed under the NPL is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL
* for the specific language governing rights and limitations under the
* NPL.
*
* The Initial Developer of this code under the NPL is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998 Netscape Communications Corporation. All Rights
* Reserved.
*/
/* JS reflection of the dialer stack
8/24/98
*/
#include "lm.h"
#include "prmem.h"
typedef struct JSDialer
{
JSObject* obj;
void* pstub;
} JSDialer;
/* The following definitions need to be kept synchronized with the
values the MUC DLL accepts, currently, there's no universal header
containing them, but you can look in ns/cmd/dialup/win/muc for
the code that implements MUC, and you can reference also
ns/cmd/winfe/mucproc.h for front-end code that references MUC
There should probably be an xp muc(pub).h or somesuch that contains
a universal MUC API.
*/
enum
{
kGetPluginVersion,
kSelectAcctConfig,
kSelectModemConfig,
kSelectDialOnDemand,
kConfigureDialer,
kConnect,
kHangup,
kEditEntry,
kDeleteEntry,
kRenameEntry,
kMonitor,
};
#ifdef XP_WIN
typedef long (STDAPICALLTYPE *FARPEFUNC)(
long selectorCode,
void* paramBlock,
void* returnData );
jsint CallMuc( JSDialer* dialer, long selector, void* configData, void* returnData )
{
FARPEFUNC mucFunc;
jsint error = 0;
mucFunc = (FARPEFUNC)dialer->pstub;
if ( !mucFunc )
return -1;
error = (jsint)( *mucFunc )( selector, configData, NULL );
return error;
}
#else
/* provide an empty prototype until we have Unix/Mac support */
jsint CallMuc( JSDialer*, long, void*, void* ) { }
#endif
enum dialer_slot
{
PRIVATE_STUB = -1,
};
static JSPropertySpec dialer_props[] =
{
{ "privateStub", PRIVATE_STUB, JSPROP_READONLY },
{0}
};
extern JSClass lm_dialer_class;
JSBool PR_CALLBACK
dialer_getProperty( JSContext* cx, JSObject* obj, jsval id, jsval* vp)
{
JSDialer* dialer;
enum dialer_slot dialer_slot;
JSString* str = NULL;
jsint slot;
*vp = JS_GetEmptyStringValue( cx );
if ( !JSVAL_IS_INT(id) )
return JS_TRUE;
slot = JSVAL_TO_INT( id );
dialer = JS_GetInstancePrivate( cx, obj, &lm_dialer_class, NULL);
if ( !dialer )
return JS_TRUE;
dialer_slot = slot;
switch ( dialer_slot )
{
default:
return JS_TRUE;
}
if ( str )
*vp = STRING_TO_JSVAL( str );
return JS_TRUE;
}
JSBool PR_CALLBACK
dialer_enumerate( JSContext* cx, JSObject* obj )
{
return JS_TRUE;
}
void PR_CALLBACK
dialer_finalize( JSContext* cx, JSObject* obj )
{
JSDialer* dialer;
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
return;
XP_DELETE( dialer );
}
JSBool PR_CALLBACK
dialer_toString( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval )
{
JSString* str;
str = JS_NewStringCopyZ( cx, "[object Dialer]" );
if ( !str )
return JS_FALSE;
*rval = STRING_TO_JSVAL( str );
return JS_TRUE;
}
JSClass lm_dialer_class =
{
"Dialer",
JSCLASS_HAS_PRIVATE,
JS_PropertyStub,
JS_PropertyStub,
dialer_getProperty,
dialer_getProperty,
dialer_enumerate,
JS_ResolveStub,
JS_ConvertStub,
dialer_finalize
};
PR_STATIC_CALLBACK(PRBool)
dialer_config( JSContext* cx, JSObject* obj, uint argc,
jsval* argv, jsval* rval )
{
JSObject* stringArray;
jsuint count = 0;
jsval temp;
JSString* stringObject;
jsuint stringArrayLength;
PRBool result;
JSDialer* dialer;
jsint error;
char** configData;
char* buffer;
if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) )
return JS_FALSE;
if ( argc != 1 )
return JS_FALSE;
if ( !JSVAL_IS_OBJECT( argv[ 0 ] ) )
return JS_FALSE;
JS_ValueToObject( cx, argv[ 0 ], &stringArray );
if ( !JS_IsArrayObject( cx, stringArray ) )
return JS_FALSE;
JS_GetArrayLength( cx, stringArray, &stringArrayLength );
configData = JS_malloc( cx, ( ( stringArrayLength + 1 ) * sizeof( char* ) ) );
if ( !configData )
return JS_FALSE;
configData[ 0 ] = NULL;
while ( count < stringArrayLength )
{
if ( JS_GetElement( cx, stringArray, count, &temp ) != JS_TRUE )
continue;
if ( !JSVAL_IS_STRING( temp ) )
continue;
stringObject = JS_ValueToString( cx, temp );
buffer = JS_strdup( cx, JS_GetStringBytes( stringObject ) );
if ( !buffer )
{
configData[ count ] = 0;
result = JS_FALSE;
goto fail;
}
configData[ count ] = buffer;
buffer = NULL;
configData[ ++count ] = NULL;
}
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
{
result = JS_FALSE;
goto fail;
}
error = CallMuc( dialer, kConfigureDialer, (void*)configData, (void*)NULL );
if ( error )
{
result = JS_FALSE;
goto fail;
}
result = JS_TRUE;
fail:
if ( buffer )
JS_free( cx, buffer );
count = 0;
while ( configData[ count ] )
JS_free( cx, configData[ count++ ] );
return result;
}
PR_STATIC_CALLBACK(PRBool)
dialer_connect( JSContext* cx, JSObject* obj, uint argc,
jsval* argv, jsval* rval )
{
JSDialer* dialer;
jsint error;
if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) )
return JS_FALSE;
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
return JS_FALSE;
error = CallMuc( dialer, kConnect, (void*)NULL, (void*)NULL );
if ( error )
return JS_FALSE;
return JS_TRUE;
}
PR_STATIC_CALLBACK(PRBool)
dialer_hangup( JSContext* cx, JSObject* obj, uint argc,
jsval* argv, jsval* rval )
{
JSDialer* dialer;
jsint error;
if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) )
return JS_FALSE;
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
return JS_FALSE;
error = CallMuc( dialer, kHangup, (void*)NULL, (void*)NULL );
if ( error )
return JS_FALSE;
return JS_TRUE;
}
PR_STATIC_CALLBACK(PRBool)
dialer_rename( JSContext* cx, JSObject* obj, uint argc,
jsval* argv, jsval* rval )
{
JSDialer* dialer;
JSString* string = NULL;
jsint error;
struct
{
char* from;
char* to;
} b;
if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) )
return JS_FALSE;
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
return JS_FALSE;
if ( argc != 2 )
return JS_FALSE;
if ( !JSVAL_IS_STRING( argv[ 0 ] ) ||
!JSVAL_IS_STRING( argv[ 1 ] ) )
return JS_FALSE;
string = JS_ValueToString( cx, argv[ 0 ] );
b.from = JS_strdup( cx, JS_GetStringBytes( string ) );
string = JS_ValueToString( cx, argv[ 1 ] );
b.to = JS_strdup( cx, JS_GetStringBytes( string ) );
error = CallMuc( dialer, kRenameEntry, (void*)&b, (void*)NULL );
if ( error )
return JS_FALSE;
return JS_TRUE;
}
PR_STATIC_CALLBACK(PRBool)
dialer_delete( JSContext* cx, JSObject* obj, uint argc,
jsval* argv, jsval* rval )
{
JSDialer* dialer;
JSString* string = NULL;
char* name = NULL;
jsint error;
if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) )
return JS_FALSE;
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
return JS_FALSE;
if ( argc != 1 )
return JS_FALSE;
if ( !JSVAL_IS_STRING( argv[ 0 ] ) )
return JS_FALSE;
string = JS_ValueToString( cx, argv[ 0 ] );
name = JS_strdup( cx, JS_GetStringBytes( string ) );
error = CallMuc( dialer, kDeleteEntry, (void*)name, (void*)NULL );
if ( error )
return JS_FALSE;
return JS_TRUE;
}
PR_STATIC_CALLBACK(PRBool)
dialer_monitor( JSContext* cx, JSObject* obj, uint argc,
jsval* argv, jsval* rval )
{
JSDialer* dialer;
JSString* string = NULL;
char* name = NULL;
jsint error;
if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) )
return JS_FALSE;
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
return JS_FALSE;
error = CallMuc( dialer, kMonitor, (void*)NULL, (void*)NULL );
if ( error )
return JS_FALSE;
return JS_TRUE;
}
PR_STATIC_CALLBACK(PRBool)
dialer_edit( JSContext* cx, JSObject* obj, uint argc,
jsval* argv, jsval* rval )
{
JSDialer* dialer;
JSString* string = NULL;
char* name = NULL;
jsint error;
if ( !lm_CanAccessTarget( cx, JSTARGET_UNIVERSAL_DIALER_ACCESS ) )
return JS_FALSE;
dialer = JS_GetPrivate( cx, obj );
if ( !dialer )
return JS_FALSE;
if ( argc != 1 )
return JS_FALSE;
if ( !JSVAL_IS_STRING( argv[ 0 ] ) )
return JS_FALSE;
string = JS_ValueToString( cx, argv[ 0 ] );
name = JS_strdup( cx, JS_GetStringBytes( string ) );
error = CallMuc( dialer, kEditEntry, (void*)name, (void*)NULL );
if ( error )
return JS_FALSE;
return JS_TRUE;
}
static JSFunctionSpec dialer_methods[] = {
{"configure", dialer_config, 1},
{"connect", dialer_connect, 1},
{"hangup", dialer_hangup, 0},
{"rename", dialer_rename, 2},
{"delete", dialer_delete, 1},
{"monitor", dialer_monitor, 0},
{"edit", dialer_edit, 1},
{"toString", dialer_toString, 0},
{0}
};
JSBool PR_CALLBACK
Dialer( JSContext* cx, JSObject* obj, uint argc, jsval* argv, jsval* rval )
{
return JS_TRUE;
}
JSDialer* create_dialer( JSContext* cx, JSObject* parent_obj )
{
MochaDecoder* decoder;
JSObject* obj;
JSDialer* dialer = NULL;
#ifdef XP_WIN
HINSTANCE mucDll = NULL;
FARPEFUNC stub = NULL;
long version;
#endif
decoder = JS_GetPrivate( cx, JS_GetGlobalObject( cx ) );
dialer = JS_malloc( cx, sizeof *dialer );
if ( !dialer )
return NULL;
XP_BZERO( dialer, sizeof *dialer );
obj = JS_InitClass( cx, parent_obj, NULL, &lm_dialer_class,
Dialer, 0, dialer_props, dialer_methods, NULL, NULL);
if ( !obj || !JS_SetPrivate( cx, obj, dialer ) )
{
JS_free( cx, dialer );
return NULL;
}
dialer->obj = obj;
dialer->pstub = NULL;
#ifdef XP_WIN
mucDll = LoadLibrary( "muc.dll" );
/* apparently LoadLibrary can return failure codes instead of a null ptr. */
if ( !mucDll || mucDll < 0x00000030 )
goto done;
stub = (FARPEFUNC)GetProcAddress( mucDll, "PEPluginFunc" );
if ( !stub )
goto done;
( *stub )( kGetPluginVersion, NULL, &version );
if ( version >= 0x00010001 )
dialer->pstub = (void*)stub;
#endif
done:
return dialer;
}
JSObject* lm_NewDialer( JSContext* cx, JSObject* parent_obj )
{
JSDialer* dialer;
dialer = create_dialer( cx, parent_obj );
return ( dialer ? dialer->obj : NULL);
}