1 /*------------- Telecommunications & Signal Processing Lab -------------
2                           McGill University
3 
4 Routine:
5   int FLhomeDir (const char User[], char Home[])
6 
7 Purpose:
8   Get the home directory for a user
9 
10 Description:
11   This routine returns the path name corresponding to the home directory for a
12   user.  When the User argument is empty, the current user is assumed.  In that
13   case, the translation of the environment variable HOME is used if possible.
14   In other cases, the home directory is taken from the password entry for the
15   user.  If the user is unknown, the home directory string is returned as
16   "~User".
17 
18 Parameters:
19   <-  int FLhomeDir
20       Number of characters in the output string
21    -> const char User[]
22       Input character string specifying the user.  If this string is empty, the
23       current user is used.
24   <-  char Home[]
25       Output string with the home directory.  Except for the case of the root
26       directory "/", the directory name does not have a trailing '/' character.
27       This string is at most FILENAME_MAX characters long including the
28       terminating null character.
29 
30 Author / revision:
31   P. Kabal  Copyright (C) 2003
32   $Revision: 1.24 $  $Date: 2003/05/09 01:36:44 $
33 
34 ----------------------------------------------------------------------*/
35 
36 #include <stdlib.h>		/* getenv prototype */
37 #include <string.h>
38 
39 #include <libtsp.h>
40 #include <libtsp/nucleus.h>
41 #include <libtsp/sysOS.h>
42 
43 #if (SY_POSIX)
44 #  include <pwd.h>	/* struct passwd, getpwnam prototype */
45 #  include <unistd.h>	/* getuid definitions */
46 #endif
47 
48 #if (SY_FILENAME_SPEC == SY_FNS_UNIX)
49 #  define DIR_SEP_STR	"/"
50 #elif (SY_FILENAME_SPEC == SY_FNS_WINDOWS)
51 #  define DIR_SEP_STR	"\\"
52 #else
53 #  error "Bad SY_FILENAME_SPEC value"
54 #endif
55 #define DIR_SEP_CHAR	((DIR_SEP_STR)[0])
56 
57 
58 int
FLhomeDir(const char User[],char Home[])59 FLhomeDir (const char User[], char Home[])
60 
61 {
62   char *h, *p;
63   int n, nc;
64 #if (SY_OS == SY_OS_WINDOWS)
65   char temp[FILENAME_MAX-1];
66   char *q;
67 #endif
68 #if (SY_POSIX)
69   struct passwd *pwd;
70 #endif
71 
72   h = NULL;
73   if (User[0] == '\0' || strcmp (User, UTgetUser()) == 0) {
74 
75     /* No user name specified or same as logged in user */
76     /* Try the environment variable HOME
77        - On Cygwin, HOME is translated to Unix file conventions
78     */
79     p = getenv ("HOME");
80     if (p != NULL && *p != '\0')
81       h = p;
82 
83 #if (SY_OS == SY_OS_WINDOWS)
84     /* Get the home directory from the environment variables
85        HOMEDRIVE and HOMEPATH.
86     */
87     p = getenv ("HOMEDRIVE");
88     q = getenv ("HOMEPATH");
89     if (p != NULL && *p != '\0' && q != NULL && q!= '\0') {
90       STcopyMax (p, temp, FILENAME_MAX-1);
91       STcatMax (q, temp, FILENAME_MAX-1);
92       h = temp;
93     }
94 #endif
95 
96 #if (SY_POSIX)
97     /* Try the password entry */
98     else {
99       pwd = getpwuid (getuid ());
100       if (pwd != NULL)
101 	h = pwd->pw_dir;
102     }
103 #endif
104   }
105 
106 #if (SY_POSIX)
107   else {
108 
109 /* User specified, try the password entry */
110     pwd = getpwnam (User);
111     if (pwd != NULL)
112       h = pwd->pw_dir;
113   }
114 #endif
115 
116   if (h != NULL) {
117 
118 /* Found a home directory */
119     nc = strlen (h);
120     if (nc > 1 && h[nc-1] == DIR_SEP_CHAR)
121       --nc;
122     n = STcopyNMax (h, Home, nc, FILENAME_MAX-1);
123   }
124 
125   else {
126 
127 /* Unsuccessful */
128     Home[0] = '~';
129     n = STcopyMax (User, &Home[1], FILENAME_MAX-2);
130     n = n + 1;
131   }
132 
133   return n;
134 }
135