summaryrefslogtreecommitdiff
path: root/mda/lib/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'mda/lib/util.c')
-rw-r--r--mda/lib/util.c185
1 files changed, 185 insertions, 0 deletions
diff --git a/mda/lib/util.c b/mda/lib/util.c
new file mode 100644
index 000000000..147da6885
--- /dev/null
+++ b/mda/lib/util.c
@@ -0,0 +1,185 @@
+/* GNU Mailutils -- a suite of utilities for electronic mail
+ Copyright (C) 2007-2019 Free Software Foundation, Inc.
+
+ GNU Mailutils 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.
+
+ GNU Mailutils 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 GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "libmda.h"
+
+int exit_code;
+
+void
+mda_close_fds (void)
+{
+ int i;
+ long fdlimit = sysconf (_SC_OPEN_MAX);
+ for (i = 3; i < fdlimit; i++)
+ close (i);
+}
+
+int
+mda_switch_user_id (struct mu_auth_data *auth, int user)
+{
+ int rc;
+ uid_t uid;
+
+ if (!auth || auth->change_uid == 0)
+ return 0;
+
+ if (user)
+ uid = auth->uid;
+ else
+ uid = 0;
+
+#if defined(HAVE_SETREUID)
+ rc = setreuid (0, uid);
+#elif defined(HAVE_SETRESUID)
+ rc = setresuid (-1, uid, -1);
+#elif defined(HAVE_SETEUID)
+ rc = seteuid (uid);
+#else
+# error "No way to reset user privileges?"
+#endif
+ if (rc < 0)
+ mda_error ("setreuid(0, %d): %s (r=%d, e=%d)",
+ uid, strerror (errno), getuid (), geteuid ());
+ return rc;
+}
+
+static int temp_errors[] = {
+#ifdef EAGAIN
+ EAGAIN, /* Try again */
+#endif
+#ifdef EBUSY
+ EBUSY, /* Device or resource busy */
+#endif
+#ifdef EPROCLIM
+ EPROCLIM, /* Too many processes */
+#endif
+#ifdef EUSERS
+ EUSERS, /* Too many users */
+#endif
+#ifdef ECONNABORTED
+ ECONNABORTED, /* Software caused connection abort */
+#endif
+#ifdef ECONNREFUSED
+ ECONNREFUSED, /* Connection refused */
+#endif
+#ifdef ECONNRESET
+ ECONNRESET, /* Connection reset by peer */
+#endif
+#ifdef EDEADLK
+ EDEADLK, /* Resource deadlock would occur */
+#endif
+#ifdef EDEADLOCK
+ EDEADLOCK, /* Resource deadlock would occur */
+#endif
+#ifdef EFBIG
+ EFBIG, /* File too large */
+#endif
+#ifdef EHOSTDOWN
+ EHOSTDOWN, /* Host is down */
+#endif
+#ifdef EHOSTUNREACH
+ EHOSTUNREACH, /* No route to host */
+#endif
+#ifdef EMFILE
+ EMFILE, /* Too many open files */
+#endif
+#ifdef ENETDOWN
+ ENETDOWN, /* Network is down */
+#endif
+#ifdef ENETUNREACH
+ ENETUNREACH, /* Network is unreachable */
+#endif
+#ifdef ENETRESET
+ ENETRESET, /* Network dropped connection because of reset */
+#endif
+#ifdef ENFILE
+ ENFILE, /* File table overflow */
+#endif
+#ifdef ENOBUFS
+ ENOBUFS, /* No buffer space available */
+#endif
+#ifdef ENOMEM
+ ENOMEM, /* Out of memory */
+#endif
+#ifdef ENOSPC
+ ENOSPC, /* No space left on device */
+#endif
+#ifdef EROFS
+ EROFS, /* Read-only file system */
+#endif
+#ifdef ESTALE
+ ESTALE, /* Stale NFS file handle */
+#endif
+#ifdef ETIMEDOUT
+ ETIMEDOUT, /* Connection timed out */
+#endif
+#ifdef EWOULDBLOCK
+ EWOULDBLOCK, /* Operation would block */
+#endif
+};
+
+static void
+guess_retval (int ec)
+{
+ int i;
+ /* Temporary failures override hard errors. */
+ if (exit_code == EX_TEMPFAIL)
+ return;
+#ifdef EDQUOT
+ if (ec == EDQUOT)
+ {
+ exit_code = EX_QUOTA;
+ return;
+ }
+#endif
+
+ for (i = 0; i < sizeof (temp_errors)/sizeof (temp_errors[0]); i++)
+ if (temp_errors[i] == ec)
+ {
+ exit_code = EX_TEMPFAIL;
+ return;
+ }
+ exit_code = EX_UNAVAILABLE;
+}
+
+void
+mda_error (const char *fmt, ...)
+{
+ va_list ap;
+ guess_retval (errno);
+ va_start (ap, fmt);
+ mu_verror (fmt, ap);
+ va_end (ap);
+}
+
+static struct mu_cli_capa mda_cli_capa[] = {
+ { "forward", NULL, mda_forward_cfg },
+ { "deliver", mda_deliver_options, mda_deliver_cfg },
+#ifdef USE_MAILBOX_QUOTAS
+ { "quota", NULL, mda_mailquota_cfg },
+#endif
+ { "script", mda_script_options, mda_script_cfg },
+ { NULL }
+};
+
+void
+mda_cli_capa_init (void)
+{
+ size_t i;
+
+ for (i = 0; mda_cli_capa[i].name; i++)
+ mu_cli_capa_register (&mda_cli_capa[i]);
+}

Return to:

Send suggestions and report system problems to the System administrator.