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: cmdUname.c.src.html,v 1.6 2006/01/18 05:35:11 rkowen Exp $";
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 Successfull 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 |
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' **/