1 /***************************************************************************
2  * LPRng - An Extended Print Spooler System
3  *
4  * Copyright 1988-2003, Patrick Powell, San Diego, CA
5  *     papowell@lprng.com
6  * See LICENSE for conditions of use.
7  *
8  ***************************************************************************/
9 
10  static char *const _id =
11 "$Id: proctitle.c,v 1.74 2004/09/24 20:19:58 papowell Exp $";
12 
13 #include "lp.h"
14 #include "proctitle.h"
15 /**** ENDINCLUDE ****/
16 
17 /*
18  *  SETPROCTITLE -- set process title for ps
19  *  proctitle( char *str );
20  *
21  *	Returns: none.
22  *
23  *	Side Effects: Clobbers argv of our main procedure so ps(1) will
24  * 		      display the title.
25  */
26 
27 /*
28  * From the Sendmail.8.8.8 Source Distribution
29  *
30  * Copyright (c) 1983, 1995-2000 Eric P. Allman
31  * Copyright (c) 1988, 1993
32  *	The Regents of the University of California.  All rights reserved.
33  *
34  * Redistribution and use in source and binary forms, with or without
35  * modification, are permitted provided that the following conditions
36  * are met:
37  * 1. Redistributions of source code must retain the above copyright
38  *    notice, this list of conditions and the following disclaimer.
39  * 2. Redistributions in binary form must reproduce the above copyright
40  *    notice, this list of conditions and the following disclaimer in the
41  *    documentation and/or other materials provided with the distribution.
42  * 3. All advertising materials mentioning features or use of this software
43  *    must display the following acknowledgement:
44  *	This product includes software developed by the University of
45  *	California, Berkeley and its contributors.
46  * 4. Neither the name of the University nor the names of its contributors
47  *    may be used to endorse or promote products derived from this software
48  *    without specific prior written permission.
49  *
50  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60  * SUCH DAMAGE.
61  *
62  *	@(#)conf.h	8.335 (Berkeley) 10/24/97
63  */
64 
65 #ifdef __hpux
66 # define SPT_TYPE	SPT_PSTAT
67 #endif
68 
69 #if defined(_AIX32) || defined(_AIX) || defined(AIX) || defined(IS_AIX32)
70 # define SPT_PADCHAR	'\0'	/* pad process title with nulls */
71 #endif
72 
73 #ifdef	DGUX
74 # define SPT_TYPE	SPT_NONE	/* don't use setproctitle */
75 #endif
76 
77 #if defined(BSD4_4) && !defined(__bsdi__) && !defined(__GNU__)
78 # define SPT_TYPE	SPT_PSSTRINGS	/* use PS_STRINGS pointer */
79 #endif
80 
81 #ifdef __bsdi__
82 # if defined(_BSDI_VERSION) && _BSDI_VERSION >= 199312
83 #  undef SPT_TYPE
84 #  define SPT_TYPE	SPT_BUILTIN	/* setproctitle is in libc */
85 # else
86 #  define SPT_PADCHAR	'\0'	/* pad process title with nulls */
87 # endif
88 #endif
89 
90 #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
91 # if defined(__NetBSD__) && (NetBSD > 199307 || NetBSD0_9 > 1)
92 #  undef SPT_TYPE
93 #  define SPT_TYPE	SPT_BUILTIN	/* setproctitle is in libc */
94 # endif
95 # if defined(__FreeBSD__)
96 #  undef SPT_TYPE
97 #  if __FreeBSD__ >= 2
98 #   include <osreldate.h>		/* and this works */
99 #   if __FreeBSD_version >= 199512	/* 2.2-current right now */
100 #    include <libutil.h>
101 #    define SPT_TYPE	SPT_BUILTIN
102 #   endif
103 #  endif
104 #  ifndef SPT_TYPE
105 #   define SPT_TYPE	SPT_REUSEARGV
106 #   define SPT_PADCHAR	'\0'		/* pad process title with nulls */
107 #  endif
108 # endif
109 # if defined(__OpenBSD__)
110 #  undef SPT_TYPE
111 #  define SPT_TYPE	SPT_BUILTIN	/* setproctitle is in libc */
112 # endif
113 #endif
114 
115 #ifdef __GNU_HURD__
116 # define SPT_TYPE	SPT_CHANGEARGV
117 #endif /* GNU */
118 
119 /* SCO UNIX 3.2v4.0 Open Desktop 2.0 and earlier */
120 #ifdef _SCO_unix_
121 # define SPT_TYPE	SPT_SCO		/* write kernel u. area */
122 #endif
123 
124 #ifdef __linux__
125 # define SPT_PADCHAR	'\0'		/* pad process title with nulls */
126 #endif
127 
128 #ifdef _SEQUENT_
129 # define SPT_TYPE	SPT_NONE	/* don't use setproctitle */
130 #endif
131 
132 #ifdef apollo
133 # define SPT_TYPE	SPT_NONE	/* don't use setproctitle */
134 #endif
135 #ifdef NCR_MP_RAS2
136 # define SPT_TYPE  SPT_NONE
137 #endif
138 
139 #ifdef NCR_MP_RAS3
140 # define SPT_TYPE 	SPT_NONE
141 #endif
142 /*
143 **  SETPROCTITLE -- set process title for ps
144 **
145 **	Parameters:
146 **		fmt -- a printf style format string.
147 **		a, b, c -- possible parameters to fmt.
148 **
149 **	Returns:
150 **		none.
151 **
152 **	Side Effects:
153 **		Clobbers argv of our main procedure so ps(1) will
154 **		display the title.
155 */
156 
157 #define SPT_NONE	0	/* don't use it at all */
158 #define SPT_REUSEARGV	1	/* cover argv with title information */
159 #define SPT_BUILTIN	2	/* use libc builtin */
160 #define SPT_PSTAT	3	/* use pstat(PSTAT_SETCMD, ...) */
161 #define SPT_PSSTRINGS	4	/* use PS_STRINGS->... */
162 #define SPT_SYSMIPS	5	/* use sysmips() supported by NEWS-OS 6 */
163 #define SPT_SCO		6	/* write kernel u. area */
164 #define SPT_CHANGEARGV	7	/* write our own strings into argv[] */
165 
166 #ifndef SPT_TYPE
167 # define SPT_TYPE	SPT_REUSEARGV
168 #endif
169 
170 #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
171 
172 # if SPT_TYPE == SPT_PSTAT
173 #  include <sys/pstat.h>
174 # endif
175 # if SPT_TYPE == SPT_PSSTRINGS
176 #  include <machine/vmparam.h>
177 #  include <sys/exec.h>
178 #  ifndef PS_STRINGS	/* hmmmm....  apparently not available after all */
179 #   undef SPT_TYPE
180 #   define SPT_TYPE	SPT_REUSEARGV
181 #  else
182 #   ifndef NKPDE			/* FreeBSD 2.0 */
183 #    define NKPDE 63
184  typedef unsigned int	*pt_entry_t;
185 #   endif
186 #  endif
187 # endif
188 
189 # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
190 #  define SETPROC_STATIC	static
191 # else
192 #  define SETPROC_STATIC
193 # endif
194 
195 # if SPT_TYPE == SPT_SYSMIPS
196 #  include <sys/sysmips.h>
197 #  include <sys/sysnews.h>
198 # endif
199 
200 # if SPT_TYPE == SPT_SCO
201 #  include <sys/immu.h>
202 #  include <sys/dir.h>
203 #  include <sys/user.h>
204 #  include <sys/fs/s5param.h>
205 #  if PSARGSZ > LINEBUFFER
206 #   define SPT_BUFSIZE	PSARGSZ
207 #  endif
208 # endif
209 
210 # ifndef SPT_PADCHAR
211 #  define SPT_PADCHAR	' '
212 # endif
213 
214 # ifndef SPT_BUFSIZE
215 #  define SPT_BUFSIZE	LINEBUFFER
216 # endif
217 
218 #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
219 
220 /*
221 **  Pointers for setproctitle.
222 **	This allows "ps" listings to give more useful information.
223 */
224 # if SPT_TYPE != SPT_BUILTIN
225  static char	**Argv = NULL;		/* pointer to argument vector */
226  static char	*LastArgv = NULL;	/* end of argv */
227 #endif
228 
229 
initsetproctitle(argc,argv,envp)230  void initsetproctitle(argc, argv, envp)
231 	int argc;
232 	char **argv;
233 	char **envp;
234 {
235 # if SPT_TYPE != SPT_BUILTIN
236 	register int i, envpsize = 0;
237 	extern char **environ;
238 
239 	/*
240 	**  Move the environment so setproctitle can use the space at
241 	**  the top of memory.
242 	*/
243 
244 	DEBUG1("initsetproctitle: doing setup");
245 	for (i = 0; envp[i] != NULL; i++)
246 		envpsize += safestrlen(envp[i]) + 1;
247 	{
248 	char *s;
249 	environ = (char **) malloc_or_die((sizeof (char *) * (i + 1))+envpsize+1,__FILE__,__LINE__);
250 	s = ((char *)environ)+((sizeof (char *) * (i + 1)));
251 	for (i = 0; envp[i] != NULL; i++){
252 		strcpy(s,envp[i]);
253 		environ[i] = s;
254 		s += safestrlen(s)+1;
255 	}
256 	}
257 	environ[i] = NULL;
258 
259 	/*
260 	**  Save start and extent of argv for setproctitle.
261 	*/
262 
263 	Argv = argv;
264 
265 	/*
266 	**  Determine how much space we can use for setproctitle.
267 	**  Use all contiguous argv and envp pointers starting at argv[0]
268  	*/
269 	for (i = 0; i < argc; i++)
270 	{
271 		if (i==0 || LastArgv + 1 == argv[i])
272 			LastArgv = argv[i] + safestrlen(argv[i]);
273 		else
274 			continue;
275 	}
276 	for (i=0; envp[i] != NULL; i++)
277 	{
278 		if (LastArgv + 1 == envp[i])
279 			LastArgv = envp[i] + safestrlen(envp[i]);
280 		else
281 			continue;
282 	}
283 	DEBUG1("initsetproctitle: Argv 0x%p, LastArgv 0x%p", Argv, LastArgv);
284 #else
285 	DEBUG1("initsetproctitle: using builtin");
286 #endif
287 }
288 
289 #if SPT_TYPE != SPT_BUILTIN
290 
291  void
292 #ifdef HAVE_STDARGS
setproctitle(const char * fmt,...)293  setproctitle (const char *fmt,...)
294 #else
295  setproctitle (va_alist) va_dcl
296 #endif
297 
298 {
299 # if SPT_TYPE != SPT_NONE
300 	register int i;
301 	SETPROC_STATIC char buf[SPT_BUFSIZE];
302 #  if SPT_TYPE == SPT_PSTAT
303 	union pstun pst;
304 #  endif
305 #  if SPT_TYPE == SPT_SCO
306 	off_t seek_off;
307 	static int kmem = -1;
308 	static int kmempid = -1;
309 	struct user u;
310 #  endif
311 
312     VA_LOCAL_DECL
313     /* print the argument string */
314     VA_START (fmt);
315     VA_SHIFT (fmt, char *);
316     (void) plp_vsnprintf(buf, sizeof(buf), fmt, ap);
317     VA_END;
318 
319 	i = safestrlen(buf);
320 
321 #  if SPT_TYPE == SPT_PSTAT
322 	pst.pst_command = buf;
323 	pstat(PSTAT_SETCMD, pst, i, 0, 0);
324 #  endif
325 #  if SPT_TYPE == SPT_PSSTRINGS
326 	PS_STRINGS->ps_nargvstr = 1;
327 	PS_STRINGS->ps_argvstr = buf;
328 #  endif
329 #  if SPT_TYPE == SPT_SYSMIPS
330 	sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
331 #  endif
332 #  if SPT_TYPE == SPT_SCO
333 	if (kmem < 0 || kmempid != getpid())
334 	{
335 		if (kmem >= 0)
336 			close(kmem);
337 		kmem = open(_PATH_KMEM, O_RDWR, 0);
338 		if (kmem < 0)
339 			return;
340 		(void) fcntl(kmem, F_SETFD, 1);
341 		kmempid = getpid();
342 	}
343 	buf[PSARGSZ - 1] = '\0';
344 	seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
345 	if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
346 		(void) write(kmem, buf, PSARGSZ);
347 #  endif
348 #  if SPT_TYPE == SPT_REUSEARGV
349 	if (i > LastArgv - Argv[0] - 2)
350 	{
351 		i = LastArgv - Argv[0] - 2;
352 		buf[i] = '\0';
353 	}
354 	(void) strcpy(Argv[0], buf);
355 	{ char *p;
356 	p = &Argv[0][i];
357 	while (p < LastArgv)
358 		*p++ = SPT_PADCHAR;
359 	}
360 	Argv[1] = NULL;
361 #  endif
362 #  if SPT_TYPE == SPT_CHANGEARGV
363 	Argv[0] = buf;
364 	Argv[1] = 0;
365 #  endif
366 # endif /* SPT_TYPE != SPT_NONE */
367 }
368 
369 #endif /* SPT_TYPE != SPT_BUILTIN */
370