11 #include <X11/StringDefs.h>
12 #include <X11/Intrinsic.h>
14 #include <X11/cursorfont.h>
16 #include <Xm/MessageB.h>
18 #include <sys/types.h>
22 static char rcsid[] = "$Header$";
24 void extra_help_callback();
25 extern EntryForm *MoiraForms[];
26 static DoMoiraSelect(), DoReference();
28 static Widget logwidget = NULL;
31 /* No-op action to mask built-in actions */
33 void noopACT(w, event, p, n)
42 /* Action to do a moira retrieve on what was clicked at */
44 void moiraRetrieveACT(w, event, p, n)
53 be = (XButtonEvent *)event;
55 pos = XmTextXYToPos(w, be->x, be->y);
56 DoMoiraSelect(pos, w, 0);
60 /* Action to modify the moira object that was clicked on */
62 void moiraModifyACT(w, event, p, n)
71 be = (XButtonEvent *)event;
73 pos = XmTextXYToPos(w, be->x, be->y);
74 DoMoiraSelect(pos, w, 1);
78 static XtActionsRec myactions[] = {
79 { "moiraRetrieve", moiraRetrieveACT },
80 { "moiraModify", moiraModifyACT },
85 /* Create the log window, and setup the translation table to taking
90 SetupLogWidget(parent)
101 XtSetArg(wargs[n], XmNeditMode, XmMULTI_LINE_EDIT); n++;
102 XtSetArg(wargs[n], XmNeditable, False); n++;
104 logwidget = XmCreateScrolledText( parent,
107 XtManageChild(logwidget);
109 XtAppAddActions(XtWidgetToApplicationContext(logwidget),
110 myactions, XtNumber(myactions));
111 trans = XtParseTranslationTable(resources.log_trans);
112 XtOverrideTranslations(logwidget, trans);
117 /* This actually does all of the work for handling mouse clicks. It
118 * finds the surrounding text and decides what to do with the click,
119 * the actually starts the moira query or pops up the form.
122 static DoMoiraSelect(pos, w, modify)
127 char *log, *p, *p1, *p2;
128 char name[256], type[256], type2[256];
130 log = XmTextGetString(w);
131 for (p = &log[pos]; p > log; p--)
132 if (isspace(*p) || *p == ':') break;
134 /* p now points to the beginning of the word on which the mouse was
135 * clicked. Begin gross hacking to find the name and type of object.
140 while (*p1 && !isspace(*p1)) *p2++ = *p1++;
142 /* backup two words before for type2 */
143 while (p >= log && isspace(*p) || *p == ':') p--;
144 while (p >= log && !isspace(*p)) p--;
145 while (p >= log && isspace(*p)) p--;
146 while (p >= log && !isspace(*p)) p--;
151 while (!isspace(*p)) *p2++ = *p++;
153 /* skip additional whitespace */
154 while (isspace(*p)) p++;
156 /* get type & rest of type2 */
158 while (*p && *p != ':' && !isspace(*p)) *p2++ = *p1++ = *p++;
162 printf("name \"%s\", type \"%s\" type2 \"%s\"\n", name, type, type2);
164 if (!strcasecmp(type, "USER") ||
165 !strcmp(type, "name") ||
166 !strcmp(type2, "Modified by") ||
167 !strcmp(type2, "User Ownership") ||
168 !strcmp(type2, "Login name") ||
169 !strcmp(type, "login")) {
170 DoReference(name, "select_user", MM_MOD_USER, MM_SHOW_USER,
171 "get_user_account_by_login", modify);
172 } else if (!strcasecmp(type, "LIST") ||
173 !strcmp(type2, "Group Ownership")) {
174 DoReference(name, "select_list", MM_MOD_LIST, MM_SHOW_LIST,
175 "get_list_info", modify);
176 } else if (!strcasecmp(type, "MACHINE") ||
177 !strcmp(type, "host") ||
178 !strcasecmp(type, "Server") ||
179 !strcmp(type, "on") ||
180 !strcmp(type, "Box")) {
181 DoReference(name, "select_machine", MM_MOD_MACH, MM_SHOW_MACH,
182 "get_machine", modify);
183 } else if (!strcasecmp(type, "CLUSTER")) {
184 DoReference(name, "select_cluster", MM_MOD_CLUSTER, MM_SHOW_CLUSTER,
185 "get_cluster", modify);
186 } else if (!strcasecmp(type, "FILESYSTEM") ||
187 !strcmp(type, "FILESYS") ||
188 !strcmp(type2, "syslib Data")) {
189 DoReference(name, "select_filsys", MM_MOD_FILSYS, MM_SHOW_FILSYS,
190 "get_filesys_by_label", modify);
191 } else if (!strcmp(type2, "Filesystem Group")) {
192 DoReference(name, "order_fsgroup", MM_MOV_FSGROUP, MM_SHOW_FSGROUP,
193 "get_filesys_by_label", modify);
194 } else if (!strcmp(type, "Printer") ||
195 !strcmp(type2, "lpr Data")) {
196 DoReference(name, "select_printer", MM_MOD_PCAP, MM_SHOW_PCAP,
197 "get_printcap_entry", modify);
198 } else if (!strcmp(type, "Service")) {
199 DoReference(name, "select_service", MM_MOD_SERVICE, MM_SHOW_SERVICE,
200 "get_server_info", modify);
201 /* This code isn't complete, and it's not clear that we really want it...
202 } else if (!strcmp(type, "Packname")) {
204 sprintf(name2, "%s:%s", type2, name);
205 p = strrchr(name2, '/');
207 DoReference(name, "select_nfs", MM_MOD_NFS, MM_SHOW_NFS,
208 "get_nfsphys", modify);
210 XBell(XtDisplay(w), 100);
216 /* This is the heart of handling the reference once we have found out
217 * what type of reference it is.
220 static DoReference(name, formname, modop, showop, query, modify)
230 char *argv[2], **aargv;
234 form = GetAndClearForm(formname);
235 StoreField(form, 0, name);
240 if (showop == MM_SHOW_FSGROUP) {
242 MoiraValueChanged(form, form->inputlines[0]);
244 MoiraFormApply(0, form);
247 if (showop == MM_SHOW_FILSYS ||
248 showop == MM_SHOW_FSGROUP) f.extrastuff = (caddr_t) sq_create();
250 m.operation = showop;
251 status = MoiraQuery(query, 1, argv, DisplayCallback, &f);
252 if (showop == MM_SHOW_FILSYS ||
253 showop == MM_SHOW_FSGROUP) {
254 while (sq_get_data(f.extrastuff, &aargv)) {
257 sq_destroy(f.extrastuff);
260 com_err(program_name, status, " while looking up data");
268 ** PopupErrorMessage(text)
270 ** Given a char* pointing to an error message, possibly with imbedded
271 ** newlines, display the text in a popup window and put two buttons
272 ** at the bottom of the window, labelled "OK" and "Cancel." Pop down
273 ** when one of the buttons is pressed.
275 ** Return 0 if "OK" is pressed, 1 for "Cancel."
279 PopupErrorMessage(text, extrahelp)
286 static XmString label;
289 printf("%s\r\n", text);
295 XtDestroyWidget(child);
299 label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
302 XtSetArg(wargs[n], XmNmessageString, label); n++;
304 child = (Widget) XmCreateErrorDialog(logwidget, "errormessage", wargs, n);
306 XtAddCallback (child, XmNhelpCallback, extra_help_callback, extrahelp);
308 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
309 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
310 XtManageChild(child);
314 ** PopupHelpWindow(text)
316 ** Given a char* pointing to an help message, possibly with imbedded
317 ** newlines, display the text in a popup window and put a single button
318 ** at the bottom of the window, labelled "OK." Pop down when the
319 ** the buttons is pressed.
323 PopupHelpWindow(text)
330 static XmString label;
333 XtDestroyWidget(child);
336 label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
339 XtSetArg(wargs[n], XmNmessageString, label); n++;
341 child = (Widget) XmCreateMessageDialog(logwidget, "helpmessage", wargs, n);
342 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_CANCEL_BUTTON));
343 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
345 XtManageChild(child);
349 ** Given a char* to a single line of text, append this line at the bottom
350 ** of the log window. Return 0 of the append was sucessful, non-zero
351 ** for an error condition.
366 string = XmTextGetString(logwidget);
367 pos = strlen(string);
370 XmTextReplace(logwidget, pos, pos, text);
371 XmTextSetCursorPosition(logwidget, pos + strlen(text));
372 if (pos > resources.maxlogsize) {
373 for (p = &string[pos-resources.maxlogsize]; *p && *p != '\n'; p++);
376 XmTextReplace(logwidget, 0, pos, "");
381 MakeWatchCursor(topW)
384 static Cursor mycursor = NULL;
391 mycursor = XCreateFontCursor (XtDisplay(topW), XC_watch);
393 XDefineCursor(XtDisplay(topW), XtWindow(topW), mycursor);
394 for (fp = MoiraForms; *fp; fp++)
395 if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
396 XDefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer), mycursor);
400 MakeNormalCursor(topW)
408 XUndefineCursor(XtDisplay(topW), XtWindow(topW));
409 for (fp = MoiraForms; *fp; fp++)
410 if ((*fp)->formpointer && XtIsManaged((*fp)->formpointer))
411 XUndefineCursor(XtDisplay(topW), XtWindow((*fp)->formpointer));
415 ** Move through the fields of the spec and make certain that the
416 ** form's widgets actually reflect the current values.
423 UserPrompt **myinputlines = spec->inputlines;
429 if (tty || spec->formpointer == NULL) return;
431 for ( current = (*myinputlines);
433 myinputlines++, current = (*myinputlines)) {
435 if (current->changed) {
437 XtSetArg(wargs[n], XmNsensitive,
438 current->insensitive ? False : True); n++;
439 XtSetValues(current->mywidget, wargs, n);
440 current->changed = False;
443 switch (current->type) {
445 if (current->returnvalue.stringvalue) {
446 XmTextSetString (current->mywidget, current->returnvalue.stringvalue);
452 XtSetArg(wargs[n], XmNset,
453 current->returnvalue.booleanvalue ? True : False); n++;
454 XtSetValues (current->mywidget, wargs, n);
458 kidcount = NumChildren(current->mywidget);
461 kid = NthChild(current->mywidget, kidcount);
462 if (current->returnvalue.stringvalue &&
463 (!strcmp (XtName(kid), current->returnvalue.stringvalue))) {
464 XtSetArg(wargs[n], XmNset, True);
468 XtSetArg(wargs[n], XmNset, False);
471 XtSetValues (kid, wargs, n);
479 XtSetArg(wargs[n], XtNsensitive, !(current->insensitive)); n++;
480 XtSetValues (current->mywidget, wargs, n);
485 extra_help_callback(w, client_data, call_data)
488 XmAnyCallbackStruct *call_data;
494 int write_log_to_file(fn)
497 char *string, buf[256];
501 string = XmTextGetString(logwidget);
502 fd = open(fn, O_WRONLY|O_CREAT, 0666);
504 sprintf(buf, "opening output file \"%s\"", fn);
505 com_err(program_name, errno, buf);
508 if ((i = write(fd, string, strlen(string))) < 0) {
509 sprintf(buf, "writing output file \"%s\"", fn);
510 com_err(program_name, errno, buf);
513 if ((i = close(fd)) < 0) {
514 sprintf(buf, "closing output file \"%s\"", fn);
515 com_err(program_name, errno, buf);
522 void yesCallback(w, ret, dummy)
527 int *ip = (int *)ret;
531 void noCallback(w, ret, dummy)
536 int *ip = (int *)ret;
542 static XtCallbackRec yescb[] = { { yesCallback, (XtPointer) &value },
544 static XtCallbackRec nocb[] = { { noCallback, (XtPointer) &value },
547 Boolean AskQuestion(text, helpname)
548 char *text, *helpname;
553 static XmString label, yes = NULL, no;
555 XtAppContext _XtDefaultAppContext();
561 printf("%s (Y/N) ", text);
563 if (mgets(buf, sizeof(buf)))
565 if (buf[0] == 'T' || buf[0] == 't' ||
566 buf[0] == 'Y' || buf[0] == 'y')
568 else if (buf[0] == 'F' || buf[0] == 'f' ||
569 buf[0] == 'N' || buf[0] == 'n')
571 printf("Please answer Yes or No\r\n");
576 yes = XmStringCreate("Yes", XmSTRING_DEFAULT_CHARSET);
577 no = XmStringCreate("No", XmSTRING_DEFAULT_CHARSET);
581 XtDestroyWidget(child);
584 label = XmStringCreateLtoR( text, XmSTRING_DEFAULT_CHARSET);
587 XtSetArg(wargs[n], XmNmessageString, label); n++;
588 XtSetArg(wargs[n], XmNokLabelString, yes); n++;
589 XtSetArg(wargs[n], XmNcancelLabelString, no); n++;
590 XtSetArg(wargs[n], XmNokCallback, yescb); n++;
591 XtSetArg(wargs[n], XmNcancelCallback, nocb); n++;
593 child = (Widget) XmCreateQuestionDialog(logwidget, "question", wargs, n);
595 XtAddCallback (child, XmNhelpCallback, extra_help_callback, helpname);
597 XtUnmanageChild(XmMessageBoxGetChild (child, XmDIALOG_HELP_BUTTON));
599 XtManageChild(child);
602 XtAppNextEvent(_XtDefaultAppContext(), &event);
603 XtDispatchEvent(&event);
613 /******* temporary ********/
617 PopupErrorMessage(msg, "no_more_help");