/* * Originally taken by Andy Igoshin from * Sendmail 8.8.8 by Eric Allman . * Edited a bit by Dima Maloff for Binkd/0.9.3 */ /* * $Id: setpttl.c,v 2.2 2003/02/28 20:39:09 gul Exp $ * * Revision history: * $Log: setpttl.c,v $ * Revision 2.2 2003/02/28 20:39:09 gul * Code cleanup: * change "()" to "(void)" in function declarations; * change C++-style comments to C-style * * Revision 2.1 2001/10/27 08:31:30 gul * minor fix * * Revision 2.0 2001/01/10 12:12:40 gul * Binkd is under CVS again * * */ #include #include #include #include /* * First -- map autoconf's values to sendmail's */ #ifdef HAVE_SETPROCTITLE /* We have built-in setproctitle() */ #define SPT_TYPE SPT_BUILTIN #endif /* * (xalloc.c) allocate memory or log error */ extern void *xalloc (size_t size); extern void *xstrdup (const char *str); #define MAXLINE 2048 #define SPACELEFT(buf, ptr) (sizeof buf - ((ptr) - buf)) /* ** SETPROCTITLE -- set process title for ps ** ** Parameters: ** fmt -- a printf style format string. ** a, b, c -- possible parameters to fmt. ** ** Returns: ** none. ** ** Side Effects: ** Clobbers argv of our main procedure so ps(1) will ** display the title. */ #define SPT_NONE 0 /* don't use it at all */ #define SPT_REUSEARGV 1 /* cover argv with title information */ #define SPT_BUILTIN 2 /* use libc builtin */ #define SPT_PSTAT 3 /* use pstat(PSTAT_SETCMD, ...) */ #define SPT_PSSTRINGS 4 /* use PS_STRINGS->... */ #define SPT_SYSMIPS 5 /* use sysmips() supported by NEWS-OS 6 */ #define SPT_SCO 6 /* write kernel u. area */ #define SPT_CHANGEARGV 7 /* write our own strings into argv[] */ #ifndef SPT_TYPE # define SPT_TYPE SPT_REUSEARGV #endif #if SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN # if SPT_TYPE == SPT_PSTAT # include # endif # if SPT_TYPE == SPT_PSSTRINGS # include # include # ifndef PS_STRINGS /* hmmmm.... apparently not available after all */ # undef SPT_TYPE # define SPT_TYPE SPT_REUSEARGV # else # ifndef NKPDE /* FreeBSD 2.0 */ # define NKPDE 63 typedef unsigned int *pt_entry_t; # endif # endif # endif # if SPT_TYPE == SPT_PSSTRINGS || SPT_TYPE == SPT_CHANGEARGV # define SETPROC_STATIC static # else # define SETPROC_STATIC # endif # if SPT_TYPE == SPT_SYSMIPS # include # include # endif # if SPT_TYPE == SPT_SCO # include # include # include # include # if PSARGSZ > MAXLINE # define SPT_BUFSIZE PSARGSZ # endif # endif # ifndef SPT_PADCHAR /*# define SPT_PADCHAR ' ' */ # define SPT_PADCHAR '\0' # endif # ifndef SPT_BUFSIZE # define SPT_BUFSIZE MAXLINE # endif #endif /* SPT_TYPE != SPT_NONE && SPT_TYPE != SPT_BUILTIN */ /* ** Pointers for setproctitle. ** This allows "ps" listings to give more useful information. */ char **Argv = NULL; /* pointer to argument vector */ char *LastArgv = NULL; /* end of argv */ void initsetproctitle(argc, argv, envp) int argc; char **argv; char **envp; { register int i, envpsize = 0; extern char **environ; /* ** Move the environment so setproctitle can use the space at ** the top of memory. */ for (i = 0; envp[i] != NULL; i++) envpsize += strlen(envp[i]) + 1; environ = (char **) xalloc(sizeof (char *) * (i + 1)); for (i = 0; envp[i] != NULL; i++) environ[i] = xstrdup(envp[i]); environ[i] = NULL; /* ** Save start and extent of argv for setproctitle. */ Argv = argv; /* ** Find the last environment variable within sendmail's ** process memory area. */ while (i > 0 && (envp[i - 1] < argv[0] || envp[i - 1] > (argv[argc - 1] + strlen(argv[argc - 1]) + 1 + envpsize))) i--; if (i > 0) LastArgv = envp[i - 1] + strlen(envp[i - 1]); else LastArgv = argv[argc - 1] + strlen(argv[argc - 1]); } #if SPT_TYPE != SPT_BUILTIN void setproctitle(const char *fmt, ...) { # if SPT_TYPE != SPT_NONE register char *p; register int i; SETPROC_STATIC char buf[SPT_BUFSIZE]; va_list ap; # if SPT_TYPE == SPT_PSTAT union pstun pst; # endif # if SPT_TYPE == SPT_SCO off_t seek_off; static int kmem = -1; static int kmempid = -1; struct user u; # endif p = buf; /* print sendmail: heading for grep */ (void) strcpy(p, "binkd: "); p += strlen(p); /* print the argument string */ va_start(ap, fmt); #ifdef HAVE_SNPRINTF (void) vsnprintf(p, SPACELEFT(buf, p), fmt, ap); #else (void) vsprintf(p, fmt, ap); #endif va_end(ap); i = strlen(buf); # if SPT_TYPE == SPT_PSTAT pst.pst_command = buf; pstat(PSTAT_SETCMD, pst, i, 0, 0); # endif # if SPT_TYPE == SPT_PSSTRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = buf; # endif # if SPT_TYPE == SPT_SYSMIPS sysmips(SONY_SYSNEWS, NEWS_SETPSARGS, buf); # endif # if SPT_TYPE == SPT_SCO if (kmem < 0 || kmempid != getpid()) { if (kmem >= 0) close(kmem); kmem = open(_PATH_KMEM, O_RDWR, 0); if (kmem < 0) return; (void) fcntl(kmem, F_SETFD, 1); kmempid = getpid(); } buf[PSARGSZ - 1] = '\0'; seek_off = UVUBLK + (off_t) u.u_psargs - (off_t) &u; if (lseek(kmem, (off_t) seek_off, SEEK_SET) == seek_off) (void) write(kmem, buf, PSARGSZ); # endif # if SPT_TYPE == SPT_REUSEARGV if (LastArgv == NULL) return; if (i > LastArgv - Argv[0] - 2) { i = LastArgv - Argv[0] - 2; buf[i] = '\0'; } (void) strcpy(Argv[0], buf); p = &Argv[0][i]; while (p < LastArgv) *p++ = SPT_PADCHAR; Argv[1] = NULL; # endif # if SPT_TYPE == SPT_CHANGEARGV Argv[0] = buf; Argv[1] = 0; # endif # endif /* SPT_TYPE != SPT_NONE */ } #endif /* SPT_TYPE != SPT_BUILTIN */