|
|
1.1 root 1: /* $Header: talkd.c,v 1.2 85/01/09 13:05:13 rcs Exp $ */
2:
3: /* The top level of the daemon, the format is heavily borrowed
4: from rwhod.c. Basically: find out who and where you are;
5: disconnect all descriptors and ttys, and then endless
6: loop on waiting for and processing requests
7: */
8:
9: #include "ctl.h"
10:
11: #include <stdio.h>
12: #include <errno.h>
13: #include <sgtty.h>
14: #include <sys/ioctl.h>
15:
16: #define MAX_ERR 20 /* Number of times to attempt to open the
17: control socket */
18:
19: extern errno;
20:
21: struct sockaddr_in sin = { AF_INET };
22:
23: CTL_MSG request;
24: CTL_RESPONSE response;
25: int sockt;
26: char hostname[HOST_NAME_LENGTH];
27:
28: CTL_MSG swapmsg();
29: struct hostent *gethostbyname();
30: struct servent *getservbyname();
31:
32: int vaxbyteorder;
33: int tonetmsg();
34: int frnetmsg();
35: int tonetresp();
36:
37: int debug = 0;
38:
39: char *inet_ntoa();
40: /*--------------------------------------------------------------
41: Changes
42: . perform byte-ordering within messages as reported from
43: the usenet
44: -------------------------------------------------------------*/
45: main(argc)
46: int argc;
47: {
48: struct sockaddr_in from;
49: int from_size;
50: int cc;
51: int name_length = sizeof(hostname);
52: struct servent *sp;
53: struct hostent *hp;
54:
55: NETCTL_RESPONSE netresp; /* to convert to net format */
56: NETCTL_MSG netreq;
57: int swapped;
58:
59: if ( argc > 1 ) {
60: debug = 1;
61: }
62:
63: if ( !debug ) {
64: if (fork()) {
65: exit(0);
66: }
67: }
68:
69: gethostname(hostname, &name_length);
70:
71: hp = gethostbyname(hostname);
72: if (hp == (struct hostent *) 0) {
73: fprintf(stderr, "talkd: Cannot obtain local address\n");
74: exit(1);
75: }
76:
77: #ifdef NTALK
78: sp = getservbyname("ntalk", "udp");
79: #else
80: sp = getservbyname("talk", "udp");
81: #endif
82:
83: if (sp == 0) {
84: fprintf(stderr, "talkd: udp/talk: unknown service\n");
85: exit(1);
86: }
87:
88: if (getuid()) {
89: fprintf(stderr, "Talkd : not super user\n");
90: exit(1);
91: }
92:
93: setup_desc();
94:
95: sin.sin_port = sp->s_port;
96: sockt = socket(AF_INET, SOCK_DGRAM, 0, 0);
97: if (sockt < 0) {
98: print_error("talkd: socket");
99: exit(1);
100: }
101:
102: if (bind(sockt, (caddr_t)&sin, sizeof (sin), 0) < 0) {
103: print_error("bind");
104: exit(1);
105: }
106:
107: for (;;) {
108:
109: from_size = sizeof(from);
110: cc = recvfrom(sockt, (char *)&netreq, sizeof (netreq), 0,
111: &from, &from_size);
112:
113: if (debug) {
114: int i;
115: char *t = (char *)&netreq;
116:
117: printf("incoming request: ");
118: /* for (i = 0; i<sizeof(NETCTL_MSG); i++) {
119: /* printf("%x.", t[i] & 0xff);
120: /* }
121: /**/
122: printf("\n");
123: }
124:
125: if (cc != sizeof(netreq)) {
126: if (cc < 0 && errno != EINTR) {
127: print_error("receive");
128: }
129: } else {
130:
131: swapped = frnetmsg(&netreq, &request);
132: if (debug) printf("Request is in VAX-byte-order == %d\n",swapped);
133:
134: if (debug) printf("Request received : \n");
135: if (debug) print_request(&request);
136:
137: process_request(&request, &response);
138:
139: if (debug) printf("Response sent : \n");
140: if (debug) print_response(&response);
141:
142: /* can block here, is this what I want? */
143:
144: tonetresp(&response, &netresp, swapped );
145: if (debug) {
146: printf("Send response to: ");
147: print_addr(request.ctlm_ctl_addr);
148: }
149: cc = sendto(sockt, (char *) &netresp, sizeof(netresp), 0,
150: &request.ctlm_ctl_addr, sizeof(request.ctlm_ctl_addr));
151:
152: if (cc != sizeof(netresp)) {
153: print_error("Send");
154: }
155: }
156: }
157: }
158:
159: /* disconnect all descriptors, remove ourself from the process
160: * group that spawned us
161: */
162:
163: setup_desc()
164: {
165: int s;
166:
167: if (debug) return;
168:
169: for (s = 0; s < 10; s++) {
170: (void) close(s);
171: }
172:
173: (void) open("/dev/null", 0);
174: (void) dup2(0, 1);
175: (void) dup2(0, 2);
176:
177: s = open("/dev/tty", 2);
178:
179: if (s >= 0) {
180: ioctl(s, TIOCNOTTY, (struct sgttyb *) 0);
181: (void) close(s);
182: }
183:
184: (void) chdir("/dev");
185: }
186:
187: extern int sys_nerr;
188: extern char *sys_errlist[];
189:
190: print_error(string)
191: char *string;
192: {
193: FILE *cons;
194: char *err_dev = "/dev/console";
195: char *sys;
196: int val, pid;
197:
198: if (debug) err_dev = "/dev/tty";
199:
200: sys = "Unknown error";
201:
202: if(errno < sys_nerr) {
203: sys = sys_errlist[errno];
204: }
205:
206: /* don't ever open tty's directly, let a child do it */
207: if ((pid = fork()) == 0) {
208: cons = fopen(err_dev, "a");
209: if (cons != NULL) {
210: fprintf(cons, "Talkd : %s : %s(%d)\n\r", string, sys,
211: errno);
212: fclose(cons);
213: }
214: exit(0);
215: } else {
216: /* wait for the child process to return */
217: do {
218: val = wait(0);
219: if (val == -1) {
220: if (errno == EINTR) {
221: continue;
222: } else if (errno == ECHILD) {
223: break;
224: }
225: }
226: } while (val != pid);
227: }
228: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.