diff options
Diffstat (limited to 'openbsd-compat/setproctitle.c')
-rw-r--r-- | openbsd-compat/setproctitle.c | 308 |
1 files changed, 111 insertions, 197 deletions
diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c index 07af7e9c0..b41100fc6 100644 --- a/openbsd-compat/setproctitle.c +++ b/openbsd-compat/setproctitle.c | |||
@@ -1,41 +1,34 @@ | |||
1 | /* | 1 | /* Based on conf.c from UCB sendmail 8.8.8 */ |
2 | * Based on src/backend/utils/misc/pg_status.c from | ||
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. | ||
25 | */ | ||
26 | 2 | ||
27 | /*-------------------------------------------------------------------- | 3 | /* |
28 | * ps_status.c | 4 | * Copyright 2003 Damien Miller |
29 | * | 5 | * Copyright (c) 1983, 1995-1997 Eric P. Allman |
30 | * Routines to support changing the ps display of PostgreSQL backends | 6 | * Copyright (c) 1988, 1993 |
31 | * to contain some useful information. Mechanism differs wildly across | 7 | * The Regents of the University of California. All rights reserved. |
32 | * platforms. | ||
33 | * | 8 | * |
34 | * $Header: /var/cvs/openssh/openbsd-compat/setproctitle.c,v 1.5 2003/01/20 02:15:11 djm Exp $ | 9 | * Redistribution and use in source and binary forms, with or without |
10 | * modification, are permitted provided that the following conditions | ||
11 | * are met: | ||
12 | * 1. Redistributions of source code must retain the above copyright | ||
13 | * notice, this list of conditions and the following disclaimer. | ||
14 | * 2. Redistributions in binary form must reproduce the above copyright | ||
15 | * notice, this list of conditions and the following disclaimer in the | ||
16 | * documentation and/or other materials provided with the distribution. | ||
17 | * 3. Neither the name of the University nor the names of its contributors | ||
18 | * may be used to endorse or promote products derived from this software | ||
19 | * without specific prior written permission. | ||
35 | * | 20 | * |
36 | * Copyright 2000 by PostgreSQL Global Development Group | 21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
37 | * various details abducted from various places | 22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
38 | *-------------------------------------------------------------------- | 23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | ||
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
26 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | ||
27 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | ||
28 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | ||
29 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | ||
30 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | ||
31 | * SUCH DAMAGE. | ||
39 | */ | 32 | */ |
40 | 33 | ||
41 | #include "includes.h" | 34 | #include "includes.h" |
@@ -44,200 +37,121 @@ | |||
44 | 37 | ||
45 | #include <unistd.h> | 38 | #include <unistd.h> |
46 | #ifdef HAVE_SYS_PSTAT_H | 39 | #ifdef HAVE_SYS_PSTAT_H |
47 | #include <sys/pstat.h> /* for HP-UX */ | 40 | #include <sys/pstat.h> |
48 | #endif | ||
49 | #ifdef HAVE_PS_STRINGS | ||
50 | #include <machine/vmparam.h> /* for old BSD */ | ||
51 | #include <sys/exec.h> | ||
52 | #endif | 41 | #endif |
53 | 42 | ||
54 | /*------ | 43 | #define SPT_NONE 0 /* don't use it at all */ |
55 | * Alternative ways of updating ps display: | 44 | #define SPT_PSTAT 1 /* cover argv with title information */ |
56 | * | 45 | #define SPT_REUSEARGV 2 /* use pstat(PSTAT_SETCMD, ...) */ |
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 | 46 | ||
74 | #define PS_USE_NONE 0 | 47 | #ifndef SPT_TYPE |
75 | #define PS_USE_PSTAT 1 | 48 | # define SPT_TYPE SPT_NONE |
76 | #define PS_USE_PS_STRINGS 2 | ||
77 | #define PS_USE_CHANGE_ARGV 3 | ||
78 | #define PS_USE_CLOBBER_ARGV 4 | ||
79 | |||
80 | #ifndef SETPROCTITLE_STRATEGY | ||
81 | # define SETPROCTITLE_STRATEGY PS_USE_NONE | ||
82 | #endif | 49 | #endif |
83 | 50 | ||
84 | #ifndef SETPROCTITLE_PS_PADDING | 51 | #ifndef SPT_PADCHAR |
85 | # define SETPROCTITLE_PS_PADDING ' ' | 52 | # define SPT_PADCHAR '\0' |
86 | #endif | 53 | #endif |
87 | #endif /* HAVE_SETPROCTITLE */ | ||
88 | 54 | ||
89 | extern char **environ; | 55 | #if SPT_TYPE == SPT_REUSEARGV |
90 | 56 | static char *argv_start = NULL; | |
91 | /* | 57 | static size_t argv_env_len = 0; |
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 | 58 | #endif |
101 | 59 | ||
102 | /* save the original argv[] location here */ | 60 | #endif /* HAVE_SETPROCTITLE */ |
103 | static int save_argc; | ||
104 | static char **save_argv; | ||
105 | |||
106 | extern char *__progname; | ||
107 | 61 | ||
108 | #ifndef HAVE_SETPROCTITLE | ||
109 | /* | ||
110 | * Call this to update the ps status display to a fixed prefix plus an | ||
111 | * indication of what you're currently doing passed in the argument. | ||
112 | */ | ||
113 | void | 62 | void |
114 | setproctitle(const char *fmt, ...) | 63 | compat_init_setproctitle(int argc, char *argv[]) |
115 | { | 64 | { |
116 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT | 65 | #if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV |
117 | union pstun pst; | 66 | extern char **environ; |
118 | #endif | 67 | char *lastargv = NULL; |
119 | #if SETPROCTITLE_STRATEGY != PS_USE_NONE | 68 | char **envp = environ; |
120 | ssize_t used; | 69 | int i; |
121 | va_list ap; | ||
122 | |||
123 | /* no ps display if you didn't call save_ps_display_args() */ | ||
124 | if (save_argv == NULL) | ||
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 | 70 | ||
132 | /* | 71 | /* |
133 | * Overwrite argv[] to point at appropriate space, if needed | 72 | * NB: This assumes that argv has already been copied out of the |
73 | * way. This is true for sshd, but may not be true for other | ||
74 | * programs. Beware. | ||
134 | */ | 75 | */ |
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 | 76 | ||
140 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | 77 | if (argc == 0 || argv[0] == NULL) |
141 | save_argv[1] = NULL; | 78 | return; |
142 | #endif /* PS_USE_CLOBBER_ARGV */ | 79 | |
80 | /* Fail if we can't allocate room for the new environment */ | ||
81 | for (i = 0; envp[i] != NULL; i++) | ||
82 | ; | ||
83 | if ((environ = malloc(sizeof(*environ) * (i + 1))) == NULL) { | ||
84 | environ = envp; /* put it back */ | ||
85 | return; | ||
86 | } | ||
143 | 87 | ||
144 | /* | 88 | /* |
145 | * Make fixed prefix of ps display. | 89 | * Find the last argv string or environment variable within |
90 | * our process memory area. | ||
146 | */ | 91 | */ |
147 | 92 | for (i = 0; i < argc; i++) { | |
148 | va_start(ap, fmt); | 93 | if (lastargv == NULL || lastargv + 1 == argv[i]) |
149 | if (fmt == NULL) | 94 | lastargv = argv[i] + strlen(argv[i]); |
150 | snprintf(ps_buffer, ps_buffer_size, "%s", __progname); | 95 | } |
151 | else { | 96 | for (i = 0; envp[i] != NULL; i++) { |
152 | used = snprintf(ps_buffer, ps_buffer_size, "%s: ", __progname); | 97 | if (lastargv + 1 == envp[i]) |
153 | if (used == -1 || used >= ps_buffer_size) | 98 | lastargv = envp[i] + strlen(envp[i]); |
154 | used = ps_buffer_size; | ||
155 | vsnprintf(ps_buffer + used, ps_buffer_size - used, fmt, ap); | ||
156 | } | 99 | } |
157 | va_end(ap); | ||
158 | |||
159 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT | ||
160 | pst.pst_command = ps_buffer; | ||
161 | pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); | ||
162 | #endif /* PS_USE_PSTAT */ | ||
163 | |||
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 | 100 | ||
169 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | 101 | argv[1] = NULL; |
170 | /* pad unused memory */ | 102 | argv_start = argv[0]; |
171 | used = strlen(ps_buffer); | 103 | argv_env_len = lastargv - argv[0] - 1; |
172 | memset(ps_buffer + used, SETPROCTITLE_PS_PADDING, | ||
173 | ps_buffer_size - used); | ||
174 | #endif /* PS_USE_CLOBBER_ARGV */ | ||
175 | 104 | ||
176 | #endif /* PS_USE_NONE */ | 105 | /* |
106 | * Copy environment | ||
107 | * XXX - will truncate env on strdup fail | ||
108 | */ | ||
109 | for (i = 0; envp[i] != NULL; i++) | ||
110 | environ[i] = strdup(envp[i]); | ||
111 | environ[i] = NULL; | ||
112 | #endif /* SPT_REUSEARGV */ | ||
177 | } | 113 | } |
178 | 114 | ||
179 | #endif /* HAVE_SETPROCTITLE */ | 115 | #ifndef 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 | 116 | void |
190 | compat_init_setproctitle(int argc, char *argv[]) | 117 | setproctitle(const char *fmt, ...) |
191 | { | 118 | { |
192 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV | 119 | #if SPT_TYPE != SPT_NONE |
193 | char *end_of_area = NULL; | 120 | va_list ap; |
194 | char **new_environ; | 121 | char buf[1024]; |
195 | int i; | 122 | size_t len; |
123 | extern char *__progname; | ||
124 | #if SPT_TYPE == SPT_PSTAT | ||
125 | union pstun pst; | ||
196 | #endif | 126 | #endif |
197 | 127 | ||
198 | save_argc = argc; | 128 | #if SPT_TYPE == SPT_REUSEARGV |
199 | save_argv = argv; | 129 | if (argv_env_len <= 0) |
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; | 130 | return; |
220 | } | 131 | #endif |
221 | 132 | ||
222 | /* | 133 | strlcpy(buf, __progname, sizeof(buf)); |
223 | * check for contiguous environ strings following argv | 134 | |
224 | */ | 135 | va_start(ap, fmt); |
225 | for (i = 0; environ[i] != NULL; i++) { | 136 | if (fmt != NULL) { |
226 | if (end_of_area + 1 == environ[i]) | 137 | len = strlcat(buf, ": ", sizeof(buf)); |
227 | end_of_area = environ[i] + strlen(environ[i]); | 138 | if (len < sizeof(buf)) |
139 | vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); | ||
228 | } | 140 | } |
141 | va_end(ap); | ||
229 | 142 | ||
230 | ps_buffer = argv[0]; | 143 | #if SPT_TYPE == SPT_PSTAT |
231 | ps_buffer_size = end_of_area - argv[0] - 1; | 144 | pst.pst_command = buf; |
145 | pstat(PSTAT_SETCMD, pst, strlen(buf), 0, 0); | ||
146 | #elif SPT_TYPE == SPT_REUSEARGV | ||
147 | /* debug("setproctitle: copy \"%s\" into len %d", | ||
148 | buf, argv_env_len); */ | ||
149 | len = strlcpy(argv_start, buf, argv_env_len); | ||
150 | for(; len < argv_env_len; len++) | ||
151 | argv_start[len] = SPT_PADCHAR; | ||
152 | #endif | ||
232 | 153 | ||
233 | /* | 154 | #endif /* SPT_NONE */ |
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 | } | 155 | } |
243 | 156 | ||
157 | #endif /* HAVE_SETPROCTITLE */ | ||