122401Sdist /*
2*61449Sbostic * Copyright (c) 1983, 1993
3*61449Sbostic * The Regents of the University of California. All rights reserved.
434360Sbostic *
542673Sbostic * %sccs.include.redist.c%
622401Sdist */
722401Sdist
816366Skarels #ifndef lint
9*61449Sbostic static char copyright[] =
10*61449Sbostic "@(#) Copyright (c) 1983, 1993\n\
11*61449Sbostic The Regents of the University of California. All rights reserved.\n";
1234360Sbostic #endif /* not lint */
1316360Skarels
1422401Sdist #ifndef lint
15*61449Sbostic static char sccsid[] = "@(#)talkd.c 8.1 (Berkeley) 06/04/93";
1634360Sbostic #endif /* not lint */
1722401Sdist
1816366Skarels /*
1916366Skarels * The top level of the daemon, the format is heavily borrowed
2016366Skarels * from rwhod.c. Basically: find out who and where you are;
2116366Skarels * disconnect all descriptors and ttys, and then endless
2216366Skarels * loop on waiting for and processing requests
2316360Skarels */
2446683Sbostic #include <sys/types.h>
2546683Sbostic #include <sys/socket.h>
2646683Sbostic #include <protocols/talkd.h>
2716366Skarels #include <signal.h>
2826841Smckusick #include <syslog.h>
2946683Sbostic #include <time.h>
3046683Sbostic #include <errno.h>
3146683Sbostic #include <unistd.h>
3246683Sbostic #include <stdio.h>
3346683Sbostic #include <stdlib.h>
3446683Sbostic #include <string.h>
3537991Sbostic #include <paths.h>
3616360Skarels
3716366Skarels CTL_MSG request;
3816366Skarels CTL_RESPONSE response;
3916360Skarels
4016366Skarels int sockt;
4116366Skarels int debug = 0;
4246683Sbostic void timeout();
4316366Skarels long lastmsgtime;
4416360Skarels
4516366Skarels char hostname[32];
4616360Skarels
4716366Skarels #define TIMEOUT 30
4816366Skarels #define MAXIDLE 120
4916366Skarels
main(argc,argv)5016366Skarels main(argc, argv)
5116366Skarels int argc;
5216366Skarels char *argv[];
5316360Skarels {
5426841Smckusick register CTL_MSG *mp = &request;
5526841Smckusick int cc;
5616360Skarels
5716366Skarels if (getuid()) {
5850712Smarc fprintf(stderr, "%s: getuid: not super-user\n", argv[0]);
5916366Skarels exit(1);
6016360Skarels }
6126841Smckusick openlog("talkd", LOG_PID, LOG_DAEMON);
6226841Smckusick if (gethostname(hostname, sizeof (hostname) - 1) < 0) {
6326841Smckusick syslog(LOG_ERR, "gethostname: %m");
6426841Smckusick _exit(1);
6526841Smckusick }
6637991Sbostic if (chdir(_PATH_DEV) < 0) {
6737991Sbostic syslog(LOG_ERR, "chdir: %s: %m", _PATH_DEV);
6826841Smckusick _exit(1);
6926841Smckusick }
7026841Smckusick if (argc > 1 && strcmp(argv[1], "-d") == 0)
7126841Smckusick debug = 1;
7216366Skarels signal(SIGALRM, timeout);
7316366Skarels alarm(TIMEOUT);
7416366Skarels for (;;) {
7516366Skarels extern int errno;
7616360Skarels
7726841Smckusick cc = recv(0, (char *)mp, sizeof (*mp), 0);
7826841Smckusick if (cc != sizeof (*mp)) {
7916366Skarels if (cc < 0 && errno != EINTR)
8026841Smckusick syslog(LOG_WARNING, "recv: %m");
8116366Skarels continue;
8216366Skarels }
8316366Skarels lastmsgtime = time(0);
8426841Smckusick process_request(mp, &response);
8516360Skarels /* can block here, is this what I want? */
8626841Smckusick cc = sendto(sockt, (char *)&response,
8738638Skarels sizeof (response), 0, (struct sockaddr *)&mp->ctl_addr,
8838638Skarels sizeof (mp->ctl_addr));
8926841Smckusick if (cc != sizeof (response))
9026841Smckusick syslog(LOG_WARNING, "sendto: %m");
9116360Skarels }
9216360Skarels }
9316360Skarels
9446683Sbostic void
timeout()9516366Skarels timeout()
9616360Skarels {
9716360Skarels
9816366Skarels if (time(0) - lastmsgtime >= MAXIDLE)
9926841Smckusick _exit(0);
10016366Skarels alarm(TIMEOUT);
10116360Skarels }
102