mikew@wyse.wyse.com (Mike Wexler) (08/16/88)
Submitted-by: rusty@cartan.berkeley.edu (Rusty C. Wright) Posting-number: Volume 1, Issue 1 Archive-name: xtools/part01 [Xtools is a convenient way to start up your X applications when your system doesn't support starting up the X window system from the getty process. The applications that xtools starts up are specified in a .xtools file. You can have different .xtools files, one for each host. I had a couple of problems with it. First it didn't understand shell notations suchs as "abc def" as being one parameter. Second when running under awm, its confirmation box had to be positioned with the mouse and it appeared behind the main xtools window anyway.] #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh <file", e.g.. If this archive is complete, you # will see the following message at the end: # "End of shell archive." # Contents: top_setup.c home_setup.c quit_button.c help_button.c # confirm_setup.c main.c client_start.c globs.c parse.c yep_button.c # nope_button.c setenv.c home_globs.h globs.h confirm_globs.h # xtools.xbm Imakefile dot_xtools xtools.man setenv.3 # Wrapped by rusty@velveeta on Tue Jul 5 21:37:52 1988 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'top_setup.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'top_setup.c'\" else echo shar: Extracting \"'top_setup.c'\" \(1679 characters\) sed "s/^X//" >'top_setup.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <X11/Command.h> X# include <X11/Shell.h> X# include <X11/Form.h> X# include <stdio.h> X X# include "home_globs.h" X# include "globs.h" X X# include "xtools.xbm" X XString display_name; Xstatic Widget top_shell; X Xstatic XrmOptionDescRec options[] = { X { "-file", "file", XrmoptionSepArg, NULL }, X { "-debug", "debug", XrmoptionIsArg, "False" }, X}; X Xstatic XtResource resources[] = { X { "file", "file", XtRString, sizeof(char *), (Cardinal) &file, X XtRString, NULL }, X { "debug", "debug", XtRBoolean, sizeof(Boolean), (Cardinal) &debug, X XtRBoolean, 0 }, X}; X XWidget Xtop_setup(argc, argv) X int argc; X char **argv; X{ X Widget top_form; X Arg args[1]; X X top_shell = XtInitialize("top", "XTools", options, X XtNumber(options), &argc, argv ); X if (argc != 1) X usage(); X X XtGetApplicationResources(top_shell, (caddr_t) NULL, resources, X XtNumber(resources), NULL, 0); X X XtSetArg(args[0], XtNiconPixmap, X XCreateBitmapFromData(XtDisplay(top_shell), X XtScreen(top_shell)->root, X xtools_bits, xtools_width, X xtools_height)); X XtSetValues(top_shell, args, 1); X X XtSetArg(args[0], XtNallowShellResize, True); X XtSetValues(top_shell, args, 1); X X# ifdef use_popup X top_form = top_shell; X# else /* use_popup */ X top_form = XtCreateManagedWidget("top", formWidgetClass, top_shell, X NULL, 0); X X XtSetArg(args[0], XtNallowShellResize, True); X XtSetValues(top_form, args, 1); X# endif /* use_popup */ X X display_name = XDisplayString(XtDisplay(top_shell)); X X return(top_form); X} X Xvoid Xtop_start(home_form) X Widget home_form; X{ X XtManageChild(home_form); X XtRealizeWidget(top_shell); X} END_OF_FILE if test 1679 -ne `wc -c <'top_setup.c'`; then echo shar: \"'top_setup.c'\" unpacked with wrong size! fi # end of 'top_setup.c' fi if test -f 'home_setup.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'home_setup.c'\" else echo shar: Extracting \"'home_setup.c'\" \(1399 characters\) sed "s/^X//" >'home_setup.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <X11/Command.h> X# include <X11/Form.h> X# include <stdio.h> X X# include "home_globs.h" X Xstatic char label_text[] = "xtools"; X Xstatic Arg label_args[] = { X { XtNlabel, (XtArgVal) label_text }, X { XtNborderWidth, (XtArgVal) 0 }, X}; X Xstatic int label_args_n = XtNumber(label_args); X XWidget quit_button; X XWidget Xhome_setup(parent) X Widget parent; X{ X Widget home_form; X Widget label_widget; X Widget help_button; X Arg args[1]; X X home_form = XtCreateWidget("home", formWidgetClass, parent, X NULL, 0); X X label_widget = XtCreateManagedWidget("home", labelWidgetClass, X home_form, label_args, X label_args_n); X X quit_button = XtCreateManagedWidget("quit", commandWidgetClass, X home_form, quit_button_args, X quit_button_args_n); X XtSetArg(args[0], XtNfromVert, label_widget); X XtSetValues(quit_button, args, 1); X XtAddCallback(quit_button, XtNcallback, quit_func, X (caddr_t) home_form); X X help_button = XtCreateManagedWidget("help", commandWidgetClass, X home_form, help_button_args, X help_button_args_n); X XtSetArg(args[0], XtNfromHoriz, quit_button); X XtSetValues(help_button, args, 1); X XtSetArg(args[0], XtNfromVert, label_widget); X XtSetValues(help_button, args, 1); X XtAddCallback(help_button, XtNcallback, help_func, X (caddr_t) home_form); X X return(home_form); X} END_OF_FILE if test 1399 -ne `wc -c <'home_setup.c'`; then echo shar: \"'home_setup.c'\" unpacked with wrong size! fi # end of 'home_setup.c' fi if test -f 'quit_button.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'quit_button.c'\" else echo shar: Extracting \"'quit_button.c'\" \(476 characters\) sed "s/^X//" >'quit_button.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <stdio.h> X X# include "home_globs.h" X# include "confirm_globs.h" X Xstatic char quit_button_label[] = "quit"; X XArg quit_button_args[] = { X { XtNlabel, (XtArgVal) quit_button_label } X}; X Xint quit_button_args_n = XtNumber(quit_button_args); X Xvoid Xquit_func(w, client_data, call_data) X Widget w; X caddr_t client_data; X caddr_t call_data; X{ X XtSetSensitive(quit_button, False); X confirm((Widget) client_data); X} END_OF_FILE if test 476 -ne `wc -c <'quit_button.c'`; then echo shar: \"'quit_button.c'\" unpacked with wrong size! fi # end of 'quit_button.c' fi if test -f 'help_button.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'help_button.c'\" else echo shar: Extracting \"'help_button.c'\" \(491 characters\) sed "s/^X//" >'help_button.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <X11/Form.h> X# include <stdio.h> X X# include "home_globs.h" X Xstatic char help_button_label[] = "help"; X XArg help_button_args[] = { X { XtNlabel, (XtArgVal) help_button_label }, X { XtNsensitive, (XtArgVal) False }, X}; X Xint help_button_args_n = XtNumber(help_button_args); X Xvoid Xhelp_func(w, client_data, call_data) X Widget w; X caddr_t client_data; X caddr_t call_data; X{ X /* (void) printf("no help at the moment.\n"); */ X} END_OF_FILE if test 491 -ne `wc -c <'help_button.c'`; then echo shar: \"'help_button.c'\" unpacked with wrong size! fi # end of 'help_button.c' fi if test -f 'confirm_setup.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'confirm_setup.c'\" else echo shar: Extracting \"'confirm_setup.c'\" \(2616 characters\) sed "s/^X//" >'confirm_setup.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <X11/Command.h> X# include <X11/Shell.h> X# include <X11/Form.h> X# include <stdio.h> X X# include "home_globs.h" X# include "confirm_globs.h" X# include "globs.h" X XWidget confirm_form; X X# ifdef use_popup XWidget confirm_popup; X Xstatic Arg confirm_popup_args[] = { X { XtNx, 0 }, X { XtNy, 0 } X}; X Xstatic int confirm_popup_args_n = XtNumber(confirm_popup_args); X# endif /* use_popup */ X Xstatic char label_text[] = "REALLY QUIT?"; X Xstatic Arg label_args[] = { X { XtNlabel, (XtArgVal) label_text }, X { XtNborderWidth, (XtArgVal) 0 }, X}; X Xstatic int label_args_n = XtNumber(label_args); X XWidget Xconfirm_setup(parent, home_form) X Widget parent; X Widget home_form; X{ X Widget yep_button; X Widget nope_button; X Widget label_widget; X Arg args[1]; X X# ifdef use_popup X XtSetArg(confirm_popup_args[0], XtNx, X DisplayWidth(XtDisplay(parent), X XDefaultScreen(XtDisplay(parent)))/2); X XtSetArg(confirm_popup_args[1], XtNy, X DisplayHeight(XtDisplay(parent), X XDefaultScreen(XtDisplay(parent)))/2); X X confirm_popup = XtCreatePopupShell("confirm", X transientShellWidgetClass, parent, X confirm_popup_args, X confirm_popup_args_n); X X confirm_form = XtCreateManagedWidget("confirm", formWidgetClass, X confirm_popup, NULL, 0); X# else /* use_popup */ X confirm_form = XtCreateWidget("confirm", formWidgetClass, X parent, NULL, 0); X# endif /* use_popup */ X X/* XtSetArg(label_args[2], XtNfont, query_font); */ X label_widget = XtCreateManagedWidget("confirm", labelWidgetClass, X confirm_form, label_args, X label_args_n); X X yep_button = XtCreateManagedWidget("yep", commandWidgetClass, X confirm_form, yep_button_args, X yep_button_args_n); X XtSetArg(args[0], XtNfromVert, label_widget); X XtSetValues(yep_button, args, 1); X XtAddCallback(yep_button, XtNcallback, yep_func, (caddr_t) parent); X X nope_button = XtCreateManagedWidget("nope", commandWidgetClass, X confirm_form, nope_button_args, X nope_button_args_n); X XtSetArg(args[0], XtNfromVert, label_widget); X XtSetValues(nope_button, args, 1); X XtSetArg(args[0], XtNfromHoriz, yep_button); X XtSetValues(nope_button, args, 1); X XtAddCallback(nope_button, XtNcallback, nope_func, X (caddr_t) home_form); X X# ifdef use_popup X XtRealizeWidget(confirm_popup); X# endif /* use_popup */ X X return(confirm_form); X} X Xconfirm(home_form) X Widget home_form; X{ X# ifdef use_popup X XtPopup(confirm_popup, XtGrabExclusive); X# else /* use_popup */ X XtUnmanageChild(home_form); X XtManageChild(confirm_form); X# endif /* use_popup */ X} END_OF_FILE if test 2616 -ne `wc -c <'confirm_setup.c'`; then echo shar: \"'confirm_setup.c'\" unpacked with wrong size! fi # end of 'confirm_setup.c' fi if test -f 'main.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'main.c'\" else echo shar: Extracting \"'main.c'\" \(692 characters\) sed "s/^X//" >'main.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <stdio.h> X X# include "home_globs.h" X# include "globs.h" X Xmain(argc, argv) X int argc; X char **argv; X{ X extern void top_start(); X Widget top_form; X Widget home_form; X X /* X * top_setup calls xtinitialize which parses argv for us. X */ X top_form = top_setup(argc, argv); X X setenv("DISPLAY", display_name); X X /* X * client_start reads .xtools and starts the clients. X */ X if (client_start() == -1) X exit(1); X X if (! debug) { X home_form = home_setup(top_form); X top_start(home_form); X (void) confirm_setup(top_form, home_form); X X XtMainLoop(); X } X X exit(0); X} X Xusage() { X (void) fprintf(stderr, "usage: xtools [-debug] [-file name]\n"); X exit(1); X} END_OF_FILE if test 692 -ne `wc -c <'main.c'`; then echo shar: \"'main.c'\" unpacked with wrong size! fi # end of 'main.c' fi if test -f 'client_start.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'client_start.c'\" else echo shar: Extracting \"'client_start.c'\" \(5194 characters\) sed "s/^X//" >'client_start.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <sys/wait.h> X# include <sys/file.h> X# include <signal.h> X# include <fcntl.h> X# include <pwd.h> X# include <stdio.h> X X# include "globs.h" X Xstatic int pids[128]; Xstatic int npids; Xstatic int dohang; X X/* X * client_start reads the .xtools file and runs each line. X */ Xclient_start() { X extern char *index(); X extern void shutdown(); X extern void cleanup(); X extern char *getname(); X extern char *getline(); X FILE *fd; X char *cp; X X /* X * if getname can't file a .xtools file then just X * start an xterm console. X */ X if ((cp = getname()) == NULL) { X if (execute("xterm -C &") == -1) { X fprintf(stderr, "can't start console xterm\n"); X return(-1); X } X return(0); X } X X if ((fd = fopen(cp, "r")) == NULL) { X (void) fprintf(stderr, "open: "); X perror(cp); X return(-1); X } X X if (fcntl(fileno(fd), F_SETFD, 1) == -1) { X (void) fprintf(stderr, "fcntl: "); X perror(cp); X (void) fclose(fd); X return(-1); X } X X (void) signal(SIGINT, (int (*)()) shutdown); X (void) signal(SIGCHLD, (int (*)()) cleanup); X X while ((cp = getline(fd)) != NULL) { X if (execute(cp) == -1) X (void) fprintf(stderr, "can't execute \"%s\"\n", cp); X } X dohang = 0; X X fclose(fd); X X return(0); X} X X/* X * getname returns the pathname to the user's .xtools file. X */ Xstatic char * Xgetname() { X extern char *getenv(); X extern char *rindex(); X struct passwd *pw; X char *home, *cp; X char host[128]; X static char path[256]; X X if (file != NULL) X return(file); X X if ((home = getenv("HOME")) == NULL) { X if ((pw = getpwuid(getuid())) == NULL) { X (void) fprintf(stderr, "who are you?\n"); X return(NULL); X } X home = pw->pw_dir; X endpwent(); X } X X /* X * try finding a .xtools file of the form .xtools-hostname, where X * hostname can be the fully qualified host name or it can have X * the upper domains missing. for example, X * .xtools-velveeta.berkeley.edu X * .xtools-velveeta.berkely X * .xtools-velveeta X * will all work. X */ X if (gethostname(host, sizeof(host)) != -1) { X sprintf(path, "%s/.xtools-%s", home, host); X if (access(path, F_OK) == 0) X return(path); X X /* try trimming off domain */ X while ((cp = rindex(host, '.')) != NULL) { X *cp = NULL; X sprintf(path, "%s/.xtools-%s", home, host); X if (access(path, F_OK) == 0) X return(path); X } X } X X sprintf(path, "%s/.xtools", home); X X if (access(path, F_OK) == 0) X return(path); X X (void) strcpy(path, DEFAULT_STARTUP); X X if (access(path, F_OK) == 0) X return(path); X X return(NULL); X} X X/* X * execute runs the line and remembers the pid of the process. X */ Xstatic Xexecute(line) X char *line; X{ X extern char **getargs(); X extern void checkamp(); X char **args; X int pid; X int i; X X if ((args = getargs(line)) == NULL) X return(-1); X X checkamp(args); X X if (debug) { X (void) printf("execvp(\"%s\"", args[0]); X for (i = 1; args[i] != NULL; i++) X (void) printf(", \"%s\"", args[i]); X (void) printf(")\n"); X return(0); X } X X if ((pid = fork()) == 0) { X if (setpgrp(0, getpid()) == -1) X perror("setpgrp(0)"); X X execvp(args[0], &args[0]); X X (void) fprintf(stderr, "can't execvp(\"%s\"): ", args[0]); X perror("execvp"); X exit(1); X } X else if (pid > 0) { X for (i = 0; i < npids; i++) { X if (pids[i] == 0) X pids[i] = pid; X } X if (i == npids) X pids[npids++] = pid; X X /* sleep(1); */ /* helps reduce thrashing */ X X /* X * don't bother checking return status because X * some programs do their work and then exit. X */ X (void) setpgrp(pid, pid); X } X else /* pid == -1, fork failed */ X return(-1); X X cleanup(); X X return(0); X} X X/* X * checkamp checks for an ampersand as either X * the last argument (i.e., it has a space in X * front of it, or the last argument has an X * ampersand appended to it. X */ Xstatic void Xcheckamp(args) X char **args; X{ X int i, amploc; X char *cp; X X dohang = 1; X X for (i = 0; args[i] != NULL; i++) X continue; X X i--; /* back up to last non-NULL arg */ X X cp = args[i]; X if (strcmp(cp, "&") == 0) { X args[i] = NULL; X dohang = 0; X } X else if (cp[amploc = strlen(cp)-1] == '&') { X cp[amploc] = NULL; X dohang = 0; X } X} X X# define SIGS (sizeof(sigs) / sizeof(sigs[0])) Xint sigs[] = { SIGTERM /* , SIGHUP, SIGKILL */ }; X X/* X * shutdown is called when quitting. it kills all outstanding X * processes. X */ Xstatic void Xshutdown() { X int i, j; X X for (j = 0; j < SIGS; j++) { X for (i = 0; i < npids; i++) { X if (pids[i] == 0) X continue; X X /* X * don't try to kill children that have X * already exited. X */ X if (getpgrp(pids[i]) == -1) { X pids[i] = 0; X continue; X } X X if (killpg(pids[i], sigs[j]) == -1) { X if (debug) X (void) printf("can't kill pid %d\n", X pids[i]); X continue; X } X } X } X X dohang = 0; X cleanup(); X X exit(0); X} X X/* X * cleanup collectes dead children. X */ Xstatic void Xcleanup() { X union wait status; X int options; X int pid; X int i; X X options = (dohang == 1) ? 0 : WNOHANG; X X while ((pid = wait3(&status, options, (struct rusage *) NULL)) > 0) { X for (i = 0; i < npids; i++) { X if (pids[i] == pid) { X if (debug) X (void) printf("caught pid %d\n", X pids[i]); X pids[i] = 0; X } X } X X /* pull up the tail */ X while (pids[npids-1] == 0) { X npids--; X if (npids == 0) X return; X } X } X} END_OF_FILE if test 5194 -ne `wc -c <'client_start.c'`; then echo shar: \"'client_start.c'\" unpacked with wrong size! fi # end of 'client_start.c' fi if test -f 'globs.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'globs.c'\" else echo shar: Extracting \"'globs.c'\" \(84 characters\) sed "s/^X//" >'globs.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X XXFontStruct *query_font; XBoolean debug; XString file; END_OF_FILE if test 84 -ne `wc -c <'globs.c'`; then echo shar: \"'globs.c'\" unpacked with wrong size! fi # end of 'globs.c' fi if test -f 'parse.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'parse.c'\" else echo shar: Extracting \"'parse.c'\" \(1327 characters\) sed "s/^X//" >'parse.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <ctype.h> X# include <stdio.h> X X# include "globs.h" X X/* X * getline reads a line from the .xtools file and trims X * any leading whitespace. lines that begin with a # and X * empty lines are skipped. X */ Xchar * Xgetline(fd) X FILE *fd; X{ X extern char *index(); X static char buf[BUFSIZ]; X char *cp; X X for (cp = &buf[0]; cp < &buf[BUFSIZ]; cp++) X *cp = 0; X X for (;;) { X if (fgets(buf, sizeof(buf), fd) == NULL) X return(NULL); X X if ((cp = index(buf, '\n')) != NULL) X *cp = NULL; X X /* skip leading spaces */ X for (cp = &buf[0]; *cp != NULL; cp++) { X if (! isspace(*cp)) X break; X } X X if ((*cp != NULL) && (*cp != '#')) X break; X } X X return(cp); X} X X# define MAXARGS 128 X X/* X * getargs breaks up a space-delimited line and returns it X * as an array of char *. X */ Xchar ** Xgetargs(line) X char *line; X{ X static char *args[MAXARGS]; X char *cp; X int i; X X for (i = 0; i < MAXARGS; i++) X args[i] = NULL; X X cp = line; X X for (i = 0; *cp != NULL; i++) { X args[i] = cp; X X /* skip to end of word */ X while ((*cp != NULL) && (! isspace(*cp))) X cp++; X X if (*cp == NULL) X break; X X *cp++ = NULL; X X if (debug) X (void) printf("args[%d]=%s\n", i, args[i]); X X /* skip over spaces */ X while ((*cp != NULL) && (isspace(*cp))) X cp++; X } X X return(args); X} END_OF_FILE if test 1327 -ne `wc -c <'parse.c'`; then echo shar: \"'parse.c'\" unpacked with wrong size! fi # end of 'parse.c' fi if test -f 'yep_button.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'yep_button.c'\" else echo shar: Extracting \"'yep_button.c'\" \(468 characters\) sed "s/^X//" >'yep_button.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <X11/Form.h> X# include <stdio.h> X Xstatic char yep_button_label[] = "yep"; X XArg yep_button_args[] = { X { XtNfromVert, (XtArgVal) NULL }, X { XtNlabel, (XtArgVal) yep_button_label } X}; X Xint yep_button_args_n = XtNumber(yep_button_args); X Xvoid Xyep_func(w, client_data, call_data) X Widget w; X caddr_t client_data; X caddr_t call_data; X{ X XtDestroyWidget((Widget) client_data); X shutdown(); X exit(0); X} END_OF_FILE if test 468 -ne `wc -c <'yep_button.c'`; then echo shar: \"'yep_button.c'\" unpacked with wrong size! fi # end of 'yep_button.c' fi if test -f 'nope_button.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'nope_button.c'\" else echo shar: Extracting \"'nope_button.c'\" \(628 characters\) sed "s/^X//" >'nope_button.c' <<'END_OF_FILE' X# include <X11/Intrinsic.h> X# include <X11/StringDefs.h> X# include <X11/Form.h> X# include <stdio.h> X X# include "home_globs.h" X# include "confirm_globs.h" X Xstatic char nope_button_label[] = "nope"; X XArg nope_button_args[] = { X { XtNlabel, (XtArgVal) nope_button_label } X}; X Xint nope_button_args_n = XtNumber(nope_button_args); X Xvoid Xnope_func(w, client_data, call_data) X Widget w; X caddr_t client_data; X caddr_t call_data; X{ X# ifdef use_popup X XtPopdown(confirm_popup); X XtSetSensitive(quit_button, True); X# else /* use_popup */ X XtUnmanageChild(confirm_form); X XtManageChild((Widget) client_data); X# endif /* use_popup */ X} END_OF_FILE if test 628 -ne `wc -c <'nope_button.c'`; then echo shar: \"'nope_button.c'\" unpacked with wrong size! fi # end of 'nope_button.c' fi if test -f 'setenv.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'setenv.c'\" else echo shar: Extracting \"'setenv.c'\" \(4480 characters\) sed "s/^X//" >'setenv.c' <<'END_OF_FILE' X/* Written by Stephen J. Muir, Computing Dept., Lancaster University */ X X# include <strings.h> X X/* This is the number of extra array elements to allocate each time it becomes X * necessary. X */ X# define INC 10 X Xextern char **environ, *malloc (); Xextern int free (); X Xstatic char **original, **current, **limit; X X/* This routine should be called only once (when either "setenv" or "delenv" is X * called for the first time). It would only be called again if it fails due X * to lack of memory. It makes a copy of the original environment because the X * original environment array and its elements were not obtained from "malloc" X * and the "free" routine cannot, therefore, be called with any of its X * elements. X * X * return values: X * 0: success X * -1: out of memory - nothing has changed X */ Xstatic /* this is a private routine */ Xinitialise () X { register char **old, **new_ptr, *tmp, **new_env; X X /* count number of existing strings */ X for (old = environ; *old; ++old) X ; X X /* make space for extra strings */ X if ((new_ptr = X new_env = X (char **)malloc (sizeof (char **) * ((old - environ) + INC + 1)) X ) X == 0 X ) X return (-1); X X /* "limit" points to the last element of the array -- it is used to X * decide when to recreate it X */ X limit = new_env + (old - environ) + INC; X X /* copy across old strings */ X for (old = environ; *old; ++old) X { if ((tmp = malloc (strlen (*old) + 1)) == 0) X { /* out of memory -- undo everything */ X while (new_ptr != new_env) X free (*--new_ptr); X free ((char *)new_ptr); X return (-1); X } X strcpy (tmp, *old); X *new_ptr++ = tmp; X } X /* "current" points to the null pointer at the end of the array */ X *(current = new_ptr) = 0; X X /* this is really just a flag to say it's initialised */ X original = environ; X /* overwrite old environment with new */ X environ = new_env; X return (0); X } X X/* This is a special routine to compare a string "name" of the form "NAME" with X * a string "name_value" of the form "NAME=VALUE". It returns zero if the X * comparison is successful X */ Xstatic /* this is a private routine */ Xdiffer (name, name_value) X char *name, *name_value; X { while (*name && *name_value) X if (*name++ != *name_value++) X return (1); X return (*name_value != '='); X } X X/* This routine deletes an environment variable, e.g. delenv ("SHELL"); X * X * return values: X * 0: success X * 1: environment variable not found X * -1: out of memory - nothing has changed X */ Xdelenv (name) X char *name; X { register char **ptr; X X /* initialise if necessary */ X if (original == 0 && initialise ()) X return (-1); X X /* attempt to find it */ X for (ptr = environ; *ptr && differ (name, *ptr); ++ptr) X ; X if (*ptr == 0) X return (1); /* not found */ X X /* delete it */ X free (*ptr); X *ptr = *--current; X *current = 0; X return (0); X } X X/* This routine sets a new environment variable, replacing an existing one X * where appropriate, e.g. setenv ("SHELL", "/bin/csh"); X * X * return values: X * 0: success X * -1: out of memory - nothing has changed X */ Xsetenv (name, value) X char *name, *value; X { register char **old, **new_ptr, *cp, *tmp, **new_env; X X /* initialise if necessary */ X if (original == 0 && initialise ()) X return (-1); X X /* allocate space for the new string */ X if ((cp = tmp = malloc (strlen (name) + strlen (value) + 2)) == 0) X return (-1); X X /* find an existing one if we can - we do this now as we will lose X * the original "name" pointer in the while loop following X */ X for (old = environ; *old && differ (name, *old); ++old) X ; X X /* make the new entry */ X while (*name) X *cp++ = *name++; X *cp++ = '='; X while (*value) X *cp++ = *value++; X *cp = '\0'; X X /* case 1: overwrite previous value */ X if (*old) X { free (*old); X *old = tmp; X } X X /* case 2: no previous value and no space left - allocate more */ X else if (current == limit) X { if ((new_ptr = X new_env = X (char **)malloc (sizeof (char **) * X ((old - environ) + INC + 1) X ) X ) == 0 X ) X { free (tmp); X return (-1); X } X limit = new_env + (old - environ) + INC; X for (old = environ; *old; ) X *new_ptr++ = *old++; X *new_ptr++ = tmp; X *(current = new_ptr) = 0; X free ((char *)environ); X environ = new_env; X } X X /* case 3: no previous value and there is enough space */ X else X { *current++ = tmp; X *current = 0; X } X return (0); X } END_OF_FILE if test 4480 -ne `wc -c <'setenv.c'`; then echo shar: \"'setenv.c'\" unpacked with wrong size! fi # end of 'setenv.c' fi if test -f 'home_globs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'home_globs.h'\" else echo shar: Extracting \"'home_globs.h'\" \(211 characters\) sed "s/^X//" >'home_globs.h' <<'END_OF_FILE' Xextern void quit_func(); Xextern void help_func(); X Xextern int help_button_args_n; Xextern int quit_button_args_n; X Xextern Arg help_button_args[]; Xextern Arg quit_button_args[]; X Xextern Widget quit_button; END_OF_FILE if test 211 -ne `wc -c <'home_globs.h'`; then echo shar: \"'home_globs.h'\" unpacked with wrong size! fi # end of 'home_globs.h' fi if test -f 'globs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'globs.h'\" else echo shar: Extracting \"'globs.h'\" \(195 characters\) sed "s/^X//" >'globs.h' <<'END_OF_FILE' Xextern XFontStruct *query_font; Xextern Boolean debug; Xextern String file; Xextern String display_name; X Xextern Widget top_setup(); Xextern Widget home_setup(); Xextern Widget confirm_setup(); END_OF_FILE if test 195 -ne `wc -c <'globs.h'`; then echo shar: \"'globs.h'\" unpacked with wrong size! fi # end of 'globs.h' fi if test -f 'confirm_globs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'confirm_globs.h'\" else echo shar: Extracting \"'confirm_globs.h'\" \(274 characters\) sed "s/^X//" >'confirm_globs.h' <<'END_OF_FILE' Xextern void yep_func(); Xextern void nope_func(); X Xextern Arg yep_button_args[]; Xextern Arg nope_button_args[]; X Xextern int yep_button_args_n; Xextern int nope_button_args_n; X Xextern Widget confirm_form; X X# ifdef use_popup Xextern Widget confirm_popup; X# endif /* use_popup */ END_OF_FILE if test 274 -ne `wc -c <'confirm_globs.h'`; then echo shar: \"'confirm_globs.h'\" unpacked with wrong size! fi # end of 'confirm_globs.h' fi if test -f 'xtools.xbm' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xtools.xbm'\" else echo shar: Extracting \"'xtools.xbm'\" \(2462 characters\) sed "s/^X//" >'xtools.xbm' <<'END_OF_FILE' X#define xtools_width 58 X#define xtools_height 58 Xstatic char xtools_bits[] = { X 0x00,0x00,0x80,0x3f,0x00,0x00,0x00,0x00,0x00,0x00,0xf0,0xff,0x01,0x00,0x00, X 0x00,0x00,0x00,0xf8,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0xf8,0xff,0x07,0x00, X 0x00,0x00,0x00,0x00,0xfe,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0x0f, X 0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x80,0xff,0xff, X 0x1f,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x80,0xff, X 0xff,0x1f,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x80, X 0xff,0xff,0x1f,0x00,0x00,0x00,0x00,0x80,0xff,0xff,0x1f,0x00,0x00,0x00,0x00, X 0x80,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x0f,0x00,0x00,0x00, X 0x00,0x00,0xff,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0xfe,0xff,0x07,0x00,0x00, X 0x00,0x00,0x00,0xfe,0xff,0x03,0x00,0x00,0x00,0x00,0x00,0xfc,0xff,0x01,0x00, X 0x00,0x00,0x00,0x00,0xf8,0xff,0x0f,0x00,0x00,0x00,0x00,0x00,0xe0,0xff,0xff, X 0x01,0x00,0x00,0xc0,0x1f,0x80,0xff,0xff,0x07,0xf0,0x00,0xf0,0x7f,0x00,0xff, X 0xff,0x0f,0xf8,0x01,0xf8,0xff,0x81,0xff,0xff,0x1f,0xf8,0x03,0xfc,0xff,0xc1, X 0x3f,0xfc,0x39,0xfc,0x03,0xfe,0xff,0xe7,0x0f,0xf0,0x70,0xfc,0x03,0xfe,0xff, X 0xf7,0x03,0xc0,0x60,0xfc,0x03,0xfe,0xff,0xff,0xe3,0xc0,0x60,0xfc,0x03,0xff, X 0xff,0xff,0x31,0x80,0xcc,0xfc,0x03,0xff,0xff,0xff,0x11,0x00,0xde,0xff,0x01, X 0xff,0xff,0xff,0x11,0x00,0xbf,0xf8,0x01,0xff,0xff,0xff,0x10,0x1e,0x7f,0xf0, X 0x00,0xff,0xff,0xff,0x20,0x3f,0x3d,0x40,0x00,0xff,0xff,0xff,0x00,0x7f,0x11, X 0x80,0x00,0xff,0xff,0xff,0x00,0xbf,0x12,0x00,0x01,0xff,0xff,0xff,0x01,0x9d, X 0x0a,0x00,0x01,0xfe,0xff,0xff,0x01,0x81,0x0c,0x00,0x01,0xfe,0xff,0xff,0x01, X 0x81,0x0c,0x00,0x01,0xfe,0xff,0xff,0x03,0x82,0x0a,0x80,0x00,0xfc,0xff,0xfd, X 0x07,0x44,0x01,0x80,0x00,0xf8,0xff,0xfc,0x0f,0x78,0x01,0x80,0x00,0xe0,0x7f, X 0xfc,0x3f,0x00,0x01,0x80,0x00,0xc0,0x1f,0xfc,0xff,0x00,0x03,0x40,0x00,0x00, X 0x00,0xfc,0xff,0x03,0x00,0x60,0x00,0x00,0x00,0xf8,0x3f,0x00,0x00,0x20,0x00, X 0x00,0x00,0xf8,0x8f,0x03,0x00,0x30,0x00,0x00,0x00,0xf8,0xc7,0x00,0x00,0x18, X 0x00,0x00,0x00,0xf8,0xc3,0x03,0x00,0x06,0x00,0x00,0x00,0xf0,0x43,0x0e,0xc0, X 0x03,0x00,0x00,0x00,0xe0,0x41,0xfc,0x7f,0x02,0x00,0x00,0x00,0xe0,0x81,0xf0, X 0x7f,0x02,0x00,0x00,0x00,0x80,0x01,0xe0,0x7f,0x02,0x00,0x00,0x00,0x80,0x01, X 0xe0,0x3f,0x01,0x00,0x00,0x00,0x00,0x02,0xc0,0x9f,0x01,0x00,0x00,0x00,0x00, X 0x0e,0x80,0xcf,0x00,0x00,0x00,0x00,0x00,0xf8,0x10,0x60,0x00,0x00,0x00,0x00, X 0x00,0xc0,0x27,0x18,0x00,0x00,0x00,0x00,0x00,0x00,0xfc,0x07,0x00,0x00}; END_OF_FILE if test 2462 -ne `wc -c <'xtools.xbm'`; then echo shar: \"'xtools.xbm'\" unpacked with wrong size! fi # end of 'xtools.xbm' fi if test -f 'Imakefile' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'Imakefile'\" else echo shar: Extracting \"'Imakefile'\" \(558 characters\) sed "s/^X//" >'Imakefile' <<'END_OF_FILE' X INCLUDES = -I$(TOP) -I$(TOP)/X11 XLOCAL_LIBRARIES = $(XAWLIB) $(XTOOLLIB) $(XLIB) XDEFAULT_STARTUP = $(LIBDIR)/xtools_startup X STD_DEFINES = -DDEFAULT_STARTUP=\"$(DEFAULT_STARTUP)\" -Duse_popup X X SRCS = top_setup.c home_setup.c quit_button.c help_button.c \ X confirm_setup.c main.c client_start.c globs.c parse.c \ X yep_button.c nope_button.c setenv.c X X OBJS = top_setup.o home_setup.o quit_button.o help_button.o \ X confirm_setup.o main.o client_start.o globs.o parse.o \ X yep_button.o nope_button.o setenv.o X XComplexProgramTarget(xtools) END_OF_FILE if test 558 -ne `wc -c <'Imakefile'`; then echo shar: \"'Imakefile'\" unpacked with wrong size! fi # end of 'Imakefile' fi if test -f 'dot_xtools' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'dot_xtools'\" else echo shar: Extracting \"'dot_xtools'\" \(295 characters\) sed "s/^X//" >'dot_xtools' <<'END_OF_FILE' Xxrdb .xrdb Xxsetroot -grey Xxhost yuban ovaltine bosco Xxset m 8 8 r off c 100 Xtwm & Xxterm -i -name velveeta -T velveeta #0x0-85+100 & Xxterm -i -name cartan -T cartan #0x0-85+240 -e cartan -e & Xxterm -i -C -r -name console -T console #0x0-85+380 & Xxperfmon =175x290-115+0 & Xxclock & Xxbiff & END_OF_FILE if test 295 -ne `wc -c <'dot_xtools'`; then echo shar: \"'dot_xtools'\" unpacked with wrong size! fi # end of 'dot_xtools' fi if test -f 'xtools.man' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'xtools.man'\" else echo shar: Extracting \"'xtools.man'\" \(3941 characters\) sed "s/^X//" >'xtools.man' <<'END_OF_FILE' X.TH XTOOLS 1 X.SH NAME Xxtools \- easy way to start X programs X.SH SYNOPSIS Xxinit xtools [-display hostname:dpy] [normal Xaw options] X.SH DESCRIPTION X.I xtools Xis a convenient way to start up your X applications when your system Xdoesn't support starting up the X window system from the getty Xprocess. X.PP XThe applications that X.I xtools Xstarts up are specified in a .xtools file. You can have different X.I .xtools Xfiles, one for each host. X.I xtools Xfirst tries to open the file .xtools-fully.qualified.domain.name where X``fully.qualified.domain.name'' is the fully qualified domain name of Xyour workstation (as returned by the gethostname() system call). If Xthat file doesn't exist then, starting at the right, it trims off Xportions of the domain name and retries. Using the above example Xdomain name, the following files would be tried in order: X.sp X.nf X .xtools-fully.qualified.domain.name X .xtools-fully.qualified.domain X .xtools-fully.qualified X .xtools-fully X .xtools X.fi X.sp XIf none of the .xtools files with a machine or domain name exist then Xit uses just ``.xtools''. X.SH CONFIGURATION FILE FORMAT XThe format of the .xtools file is the same as if you were typing the Xcommands to the shell. (But note that csh-style tilde expansion is Xnot implemented.) In particular, it is important to note that the Xcommand lines in the .xtools file must have an ampersand (&) at the Xend if the command is expected to run in the background (for example, Xxterm). A bug in X.I xtools Xrequires you to put all of those commands that don't run in the Xbackground first. Here is a sample .xtools file X.sp X.nf Xxrdb .xrdb Xxsetroot -grey Xxhost yuban ovaltine bosco Xxset m 8 8 r off c 100 Xtwm & Xxterm -i #0x0-85+100 & Xxterm -i #0x0-85+240 -e cartan -e & Xxterm -i -C -r #0x0-85+380 & Xxperfmon =175x290-115+0 & Xxclock & Xxbiff & X.fi X.sp X.SH STARTING AND QUITING XSince X.I xtools Xis started by X.I xinit Xthe DISPLAY environment variable isn't set, so you must either set it Xprior to starting xinit, or you can use the -display option with X.I xtools Xand X.I xtools Xwill propogate it down to the programs that it starts. Here's an Xexample csh alias for starting the X Window System using X.I xtools Xon a SUN workstation: X.sp X.nf Xalias x 'xinit xtools -iconic -geo -1-100 -display ${hostname}":"0 ; \\ Xsetkeys reset ; \\ Xclear' X.fi X.sp Xwhere the hostname variable was set earlier with X.sp X.nf Xset hostname = ` hostname | sed -e 's/\..*//' ` X.fi X.PP XSince X.I xtools Xwas started by X.I xinit Xyou must quit X.I xtools Xin order to quit the X Window System. X.I xtools Xhas a small window with two buttons labeled ``quit'' and ``help''. XThe help button isn't implemented yet so it is dimmed. When you click Xon the quit button a confirmation box pops up; if you click on the X``yep'' button then X.I xtools Xwill send a kill signal to all of the programs that it started. X.SH OPTIONS X.I xtools Xtakes all of the standard toolkit options. In addition, you may Xspecifiy an alternate configuration file by using the -file option Xfollowing it with the name of the configuration file. X.SH "X DEFAULTS" XThe available names and classes for the widgets used are: X.RS X.nf X.ta 4i XNAME CLASS X Xtop Shell X Xtop.home Shell.Form Xtop.home.home Shell.Form.Label Xtop.home.quit Shell.Form.Command Xtop.home.help Shell.Form.Command X Xtop.confirm Shell.Shell Xtop.confirm.confirm Shell.Shell.Form Xtop.confirm.confirm.confirm Shell.Shell.Form.Label Xtop.confirm.confirm.yep Shell.Shell.Form.Command Xtop.confirm.confirm.nope Shell.Shell.Form.Command X.fi X.RE X.PP XThese can be used to set fonts, colors, etc. tailored to the user's Xneeds. As a color example: X.PP X.RS X.ta 4i X.nf Xxtools*quit.Background: mauve Xxtools*confirm.yep.Background: peach Xxtools*confirm.nope.Background: plum Xxtools*geometry: -1-100 Xxtools*icon: on Xxtools*home.font: vbee-36 Xxtools*confirm.font: vbee-36 X.fi X.RE X.SH AUTHOR X.ta 1.2i XRusty C. Wright X.br X rusty@cartan.berkeley.edu X.br X ucbvax!cartan!rusty END_OF_FILE if test 3941 -ne `wc -c <'xtools.man'`; then echo shar: \"'xtools.man'\" unpacked with wrong size! fi # end of 'xtools.man' fi if test -f 'setenv.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'setenv.3'\" else echo shar: Extracting \"'setenv.3'\" \(1041 characters\) sed "s/^X//" >'setenv.3' <<'END_OF_FILE' X.TH SETENV 3 "22 October 1985" X.SH NAME Xsetenv, delenv \- add/change/delete environment variables X.SH SYNOPSIS X.nf X.B setenv (name, value) X.B char *name, *value; X X.B delenv (name) X.B char *name; X.fi X.SH DESCRIPTION X.I Setenv Xallows a program to set environment variables. X.I Delenv Xallows a program to delete them. XThese routines follow on logically from X.IR getenv (3). X.SH EXAMPLES X.nf Xsetenv ("EDITOR", "/usr/ucb/ex"); Xdelenv ("EDITOR"); X.fi X.SH NOTES XThe third argument to routine X.B main Xstill points to the original environment after execution of these routines. XThe flag X.I \-lsjm Xneeds to be given to X.IR cc (1) Xor X.IR ld (1). X.SH "RETURN VALUES" X.I Setenv Xand X.I delenv Xboth return 0 on success and -1 if enough memory couldn't be allocated. X.I Delenv Xcan also return 1 meaning that the X.B name Xwasn't found in the current environment. XThe first call to X.I setenv Xor X.I delenv Xinitialises both routines. XAfter that, X.I delenv Xcannot return -1. X.SH "SEE ALSO" Xgetenv (3), execve (2) X.SH AUTHOR XStephen J. Muir, Lancaster University. END_OF_FILE if test 1041 -ne `wc -c <'setenv.3'`; then echo shar: \"'setenv.3'\" unpacked with wrong size! fi # end of 'setenv.3' fi echo shar: End of shell archive. exit 0 -- Mike Wexler(wyse!mikew) Phone: (408)433-1000 x1330