#if !defined(lint) && !defined(DOS) static char rcsid[] = "$Id: pw_stuff.c 763 2007-10-23 23:37:34Z hubert@u.washington.edu $"; #endif /* * ======================================================================== * Copyright 2013-2019 Eduardo Chappa * Copyright 2006 University of Washington * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * ======================================================================== */ #include #include #include "../charconv/utf8.h" #include "../charconv/filesys.h" #include "pw_stuff.h" /* * internal prototypes */ #ifndef _WINDOWS static char *gcos_name(char *, char *); /*---------------------------------------------------------------------- Pull the name out of the gcos field if we have that sort of /etc/passwd Args: gcos_field -- The long name or GCOS field to be parsed logname -- Replaces occurrences of & with logname string Result: returns pointer to buffer with name ----*/ static char * gcos_name(char *gcos_field, char *logname) { static char fullname[MAX_FULLNAME+1]; register char *fncp, *gcoscp, *lncp, *end; /* * Full name is all chars up to first ',' (or whole gcos, if no ','). * Replace any & with Logname. */ for(fncp = fullname, gcoscp= gcos_field, end = fullname + MAX_FULLNAME; (*gcoscp != ',' && *gcoscp != '\0' && fncp < end); gcoscp++){ if(*gcoscp == '&'){ for(lncp = logname; *lncp && fncp < end; fncp++, lncp++) *fncp = (lncp == logname) ? toupper((unsigned char) (*lncp)) : (*lncp); }else *fncp++ = *gcoscp; } *fncp = '\0'; return(fullname); } #endif /* !_WINDOWS */ /*---------------------------------------------------------------------- Fill in homedir, login, and fullname for the logged in user. These are all pointers to static storage so need to be copied in the caller. Args: ui -- struct pointer to pass back answers Result: fills in the fields ----*/ void get_user_info(struct user_info *ui) { #ifndef _WINDOWS struct passwd *unix_pwd; unix_pwd = getpwuid(getuid()); if(unix_pwd == NULL) { ui->homedir = (char *) malloc(sizeof(char)); ui->homedir[0] = '\0'; ui->login = (char *) malloc(sizeof(char)); ui->login[0] = '\0'; ui->fullname = (char *) malloc(sizeof(char)); ui->fullname[0] = '\0'; }else { char *s; size_t len; len = strlen(fname_to_utf8(unix_pwd->pw_dir)); ui->homedir = (char *) malloc((len+1) * sizeof(char)); snprintf(ui->homedir, len+1, "%s", fname_to_utf8(unix_pwd->pw_dir)); len = strlen(fname_to_utf8(unix_pwd->pw_name)); ui->login = (char *) malloc((len+1) * sizeof(char)); snprintf(ui->login, len+1, "%s", fname_to_utf8(unix_pwd->pw_name)); if((s = gcos_name(unix_pwd->pw_gecos, unix_pwd->pw_name)) != NULL){ len = strlen(fname_to_utf8(s)); ui->fullname = (char *) malloc((len+1) * sizeof(char)); snprintf(ui->fullname, len+1, "%s", fname_to_utf8(s)); } } #else /* _WINDOWS */ char buf[_MAX_PATH], *p, *q; TCHAR lptstr_buf[_MAX_PATH]; int len = _MAX_PATH; if(GetUserName(lptstr_buf, &len)) ui->login = lptstr_to_utf8(lptstr_buf); else ui->login = our_getenv("USERNAME"); if((p = our_getenv("HOMEDRIVE")) && (q = our_getenv("HOMEPATH"))) snprintf(buf, sizeof(buf), "%s%s", p, q); else snprintf(buf, sizeof(buf), "%c:\\", '@' + _getdrive()); if(p) free((void *)p); if(q) free((void *)q); ui->homedir = (char *) malloc((strlen(buf)+1) * sizeof(char)); if(ui->homedir){ strncpy(ui->homedir, buf, strlen(buf)); ui->homedir[strlen(buf)] = '\0'; } ui->fullname = (char *) malloc(sizeof(char)); if(ui->fullname) ui->fullname[0] = '\0'; #endif /* _WINDOWS */ } /*---------------------------------------------------------------------- Look up a userid on the local system and return rfc822 address Args: name -- possible login name on local system Result: returns NULL or pointer to alloc'd string rfc822 address. ----*/ char * local_name_lookup(char *name) { #ifndef _WINDOWS struct passwd *pw = getpwnam(name); if(pw == NULL){ char *p; for(p = name; *p; p++) if(isupper((unsigned char)*p)) break; /* try changing it to all lower case */ if(p && *p){ char lcase[256]; size_t l; snprintf(lcase, sizeof(lcase), "%s", name); l = strlen(name); for(p = lcase; *p; p++) if(isupper((unsigned char)*p)) *p = tolower((unsigned char)*p); pw = getpwnam(lcase); if(pw){ strncpy(name, lcase, l+1); name[l] = '\0'; } } } if(pw != NULL){ char *gn, *s = NULL; size_t l; if((gn = gcos_name(pw->pw_gecos, name)) != NULL && (s = (char *) malloc(l = ((strlen(gn) + 1) * sizeof(char)))) != NULL) snprintf(s, l, "%s", gn); return(s); } else return((char *) NULL); #else /* _WINDOWS */ return(NULL); #endif /* _WINDOWS */ }