home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char sccsid[] = "@(#)suntools.c 1.2 85/03/13 SMI";
- #endif
-
- /*
- * Sun Microsystems, Inc.
- */
-
- /*
- * Root window: Provides the background window for a screen.
- * Put up environment manager menu.
- */
-
- /*
-
- Modified by Don Libes, National Bureau of Standards, 9/25/85
-
- Added the following:
-
- Menu selections via keyboard
- Su'd selections via shift key
- User-specifiable primary menu name
- User-specifiable root cursor
- Various keywords: EXIT_NOCONFIRM, VERSION, HELP, KEYS
-
- */
-
- #include <suntool/tool_hs.h>
- #include <sys/ioctl.h>
- #include <sys/dir.h>
- #include <sys/file.h>
- #include <sys/wait.h>
- #include <sys/resource.h>
- #include <sys/stat.h>
- #include <errno.h>
- #include <stdio.h>
- #include <pwd.h>
- #include <suntool/menu.h>
- #include <suntool/wmgr.h>
- #include <sundev/kbd.h> /* SHIFTMASK - DEL */
- #include <ctype.h>
- #include <suntool/icon_load.h> /* icon_load_mpr for user cursor - DEL */
-
- extern int errno;
-
- extern char *malloc (), *calloc (), *getenv (), *strcpy (), *strncat (), *strncpy ();
-
- static int rootfd = 0,
- rootnumber;
- static int root_SIGCHLD,
- root_SIGWINCH;
- static struct screen screen;
-
- static struct pixwin *pixwin;
-
- #define ROOTMENUITEMS 20
- #define ROOTMENUFILE "/usr/lib/rootmenu"
- #define ROOTMENUNAME "Suntools"
-
- struct menuitem root_items[ROOTMENUITEMS];
-
- struct menuitemstrings {
- char *mis_prog; /* program to call */
- char *mis_args; /* args to program */
- } root_itemstrings[ROOTMENUITEMS];
-
- char *rootmenufile;
- char *rootmenuname; /* DEL */
-
- struct menu wmgr_rootmenubody,
- *wmgr_rootmenu = &wmgr_rootmenubody;
- struct stat_rec {
- char *name; /* Dynamically allocated menu file name */
- time_t mftime; /* Modified file time */
- };
- #define MAX_MENUS 20
- static struct stat_rec stat_array[MAX_MENUS];
- static int menu_next;
-
- #define ROOTCOLOR_PATTERN 0
- #define ROOTCOLOR_FOREGROUND 1
- #define ROOTCOLOR_BACKGROUND 2
- static rootcolor = ROOTCOLOR_PATTERN;
- /* Default cursor is a circle filled with stipple pattern. */
- /* When or-ed against another stipple pattern, it changes constantly. */
- /* Neat, huh? - DEL */
- static short cursor_image[CUR_MAXIMAGEWORDS] = {
- 0x0000,0x03E0,0x0E38,0x1224,0x288A,0x288A,0x6223,0x6223,
- 0x4889,0x4889,0x6223,0x2222,0x288A,0x188C,0x0E38,0x03E0 };
- mpr_static (cursor_pr, 8 * sizeof (cursor_image[0]),
- sizeof (cursor_image) / sizeof (cursor_image[0]), 1,
- cursor_image);
-
- #define IS_ASCII_EVENT(x) (x>=ASCII_FIRST && x<=ASCII_LAST)
- #define KEY_BUFFER_LENGTH 30
- char key_buffer[KEY_BUFFER_LENGTH] = "";
- /* keys coming directly to the root window */
- int key_buffer_length = 0;
- #define KEYITEMS 50
- struct menuitem key_items[KEYITEMS];
- struct menuitemstrings key_itemstrings[KEYITEMS];
- struct menu keymenubody = {
- 0, 0, 0,
- };
-
- struct pixfont *sysfont;
-
- #define SU_LABEL "su"
- int label_x, label_y; /* where the label is on the screen */
- struct rect su_rect;
- struct pr_subregion su_bound;
- struct pixrect *oldpr; /* save old screen image here while we */
- /* scribble the SU_LABEL on it */
-
- int wants_su = FALSE; /* true if user has requested setuid(0) */
- int oldruid, oldrgid; /* save the originals here */
- struct passwd *pwd;
-
- main (argc, argv)
- int argc;
- char **argv;
- {
- char name[WIN_NAMESIZE],
- setupfile[MAXNAMLEN];
- int _root_sigchldcatcher (), _root_sigwinchcatcher ();
- int donosetup = 0,
- printname = 0;
- unsigned char red[256],
- green[256],
- blue[256];
- struct pixrect *fb_pixrect;
- int fullplanes = 255;
-
- /*
- * Parse cmd line.
- */
- setupfile[0] = NULL;
- win_initscreenfromargv (&screen, argv);
- if (argv) {
- char **args;
-
- for (args = ++argv; *args; args++) {
- if ((strcmp (*args, "-s") == 0) && *(args + 1)) {
- (void) strcpy (setupfile, *(args + 1));
- args++;
- }
- else if (strcmp (*args, "-F") == 0)
- rootcolor = ROOTCOLOR_FOREGROUND;
- else if (strcmp (*args, "-B") == 0)
- rootcolor = ROOTCOLOR_BACKGROUND;
- else if (strcmp (*args, "-P") == 0)
- rootcolor = ROOTCOLOR_PATTERN;
- else if (strcmp (*args, "-n") == 0)
- donosetup = 1;
- else if (strcmp (*args, "-p") == 0)
- printname = 1;
- else if (strcmp (*args, "-S") == 0)
- wants_su = 1;
- else if (argc == 2 && *args[0] != '-')/*
- * If only arg and not a flag then treat as
- * setupfile (backward compatibility with 1.0).
- */
- (void) strcpy (setupfile, *args);
- }
- }
-
- oldrgid = getgid ();
- oldruid = getuid ();
-
- if (NULL == (pwd = getpwnam("root"))) {
- fprintf(stderr,"couldn't find root in passwd file?\n");
- exit(1);
- }
- if (*pwd->pw_passwd != '\0') {
- if (wants_su) {
- if (geteuid() != 0) {
- fprintf(stderr,"suntools must be setuid(0)\n");
- exit(1);
- }
- if (strcmp(pwd->pw_passwd,
- crypt(getpass("Password: "),
- pwd->pw_passwd))) {
- fprintf(stderr,"Sorry\n");
- exit(1);
- }
- } else disable_su();
- }
- wants_su = FALSE;
-
- /*
- * Initialize root menu from menu file.
- */
- if ((rootmenufile = getenv ("ROOTMENU")) == NULL)
- rootmenufile = ROOTMENUFILE;
- /* added changeable root menu name - DEL */
- if ((rootmenuname = getenv ("ROOTMENUNAME")) == NULL)
- rootmenuname = ROOTMENUNAME;
- if (wmgr_getrootmenu (rootmenuname, wmgr_rootmenu, rootmenufile,
- root_items, root_itemstrings, ROOTMENUITEMS) <= 0) {
- fprintf (stderr, "suntools: invalid root menu\n");
- exit (1);
- }
- /*
- * Set up signal catchers.
- */
- (void) signal (SIGCHLD, _root_sigchldcatcher);
- (void) signal (SIGWINCH, _root_sigwinchcatcher);
- /*
- * Find out what colormap is so can restore later.
- * Do now before call win_screennew which changes colormap.
- */
- if (screen.scr_fbname[0] == NULL)
- strcpy (screen.scr_fbname, "/dev/fb");
- if ((fb_pixrect = pr_open (screen.scr_fbname)) == (struct pixrect *) 0) {
- fprintf (stderr, "suntools: invalid frame buffer %s\n",
- screen.scr_fbname);
- exit (1);
- }
- pr_getcolormap (fb_pixrect, 0, 256, red, green, blue);
- /*
- * Create root window
- */
- if ((rootfd = win_screennew (&screen)) == -1) {
- perror ("suntools");
- exit (1);
- }
-
- init_cursor();
-
- if (rootcolor != ROOTCOLOR_PATTERN) {
- struct cursor cursor;
-
- cursor.cur_shape = &cursor_pr;
- win_getcursor (rootfd, &cursor);
- cursor.cur_function = PIX_SRC ^ PIX_DST;
-
- win_setcursor (rootfd, &cursor);
- }
- win_screenget (rootfd, &screen);
- /*
- * Open pixwin.
- */
- if ((pixwin = pw_open (rootfd)) == 0) {
- fprintf (stderr, "%s not available for window system usage\n",
- screen.scr_fbname);
- perror ("suntools");
- exit (1);
- }
- /*
- * Set up root's name in environment
- */
- win_fdtoname (rootfd, name);
- rootnumber = win_nametonumber (name);
- we_setparentwindow (name);
- if (printname)
- fprintf (stderr, "suntools window name is %s\n", name);
- /*
- * Set up tool slot allocator
- */
- wmgr_setrectalloc (rootfd, 200, 40,
- 0, pixwin -> pw_pixrect -> pr_height - TOOL_ICONHEIGHT);
- /*
- * Setup tty parameters for all terminal emulators that will start.
- */
- {
- int tty_fd;
- tty_fd = open ("/dev/tty", O_RDWR, 0);
- if (tty_fd < 0)
- ttysw_saveparms (2);/* Try stderr */
- else {
- ttysw_saveparms (tty_fd);
- (void) close (tty_fd);
- }
- }
-
- /*
- * setup su hack - DEL
- */
-
- /* find bounding box */
- su_bound.pr = pixwin -> pw_pixrect;
- su_bound.pos.x = 0;
- su_bound.pos.y = 0;
-
- sysfont = pw_pfsysopen ();
- pf_textbound (&su_bound, strlen (SU_LABEL), sysfont, SU_LABEL);
- su_rect.r_width = su_bound.size.x;
- su_rect.r_height = su_bound.size.y;
-
- /* create pixrect to save screen while scribbling on it */
- oldpr = mem_create (su_bound.size.x, su_bound.size.y, 1);
-
- /*
- * Draw background.
- */
- _root_sigwinchhandler ();
-
- /*
- * Do initial window setup.
- */
- if (!donosetup)
- _root_initialsetup (setupfile);
-
- /*
- * Do window management loop.
- */
- _root_winmgr ();
- /*
- * Destroy screen sends SIGTERMs to all existing windows and
- * wouldn't let any windows install themselves in the window tree.
- * Calling process of win_screedestroy is spared SIGTERM.
- */
- win_screendestroy (rootfd);
- /*
- * Lock screen before clear so don't clobber frame buffer while
- * cursor moving.
- */
- pw_lock (pixwin, &screen.scr_rect);
- /*
- * Enable writing to entire depth of frame buffer.
- */
- pr_putattributes (fb_pixrect, &fullplanes);
- /*
- * Clear entire frame buffer.
- */
- pr_rop (fb_pixrect, screen.scr_rect.r_left, screen.scr_rect.r_top,
- screen.scr_rect.r_width, screen.scr_rect.r_height, PIX_CLR, 0, 0, 0);
- /*
- * Reset previous colormap.
- */
- pr_putcolormap (fb_pixrect, 0, 256, red, green, blue);
- /*
- * Unlock screen.
- */
- pw_unlock (pixwin);
- exit (0);
- }
-
- _root_winmgr () {
- struct inputmask im;
- struct inputevent event;
- struct menuitem *mi;
- extern struct menuitem *menu_display ();
- int keyexit = 0,
- exit;
-
- /*
- * Set up input mask so can do menu stuff
- */
- input_imnull (&im);
- im.im_flags |= IM_NEGEVENT;
- im.im_flags |= IM_ASCII;
- win_setinputcodebit (&im, SELECT_BUT);
- win_setinputcodebit (&im, MENU_BUT);
- /* by enabling LOC_MOVE, we can discard the input buffer when the */
- /* mouse moves. */
- win_setinputcodebit (&im, LOC_MOVE);
- win_setinputmask (rootfd, &im, (struct inputmask *) 0, WIN_NULLLINK);
- /*
- * Read and invoke menu items
- */
- for (;;) {
- int ibits,
- nfds;
-
- /*
- * Use select (to see if have input) so will return on
- * SIGWINCH or SIGCHLD.
- */
- ibits = 1 << rootfd;
- do {
- if (root_SIGCHLD)
- _root_sigchldhandler ();
- if (root_SIGWINCH)
- _root_sigwinchhandler ();
- } while (root_SIGCHLD || root_SIGWINCH);
- nfds = select (8 * sizeof (ibits), &ibits, (int *) 0, (int *) 0,
- (struct timeval *) 0);
- if (nfds == -1) {
- if (errno == EINTR)/*
- * Go around again so that signals can be
- * handled. ibits may be non-zero but should
- * be ignored in this case and they will be
- * selected again.
- */
- continue;
- else {
- perror ("suntools");
- break;
- }
- }
- if (ibits & (1 << rootfd)) {
- /*
- * Read will not block.
- */
- if (input_readevent (rootfd, &event) < 0) {
- if (errno != EWOULDBLOCK) {
- perror ("suntools");
- break;
- }
- }
- }
- else
- continue;
-
- if (win_inputnegevent (&event))
- continue;
-
- if (IS_ASCII_EVENT (event.ie_code)) {
- int i;
-
- /* add to key input buffer */
- if (isupper (event.ie_code)) {
- event.ie_code = tolower (event.ie_code);
- wants_su = TRUE;
- }
- key_buffer[key_buffer_length] = event.ie_code;
- key_buffer_length += (key_buffer_length > KEY_BUFFER_LENGTH ? 0 : 1);
- key_buffer[key_buffer_length] = '\0';
- for (i = 0; i < keymenubody.m_itemcount; i++) {
- if (strcmp (keymenubody.m_items[i].mi_imagedata,
- key_buffer) == 0)
- break;
- }
- if (i >= keymenubody.m_itemcount)
- continue;/* not found */
-
- exit = wmgr_handlerootmenuitem ((struct menu *) NULL /* not used! */ ,
- &keymenubody.m_items[i], rootfd) == -1;
- if (exit)
- break;/* exit suntools */
- /* zap buffer now that we have used it */
- /* for now this occurs simply by falling through */
- }
- key_buffer_length = 0;
- key_buffer[0] = '\0';
- wants_su = FALSE;
-
- if (event.ie_code != MENU_BUT)
- continue;
-
- if (wants_su = (event.ie_shiftmask & SHIFTMASK)) {
- struct pr_prpos textpos;
-
- /* move to the left by its width, so its right flush
- */
- /* against the menu */
- su_rect.r_left = event.ie_locx - su_bound.size.x;
- /* origin for text is from the bottom, so subtract its
- /* its height */
- su_rect.r_top = event.ie_locy - sysfont -> pf_defaultsize.y;
- /* ignore going off the screen, since clipping is
- enabled */
-
- pw_lock (pixwin, &su_rect);
- /* save whats lying on the screen */
- pr_rop (oldpr, 0, 0, su_rect.r_width, su_rect.r_height,
- PIX_SRC, pixwin -> pw_pixrect,
- su_rect.r_left, su_rect.r_top);
- textpos.pr = pixwin -> pw_pixrect;
- textpos.pos.x = su_rect.r_left;
- textpos.pos.y = su_rect.r_top
- - /* distance to baseline */ sysfont -> pf_char['a'].pc_home.y;
- /* textpos is a structure passed by value!?! - DEL */
- pf_text (textpos, PIX_SRC, sysfont, SU_LABEL);
- pw_unlock (pixwin);
- }
-
- /*
- * Do menus
- */
- if (wmgr_getrootmenu (rootmenuname, wmgr_rootmenu, rootmenufile,
- root_items, root_itemstrings, ROOTMENUITEMS) <= 0) {
- fprintf (stderr, "suntools: invalid root menu\n");
- continue;
- }
- for (;;) {
- struct inputevent tevent;
-
- exit = 0;
- tevent = event;
- mi = menu_display (&wmgr_rootmenu, &event, rootfd);
- if (mi)
- exit = wmgr_handlerootmenuitem (wmgr_rootmenu, mi, rootfd) == -1;
- if (event.ie_code == MS_LEFT && !exit) {
- event = tevent;
- /*
- win_setmouseposition(rootfd, event.ie_locx,
- event.ie_locy); */
- }
- else {
- break;
- }
- }
- if (exit)
- break; /* exit suntools */
- if (wants_su) {
- /* restore what was lying on screen */
- pw_lock (pixwin, &su_rect);
- pr_rop (pixwin -> pw_pixrect,
- su_rect.r_left, su_rect.r_top,
- su_rect.r_width, su_rect.r_height,
- PIX_SRC, oldpr, 0, 0);
- pw_unlock (pixwin);
- wants_su = FALSE;
- }
- }
- }
-
- _root_sigchldhandler () {
- union wait status;
-
- root_SIGCHLD = 0;
- while (wait3 (&status, WNOHANG, (struct rusage *) 0) > 0) {
- }
- }
-
- _root_sigwinchhandler()
- {
- root_SIGWINCH = 0;
- pw_damaged (pixwin);
- switch (rootcolor) {
- case ROOTCOLOR_PATTERN:
- pw_replrop(pixwin,
- screen.scr_rect.r_left, screen.scr_rect.r_top,
- screen.scr_rect.r_width, screen.scr_rect.r_height,
- PIX_SRC, tool_bkgrd, 0, 0);
- break;
- default:
- pw_writebackground(pixwin,
- screen.scr_rect.r_left, screen.scr_rect.r_top,
- screen.scr_rect.r_width, screen.scr_rect.r_height,
- (rootcolor == ROOTCOLOR_BACKGROUND)?PIX_CLR:PIX_SET);
- }
-
- pw_donedamaged (pixwin);
- return;
- }
-
- static
- _root_sigchldcatcher () {
- root_SIGCHLD = 1;
- }
-
- static
- _root_sigwinchcatcher () {
- root_SIGWINCH = 1;
- }
-
- char *
- _get_home_dir () {
- extern char *getlogin ();
- extern struct passwd *getpwnam (), *getpwuid ();
- struct passwd *passwdent;
- char *home_dir = getenv ("HOME"), *loginname;
-
- if (home_dir != NULL)
- return (home_dir);
- loginname = getlogin ();
- if (loginname == NULL) {
- passwdent = getpwuid (getuid ());
- }
- else {
- passwdent = getpwnam (loginname);
- }
- if (passwdent == NULL) {
- fprintf(stderr,
- "suntools: couldn't find user in password file.\n");
- return (NULL);
- }
- if (passwdent -> pw_dir == NULL) {
- fprintf (stderr,
- "suntools: no home directory in password file.\n");
- return (NULL);
- }
- return (passwdent -> pw_dir);
- }
-
- #define ROOT_ARGBUFSIZE 1000
- #define ROOT_SETUPFILE "/.suntools"
- #define ROOT_MAXTOOLDELAY 10
-
- _root_initialsetup (requestedfilename)
- char *requestedfilename;
- {
- register i;
- FILE * file;
- char filename[MAXNAMLEN],
- programname[MAXNAMLEN],
- otherargs[ROOT_ARGBUFSIZE];
- struct rect rectnormal,
- recticonic;
- int iconic,
- topchild,
- bottomchild,
- seconds,
- j;
- char line[200];
-
- if (requestedfilename[0] == NULL) {
- char *home_dir = _get_home_dir ();
- if (home_dir == NULL)
- return;
- (void) strcpy (filename, home_dir);
- (void) strncat (filename, ROOT_SETUPFILE, sizeof (filename) - 1 -
- strlen (filename) - strlen (ROOT_SETUPFILE));
- }
- else
- (void) strncpy (filename, requestedfilename, sizeof (filename) - 1);
- if ((file = fopen (filename, "r")) == 0) {
- if (requestedfilename[0] == NULL)
- /*
- * No message if was trying to open default.
- */
- return;
- fprintf (stderr, "suntools: couldn't open %s\n", filename);
- return;
- }
- while (fgets (line, sizeof (line), file)) {
- if (line[0] == '#')
- continue;
- otherargs[0] = '\0';
- programname[0] = '\0';
- i = sscanf (line, "%s%hd%hd%hd%hd%hd%hd%hd%hd%hD%[^\n]\n",
- programname,
- &rectnormal.r_left, &rectnormal.r_top,
- &rectnormal.r_width, &rectnormal.r_height,
- &recticonic.r_left, &recticonic.r_top,
- &recticonic.r_width, &recticonic.r_height,
- &iconic, otherargs);
- if (i == EOF)
- break;
- if (i < 10 || i > 11) {
- /*
- * Just get progname and args.
- */
- otherargs[0] = '\0';
- programname[0] = '\0';
- j = sscanf (line, "%s%[^\n]\n", programname, otherargs);
- if (j > 0) {
- iconic = 0;
- rect_construct (&recticonic, WMGR_SETPOS, WMGR_SETPOS,
- WMGR_SETPOS, WMGR_SETPOS);
- rect_construct (&rectnormal, WMGR_SETPOS, WMGR_SETPOS,
- WMGR_SETPOS, WMGR_SETPOS);
- }
- else {
- fprintf (stderr,
- "suntools: in file=%s fscanf gave %D, correct format is:\n",
- filename, i);
- fprintf (stderr,
- "program open-left open-top open-width open-height close-left close-top close-width close-height iconicflag [args] <newline>\n OR\nprogram [args] <newline>\n");
- continue;
- }
- }
- /*
- * Handle WMGR_SETPOS requests.
- */
- wmgr_figuretoolrect (rootfd, &rectnormal);
- wmgr_figureiconrect (rootfd, &recticonic);
- /*
- * Remember who top and bottom children windows are for use when
- * trying to determine when tool is installed.
- */
- topchild = win_getlink (rootfd, WL_TOPCHILD);
- bottomchild = win_getlink (rootfd, WL_BOTTOMCHILD);
- /*
- * Fork tool.
- */
- /*
- (void) wmgr_forktool (programname, otherargs,
- &rectnormal, &recticonic, iconic);
- */
-
- del_forktool (programname, otherargs, &rectnormal, &recticonic, iconic);
- /*
- * Give tool chance to intall self in tree before starting next.
- */
- for (seconds = 0; seconds < ROOT_MAXTOOLDELAY; seconds++) {
- sleep (1);
- if (topchild != win_getlink (rootfd, WL_TOPCHILD) ||
- bottomchild != win_getlink (rootfd, WL_BOTTOMCHILD))
- break;
- }
- }
- (void) fclose (file);
- }
-
- int
- wmgr_rootmenuschanged (menu)
- struct menu *menu;
- {
- struct stat statb;
- int sa_count;
-
- /* Whenever existing menu going up, stat menu files */
- for (sa_count = 0; sa_count < menu_next; sa_count++) {
- if (stat (stat_array[sa_count].name, &statb) < 0) {
- if (errno == ENOENT)
- return (1);
- fprintf (stderr, "suntools: ");
- perror (stat_array[sa_count].name);
- return (-1);
- }
- if (statb.st_mtime > stat_array[sa_count].mftime)
- return (1);
- }
- return (0);
- }
-
- wmgr_freerootmenus (menu)
- struct menu *menu;
- {
- int sa_count = 0;
- struct menu *next = menu -> m_next,
- *nnext;
-
- while (next) {
- nnext = next -> m_next;
- if (next -> m_items) {
- free (next -> m_items -> mi_data);
- /* free string storage */
- free (next -> m_items);/* item storage */
- }
- free (next); /* menu storage */
- next = nnext;
- }
- while (sa_count < menu_next) {
- free (stat_array[sa_count].name);/* file name */
- stat_array[sa_count].name = NULL;
- stat_array[sa_count].mftime = 0;
- sa_count++;
- }
- menu_next = 0;
- }
-
- wmgr_getrootmenu (mn, menu, mf, mi, mis, maxitems)
- char *mn,
- *mf;
- struct menu *menu;
- struct menuitem *mi;
- struct menuitemstrings *mis;
- int maxitems;
- {
- FILE * f;
- int lineno;
- char line[256];
- char tag[256], /* was 32 - DEL */
- prog[256],
- args[256];
- char *savestr ();
- struct stat statb;
- struct menu *menunext = wmgr_rootmenu;
- int nitems = 0;
- static time_t mftime = 0;
- static char *nqformat = "%[^ \t\n]%*[ \t]%[^ \t\n]%*[ \t]%[^\n]\n";
- static char *qformat = "\"%[^\"]\"%*[ \t]%[^ \t\n]%*[ \t]%[^\n]\n";
-
- if (menu == wmgr_rootmenu && menu_next != 0) {
- if (wmgr_rootmenuschanged (wmgr_rootmenu) != 0)
- wmgr_freerootmenus (wmgr_rootmenu);
- else
- return menu -> m_itemcount;
- }
- if (menu_next >= MAX_MENUS - 1) {
- fprintf (stderr,
- "suntools: max number of menus is %D\n", MAX_MENUS);
- return - 1;
- }
- if ((f = fopen (mf, "r")) == NULL) {
- fprintf (stderr, "suntools: can't open menu file %s\n", mf);
- return - 1;
- }
- if (stat (mf, &statb) < 0) {
- fprintf (stderr, "suntools: ");
- perror (mf);
- return - 1;
- }
- stat_array[menu_next].mftime = statb.st_mtime;
- stat_array[menu_next].name = savestr (mf);
- ++menu_next;
- menu -> m_imagetype = MENU_IMAGESTRING;
- menu -> m_imagedata = mn;
- menu -> m_items = mi;
- for (nitems = 0, lineno = 1; nitems < maxitems &&
- fgets (line, sizeof (line), f); lineno++) {
- if (line[0] == '#')
- continue;
- args[0] = '\0';
- if (sscanf (line, line[0] == '"' ? qformat : nqformat,
- tag, prog, args) < 2) {
- fprintf (stderr,
- "suntools: format error in %s: line %d\n",
- mf, lineno);
- mftime = 0;/* complain every time */
- continue;
- }
- if (strcmp (prog, "KEYS") == 0) {
- /* check for calling only from root menu...bah! */
- if (wmgr_getrootmenu ("keys" /* menu name */ ,
- &keymenubody, /* key file name */ args,
- &key_items[0], &key_itemstrings[0],
- KEYITEMS) <= 0) {
- fprintf (stderr, "suntools: bad key menu %s\n", args);
- continue;
- }
- /* do not link this menu in with others!!! */
- /* it will not be displayed! */
- }
- else if (strcmp (prog, "MENU") == 0) {
- struct menu *m;
- char *mi,
- *ms;
- if (menu != wmgr_rootmenu) {
- fprintf (stderr,
- "suntools: MENU command illegal in secondary menu file %s: line %d\n",
- mf, lineno);
- continue;
- }
- if (wmgr_getrootmenu (
- savestr (tag),/* menu name */
- m = (struct menu *)
- calloc (1, sizeof (struct menu)), args,
- /* file name */ mi = calloc (ROOTMENUITEMS, sizeof (struct menuitem)) ,
- ms = calloc (ROOTMENUITEMS, sizeof (struct menuitemstrings)) ,
- ROOTMENUITEMS) <= 0) {
- fprintf (stderr,
- "suntools: invalid secondary menu %s\n", args);
- free (m);
- free (mi), free (ms);
- continue;
- }
- else {
- menunext -> m_next = m;
- menunext = m;
- }
- }
- else {
- if (mi -> mi_imagedata)
- free ((char *) mi -> mi_imagedata);
- mi -> mi_imagetype = MENU_IMAGESTRING;
- mi -> mi_imagedata = (caddr_t) savestr (tag);
- mi -> mi_data = (caddr_t) mis;
- if (mis -> mis_prog)
- free (mis -> mis_prog);
- if (mis -> mis_args)
- free (mis -> mis_args);
- mis -> mis_prog = savestr (prog);
- if (args[0] == '\0')
- mis -> mis_args = (char *) NULL;
- else
- mis -> mis_args = savestr (args);
- mi++;
- mis++;
- nitems++;
- }
- }
- fclose (f);
- return menu -> m_itemcount = nitems;
- }
-
- char *
- savestr (s)
- register char *s;
- {
- register char *p;
-
- if ((p = malloc (strlen (s) + 1)) == NULL) {
- if (rootfd)
- win_screendestroy (rootfd);
- fprintf (stderr, "suntools: out of memory for menu strings\n");
- exit (1);
- }
- strcpy (p, s);
- return (p);
- }
-
- wmgr_handlerootmenuitem (menu, mi, rootfd)
- struct menu *menu;
- struct menuitem *mi;
- int rootfd;
- {
- int returncode = 0;
- struct rect recticon,
- rectnormal;
- struct menuitemstrings *mis;
-
- /*
- * Get next default tool positions
- */
- rect_construct (&recticon, WMGR_SETPOS, WMGR_SETPOS,
- WMGR_SETPOS, WMGR_SETPOS);
- rectnormal = recticon;
- mis = (struct menuitemstrings *) mi -> mi_data;
- if (strcmp (mis -> mis_prog, "EXIT_NOCONFIRM") == 0) {
- returncode = -1;
- }
- else if (strcmp (mis -> mis_prog, "EXIT") == 0) {
- returncode = wmgr_confirm (rootfd,
- "Press the left mouse button to confirm Exit. \
- To cancel, press the right mouse button now.");
- }
- else if (strcmp (mis -> mis_prog, "REFRESH") == 0) {
- wmgr_refreshwindow (rootfd);
- }
- else if (strcmp (mis -> mis_prog, "HELP") == 0) {
- wmgr_confirm (rootfd, "Right mouse down displays menus. \
- Right mouse up selects. \
- Left mouse down selects without losing menus. \
- Holding shift key down before right mouse enables superuser. \
- Press any key to remove this garbage.");
- }
- else if (strcmp (mis -> mis_prog, "VERSION") == 0) {
- wmgr_confirm(rootfd,"suntools 1.2.4 (9/26/85) by Don Libes \
- at NBS (nbs-amrf!libes). Based on suntools 1.2 (3/13/85) by unknown \
- at SMI. Press any key to remove this garbage.");
- }
- else {
- wmgr_figureiconrect (rootfd, &recticon);
- wmgr_figuretoolrect (rootfd, &rectnormal);
- del_forktool (mis -> mis_prog, mis -> mis_args,
- &rectnormal, &recticon, 0 /* not iconic */ );
- }
- return (returncode);
- }
-
- enable_su () {
- if (setuid (0)) perror ("setuid(0)");
- setgid (1);
- }
-
- disable_su () {
- setgid (oldrgid);
- if (setuid (oldruid)) perror ("setuid(oldruid)");
- }
-
- del_forktool (program, args, open_rect, closed_rect, iconic)
- char *program, *args;
- struct rect open_rect, closed_rect;
- int iconic;
- {
- if (0 == fork ()) { /* child */
- char buffer[5000];/* space for program name and args */
- /* if doesn't have rectnormal, add it */
- /* if doesn't have recticon, add it */
- /* if it doesn't have iconic, add it if iconic */
- if (wants_su && (geteuid() == 0))
- enable_su ();
- else
- disable_su ();
- if (args)
- sprintf (buffer, "%s %s", program, args);
- else
- strcpy (buffer, program);
-
- /*
- now exec the program. Only problem is we have the
- prog name and args in a character string. We have
- to tokenize them in order to call exec or exec sh
- and have that do it for us. But that will create
- two processes for every one.
- */
- /* execl ("/bin/sh", "sh", "-c", buffer, 0);*/
- del_exec(buffer);
- _exit (127);
- }
- }
-
- #define end_token if (in_token) { \
- /* terminate current token */ *cp = '\0'; \
- /* advance to next token */ args[++argi] = cp = ++s;\
- /* not sure if there is anything valid here, so */ in_token = FALSE; }\
- else s++;
-
- /* exec a program and args that are all stored as one string */
- del_exec(s)
- char *s;
- {
- char *args[50];
- char *cp;
- int argi = 0;
- int quoting = FALSE;
- int in_token = FALSE; /* TRUE if we are reading a token */
-
- args[0] = cp = s;
- while (*s) {
- if (quoting) {
- if (*s == '\\' && *(s+1) == '"') { /* quoted quote */
- s++; /* get past " */
- *cp++ = *s++;
- } else if (*s == '\"') { /* close quote */
- end_token
- quoting = FALSE;
- } else *cp++ = *s++; /* suck up anything */
- } else if (*s == '\"') { /* open quote */
- in_token = TRUE;
- quoting = TRUE;
- s++;
- } else if (isspace(*s)) {
- end_token
- } else {
- *cp++ = *s++;
- in_token = TRUE;
- }
- }
- end_token
- args[argi] = (char *) 0; /* terminate argv */
- execvp(args[0],args);
- }
-
- /* allow user to set cursor attributes - DEL */
- init_cursor()
- {
- struct cursor cursor;
- char *cursorfile, *x_hot, *y_hot, *cursor_rop; /* environment parms */
-
- cursor.cur_shape = &cursor_pr;
-
- /* default cursor is a weird looking dot */
- cursor.cur_xhot = 8;
- cursor.cur_yhot = 8;
- cursor.cur_function = PIX_SRC | PIX_DST;
- win_setcursor(rootfd,&cursor);
-
- /* win_getcursor(rootfd, &cursor); */
- if (cursorfile = getenv("ROOT_CURSOR")) {
- char errmsg[1000];
-
- if (cursor.cur_shape = icon_load_mpr(cursorfile,errmsg)) {
- if (x_hot = getenv("ROOT_CURSOR_HOTSPOT_X"))
- cursor.cur_xhot = atoi(x_hot);
- if (y_hot = getenv("ROOT_CURSOR_HOTSPOT_Y"))
- cursor.cur_yhot = atoi(y_hot);
- if (cursor_rop = getenv("ROOT_CURSOR_ROP"))
- cursor.cur_function = atoi(cursor_rop);
- win_setcursor(rootfd,&cursor);
- } else printf(errmsg);
- }
- }
-