|
|
1.1 root 1: /* $Header: talkd.c 1.5 83/05/10 13:57:29 moore 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: struct hostent *gethostbyname();
29: struct servent *getservbyname();
30:
31: int debug = 0;
32:
33: main(argc)
34: int argc;
35: {
36: struct sockaddr_in from;
37: int from_size;
38: int cc;
39: int name_length = sizeof(hostname);
40: struct servent *sp;
41: struct hostent *hp;
42:
43:
44: if ( argc > 1 ) {
45: debug = 1;
46: }
47:
48: if ( !debug ) {
49: if (fork()) {
50: exit(0);
51: }
52: }
53:
54: gethostname(hostname, &name_length);
55:
56: hp = gethostbyname(hostname);
57: if (hp == (struct hostent *) 0) {
58: fprintf(stderr, "talkd: Cannot obtain local address\n");
59: exit(1);
60: }
61:
62: #ifdef NTALK
63: sp = getservbyname("ntalk", "udp");
64: #else
65: sp = getservbyname("talk", "udp");
66: #endif
67:
68: if (sp == 0) {
69: fprintf(stderr, "talkd: udp/talk: unknown service\n");
70: exit(1);
71: }
72:
73: if (getuid()) {
74: fprintf(stderr, "Talkd : not super user\n");
75: exit(1);
76: }
77:
78: setup_desc();
79:
80: sin.sin_port = sp->s_port;
81: sockt = socket(AF_INET, SOCK_DGRAM, 0, 0);
82: if (sockt < 0) {
83: print_error("talkd: socket");
84: exit(1);
85: }
86:
87: if (bind(sockt, (caddr_t)&sin, sizeof (sin), 0) < 0) {
88: print_error("bind");
89: exit(1);
90: }
91:
92: for (;;) {
93:
94: from_size = sizeof(from);
95: cc = recvfrom(sockt, (char *)&request, sizeof (request), 0,
96: &from, &from_size);
97:
98: if (cc != sizeof(request)) {
99: if (cc < 0 && errno != EINTR) {
100: print_error("receive");
101: }
102: } else {
103:
104: if (debug) printf("Request received : \n");
105: if (debug) print_request(&request);
106:
107: process_request(&request, &response);
108:
109: if (debug) printf("Response sent : \n");
110: if (debug) print_response(&response);
111:
112: /* can block here, is this what I want? */
113:
114: cc = sendto(sockt, (char *) &response, sizeof(response), 0,
115: &request.ctl_addr, sizeof(request.ctl_addr));
116:
117: if (cc != sizeof(response)) {
118: print_error("Send");
119: }
120: }
121: }
122: }
123:
124: /* disconnect all descriptors, remove ourself from the process
125: * group that spawned us
126: */
127:
128: setup_desc()
129: {
130: int s;
131:
132: if (debug) return;
133:
134: for (s = 0; s < 10; s++) {
135: (void) close(s);
136: }
137:
138: (void) open("/dev/null", 0);
139: (void) dup2(0, 1);
140: (void) dup2(0, 2);
141:
142: s = open("/dev/tty", 2);
143:
144: if (s >= 0) {
145: ioctl(s, TIOCNOTTY, (struct sgttyb *) 0);
146: (void) close(s);
147: }
148:
149: (void) chdir("/dev");
150: }
151:
152: extern int sys_nerr;
153: extern char *sys_errlist[];
154:
155: print_error(string)
156: char *string;
157: {
158: FILE *cons;
159: char *err_dev = "/dev/console";
160: char *sys;
161: int val, pid;
162:
163: if (debug) err_dev = "/dev/tty";
164:
165: sys = "Unknown error";
166:
167: if(errno < sys_nerr) {
168: sys = sys_errlist[errno];
169: }
170:
171: /* don't ever open tty's directly, let a child do it */
172: if ((pid = fork()) == 0) {
173: cons = fopen(err_dev, "a");
174: if (cons != NULL) {
175: fprintf(cons, "Talkd : %s : %s(%d)\n\r", string, sys,
176: errno);
177: fclose(cons);
178: }
179: exit(0);
180: } else {
181: /* wait for the child process to return */
182: do {
183: val = wait(0);
184: if (val == -1) {
185: if (errno == EINTR) {
186: continue;
187: } else if (errno == ECHILD) {
188: break;
189: }
190: }
191: } while (val != pid);
192: }
193: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.