diff options
Diffstat (limited to 'openbsd-compat/setproctitle.c')
-rw-r--r-- | openbsd-compat/setproctitle.c | 308 |
1 files changed, 197 insertions, 111 deletions
diff --git a/openbsd-compat/setproctitle.c b/openbsd-compat/setproctitle.c index b41100fc6..07af7e9c0 100644 --- a/openbsd-compat/setproctitle.c +++ b/openbsd-compat/setproctitle.c | |||
@@ -1,34 +1,41 @@ | |||
1 | /* Based on conf.c from UCB sendmail 8.8.8 */ | ||
2 | |||
3 | /* | 1 | /* |
4 | * Copyright 2003 Damien Miller | 2 | * Based on src/backend/utils/misc/pg_status.c from |
5 | * Copyright (c) 1983, 1995-1997 Eric P. Allman | 3 | * PostgreSQL Database Management System |
6 | * Copyright (c) 1988, 1993 | 4 | * |
7 | * The Regents of the University of California. All rights reserved. | 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 | |||
27 | /*-------------------------------------------------------------------- | ||
28 | * ps_status.c | ||
8 | * | 29 | * |
9 | * Redistribution and use in source and binary forms, with or without | 30 | * Routines to support changing the ps display of PostgreSQL backends |
10 | * modification, are permitted provided that the following conditions | 31 | * to contain some useful information. Mechanism differs wildly across |
11 | * are met: | 32 | * platforms. |
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. | ||
20 | * | 33 | * |
21 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND | 34 | * $Header: /var/cvs/openssh/openbsd-compat/setproctitle.c,v 1.5 2003/01/20 02:15:11 djm Exp $ |
22 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | 35 | * |
23 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 36 | * Copyright 2000 by PostgreSQL Global Development Group |
24 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE | 37 | * various details abducted from various places |
25 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | 38 | *-------------------------------------------------------------------- |
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. | ||
32 | */ | 39 | */ |
33 | 40 | ||
34 | #include "includes.h" | 41 | #include "includes.h" |
@@ -37,121 +44,200 @@ | |||
37 | 44 | ||
38 | #include <unistd.h> | 45 | #include <unistd.h> |
39 | #ifdef HAVE_SYS_PSTAT_H | 46 | #ifdef HAVE_SYS_PSTAT_H |
40 | #include <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> | ||
41 | #endif | 52 | #endif |
42 | 53 | ||
43 | #define SPT_NONE 0 /* don't use it at all */ | 54 | /*------ |
44 | #define SPT_PSTAT 1 /* cover argv with title information */ | 55 | * Alternative ways of updating ps display: |
45 | #define SPT_REUSEARGV 2 /* use pstat(PSTAT_SETCMD, ...) */ | 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 | */ | ||
46 | 73 | ||
47 | #ifndef SPT_TYPE | 74 | #define PS_USE_NONE 0 |
48 | # define SPT_TYPE SPT_NONE | 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 | ||
79 | |||
80 | #ifndef SETPROCTITLE_STRATEGY | ||
81 | # define SETPROCTITLE_STRATEGY PS_USE_NONE | ||
49 | #endif | 82 | #endif |
50 | 83 | ||
51 | #ifndef SPT_PADCHAR | 84 | #ifndef SETPROCTITLE_PS_PADDING |
52 | # define SPT_PADCHAR '\0' | 85 | # define SETPROCTITLE_PS_PADDING ' ' |
53 | #endif | 86 | #endif |
87 | #endif /* HAVE_SETPROCTITLE */ | ||
54 | 88 | ||
55 | #if SPT_TYPE == SPT_REUSEARGV | 89 | extern char **environ; |
56 | static char *argv_start = NULL; | 90 | |
57 | static size_t argv_env_len = 0; | 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 */ | ||
58 | #endif | 100 | #endif |
59 | 101 | ||
60 | #endif /* HAVE_SETPROCTITLE */ | 102 | /* save the original argv[] location here */ |
103 | static int save_argc; | ||
104 | static char **save_argv; | ||
105 | |||
106 | extern char *__progname; | ||
61 | 107 | ||
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 | */ | ||
62 | void | 113 | void |
63 | compat_init_setproctitle(int argc, char *argv[]) | 114 | setproctitle(const char *fmt, ...) |
64 | { | 115 | { |
65 | #if defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV | 116 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT |
66 | extern char **environ; | 117 | union pstun pst; |
67 | char *lastargv = NULL; | 118 | #endif |
68 | char **envp = environ; | 119 | #if SETPROCTITLE_STRATEGY != PS_USE_NONE |
69 | int i; | 120 | ssize_t used; |
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 */ | ||
70 | 131 | ||
71 | /* | 132 | /* |
72 | * NB: This assumes that argv has already been copied out of the | 133 | * Overwrite argv[] to point at appropriate space, if needed |
73 | * way. This is true for sshd, but may not be true for other | ||
74 | * programs. Beware. | ||
75 | */ | 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 */ | ||
76 | 139 | ||
77 | if (argc == 0 || argv[0] == NULL) | 140 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
78 | return; | 141 | save_argv[1] = NULL; |
79 | 142 | #endif /* PS_USE_CLOBBER_ARGV */ | |
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 | } | ||
87 | 143 | ||
88 | /* | 144 | /* |
89 | * Find the last argv string or environment variable within | 145 | * Make fixed prefix of ps display. |
90 | * our process memory area. | ||
91 | */ | 146 | */ |
92 | for (i = 0; i < argc; i++) { | 147 | |
93 | if (lastargv == NULL || lastargv + 1 == argv[i]) | 148 | va_start(ap, fmt); |
94 | lastargv = argv[i] + strlen(argv[i]); | 149 | if (fmt == NULL) |
95 | } | 150 | snprintf(ps_buffer, ps_buffer_size, "%s", __progname); |
96 | for (i = 0; envp[i] != NULL; i++) { | 151 | else { |
97 | if (lastargv + 1 == envp[i]) | 152 | used = snprintf(ps_buffer, ps_buffer_size, "%s: ", __progname); |
98 | lastargv = envp[i] + strlen(envp[i]); | 153 | if (used == -1 || used >= ps_buffer_size) |
154 | used = ps_buffer_size; | ||
155 | vsnprintf(ps_buffer + used, ps_buffer_size - used, fmt, ap); | ||
99 | } | 156 | } |
157 | va_end(ap); | ||
100 | 158 | ||
101 | argv[1] = NULL; | 159 | #if SETPROCTITLE_STRATEGY == PS_USE_PSTAT |
102 | argv_start = argv[0]; | 160 | pst.pst_command = ps_buffer; |
103 | argv_env_len = lastargv - argv[0] - 1; | 161 | pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); |
162 | #endif /* PS_USE_PSTAT */ | ||
104 | 163 | ||
105 | /* | 164 | #if SETPROCTITLE_STRATEGY == PS_USE_PS_STRINGS |
106 | * Copy environment | 165 | PS_STRINGS->ps_nargvstr = 1; |
107 | * XXX - will truncate env on strdup fail | 166 | PS_STRINGS->ps_argvstr = ps_buffer; |
108 | */ | 167 | #endif /* PS_USE_PS_STRINGS */ |
109 | for (i = 0; envp[i] != NULL; i++) | 168 | |
110 | environ[i] = strdup(envp[i]); | 169 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
111 | environ[i] = NULL; | 170 | /* pad unused memory */ |
112 | #endif /* SPT_REUSEARGV */ | 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 */ | ||
113 | } | 177 | } |
114 | 178 | ||
115 | #ifndef 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 | */ | ||
116 | void | 189 | void |
117 | setproctitle(const char *fmt, ...) | 190 | compat_init_setproctitle(int argc, char *argv[]) |
118 | { | 191 | { |
119 | #if SPT_TYPE != SPT_NONE | 192 | #if SETPROCTITLE_STRATEGY == PS_USE_CLOBBER_ARGV |
120 | va_list ap; | 193 | char *end_of_area = NULL; |
121 | char buf[1024]; | 194 | char **new_environ; |
122 | size_t len; | 195 | int i; |
123 | extern char *__progname; | ||
124 | #if SPT_TYPE == SPT_PSTAT | ||
125 | union pstun pst; | ||
126 | #endif | 196 | #endif |
127 | 197 | ||
128 | #if SPT_TYPE == SPT_REUSEARGV | 198 | save_argc = argc; |
129 | if (argv_env_len <= 0) | 199 | save_argv = argv; |
130 | return; | 200 | |
131 | #endif | 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 | */ | ||
132 | 206 | ||
133 | strlcpy(buf, __progname, sizeof(buf)); | 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 | } | ||
134 | 214 | ||
135 | va_start(ap, fmt); | 215 | /* probably can't happen? */ |
136 | if (fmt != NULL) { | 216 | if (end_of_area == NULL) { |
137 | len = strlcat(buf, ": ", sizeof(buf)); | 217 | ps_buffer = NULL; |
138 | if (len < sizeof(buf)) | 218 | ps_buffer_size = 0; |
139 | vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); | 219 | return; |
140 | } | 220 | } |
141 | va_end(ap); | ||
142 | 221 | ||
143 | #if SPT_TYPE == SPT_PSTAT | 222 | /* |
144 | pst.pst_command = buf; | 223 | * check for contiguous environ strings following argv |
145 | pstat(PSTAT_SETCMD, pst, strlen(buf), 0, 0); | 224 | */ |
146 | #elif SPT_TYPE == SPT_REUSEARGV | 225 | for (i = 0; environ[i] != NULL; i++) { |
147 | /* debug("setproctitle: copy \"%s\" into len %d", | 226 | if (end_of_area + 1 == environ[i]) |
148 | buf, argv_env_len); */ | 227 | end_of_area = environ[i] + strlen(environ[i]); |
149 | len = strlcpy(argv_start, buf, argv_env_len); | 228 | } |
150 | for(; len < argv_env_len; len++) | ||
151 | argv_start[len] = SPT_PADCHAR; | ||
152 | #endif | ||
153 | 229 | ||
154 | #endif /* SPT_NONE */ | 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 */ | ||
155 | } | 242 | } |
156 | 243 | ||
157 | #endif /* HAVE_SETPROCTITLE */ | ||