1 /*
2 * setproctitle()-related routines in this file are derived from Sendmail
3 * 8.13.5 which is:
4 *
5 * Copyright (c) 1998-2005 Sendmail, Inc. and its suppliers.
6 * All rights reserved.
7 * Copyright (c) 1983, 1995-1997 Eric P. Allman. All rights reserved.
8 * Copyright (c) 1988, 1993
9 * The Regents of the University of California. All rights reserved.
10 *
11 * By using this file, you agree to the terms and conditions set
12 * forth in the LICENSE file which can be found at the top level of
13 * the sendmail distribution.
14 *
15 */
16
17 #include "pmacct.h"
18
19 /*
20 * SETPROCTITLE -- set process title for ps
21 */
22
23 #define SPT_NONE 0 /* don't use it at all */
24 #define SPT_REUSEARGV 1 /* cover argv with title information */
25 #define SPT_BUILTIN 2 /* use libc builtin */
26 #define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */
27
28 #include "setproctitle.h"
29
30 #define MAXLINE (2*LONGLONGSRVBUFLEN)
31 #define SPACELEFT(x) (sizeof(x)-strlen(x))
32
33 #if defined PROGNAME && SPT_TYPE == SPT_REUSEARGV
34 extern char *__progname;
35 #endif
36
37 char pmacctd_globstr[] = "pmacctd\0";
38 char nfacctd_globstr[] = "nfacctd\0";
39 char sfacctd_globstr[] = "sfacctd\0";
40 char uacctd_globstr[] = "uacctd\0";
41 char pmtele_globstr[] = "pmtelemetryd\0";
42 char pmbgpd_globstr[] = "pmbgpd\0";
43 char pmbmpd_globstr[] = "pmbmpd\0";
44
45 /*
46 * NEWSTR -- Create a copy of a C string
47 */
48
spt_newstr(s)49 char *spt_newstr(s)
50 const char *s;
51 {
52 size_t l;
53 char *n;
54
55 l = strlen(s);
56 n = malloc(l + 1);
57 strlcpy(n, s, l + 1);
58
59 return n;
60 }
61
62 #ifndef SPT_TYPE
63 # define SPT_TYPE SPT_NONE
64 #endif /* ! SPT_TYPE */
65
66
67 #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
68
69 #if SPT_TYPE == SPT_PSTAT
70 # include <sys/pstat.h>
71 #endif /* SPT_TYPE == SPT_PSTAT */
72
73 #ifndef SPT_PADCHAR
74 # define SPT_PADCHAR ' '
75 #endif /* ! SPT_PADCHAR */
76
77 #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
78
79 #ifndef SPT_BUFSIZE
80 # define SPT_BUFSIZE MAXLINE
81 #endif /* ! SPT_BUFSIZE */
82
83 /*
84 * Pointers for setproctitle.
85 * This allows "ps" listings to give more useful information.
86 */
87
88 static char **Argv = NULL; /* pointer to argument vector */
89 static char *LastArgv = NULL; /* end of argv */
90
91 void
initsetproctitle(argc,argv,envp)92 initsetproctitle(argc, argv, envp)
93 int argc;
94 char **argv;
95 char **envp;
96 {
97 register int i;
98 extern char **environ;
99
100 /*
101 ** Move the environment so setproctitle can use the space at
102 ** the top of memory.
103 */
104
105 if (envp != NULL)
106 {
107 for (i = 0; envp[i] != NULL; i++)
108 continue;
109 environ = (char **) malloc(sizeof (char *) * (i + 1));
110 for (i = 0; envp[i] != NULL; i++)
111 environ[i] = spt_newstr(envp[i]);
112 environ[i] = NULL;
113 }
114
115 /*
116 ** Save start and extent of argv for setproctitle.
117 */
118
119 Argv = argv;
120
121 /*
122 ** Determine how much space we can use for setproctitle.
123 ** Use all contiguous argv and envp pointers starting at argv[0]
124 */
125
126 for (i = 0; i < argc; i++)
127 {
128 if (i == 0 || LastArgv + 1 == argv[i])
129 LastArgv = argv[i] + strlen(argv[i]);
130 }
131 for (i = 0; LastArgv != NULL && envp != NULL && envp[i] != NULL; i++)
132 {
133 if (LastArgv + 1 == envp[i])
134 LastArgv = envp[i] + strlen(envp[i]);
135 }
136
137 #if defined PROGNAME && SPT_TYPE == SPT_REUSEARGV
138 if (config.uacctd_group) __progname = uacctd_globstr; /* XXX: hack */
139 else if (config.acct_type == ACCT_PM) __progname = pmacctd_globstr;
140 else if (config.acct_type == ACCT_NF) __progname = nfacctd_globstr;
141 else if (config.acct_type == ACCT_SF) __progname = sfacctd_globstr;
142 else if (config.acct_type == ACCT_PMTELE) __progname = pmtele_globstr;
143 else if (config.acct_type == ACCT_PMBGP) __progname = pmbgpd_globstr;
144 else if (config.acct_type == ACCT_PMBMP) __progname = pmbmpd_globstr;
145 #endif
146 }
147
148 #if SPT_TYPE != SPT_BUILTIN
149
150 /*VARARGS1*/
151 static void
152 # ifdef __STDC__
setproctitle(const char * fmt,...)153 setproctitle(const char *fmt, ...)
154 # else /* __STDC__ */
155 setproctitle(fmt, va_alist)
156 const char *fmt;
157 va_dcl
158 # endif /* __STDC__ */
159 {
160 # if SPT_TYPE != SPT_NONE
161 register int i;
162 register char *p;
163 char buf[SPT_BUFSIZE];
164 va_list ap;
165 # if SPT_TYPE == SPT_PSTAT
166 union pstun pst;
167 # endif /* SPT_TYPE == SPT_PSTAT */
168
169 memset(buf, 0, SPT_BUFSIZE);
170 p = buf;
171 va_start(ap, fmt);
172 vsnprintf(p, SPACELEFT(buf), fmt, ap);
173 va_end(ap);
174
175 i = (int) strlen(buf);
176 if (i < 0) return;
177
178 # if SPT_TYPE == SPT_PSTAT
179 pst.pst_command = buf;
180 pstat(PSTAT_SETCMD, pst, i, 0, 0);
181 # endif /* SPT_TYPE == SPT_PSTAT */
182 # if SPT_TYPE == SPT_REUSEARGV
183 if (LastArgv == NULL)
184 return;
185
186 if (i > (LastArgv - Argv[0]) - 2)
187 {
188 i = (LastArgv - Argv[0]) - 2;
189 buf[i] = '\0';
190 }
191 (void) strlcpy(Argv[0], buf, i + 1);
192 p = &Argv[0][i];
193 while (p < LastArgv)
194 *p++ = SPT_PADCHAR;
195 Argv[1] = NULL;
196 # endif /* SPT_TYPE == SPT_REUSEARGV */
197 # endif /* SPT_TYPE != SPT_NONE */
198 }
199
200 #endif /* SPT_TYPE != SPT_BUILTIN */
201 /*
202 * PM_SETPROCTITLE -- set process task and set process title for ps
203 */
204
205 /*VARARGS2*/
206 void
207 #ifdef __STDC__
pm_setproctitle(const char * fmt,...)208 pm_setproctitle(const char *fmt, ...)
209 #else /* __STDC__ */
210 pm_setproctitle(fmt, va_alist)
211 const char *fmt;
212 va_dcl
213 #endif /* __STDC__ */
214 {
215 char buf[SPT_BUFSIZE];
216 char prefix[16];
217 va_list ap;
218
219 memset(prefix, 0, sizeof(prefix));
220 memset(buf, 0, sizeof(buf));
221
222 if (config.uacctd_group) strcpy(prefix, uacctd_globstr); /* XXX: hack */
223 else if (config.acct_type == ACCT_PM) strcpy(prefix, pmacctd_globstr);
224 else if (config.acct_type == ACCT_NF) strcpy(prefix, nfacctd_globstr);
225 else if (config.acct_type == ACCT_SF) strcpy(prefix, sfacctd_globstr);
226 else if (config.acct_type == ACCT_PMTELE) strcpy(prefix, pmtele_globstr);
227 else if (config.acct_type == ACCT_PMBGP) strcpy(prefix, pmbgpd_globstr);
228 else if (config.acct_type == ACCT_PMBMP) strcpy(prefix, pmbmpd_globstr);
229
230 va_start(ap, fmt);
231 vsnprintf(buf, sizeof(buf), fmt, ap);
232 va_end(ap);
233
234 #if SPT_TYPE != SPT_BUILTIN
235 setproctitle("%s: %s", prefix, buf);
236 #else
237 setproctitle("%s", buf);
238 #endif
239 }
240
241