/* * Secure X Message Passing Library v2 examples. * * (c) Originally written by somebody else ... * (c) Alexander Vdolainen 2013-2015 * * libsxmp is free software: you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * libsxmp 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 Lesser 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 ."; * * This is a simple helpers to make code more clean; * */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include int openlistener_socket(int port) { int sd; struct sockaddr_in addr; sd = socket(PF_INET, SOCK_STREAM, 0); memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; addr.sin_port = htons(port); addr.sin_addr.s_addr = INADDR_ANY; if(bind(sd, (struct sockaddr*)&addr, sizeof(addr)) != 0) { perror("can't bind port"); abort(); } if(listen(sd, 10) != 0) { perror("Can't configure listening port"); abort(); } return sd; } char *nodehostname(void) { char *hm = malloc(HOST_NAME_MAX); if(!gethostname(hm, HOST_NAME_MAX)) return hm; else { if(hm) free(hm); return NULL; } } static inline int __removechar(char *b, size_t chrs) { char *c = b + chrs; size_t blen = strlen(c) + sizeof(char); memmove(b, c, blen); return chrs; } int normalize_path(char *path) { char *obuf = path; int cutlen; /* first remove useless / if found */ while((obuf = strchr(obuf, '/'))) { obuf++; while(*obuf == '/') __removechar(obuf, 1); } obuf = path; /* much cleaner now */ while(*obuf != '\0') { if(*obuf == '.' && *(obuf - 1) == '/') { if(!strcmp(obuf, "./")) __removechar(obuf, 2); else if(!strcmp(obuf, "../")) { cutlen = strlen(path) - strlen(obuf); if(cutlen < 4) return -1; else cutlen = 4; obuf -= 2; while(*obuf != '/') { obuf--; cutlen++; } __removechar(obuf, cutlen); } } obuf++; } return 0; } /* syslog stuff */ static size_t writer(void *cookie, char const *data, size_t len) { (void)cookie; syslog(LOG_DEBUG, "%.*s", (int)len, data); return len; } static int noop(void) { return 0; } static cookie_io_functions_t log_fns = { (void*) noop, (void*) writer, (void*) noop, (void*) noop }; void tosyslog(FILE **pfp) { setvbuf(*pfp = fopencookie(NULL, "w", log_fns), NULL, _IOLBF, 0); } /* daemonization stuff */ #define DM_MAX_CLOSE 8192 int daemonize(void) { pid_t pid; /* fork */ pid = fork(); if (pid == -1) { perror("fork() failed"); return EFAULT; } else if (pid != 0) { exit(EXIT_SUCCESS); } /* create new session and progress group */ if (setsid() == -1) { perror("setsid() failed"); return EFAULT; } /* set the working directory to the root directory */ if (chdir("/") == -1) { perror("chdir() failed"); return EFAULT; } /* close all open files */ int fd; int maxfd = sysconf(_SC_OPEN_MAX); if (maxfd == -1) maxfd = DM_MAX_CLOSE; /* if this limit is indeterminate, take a guess */ for (fd = 0; fd < maxfd; fd++) close(fd); /* reopen standard fd's /dev/null */ close(STDIN_FILENO); fd = open("/dev/null", O_RDWR); if (fd != STDIN_FILENO) { /* fd should be 0 */ return EBADFD; } if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO) { return EBADFD; } if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO) { return EBADFD; } /* redirect output to syslog as well */ tosyslog(&stdout); tosyslog(&stderr); return 0; }