diff options
Diffstat (limited to 'openbsd-compat/setproctitle.c')
-rw-r--r-- | openbsd-compat/setproctitle.c | 281 |
1 files changed, 211 insertions, 70 deletions
diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c index e165dd13c..07af7e9c0 100644 --- a/openbsd-compat/setproctitle.c +++ b/openbsd-compat/setproctitle.c | |||
@@ -1,102 +1,243 @@ | |||
1 | /* | 1 | /* |
2 | * Modified for OpenSSH by Kevin Steves | 2 | * Based on src/backend/utils/misc/pg_status.c from |
3 | * October 2000 | 3 | * PostgreSQL Database Management System |
4 | * | ||
5 | * Portions Copyright (c) 1996-2001, The PostgreSQL Global Development Group | ||
6 | * | ||
7 | * Portions Copyright (c) 1994, The Regents of the University of California | ||
8 | * | ||
9 | * Permission to use, copy, modify, and distribute this software and its | ||
10 | * documentation for any purpose, without fee, and without a written agreement | ||
11 | * is hereby granted, provided that the above copyright notice and this | ||
12 | * paragraph and the following two paragraphs appear in all copies. | ||
13 | * | ||
14 | * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR | ||
15 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING | ||
16 | * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS | ||
17 | * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE | ||
18 | * POSSIBILITY OF SUCH DAMAGE. | ||
19 | * | ||
20 | * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, | ||
21 | * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY | ||
22 | * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS | ||
23 | * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO | ||
24 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. | ||
4 | */ | 25 | */ |
5 | 26 | ||
6 | /* | 27 | /*-------------------------------------------------------------------- |
7 | * Copyright (c) 1994, 1995 Christopher G. Demetriou | 28 | * ps_status.c |
8 | * All rights reserved. | 29 | * |
30 | * Routines to support changing the ps display of PostgreSQL backends | ||
31 | * to contain some useful information. Mechanism differs wildly across | ||
32 | * platforms. | ||
9 | * | 33 | * |
10 | * Redistribution and use in source and binary forms, with or without | 34 | * $Header: /var/cvs/openssh/openbsd-compat/setproctitle.c,v 1.5 2003/01/20 02:15:11 djm Exp $ |
11 | * modification, are permitted provided that the following conditions | ||
12 | * are met: | ||
13 | * 1. Redistributions of source code must retain the above copyright | ||
14 | * notice, this list of conditions and the following disclaimer. | ||
15 | * 2. Redistributions in binary form must reproduce the above copyright | ||
16 | * notice, this list of conditions and the following disclaimer in the | ||
17 | * documentation and/or other materials provided with the distribution. | ||
18 | * 3. All advertising materials mentioning features or use of this software | ||
19 | * must display the following acknowledgement: | ||
20 | * This product includes software developed by Christopher G. Demetriou | ||
21 | * for the NetBSD Project. | ||
22 | * 4. The name of the author may not be used to endorse or promote products | ||
23 | * derived from this software without specific prior written permission | ||
24 | * | 35 | * |
25 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | 36 | * Copyright 2000 by PostgreSQL Global Development Group |
26 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | 37 | * various details abducted from various places |
27 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | 38 | *-------------------------------------------------------------------- |
28 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
29 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
30 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
31 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
32 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
33 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
34 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
35 | */ | 39 | */ |
36 | 40 | ||
37 | #if defined(LIBC_SCCS) && !defined(lint) | ||
38 | static char rcsid[] = "$OpenBSD: setproctitle.c,v 1.8 2001/11/06 19:21:40 art Exp $"; | ||
39 | #endif /* LIBC_SCCS and not lint */ | ||
40 | |||
41 | #include "includes.h" | 41 | #include "includes.h" |
42 | 42 | ||
43 | #ifndef HAVE_SETPROCTITLE | 43 | #ifndef HAVE_SETPROCTITLE |
44 | 44 | ||
45 | #define SPT_NONE 0 | 45 | #include <unistd.h> |
46 | #define SPT_PSTAT 1 | 46 | #ifdef HAVE_SYS_PSTAT_H |
47 | #include <sys/pstat.h> /* for HP-UX */ | ||
48 | #endif | ||
49 | #ifdef HAVE_PS_STRINGS | ||
50 | #include <machine/vmparam.h> /* for old BSD */ | ||
51 | #include <sys/exec.h> | ||
52 | #endif | ||
53 | |||
54 | /*------ | ||
55 | * Alternative ways of updating ps display: | ||
56 | * | ||
57 | * SETPROCTITLE_STRATEGY == PS_USE_PSTAT | ||
58 | * use the pstat(PSTAT_SETCMD, ) | ||
59 | * (HPUX) | ||
60 | * SETPROCTITLE_STRATEGY == PS_USE_PS_STRINGS | ||
61 | * assign PS_STRINGS->ps_argvstr = "string" | ||
62 | * (some BSD systems) | ||
63 | * SETPROCTITLE_STRATEGY == PS_USE_CHANGE_ARGV | ||
64 | * assign argv[0] = "string" | ||
65 | * (some other BSD systems) | ||
66 | * SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | ||
67 | * write over the argv and environment area | ||
68 | * (most SysV-like systems) | ||
69 | * SETPROCTITLE_STRATEGY == PS_USE_NONE | ||
70 | * don't update ps display | ||
71 | * (This is the default, as it is safest.) | ||
72 | */ | ||
73 | |||
74 | #define PS_USE_NONE 0 | ||
75 | #define PS_USE_PSTAT 1 | ||
76 | #define PS_USE_PS_STRINGS 2 | ||
77 | #define PS_USE_CHANGE_ARGV 3 | ||
78 | #define PS_USE_CLOBBER_ARGV 4 | ||
47 | 79 | ||
48 | #ifndef SPT_TYPE | 80 | #ifndef SETPROCTITLE_STRATEGY |
49 | #define SPT_TYPE SPT_NONE | 81 | # define SETPROCTITLE_STRATEGY PS_USE_NONE |
50 | #endif | 82 | #endif |
51 | 83 | ||
52 | #if SPT_TYPE == SPT_PSTAT | 84 | #ifndef SETPROCTITLE_PS_PADDING |
53 | #include <sys/param.h> | 85 | # define SETPROCTITLE_PS_PADDING ' ' |
54 | #include <sys/pstat.h> | 86 | #endif |
55 | #endif /* SPT_TYPE == SPT_PSTAT */ | 87 | #endif /* HAVE_SETPROCTITLE */ |
56 | 88 | ||
57 | #define MAX_PROCTITLE 2048 | 89 | extern char **environ; |
90 | |||
91 | /* | ||
92 | * argv clobbering uses existing argv space, all other methods need a buffer | ||
93 | */ | ||
94 | #if SETPROCTITLE_STRATEGY != PS_USE_CLOBBER_ARGV | ||
95 | static char ps_buffer[256]; | ||
96 | static const size_t ps_buffer_size = sizeof(ps_buffer); | ||
97 | #else | ||
98 | static char *ps_buffer; /* will point to argv area */ | ||
99 | static size_t ps_buffer_size; /* space determined at run time */ | ||
100 | #endif | ||
101 | |||
102 | /* save the original argv[] location here */ | ||
103 | static int save_argc; | ||
104 | static char **save_argv; | ||
58 | 105 | ||
59 | extern char *__progname; | 106 | extern char *__progname; |
60 | 107 | ||
108 | #ifndef HAVE_SETPROCTITLE | ||
61 | /* | 109 | /* |
62 | * Set Process Title (SPT) defines. Modeled after sendmail's | 110 | * Call this to update the ps status display to a fixed prefix plus an |
63 | * SPT type definition strategy. | 111 | * indication of what you're currently doing passed in the argument. |
64 | * | ||
65 | * SPT_TYPE: | ||
66 | * | ||
67 | * SPT_NONE: Don't set the process title. Default. | ||
68 | * SPT_PSTAT: Use pstat(PSTAT_SETCMD). HP-UX specific. | ||
69 | */ | 112 | */ |
70 | |||
71 | void | 113 | void |
72 | setproctitle(const char *fmt, ...) | 114 | setproctitle(const char *fmt, ...) |
73 | { | 115 | { |
74 | #if SPT_TYPE != SPT_NONE | 116 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT |
117 | union pstun pst; | ||
118 | #endif | ||
119 | #if SETPROCTITLE_STRATEGY != PS_USE_NONE | ||
120 | ssize_t used; | ||
75 | va_list ap; | 121 | va_list ap; |
76 | |||
77 | char buf[MAX_PROCTITLE]; | ||
78 | size_t used; | ||
79 | 122 | ||
80 | #if SPT_TYPE == SPT_PSTAT | 123 | /* no ps display if you didn't call save_ps_display_args() */ |
81 | union pstun pst; | 124 | if (save_argv == NULL) |
82 | #endif /* SPT_TYPE == SPT_PSTAT */ | 125 | return; |
126 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | ||
127 | /* If ps_buffer is a pointer, it might still be null */ | ||
128 | if (ps_buffer == NULL) | ||
129 | return; | ||
130 | #endif /* PS_USE_CLOBBER_ARGV */ | ||
131 | |||
132 | /* | ||
133 | * Overwrite argv[] to point at appropriate space, if needed | ||
134 | */ | ||
135 | #if SETPROCTITLE_STRATEGY == PS_USE_CHANGE_ARGV | ||
136 | save_argv[0] = ps_buffer; | ||
137 | save_argv[1] = NULL; | ||
138 | #endif /* PS_USE_CHANGE_ARGV */ | ||
139 | |||
140 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | ||
141 | save_argv[1] = NULL; | ||
142 | #endif /* PS_USE_CLOBBER_ARGV */ | ||
143 | |||
144 | /* | ||
145 | * Make fixed prefix of ps display. | ||
146 | */ | ||
83 | 147 | ||
84 | va_start(ap, fmt); | 148 | va_start(ap, fmt); |
85 | if (fmt != NULL) { | 149 | if (fmt == NULL) |
86 | used = snprintf(buf, MAX_PROCTITLE, "%s: ", __progname); | 150 | snprintf(ps_buffer, ps_buffer_size, "%s", __progname); |
87 | if (used >= MAX_PROCTITLE) | 151 | else { |
88 | used = MAX_PROCTITLE - 1; | 152 | used = snprintf(ps_buffer, ps_buffer_size, "%s: ", __progname); |
89 | (void)vsnprintf(buf + used, MAX_PROCTITLE - used, fmt, ap); | 153 | if (used == -1 || used >= ps_buffer_size) |
90 | } else | 154 | used = ps_buffer_size; |
91 | (void)snprintf(buf, MAX_PROCTITLE, "%s", __progname); | 155 | vsnprintf(ps_buffer + used, ps_buffer_size - used, fmt, ap); |
156 | } | ||
92 | va_end(ap); | 157 | va_end(ap); |
93 | used = strlen(buf); | ||
94 | 158 | ||
95 | #if SPT_TYPE == SPT_PSTAT | 159 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT |
96 | pst.pst_command = buf; | 160 | pst.pst_command = ps_buffer; |
97 | pstat(PSTAT_SETCMD, pst, used, 0, 0); | 161 | pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); |
98 | #endif /* SPT_TYPE == SPT_PSTAT */ | 162 | #endif /* PS_USE_PSTAT */ |
99 | 163 | ||
100 | #endif /* SPT_TYPE != SPT_NONE */ | 164 | #if SETPROCTITLE_STRATEGY == PS_USE_PS_STRINGS |
165 | PS_STRINGS->ps_nargvstr = 1; | ||
166 | PS_STRINGS->ps_argvstr = ps_buffer; | ||
167 | #endif /* PS_USE_PS_STRINGS */ | ||
168 | |||
169 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | ||
170 | /* pad unused memory */ | ||
171 | used = strlen(ps_buffer); | ||
172 | memset(ps_buffer + used, SETPROCTITLE_PS_PADDING, | ||
173 | ps_buffer_size - used); | ||
174 | #endif /* PS_USE_CLOBBER_ARGV */ | ||
175 | |||
176 | #endif /* PS_USE_NONE */ | ||
101 | } | 177 | } |
178 | |||
102 | #endif /* HAVE_SETPROCTITLE */ | 179 | #endif /* HAVE_SETPROCTITLE */ |
180 | |||
181 | /* | ||
182 | * Call this early in startup to save the original argc/argv values. | ||
183 | * | ||
184 | * argv[] will not be overwritten by this routine, but may be overwritten | ||
185 | * during setproctitle. Also, the physical location of the environment | ||
186 | * strings may be moved, so this should be called before any code that | ||
187 | * might try to hang onto a getenv() result. | ||
188 | */ | ||
189 | void | ||
190 | compat_init_setproctitle(int argc, char *argv[]) | ||
191 | { | ||
192 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | ||
193 | char *end_of_area = NULL; | ||
194 | char **new_environ; | ||
195 | int i; | ||
196 | #endif | ||
197 | |||
198 | save_argc = argc; | ||
199 | save_argv = argv; | ||
200 | |||
201 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | ||
202 | /* | ||
203 | * If we're going to overwrite the argv area, count the available | ||
204 | * space. Also move the environment to make additional room. | ||
205 | */ | ||
206 | |||
207 | /* | ||
208 | * check for contiguous argv strings | ||
209 | */ | ||
210 | for (i = 0; i < argc; i++) { | ||
211 | if (i == 0 || end_of_area + 1 == argv[i]) | ||
212 | end_of_area = argv[i] + strlen(argv[i]); | ||
213 | } | ||
214 | |||
215 | /* probably can't happen? */ | ||
216 | if (end_of_area == NULL) { | ||
217 | ps_buffer = NULL; | ||
218 | ps_buffer_size = 0; | ||
219 | return; | ||
220 | } | ||
221 | |||
222 | /* | ||
223 | * check for contiguous environ strings following argv | ||
224 | */ | ||
225 | for (i = 0; environ[i] != NULL; i++) { | ||
226 | if (end_of_area + 1 == environ[i]) | ||
227 | end_of_area = environ[i] + strlen(environ[i]); | ||
228 | } | ||
229 | |||
230 | ps_buffer = argv[0]; | ||
231 | ps_buffer_size = end_of_area - argv[0] - 1; | ||
232 | |||
233 | /* | ||
234 | * Duplicate and move the environment out of the way | ||
235 | */ | ||
236 | new_environ = malloc(sizeof(char *) * (i + 1)); | ||
237 | for (i = 0; environ[i] != NULL; i++) | ||
238 | new_environ[i] = strdup(environ[i]); | ||
239 | new_environ[i] = NULL; | ||
240 | environ = new_environ; | ||
241 | #endif /* PS_USE_CLOBBER_ARGV */ | ||
242 | } | ||
243 | |||