📄 lockscreen.c
字号:
/* (void)signal(SIGCHLD, (int (*)())(LINT_CAST(sigchild_handler))); */ vec.sv_handler = (void (*)())(LINT_CAST(sigchild_handler)); vec.sv_mask = vec.sv_onstack = 0; sigvec(SIGCHLD, &vec, 0); fg_pid = vfork(); if (fg_pid == -1) { /* Possible error? */ (void)fprintf(stderr, "foreground process vfork failed\n"); perror(progname); fg_pid = 0; exit_and_kill(1); } if (fg_pid == 0) { /* child */ (void)win_fdtoname(tool_local->tl_windowfd, WinName); (void)we_setgfxwindow(WinName); execvp(fg_prog, fg_argv); } if (!setpriority(PRIO_USER, fg_pid, 20)) perror(progname); } if (!bg_pid && *bg_prog) { bg_pid = vfork(); if (bg_pid == -1) { /* Possible error? */ (void)fprintf(stderr, "background process vfork failed\n"); perror(progname); bg_pid = 0; exit_and_kill(1); } if (bg_pid == 0) { /* child */ execvp(bg_prog, (char *)0); } } fork_var = 0; } else if (!fg_pid && *timer && ((*timer)->tv_sec == 0) && ((*timer)->tv_usec == 0) && (tool_local->tl_flags & TOOL_ICONIC)) { /* * Reset old image. */ (void)pw_writebackground(tool_local->tl_pixwin, imagerect.r_left, imagerect.r_top, imagerect.r_width, imagerect.r_height, PIX_SET); /* * Choose new position. */ imagerect.r_left = r(rectcreate.r_left, rectcreate.r_width-imagerect.r_width); imagerect.r_top = r(rectcreate.r_top, rectcreate.r_height-imagerect.r_height); /* * Draw new image. */ k = random()%(CMSIZE-2) + 1; if (colormonitor) (void)pw_stencil(tool_local->tl_pixwin, imagerect.r_left, imagerect.r_top, imagerect.r_width, imagerect.r_height, PIX_SRC|PIX_COLOR(k), lockscreen_mpr, 0, 0, (struct pixrect *)NULL, 0, 0); else (void)pw_write(tool_local->tl_pixwin, imagerect.r_left, imagerect.r_top, imagerect.r_width, imagerect.r_height, PIX_SRC ^ PIX_DST, lockscreen_mpr, 0, 0); } if (!(tool_local->tl_flags & TOOL_ICONIC) && --countdown == 0) abort_proc(); if (*ibits & (1 << tool_local->tl_windowfd)) { struct inputevent event; countdown = timeout; if (input_readevent(tool_local->tl_windowfd, &event) == -1) { perror(progname); return; }#ifndef SUN2.0 INPUT_FOCUS if (event_action(&event) > META_LAST && event_action(&event) < SHIFT_LEFT) { *ibits = *obits = *ebits = 0; tooltimer = sectimer; *timer = fg_pid ? 0 : &tooltimer; return; }#endif if (tool_local->tl_flags & TOOL_ICONIC) { char *getloginname(); if (fg_pid) { k = fg_pid, fg_pid = 0, fork_var = 1; /* Lock screen so sure that child doesn't have it locked */ (void)pw_lock(tool_local->tl_pixwin, &rectcreate); (void)kill(k, SIGKILL); (void)pw_unlock(tool_local->tl_pixwin); } /* * blow away if the no_lock option is * set or if the user has no password. */ if (no_lock || no_password()) { (void)tool_done(tool_local); return; } /* * Open tool from iconic state on any event. * Note: Do not use wmgr_open because not * really closed. */ wmgr_changestate(tool_local->tl_windowfd, tool_local->tl_windowfd, FALSE);#ifndef SUN2.0 INPUT_FOCUS /* Direct keyboard input to panel */ (void)win_set_kbd_focus(panel_toolsw->ts_windowfd, win_fdtonumber(panel_toolsw->ts_windowfd));#endif /* * Reset state for open. */ (void)panel_set_value(name_item, getloginname()); (void)panel_set_value(passwd_item,""); (void)panel_set(panel_toolsw->ts_data, PANEL_CARET_ITEM, passwd_item, 0); first_char = 0; /* event.ie_code; /* ?? Fix read ahead problem */ /* * Call toolhandlesigwinch explicitly because changing * state in previous call does not envoke SIGWINCH * because clipping stays the same. */ toolhandlesigwinch(tool_local); } } *ibits = *obits = *ebits = 0; tooltimer = sectimer; *timer = fg_pid ? 0 : &tooltimer;}statictoolhandlesigwinch(tool_local) struct tool *tool_local;{ struct rect rect; int iconic; int wmgr_iswindowopen(); tool_local->tl_flags &= ~TOOL_SIGWINCHPENDING; iconic = !wmgr_iswindowopen(tool_local->tl_windowfd); (void)win_getsize(tool_local->tl_windowfd, &rect); if (iconic && (~tool_local->tl_flags&TOOL_ICONIC)) { /* * Tool has just gone iconic, so, add y offset to sws * to move them out of the picture. */ (void)_tool_addyoffsettosws(tool_local, 2048); tool_local->tl_flags |= TOOL_ICONIC; tool_local->tl_rectcache = rect; } else if (!iconic && (tool_local->tl_flags&TOOL_ICONIC)) { static struct timeval panel_timer = { 0, 50000 }; /* * Tool has just gone from iconic to normal, so, subtract * y offset from sws to move them into the picture again. */ tool_local->tl_flags &= ~TOOL_ICONIC; (void)_tool_addyoffsettosws(tool_local, -2048); tool_local->tl_rectcache = rect; /* set the panel timer */ panel_toolsw->ts_io.tio_timer = &panel_timer; } /* /* * Refresh tool now */ (void)pw_damaged(tool_local->tl_pixwin); (void)pw_donedamaged(tool_local->tl_pixwin); if (tool_local->tl_flags & TOOL_ICONIC) (void)pw_writebackground(tool_local->tl_pixwin, rect.r_left, rect.r_top, rect.r_width, rect.r_height, PIX_SET); else (void)tool_displaytoolonly(tool_local); /* * Refresh subwindows now */ (void)_tool_subwindowshandlesigwinch(tool_local); return;}/* This is the notify procedure for the password item. It is called on *//* every input character. All characters are accepted. The showdtop () *//* routine is called upon a \r\n\t. */Panel_setting notify (passwd_item, event)Panel_item passwd_item;Event *event;{ switch (event_id(event)) { case '\011': /* tab */ case '\012': /* new line */ case '\015': /* return */ { showdtop_proc (); return (PANEL_NONE); } default: return (PANEL_INSERT); }}static intshowdtop_proc()/* showdtop_proc gets the current login name & password and checks them for validity. Note that this is the notify proc for the password item, and that the notify arguments are ignored.*/{ char *name, *passwd, *loginname, *crypted; struct passwd *passwdent; extern struct passwd *getpwnam(); char *getloginname(), *crypt(), passwd_buf[100]; /* get the login name & password */ name = (char *)panel_get_value(name_item); passwd = (char *)panel_get_value(passwd_item); first_char = first_char > ' ' && first_char < 128 ? first_char : 0; if (first_char) { *passwd_buf = (char)first_char; (void)strcpy(passwd_buf + 1, passwd); passwd = passwd_buf; first_char = 0; } if (*name) { paintmsg("Validating login...."); /* Find out who is logged in. */ if ((loginname = getloginname()) == 0) { paintmsg("You don't have a login name."); (void)panel_set_value(passwd_item,""); return 0; } /* See if should let root try to break into desktop. */ else if (strcmp("root", name) == 0 && strcmp(loginname, "root") != 0) { if (rootenable) loginname = "root"; else { paintmsg("Root access not enabled (-r switch)."); (void)panel_set_value(passwd_item,""); return 0; } } if (strcmp(loginname, name)) /* Only let person who is logged in (or root) login. */ paintmsg("Invalid login."); else if ((passwdent = getpwnam(loginname)) == 0) /* Get password entry with can compare typed in password. */ paintmsg("You don't have a password."); else { /* Encrypt passwd so can compare with passwd file entry. */ crypted = crypt(passwd, passwdent->pw_passwd); if (strcmp(crypted, passwdent->pw_passwd)) paintmsg("Invalid login."); else { (void)panel_set_value(passwd_item,""); (void)tool_done(tool); return 0; } } } else paintmsg("Invalid login."); (void)panel_set_value(passwd_item,""); return 0;}staticpaintmsg(str)char *str;{ (void)panel_set(msg_item, PANEL_LABEL_STRING, str, 0);}static voidabort_proc(){ /* * Note: Do not use wmgr_open because not really opened. */ wmgr_changestate(tool->tl_windowfd, tool->tl_windowfd, TRUE);#ifndef SUN2.0 INPUT_FOCUS /* Direct keyboard input to tool */ (void)win_set_kbd_focus(tool->tl_windowfd, win_fdtonumber(tool->tl_windowfd));#endif /* * Call toolhandlesigwinch explicitely because changing * state in previous call does not envoke SIGWINCH * because clipping stays the same. */ (void)panel_set_value(passwd_item,""); toolhandlesigwinch(tool);}/* -------------------- begin exiting --------------------------------------*//* This whole section rewritten by vmh, Jan 1990, bugid 1025886 (to * work for multiple heads, to actually log the user out for the -e * option. * * Features: * * Logs the user out (but leaves remote logins alive) * * Leaves background processes alive * * Works for multi-headed systems * * if you use textedit, a backup of your files will be stored * * Implementation Notes: * Cannot use win_screendestroy, because it itself * sends signals. Versions of kill are not selective enough. * Using the process tables directly would be more efficient, * but also a major project. */static voidexit_proc(){ /* variables for the confirmer */ Event alert_event; int result, real_result; /* variables for the killing */ int mypid, npids, nlockpids; int status, i; int pids[MAXPIDS], lockpids[MAXPIDS]; /*----------------------------------------------------------------*/ /* Put up confirmer to make sure the user wants to log out. */ result = alert_prompt( (Frame)0, &alert_event, ALERT_MESSAGE_STRINGS, "Really exit Sunview and logout current user ?", 0, ALERT_BUTTON_YES, "Confirm", ALERT_BUTTON_NO, "Cancel", 0); switch (result) { case ALERT_YES: real_result = 1; break; case ALERT_NO: real_result = 0; break; default: /* alert_failed */ real_result = 0; break; } if (real_result == 0) return; /*----------------------------------------------------------------*/ /* make sure you can't write to these devices anymore */ chmod("/dev/console", 0); close(stdout); close(stderr); close(stdin); mypid = getpid(); /* This is me */ /* Blank the cursor */ (void)blank_cursor(panel_toolsw->ts_windowfd); clear_my_colormap; /* * HANG UP all processes; this will detach background * processes so they won't be killed in the next steps. */ npids = get_other_procs(pids, MAXPIDS); for (i=npids; --i >= 0; ) if (pids[i] != mypid) { (void)kill(pids[i], SIGHUP); } usleep(1 << 20); /* sleep for 1 second */ /* Now, KILL any remaining processes; re-get to eliminate * new background processes without a parent. * This makes sure they are all dead * before we kill the lockscreens. */ npids = get_other_procs(pids, MAXPIDS); for (i=npids; --i >= 0;) if (pids[i] != mypid) { errno = 0; (void)kill(pids[i], SIGKILL); if (errno != ESRCH) { wait4(pids[i], &status, NULL, NULL); } } /* Now, KILL the lockscreens (except myself) */ nlockpids = get_lockscreen_procs(lockpids, MAXPIDS); for (i=nlockpids; --i >= 0;) if (lockpids[i] != mypid) { (void)kill(lockpids[i], SIGHUP); } usleep(1 << 20); /* sleep for 2 seconds */ exit(0); /* bye bye */}/*----------------------------------------------------------------*//* This is a crutch to clear the colormap. This only clears the map * of the screen we are running on - so exiting from a peripheral * display can still leave your login console screen hosed up, i.e. * left with foreground and background the same color. */ static void clear_my_colormap(){ register i; register Pixwin *pixwin = tool->tl_pixwin; struct screen screen; char name[WIN_NAMESIZE]; char color[256]; /* Lock screen before clear so we don''t clobber frame buffer * while cursor is moving. */ (void)pw_lock(pixwin, &screen.scr_rect); /* Clear available plane groups */ (void)win_screenget(tool->tl_windowfd, &screen); (void)bzero(color, 256); color[0] = 255; for (i = 0; i < PIX_MAX_PLANE_GROUPS; i++) { if (pixwin->pw_clipdata->pwcd_plane_groups_available[i]) { /* Write to all plane groups */ (void)pr_set_planes(pixwin->pw_pixrect, i, PIX_ALL_PLANES); /* Clear screen */ (void)pr_rop(pixwin->pw_pixrect, screen.scr_rect.r_left, screen.scr_rect.r_top, screen.scr_rect.r_width, screen.scr_rect.r_height, PIX_CLR, (Pixrect *)0, 0, 0); /* Reset "reasonable" colormap */ (void)pr_putcolormap(pixwin->pw_pixrect, 0, 256, (unsigned char *)color, (unsigned char *)color, (unsigned char *)color); } } (void)pw_unlock(pixwin);}/*----------------------------------------------------------------*//* findnextstart -- find the first place in the string that * starts with same char as substring. * return points to nullstring if none found. */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -