--- lmtp2nntp_config.c 2002/01/31 09:03:58 1.19
+++ lmtp2nntp_config.c 2002/01/31 10:14:54 1.20
@@ -257,6 +257,108 @@
catch (ex)
rethrow;
+ /* --bind SINGLE */
+ try {
+ if ( (val_get(ctx->val, "option.bind", &ov) != VAL_OK)
+ || (ov->ndata != 1)
+ || (ov->data.s == NULL)
+ ) throw(0,0,0);
+ log1(ctx, TRACE, "--bind = \"%s\"", ov->data.s);
+
+ /* dash means stdio */
+ if (strcmp(ov->data.s, "-") != 0) { //FIXME does this work with popt()?
+ if ((rc = sa_create(&ctx->saServerbind)) != SA_OK) {
+ log1(ctx, ERROR, "option --bind, creating TCP socket (internal) failed with \"%s\"",
+ sa_error(rc));
+ throw(0,0,0);
+ }
+ if ((rc = sa_addr_create(&ctx->saaServerbind)) != SA_OK) {
+ log1(ctx, ERROR, "option --bind, create address (internal) failed with \"%s\"",
+ sa_error(rc));
+ throw(0,0,0);
+ }
+ /* slash means UNIX socket */
+ if (ov->data.s[0] == '/') {
+ char *cpPath;
+ char *cpPerm;
+ int nPerm;
+ int n;
+ int i;
+
+ cpPath = strdup(optarg);
+ cpPerm = NULL;
+ nPerm = -1;
+ if ((cpPerm = strrchr(cpPath, ':')) != NULL) {
+ *cpPerm++ = '\0';
+ nPerm = 0;
+ for (i = 0; i < 4 && cpPerm[i] != '\0'; i++) {
+ if (!isdigit((int)cpPerm[i])) {
+ nPerm = -1;
+ break;
+ }
+ n = cpPerm[i] - '0';
+ if (n > 7) {
+ nPerm = -1;
+ break;
+ }
+ nPerm = ((nPerm << 3) | n);
+ }
+ if (nPerm == -1 || cpPerm[i] != '\0') {
+ log1(ctx, ERROR, "option --bind, invalid permissions \"%s\"",
+ cpPerm);
+ throw(0,0,0);
+ }
+ }
+ if ((rc = sa_addr_u2a(ctx->saaServerbind, "unix:%s", cpPath)) != SA_OK) {
+ log2(ctx, ERROR, "option --bind, parsing alternate IO guessing UNIX socket (%s) failed with \"%s\"",
+ cpPath, sa_error(rc));
+ throw(0,0,0);
+ }
+ if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) {
+ log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"",
+ cpPath, sa_error(rc));
+ throw(0,0,0);
+ }
+ if (nPerm != -1) {
+ if (chmod(cpPath, nPerm) == -1) {
+ log3(ctx, ERROR, "option --bind, chmod (%s, 0%o) failed with \"%s\"",
+ cpPath, nPerm, strerror(errno));
+ throw(0,0,0);
+ }
+ }
+ if (getuid() == 0 && getuid() != ctx->option_uid) {
+ if (chown(cpPath, ctx->option_uid, -1) == -1) {
+ log3(ctx, ERROR, "option --bind, chown (%s, %d) failed with \"%s\"",
+ cpPath, ctx->option_uid, strerror(errno));
+ throw(0,0,0);
+ }
+ }
+ free(cpPath);
+ }
+ /* otherwise assume INET socket */
+ else {
+ if ((rc = sa_addr_u2a(ctx->saaServerbind, "inet://%s", ov->data.s)) != SA_OK) {
+ log2(ctx, ERROR, "option --bind, parsing alternate IO guessing INET socket (%s) failed with \"%s\"",
+ ov->data.s, sa_error(rc));
+ throw(0,0,0);
+ }
+ if ((rc = sa_bind(ctx->saServerbind, ctx->saaServerbind)) != SA_OK) {
+ log2(ctx, ERROR, "option --bind, bind (%s) failed with \"%s\"",
+ ov->data.s, sa_error(rc));
+ throw(0,0,0);
+ }
+ }
+ /* for either sockets */
+ if ((rc = sa_listen(ctx->saServerbind, -1)) != SA_OK) {
+ log2(ctx, ERROR, "option --bind, listen (%s) failed with \"%s\"",
+ ov->data.s, sa_error(rc));
+ throw(0,0,0);
+ }
+ }
+ }
+ catch (ex)
+ rethrow;
+
CUS:
return;
}
|