3e43f147e3
- Trim old-style header.
285 lines
7.3 KiB
C
285 lines
7.3 KiB
C
--- skkserv/skkserv.c.orig 1997-01-21 04:16:36.000000000 +0900
|
|
+++ skkserv/skkserv.c 2013-05-06 00:49:10.000000000 +0900
|
|
@@ -102,6 +102,8 @@
|
|
|
|
#define err(m) \
|
|
{if (debug) fprintf(errout, "%s: %s\n", pgmnm, m); exit(1);}
|
|
+#define nderr(m) \
|
|
+ {fprintf(errout, "%s: %s\n", pgmnm, m); exit(1);}
|
|
|
|
/*
|
|
* Global Variables
|
|
@@ -124,18 +126,25 @@
|
|
int clientsock[MAXCLNT]; /* socket for each client */
|
|
int nclients; /* max index for active clients */
|
|
|
|
+char listenaddr[NI_MAXHOST];
|
|
+uid_t uid;
|
|
+gid_t gid;
|
|
+
|
|
main(argc, argv)
|
|
char *argv[];
|
|
{
|
|
int parg;
|
|
int setjisho = 0;
|
|
int ctlterm; /* fildes for control terminal */
|
|
+ struct passwd *pwent;
|
|
void reread();
|
|
|
|
pgmnm = argv[0];
|
|
debug = 0;
|
|
errout = stderr;
|
|
portnum = 0;
|
|
+ uid = getuid();
|
|
+ gid = getgid();
|
|
|
|
/* The following patch (a work-around due to "rsh" bug) was pointed */
|
|
/* out by kazushi@kubota.co.jp in the message "714" in SKK-ML */
|
|
@@ -155,7 +164,7 @@
|
|
if (parg + 1 == argc) showusage();
|
|
if ((errout = fopen(argv[++parg], "w")) == NULL) {
|
|
fprintf(stderr, "%s: opening logfile \"%s\" failed\n",
|
|
- pgmnm, *argv[parg]);
|
|
+ pgmnm, argv[parg]);
|
|
exit(1);
|
|
}
|
|
debug = 1; break;
|
|
@@ -166,6 +175,24 @@
|
|
case 'P':
|
|
if (parg +1 == argc) showusage();
|
|
portnum = atoi(argv[++parg]); break;
|
|
+ case 'u':
|
|
+ case 'U':
|
|
+ if (parg + 1 == argc) showusage();
|
|
+ pwent = getpwnam(argv[++parg]);
|
|
+ if (pwent == NULL) {
|
|
+ fprintf(stderr,
|
|
+ "%s: invalid uid \"%s\"\n", pgmnm, argv[parg]);
|
|
+ exit(1);
|
|
+ }
|
|
+ uid = pwent->pw_uid;
|
|
+ gid = pwent->pw_gid;
|
|
+ break;
|
|
+ case 'a':
|
|
+ case 'A':
|
|
+ if (parg +1 == argc) showusage();
|
|
+ strncpy(listenaddr, argv[++parg], sizeof(listenaddr) - 1);
|
|
+ listenaddr[sizeof(listenaddr) - 1] = '\0';
|
|
+ break;
|
|
default: showusage();
|
|
}
|
|
} else if (setjisho == 0) {
|
|
@@ -183,6 +210,17 @@
|
|
exit(1);
|
|
}
|
|
|
|
+ if (setgid(gid) == -1) {
|
|
+ fprintf(stderr,
|
|
+ "%s: setgid() failed\n", pgmnm);
|
|
+ exit(1);
|
|
+ }
|
|
+ if (setuid(uid) == -1) {
|
|
+ fprintf(stderr,
|
|
+ "%s: setuid() failed\n", pgmnm);
|
|
+ exit(1);
|
|
+ }
|
|
+
|
|
set_hname();
|
|
|
|
/* make socket */
|
|
@@ -192,8 +230,18 @@
|
|
mkjtab();
|
|
|
|
if (!debug) {
|
|
+ pid_t pid;
|
|
/* parent process exits now */
|
|
- if (fork() != 0) exit(0);
|
|
+ pid = fork();
|
|
+ if (pid != 0) {
|
|
+ if (pid == -1)
|
|
+ err("fork");
|
|
+ exit(0);
|
|
+ }
|
|
+ /* child process */
|
|
+#ifdef __FreeBSD__
|
|
+ daemon(0, 0);
|
|
+#else
|
|
|
|
fclose(stdin);
|
|
fclose(stdout);
|
|
@@ -215,6 +263,7 @@
|
|
signal(SIGHUP, SIG_IGN);
|
|
if (fork() != 0) exit(0);
|
|
#endif
|
|
+#endif
|
|
} else { /* debug mode */
|
|
fprintf(errout, "SKK-JISYO is %s\n", jname);
|
|
fflush(errout);
|
|
@@ -226,15 +275,18 @@
|
|
/* 1993/6/5 by kam, re-read dictionary by "INT" signal */
|
|
|
|
nclients = 0;
|
|
+ fprintf(errout, "leave main\n");
|
|
main_loop();
|
|
}
|
|
|
|
showusage()
|
|
{
|
|
fprintf(stderr,
|
|
- "Usage: %s [-d] [-l logfile] [-p port] \n", pgmnm);
|
|
+ "Usage: %s [-d] [-l logfile] [-p port] [-a listenaddr] [-u uid]\n",
|
|
+ pgmnm);
|
|
fprintf(stderr,
|
|
- " %s [-d] [-l logfile] [-p port] skk-jisho\n", pgmnm);
|
|
+ " %s [-d] [-l logfile] [-p port] [-a listenaddr] [-u uid]"
|
|
+ " skk-jisho\n", pgmnm);
|
|
exit(1);
|
|
}
|
|
|
|
@@ -249,27 +301,41 @@
|
|
|
|
bzero((char*)&sin, sizeof(sin));
|
|
sin.sin_family = AF_INET;
|
|
- sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
+ if (listenaddr[0] == '\0') {
|
|
+ sin.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
+ } else {
|
|
+ if (!inet_aton(listenaddr, &sin.sin_addr)) {
|
|
+ struct hostent *hp;
|
|
+ struct in_addr **pptr;
|
|
+
|
|
+ if ((hp = gethostbyname(listenaddr)) == NULL) {
|
|
+ nderr("could not resolve the specified listen address");
|
|
+ }
|
|
+ pptr = (struct in_addr **)hp->h_addr_list;
|
|
+ memcpy(&sin.sin_addr.s_addr, pptr[0], sizeof(struct in_addr));
|
|
+ }
|
|
+ }
|
|
+
|
|
if (portnum == 0) {
|
|
#ifdef PORTNUM
|
|
portnum = PORTNUM;
|
|
#else
|
|
if ((sp = getservbyname(SERVICE_NAME, "tcp")) == NULL)
|
|
- err("service name is undefined in /etc/services file");
|
|
+ nderr("service name is undefined in /etc/services file");
|
|
portnum = ntohs(sp->s_port);
|
|
#endif
|
|
}
|
|
sin.sin_port = htons(portnum);
|
|
|
|
if ((initsock = socket(PF_INET, SOCK_STREAM, 0)) < 0)
|
|
- err("socket error; socket cannot be created");
|
|
+ nderr("socket error; socket cannot be created");
|
|
if (setsockopt(initsock, SOL_SOCKET, SO_REUSEADDR,
|
|
&optbuf, sizeof(optbuf)) < 0)
|
|
- err("socket error; cannot set socket option");
|
|
+ nderr("socket error; cannot set socket option");
|
|
if (bind(initsock, (struct sockaddr *)&sin, sizeof(sin))< 0)
|
|
- err("bind error; the socket is already used");
|
|
+ nderr("bind error; the socket is already used");
|
|
if (listen(initsock, MAXQUE) < 0)
|
|
- err("listen error; something wrong happened with the socket");
|
|
+ nderr("listen error; something wrong happened with the socket");
|
|
if (debug) {
|
|
fprintf(errout, "file descriptor for initsock is %d\n", initsock);
|
|
fflush(errout);
|
|
@@ -382,6 +448,10 @@
|
|
code = KANA_END;
|
|
|
|
while ((c = fgetc(jisho)) != EOF) {
|
|
+ if (c == '>') {
|
|
+ fgets(buf, BUFSIZE, jisho);
|
|
+ continue;
|
|
+ }
|
|
target = ((c & 0xff)<< 8) | (fgetc(jisho) & 0xff);
|
|
if (target == STRMARK) {
|
|
fgets(buf, BUFSIZE, jisho);
|
|
@@ -452,10 +522,17 @@
|
|
* server main loop
|
|
*/
|
|
|
|
+struct rfds {
|
|
+ fd_set fds;
|
|
+ int maxfd;
|
|
+};
|
|
+
|
|
+struct rfds getrfds(void);
|
|
+
|
|
main_loop()
|
|
{
|
|
+ struct rfds r;
|
|
fd_set readfds, writefds, exceptfds;
|
|
- fd_set getrfds();
|
|
struct sockaddr_in from;
|
|
int len;
|
|
register int i;
|
|
@@ -463,8 +540,10 @@
|
|
FD_ZERO(&writefds);
|
|
FD_ZERO(&exceptfds);
|
|
for(;;) { /* infinite loop; waiting for client's request */
|
|
- readfds = getrfds();
|
|
- if (select(MAXDTAB, &readfds, &writefds, &exceptfds, NULL) < 0) {
|
|
+ r = getrfds();
|
|
+ fprintf(errout, "before select: r.maxfd = %d\n", r.maxfd);
|
|
+ readfds = r.fds;
|
|
+ if (select(r.maxfd + 1, &readfds, &writefds, &exceptfds, NULL) < 0) {
|
|
if (errno == EINTR) /* if signal happens */
|
|
continue;
|
|
err("select error; something wrong happened with the socket");
|
|
@@ -476,7 +555,7 @@
|
|
|
|
if (FD_ISSET(initsock, &readfds)) {
|
|
len = sizeof(from);
|
|
- if ((clientsock[nclients ++] = accept(initsock, &from, &len)) < 0) {
|
|
+ if ((clientsock[nclients ++] = accept(initsock, (struct sockaddr*)&from, &len)) < 0) {
|
|
err("accept error; something wrong happened with the socket");
|
|
}
|
|
if (nclients >= MAXDTAB - 3 - debug * 2) {
|
|
@@ -498,10 +577,12 @@
|
|
|
|
if (debug) {
|
|
fprintf(errout, "number of clients %d\n", nclients);
|
|
- fprintf(errout, "file descriptors of clients are :");
|
|
+ if (nclients) {
|
|
+ fprintf(errout, "file descriptors of clients are:");
|
|
for (i = 0; i < nclients; i ++)
|
|
- fprintf(errout, "%d:", clientsock[i]);
|
|
+ fprintf(errout, " %d%s", clientsock[i], (i < nclients - 1) ? "," : "");
|
|
fputs("\n", errout);
|
|
+ }
|
|
fflush(errout);
|
|
}
|
|
}
|
|
@@ -511,16 +592,24 @@
|
|
* get bit pattern of read file descriptor
|
|
*/
|
|
|
|
-fd_set getrfds()
|
|
+struct rfds
|
|
+getrfds(void)
|
|
{
|
|
- fd_set rfds;
|
|
+ struct rfds r;
|
|
register int i;
|
|
|
|
- FD_ZERO(&rfds);
|
|
- FD_SET(initsock, &rfds);
|
|
- for (i = 0; i < nclients; i ++)
|
|
- FD_SET(clientsock[i], &rfds);
|
|
- return (rfds);
|
|
+ FD_ZERO(&r.fds);
|
|
+ FD_SET(initsock, &r.fds);
|
|
+ r.maxfd = initsock;
|
|
+ for (i = 0; i < nclients; i ++) {
|
|
+ if (clientsock[i] > 0) {
|
|
+ FD_SET(clientsock[i], &r.fds);
|
|
+ if (clientsock[i] > r.maxfd)
|
|
+ r.maxfd = clientsock[i];
|
|
+ }
|
|
+ }
|
|
+
|
|
+ return (r);
|
|
}
|
|
|
|
/*
|