diff options
Diffstat (limited to 'src/socket.c')
-rw-r--r-- | src/socket.c | 197 |
1 files changed, 78 insertions, 119 deletions
diff --git a/src/socket.c b/src/socket.c index 03ee59c..8f32ae7 100644 --- a/src/socket.c +++ b/src/socket.c @@ -1,18 +1,18 @@ -/* This file is part of Mailfromd. - Copyright (C) 2007, 2008 Sergey Poznyakoff +/* This file is part of Pies. + Copyright (C) 2007, 2008, 2009 Sergey Poznyakoff - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the - Free Software Foundation; either version 3 of the License, or (at your - option) any later version. + Pies is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3, or (at your option) + any later version. - This program is distributed in the hope that it will be useful, + Pies is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - You should have received a copy of the GNU General Public License along - with this program. If not, see <http://www.gnu.org/licenses/>. */ + You should have received a copy of the GNU General Public License + along with Pies. If not, see <http://www.gnu.org/licenses/>. */ #include "pies.h" @@ -38,18 +38,18 @@ switch_eids (uid_t *puid, gid_t *pgid, mode_t *pumask) mode_t omask = umask (*pumask); if (setegid (*pgid)) - mu_error (_("Cannot switch to EGID %lu: %s"), - (unsigned long) *pgid, mu_strerror (errno)); + logmsg (LOG_ERR, _("Cannot switch to EGID %lu: %s"), + (unsigned long) *pgid, strerror (errno)); if (seteuid (*puid)) - mu_error (_("Cannot switch to EUID %lu: %s"), - (unsigned long) *puid, mu_strerror (errno)); + logmsg (LOG_ERR, _("Cannot switch to EUID %lu: %s"), + (unsigned long) *puid, strerror (errno)); *puid = ouid; *pgid = ogid; *pumask = omask; } int -create_socket (mu_url_t url, const char *user, mode_t umaskval) +create_socket (struct pies_url *url, const char *user, mode_t umaskval) { int rc; int fd; @@ -60,73 +60,64 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval) struct sockaddr_un s_un; } addr; socklen_t socklen; - const char *scheme; uid_t uid = 0; gid_t gid = 0; int switch_back; - rc = mu_url_sget_scheme (url, &scheme); - if (rc) + if (strcmp (url->proto, "unix") == 0 + || strcmp (url->proto, "file") == 0 + || strcmp (url->proto, "socket") == 0) { - mu_error ("mu_url_sget_scheme: %s", mu_strerror (rc)); - return -1; - } - - if (strcmp (scheme, "unix") == 0 - || strcmp (scheme, "file") == 0 || strcmp (scheme, "socket") == 0) - { - const char *path = NULL; struct stat st; - size_t vpc; - char **vpairs; - char *group = NULL; + const char *group = NULL; - mu_url_sget_user (url, &user); - if (mu_url_sget_fvpairs (url, &vpc, &vpairs) == 0) + user = url->user; + if (url->argc) { size_t i; - for (i = 0; i < vpc; i++) + for (i = 0; i < url->argc; i++) { - size_t len = strcspn (vpairs[i], "="); - if (strncmp (vpairs[i], "user", len) == 0) - user = vpairs[i] + len + 1; - else if (strncmp (vpairs[i], "group", len) == 0) - group = vpairs[i] + len + 1; - else if (strncmp (vpairs[i], "umask", len) == 0) + const char *arg = url->argv[i]; + size_t len = strcspn (arg, "="); + if (strncmp (arg, "user", len) == 0) + user = arg + len + 1; + else if (strncmp (arg, "group", len) == 0) + group = arg + len + 1; + else if (strncmp (arg, "umask", len) == 0) { char *p; - unsigned long n = strtoul (vpairs[i] + len + 1, &p, 8); + unsigned long n = strtoul (arg + len + 1, &p, 8); if (*p) - mu_error (_("%s: invalid octal number (%s)"), - mu_url_to_string (url), vpairs[i] + len + 1); + logmsg (LOG_ERR, _("%s: invalid octal number (%s)"), + url->string, arg + len + 1); else if (n & ~0777) - mu_error (_("%s: invalid umask (%s)"), - mu_url_to_string (url), vpairs[i] + len + 1); + logmsg (LOG_ERR, _("%s: invalid umask (%s)"), + url->string, arg + len + 1); else umaskval = n & 0777; } - else if (strncmp (vpairs[i], "mode", len) == 0) + else if (strncmp (arg, "mode", len) == 0) { char *p; - unsigned long n = strtoul (vpairs[i] + len + 1, &p, 8); + unsigned long n = strtoul (arg + len + 1, &p, 8); if (*p) - mu_error (_("%s: invalid octal number (%s)"), - mu_url_to_string (url), vpairs[i] + len + 1); + logmsg (LOG_ERR, _("%s: invalid octal number (%s)"), + url->string, arg + len + 1); else if (n & ~0777) - mu_error (_("%s: invalid mode (%s)"), - mu_url_to_string (url), vpairs[i] + len + 1); + logmsg (LOG_ERR, _("%s: invalid mode (%s)"), + url->string, arg + len + 1); else umaskval = 0777 & ~n; } } } - + if (user) { struct passwd *pw = getpwnam (user); if (!pw) { - mu_error (_("No such user: %s"), user); + logmsg (LOG_ERR, _("no such user: %s"), user); return -1; } uid = pw->pw_uid; @@ -138,83 +129,51 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval) struct group *grp = getgrnam (group); if (!grp) { - mu_error (_("No such group: %s"), user); + logmsg (LOG_ERR, _("no such group: %s"), user); return -1; } gid = grp->gr_gid; } - rc = mu_url_sget_path (url, &path); - if (rc) - { - mu_error ("mu_url_sget_path: %s", mu_strerror (rc)); - return -1; - } - - if (strlen (path) > sizeof addr.s_un.sun_path) + if (strlen (url->path) > sizeof addr.s_un.sun_path) { errno = EINVAL; - mu_error (_("%s: UNIX socket name too long"), - mu_url_to_string (url)); + logmsg (LOG_ERR, _("%s: UNIX socket name too long"), url->path); return -1; } addr.sa.sa_family = PF_UNIX; socklen = sizeof (addr.s_un); - strcpy (addr.s_un.sun_path, path); - if (stat(path, &st)) + strcpy (addr.s_un.sun_path, url->path); + if (stat (url->path, &st)) { if (errno != ENOENT) { - mu_error (_("%s: cannot stat socket: %s"), - mu_url_to_string (url), - mu_strerror (errno)); + logmsg (LOG_ERR, _("%s: cannot stat socket: %s"), + url->string, strerror (errno)); return -1; } } else { /* FIXME: Check permissions? */ - if (!S_ISSOCK(st.st_mode)) + if (!S_ISSOCK (st.st_mode)) { - mu_error (_("%s: not a socket"), mu_url_to_string (url)); + logmsg (LOG_ERR, _("%s: not a socket"), url->string); return -1; } - if (/*rmsocket && */ unlink (path)) + if (/*rmsocket && */ unlink (url->path)) { - mu_error (_("%s: cannot unlink: %s"), - path, mu_strerror (errno)); + logmsg (LOG_ERR, _("%s: cannot unlink: %s"), + url->path, strerror (errno)); return -1; } } } - else if (strcmp (scheme, "inet") == 0) + else if (strcmp (url->proto, "inet") == 0) { - long n; - const char *host = NULL; - short port = 0; + const char *host = url->host; + short port = url->port; - rc = mu_url_get_port (url, &n); - if (rc) - { - mu_error ("mu_url_get_port: %s", mu_strerror (rc)); - return -1; - } - - if (n == 0 || (port = n) != n) - { - mu_error (_("%s: port out of range"), mu_url_to_string (url)); - return -1; - } - - rc = mu_url_sget_host (url, &host); - if (rc == MU_ERR_NOENT) - host = NULL; - else if (rc) - { - mu_error ("mu_url_sget_host: %s", mu_strerror (rc)); - return -1; - } - addr.sa.sa_family = PF_INET; socklen = sizeof (addr.s_in); @@ -225,8 +184,8 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval) struct hostent *hp = gethostbyname (host); if (!hp) { - mu_error (_("%s: Unknown host name %s"), - mu_url_to_string (url), host); + logmsg (LOG_ERR, _("%s: Unknown host name %s"), + url->string, host); return -1; } addr.sa.sa_family = hp->h_addrtype; @@ -236,25 +195,25 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval) memmove (&addr.s_in.sin_addr, hp->h_addr, 4); addr.s_in.sin_port = htons (port); break; - + default: - mu_error (_("%s: unsupported address family"), - mu_url_to_string (url)); + logmsg (LOG_ERR, _("%s: unsupported address family"), + url->string); return -1; } } } else { - mu_error ("%s: unknown scheme", mu_url_to_string (url)); + logmsg (LOG_ERR, "%s: unknown scheme", url->string); return -1; } - + fd = socket (addr.sa.sa_family, SOCK_STREAM, 0); if (fd == -1) { - mu_error (_("%s: Cannot create socket: %s"), - mu_url_to_string (url), mu_strerror (errno)); + logmsg (LOG_ERR, _("%s: cannot create socket: %s"), + url->string, strerror (errno)); return -1; } @@ -263,9 +222,9 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval) && setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (void *) &rc, sizeof (rc)) == -1) { - mu_error (_("%s: set reuseaddr failed (%s)"), - mu_url_to_string (url), mu_strerror (errno)); - close(fd); + logmsg (LOG_ERR, _("%s: set reuseaddr failed (%s)"), + url->string, strerror (errno)); + close (fd); return -1; } @@ -281,8 +240,8 @@ create_socket (mu_url_t url, const char *user, mode_t umaskval) switch_eids (&uid, &gid, &umaskval); if (rc < 0) { - mu_error (_("%s: Cannot bind: %s"), - mu_url_to_string (url), mu_strerror (errno)); + logmsg (LOG_ERR, _("%s: cannot bind: %s"), + url->string, strerror (errno)); close (fd); return -1; } @@ -297,14 +256,14 @@ open_unix_socket (const char *socket_name) if (strlen (socket_name) > sizeof addr.sun_path) { - mu_error (_("%s: UNIX socket name too long"), socket_name); + logmsg (LOG_ERR, _("%s: UNIX socket name too long"), socket_name); return -1; } fd = socket (PF_UNIX, SOCK_STREAM, 0); if (fd == -1) { - mu_error ("socket: %s", mu_strerror (errno)); + logmsg (LOG_ERR, "socket: %s", strerror (errno)); return -1; } addr.sun_family = AF_UNIX; @@ -312,7 +271,7 @@ open_unix_socket (const char *socket_name) if (connect (fd, (struct sockaddr *) &addr, sizeof (addr))) { - mu_error (_("%s: connect failed: %s"), socket_name, mu_strerror (errno)); + logmsg (LOG_ERR, _("%s: connect failed: %s"), socket_name, strerror (errno)); close (fd); return -1; } @@ -349,7 +308,7 @@ pass_fd0 (int fd, int payload) msg.msg_accrights = (caddr_t) &payload; msg.msg_accrightslen = sizeof (int); #else - mu_error (_("no way to send fd")); + logmsg (LOG_ERR, _("no way to send fd")); return 1; #endif /* HAVE_MSGHDR_MSG_CONTROL */ @@ -379,7 +338,7 @@ pass_fd (const char *socket, int fd) if (!S_ISSOCK (st.st_mode)) { - mu_error (_("%s: not a socket"), socket); + logmsg (LOG_ERR, _("%s: not a socket"), socket); break; } sockfd = open_unix_socket (socket); @@ -394,7 +353,7 @@ pass_fd (const char *socket, int fd) } if (errno != ENOENT) { - mu_error (_("cannot stat %s: %s"), socket, mu_strerror (errno)); + logmsg (LOG_ERR, _("cannot stat %s: %s"), socket, strerror (errno)); break; } } @@ -410,7 +369,7 @@ register_listener (int fd) { if (listen (fd, 8) == -1) { - mu_error (_("listen: %s"), mu_strerror (errno)); + logmsg (LOG_ERR, _("listen: %s"), strerror (errno)); return 1; } FD_SET (fd, &listenset); @@ -438,7 +397,7 @@ pies_pause () else if (rc < 0) { if (errno != EINTR) - mu_error ("select: %s", mu_strerror (errno)); + logmsg (LOG_ERR, "select: %s", strerror (errno)); break; } } |