aboutsummaryrefslogtreecommitdiff
path: root/src/socket.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/socket.c')
-rw-r--r--src/socket.c197
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;
}
}

Return to:

Send suggestions and report system problems to the System administrator.