1124208Sdes/* Based on conf.c from UCB sendmail 8.8.8 */ 2124208Sdes 398937Sdes/* 4124208Sdes * Copyright 2003 Damien Miller 5124208Sdes * Copyright (c) 1983, 1995-1997 Eric P. Allman 6124208Sdes * Copyright (c) 1988, 1993 7124208Sdes * The Regents of the University of California. All rights reserved. 898937Sdes * 9124208Sdes * Redistribution and use in source and binary forms, with or without 10124208Sdes * modification, are permitted provided that the following conditions 11124208Sdes * are met: 12124208Sdes * 1. Redistributions of source code must retain the above copyright 13124208Sdes * notice, this list of conditions and the following disclaimer. 14124208Sdes * 2. Redistributions in binary form must reproduce the above copyright 15124208Sdes * notice, this list of conditions and the following disclaimer in the 16124208Sdes * documentation and/or other materials provided with the distribution. 17124208Sdes * 3. Neither the name of the University nor the names of its contributors 18124208Sdes * may be used to endorse or promote products derived from this software 19124208Sdes * without specific prior written permission. 2098937Sdes * 21124208Sdes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 22124208Sdes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 23124208Sdes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 24124208Sdes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 25124208Sdes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 26124208Sdes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 27124208Sdes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 28124208Sdes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 29124208Sdes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 30124208Sdes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 31124208Sdes * SUCH DAMAGE. 3298937Sdes */ 3398937Sdes 3498937Sdes#include "includes.h" 3598937Sdes 3698937Sdes#ifndef HAVE_SETPROCTITLE 3798937Sdes 38162852Sdes#include <stdarg.h> 39162852Sdes#include <stdlib.h> 40113908Sdes#include <unistd.h> 41113908Sdes#ifdef HAVE_SYS_PSTAT_H 42124208Sdes#include <sys/pstat.h> 43113908Sdes#endif 44162852Sdes#include <string.h> 4598937Sdes 46181111Sdes#include <vis.h> 47181111Sdes 48124208Sdes#define SPT_NONE 0 /* don't use it at all */ 49126274Sdes#define SPT_PSTAT 1 /* use pstat(PSTAT_SETCMD, ...) */ 50126274Sdes#define SPT_REUSEARGV 2 /* cover argv with title information */ 51113908Sdes 52124208Sdes#ifndef SPT_TYPE 53124208Sdes# define SPT_TYPE SPT_NONE 5498937Sdes#endif 5598937Sdes 56124208Sdes#ifndef SPT_PADCHAR 57124208Sdes# define SPT_PADCHAR '\0' 58113908Sdes#endif 5998937Sdes 60124208Sdes#if SPT_TYPE == SPT_REUSEARGV 61124208Sdesstatic char *argv_start = NULL; 62124208Sdesstatic size_t argv_env_len = 0; 63113908Sdes#endif 64113908Sdes 65124208Sdes#endif /* HAVE_SETPROCTITLE */ 66113908Sdes 6798937Sdesvoid 68124208Sdescompat_init_setproctitle(int argc, char *argv[]) 6998937Sdes{ 70261320Sdes#if !defined(HAVE_SETPROCTITLE) && \ 71261320Sdes defined(SPT_TYPE) && SPT_TYPE == SPT_REUSEARGV 72124208Sdes extern char **environ; 73124208Sdes char *lastargv = NULL; 74124208Sdes char **envp = environ; 75124208Sdes int i; 7698937Sdes 77113908Sdes /* 78124208Sdes * NB: This assumes that argv has already been copied out of the 79124208Sdes * way. This is true for sshd, but may not be true for other 80124208Sdes * programs. Beware. 81113908Sdes */ 82113908Sdes 83124208Sdes if (argc == 0 || argv[0] == NULL) 84124208Sdes return; 85113908Sdes 86124208Sdes /* Fail if we can't allocate room for the new environment */ 87124208Sdes for (i = 0; envp[i] != NULL; i++) 88124208Sdes ; 89162852Sdes if ((environ = calloc(i + 1, sizeof(*environ))) == NULL) { 90124208Sdes environ = envp; /* put it back */ 91124208Sdes return; 92124208Sdes } 93124208Sdes 94113908Sdes /* 95124208Sdes * Find the last argv string or environment variable within 96124208Sdes * our process memory area. 97113908Sdes */ 98124208Sdes for (i = 0; i < argc; i++) { 99124208Sdes if (lastargv == NULL || lastargv + 1 == argv[i]) 100124208Sdes lastargv = argv[i] + strlen(argv[i]); 101113908Sdes } 102124208Sdes for (i = 0; envp[i] != NULL; i++) { 103124208Sdes if (lastargv + 1 == envp[i]) 104124208Sdes lastargv = envp[i] + strlen(envp[i]); 105124208Sdes } 10698937Sdes 107124208Sdes argv[1] = NULL; 108124208Sdes argv_start = argv[0]; 109124208Sdes argv_env_len = lastargv - argv[0] - 1; 11098937Sdes 111124208Sdes /* 112124208Sdes * Copy environment 113124208Sdes * XXX - will truncate env on strdup fail 114124208Sdes */ 115124208Sdes for (i = 0; envp[i] != NULL; i++) 116124208Sdes environ[i] = strdup(envp[i]); 117124208Sdes environ[i] = NULL; 118124208Sdes#endif /* SPT_REUSEARGV */ 11998937Sdes} 120113908Sdes 121124208Sdes#ifndef HAVE_SETPROCTITLE 122113908Sdesvoid 123124208Sdessetproctitle(const char *fmt, ...) 124113908Sdes{ 125124208Sdes#if SPT_TYPE != SPT_NONE 126124208Sdes va_list ap; 127181111Sdes char buf[1024], ptitle[1024]; 128124208Sdes size_t len; 129261320Sdes int r; 130124208Sdes extern char *__progname; 131124208Sdes#if SPT_TYPE == SPT_PSTAT 132124208Sdes union pstun pst; 133113908Sdes#endif 134113908Sdes 135124208Sdes#if SPT_TYPE == SPT_REUSEARGV 136124208Sdes if (argv_env_len <= 0) 137124208Sdes return; 138124208Sdes#endif 139113908Sdes 140124208Sdes strlcpy(buf, __progname, sizeof(buf)); 141113908Sdes 142261320Sdes r = -1; 143124208Sdes va_start(ap, fmt); 144124208Sdes if (fmt != NULL) { 145124208Sdes len = strlcat(buf, ": ", sizeof(buf)); 146124208Sdes if (len < sizeof(buf)) 147261320Sdes r = vsnprintf(buf + len, sizeof(buf) - len , fmt, ap); 148113908Sdes } 149124208Sdes va_end(ap); 150261320Sdes if (r == -1 || (size_t)r >= sizeof(buf) - len) 151261320Sdes return; 152181111Sdes strnvis(ptitle, buf, sizeof(ptitle), 153181111Sdes VIS_CSTYLE|VIS_NL|VIS_TAB|VIS_OCTAL); 154113908Sdes 155124208Sdes#if SPT_TYPE == SPT_PSTAT 156181111Sdes pst.pst_command = ptitle; 157181111Sdes pstat(PSTAT_SETCMD, pst, strlen(ptitle), 0, 0); 158124208Sdes#elif SPT_TYPE == SPT_REUSEARGV 159124208Sdes/* debug("setproctitle: copy \"%s\" into len %d", 160124208Sdes buf, argv_env_len); */ 161181111Sdes len = strlcpy(argv_start, ptitle, argv_env_len); 162124208Sdes for(; len < argv_env_len; len++) 163124208Sdes argv_start[len] = SPT_PADCHAR; 164124208Sdes#endif 165113908Sdes 166124208Sdes#endif /* SPT_NONE */ 167113908Sdes} 168113908Sdes 169124208Sdes#endif /* HAVE_SETPROCTITLE */ 170