1 /*
2 * Originally taken by Andy Igoshin <ai@vsu.ru> from
3 * Sendmail 8.8.8 by Eric Allman <eric@sendmail.org>.
4 * Edited a bit by Dima Maloff for Binkd/0.9.3
5 */
6 /*
7 * $Id: setpttl.c,v 2.3 2003/12/02 13:02:27 gul Exp $
8 *
9 * Revision history:
10 * $Log: setpttl.c,v $
11 * Revision 2.3 2003/12/02 13:02:27 gul
12 * Use own snprintf() instead of sprintf() if no HAVE_SNPRINTF
13 *
14 * Revision 2.2 2003/02/28 20:39:09 gul
15 * Code cleanup:
16 * change "()" to "(void)" in function declarations;
17 * change C++-style comments to C-style
18 *
19 * Revision 2.1 2001/10/27 08:31:30 gul
20 * minor fix
21 *
22 * Revision 2.0 2001/01/10 12:12:40 gul
23 * Binkd is under CVS again
24 *
25 *
26 */
27
28 #include <stdlib.h>
29 #include <stdio.h>
30 #include <stdarg.h>
31 #include <string.h>
32
33 /*
34 * First -- map autoconf's values to sendmail's
35 */
36 #ifdef HAVE_SETPROCTITLE /* We have built-in setproctitle() */
37 #define SPT_TYPE SPT_BUILTIN
38 #endif
39
40 /*
41 * (xalloc.c) allocate memory or log error
42 */
43 extern void *xalloc (size_t size);
44 extern void *xstrdup (const char *str);
45
46
47 #define MAXLINE 2048
48 #define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf))
49
50
51 /*
52 ** SETPROCTITLE -- set process title for ps
53 **
54 ** Parameters:
55 ** fmt -- a printf style format string.
56 ** a, b, c -- possible parameters to fmt.
57 **
58 ** Returns:
59 ** none.
60 **
61 ** Side Effects:
62 ** Clobbers argv of our main procedure so ps(1) will
63 ** display the title.
64 */
65
66 #define SPT_NONE 0 /* don't use it at all */
67 #define SPT_REUSEARGV 1 /* cover argv with title information */
68 #define SPT_BUILTIN 2 /* use libc builtin */
69 #define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */
70 #define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */
71 #define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */
72 #define SPT_SCO 6 /* write kernel u. area */
73 #define SPT_CHANGEARGV 7 /* write our own strings into argv[] */
74
75 #ifndef SPT_TYPE
76 # define SPT_TYPE SPT_REUSEARGV
77 #endif
78
79 #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN
80
81 # if SPT_TYPE == SPT_PSTAT
82 # include <sys/pstat.h>
83 # endif
84 # if SPT_TYPE == SPT_PSSTRINGS
85 # include <machine/vmparam.h>
86 # include <sys/exec.h>
87 # ifndef PS_STRINGS /* hmmmm.... apparently not available after all */
88 # undef SPT_TYPE
89 # define SPT_TYPE SPT_REUSEARGV
90 # else
91 # ifndef NKPDE /* FreeBSD 2.0 */
92 # define NKPDE 63
93 typedef unsigned int *pt_entry_t;
94 # endif
95 # endif
96 # endif
97
98 # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV
99 # define SETPROC_STATIC static
100 # else
101 # define SETPROC_STATIC
102 # endif
103
104 # if SPT_TYPE == SPT_SYSMIPS
105 # include <sys/sysmips.h>
106 # include <sys/sysnews.h>
107 # endif
108
109 # if SPT_TYPE == SPT_SCO
110 # include <sys/immu.h>
111 # include <sys/dir.h>
112 # include <sys/user.h>
113 # include <sys/fs/s5param.h>
114 # if PSARGSZ > MAXLINE
115 # define SPT_BUFSIZE PSARGSZ
116 # endif
117 # endif
118
119 # ifndef SPT_PADCHAR
120 /*# define SPT_PADCHAR ' ' */
121 # define SPT_PADCHAR '\0'
122 # endif
123
124 # ifndef SPT_BUFSIZE
125 # define SPT_BUFSIZE MAXLINE
126 # endif
127
128 #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */
129
130 /*
131 ** Pointers for setproctitle.
132 ** This allows "ps" listings to give more useful information.
133 */
134
135 char **Argv = NULL; /* pointer to argument vector */
136 char *LastArgv = NULL; /* end of argv */
137
138 void
initsetproctitle(argc,argv,envp)139 initsetproctitle(argc, argv, envp)
140 int argc;
141 char **argv;
142 char **envp;
143 {
144 register int i, envpsize = 0;
145 extern char **environ;
146
147 /*
148 ** Move the environment so setproctitle can use the space at
149 ** the top of memory.
150 */
151
152 for (i = 0; envp[i] != NULL; i++)
153 envpsize += strlen(envp[i]) + 1;
154 environ = (char **) xalloc(sizeof (char *) * (i + 1));
155 for (i = 0; envp[i] != NULL; i++)
156 environ[i] = xstrdup(envp[i]);
157 environ[i] = NULL;
158
159 /*
160 ** Save start and extent of argv for setproctitle.
161 */
162
163 Argv = argv;
164
165 /*
166 ** Find the last environment variable within sendmail's
167 ** process memory area.
168 */
169 while (i > 0 && (envp[i - 1] < argv[0] ||
170 envp[i - 1] > (argv[argc - 1] +
171 strlen(argv[argc - 1]) + 1 + envpsize)))
172 i--;
173
174 if (i > 0)
175 LastArgv = envp[i - 1] + strlen(envp[i - 1]);
176 else
177 LastArgv = argv[argc - 1] + strlen(argv[argc - 1]);
178 }
179
180 #if SPT_TYPE != SPT_BUILTIN
181
182
setproctitle(const char * fmt,...)183 void setproctitle(const char *fmt, ...)
184 {
185 # if SPT_TYPE != SPT_NONE
186 register char *p;
187 register int i;
188 SETPROC_STATIC char buf[SPT_BUFSIZE];
189 va_list ap;
190 # if SPT_TYPE == SPT_PSTAT
191 union pstun pst;
192 # endif
193 # if SPT_TYPE == SPT_SCO
194 off_t seek_off;
195 static int kmem = -1;
196 static int kmempid = -1;
197 struct user u;
198 # endif
199
200 p = buf;
201
202 /* print sendmail: heading for grep */
203 (void) strcpy(p, "binkd: ");
204 p += strlen(p);
205
206 /* print the argument string */
207 va_start(ap, fmt);
208 (void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap);
209 va_end(ap);
210
211 i = strlen(buf);
212
213 # if SPT_TYPE == SPT_PSTAT
214 pst.pst_command = buf;
215 pstat(PSTAT_SETCMD, pst, i, 0, 0);
216 # endif
217 # if SPT_TYPE == SPT_PSSTRINGS
218 PS_STRINGS->ps_nargvstr = 1;
219 PS_STRINGS->ps_argvstr = buf;
220 # endif
221 # if SPT_TYPE == SPT_SYSMIPS
222 sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf);
223 # endif
224 # if SPT_TYPE == SPT_SCO
225 if (kmem < 0 || kmempid != getpid())
226 {
227 if (kmem >= 0)
228 close(kmem);
229 kmem = open(_PATH_KMEM, O_RDWR, 0);
230 if (kmem < 0)
231 return;
232 (void) fcntl(kmem, F_SETFD, 1);
233 kmempid = getpid();
234 }
235 buf[PSARGSZ - 1] = '\0';
236 seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u;
237 if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off)
238 (void) write(kmem, buf, PSARGSZ);
239 # endif
240 # if SPT_TYPE == SPT_REUSEARGV
241 if (LastArgv == NULL)
242 return;
243
244 if (i > LastArgv - Argv[0] - 2)
245 {
246 i = LastArgv - Argv[0] - 2;
247 buf[i] = '\0';
248 }
249 (void) strcpy(Argv[0], buf);
250 p = &Argv[0][i];
251 while (p < LastArgv)
252 *p++ = SPT_PADCHAR;
253 Argv[1] = NULL;
254 # endif
255 # if SPT_TYPE == SPT_CHANGEARGV
256 Argv[0] = buf;
257 Argv[1] = 0;
258 # endif
259 # endif /* SPT_TYPE != SPT_NONE */
260 }
261
262 #endif /* SPT_TYPE != SPT_BUILTIN */
263