2 * $Id: server_ipc.c,v 1.4 2010-01-21 14:14:49 didg Exp $
4 * All rights reserved. See COPYRIGHT.
7 * ipc between parent and children.
14 #include <sys/types.h>
22 #include <atalk/server_child.h>
23 #include <atalk/server_ipc.h>
24 #include <atalk/logger.h>
26 typedef struct ipc_header {
34 static int pipe_fd[2];
36 void *server_ipc_create(void)
44 /* ----------------- */
45 int server_ipc_child(void *obj _U_)
52 /* ----------------- */
53 int server_ipc_parent(void *obj _U_)
58 /* ----------------- */
59 static int ipc_kill_token (struct ipc_header *ipc, server_child *children)
63 if (ipc->len != sizeof(pid_t)) {
66 /* assume signals SA_RESTART set */
67 memcpy (&pid, ipc->msg, sizeof(pid_t));
69 LOG(log_info, logtype_default, "child %d user %d disconnected", pid, ipc->uid);
70 server_child_kill_one(children, CHILD_DSIFORK, pid, ipc->uid);
74 /* ----------------- */
75 static int ipc_get_session (struct ipc_header *ipc, server_child *children)
82 if (ipc->len < (sizeof(idlen) + sizeof(boottime)) ) {
86 memcpy (&idlen, p, sizeof(idlen));
87 idlen = ntohl (idlen);
90 memcpy (&boottime, p, sizeof(boottime));
91 p += sizeof(boottime);
93 if (ipc->len < idlen + sizeof(idlen) + sizeof(boottime)) {
96 if (NULL == (clientid = (char*) malloc(idlen)) ) {
99 memcpy (clientid, p, idlen);
101 server_child_kill_one_by_id (children, CHILD_DSIFORK, ipc->child_pid, ipc->uid, idlen, clientid, boottime);
102 /* FIXME byte to ascii if we want to log clientid */
103 LOG (log_debug, logtype_afpd, "ipc_get_session: len: %u, idlen %d, time %x", ipc->len, idlen, boottime);
107 #define IPC_HEADERLEN 14
108 #define IPC_MAXMSGSIZE 90
117 int server_ipc_read(server_child *children)
120 struct ipc_header ipc;
121 char buf[IPC_MAXMSGSIZE], *p;
123 if ((ret = read(pipe_fd[0], buf, IPC_HEADERLEN)) != IPC_HEADERLEN) {
124 LOG (log_info, logtype_afpd, "Reading IPC header failed (%u of %u bytes read)", ret, IPC_HEADERLEN);
130 memcpy(&ipc.command, p, sizeof(ipc.command));
131 p += sizeof(ipc.command);
133 memcpy(&ipc.child_pid, p, sizeof(ipc.child_pid));
134 p += sizeof(ipc.child_pid);
136 memcpy(&ipc.uid, p, sizeof(ipc.uid));
137 p += sizeof(ipc.uid);
139 memcpy(&ipc.len, p, sizeof(ipc.len));
141 /* This should never happen */
142 if (ipc.len > (IPC_MAXMSGSIZE - IPC_HEADERLEN))
144 LOG (log_info, logtype_afpd, "IPC message exceeds allowed size (%u)", ipc.len);
148 memset (buf, 0, IPC_MAXMSGSIZE);
150 if ((ret = read(pipe_fd[0], buf, ipc.len)) != (int) ipc.len) {
151 LOG (log_info, logtype_afpd, "Reading IPC message failed (%u of %u bytes read)", ret, ipc.len);
157 LOG (log_debug, logtype_afpd, "ipc_read: command: %u, pid: %u, len: %u", ipc.command, ipc.child_pid, ipc.len);
162 return (ipc_kill_token(&ipc, children));
165 return (ipc_get_session(&ipc, children));
168 LOG (log_info, logtype_afpd, "ipc_read: unknown command: %d", ipc.command);
174 /* ----------------- */
175 int server_ipc_write( u_int16_t command, int len, void *msg)
177 char block[IPC_MAXMSGSIZE], *p;
182 memset ( p, 0 , IPC_MAXMSGSIZE);
183 if (len + IPC_HEADERLEN > IPC_MAXMSGSIZE)
186 memcpy(p, &command, sizeof(command));
187 p += sizeof(command);
190 memcpy(p, &pid, sizeof(pid_t));
194 * using uid is wrong. It will not disconnect if the new connection
195 * is with a different user.
196 * But we really don't want a remote kill command.
199 memcpy(p, &uid, sizeof(uid_t));
207 LOG (log_debug, logtype_afpd, "ipc_write: command: %u, pid: %u, msglen: %u", command, pid, len);
208 return write(pipe_fd[1], block, len+IPC_HEADERLEN );