freebsd-ports/japanese/skkserv/files/patch-skkserv.c
2013-05-05 15:53:04 +00:00

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);
}
/*