]> andersk Git - moira.git/blob - clients/mmoira/stubs.c
don't clear form->extrastuff on every query or the modify operations
[moira.git] / clients / mmoira / stubs.c
1 /*
2 ** Stub functions
3 */
4
5 #include        <ctype.h>
6 #include        <stdio.h>
7 #include        <X11/StringDefs.h>
8 #include        <X11/Intrinsic.h>
9 #include        <X11/Core.h>
10 #include        <X11/cursorfont.h>
11 #include        <Xm/Text.h>
12 #include        <Xm/MessageB.h>
13 #include        "mmoira.h"
14 #include        <sys/file.h>
15
16 static char rcsid[] = "$Header$";
17
18 void    extra_help_callback();
19 extern EntryForm *MoiraForms[];
20 static DoMoiraSelect(), DoReference();
21
22 static Widget   logwidget = NULL;
23
24
25 /* No-op action to mask built-in actions */
26
27 void noopACT(w, event, p, n)
28 Widget w;
29 XEvent *event;
30 String *p;
31 Cardinal *n;
32 {
33 }
34
35
36 /* Action to do a moira retrieve on what was clicked at */
37
38 void moiraRetrieveACT(w, event, p, n)
39 Widget w;
40 XEvent *event;
41 String *p;
42 Cardinal *n;
43 {
44     XmTextPosition pos;
45     XButtonEvent *be;
46
47     be = (XButtonEvent *)event;
48
49     pos = XmTextXYToPos(w, be->x, be->y);
50     DoMoiraSelect(pos, w, 0);
51 }
52
53
54 /* Action to modify the moira object that was clicked on */
55
56 void moiraModifyACT(w, event, p, n)
57 Widget w;
58 XEvent *event;
59 String *p;
60 Cardinal *n;
61 {
62     XmTextPosition pos;
63     XButtonEvent *be;
64
65     be = (XButtonEvent *)event;
66
67     pos = XmTextXYToPos(w, be->x, be->y);
68     DoMoiraSelect(pos, w, 1);
69 }
70
71
72 static XtActionsRec myactions[] = {
73     { "moiraRetrieve", moiraRetrieveACT },
74     { "moiraModify", moiraModifyACT },
75     { "noop", noopACT },
76 };
77
78
79 /* Create the log window, and setup the translation table to taking
80  * mouse clicks in it.
81  */
82
83 Widget
84 SetupLogWidget(parent)
85 Widget  parent;
86 {
87         Arg             wargs[10];
88         int             n;
89         XtTranslations  trans;
90
91         if (logwidget)
92                 return (logwidget);
93         
94         n = 0;
95         XtSetArg(wargs[n], XmNeditMode, XmMULTI_LINE_EDIT);     n++;
96         XtSetArg(wargs[n], XmNeditable, False);                 n++;
97
98         logwidget = XmCreateScrolledText(       parent,
99                                                 "logwidget", 
100                                                 wargs, n);
101         XtManageChild(logwidget);
102
103         XtAppAddActions(XtWidgetToApplicationContext(logwidget),
104                         myactions, XtNumber(myactions));
105         trans = XtParseTranslationTable(resources.log_trans);
106         XtOverrideTranslations(logwidget, trans);
107         return (logwidget);
108 }
109
110
111 /* This actually does all of the work for handling mouse clicks.  It
112  * finds the surrounding text and decides what to do with the click,
113  * the actually starts the moira query or pops up the form.
114  */
115
116 static DoMoiraSelect(pos, w, modify)
117 XmTextPosition pos;
118 Widget w;
119 int modify;    
120 {
121     char *log, *p, *p1, *p2;
122     char name[256], type[256], type2[256];
123
124     log = XmTextGetString(w);
125     for (p = &log[pos]; p > log; p--)
126       if (isspace(*p) || *p == ':') break;
127
128     /* p now points to the beginning of the word on which the mouse was
129      * clicked.  Begin gross hacking to find the name and type of object.
130      */
131     /* get name */
132     p1 = p + 1;
133     p2 = name;
134     while (*p1 && !isspace(*p1)) *p2++ = *p1++;
135     *p2 = 0;
136     /* backup two words before for type2 */
137     while (p >= log && isspace(*p) || *p == ':') p--;
138     while (p >= log && !isspace(*p)) p--;
139     while (p >= log && isspace(*p)) p--;
140     while (p >= log && !isspace(*p)) p--;
141     p++;
142     p2 = type2;
143     /* new get type2 */
144     if (p > log) {
145         while (!isspace(*p)) *p2++ = *p++;
146         *p2++ = *p++;
147         /* skip additional whitespace */
148         while (isspace(*p)) p++;
149     }
150     /* get type & rest of type2 */
151     p1 = type;
152     while (*p && *p != ':' && !isspace(*p)) *p2++ = *p1++ = *p++;
153     *p2 = *p1 = 0;
154     /* Done! */
155 #ifdef DEBUG
156     printf("name \"%s\", type \"%s\" type2 \"%s\"\n", name, type, type2);
157 #endif /* DEBUG */
158     if (!strcasecmp(type, "USER") ||
159         !strcmp(type, "name") ||
160         !strcmp(type2, "Modified by") ||
161         !strcmp(type2, "User Ownership") ||
162         !strcmp(type2, "Login name") ||
163         !strcmp(type, "login")) {
164         DoReference(name, "select_user", MM_MOD_USER, MM_SHOW_USER,
165                     "get_user_account_by_login", modify);
166     } else if (!strcasecmp(type, "LIST") ||
167                !strcmp(type2, "Group Ownership")) {
168         DoReference(name, "select_list", MM_MOD_LIST, MM_SHOW_LIST,
169                     "get_list_info", modify);
170     } else if (!strcasecmp(type, "MACHINE") ||
171                !strcmp(type, "host") ||
172                !strcasecmp(type, "Server") ||
173                !strcmp(type, "on") ||
174                !strcmp(type, "Box")) {
175         DoReference(name, "select_machine", MM_MOD_MACH, MM_SHOW_MACH,
176                     "get_machine", modify);
177     } else if (!strcasecmp(type, "CLUSTER")) {
178         DoReference(name, "select_cluster", MM_MOD_CLUSTER, MM_SHOW_CLUSTER,
179                     "get_cluster", modify);
180     } else if (!strcasecmp(type, "FILESYSTEM") ||
181                !strcmp(type, "FILESYS") ||
182                !strcmp(type2, "syslib Data")) {
183         DoReference(name, "select_filsys", MM_MOD_FILSYS, MM_SHOW_FILSYS,
184                     "get_filesys_by_label", modify);
185     } else if (!strcmp(type2, "Filesystem Group")) {
186         DoReference(name, "order_fsgroup", MM_MOV_FSGROUP, MM_SHOW_FSGROUP,
187                     "get_filesys_by_label", modify);
188     } else if (!strcmp(type, "Printer") ||
189                !strcmp(type2, "lpr Data")) {
190         DoReference(name, "select_printer", MM_MOD_PCAP, MM_SHOW_PCAP,
191                     "get_printcap_entry", modify);
192     } else if (!strcmp(type, "Service")) {
193         DoReference(name, "select_service", MM_MOD_SERVICE, MM_SHOW_SERVICE,
194                     "get_server_info", modify);
195 /* This code isn't complete, and it's not clear that we really want it...
196     } else if (!strcmp(type, "Packname")) {
197         char name2[256];
198         sprintf(name2, "%s:%s", type2, name);
199         p = rindex(name2, '/');
200         if (p) *p = 0;
201         DoReference(name, "select_nfs", MM_MOD_NFS, MM_SHOW_NFS,
202                     "get_nfsphys", modify);
203 */  } else {
204         XBell(XtDisplay(w), 100);
205     }
206     XtFree(log);
207 }
208
209
210 /* This is the heart of handling the reference once we have found out
211  * what type of reference it is.
212  */
213
214 static DoReference(name, formname, modop, showop, query, modify)
215 char *name;
216 char *formname;
217 int modop;
218 int showop;
219 char *query;
220 int modify;
221 {
222     EntryForm *form, f;
223     MenuItem m;
224     char *argv[2], **aargv;
225     int status;
226
227     if (modify) {
228         form = GetAndClearForm(formname);
229         StoreField(form, 0, name);
230         form->menu = &m;
231         m.operation = modop;
232         m.query = query;
233         m.argc = 1;
234         if (showop == MM_SHOW_FSGROUP) {
235             DisplayForm(form);
236             MoiraValueChanged(form, form->inputlines[0]);
237         } else
238           MoiraFormApply(0, form);
239     } else {
240         f.menu = &m;
241         if (showop == MM_SHOW_FILSYS ||
242             showop == MM_SHOW_FSGROUP) f.extrastuff = (caddr_t) sq_create();
243         argv[0] = name;
244         m.operation = showop;
245         status = MoiraQuery(query, 1, argv, DisplayCallback, &f);
246         if (showop == MM_SHOW_FILSYS ||
247             showop == MM_SHOW_FSGROUP) {
248             while (sq_get_data(f.extrastuff, &aargv)) {
249                 ShowFilsys(aargv);
250             }
251             sq_destroy(f.extrastuff);
252         }
253         if (status)
254           com_err(program_name, status, " while looking up data");
255         else
256           AppendToLog("\n");
257     }
258 }
259
260
261 /*
262 ** PopupErrorMessage(text)
263 **
264 ** Given a char* pointing to an error message, possibly with imbedded
265 ** newlines, display the text in a popup window and put two buttons
266 ** at the bottom of the window, labelled "OK" and "Cancel."  Pop down
267 ** when one of the buttons is pressed.
268 **
269 ** Return 0 if "OK" is pressed, 1 for "Cancel."
270 */
271
272 Boolean
273 PopupErrorMessage(text, extrahelp)
274 char    *text;
275 char    *extrahelp;
276 {
277         static Widget           child;
278         Arg             wargs[10];
279         int             n;
280         static XmString        label;
281
282         if (tty) {
283             printf("%s\r\n", text);
284             return;
285         }
286
287         if (label) {
288                 XtFree(label);
289                 XtDestroyWidget(child);
290         }
291
292
293         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
294
295         n = 0;
296         XtSetArg(wargs[n], XmNmessageString, label);            n++;
297
298         child = (Widget) XmCreateErrorDialog(logwidget, "errormessage", wargs, n);
299         if (extrahelp) 
300                 XtAddCallback (child, XmNhelpCallback, extra_help_callback, extrahelp);
301         else
302                 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
303         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
304         XtManageChild(child);
305 }
306
307 /*
308 ** PopupHelpWindow(text)
309 **
310 ** Given a char* pointing to an help message, possibly with imbedded
311 ** newlines, display the text in a popup window and put a single button
312 ** at the bottom of the window, labelled "OK."  Pop down when the
313 ** the buttons is pressed.
314 */
315
316 void
317 PopupHelpWindow(text)
318 char    *text;
319 {
320         static Widget           child;
321         Arg             wargs[10];
322         int             n;
323
324         static XmString        label;
325         if (label) {
326                 XtFree(label);
327                 XtDestroyWidget(child);
328         }
329
330         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
331
332         n = 0;
333         XtSetArg(wargs[n], XmNmessageString, label);            n++;
334
335         child = (Widget) XmCreateMessageDialog(logwidget, "helpmessage", wargs, n);
336         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
337         XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
338
339         XtManageChild(child);
340 }
341
342 /*
343 ** Given a char* to a single line of text, append this line at the bottom
344 ** of the log window.  Return 0 of the append was sucessful, non-zero
345 ** for an error condition.
346 */
347
348 int
349 AppendToLog(text)
350 char    *text;
351 {
352         XmTextPosition  pos;
353         char            *string, *p;
354
355         if (tty) {
356             fputs(text, stdout);
357             return;
358         }
359
360         string = XmTextGetString(logwidget);
361         pos = strlen(string);
362         XtFree(string);
363
364         XmTextReplace(logwidget, pos, pos, text);
365         XmTextSetCursorPosition(logwidget, pos + strlen(text));
366         if (pos > resources.maxlogsize) {
367             for (p = &string[pos-resources.maxlogsize]; *p && *p != '\n'; p++);
368             if (*p)
369               pos = p - string;
370             XmTextReplace(logwidget, 0, pos, "");
371         }
372 }
373
374 void
375 MakeWatchCursor(topW)
376 Widget  topW;
377 {
378     static Cursor mycursor = NULL;
379     EntryForm **fp;
380
381     if (!topW)
382       return;
383
384     if (!mycursor)
385       mycursor = XCreateFontCursor (XtDisplay(topW), XC_watch);
386
387     XDefineCursor(XtDisplay(topW), XtWindow(topW), mycursor);
388     for (fp = MoiraForms; *fp; fp++)
389       if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
390         XDefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer), mycursor);
391 }
392
393 void
394 MakeNormalCursor(topW)
395 Widget  topW;
396 {
397     EntryForm **fp;
398
399     if (!topW)
400       return;
401
402     XUndefineCursor(XtDisplay(topW), XtWindow(topW));
403     for (fp = MoiraForms; *fp; fp++)
404       if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
405         XUndefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer));
406 }
407
408 /*
409 ** Move through the fields of the spec and make certain that the
410 ** form's widgets actually reflect the current values.
411 */
412
413 void
414 UpdateForm(spec)
415 EntryForm       *spec;
416 {
417         UserPrompt      **myinputlines = spec->inputlines;
418         UserPrompt      *current;
419         Arg             wargs[10];
420         int             n, kidcount;
421         Widget          kid;
422
423         if (tty || spec->formpointer == NULL) return;
424
425         for (   current = (*myinputlines);
426                 current; 
427                 myinputlines++, current = (*myinputlines)) {
428
429                 if (current->changed) {
430                     n = 0;
431                     XtSetArg(wargs[n], XmNsensitive,
432                              current->insensitive ? False : True); n++;
433                     XtSetValues(current->mywidget, wargs, n);
434                     current->changed = False;
435                 }
436
437                 switch (current->type) {
438                 case FT_STRING:
439                         if (current->returnvalue.stringvalue) {
440                                 XmTextSetString (current->mywidget, current->returnvalue.stringvalue);
441                         }
442                         break;
443
444                 case FT_BOOLEAN:
445                         n = 0;
446                         XtSetArg(wargs[n], XmNset,
447                                  current->returnvalue.booleanvalue ? True : False);     n++;
448                         XtSetValues (current->mywidget, wargs, n);
449                         break;
450
451                 case FT_KEYWORD:
452                         kidcount = NumChildren(current->mywidget);
453                         while(kidcount--) {
454                                 n = 0;
455                                 kid = NthChild(current->mywidget, kidcount);
456                                 if (current->returnvalue.stringvalue &&
457                                         (!strcmp (XtName(kid), current->returnvalue.stringvalue))) {
458                                         XtSetArg(wargs[n], XmNset, True);
459                                         n++;
460                                 }
461                                 else {
462                                         XtSetArg(wargs[n], XmNset, False);
463                                         n++;
464                                 }
465                                 XtSetValues (kid, wargs, n);
466                         }
467                         break;
468
469                 case FT_NUMBER:
470                         break;
471                 }
472                 n = 0;
473                 XtSetArg(wargs[n], XtNsensitive, !(current->insensitive));              n++;
474                 XtSetValues (current->mywidget, wargs, n);
475         }
476 }
477
478 void
479 extra_help_callback(w, client_data, call_data)
480 Widget  w;
481 char    *client_data;
482 XmAnyCallbackStruct     *call_data;
483 {
484     help(client_data);
485 }
486
487
488 int write_log_to_file(fn)
489 char *fn;
490 {
491     char *string, buf[256];
492     int fd, i;
493     extern int errno;
494
495     string = XmTextGetString(logwidget);
496     fd = open(fn, O_WRONLY|O_CREAT, 0666);
497     if (fd < 0) {
498         sprintf(buf, "opening output file \"%s\"", fn);
499         com_err(program_name, errno, buf);
500         return(1);
501     }
502     if ((i = write(fd, string, strlen(string))) < 0) {
503         sprintf(buf, "writing output file \"%s\"", fn);
504         com_err(program_name, errno, buf);
505         return(1);
506     }
507     if ((i = close(fd)) < 0) {
508         sprintf(buf, "closing output file \"%s\"", fn);
509         com_err(program_name, errno, buf);
510         return(1);
511     }
512     return(0);
513 }
514
515
516 void yesCallback(w, ret, dummy)
517 Widget w;
518 XtPointer ret;
519 XtPointer dummy;
520 {
521     int *ip = (int *)ret;
522     *ip = 1;
523 }
524
525 void noCallback(w, ret, dummy)
526 Widget w;
527 XtPointer ret;
528 XtPointer dummy;
529 {
530     int *ip = (int *)ret;
531     *ip = -1;
532 }
533
534
535 static int value;
536 static XtCallbackRec yescb[] = { { yesCallback, (XtPointer) &value },
537                                  { NULL, NULL} };
538 static XtCallbackRec nocb[]  = { { noCallback, (XtPointer) &value },
539                                  {NULL, NULL} };
540
541 Boolean AskQuestion(text, helpname)
542 char *text, *helpname;
543 {
544         static Widget           child;
545         Arg             wargs[10];
546         int             n;
547         static XmString        label, yes = NULL, no;
548         XEvent  event;
549         XtAppContext _XtDefaultAppContext();
550
551         if (!yes) {
552             yes = XmStringCreate("Yes", XmSTRING_DEFAULT_CHARSET);
553             no = XmStringCreate("No", XmSTRING_DEFAULT_CHARSET);
554         }
555         if (label) {
556                 XtFree(label);
557                 XtDestroyWidget(child);
558         }
559
560         label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
561
562         n = 0;
563         XtSetArg(wargs[n], XmNmessageString, label);            n++;
564         XtSetArg(wargs[n], XmNokLabelString, yes);              n++;
565         XtSetArg(wargs[n], XmNcancelLabelString, no);           n++;
566         XtSetArg(wargs[n], XmNokCallback, yescb);               n++;
567         XtSetArg(wargs[n], XmNcancelCallback, nocb);            n++;
568
569         child = (Widget) XmCreateQuestionDialog(logwidget, "question", wargs, n);
570         if (helpname) 
571                 XtAddCallback (child, XmNhelpCallback, extra_help_callback, helpname);
572         else
573                 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
574
575         XtManageChild(child);
576         value = 0;
577         while (value == 0) {
578             XtAppNextEvent(_XtDefaultAppContext(), &event);
579             XtDispatchEvent(&event);
580         }
581         if (value > 0)
582           return(1);
583         else
584           return(0);
585 }
586
587
588
589 /******* temporary ********/
590 display_error(msg)
591 char *msg;
592 {
593     PopupErrorMessage(msg, "no_more_help");
594 }
This page took 0.506207 seconds and 5 git commands to generate.