1 /*
2
3 * Copyright (c) 1984, 1985, 1986 AT&T
4 * All Rights Reserved
5
6 * THIS IS UNPUBLISHED PROPRIETARY SOURCE
7 * CODE OF AT&T.
8 * The copyright notice above does not
9 * evidence any actual or intended
10 * publication of such source code.
11
12 */
13 /* @(#)tilde.c 1.1 */
14
15 /*
16 * logdir - get login directory given login name
17 *
18 * David Korn
19 * AT&T Bell Laboratories
20 * Room 5D-112
21 * Murray Hill, N. J. 07974
22 * Tel. x7975
23 *
24 * February, 1983
25 */
26
27
28 #include <stdio.h>
29 #ifdef KSHELL
30 #include "flags.h"
31 #include "name.h"
32 #include "builtins.h"
33 extern struct Namnod *bltin_nodes;
34 #else
35 #define HOMENOD "HOME"
36 #define valup(arg) getenv(arg)
37 #endif /* KSHELL */
38
39 #define UNAME 20
40 #define LOGDIR 64
41 static char u_name[UNAME];
42 static char u_logdir[LOGDIR];
43
44 #ifdef BSD
45 #define strrchr rindex
46 #endif /* BSD */
47 extern char *strrchr();
48 extern char *strcpy();
49 extern char *valup();
50 extern void setbuf();
51
52 static char *logdir();
53 static int passwdent();
54
55 /*
56 * This routine is used to resolve ~ filenames.
57 * If string starts with ~ then ~name is replaced with login directory of name.
58 * A ~ by itself is replaced with the users login directory.
59 * A ~- is replaced by the last working directory in Shell.
60 * If string doesn't start with ~ then NULL returned.
61 * If not found then the NULL string is returned.
62 */
63
tilde(string)64 char *tilde(string)
65 char *string;
66 {
67 register char *sp = string;
68 register char *cp;
69 register int c;
70 if(*sp++!='~')
71 return(NULL);
72 if((c = *sp)==0 || c=='/')
73 {
74 return(valup(HOME));
75 }
76 #ifdef KSHELL
77 if((c=='-' || c=='+') && ((c= *(sp+1))==0 || c=='/'))
78 {
79 char *oldpwd;
80 if(*sp=='+')
81 return(valup(PWDNOD));
82 else if(oldpwd=valup(OLDPWDNOD))
83 return(oldpwd);
84 else
85 return(valup(HOME));
86 }
87 #endif /* KSHELL */
88 if((cp=strrchr(sp,'/')) != NULL)
89 *cp = 0;
90 sp = logdir(sp);
91 if(cp)
92 *cp = '/';
93 return(sp);
94 }
95
96
97 /*
98 * This routine returns a pointer to a null-terminated string that
99 * contains the login directory of the given <user>.
100 * NULL is returned if there is no entry for the given user in the
101 * /etc/passwd file or if no room for directory entry.
102 * The most recent login directory is saved for future access
103 */
104
logdir(user)105 static char *logdir(user)
106 char *user;
107 {
108 if(strcmp(user,u_name))
109 {
110 if(passwdent(user)<0)
111 return(NULL);
112 }
113 return(u_logdir);
114 }
115
116
117 /*
118 * read the passwd entry for a given <user> and save the uid, gid and home
119 */
120
passwdent(user)121 static int passwdent(user)
122 char *user;
123 {
124 register char *sp=user;
125 register int c;
126 register int field=0;
127 register FILE *fd;
128 int rval = -1;
129 int val = 0;
130 char buff[BUFSIZ];
131 if(strlen(sp)>=UNAME)
132 return(-1);
133 if((fd=fdopen(open("/etc/passwd",0),"r"))==NULL)
134 return(-1);
135 setbuf(fd,buff);
136 while((c=getc(fd)) !=EOF)
137 {
138 if(c == ':')
139 {
140 if(field==5)
141 goto good;
142 else if(field++ ==0)
143 {
144 if(*sp)
145 field = 10;
146 else
147 sp = u_logdir;
148 }
149 }
150 else if(c=='\n')
151 {
152 if(field==5)
153 goto good;
154 sp = user;
155 field = 0;
156 }
157 else
158 {
159 switch(field)
160 {
161 /* match name */
162 case 0:
163 if(c != *sp++)
164 field = 10;
165 break;
166
167 case 5:
168 *sp++ = c;
169 /* see if too big */
170 if(sp >= (u_logdir+LOGDIR))
171 goto leave;
172 }
173 }
174 }
175 while(c != EOF);
176 goto leave;
177 good:
178 rval = 0;
179 *sp = 0;
180 strcpy(u_name,user);
181 leave:
182 setbuf(fd,(char*)0);
183 fclose(fd);
184 return(rval);
185 }
186
187