xref: /freebsd/crypto/openssh/openbsd-compat/bsd-misc.c (revision 6b3455a7665208c366849f0b2b3bc916fb97516e)
1 /*
2  * Copyright (c) 1999-2004 Damien Miller <djm@mindrot.org>
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 "includes.h"
18 #include "xmalloc.h"
19 
20 RCSID("$Id: bsd-misc.c,v 1.21 2004/02/17 05:49:55 djm Exp $");
21 
22 /*
23  * NB. duplicate __progname in case it is an alias for argv[0]
24  * Otherwise it may get clobbered by setproctitle()
25  */
26 char *ssh_get_progname(char *argv0)
27 {
28 #ifdef HAVE___PROGNAME
29 	extern char *__progname;
30 
31 	return xstrdup(__progname);
32 #else
33 	char *p;
34 
35 	if (argv0 == NULL)
36 		return ("unknown");	/* XXX */
37 	p = strrchr(argv0, '/');
38 	if (p == NULL)
39 		p = argv0;
40 	else
41 		p++;
42 
43 	return (xstrdup(p));
44 #endif
45 }
46 
47 #ifndef HAVE_SETLOGIN
48 int setlogin(const char *name)
49 {
50 	return (0);
51 }
52 #endif /* !HAVE_SETLOGIN */
53 
54 #ifndef HAVE_INNETGR
55 int innetgr(const char *netgroup, const char *host,
56             const char *user, const char *domain)
57 {
58 	return (0);
59 }
60 #endif /* HAVE_INNETGR */
61 
62 #if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
63 int seteuid(uid_t euid)
64 {
65 	return (setreuid(-1, euid));
66 }
67 #endif /* !defined(HAVE_SETEUID) && defined(HAVE_SETREUID) */
68 
69 #if !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID)
70 int setegid(uid_t egid)
71 {
72 	return(setresgid(-1, egid, -1));
73 }
74 #endif /* !defined(HAVE_SETEGID) && defined(HAVE_SETRESGID) */
75 
76 #if !defined(HAVE_STRERROR) && defined(HAVE_SYS_ERRLIST) && defined(HAVE_SYS_NERR)
77 const char *strerror(int e)
78 {
79 	extern int sys_nerr;
80 	extern char *sys_errlist[];
81 
82 	if ((e >= 0) && (e < sys_nerr))
83 		return (sys_errlist[e]);
84 
85 	return ("unlisted error");
86 }
87 #endif
88 
89 #ifndef HAVE_UTIMES
90 int utimes(char *filename, struct timeval *tvp)
91 {
92 	struct utimbuf ub;
93 
94 	ub.actime = tvp[0].tv_sec;
95 	ub.modtime = tvp[1].tv_sec;
96 
97 	return (utime(filename, &ub));
98 }
99 #endif
100 
101 #ifndef HAVE_TRUNCATE
102 int truncate(const char *path, off_t length)
103 {
104 	int fd, ret, saverrno;
105 
106 	fd = open(path, O_WRONLY);
107 	if (fd < 0)
108 		return (-1);
109 
110 	ret = ftruncate(fd, length);
111 	saverrno = errno;
112 	close(fd);
113 	if (ret == -1)
114 		errno = saverrno;
115 
116 	return(ret);
117 }
118 #endif /* HAVE_TRUNCATE */
119 
120 #if !defined(HAVE_SETGROUPS) && defined(SETGROUPS_NOOP)
121 /*
122  * Cygwin setgroups should be a noop.
123  */
124 int
125 setgroups(size_t size, const gid_t *list)
126 {
127 	return (0);
128 }
129 #endif
130 
131 #if !defined(HAVE_NANOSLEEP) && !defined(HAVE_NSLEEP)
132 int nanosleep(const struct timespec *req, struct timespec *rem)
133 {
134 	int rc, saverrno;
135 	extern int errno;
136 	struct timeval tstart, tstop, tremain, time2wait;
137 
138 	TIMESPEC_TO_TIMEVAL(&time2wait, req)
139 	(void) gettimeofday(&tstart, NULL);
140 	rc = select(0, NULL, NULL, NULL, &time2wait);
141 	if (rc == -1) {
142 		saverrno = errno;
143 		(void) gettimeofday (&tstop, NULL);
144 		errno = saverrno;
145 		tremain.tv_sec = time2wait.tv_sec -
146 			(tstop.tv_sec - tstart.tv_sec);
147 		tremain.tv_usec = time2wait.tv_usec -
148 			(tstop.tv_usec - tstart.tv_usec);
149 		tremain.tv_sec += tremain.tv_usec / 1000000L;
150 		tremain.tv_usec %= 1000000L;
151 	} else {
152 		tremain.tv_sec = 0;
153 		tremain.tv_usec = 0;
154 	}
155 	TIMEVAL_TO_TIMESPEC(&tremain, rem)
156 
157 	return(rc);
158 }
159 #endif
160 
161 #ifndef HAVE_TCGETPGRP
162 pid_t
163 tcgetpgrp(int fd)
164 {
165 	int ctty_pgrp;
166 
167 	if (ioctl(fd, TIOCGPGRP, &ctty_pgrp) == -1)
168 		return(-1);
169 	else
170 		return(ctty_pgrp);
171 }
172 #endif /* HAVE_TCGETPGRP */
173 
174 #ifndef HAVE_TCSENDBREAK
175 int
176 tcsendbreak(int fd, int duration)
177 {
178 # if defined(TIOCSBRK) && defined(TIOCCBRK)
179 	struct timeval sleepytime;
180 
181 	sleepytime.tv_sec = 0;
182 	sleepytime.tv_usec = 400000;
183 	if (ioctl(fd, TIOCSBRK, 0) == -1)
184 		return (-1);
185 	(void)select(0, 0, 0, 0, &sleepytime);
186 	if (ioctl(fd, TIOCCBRK, 0) == -1)
187 		return (-1);
188 	return (0);
189 # else
190 	return -1;
191 # endif
192 }
193 #endif /* HAVE_TCSENDBREAK */
194 
195 mysig_t
196 mysignal(int sig, mysig_t act)
197 {
198 #ifdef HAVE_SIGACTION
199 	struct sigaction sa, osa;
200 
201 	if (sigaction(sig, NULL, &osa) == -1)
202 		return (mysig_t) -1;
203 	if (osa.sa_handler != act) {
204 		memset(&sa, 0, sizeof(sa));
205 		sigemptyset(&sa.sa_mask);
206 		sa.sa_flags = 0;
207 #ifdef SA_INTERRUPT
208 		if (sig == SIGALRM)
209 			sa.sa_flags |= SA_INTERRUPT;
210 #endif
211 		sa.sa_handler = act;
212 		if (sigaction(sig, &sa, NULL) == -1)
213 			return (mysig_t) -1;
214 	}
215 	return (osa.sa_handler);
216 #else
217 	#undef signal
218 	return (signal(sig, act));
219 #endif
220 }
221