]> git.evergreen-ils.org Git - working/Evergreen.git/blob - Open-ILS/xul/staff_client/chrome/content/util/network.js
LP88653 force SSL for requests from local XUL
[working/Evergreen.git] / Open-ILS / xul / staff_client / chrome / content / util / network.js
1 dump('entering util/network.js\n');
2 // vim:noet:sw=4:ts=4:
3
4 var offlineStrings;
5
6 if (typeof util == 'undefined') util = {};
7 util.network = function () {
8
9     try {
10
11         JSAN.use('util.error'); this.error = new util.error();
12         JSAN.use('util.sound'); this.sound = new util.sound();
13
14         offlineStrings = document.getElementById('offlineStrings');
15
16     } catch(E) {
17         alert('error in util.network constructor: ' + E);
18         throw(E);
19     }
20
21     return this;
22 };
23
24 util.network.prototype = {
25
26     'link_id' : 0,
27
28     'network_timeout' : 55, /* seconds */
29
30     'NETWORK_FAILURE' : null,
31
32     'simple_request' : function(method_id,params,f,override_params) {
33         //var obj = this;
34         //var sparams = js2JSON(params);
35         //obj.error.sdump('D_SES','simple_request '+ method_id +' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
36         //    '\noverride_params = ' + override_params + '\n');
37         if (typeof api[method_id] == 'undefined') {
38             throw( offlineStrings.getFormattedString('network.method_not_found.error', [method_id]) );
39         }
40         var secure = true; if (typeof api[method_id].secure != 'undefined') secure = api[method_id].secure;
41         return this.request(api[method_id].app,api[method_id].method,params,f,override_params,{ 'secure' : secure, 'method_id' : method_id });
42     },
43
44     'get_result' : function (req) {
45         var obj = this;
46         var result;
47         var fake_ilsevent_for_network_errors = { 'ilsevent' : -1, 'textcode' : offlineStrings.getString('network.server_or_method.error') }; 
48         try {
49             if (req.cancelled) {
50                 result = fake_ilsevent_for_network_errors;
51             } else {
52                 result = req.getResultObject();   
53                 if(result && req._reported_events) {
54                     if(typeof result.ilsevent != 'undefined') {
55                         result._reported_events = req._reported_events;
56                     } else {
57                         result[0]._reported_events = req._reported_events;
58                     }
59                 } 
60             }
61         } catch(E) {
62             try {
63                 if (instanceOf(E, NetworkFailure)) {
64                     obj.NETWORK_FAILURE = E;
65                 } else {
66                     try { obj.NETWORK_FAILURE = js2JSON(E); } catch(F) { dump(F + '\n'); obj.NETWORK_FAILURE = E; };
67                 }
68             } catch(I) { 
69                 obj.NETWORK_FAILURE = offlineStrings.getString('network.unknown_status');
70             }
71             result = fake_ilsevent_for_network_errors;
72         }
73         return result;
74     },
75
76     'request' : function (app,name,params,f,override_params,_params) {
77
78         var obj = this;
79         
80         //var sparams = js2JSON(params);
81         //obj.error.sdump('D_SES','request '+ app + ' ' + name +' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
82         //    '\noverride_params = ' + override_params + '\n_params = ' + _params + '\n');
83
84         try {
85
86             if (typeof _params == 'undefined') {
87                 // If we're not using simple_request to get here, let's assume secure by default
88                 _params = { 'secure' : true };
89             }
90
91             var request =  this._request(app,name,params,f,override_params,_params);
92             if (request) {
93                 return this.get_result(request);
94             } else {
95                 return null;
96             }
97     
98         } catch(E) {
99             alert('1: ' + E); 
100         }
101     },
102
103     '_request' : function (app,name,params,f,override_params,_params) {
104         var obj = this;
105         try {
106             var sparams = js2JSON(params);
107             obj.error.sdump('D_SES','_request '+app+' '+name+' '+obj.error.pretty_print(sparams.slice(1,sparams.length-1))+
108                 '\noverride_params = ' + override_params + '\n_params = ' + _params +
109                 '\nResult #' + (++obj.link_id) + ( f ? ' asynced' : ' synced' ) +
110                 '\nlocation.href = ' + location.href );
111
112             if (document.getElementById('network_progress')) {
113                 if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.inc == 'function') g.menu.network_meter.inc(app,name);
114             } else if (typeof xulG != 'undefined') {
115                 if (xulG && xulG.network_meter && typeof xulG.network_meter.inc == 'function') xulG.network_meter.inc(app,name);
116             }
117
118             var request = new RemoteRequest( app, name );
119             if (_params && _params.secure) {
120                 request.setSecure(true);
121             } else {
122                 request.setSecure(false);
123             }
124             for(var index in params) {
125                 request.addParam(params[index]);
126             }
127
128             var start_timer = (new Date).getTime();    
129             if (f)  {
130                 request.setCompleteCallback(
131                     function(req) {
132                         try {
133                             var duration = ( (new Date).getTime() - start_timer )/1000;
134                             if ( obj.get_result(req) == null && duration > obj.network_timeout ) req.cancelled = true;
135
136                             if (document.getElementById('network_progress')) {
137                                 if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
138                             } else if (typeof xulG != 'undefined') {
139                                 if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
140                             }
141
142                             var json_string = js2JSON(obj.get_result(req));
143                             obj.error.sdump('D_SES_RESULT','asynced result #' 
144                                 + obj.link_id + '\n\n' 
145                                 + (json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string) 
146                                 + '\n\nOriginal Request:\n\n' 
147                                 + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
148                             obj.play_sounds( request );
149                             req = obj.rerequest_on_session_timeout(app,name,params,req,override_params,_params);
150                             req = obj.rerequest_on_perm_failure(app,name,params,req,override_params,_params);
151                             if (override_params) {
152                                 req = obj.rerequest_on_override(app,name,params,req,override_params,_params);
153                             }
154                             req = obj.check_for_offline(app,name,params,req,override_params,_params);
155                             f(req);
156                             obj.NETWORK_FAILURE = null;
157                         } catch(E) {
158                             try {
159                                 E.ilsevent = -2;
160                                 E.textcode = offlineStrings.getString('network.server_or_method.error');
161                             } catch(F) {}
162                             f( { 'getResultObject' : function() { return E; } } );
163                         }
164                     }
165                 );
166                 try {
167                     request.send(false);
168                 } catch(E) {
169                     throw(E);
170                 }
171                 return null;
172             } else {
173                 try {
174                     request.send(true);
175                     var duration = ( (new Date).getTime() - start_timer )/1000;
176                     if ( obj.get_result(request) == null && duration > obj.network_timeout ) request.cancelled = true;
177
178                     if (document.getElementById('network_progress')) {
179                         if (g && g.menu && g.menu.network_meter && typeof g.menu.network_meter.dec == 'function') g.menu.network_meter.dec(app,name);
180                     } else if (typeof xulG != 'undefined') {
181                         if (xulG && xulG.network_meter && typeof xulG.network_meter.dec == 'function') xulG.network_meter.dec(app,name);
182                     }
183
184                 } catch(E) {
185                     throw(E);
186                 }
187                 var result = obj.get_result(request);
188                 var json_string = js2JSON(result);
189                 this.error.sdump('D_SES_RESULT','synced result #' 
190                     + obj.link_id + '\n\n' + ( json_string.length > 80 ? obj.error.pretty_print(json_string) : json_string ) 
191                     + '\n\nOriginal Request:\n\n' 
192                     + 'request '+app+' '+name+' '+ sparams.slice(1,sparams.length-1));
193                 obj.play_sounds( request );
194                 request = obj.rerequest_on_session_timeout(app,name,params,request,override_params,_params);
195                 request = obj.rerequest_on_perm_failure(app,name,params,request,override_params,_params);
196                 if (override_params) {
197                     request = obj.rerequest_on_override(app,name,params,request,override_params,_params);
198                 }
199                 request = obj.check_for_offline(app,name,params,request,override_params,_params);
200                 obj.NETWORK_FAILURE = null;
201                 return request;
202             }
203
204         } catch(E) {
205             alert('2: ' + E);
206             if (instanceOf(E,perm_ex)) {
207                 alert('in util.network, _request : permission exception: ' + js2JSON(E));
208             }
209             throw(E);
210         }
211     },
212
213     'check_for_offline' : function (app,name,params,req,override_params,_params) {
214         try {
215             var obj = this;
216             var result = obj.get_result(req);
217             if (result == null) return req;
218             if (typeof result.ilsevent == 'undefined') return req;
219             if (result.ilsevent != -1) return req;
220
221             JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
222             var proceed = true;
223
224             while(proceed) {
225
226                 proceed = false;
227
228                 var r;
229
230                 if (data.proceed_offline) {
231
232                     r = 1;
233
234                 } else {
235
236                     var network_failure_string;
237                     var network_failure_status_string;
238                     var msg;
239
240                     try { network_failure_string = String( obj.NETWORK_FAILURE ); } catch(E) { network_failure_string = E; }
241                     try { network_failure_status_string = typeof obj.NETWORK_FAILURE == 'object' && typeof obj.NETWORK_FAILURE != 'null' && typeof obj.NETWORK_FAILURE.status == 'function' ? obj.NETWORK_FAILURE.status() : ''; } catch(E) { network_failure_status_string = ''; obj.error.sdump('D_ERROR', 'setting network_failure_status_string: ' + E); }
242                     
243                     try { msg = offlineStrings.getFormattedString('network.server.failure.exception', [data.server_unadorned]) + '\n' +
244                                 offlineStrings.getFormattedString('network.server.method', [name]) + '\n' + 
245                                 offlineStrings.getFormattedString('network.server.params', [js2JSON(params)]) + '\n' + 
246                                 offlineStrings.getString('network.server.thrown_label') + '\n' + network_failure_string + '\n' + 
247                                 offlineStrings.getString('network.server.status_label') + '\n' + network_failure_status_string;
248                     } catch(E) { msg = E; }
249
250                     try { obj.error.sdump('D_SES_ERROR',msg); } catch(E) { alert('3: ' + E); }
251
252                     r = obj.error.yns_alert(
253                         msg,
254                         offlineStrings.getString('network.network_failure'),
255                         offlineStrings.getString('network.retry_network'),
256                         offlineStrings.getString('network.ignore_errors'),
257                         null,
258                         offlineStrings.getString('common.confirm')
259                     );
260                     if (r == 1) {
261                         data.proceed_offline = true; data.stash('proceed_offline');
262                         dump('Remembering proceed_offline for 200000 ms.\n');
263                         setTimeout(
264                             function() {
265                                 data.proceed_offline = false; data.stash('proceed_offline');
266                                 dump('Setting proceed_offline back to false.\n');
267                             }, 200000
268                         );
269                     }
270                 }
271
272                 dump( r == 0 ? 'Retry Network\n' : 'Ignore Errors\n' );
273
274                 switch(r) {
275                     case 0: 
276                         req = obj._request(app,name,params,null,override_params,_params);
277                         if (obj.get_result(req)) proceed = true; /* daily WTF, why am I even doing this? :) */
278                         return req;
279                     break;
280
281                     case 1: 
282                         return req;
283                     break;
284                 }
285             }
286         } catch(E) {
287             alert('4: ' + E);
288             throw(E);
289         }
290     },
291
292     'reset_titlebars' : function(data) {
293         var obj = this;
294         data.stash_retrieve();
295         try {
296             JSAN.use('util.window'); var win =  new util.window();
297             var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
298             var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
299             var enumerator = windowManagerInterface.getEnumerator(null);
300
301             var w; // set title on all appshell windows
302             while ( w = enumerator.getNext() ) {
303                 if (w.document.title.match(/^\d/)) {
304                     w.document.title = 
305                         win.appshell_name_increment() 
306                         + ': ' + data.list.au[0].usrname() 
307                         + '@' + data.ws_name;
308                         + '.' + data.server_unadorned 
309                 }
310             }
311         } catch(E) {
312             obj.error.standard_unexpected_error_alert(offlineStrings.getString('network.window_title.error'),E);
313         }
314     },
315
316     'set_user_status' : function() {
317         data.stash_retrieve();
318         try {
319             var windowManager = Components.classes["@mozilla.org/appshell/window-mediator;1"].getService();
320             var windowManagerInterface = windowManager.QueryInterface(Components.interfaces.nsIWindowMediator);
321             var permlist = windowManagerInterface.getMostRecentWindow('eg_main').get_menu_perms(null);
322             var offlinestrings;
323             var enumerator = windowManagerInterface.getEnumerator('eg_menu');
324
325             var w;
326             var x;
327             while ( w = enumerator.getNext() ) {
328                 x = w.document.getElementById('oc_menuitem');
329
330                 if(!offlinestrings) w.document.getElementById('offlineStrings');
331                 if(permlist) w.g.menu.set_menu_access(permlist);
332                 if(data.list.au.length > 1) {
333                     addCSSClass(w.document.getElementById('main_tabbox'),'operator_change');
334                     x.setAttribute('label', offlineStrings.getFormattedString('menu.cmd_chg_session.operator.label', [data.list.au[1].usrname()]) );
335                 }
336                 else {
337                     removeCSSClass(w.document.getElementById('main_tabbox'),'operator_change');
338                     x.setAttribute('label', x.getAttribute('label_orig'));
339                 }
340             }
341         } catch(E) {
342             obj.error.standard_unexpected_error_alert(offlineStrings.getString('network.window_title.error'),E);
343         }
344     },
345
346     'get_new_session' : function(name,xulG,text) {
347         var obj = this;
348         try {
349
350         netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
351         var url = urls.XUL_AUTH_SIMPLE;
352         if (typeof xulG != 'undefined' && typeof xulG.url_prefix == 'function') url = xulG.url_prefix( url );
353         JSAN.use('util.window'); var win = new util.window();
354         var my_xulG = win.open(
355             url,
356             //+ '?login_type=staff'
357             //+ '&desc_brief=' + window.escape( text ? 'Session Expired' : 'Operator Change' )
358             //+ '&desc_full=' + window.escape( text ? 'Please enter the credentials for a new login session.' : 'Please enter the credentials for the new login session.  Note that the previous session is still active.'),
359             //'simple_auth' + (new Date()).toString(),
360             offlineStrings.getString('network.new_session.authorize'),
361             'chrome,resizable,modal,width=700,height=500',
362             {
363                 'login_type' : 'staff',
364                 'desc_brief' : text ? offlineStrings.getString('network.new_session.expired') : offlineStrings.getString('network.new_session.operator_change'),
365                 'desc_full' : text ? offlineStrings.getString('network.new_session.expired.prompt') : offlineStrings.getString('network.new_session.operator_change.prompt')
366                 //'simple_auth' : (new Date()).toString(),
367             }
368         );
369         JSAN.use('OpenILS.data');
370         var data = new OpenILS.data(); data.init({'via':'stash'});
371         if (typeof data.temporary_session != 'undefined' && data.temporary_session != '') {
372             data.session.key = data.temporary_session.key; 
373             data.session.authtime = data.temporary_session.authtime; 
374             data.stash('session');
375             try {
376                 var ios = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService);
377                 var cookieUri = ios.newURI("http://" + data.server_unadorned, null, null);
378                 var cookieUriSSL = ios.newURI("https://" + data.server_unadorned, null, null);
379                 var cookieSvc = Components.classes["@mozilla.org/cookieService;1"].getService(Components.interfaces.nsICookieService);
380
381                 cookieSvc.setCookieString(cookieUri, null, "ses="+data.session.key, null);
382                 cookieSvc.setCookieString(cookieUriSSL, null, "ses="+data.session.key, null);
383
384             } catch(E) {
385                 alert(offineStrings.getFormattedString('main.session_cookie.error', [E]));
386             }
387             if (! data.list.au ) data.list.au = [];
388             data.list.au[0] = JSON2js( data.temporary_session.usr );
389             data.stash('list');
390             obj.reset_titlebars(data);
391             return true;
392         } else {
393             obj.error.sdump('D_TRACE','No new session key after simple_auth in util/network\n');
394         }
395         return false;
396
397         } catch(E) {
398             obj.error.standard_unexpected_error_alert('util.network.get_new_session',E);
399         }
400     },
401
402     'rerequest_on_session_timeout' : function(app,name,params,req,override_params,_params) {
403         try {
404             var obj = this;
405             var robj = obj.get_result(req);
406             if (robj != null && robj.ilsevent && robj.ilsevent == 1001 /* NO_SESSION */) {
407
408                 if (obj.get_new_session(name,undefined,true)) {
409                     JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
410                     params[0] = data.session.key;
411                     req = obj._request(app,name,params,null,override_params,_params);
412                 }
413             }
414         } catch(E) {
415             this.error.standard_unexpected_error_alert('rerequest_on_session_timeout',E);
416         }
417         return req;
418     },
419     
420     'rerequest_on_perm_failure' : function(app,name,params,req,override_params,_params) {
421         try {
422             var obj = this;
423             var robj = obj.get_result(req);
424             if (robj != null && robj.ilsevent && robj.ilsevent == 5000) {
425                 netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
426                 if (location.href.match(/^chrome/)) {
427                     //alert('Permission denied.');
428                 } else {
429                     JSAN.use('util.window'); var win = new util.window();
430                     var my_xulG = win.open(
431                         urls.XUL_AUTH_SIMPLE,
432                         //+ '?login_type=temp'
433                         //+ '&desc_brief=' + window.escape('Permission Denied: ' + robj.ilsperm)
434                         //+ '&desc_full=' + window.escape('Another staff member with the above permission may authorize this specific action.  Please notify your library administrator if you need this permission.  If you feel you have received this exception in error, inform your friendly Evergreen developers of the above permission and this debug information: ' + name),
435                         //'simple_auth' + (new Date()).toString(),
436                         offlineStrings.getFormattedString('network.permission.authorize'),
437                         'chrome,resizable,modal,width=700,height=500',
438                         {
439                             'login_type' : 'temp',
440                             'desc_brief' : offlineStrings.getFormattedString('network.permission.description.brief', [robj.ilsperm]),
441                             'desc_full' : offlineStrings.getFormattedString('network.permission.description.full', [name])
442                             //'simple_auth' : (new Date()).toString(),
443                         }
444                     );
445                     JSAN.use('OpenILS.data');
446                     //var data = new OpenILS.data(); data.init({'via':'stash'});
447                     if (typeof my_xulG.temporary_session != 'undefined' && my_xulG.temporary_session != '') {
448                         params[0] = my_xulG.temporary_session.key;
449                         req = obj._request(app,name,params,null,override_params,_params);
450                     }
451                 }
452             }
453         } catch(E) {
454             this.error.sdump('D_ERROR',E);
455         }
456         return req;
457     },
458
459     'rerequest_on_override' : function (app,name,params,req,override_params,_params) {
460         var obj = this;
461         try {
462             if (!override_params.text) override_params.text = {};
463             if (!override_params.auto_override_these_events) override_params.auto_override_these_events = [];
464             if (!override_params.report_override_on_events) override_params.report_override_on_events = [];
465             function override(r) {
466                 try {
467                     // test to see if we can suppress this dialog and auto-override
468                     var auto_override = false;
469                     if (override_params.auto_override_these_events.length > 0) {
470                         auto_override = true;
471                         for (var i = 0; i < r.length; i++) {
472                             if ( 
473                                 (typeof r[i].ilsevent != 'undefined') && 
474                                 (
475                                     (override_params.auto_override_these_events.indexOf( r[i].ilsevent == null ? null : Number(r[i].ilsevent) ) != -1) ||
476                                     (override_params.auto_override_these_events.indexOf( r[i].textcode ) != -1) 
477                                 )
478                             ) {
479                                 // so far so good
480                             } else {
481                                 // showstopper
482                                 auto_override = false;
483                             }
484                         }
485                     }
486                     if (auto_override) {
487                         obj.sound.bad();
488                         req = obj._request(app,name + '.override',params);
489                         return req;
490                     }
491
492                     netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect UniversalBrowserWrite');
493                     var xml = '<vbox xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">' + 
494                         '<groupbox><caption label="' + offlineStrings.getString('network.override.exceptions') + '"/>' + 
495                         '<grid><columns><column/><column flex="1"/></columns><rows>';
496                     for (var i = 0; i < r.length; i++) {
497                         var t1 = String(r[i].ilsevent).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
498                         var t2 = String(r[i].textcode).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
499                         var t3 = String((override_params.text[r[i].ilsevent] ? override_params.text[r[i].ilsevent](r[i]) : '')).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
500                         var t4 = String(r[i].desc).replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;');
501                         xml += '<row>' + 
502                             '<description class="oils_event" tooltiptext="' + t1 + '">' + t2 + '</description>' + 
503                             '<description>' + t3 + '</description>' + 
504                             '</row><row>' + '<description>' + t4 + '</description>' + '</row>';
505                     }
506                     xml += '</rows></grid></groupbox><groupbox><caption label="' + offlineStrings.getString('network.override.override') +'"/><hbox>' + 
507                         '<description>' + offlineStrings.getString('network.override.force.prompt') + '</description>' + 
508                         '<button accesskey="' + offlineStrings.getString('common.no.accesskey') + '" label="' + offlineStrings.getString('common.no') + '" name="fancy_cancel"/>' + 
509                         '<button id="override" accesskey="' + offlineStrings.getString('common.yes.accesskey') + '" label="' + offlineStrings.getString('common.yes') + '" name="fancy_submit" value="override"/></hbox></groupbox></vbox>';
510                     //JSAN.use('OpenILS.data');
511                     //var data = new OpenILS.data(); data.init({'via':'stash'});
512                     //data.temp_override_xml = xml; data.stash('temp_override_xml');
513                     JSAN.use('util.window'); var win = new util.window();
514                     var fancy_prompt_data = win.open(
515                         urls.XUL_FANCY_PROMPT,
516                         //+ '?xml_in_stash=temp_override_xml'
517                         //+ '&title=' + window.escape(override_params.title),
518                         'fancy_prompt', 'chrome,resizable,modal,width=700,height=500',
519                         { 'xml' : xml, 'title' : override_params.title, 'sound' : 'bad', 'sound_object' : obj.sound }
520                     );
521                     if (fancy_prompt_data.fancy_status == 'complete') {
522                         req = obj._request(app,name + '.override',params);
523                         if (req && override_params.report_override_on_events.length > 0 && typeof result == 'object') {
524                             var reported_events = [];
525                             for (var i = 0; i < r.length; i++) {
526                                 if (typeof r[i].ilsevent != 'undefined') {
527                                     if (override_params.report_override_on_events.indexOf( r[i].ilsevent == null ? null : Number(r[i].ilsevent) ) != -1) {
528                                         reported_events.push(Number(r[i].ilsevent));
529                                     }
530                                     if (override_params.report_override_on_events.indexOf( r[i].textcode ) != -1) {
531                                         reported_events.push(r[i].textcode);
532                                     }
533                                 }
534                             }
535                             req._reported_events = reported_events;
536                         }
537                     }
538                     return req;
539                 } catch(E) {
540                     alert('in util.network, rerequest_on_override, override:' + E);
541                 }
542             }
543
544             var result = obj.get_result(req);
545             if (!result) return req;
546
547             if ( 
548                 (typeof result.ilsevent != 'undefined') && 
549                 (
550                     (override_params.overridable_events.indexOf( result.ilsevent == null || result.ilsevent == '' ? null : Number(result.ilsevent) ) != -1) ||
551                     (override_params.overridable_events.indexOf( result.textcode ) != -1)
552                 )
553             ) {
554                 req = override([result]);
555             } else {
556                 var found_good = false; var found_bad = false;
557                 for (var i = 0; i < result.length; i++) {
558                     if ( 
559                         (typeof result[i].ilsevent != 'undefined') && 
560                         (
561                             (override_params.overridable_events.indexOf( result[i].ilsevent == null || result[i].ilsevent == '' ? null : Number(result[i].ilsevent) ) != -1) ||
562                             (override_params.overridable_events.indexOf( result[i].textcode ) != -1) 
563                         )
564                     ) {
565                         found_good = true;
566                     } else {
567                         found_bad = true;
568                     }
569                 }
570                 if (found_good && (!found_bad)) req = override(result);
571             }
572
573             return req;
574         } catch(E) {
575             throw(E);
576         }
577     },
578
579     'ping' : function() {
580         try {
581             JSAN.use('util.file'); JSAN.use('OpenILS.data'); var data = new OpenILS.data(); data.init({'via':'stash'});
582             var file = new util.file('ping.bat');
583             var path = file._file.path;
584             file.write_content('truncate+exec',
585                 '#!/bin/sh\n' +
586                 'ping -n 15 ' + data.server_unadorned + ' > "' + path + '.txt"\n' + /* windows */
587                 'ping -c 15 ' + data.server_unadorned + ' >> "' + path + '.txt"\n'  /* unix */
588             );
589             file.close();
590             file = new util.file('ping.bat');
591
592             var process = Components.classes["@mozilla.org/process/util;1"].createInstance(Components.interfaces.nsIProcess);
593             process.init(file._file);
594
595             var args = [];
596
597             dump('process.run = ' + process.run(true, args, args.length) + '\n');
598
599             file.close();
600
601             var file = new util.file('ping.bat.txt');
602             var output = file.get_content();
603             file.close();
604
605             return output;
606         } catch(E) {
607             alert(E);
608         }
609     },
610
611     'play_sounds' : function(req) {
612         var obj = this;
613         try {
614             var result = req.getResultObject();
615             if (result == null) { return; }
616             if (typeof result.textcode != 'undefined') {
617                 obj.sound.event( result );
618             } else {
619                 if (typeof result.length != 'undefined') {
620                     for (var i = 0; i < result.length; i++) {
621                         if (typeof result[i].textcode != 'undefined') {
622                             obj.sound.event( result[i] );
623                         }
624                     }
625                 }
626             }
627         } catch(E) {
628             dump('Error in network.js, play_sounds() : ' + E + '\n');
629         }
630     }
631 }
632
633 /*
634 function sample_callback(request) {
635     var result = request.getResultObject();
636 }
637 */
638
639 dump('exiting util/network.js\n');