1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10
11
12 #include <dx/dx.h>
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #if defined(HAVE_UNISTD_H)
17 #include <unistd.h>
18 #endif
19 #if defined(HAVE_SYS_WAIT_H)
20 #include <sys/wait.h>
21 #endif
22 #if defined(HAVE_SYS_PARAM_H)
23 #include <sys/param.h>
24 #endif
25 #if defined(HAVE_CTYPE_H)
26 #include <ctype.h>
27 #endif
28 #if defined(HAVE_STRING_H)
29 #include <string.h>
30 #endif
31 #if defined(HAVE_NETDB_H)
32 #include <netdb.h>
33 #endif
34
35 #include "config.h"
36 #include "command.h"
37 #include "function.h"
38 #include "remote.h"
39 #include "compile.h"
40 #include "d.h"
41 #include "exobject.h"
42 #include "_variable.h"
43 #include "_macro.h"
44 #include "version.h"
45 #include "parse.h"
46 #include "graph.h"
47 #include "graphqueue.h"
48 #include "parsemdf.h"
49 #include "swap.h"
50 #include "loader.h"
51 #include "help.h"
52 #include "userinter.h"
53 #include "dxpfsmgr.h"
54 #include "evalgraph.h"
55 #include "dxmain.h"
56
57 #ifdef DXD_WIN
58 #define strcasecmp stricmp
59 #endif
60
61 #ifdef DXD_LICENSED_VERSION
62 static char _dxd_LicenseKey[5];
63 #endif
64
65 #define MAXOBJECTS 21 /* must match mdf-c generated dx.mdf file */
66
67 /* dummy entry for master host */
68 static dpgraphstat masterentry = {NULL, NULL, NULL, -1, 0, 0, 0, 0};
69 static int *update_dptable = NULL;
70
71 /* Defined programatically in libdx */
72 extern void _dxf_user_modules(); /* from libdx/ */
73 extern void _dxf_private_modules(); /* from libdx/ */
74
75 /* Defined in libdx/client.c */
76 extern int _dxfHostIsLocal(char *host); /* from libdx/ */
77
78 /* Defined by yuiif.c */
79 void _dxf_ExReadDXRCFiles ();
80
81 typedef struct _EXTab *EXTab;
82
83 typedef struct _EXTab
84 {
85 char *name; /* string to match */
86 PFI func; /* function to call on match */
87 EXTab table; /* table to search on match */
88 int size; /* size of the table */
89 } _EXTab;
90
91
92 static Error CmdProc (Object *in);
93 static Error MustRunOnMaster (Object in0);
94
95 #if DXD_OS2_SYSCALL
96 static int _Optlink Compare (const void *key, const void *data);
97 #else
98 static int Compare (const void *key, const void *data);
99 #endif
100
101 static Error ProcessTable (char *cmd, Object *in, EXTab table, int len);
102
103 static Error Assign (char *c, Object *in);
104 static Error AssignNoExec (char *c, Object *in);
105 static Error Describe (char *c, Object *in);
106 static Error FlushCache (char *c, Object *in);
107 static Error FlushGlobal (char *c, Object *in);
108 static Error FlushMacro (char *c, Object *in);
109 static Error Getenv (char *c, Object *in);
110 static Error GetKey (char *c, Object *in);
111 static Error GroupAttach (char *c, Object *in);
112 static Error GroupDetach (char *c, Object *in);
113 static Error HostDisconnect (char *c, Object *in);
114 static Error KillGraph (char *c, Object *in);
115 static Error License (char *c, Object *in);
116 static Error LoadObjFile (char *c, Object *in);
117 static Error LoadInteractors (char *c, Object *in);
118 static Error MdfLoadFile (char *c, Object *in);
119 static Error MdfLoadString (char *c, Object *in);
120 static Error OutboardKill (char *c, Object *in);
121 static Error Pfsmgr (char *c, Object *in);
122 static Error PrintCache (char *c, Object *in);
123 static Error PrintExObjects (char *c, Object *in);
124 static Error PrintFunction (char *c, Object *in);
125 static Error PrintGlobal (char *c, Object *in);
126 static Error PrintGroups (char *c, Object *in);
127 static Error PrintHosts (char *c, Object *in);
128 static Error ProductVersion (char *c, Object *in);
129 static Error Reclaim (char *c, Object *in);
130 static Error Terminate (char *c, Object *in);
131 static Error Version (char *c, Object *in);
132 static Error SyncGraph (char *c, Object *in);
133 static int UpdateWorkers (char *host, char *user, char *options, int add);
134
135 #define FCALL(_n,_f) {_n, _f, NULL, 0}
136 #define TABLE(_n,_t) {_n, NULL, _t, sizeof (_t)}
137 #define FANDT(_n,_f,_t) {_n, _f, _t, sizeof (_t)}
138
139
140 static _EXTab AssignTable[] =
141 {
142 FCALL ("", Assign),
143 FCALL ("noexecute", AssignNoExec)
144 };
145
146 static _EXTab FlushTable[] =
147 {
148 FCALL ("cache", FlushCache),
149 FCALL ("dictionary", FlushGlobal),
150 FCALL ("macro", FlushMacro),
151 FCALL ("macros", FlushMacro)
152 };
153
154 static _EXTab GroupTable[] =
155 {
156 FCALL ("attach", GroupAttach),
157 FCALL ("detach", GroupDetach)
158 };
159
160 static _EXTab HostTable[] =
161 {
162 FCALL ("disconnect", HostDisconnect)
163 };
164
165 static _EXTab MdfTable[] =
166 {
167 FCALL ("describe", Describe),
168 FCALL ("file", MdfLoadFile),
169 FCALL ("print", Describe),
170 FCALL ("string", MdfLoadString)
171 };
172
173 static _EXTab OutboardTable[] =
174 {
175 FCALL ("delete", OutboardKill),
176 };
177
178 static _EXTab PrintTable[] =
179 {
180 FCALL ("cache", PrintCache),
181 FCALL ("dictionary", PrintGlobal),
182 FCALL ("env", Getenv),
183 FCALL ("exobjects", PrintExObjects),
184 FCALL ("functions", PrintFunction),
185 FCALL ("global", PrintGlobal),
186 FCALL ("globals", PrintGlobal),
187 FCALL ("groups", PrintGroups),
188 FCALL ("hosts", PrintHosts),
189 FCALL ("mdf", Describe),
190 FCALL ("version", Version)
191 };
192
193 static _EXTab ProductTable[] =
194 {
195 FCALL ("version", ProductVersion),
196 };
197
198
199 /*
200 * The top level command table
201 */
202
203 static _EXTab TopLevel[] =
204 {
205 TABLE ("assign", AssignTable),
206 FCALL ("describe", Describe),
207 FCALL ("exit", Terminate),
208 TABLE ("flush", FlushTable),
209 FCALL ("getenv", Getenv),
210 FCALL ("getkey", GetKey),
211 TABLE ("group", GroupTable),
212 TABLE ("host", HostTable),
213 FCALL ("kill", KillGraph),
214 FCALL ("license", License),
215 FCALL ("load", LoadObjFile),
216 FCALL ("loadinteractors", LoadInteractors),
217 TABLE ("mdf", MdfTable),
218 TABLE ("nop", NULL),
219 TABLE ("outboard", OutboardTable),
220 FCALL ("pfsmgr", Pfsmgr),
221 TABLE ("print", PrintTable),
222 TABLE ("product", ProductTable),
223 FCALL ("quit", Terminate),
224 FCALL ("reclaim", Reclaim),
225 FCALL ("sync", SyncGraph),
226 FCALL ("version", Version)
227 #if 0
228 FCALL ("unload", UnLoadObjFile),
229 #endif
230 };
231
232 /*
233 * The top level command interface
234 */
235
_dxf_ExExecCommand(Object * in)236 Error _dxf_ExExecCommand (Object *in)
237 {
238 Error ret, i;
239
240 for (i=0; i < (MAXOBJECTS + 1) && in[i]; i++)
241 ;
242
243 if (MustRunOnMaster (in[0]))
244 ret = _dxf_ExRunOn (1, CmdProc, in, ((i+1) * sizeof(Object)));
245 else
246 ret = CmdProc (in);
247
248 return (ret);
249 }
250
_dxf_ExExecCommandStr(char * cmd)251 Error _dxf_ExExecCommandStr (char *cmd)
252 {
253 Object in[MAXOBJECTS + 1];
254 int ret, i;
255
256 in[0] = (Object)DXNewString(cmd);
257 if(!in[0])
258 return(ERROR);
259 for(i = 1; i < MAXOBJECTS + 1; i++)
260 in[1] = NULL;
261 ret = _dxf_ExExecCommand(in);
262 DXDelete(in[0]);
263 return(ret);
264 }
265
266 void
_dxf_ExDeletePeer(SlavePeers * sp,int closepeer)267 _dxf_ExDeletePeer(SlavePeers *sp, int closepeer)
268 {
269 /* if name is NULL but we still have a valid file descrip then */
270 /* we are effectively marking this to be deleted when the socket */
271 /* closes. */
272 if(closepeer)
273 DXRegisterInputHandler(NULL, sp->sfd, NULL);
274 if(sp->peername) {
275 DXFree(sp->peername);
276 sp->peername = NULL;
277 }
278 sp->SlaveId = -1;
279 sp->wait_on_ack = FALSE;
280 sp->pending_req = FALSE;
281 sp->sendq.head = NULL;
282 sp->sendq.tail = NULL;
283 if(closepeer) {
284 close(sp->sfd);
285 sp->sfd = -99; /* reuse */
286 }
287 }
288
289 void
_dxf_ExDeletePeerByName(char * host,int closepeer)290 _dxf_ExDeletePeerByName(char *host, int closepeer)
291 {
292 int i, limit;
293 SlavePeers *sp;
294
295 for (i = 0, limit = SIZE_LIST(_dxd_slavepeers); i < limit; ++i)
296 {
297 sp = FETCH_LIST(_dxd_slavepeers, i);
298 if(sp->sfd == -99)
299 continue;
300 if (!strcmp(sp->peername,host)) {
301 _dxf_ExDeletePeer(sp, closepeer);
302 break;
303 }
304 }
305 }
306
307 void
_dxf_ExAddPeer(SlavePeers * sp)308 _dxf_ExAddPeer(SlavePeers *sp)
309 {
310 int k, limit;
311 SlavePeers *index;
312
313 for (k = 0, limit = SIZE_LIST(_dxd_slavepeers); k < limit; ++k) {
314 index = FETCH_LIST(_dxd_slavepeers, k);
315 if(index->sfd == -99) { /* reuse entry */
316 UPDATE_LIST(_dxd_slavepeers, *sp, k);
317 return;
318 }
319 }
320 /* we didn't find an entry to reuse */
321 APPEND_LIST(SlavePeers, _dxd_slavepeers, *sp);
322 }
323
324 void
_dxf_ExDeleteHost(char * host,int err,int closepeer)325 _dxf_ExDeleteHost(char *host, int err, int closepeer)
326 {
327 dpgraphstat *index, *hostentry;
328 PGassign *pgindex;
329 int i, j, limit, limit2;
330 char savehost[MAXHOSTNAMELEN];
331
332 strcpy(savehost, host);
333 _dxf_ExDeletePeerByName(savehost, closepeer);
334
335 /* entry 0 is a dummy for the master so skip it */
336 for (i = 1, limit = SIZE_LIST(_dxd_dpgraphstat); i < limit; ++i) {
337 index = FETCH_LIST(_dxd_dpgraphstat, i);
338 /* entry not used */
339 if(index->procfd == -99)
340 continue;
341 if (!strcmp(index->prochostname,savehost)) {
342 if(err)
343 DXUIMessage("ERROR",
344 "PEER ABORT - Connection to peer %s has been broken.",savehost);
345 else if(index->procfd >= 0) {
346 int peerwait = 1;
347 _dxf_ExDistMsgfd(DM_EXIT, (Pointer)&peerwait, index->procfd);
348 _dxf_ExDistributeMsg(DM_DELETEPEER, (Pointer)savehost, strlen(savehost)+1, TOSLAVES);
349 }
350 for (j = 0, limit2 = SIZE_LIST(_dxd_pgassign); j < limit2; ++j) {
351 pgindex = FETCH_LIST(_dxd_pgassign, j);
352 if(pgindex->hostindex < 0)
353 continue; /* no host assignment */
354 hostentry = FETCH_LIST(_dxd_dpgraphstat, pgindex->hostindex);
355 if(!strcmp(hostentry->prochostname, savehost)) {
356 pgindex->hostindex = -1;
357 _dxf_ExGVariableSetStr(pgindex->pgname, NULL);
358 }
359 }
360
361 DXFree(index->prochostname);
362 DXFree(index->procusername);
363 DXFree(index->options);
364 index->prochostname = NULL;
365 index->procusername = NULL;
366 index->options = NULL;
367 if(index->procfd >= 0) {
368 close(index->procfd);
369 (*_dxd_exNSlaves)--;
370 /* If we have to, wait for the child. */
371 if (!_dxd_exDebugConnect)
372 wait(0);
373 }
374 index->procfd = -99; /* reuse this entry */
375 index->numpgrps = 0;
376 /* set error to TRUE so we won't try to restart this entry */
377 index->error = TRUE;
378 break;
379 }
380 }
381 }
382
383 /*
384 * update a global variable without causing a graph execution.
385 */
_dxf_ExStealthUpdate(char * name,Object obj)386 Error _dxf_ExStealthUpdate (char *name, Object obj)
387 {
388 return _dxf_ExUpdateGlobalDict (name, obj, 0);
389 }
390
_dxf_InitDPtableflag()391 void _dxf_InitDPtableflag()
392 {
393 update_dptable = (int *)DXAllocate(sizeof(int *));
394 if(update_dptable == NULL)
395 _dxf_ExDie("Unable to allocate space for distributed flag");
396 *update_dptable = FALSE;
397 INIT_LIST(_dxd_dpgraphstat);
398 masterentry.prochostname = _dxd_exHostName;
399 masterentry.procusername = NULL;
400 APPEND_LIST(dpgraphstat, _dxd_dpgraphstat, masterentry);
401 }
402
403 /* if a new host was added to the table return true */
_dxf_NewDPTableEntry()404 int _dxf_NewDPTableEntry()
405 {
406 if(*update_dptable) {
407 *update_dptable = FALSE;
408 return(TRUE);
409 }
410 else
411 return(FALSE);
412 }
413
414 /* host string is in the form "hostname -options".
415 * This will update the list of slave hosts, for a delete command
416 * the entry will not be removed from the table and the sockets will
417 * not be closed.
418 */
419
UpdateWorkers(char * host,char * user,char * options,int add)420 static int UpdateWorkers(char *host, char *user, char *options, int add)
421 {
422 int k, limit;
423 dpgraphstat *index;
424 dpgraphstat dpentry;
425 int optlen = 0;
426 int opterr = FALSE;
427
428 if(add) {
429 if(options && *options != '-') {
430 /* print error but add to table anyway */
431 DXSetError(ERROR_BAD_PARAMETER,"bad option string %s", options);
432 opterr = TRUE;
433 }
434 if(options)
435 optlen = strlen(options) + 1;
436 }
437
438 /* if new worker is the master don't add it to table of workers */
439 if(_dxfHostIsLocal(host)) {
440 if(add) {
441 if(options != NULL)
442 DXWarning("%s is already connected, host arguments ignored.",
443 _dxd_exHostName);
444 DXFree(host);
445 return(0);
446 }
447 else return(-1);
448 }
449
450 /* entry 0 is a dummy for the master, skip it */
451 for (k = 1, limit = SIZE_LIST(_dxd_dpgraphstat); k < limit; ++k) {
452 index = FETCH_LIST(_dxd_dpgraphstat, k);
453 /* entry not used */
454 if(index->procfd == -99)
455 continue;
456
457 if (!strcmp(index->prochostname, host)) {
458 ExDebug("*1","Current host %s already in dpgraphstat", host);
459 /* not adding new host to table */
460 if(add) {
461 DXFree(host);
462 if(index->procfd >= 0) {
463 if(options != NULL) {
464 if(index->options != NULL &&
465 !strcmp(index->options, options)) {
466 index->error = opterr;
467 if(!opterr)
468 index->numpgrps++;
469 return(k);
470 }
471 }
472 else {
473 if(index->options == NULL) {
474 index->error = FALSE;
475 index->numpgrps++;
476 return(k);
477 }
478 }
479
480 /* new options differ from old options */
481 if(index->numpgrps == 0) {
482 int peerwait = 0;
483 _dxf_ExDistMsgfd(DM_EXIT, (Pointer)&peerwait, index->procfd);
484 if(index->procfd >= 0) {
485 close(index->procfd);
486 /* If we have to, wait for the child. */
487 if (!_dxd_exDebugConnect)
488 wait(0);
489 }
490 index->procfd = -1;
491 index->error = opterr;
492 if(!opterr)
493 index->numpgrps++;
494 if(index->options) {
495 if(optlen > (strlen(index->options) + 1));
496 index->options =
497 DXReAllocate(index->options, optlen);
498 }
499 else
500 index->options = DXAllocateLocal(optlen);
501 if(!index->options) {
502 index->error = TRUE;
503 DXSetError(ERROR_NO_MEMORY,
504 "Cannot allocate memory for host table entry");
505 return(k);
506 }
507 if(optlen > 0)
508 strcpy(index->options, options);
509 else {
510 DXFree(index->options);
511 index->options = NULL;
512 }
513 *update_dptable = TRUE;
514 ExDebug("*7", "Set Flag to Update distributed table");
515 return(k);
516 }
517 else {
518 DXSetError(ERROR_BAD_PARAMETER,
519 "Host already connected, cannot specify new options");
520 index->error = TRUE;
521 return(k);
522 }
523 }
524 else { /* host not connected */
525 if(optlen > 0) {
526 if(index->options) {
527 if(optlen > (strlen(index->options) + 1))
528 index->options = DXReAllocate(index->options,
529 optlen);
530 }
531 else
532 index->options = DXAllocateLocal(optlen);
533 if(!index->options) {
534 index->error = TRUE;
535 DXSetError(ERROR_NO_MEMORY,
536 "Cannot allocate memory for host table entry");
537 return(k);
538 }
539 strcpy(index->options, options);
540 }
541 else { /* no options to add, free old ones */
542 if(index->options) {
543 DXFree(index->options);
544 index->options = NULL;
545 }
546 }
547 index->error = opterr;
548 if(!opterr)
549 index->numpgrps++;
550 *update_dptable = TRUE;
551 ExDebug("*7", "Set Flag to Update distributed table");
552 return(k);
553 }
554 }
555 else { /* not adding a host */
556 index->numpgrps--;
557 if(index->numpgrps == 0)
558 _dxf_ExDeleteHost(host, 0, 0);
559 return(-1);
560 }
561 }
562 }
563 if(add) {
564 /* if we got here we did not find host name in list */
565 dpentry.error = opterr;
566 dpentry.prochostname = host;
567 dpentry.procusername = user;
568 if(optlen > 0) {
569 dpentry.options = (char *) DXAllocateLocal (optlen);
570 if(!dpentry.options) {
571 dpentry.error = TRUE;
572 DXSetError(ERROR_NO_MEMORY,
573 "Could not allocate memory for remote host table entry");
574 }
575 else
576 strcpy(dpentry.options, options);
577 }
578 else dpentry.options = NULL;
579 dpentry.procfd = -1;
580 dpentry.SlaveId = -1;
581 dpentry.SwapMsg = -1;
582 if(!opterr)
583 dpentry.numpgrps = 1;
584 else
585 dpentry.numpgrps = 0;
586 /* entry 0 is a dummy for the master */
587 for (k = 1, limit = SIZE_LIST(_dxd_dpgraphstat); k < limit; ++k) {
588 index = FETCH_LIST(_dxd_dpgraphstat, k);
589 if(index->procfd == -99) { /* reuse entry */
590 UPDATE_LIST(_dxd_dpgraphstat, dpentry, k);
591 *update_dptable = TRUE;
592 ExDebug("*7", "Set Flag to Update distributed table");
593 return(k);
594 }
595 }
596 /* we didn't find an entry to reuse */
597 APPEND_LIST(dpgraphstat, _dxd_dpgraphstat, dpentry);
598 *update_dptable = TRUE;
599 ExDebug("*7", "Set Flag to Update distributed table");
600 limit = SIZE_LIST(_dxd_dpgraphstat);
601 return(limit-1);
602 }
603 else
604 return(-1);
605 }
606
_dxf_ExPrintGroups()607 Error _dxf_ExPrintGroups()
608 {
609 int i, limit;
610 PGassign *index;
611 dpgraphstat *hostentry;
612
613 DXMessage("Group Attach Table");
614 DXMessage("%-25s %s", "Groupname", "Hostname");
615 for (i = 0, limit = SIZE_LIST(_dxd_pgassign); i < limit; ++i) {
616 index = FETCH_LIST(_dxd_pgassign, i);
617 if(index->hostindex >= 0) {
618 hostentry = FETCH_LIST(_dxd_dpgraphstat, index->hostindex);
619 DXMessage("%-25s %s", index->pgname, hostentry->prochostname);
620 }
621 else
622 DXMessage("%-25s", index->pgname);
623 }
624 return OK;
625 }
626
_dxf_ExPrintHosts()627 Error _dxf_ExPrintHosts()
628 {
629 int i, limit;
630 dpgraphstat *index;
631
632 DXMessage("Number of Slaves %d", *_dxd_exNSlaves);
633 DXMessage("Host Connection Table");
634 DXMessage("%-25s %s", "Hostname", "Status");
635 /* entry 0 is a dummy for the master */
636 for (i = 1, limit = SIZE_LIST(_dxd_dpgraphstat); i < limit; ++i) {
637 index = FETCH_LIST(_dxd_dpgraphstat, i);
638 if(index->procfd == -99)
639 continue;
640 if(index->procfd < 0) {
641 if(index->error) {
642 if(index->prochostname)
643 DXMessage("%-25s %s", index->prochostname, "connect error");
644 }
645 else
646 DXMessage("%-25s %s", index->prochostname, "not connected");
647 }
648 else {
649 if(index->numpgrps == 1)
650 DXMessage("%-25s %s: %d group attached",
651 index->prochostname, "connected", index->numpgrps);
652 else
653 DXMessage("%-25s %s: %d groups attached",
654 index->prochostname, "connected", index->numpgrps);
655 }
656 }
657 return OK;
658 }
659
660 /*
661 * hack for now. the mdf commands CAN'T be started with
662 * the subroutine which is used to be sure the executive
663 * commands run on processor 0, so start implementing a layer
664 * which eventually could be used to run executive commands
665 * which are not dependent on running on proc 0 from whichever
666 * processor picked up the executive module in the first place.
667 */
MustRunOnMaster(Object in0)668 static Error MustRunOnMaster (Object in0)
669 {
670 char *cmd;
671
672 if (!in0 || ! DXExtractString (in0, &cmd))
673 return ERROR;
674
675 if (strncmp(cmd, "mdf", 3))
676 return OK;
677
678 return ERROR;
679 }
680
681
CmdProc(Object * in)682 static Error CmdProc (Object *in)
683 {
684 Error ret;
685 char *cmd;
686
687 if (!in[0] || ! DXExtractString (in[0], &cmd)) {
688 DXSetError (ERROR_BAD_PARAMETER, "#10200", "command input");
689 return (ERROR);
690 }
691
692 ret = ProcessTable (cmd, &in[1], TopLevel, sizeof (TopLevel));
693 return (ret);
694 }
695
696
697 #if DXD_OS2_SYSCALL
698 static int _Optlink
699 #else
700 static int
701 #endif
Compare(const void * key,const void * data)702 Compare (const void *key, const void *data)
703 {
704 EXTab a = (EXTab) key;
705 EXTab b = (EXTab) data;
706 return (strcmp (a->name, b->name));
707 }
708
709
ProcessTable(char * cmd,Object * in,EXTab table,int len)710 static Error ProcessTable (char *cmd, Object *in, EXTab table, int len)
711 {
712 char *next;
713 char buf[1024];
714 _EXTab dummy;
715 EXTab tab;
716 Error fret = OK;
717 Error tret = OK;
718
719 for (next = cmd; next && *next && isspace (*next); next++)
720 continue;
721
722 buf[0] = '\0';
723 if (sscanf (next, "%1023s", buf) != 1) {
724 DXSetError(ERROR_BAD_PARAMETER, "#8310", cmd);
725 return ERROR;
726 }
727 dummy.name = buf;
728 tab = (EXTab) bsearch ((char *) &dummy, (char *) table,
729 len / sizeof (_EXTab), sizeof (_EXTab),
730 Compare);
731
732 if (! tab) {
733 DXSetError (ERROR_BAD_PARAMETER, "#8310", cmd);
734 return (ERROR);
735 }
736
737 for (next = next + strlen (buf); next && *next && isspace (*next); next++)
738 continue;
739
740 if (tab->func)
741 fret = (* tab->func) (next, in);
742
743 if (tab->table) {
744 if(strcmp(next, "") == 0) {
745 DXSetError(ERROR_BAD_PARAMETER, "#8312", cmd);
746 return (ERROR);
747 }
748 tret = ProcessTable (next, in, tab->table, tab->size);
749 }
750
751 return (fret == OK && tret == OK ? OK : ERROR);
752 }
753
754
755 /*
756 * Functions executed by the tables.
757 */
758
Assign(char * c,Object * in)759 static int Assign(char *c, Object *in)
760 {
761 return(ERROR);
762 }
763
AssignNoExec(char * c,Object * in)764 static int AssignNoExec(char *c, Object *in)
765 {
766 char *name;
767
768 if (!in[0] || ! DXExtractString (in[0], &name)) {
769 DXSetError (ERROR_BAD_PARAMETER, "#10200", "variable name");
770 return (ERROR);
771 }
772 return (_dxf_ExStealthUpdate(name, in[1]));
773
774 }
775
Describe(char * c,Object * in)776 static int Describe (char *c, Object *in)
777 {
778 char *str;
779 int i, j, k, n;
780 char *key;
781 node *func;
782 node *minn;
783 int mini;
784 node **funcs = NULL;
785 char help[1024];
786 char *hp;
787
788 if ((c == NULL || *c == '\000') && (in == NULL || in[0] == NULL))
789 {
790 _dxf_ExDictionaryBeginIterate (_dxd_exMacroDict);
791 for (n = 0; _dxf_ExDictionaryIterate (_dxd_exMacroDict, &key) != NULL; n++)
792 ;
793 _dxf_ExDictionaryEndIterate (_dxd_exMacroDict);
794
795 funcs = (node **) DXAllocateLocal (n * sizeof (node *));
796
797 DXBeginLongMessage ();
798 _dxf_ExDictionaryBeginIterate (_dxd_exMacroDict);
799 for (i = 0, k = 0; i < n; i++)
800 {
801 func = (node *) _dxf_ExDictionaryIterate (_dxd_exMacroDict, &key);
802 /* skip over dummy function definitions */
803 if (func->v.module.def.func == m__badfunc)
804 continue;
805 if (funcs != NULL)
806 funcs[k] = func;
807 else
808 DXMessage ("%-25s %s\n", func->v.module.id->v.id.id,
809 func->type == NT_MACRO
810 ? "macro" : "module");
811 k++;
812 }
813 _dxf_ExDictionaryEndIterate (_dxd_exMacroDict);
814
815 for (i = 0; i < k; i++)
816 {
817 minn = funcs[i];
818 mini = i;
819 for (j = i; j < k; j++)
820 {
821 if (strcasecmp (minn->v.function.id->v.id.id,
822 funcs[j]->v.function.id->v.id.id) > 0)
823 {
824 minn = funcs[j];
825 mini = j;
826 }
827 }
828 func = funcs[i];
829 funcs[i] = funcs[mini];
830 funcs[mini] = func;
831 }
832
833 if (funcs != NULL)
834 {
835 for (i = 0; i < k; i++)
836 DXMessage ("%-25s %s\n", funcs[i]->v.module.id->v.id.id,
837 funcs[i]->type == NT_MACRO
838 ? "macro" : "module");
839 }
840 DXEndLongMessage ();
841
842 DXFree ((Pointer) funcs);
843 return (OK);
844 }
845
846 if (c && *c) {
847 while (*c)
848 {
849 int ret = 0;
850 help[0] = '\000';
851 ret = sscanf (c, "%1023s", help);
852 if (ret != 1 || help[0] == '\000')
853 break;
854 str = _dxf_ExHelpFunction (help);
855 if (str)
856 {
857 DXBeginLongMessage ();
858 DXMessage (str);
859 DXEndLongMessage ();
860 DXFree ((Pointer) str);
861 }
862 for (c = c + strlen (help); *c && isspace (*c); c++)
863 continue;
864 }
865 }
866 else
867 {
868 for (i = 0; DXExtractString (in[i], &hp); i++)
869 {
870 str = _dxf_ExHelpFunction (hp);
871 if (str)
872 {
873 DXBeginLongMessage ();
874 DXMessage (str);
875 DXEndLongMessage ();
876 DXFree ((Pointer) str);
877 }
878 }
879 }
880 return (OK);
881 }
882
883
FlushCache(char * c,Object * in)884 static int FlushCache (char *c, Object *in)
885 {
886 _dxf_ExCacheFlush (FALSE);
887 return (OK);
888 }
889
890
_dxf_ExFlushGlobal(void)891 void _dxf_ExFlushGlobal (void)
892 {
893 char *dummy=NULL;
894 Object *in=NULL;
895
896 FlushGlobal(dummy, in);
897 }
898
ExResetGroupAssign()899 void ExResetGroupAssign ()
900 {
901 int k, limit;
902 PGassign *index;
903 dpgraphstat *hostentry;
904
905 for (k = 0, limit = SIZE_LIST(_dxd_pgassign); k < limit; ++k) {
906 index = FETCH_LIST(_dxd_pgassign, k);
907 hostentry = FETCH_LIST(_dxd_dpgraphstat, index->hostindex);
908 if(!hostentry->error)
909 _dxf_ExGVariableSetStr(index->pgname,
910 hostentry->prochostname);
911 }
912 }
913
FlushGlobal(char * c,Object * in)914 static int FlushGlobal (char *c, Object *in)
915 {
916 if(!_dxd_exRemoteSlave) {
917 /* _dxf_ExCacheFlush and _dxf_ExDictionaryPurge will send msgs
918 * to slaves and slaves will call each of these routines
919 * seperately
920 */
921 _dxf_ExCacheFlush (TRUE);
922 DXDebug ("1", "flushing dictionary");
923 _dxf_ExDictionaryPurge (_dxd_exGlobalDict);
924 _dxf_ExDistributeMsg(DM_FLUSHGLOBAL, NULL, 0, TOSLAVES);
925 }
926 _dxf_ExInitSystemVars ();
927 ExResetGroupAssign ();
928 return (OK);
929 }
930
_dxf_ExFlushMacro(void)931 void _dxf_ExFlushMacro (void)
932 {
933 char *dummy=NULL;
934 Object *in=NULL;
935
936 FlushMacro(dummy, in);
937 }
938
FlushMacro(char * c,Object * in)939 static int FlushMacro (char *c, Object *in)
940 {
941 if(!_dxd_exRemoteSlave) {
942 /* _dxf_ExDictionaryPurge will send msg to slaves and cause
943 * the slaves to call this routine seperately
944 */
945 _dxf_ExDictionaryPurge (_dxd_exMacroDict);
946 _dxf_ExDistributeMsg(DM_FLUSHMACRO, NULL, 0, TOSLAVES);
947 }
948 _dxf_user_modules ();
949 _dxf_private_modules ();
950 _dxf_ExFunctionDone ();
951 return (OK);
952 }
953
954
Getenv(char * c,Object * in)955 static int Getenv (char *c, Object *in)
956 {
957 char *env;
958 char **envp;
959
960 DXBeginLongMessage ();
961 if (c && *c)
962 {
963 env = (char *) getenv (c);
964 if (env)
965 DXMessage ("%s=%s", c, env);
966 else
967 DXMessage ("%s is not in the environment", c);
968 }
969 else
970 {
971 envp = (char **) _dxf_ExEnvp ();
972 for ( ;envp && *envp; envp++)
973 DXMessage ("%s\n", *envp);
974 }
975 DXEndLongMessage ();
976
977 return (OK);
978 }
979
980 /* Insert a group to hostname assignment in table. This will not make the
981 * connection to the remote host until the current graph has finished
982 * executing. If this is updated in the middle of a graph evaluation we
983 * have a slave that is started but is not executing the current graph.
984 * The master will see the new slave and try to wait for it to execute
985 * the current graph which is doesn't have.
986 * This takes a string list with each string element being:
987 * "group1, group2, group3:hostname -options"
988 */
989
GroupAttach(char * c,Object * in)990 static int GroupAttach(char *c, Object *in)
991 {
992 int n, k, limit, grouplen, found;
993 dpgraphstat *hostentry;
994 char *str, *delimiter;
995 char *hoststr, *userstr;
996 PGassign pgassign, *index=NULL;
997 int cerror = FALSE;
998 char *hostname;
999 char *username;
1000 char *optr;
1001 int hostlen, userlen;
1002
1003 if(_dxd_exRemoteSlave)
1004 return(OK);
1005
1006 if(!in[0]) {
1007 DXSetError (ERROR_BAD_PARAMETER, "#10200", "group assignment");
1008 return (ERROR);
1009 }
1010
1011 n = 0;
1012 while(DXExtractNthString(in[0], n, &str)) {
1013 hoststr = strchr(str, ':');
1014 if(hoststr == NULL) {
1015 DXSetError(ERROR_BAD_PARAMETER, "no host assignment");
1016 return(ERROR);
1017 }
1018 hoststr++;
1019
1020 while(*hoststr == ' ')
1021 hoststr++;
1022 if(*hoststr == '\0') {
1023 DXSetError(ERROR_BAD_PARAMETER, "no host assignment");
1024 return(ERROR);
1025 }
1026
1027 if ( strchr(hoststr, '@') ) {
1028 userstr = hoststr;
1029 hoststr = strchr(hoststr, '@') + 1;
1030 if ( *userstr == '@' ) {
1031 DXSetError(ERROR_BAD_PARAMETER, "no user assignment");
1032 return(ERROR);
1033 }
1034 optr = userstr;
1035 while(*optr != ' ' && *optr != '@')
1036 optr++;
1037
1038 userlen = optr - userstr;
1039 }
1040 else
1041 userstr = NULL, userlen = 0;
1042
1043 while(*hoststr == ' ')
1044 hoststr++;
1045 if(*hoststr == '\0') {
1046 DXSetError(ERROR_BAD_PARAMETER, "no host assignment");
1047 return(ERROR);
1048 }
1049
1050 optr = hoststr;
1051
1052 while(*optr && *optr != ' ' && *optr != ':')
1053 optr++;
1054
1055 if(*optr)
1056 hostlen = optr - hoststr;
1057 else
1058 hostlen = strlen(hoststr);
1059
1060 while(*optr && *optr == ' ')
1061 optr++;
1062
1063 if(*optr == '\0')
1064 optr = NULL;
1065
1066 while(*str == ' ')
1067 str++;
1068 if(*str == ':' || *str == ',') {
1069 DXSetError(ERROR_BAD_PARAMETER, "no group name");
1070 return(ERROR);
1071 }
1072 while(*str) {
1073 hostname = (char *)DXAllocateLocal(hostlen + 1);
1074 if(hostname == NULL)
1075 DXSetError(ERROR_NO_MEMORY,
1076 "Cannot allocate memory for host table entry");
1077 strncpy(hostname, hoststr, hostlen);
1078 hostname[hostlen] = '\0';
1079
1080 if ( userstr ) {
1081 username = (char *)DXAllocateLocal(userlen + 1);
1082 if(username == NULL)
1083 DXSetError(ERROR_NO_MEMORY,
1084 "Cannot allocate memory for user table entry");
1085 strncpy(username, userstr, userlen);
1086 username[userlen] = '\0';
1087 userstr = username;
1088 }
1089
1090 delimiter = str;
1091 while(*delimiter && *delimiter != ',' &&
1092 *delimiter != ' ' && *delimiter != ':')
1093 delimiter++;
1094 grouplen = delimiter - str;
1095 pgassign.pgname = (char *)DXAllocateLocal(grouplen + 1);
1096 if(pgassign.pgname == NULL)
1097 DXSetError(ERROR_NO_MEMORY,
1098 "Cannot allocate memory for group table entry");
1099 strncpy(pgassign.pgname, str, grouplen);
1100 pgassign.pgname[grouplen] = '\0';
1101 found = FALSE;
1102 /* search table to see if process group is already assigned */
1103 for (k = 0, limit = SIZE_LIST(_dxd_pgassign); k < limit; ++k) {
1104 index = FETCH_LIST(_dxd_pgassign, k);
1105 if(!strcmp(index->pgname, pgassign.pgname)) {
1106 found = TRUE;
1107 break;
1108 }
1109 }
1110 if(found) {
1111 /* see if it is already attached */
1112 if(index->hostindex >= 0)
1113 hostentry = FETCH_LIST(_dxd_dpgraphstat, index->hostindex);
1114 else hostentry = NULL;
1115 if(hostentry && (hostentry->error == FALSE) &&
1116 !strcmp(hostentry->prochostname, hostname)) {
1117 if(optr != NULL) {
1118 if(hostentry->options != NULL &&
1119 !strcmp(hostentry->options, optr)) {
1120 DXFree(pgassign.pgname);
1121 goto next_string;
1122 }
1123 }
1124 else {
1125 if(hostentry->options == NULL) {
1126 DXFree(pgassign.pgname);
1127 goto next_string;
1128 }
1129 }
1130 }
1131 /* replace host assignment in table */
1132 index->hostindex = UpdateWorkers(hostname, userstr, optr, 1);
1133 hostentry = FETCH_LIST(_dxd_dpgraphstat, index->hostindex);
1134 DXFree(pgassign.pgname);
1135 if(!hostentry->error) {
1136 _dxf_ExGVariableSetStr(index->pgname,
1137 hostentry->prochostname);
1138 if(_dxd_exDebug)
1139 printf("reassigning %s to %s\n",index->pgname,
1140 hostentry->prochostname);
1141 }
1142 else
1143 cerror = hostentry->error;
1144 }
1145 else { /* adding new process group assignment */
1146 pgassign.hostindex = UpdateWorkers(hostname, userstr, optr, 1);
1147 hostentry = FETCH_LIST(_dxd_dpgraphstat, pgassign.hostindex);
1148 APPEND_LIST(PGassign, _dxd_pgassign, pgassign);
1149 if(!hostentry->error) {
1150 _dxf_ExGVariableSetStr(pgassign.pgname,
1151 hostentry->prochostname);
1152 if(_dxd_exDebug)
1153 printf("assigning %s to %s\n",
1154 pgassign.pgname, hostentry->prochostname);
1155 }
1156 else
1157 cerror = hostentry->error;
1158 }
1159 next_string:
1160 str = delimiter;
1161 while(*str == ' ' || *str == ',')
1162 str++;
1163 if(*str == ':')
1164 break;
1165 }
1166 n++;
1167 }
1168 if(cerror)
1169 return(ERROR);
1170 else
1171 return(OK);
1172 }
1173
1174
1175 /* This routine does not close the sockets associated with a host.
1176 * This routine takes a string list of group names to be removed from the
1177 * process assignment table.
1178 */
1179
GroupDetach(char * c,Object * in)1180 static int GroupDetach(char *c, Object *in)
1181 {
1182 char *groupname;
1183 int n, k, limit;
1184 PGassign *index;
1185 dpgraphstat *hostentry;
1186
1187 if(_dxd_exRemoteSlave)
1188 return(OK);
1189
1190 if(!in[0]) {
1191 DXSetError (ERROR_BAD_PARAMETER, "#10200", "group name");
1192 return (ERROR);
1193 }
1194
1195 n = 0;
1196 while(DXExtractNthString(in[0], n, &groupname)) {
1197 for (k = 0, limit = SIZE_LIST(_dxd_pgassign); k < limit; ++k) {
1198 index = FETCH_LIST(_dxd_pgassign, k);
1199 if(!strcmp(index->pgname, groupname)) {
1200 hostentry = FETCH_LIST(_dxd_dpgraphstat, index->hostindex);
1201 if(hostentry) {
1202 if(!hostentry->error)
1203 index->hostindex = UpdateWorkers(
1204 hostentry->prochostname,
1205 hostentry->procusername, NULL, 0);
1206 }
1207 _dxf_ExGVariableSetStr(index->pgname, NULL);
1208 _dxf_ExCacheFlush(FALSE);
1209 DXFree(index->pgname);
1210 DELETE_LIST(PGassign, _dxd_pgassign, k);
1211 break;
1212 }
1213 }
1214 n++;
1215 }
1216 return(OK);
1217 }
1218
HostDisconnect(char * c,Object * in)1219 static int HostDisconnect(char *c, Object *in)
1220 {
1221 int n;
1222 char *hostname;
1223
1224 n = 0;
1225 while(DXExtractNthString(in[0], n, &hostname)) {
1226 _dxf_ExDeleteHost(hostname, 0, 0);
1227 n++;
1228 }
1229
1230 return(OK);
1231 }
1232
KillGraph(char * c,Object * in)1233 static int KillGraph (char *c, Object *in)
1234 {
1235 if (!_dxf_ExGQAllDone ()) {
1236 *_dxd_exKillGraph = TRUE;
1237 _dxf_ExDistributeMsg(DM_KILLEXECGRAPH,
1238 (Pointer)_dxd_exContext->graphId, 0, TOPEERS);
1239 }
1240 return (OK);
1241 }
1242
LoadObjFile(char * c,Object * in)1243 static int LoadObjFile(char *c, Object *in)
1244 {
1245 char *str;
1246
1247 if (!in[0] || ! DXExtractString (in[0], &str)) {
1248 DXSetError (ERROR_BAD_PARAMETER, "#10200", "object filename");
1249 return (ERROR);
1250 }
1251
1252 return DXLoadObjFile(str, "DXMODULES") != NULL;
1253 }
1254
LoadInteractors(char * c,Object * in)1255 static int LoadInteractors(char *c, Object *in)
1256 {
1257 return _dxf_ExRunOn (1, _dxfLoadUserInteractors, (Pointer)c, strlen(c)+1);
1258 }
1259
MdfLoadFile(char * c,Object * in)1260 static int MdfLoadFile(char *c, Object *in)
1261 {
1262 char *str;
1263
1264 if (!in[0] || ! DXExtractString (in[0], &str)) {
1265 DXSetError (ERROR_BAD_PARAMETER, "#10200", "mdf filename");
1266 return (ERROR);
1267 }
1268
1269 return DXLoadMDFFile(str);
1270 }
1271
MdfLoadString(char * c,Object * in)1272 static int MdfLoadString(char *c, Object *in)
1273 {
1274 char *str;
1275
1276 if (!in[0] || ! DXExtractString (in[0], &str)) {
1277 DXSetError (ERROR_BAD_PARAMETER, "#10200", "mdf definition");
1278 return (ERROR);
1279 }
1280
1281 return DXLoadMDFString(str);
1282 }
1283
1284 /* disconnect the pipe between the exec and a specific outboard module.
1285 * args are: module name, instance number (may be omitted - defaults to 0),
1286 * and process group name (may be null - defaults to localhost).
1287 */
OutboardKill(char * c,Object * in)1288 static int OutboardKill (char *c, Object *in)
1289 {
1290 char *module;
1291 int instance;
1292 char *procgroup;
1293
1294 if (!in[0] || ! DXExtractString (in[0], &module)) {
1295 DXSetError (ERROR_BAD_PARAMETER, "#10200", "outboard module name");
1296 return (ERROR);
1297 }
1298
1299 if (!in[1])
1300 instance = 0;
1301 else if (! DXExtractInteger (in[1], &instance)) {
1302 DXSetError (ERROR_BAD_PARAMETER, "#10010", "outboard instance number");
1303 return (ERROR);
1304 }
1305
1306 if (!in[2])
1307 procgroup = NULL;
1308 else if (! DXExtractString (in[2], &procgroup)) {
1309 DXSetError (ERROR_BAD_PARAMETER, "#10200", "outboard process group");
1310 return (ERROR);
1311 }
1312
1313 if (procgroup) {
1314 if (!_dxf_ExDeleteReallyRemote (procgroup, module, instance))
1315 return ERROR;
1316 }
1317 else if (!_dxf_ExDeleteRemote (module, instance))
1318 return ERROR;
1319
1320 return (OK);
1321 }
1322
Pfsmgr(char * c,Object * in)1323 static int Pfsmgr (char *c, Object *in)
1324 {
1325 int argc = 0;
1326 char *argv[1024];
1327 char *buf = NULL;
1328 char *b;
1329 int len;
1330 Error ret = ERROR;
1331
1332 if (! c)
1333 {
1334 ret = OK;
1335 goto cleanup;
1336 }
1337
1338 len = strlen (c) + 1;
1339 b = buf = (char *) DXAllocateLocal (len);
1340 if (buf == NULL)
1341 goto cleanup;
1342 memcpy (buf, c, len);
1343
1344 while (*b)
1345 {
1346 argv[argc++] = b;
1347 while (*b && ! isspace (*b))
1348 b++;
1349 while (*b && isspace (*b))
1350 b++;
1351 }
1352
1353 for (b = buf; *b; b++)
1354 if (isspace (*b))
1355 *b = (char) NULL;
1356
1357 ret = _dxf_pfsmgr (argc, argv);
1358
1359 cleanup:
1360 DXFree ((Pointer) buf);
1361 return (ret);
1362 }
1363
1364
PrintCache(char * c,Object * in)1365 static int PrintCache (char *c, Object *in)
1366 {
1367 _dxf_ExDictPrint (_dxd_exCacheDict);
1368 return (OK);
1369 }
1370
1371
PrintExObjects(char * c,Object * in)1372 static int PrintExObjects (char *c, Object *in)
1373 {
1374 #ifdef LEAK_DEBUG
1375 PrintEXObj ();
1376 #else
1377 DXMessage ("#1280");
1378 #endif
1379 return (OK);
1380 }
1381
1382
PrintFunction(char * c,Object * in)1383 static int PrintFunction (char *c, Object *in)
1384 {
1385 _dxf_ExDictPrint (_dxd_exMacroDict);
1386 return (OK);
1387 }
1388
1389
PrintGlobal(char * c,Object * in)1390 static int PrintGlobal (char *c, Object *in)
1391 {
1392 _dxf_ExDictPrint (_dxd_exGlobalDict);
1393 return (OK);
1394 }
1395
PrintGroups(char * c,Object * in)1396 static int PrintGroups (char *c, Object *in)
1397 {
1398 _dxf_ExPrintGroups();
1399 return (OK);
1400 }
1401
PrintHosts(char * c,Object * in)1402 static int PrintHosts (char *c, Object *in)
1403 {
1404 _dxf_ExPrintHosts();
1405 return (OK);
1406 }
1407
Reclaim(char * c,Object * in)1408 static int Reclaim (char *c, Object *in)
1409 {
1410 DXTraceTime (1);
1411 _dxf_ExReclaimMemory (atol (c));
1412 DXTraceTime (0);
1413 DXPrintTimes ();
1414 return (OK);
1415 }
1416
SyncGraph(char * c,Object * in)1417 static int SyncGraph (char *c, Object *in)
1418 {
1419 _dxd_exParseAhead = FALSE;
1420 return(OK);
1421 }
1422
Terminate(char * c,Object * in)1423 static int Terminate (char *c, Object *in)
1424 {
1425 exit (0);
1426 /* not reached */
1427 return (OK);
1428 }
1429
License(char * c,Object * in)1430 static int License (char *c, Object *in)
1431 {
1432
1433 #ifdef DXD_LICENSED_VERSION
1434
1435 static int license_tried = FALSE;
1436 int i;
1437 char keybuf[14];
1438 char typebuf[5];
1439 char key[9];
1440 char salt[3];
1441
1442 /* decode and check license string here */
1443
1444 if (license_tried)
1445 exit(0); /* our UI will never call $license twice */
1446 else
1447 license_tried = TRUE;
1448
1449 for(i=0;i<13;i++)
1450 keybuf[i] = c[i];
1451 keybuf[13] = '\0';
1452
1453 for(i=0;i<4;i++)
1454 typebuf[i] = c[i+13];
1455 typebuf[4] = '\0';
1456
1457 for(i=0;i<4;i++)
1458 key[i*2] = _dxd_LicenseKey[i];
1459
1460 key[1] = 'g';
1461 key[3] = '3';
1462 key[5] = '$';
1463 key[7] = 'Q';
1464 key[8] = '\0';
1465
1466 salt[0] = '4';
1467 salt[1] = '.';
1468 salt[2] = '\0';
1469
1470 if(strcmp(keybuf,(const char *)crypt(key,salt))){
1471 DXMessage("License Error: Invalid license Message\n");
1472 DXUIMessage("LICENSE","UNAUTHORIZED");
1473 return (OK);
1474 }
1475
1476 sscanf(typebuf,"%04x",&i);
1477
1478 /* This junk below is to preserve byte order, beware ! */
1479
1480 switch(i^(*((ubyte *)&keybuf[4])<<8)+(*((ubyte *)&keybuf[5]))) {
1481
1482 case GOT_NODELOCKED:
1483 if (!ExGetPrimaryLicense())
1484 DXMessage("Exec could not get a license (UI has nodelocked)\n");
1485 else
1486 DXUIMessage("LICENSE", "AUTHORIZED");
1487 break;
1488
1489 case GOT_CONCURRENT:
1490 _dxd_ExHasLicense = TRUE;
1491 DXUIMessage("LICENSE", "AUTHORIZED");
1492 DXMessage("Running under UI's concurrent license\n");
1493 break;
1494
1495 default:
1496 DXMessage("License Error: Invalid license Message\n");
1497 break;
1498 }
1499
1500 if (_dxd_ExHasLicense == FALSE)
1501 DXUIMessage("LICENSE","UNAUTHORIZED");
1502
1503 if (_dxd_ExHasLicense && _dxd_exRemote)
1504 _dxf_ExReadDXRCFiles();
1505
1506 #else /* DXD_LICENSED_VERSION */
1507
1508 if (_dxd_exRemote)
1509 _dxf_ExReadDXRCFiles();
1510
1511 DXUIMessage("LICENSE", "AUTHORIZED");
1512
1513 #endif /* !DXD_LICENSED_VERSION */
1514
1515 return (OK);
1516 }
1517
GetKey(char * c,Object * in)1518 static int GetKey (char *c, Object *in)
1519 {
1520 #ifdef DXD_LICENSED_VERSION
1521
1522 int i;
1523
1524 srand(time(NULL));
1525 i = rand();
1526 i = (i<4096) ? (i+4096) : (i); /* forces to be 4 0x chars */
1527
1528 sprintf(_dxd_LicenseKey, "%x\n", i);
1529 DXUIMessage("LICENSE", _dxd_LicenseKey);
1530
1531 #else /* DXD_LICENSED_VERSION */
1532
1533 DXUIMessage("LICENSE","ffff"); /* write key ffff in case UI tries */
1534 /* to use license protocol */
1535 #endif /* !DXD_LICENSED_VERSION */
1536
1537 return (OK);
1538 }
1539
1540
1541
Version(char * c,Object * in)1542 static int Version (char *c, Object *in)
1543 {
1544 int n;
1545 int m0, m1, m2;
1546 char buf[256];
1547 int err = TRUE;
1548 char *b;
1549
1550 if (c == NULL || *c == '\000')
1551 {
1552 DXBeginLongMessage ();
1553 DXMessage ("Executive version: %d %d %d\n",
1554 DXD_VERSION, DXD_RELEASE, DXD_MODIFICATION);
1555 DXMessage ("Executive/UI interface: %d %d %d\n",
1556 UI_MAJOR, UI_MINOR, UI_MICRO);
1557 DXMessage ("Creation date: %s\n", EX_COM_DATE);
1558 DXMessage ("Creation host: %s\n", EX_COM_HOST);
1559 DXEndLongMessage ();
1560 return (OK);
1561 }
1562
1563 #if DXD_PRINTF_RETURNS_COUNT
1564 n = sprintf (buf,
1565 "Executive/UI version mismatch: %d %d %d vs ",
1566 UI_MAJOR, UI_MINOR, UI_MICRO);
1567 #else
1568 {
1569 sprintf (buf,
1570 "Executive/UI version mismatch: %d %d %d vs ",
1571 UI_MAJOR, UI_MINOR, UI_MICRO);
1572 n = strlen(buf);
1573 }
1574 #endif
1575 b = buf + n;
1576
1577 n = sscanf (c, "%d%d%d", &m0, &m1, &m2);
1578
1579 if (n == 3 && m0 == UI_MAJOR && m1 == UI_MINOR && m2 == UI_MICRO)
1580 err = FALSE;
1581 else
1582 sprintf (b, "%s", *c ? c : "<no version specified>");
1583
1584 if (err)
1585 DXUIMessage ("ERROR", buf);
1586
1587 return (OK);
1588 }
1589
1590
ProductVersion(char * c,Object * in)1591 static int ProductVersion (char *c, Object *in)
1592 {
1593 int n;
1594 int m0, m1, m2;
1595
1596 if (c == NULL || *c == '\000') {
1597 DXSetError(ERROR_BAD_PARAMETER,
1598 "Product Version string required for version check");
1599 return ERROR;
1600 }
1601
1602 n = sscanf (c, "%d%d%d", &m0, &m1, &m2);
1603 #define VERSION_ID(a,b,c) (((a) << 16) + ((b) << 8) + (c))
1604
1605 if (n != 3 ||
1606 (VERSION_ID(m0,m1,m2) >
1607 VERSION_ID(DXD_VERSION,DXD_RELEASE,DXD_MODIFICATION))) {
1608 DXWarning("User Interface or .net file version is newer than Executive version");
1609 }
1610
1611 return (OK);
1612 }
1613
1614 /* No longer used so make it undefined */
1615 #if 0
1616 static Error UnLoadObjFile(char *c, Object *in)
1617 {
1618 char *str;
1619
1620 if (!in[0] || ! DXExtractString (in[0], &str)) {
1621 DXSetError (ERROR_BAD_PARAMETER, "#10200", "object filename");
1622 return (ERROR);
1623 }
1624
1625 return DXUnloadObjFile(str);
1626 }
1627 #endif
1628