1: /*
2: * Copyright (c) 2013 Todd C. Miller <Todd.Miller@courtesan.com>
3: *
4: * Permission to use, copy, modify, and distribute this software for any
5: * purpose with or without fee is hereby granted, provided that the above
6: * copyright notice and this permission notice appear in all copies.
7: *
8: * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9: * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10: * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11: * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12: * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13: * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14: * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15: */
16:
17: #include <config.h>
18:
19: /* Large files not supported by procfs.h */
20: #if defined(HAVE_PROCFS_H) || defined(HAVE_SYS_PROCFS_H)
21: # undef _FILE_OFFSET_BITS
22: # undef _LARGE_FILES
23: #endif
24:
25: #include <sys/types.h>
26: #ifdef HAVE_PSTAT_GETPROC
27: # include <sys/param.h>
28: # include <sys/pstat.h>
29: #endif
30: #if defined(HAVE_PROCFS_H)
31: # include <procfs.h>
32: #elif defined(HAVE_SYS_PROCFS_H)
33: # include <sys/procfs.h>
34: #endif
35:
36: #include <stdio.h>
37: #ifdef STDC_HEADERS
38: # include <stdlib.h>
39: # include <stddef.h>
40: #else
41: # ifdef HAVE_STDLIB_H
42: # include <stdlib.h>
43: # endif
44: #endif /* STDC_HEADERS */
45: #ifdef HAVE_STRING_H
46: # include <string.h>
47: #endif /* HAVE_STRING_H */
48: #ifdef HAVE_STRINGS_H
49: # include <strings.h>
50: #endif /* HAVE_STRINGS_H */
51: #include <errno.h>
52: #include <fcntl.h>
53:
54: #include "missing.h"
55: #include "sudo_util.h"
56:
57: #if defined(HAVE_GETPROGNAME) || defined(HAVE___PROGNAME)
58:
59: /* STUB */
60: void
61: initprogname(const char *name)
62: {
63: return;
64: }
65:
66: #else
67:
68: static const char *progname = "";
69:
70: void
71: initprogname(const char *name)
72: {
73: const char *base;
74: #ifdef HAVE_PSTAT_GETPROC
75: static char ucomm[PST_UCOMMLEN];
76: struct pst_status pstat;
77: int rc;
78:
79: /*
80: * Determine the progname from pst_ucomm in struct pst_status.
81: * We may get EOVERFLOW if the whole thing doesn't fit but that is OK.
82: */
83: rc = pstat_getproc(&pstat, sizeof(pstat), (size_t)0, (int)getpid());
84: if (rc != -1 || errno == EOVERFLOW) {
85: strlcpy(ucomm, pstat.pst_ucomm, sizeof(ucomm));
86: progname = ucomm;
87: return;
88: }
89: #elif defined(HAVE_PROCFS_H) || defined(HAVE_SYS_PROCFS_H)
90: /* XXX - configure check for psinfo.pr_fname */
91: static char ucomm[PRFNSZ];
92: struct psinfo psinfo;
93: char path[PATH_MAX];
94: ssize_t nread;
95: int fd;
96:
97: /* Try to determine the tty from pr_ttydev in /proc/pid/psinfo. */
98: snprintf(path, sizeof(path), "/proc/%u/psinfo", (unsigned int)getpid());
99: if ((fd = open(path, O_RDONLY, 0)) != -1) {
100: nread = read(fd, &psinfo, sizeof(psinfo));
101: close(fd);
102: if (nread == (ssize_t)sizeof(psinfo)) {
103: strlcpy(ucomm, psinfo.pr_fname, sizeof(ucomm));
104: progname = ucomm;
105: return;
106: }
107: }
108: #endif /* HAVE_PSTAT_GETPROC */
109:
110: if ((base = strrchr(name, '/')) != NULL) {
111: base++;
112: } else {
113: base = name;
114: }
115: progname = base;
116: }
117:
118: const char *
119: getprogname(void)
120: {
121: return progname;
122: }
123:
124: #endif /* !HAVE_GETPROGNAME && !HAVE___PROGNAME */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>