date and time created 88/07/21 17:35:52 by marc
authorMarc Teitelbaum <marc@ucbvax.Berkeley.EDU>
Fri, 22 Jul 1988 08:35:52 +0000 (00:35 -0800)
committerMarc Teitelbaum <marc@ucbvax.Berkeley.EDU>
Fri, 22 Jul 1988 08:35:52 +0000 (00:35 -0800)
SCCS-vsn: local/toolchest/ksh/shlib/tilde.c 1.1

usr/src/local/toolchest/ksh/shlib/tilde.c [new file with mode: 0644]

diff --git a/usr/src/local/toolchest/ksh/shlib/tilde.c b/usr/src/local/toolchest/ksh/shlib/tilde.c
new file mode 100644 (file)
index 0000000..a8e7bee
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+
+ *      Copyright (c) 1984, 1985, 1986 AT&T
+ *      All Rights Reserved
+
+ *      THIS IS UNPUBLISHED PROPRIETARY SOURCE 
+ *      CODE OF AT&T.
+ *      The copyright notice above does not 
+ *      evidence any actual or intended
+ *      publication of such source code.
+
+ */
+/* @(#)tilde.c 1.1 */
+
+/*
+ *  logdir - get login directory given login name
+ *
+ *   David Korn
+ *   AT&T Bell Laboratories
+ *   Room 5D-112
+ *   Murray Hill, N. J. 07974
+ *   Tel. x7975
+ *
+ *   February, 1983
+ */                                              
+
+
+#include       <stdio.h>
+#ifdef KSHELL
+#include       "flags.h"
+#include       "name.h"
+#include       "builtins.h"
+extern struct Namnod *bltin_nodes;
+#else
+#define HOMENOD        "HOME"
+#define valup(arg)     getenv(arg)
+#endif /* KSHELL */
+
+#define UNAME  20
+#define LOGDIR 64            
+static char u_name[UNAME];
+static char u_logdir[LOGDIR];
+
+#ifdef BSD
+#define strrchr rindex
+#endif /* BSD */
+extern char    *strrchr();
+extern char    *strcpy();
+extern char    *valup();
+extern void    setbuf();
+
+static char    *logdir();
+static int     passwdent();
+
+/*
+ * This routine is used to resolve ~ filenames.
+ * If string starts with ~ then ~name is replaced with login directory of name.
+ * A ~ by itself is replaced with the users login directory.
+ * A ~- is replaced by the last working directory in Shell.
+ * If string doesn't start with ~ then NULL returned.
+ * If not found then the NULL string is returned.
+ */
+                                                            
+char *tilde(string)
+char *string;
+{
+       register char *sp = string;
+       register char *cp;
+       register int c;
+       if(*sp++!='~')
+               return(NULL);
+       if((c = *sp)==0 || c=='/')
+       {
+               return(valup(HOME));
+       }
+#ifdef KSHELL
+       if((c=='-' || c=='+') && ((c= *(sp+1))==0 || c=='/'))
+       {
+               char *oldpwd;
+               if(*sp=='+')
+                       return(valup(PWDNOD));
+               else if(oldpwd=valup(OLDPWDNOD))
+                       return(oldpwd);
+               else
+                       return(valup(HOME));
+       }
+#endif /* KSHELL */
+       if((cp=strrchr(sp,'/')) != NULL)
+               *cp = 0;
+       sp = logdir(sp);
+       if(cp)
+               *cp = '/';
+       return(sp);
+}
+
+/*
+ * This routine returns a pointer to a null-terminated string that
+ * contains the login directory of the given <user>.
+ * NULL is returned if there is no entry for the given user in the
+ * /etc/passwd file or if no room for directory entry.
+ * The most recent login directory is saved for future access
+ */
+
+static char *logdir(user)
+char *user;
+{
+       if(strcmp(user,u_name))
+       {
+               if(passwdent(user)<0)
+                       return(NULL);
+       }
+       return(u_logdir);
+}
+
+
+/*
+ * read the passwd entry for a given <user> and save the uid, gid and home
+ */
+
+static int passwdent(user)
+char *user;
+{
+       register char *sp=user;
+       register int c;
+       register int field=0;
+       register FILE *fd;
+       int rval = -1;
+       int val = 0;
+       char buff[BUFSIZ];
+       if(strlen(sp)>=UNAME)
+               return(-1);
+       if((fd=fdopen(open("/etc/passwd",0),"r"))==NULL)
+               return(-1);
+       setbuf(fd,buff);
+       while((c=getc(fd)) !=EOF)
+       {
+               if(c == ':')
+               {
+                       if(field==5)
+                               goto good;
+                       else if(field++ ==0)
+                       {
+                               if(*sp)
+                                       field = 10;
+                               else
+                                       sp = u_logdir;
+                       }
+               }
+               else if(c=='\n')
+               {
+                       if(field==5)
+                               goto good;
+                       sp = user;
+                       field = 0;
+               }
+               else
+               {
+                       switch(field)
+                       {
+                               /* match name */
+                               case 0:
+                                       if(c != *sp++)
+                                               field = 10;
+                                       break;
+
+                               case 5:
+                                       *sp++ = c;
+                                       /* see if too big */
+                                       if(sp >= (u_logdir+LOGDIR))
+                                               goto leave;
+                       }
+               }
+       }
+       while(c != EOF);
+       goto leave;
+good:
+       rval = 0;
+       *sp = 0;
+       strcpy(u_name,user);
+leave:
+       setbuf(fd,(char*)0);
+       fclose(fd);
+       return(rval);
+}
+