File: utils.c

package info (click to toggle)
socket 1.1-10
  • links: PTS
  • area: main
  • in suites: bullseye, buster, jessie, jessie-kfreebsd, sid, squeeze, stretch, wheezy
  • size: 128 kB
  • ctags: 81
  • sloc: ansic: 947; makefile: 159; sh: 18
file content (264 lines) | stat: -rw-r--r-- 5,096 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
/*

$Header: utils.c[1.14] Wed Sep  9 16:34:03 1992 nickel@cs.tu-berlin.de proposed $
This file is part of socket(1).
Copyright (C) 1992 by Juergen Nickelsen <nickel@cs.tu-berlin.de>
Please read the file COPYRIGHT for further details.

*/

#ifdef sgi
#define _BSD_SIGNALS
#define SIG_HANDLER_RET int
#else /* !sgi */
#define SIG_HANDLER_RET void
#endif

#include <stdio.h>
#ifdef __linux__
#include <unistd.h>
#endif
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <sys/time.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#ifdef ISC
#define WNOHANG 1
#else
#include <sys/resource.h>
#endif
#include "globals.h"


/* Signal handler, print message and exit */
SIG_HANDLER_RET exitsig(sig)
int sig ;
{
    if (sig != SIGUSR1) {
	fprintf(stderr, "\n%s occured, exiting\n", socket_siglist[sig]) ;
    }
    exit(-sig) ;
}

/* Give usage message */
void usage()
{
    static char ustring[] =
	"Usage: %s [-bclqrvw] [-B local ip] [-p prog] {{-s|host} port | [-s] /path}\n" ;

    fprintf(stderr, ustring, progname) ;
}

/* perror with progname */
void perror2(s)
char *s ;
{
    fprintf(stderr, "%s: ", progname) ;
    perror(s) ;
}

/* is s a number? */
int is_number(s)
char *s ;
{
    while (*s) {
	if (*s < '0' || *s > '9') {
	    return 0 ;
	}
	s++ ;
    }
    return 1 ;
}

/* set up signal handling. All except TSTP, CONT, CLD, and QUIT
 * are caught with exitsig(). */
void init_signals()
{
    int i ;
#ifdef BSD_SIG_SETMASK		/* only with BSD signals */
    static struct sigvec svec = { exitsig, ~0, 0 } ;
#endif

    initialize_siglist() ;	/* shamelessly stolen from BASH */
    
    for (i = 0; i < NSIG; i++) {
	switch (i) {
#ifdef SIGTSTP
	  case SIGTSTP:
	  case SIGTTOU:
	  case SIGTTIN:
	  case SIGSTOP:
	  case SIGCONT:
	    continue ;
#endif
#if !defined (SIGCHLD) && defined (SIGCLD)
#define SIGCHLD SIGCLD
#endif
#ifdef SIGCHLD
	  case SIGCHLD:
	    continue ;
#endif
#ifdef SIGWINCH
	  case SIGWINCH:	/* it is ridiculous to exit on WINCH */
	    continue ;
#endif
	  case SIGQUIT:		/* if the user wants a core dump, */
	    continue ;		/* they can have it. */
	  default:	    
#ifdef BSD_SIG_SETMASK
	    sigvec(i, &svec, NULL) ;
#else
	    signal(i, exitsig) ;
#endif
	}
    }
}

/* connect stdin with prog's stdout/stderr and stdout
 * with prog's stdin. */
void open_pipes(prog)
char *prog ;
{
    int from_cld[2] ;		/* from child process */
    int to_cld[2] ;		/* to child process */

    /* create pipes */
    if (pipe(from_cld) == -1) {
	perror2("pipe") ;
	exit(errno) ;
    }
    if (pipe(to_cld) == -1) {
	perror2("pipe") ;
	exit(errno) ;
    }

    /* for child process */
    switch (fork()) {
      case 0:			/* this is the child process */
	/* connect stdin to pipe */
	close(0) ;
	close(to_cld[1]) ;
	dup2(to_cld[0], 0) ;
	close(to_cld[0]) ;
	/* connect stdout to pipe */
	close(1) ;
	close(from_cld[0]) ;
	dup2(from_cld[1], 1) ;
	/* connect stderr to pipe */
	close(2) ;
	dup2(from_cld[1], 2) ;
	close(from_cld[1]) ;
	/* call program via sh */
	execl("/bin/sh", "sh", "-c", prog, NULL) ;
	perror2("exec /bin/sh") ;
	/* terminate parent silently */
	kill(getppid(), SIGUSR1) ;
	exit(255) ;
      case -1:
	perror2("fork") ;	/* fork failed */
	exit(errno) ;
      default:			/* parent process */
	/* connect stderr to pipe */
	close(0) ;
	close(from_cld[1]) ;
	dup2(from_cld[0], 0) ;
	close(from_cld[0]) ;
	/* connect stderr to pipe */
	close(1) ;
	close(to_cld[0]) ;
	dup2(to_cld[1], 1) ;
	close(to_cld[1]) ;
    }
}

/* remove zombie child processes */
void wait_for_children()
{
    int wret, status ;
#ifndef ISC
    struct rusage rusage ;
#endif

    /* Just do a wait, forget result */
#ifndef ISC
    while ((wret = wait3(&status, WNOHANG, &rusage)) > 0) ;
#else
    while ((wret = waitpid(-1, &status, WNOHANG)) > 0) ;
#endif
}

/* expand LF characters to CRLF and adjust *sizep */
void add_crs(from, to, sizep)
char *from, *to ;		/* *from is copied to *to */
int *sizep ;
{
    int countdown ;		/* counter */

    countdown = *sizep ;
    while (countdown) {
	if (*from == '\n') {
	    *to++ = '\r' ;
	    (*sizep)++ ;
	}
	*to++ = *from++ ;
	countdown-- ;
    }
}

/* strip CR characters from buffer and adjust *sizep */
void strip_crs(from, to, sizep)
char *from, *to ;		/* *from is copied to *to */
int *sizep ;
{

    int countdown ;		/* counter */

    countdown = *sizep ;
    while (countdown) {
	if (*from == '\r') {
	    from++ ;
	    (*sizep)-- ;
	} else {
	    *to++ = *from++ ;
	}
	countdown-- ;
    }
}

#define NULL_DEVICE "/dev/null"

/* put yourself in the background */
void background()
{
    int child_pid ;		/* PID of child process */
    int nulldev_fd ;		/* file descriptor for null device */

    child_pid = fork() ;
    switch (child_pid) {
      case -1:
	perror2("fork") ;
	exit(1) ;
      case 0:
#ifdef NOSETSID
	ioctl(0, TIOCNOTTY, 0) ;
#else
	setsid() ;
#endif
	chdir("/") ;
	if ((nulldev_fd = open(NULL_DEVICE, O_RDWR, 0)) != -1) {
	    int i ;

	    for (i = 0; i < 3; i++) {
		if (isatty(i)) {
		    dup2(nulldev_fd, i) ;
		}
	    }
	    close(nulldev_fd) ;
	}
	break ;
      default:
	exit(0) ;
    }
}