* New version 2.21.999
[alpine.git] / pith / osdep / pw_stuff.c
blobb491849f9ca474cf5bc3ba221acf06071a1a5842
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: pw_stuff.c 763 2007-10-23 23:37:34Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2013-2018 Eduardo Chappa
8 * Copyright 2006 University of Washington
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
19 #include <system.h>
20 #include <general.h>
22 #include "../charconv/utf8.h"
23 #include "../charconv/filesys.h"
24 #include "pw_stuff.h"
27 * internal prototypes
29 #ifndef _WINDOWS
31 static char *gcos_name(char *, char *);
34 /*----------------------------------------------------------------------
35 Pull the name out of the gcos field if we have that sort of /etc/passwd
37 Args: gcos_field -- The long name or GCOS field to be parsed
38 logname -- Replaces occurances of & with logname string
40 Result: returns pointer to buffer with name
41 ----*/
42 static char *
43 gcos_name(char *gcos_field, char *logname)
45 static char fullname[MAX_FULLNAME+1];
46 register char *fncp, *gcoscp, *lncp, *end;
49 * Full name is all chars up to first ',' (or whole gcos, if no ',').
50 * Replace any & with Logname.
53 for(fncp = fullname, gcoscp= gcos_field, end = fullname + MAX_FULLNAME;
54 (*gcoscp != ',' && *gcoscp != '\0' && fncp < end);
55 gcoscp++){
57 if(*gcoscp == '&'){
58 for(lncp = logname; *lncp && fncp < end; fncp++, lncp++)
59 *fncp = (lncp == logname) ? toupper((unsigned char) (*lncp))
60 : (*lncp);
61 }else
62 *fncp++ = *gcoscp;
65 *fncp = '\0';
66 return(fullname);
69 #endif /* !_WINDOWS */
73 /*----------------------------------------------------------------------
74 Fill in homedir, login, and fullname for the logged in user.
75 These are all pointers to static storage so need to be copied
76 in the caller.
78 Args: ui -- struct pointer to pass back answers
80 Result: fills in the fields
81 ----*/
82 void
83 get_user_info(struct user_info *ui)
85 #ifndef _WINDOWS
86 struct passwd *unix_pwd;
88 unix_pwd = getpwuid(getuid());
89 if(unix_pwd == NULL) {
90 ui->homedir = (char *) malloc(sizeof(char));
91 ui->homedir[0] = '\0';
92 ui->login = (char *) malloc(sizeof(char));
93 ui->login[0] = '\0';
94 ui->fullname = (char *) malloc(sizeof(char));
95 ui->fullname[0] = '\0';
96 }else {
97 char *s;
98 size_t len;
100 len = strlen(fname_to_utf8(unix_pwd->pw_dir));
101 ui->homedir = (char *) malloc((len+1) * sizeof(char));
102 snprintf(ui->homedir, len+1, "%s", fname_to_utf8(unix_pwd->pw_dir));
104 len = strlen(fname_to_utf8(unix_pwd->pw_name));
105 ui->login = (char *) malloc((len+1) * sizeof(char));
106 snprintf(ui->login, len+1, "%s", fname_to_utf8(unix_pwd->pw_name));
108 if((s = gcos_name(unix_pwd->pw_gecos, unix_pwd->pw_name)) != NULL){
109 len = strlen(fname_to_utf8(s));
110 ui->fullname = (char *) malloc((len+1) * sizeof(char));
111 snprintf(ui->fullname, len+1, "%s", fname_to_utf8(s));
115 #else /* _WINDOWS */
116 char buf[_MAX_PATH], *p, *q;
117 TCHAR lptstr_buf[_MAX_PATH];
118 int len = _MAX_PATH;
120 if(GetUserName(lptstr_buf, &len))
121 ui->login = lptstr_to_utf8(lptstr_buf);
122 else
123 ui->login = our_getenv("USERNAME");
125 if((p = our_getenv("HOMEDRIVE"))
126 && (q = our_getenv("HOMEPATH")))
127 snprintf(buf, sizeof(buf), "%s%s", p, q);
128 else
129 snprintf(buf, sizeof(buf), "%c:\\", '@' + _getdrive());
131 if(p)
132 free((void *)p);
134 if(q)
135 free((void *)q);
137 ui->homedir = (char *) malloc((strlen(buf)+1) * sizeof(char));
138 if(ui->homedir){
139 strncpy(ui->homedir, buf, strlen(buf));
140 ui->homedir[strlen(buf)] = '\0';
143 ui->fullname = (char *) malloc(sizeof(char));
144 if(ui->fullname)
145 ui->fullname[0] = '\0';
146 #endif /* _WINDOWS */
150 /*----------------------------------------------------------------------
151 Look up a userid on the local system and return rfc822 address
153 Args: name -- possible login name on local system
155 Result: returns NULL or pointer to alloc'd string rfc822 address.
156 ----*/
157 char *
158 local_name_lookup(char *name)
160 #ifndef _WINDOWS
161 struct passwd *pw = getpwnam(name);
163 if(pw == NULL){
164 char *p;
166 for(p = name; *p; p++)
167 if(isupper((unsigned char)*p))
168 break;
170 /* try changing it to all lower case */
171 if(p && *p){
172 char lcase[256];
173 size_t l;
175 snprintf(lcase, sizeof(lcase), "%s", name);
177 l = strlen(name);
178 for(p = lcase; *p; p++)
179 if(isupper((unsigned char)*p))
180 *p = tolower((unsigned char)*p);
182 pw = getpwnam(lcase);
184 if(pw){
185 strncpy(name, lcase, l+1);
186 name[l] = '\0';
191 if(pw != NULL){
192 char *gn, *s = NULL;
193 size_t l;
195 if((gn = gcos_name(pw->pw_gecos, name)) != NULL
196 && (s = (char *) malloc(l = ((strlen(gn) + 1) * sizeof(char)))) != NULL)
197 snprintf(s, l, "%s", gn);
199 return(s);
201 else
202 return((char *) NULL);
203 #else /* _WINDOWS */
204 return(NULL);
205 #endif /* _WINDOWS */