if ((n = strlcat(new_prompt, *user_runas, len)) >= len)
n = strlcpy(np,  *user_runas, np - endp); if (n >= np - endp)
static char *expand_prompt	__P((char *, char *, char *));static void  lecture		__P((void));static void  update_timestamp	__P((char *, char *));/* * This function only returns if the user can successfully * verify who he/she is.   */voidcheck_user(){    char *timestampdir = NULL;    char *timestampfile = NULL;    char *prompt;    int status;    if (user_uid == 0 || user_is_exempt())	return;    build_timestamp(&timestampdir, &timestampfile);    status = timestamp_status(timestampdir, timestampfile, user_name, TRUE);    if (status != TS_CURRENT) {	if (status == TS_MISSING || status == TS_ERROR)	    lecture();		/* first time through they get a lecture */	/* Expand any escapes in the prompt. */	prompt = expand_prompt(user_prompt ? user_prompt : def_str(I_PASSPROMPT),	    user_name, user_shost);	verify_user(auth_pw, prompt);    }    if (status != TS_ERROR)	update_timestamp(timestampdir, timestampfile);    free(timestampdir);    if (timestampfile)	free(timestampfile);}/* * Standard sudo lecture. * TODO: allow the user to specify a file name instead. */static voidlecture(){    if (def_flag(I_LECTURE)) {	(void) fputs("\n\We trust you have received the usual lecture from the local System\n\Administrator. It usually boils down to these two things:\n\\n\	#1) Respect the privacy of others.\n\	#2) Think before you type.\n\n",	stderr);    }}/* * Update the time on the timestamp file/dir or create it if necessary. */static voidupdate_timestamp(timestampdir, timestampfile)    char *timestampdir;    char *timestampfile;{    if (timestamp_uid != 0)	set_perms(PERM_TIMESTAMP);    if (touch(timestampfile ? timestampfile : timestampdir, time(NULL)) == -1) {	if (timestampfile) {	    int fd = open(timestampfile, O_WRONLY|O_CREAT|O_TRUNC, 0600);	    if (fd == -1)		log_error(NO_EXIT|USE_ERRNO, "Can't open %s", timestampfile);	    else		close(fd);	} else {	    if (mkdir(timestampdir, 0700) == -1)		log_error(NO_EXIT|USE_ERRNO, "Can't mkdir %s", timestampdir);	}    }    if (timestamp_uid != 0)	set_perms(PERM_ROOT);}/* * Expand %h and %u escapes in the prompt and pass back the dynamically * allocated result.  Returns the same string if there are no escapes. */static char *expand_prompt(old_prompt, user, host)    char *old_prompt;    char *user;    char *host;{    size_t len, n;    int subst;    char *p, *np, *new_prompt, *endp;    /* How much space do we need to malloc for the prompt? */    subst = 0;    for (p = old_prompt, len = strlen(old_prompt); *p; p++) {	if (p[0] =='%') {	    switch (p[1]) {		case 'h':		    p++;		    len += strlen(user_shost) - 2;		    subst = 1;		    break;		case 'H':		    p++;		    len += strlen(user_host) - 2;		    subst = 1;		    break;		case 'u':		    p++;		    len += strlen(user_name) - 2;		    subst = 1;		    break;		case 'U':		    p++;		    len += strlen(*user_runas) - 2;		    subst = 1;		    break;		case '%':		    p++;		    len--;		    subst = 1;		    break;		default:		    break;	    }	}    }    if (subst) {	new_prompt = (char *) emalloc(++len);	*new_prompt = '\0';	endp = new_prompt + len - 1;	for (p = old_prompt, np = new_prompt; *p; p++) {	    if (p[0] =='%') {		switch (p[1]) {		    case 'h':			p++;			if ((n = strlcat(new_prompt, user_shost, len)) >= len)			    goto oflow;			np += n;			continue;		    case 'H':			p++;			if ((n = strlcat(new_prompt, user_host, len)) >= len)			    goto oflow;			np += n;			continue;		    case 'u':			p++;			if ((n = strlcat(new_prompt, user_name, len)) >= len)			    goto oflow;			np += n;			continue;		    case 'U':			p++;			if ((n = strlcat(new_prompt, *user_runas, len)) >= len)			    goto oflow;			np += n;			continue;		    case '%':			/* convert %% -> % */			p++;			break;		    default:			/* no conversion */			break;		}	    }	    if (np >= endp)		goto oflow;	    *np++ = *p;	}	*np = '\0';    } else	new_prompt = old_prompt;    return(new_prompt);oflow:    /* We pre-allocate enough space, so this should never happen. */    (void) fprintf(stderr, "%s: internal error, expand_prompt() overflow\n",	Argv[0]);    exit(1);}