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' **/