/*** open_unixsock ************************************************************/ int open_unixsock(struct in_addr inetaddr) { struct sockaddr_un where; struct stat st; char *dir; int s; if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { warn("socket: %s", strerror(errno)); return s; } callmgr_name_unixsock( &where, inetaddr, localbind); if (stat(where.sun_path, &st) >= 0) { warn("Call manager for %s is already running.", inet_ntoa(inetaddr)); close(s); return -1; } /* Make sure path is valid. */ dir = dirnamex(where.sun_path); if (!make_valid_path(dir, 0770)) fatal("Could not make path to %s: %s", where.sun_path, strerror(errno)); free(dir); if (bind(s, (struct sockaddr *) &where, sizeof(where)) < 0) { warn("bind: %s", strerror(errno)); close(s); return -1; } chmod(where.sun_path, 0777); listen(s, 127); return s; }
/* ensure dirname exists, creating it if necessary. */ int make_valid_path(char *dir, mode_t mode) { struct stat st; char *tmp = NULL, *path = stripslash(strdup(dir)); int retval; if (stat(path, &st) == 0) { /* file exists */ if (S_ISDIR(st.st_mode)) { retval = 1; goto end; } else { retval = 0; goto end; } /* not a directory. Oops. */ } /* Directory doesn't exist. Let's make it. */ /* Make parent first. */ if (!make_valid_path(tmp = dirnamex(path), mode)) { retval = 0; goto end; } /* Now make this 'un. */ if (mkdir(path, mode) < 0) { retval = 0; goto end; } /* Success. */ retval = 1; end: if (tmp != NULL) free(tmp); if (path != NULL) free(path); return retval; }