1 /*****
2 ** ** Module Header ******************************************************* **
3 ** **
4 ** Modules Revision 3.0 **
5 ** Providing a flexible user environment **
6 ** **
7 ** File: cmdUname.c **
8 ** First Edition: 1991/10/23 **
9 ** **
10 ** Authors: John Furlan, jlf@behere.com **
11 ** Jens Hamisch, jens@Strawberry.COM **
12 ** **
13 ** Description: Provides fast aquisition of the information available**
14 ** via uname. This shows a 10x improvement over having **
15 ** to exec the actual uname program from within a **
16 ** modulefile. **
17 ** **
18 ** Exports: cmdUname **
19 ** **
20 ** Notes: **
21 ** **
22 ** ************************************************************************ **
23 ****/
24
25 /** ** Copyright *********************************************************** **
26 ** **
27 ** Copyright 1991-1994 by John L. Furlan. **
28 ** see LICENSE.GPL, which must be provided, for details **
29 ** **
30 ** ************************************************************************ **/
31
32 static char Id[] = "@(#)$Id: 986c78c90605e7e69e905b4bdd447fe724954a3d $";
33 static void *UseId[] = { &UseId, Id };
34
35 /** ************************************************************************ **/
36 /** HEADERS **/
37 /** ************************************************************************ **/
38
39 #include "modules_def.h"
40
41 #ifdef HAVE_UNAME
42 #include <sys/utsname.h>
43 #endif
44
45 /** ************************************************************************ **/
46 /** LOCAL DATATYPES **/
47 /** ************************************************************************ **/
48
49 #ifndef HAVE_UNAME
50
51 typedef struct utsname {
52 char sysname[ NAMELEN]; /** System name **/
53 char nodename[ NAMELEN]; /** Node name **/
54 char release[ NAMELEN]; /** OS Release **/
55 char version[ NAMELEN]; /** OS Version **/
56 char machine[ NAMELEN]; /** Machine type **/
57 } UTS_NAME;
58
59 #endif
60
61 /** ************************************************************************ **/
62 /** CONSTANTS **/
63 /** ************************************************************************ **/
64
65 /** not applicable **/
66
67 /** ************************************************************************ **/
68 /** MACROS **/
69 /** ************************************************************************ **/
70
71 #define NAMELEN (8 + 1) /** 8 chars + 1 terminator **/
72 #define DOMAINLEN (64 + 1) /** 8 chars + 1 terminator **/
73
74 /** ************************************************************************ **/
75 /** LOCAL DATA **/
76 /** ************************************************************************ **/
77
78 static char module_name[] = "cmdUname.c"; /** File name of this module **/
79
80 #if WITH_DEBUGGING_CALLBACK
81 static char _proc_cmdUname[] = "cmdUname";
82 #endif
83
84 static struct utsname namestruct = {
85 UNAME_SYSNAME, UNAME_NODENAME, UNAME_RELEASE, UNAME_VERSION,
86 UNAME_MACHINE
87 };
88
89 static char domain[ DOMAINLEN] = UNAME_DOMAIN;
90
91 static int namestruct_init = 0;
92
93 /** ************************************************************************ **/
94 /** PROTOTYPES **/
95 /** ************************************************************************ **/
96
97 /** not applicable **/
98
99
100 /*++++
101 ** ** Function-Header ***************************************************** **
102 ** **
103 ** Function: cmdUname **
104 ** **
105 ** Description: Callback function for the commands 'sysname', **
106 ** 'nodename', 'release', 'version' and 'machine' **
107 ** **
108 ** First Edition: 1991/10/23 **
109 ** **
110 ** Parameters: ClientData client_data **
111 ** Tcl_Interp *interp According Tcl interp.**
112 ** int argc Number of arguments **
113 ** char *argv[] Argument array **
114 ** **
115 ** Result: int TCL_OK Successful completion **
116 ** TCL_ERROR Any error **
117 ** **
118 ** Attached Globals: flags These are set up accordingly before **
119 ** this function is called in order to **
120 ** control everything **
121 ** **
122 ** ************************************************************************ **
123 ++++*/
124
cmdUname(ClientData client_data,Tcl_Interp * interp,int argc,CONST84 char * argv[])125 int cmdUname( ClientData client_data,
126 Tcl_Interp *interp,
127 int argc,
128 CONST84 char *argv[])
129 {
130 int length;
131 #ifdef PHOSTNAME
132 #ifndef HAVE_GETHOSTNAME
133 FILE* hname;
134 #endif
135 #endif
136
137 #if WITH_DEBUGGING_CALLBACK
138 ErrorLogger( NO_ERR_START, LOC, _proc_cmdUname, NULL);
139 #endif
140
141 /**
142 ** Parameter check. One parameter should be given providing a selector
143 ** do differ between:
144 **/
145
146 if( argc != 2) {
147 if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "member", NULL))
148 return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
149 }
150
151 #ifdef HAVE_UNAME
152
153 /**
154 ** Proceed the system call
155 **/
156
157 if( !namestruct_init && uname( &namestruct) < 0) {
158 if( OK != ErrorLogger( ERR_UNAME, LOC, NULL))
159 return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
160 }
161
162 #else /* not HAVE_UNAME */
163
164 /**
165 ** If we do not have the uname system call, fixed values defined
166 ** at compile time will be returned. The only differenc is the
167 ** nodename, which may be seeked for using 'gethostname' or the
168 ** PHOSTNAME file.
169 **/
170
171 #ifdef HAVE_GETHOSTNAME
172
173 if( -1 == gethostname( namestruct.nodename, NAMELEN))
174 if( OK != ErrorLogger( ERR_GETHOSTNAME, LOC, NULL))
175 return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
176
177 #else /* not HAVE_GETHOSTNAME */
178
179 #ifdef PHOSTNAME
180
181 if( NULL == (hname = popen( PHOSTNAME, "r"))) {
182 if( OK != ErrorLogger( ERR_POPEN, LOC, PHOSTNAME, "reading", NULL))
183 return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
184 }
185
186 fgets( namestruct.nodename, NAMELEN, hname);
187 namestruct.nodename[ strlen( namestruct.nodename)-1] = '\0';
188
189 if( -1 == pclose( hname))
190 if( OK != ErrorLogger( ERR_PCLOSE, LOC, PHOSTNAME, NULL))
191 return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
192
193 #endif /* not PHOSTNAME */
194 #endif /* not HAVE_GETHOSTNAME */
195
196 #endif /* not HAVE_UNAME */
197
198 /**
199 ** Set up the domain name
200 **/
201
202 #ifdef HAVE_GETDOMAINNAME
203 if( !namestruct_init)
204 if( -1 == getdomainname( domain, DOMAINLEN))
205 if( OK != ErrorLogger( ERR_GETDOMAINNAME, LOC, NULL))
206 return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
207 #endif
208
209 /**
210 ** Now the name structure surely IS initialized
211 **/
212
213 namestruct_init = 1;
214
215 /**
216 ** Return the selected value
217 **/
218
219 length = strlen( argv[1]);
220
221 if( !strncmp( argv[1], "sysname", length)) {
222 Tcl_SetResult( interp, namestruct.sysname, TCL_VOLATILE);
223 } else if( !strncmp( argv[1], "nodename", length)) {
224 Tcl_SetResult( interp, namestruct.nodename, TCL_VOLATILE);
225 } else if( !strncmp( argv[1], "release", length)) {
226 Tcl_SetResult( interp, namestruct.release, TCL_VOLATILE);
227 } else if( !strncmp( argv[1], "version", length)) {
228 Tcl_SetResult( interp, namestruct.version, TCL_VOLATILE);
229 } else if( !strncmp( argv[1], "machine", length)) {
230 Tcl_SetResult( interp, namestruct.machine, TCL_VOLATILE);
231 } else if( !strncmp( argv[1], "domain", length)) {
232 Tcl_SetResult( interp, domain, TCL_VOLATILE);
233 } else {
234 if( OK != ErrorLogger( ERR_USAGE, LOC, argv[0], "{sysname|nodename|"
235 "release|version|machine|domain}", NULL))
236 return( TCL_ERROR); /** -------- EXIT (FAILURE) -------> **/
237 }
238
239 #if WITH_DEBUGGING_CALLBACK
240 ErrorLogger( NO_ERR_END, LOC, _proc_cmdUname, NULL);
241 #endif
242
243 return( TCL_OK); /** -------- EXIT (SUCCESS) -------> **/
244
245 } /** End of 'cmdUname' **/
246