int sendstr(int so, char * str) { if ( so < 0 ) return(0); return(writet(so, str, strlen(str), READ_ANSW_TIMEOUT)); }
/*! * Connect to UNIX domain socket "name" for IPC with new afpd master * * 1. Connect * 2. send pid, which establishes a child structure for us in the master * * @args name (r) file name to use for UNIX domain socket * @returns socket fd, -1 on error */ int ipc_client_uds(const char *name) { EC_INIT; struct sockaddr_un address; socklen_t address_length; int fd = -1; pid_t pid = getpid(); EC_NEG1_LOG( fd = socket(PF_UNIX, SOCK_STREAM, 0) ); EC_ZERO_LOG( setnonblock(fd, 1) ); address.sun_family = AF_UNIX; address_length = sizeof(address.sun_family) + sprintf(address.sun_path, name); EC_ZERO_LOG( connect(fd, (struct sockaddr *)&address, address_length) ); /* 1 */ LOG(log_debug, logtype_afpd, "ipc_client_uds: connected to master"); if (writet(fd, &pid, sizeof(pid_t), 0, 1) != sizeof(pid_t)) { LOG(log_error, logtype_afpd, "ipc_client_uds: writet: %s", strerror(errno)); EC_FAIL; } EC_CLEANUP: if (ret != 0) { return -1; } LOG(log_debug, logtype_afpd, "ipc_client_uds: fd: %d", fd); return fd; }
/* * respond - write a line to a descriptor, terminate with \n\n */ ssize_t respond(int fd, const char *response) { const char terminator[] = "\n\n"; return writet(fd, response, terminator); }
/* * writeline - write a line to a descriptor, terminate with \r\n */ ssize_t writeline(int fd, const char *line) { const char terminator[] = "\r\n"; return writet(fd, line, terminator); }
/*! * Try to find an old session and pass socket * @returns -1 on error, 0 if no matching session was found, 1 if session was found and socket passed */ int server_child_transfer_session(server_child *children, int forkid, pid_t pid, uid_t uid, int afp_socket, uint16_t DSI_requestID) { EC_INIT; server_child_fork *fork; struct server_child_data *child; fork = (server_child_fork *) children->fork + forkid; if ((child = resolve_child(fork->table, pid)) == NULL) { LOG(log_note, logtype_default, "Reconnect: no child[%u]", pid); if (kill(pid, 0) == 0) { LOG(log_note, logtype_default, "Reconnect: terminating old session[%u]", pid); kill(pid, SIGTERM); sleep(2); if (kill(pid, 0) == 0) { LOG(log_error, logtype_default, "Reconnect: killing old session[%u]", pid); kill(pid, SIGKILL); sleep(2); } } return 0; } if (!child->valid) { /* hmm, client 'guess' the pid, rogue? */ LOG(log_error, logtype_default, "Reconnect: invalidated child[%u]", pid); return 0; } else if (child->uid != uid) { LOG(log_error, logtype_default, "Reconnect: child[%u] not the same user", pid); return 0; } LOG(log_note, logtype_default, "Reconnect: transfering session to child[%u]", pid); if (writet(child->ipc_fd, &DSI_requestID, 2, 0, 2) != 2) { LOG(log_error, logtype_default, "Reconnect: error sending DSI id to child[%u]", pid); EC_STATUS(-1); goto EC_CLEANUP; } EC_ZERO_LOG(send_fd(child->ipc_fd, afp_socket)); EC_ZERO_LOG(kill(pid, SIGURG)); EC_STATUS(1); EC_CLEANUP: EC_EXIT; }
void send_error(int so, int code, char * message) { char *hdr = NULL; int hdr_len=20+strlen(message); hdr = (char *)malloc(hdr_len); if ( !hdr ) { return; } memset(hdr,0,hdr_len); snprintf(hdr,hdr_len-1, "HTTP/1.0 %3d %s\r\n\r\n", code, message); writet(so, hdr, strlen(hdr), READ_ANSW_TIMEOUT); xfree(hdr); return; }
/* ----------------- */ int ipc_child_write(int fd, uint16_t command, int len, void *msg) { char block[IPC_MAXMSGSIZE], *p; pid_t pid; uid_t uid; ssize_t ret; p = block; memset ( p, 0 , IPC_MAXMSGSIZE); if (len + IPC_HEADERLEN > IPC_MAXMSGSIZE) return -1; memcpy(p, &command, sizeof(command)); p += sizeof(command); pid = getpid(); memcpy(p, &pid, sizeof(pid_t)); p += sizeof(pid_t); /* FIXME * using uid is wrong. It will not disconnect if the new connection * is with a different user. * But we really don't want a remote kill command. */ uid = geteuid(); memcpy(p, &uid, sizeof(uid_t)); p += sizeof(uid_t); memcpy(p, &len, 4); p += 4; memcpy(p, msg, len); LOG(log_debug, logtype_afpd, "ipc_child_write(%s)", ipc_cmd_str[command]); if ((ret = writet(fd, block, len+IPC_HEADERLEN, 0, 1)) != len + IPC_HEADERLEN) { return -1; } return 0; }