/* -*- 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); }