1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
|
#include <sys/types.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/unistd.h>
#include <sys/stat.h>
#include <stdio.h>
#include <dirent.h>
#include <errno.h>
extern char **environ;
const char* STDIN_FN_KEY = "STDIN_FILENAME=";
#warning "zomne.c is deprecated, don't use it."
int copyfds(int ind, int outd) {
size_t read, written;
char scratch[4096];
FILE* in;
FILE* out;
int rv = 0;
in = fdopen(ind, "r"); out = fdopen(outd, "w");
for (;;) {
read = fread(scratch, 1, sizeof scratch, in);
if (read != sizeof scratch && ferror(in))
goto cleanup;
if (read == 0)
break;
written = fwrite(scratch, 1, read, out);
if (written != read)
goto cleanup; }
rv = 1;
cleanup:
fclose(in);
fclose(out);
return rv; }
int err_die(char* argv) {
printf("Content-Type: text/plain\r\n\r\n");
printf(argv);
printf("\r\n");
return 1; }
int get_config(char* whatdir, char* whatfile, char* whatbuffer, int die) {
char scratch[MAXPATHLEN+1024];
FILE *handle;
struct stat st;
if (whatdir)
chdir(whatdir);
handle = fopen(whatfile, "r");
if (!handle) {
if (die) {
sprintf(scratch, "Could not open file '%s' in directory '%s'. errno = %d.\n", whatfile, whatdir, errno);
return err_die(scratch); }
return 1; }
fread(whatbuffer, 1, MAXPATHLEN, handle);
fclose(handle);
return 0; }
int start_twistd(char* basedir) {
char scratch[MAXPATHLEN];
char env_value[MAXPATHLEN];
char tacfile[MAXPATHLEN];
FILE* handle;
DIR* environ_dir;
struct dirent *fl;
int err, startup_complete_sock, startup_complete_accepted;
struct sockaddr_un server;
sprintf(tacfile, "%s/%s", basedir, "zomne.tac");
handle = fopen(tacfile, "r");
if (!handle) return err_die("Could not open tacfile zomne.tac");
fclose(handle);
// We have an "environment" directory, which is full of files
// which are named with environment keys and who contain environment values.
// Iterate all the files, and set keys in the environment so the child sees
// them.
if (!((environ_dir = opendir("zomne_environ")) == NULL)) {
chdir("zomne_environ");
while ((fl = readdir(environ_dir)) != NULL) {
if (err = get_config("", fl->d_name, env_value, 1)) return err;
if (setenv(fl->d_name, env_value, 1))
return err_die("Unknown error setting environment"); } }
chdir(basedir);
startup_complete_sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (startup_complete_sock < 0) return err_die("Error creating socket for startup completion notification");
server.sun_family = AF_UNIX;
strcpy(server.sun_path, "zomne_startup_complete.socket");
if (bind(startup_complete_sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)))
return err_die("Error binding zomne_startup_complete.socket");
listen(startup_complete_sock, 1);
sprintf(scratch, "twistd -oy %s", tacfile);
system(scratch);
// This blocks until the twisted process calls connectUNIX('zomne_startup_complete.socket')
startup_complete_accepted = accept(startup_complete_sock, 0, 0);
close(startup_complete_accepted);
close(startup_complete_sock);
unlink("zomne_startup_complete.socket");
return 0; }
int main(int argc, char* argv[]) {
struct sockaddr_un addr;
int s, tempfd, bytesread, err, pid;
char scratch[MAXPATHLEN];
char basedir[MAXPATHLEN];
char stdin_temp[MAXPATHLEN];
char **enviter = environ;
FILE* config_file;
char *program_name;
program_name = (char*)getenv("SCRIPT_NAME");
if (!program_name)
// If argv[0] contains any slashes, we just want the bit after the slash
// aka argv[0].split('/')[-1]
program_name = argv[0];
while (*program_name++); // Move the pointer to the end of the string
while (*(program_name-1) != '/')
program_name--; // Move the pointer back to the slash
sprintf(scratch, ".%s.dir", program_name);
if (err = get_config("", scratch, basedir, 1)) return err;
chdir(basedir);
if (get_config(basedir, "twistd.pid", scratch, 0)) {
// No pidfile, got to start twisted
if (err = start_twistd(basedir)) return err;
} else {
// TODO Send a signal to the pid to see if it is alive.
// Got an error?
// It is dead, start it up
}
s = socket(AF_UNIX, SOCK_STREAM, 0);
if (s < 0) {
return err_die("Error creating socket"); }
sprintf(addr.sun_path, "%s%s", basedir, "zomne.socket");
addr.sun_family = AF_UNIX;
if (connect(s, (struct sockaddr *)&addr, sizeof(struct sockaddr_un))) {
return err_die("Couldn't connect to server");
} else {
while (*enviter != 0) {
sprintf(scratch, "%u:", strlen(*enviter));
send(s, scratch, strlen(scratch), 0);
send(s, *enviter, strlen(*enviter), 0);
send(s, ",", strlen(","), 0);
enviter += 1; }
getcwd(scratch, MAXPATHLEN);
sprintf(stdin_temp, "%s/%s", scratch, "tmp.zomneXXXXXX");
tempfd = mkstemp(stdin_temp);
copyfds(STDIN_FILENO, tempfd);
sprintf(scratch, "%u:%s%s",
strlen(STDIN_FN_KEY) + strlen(stdin_temp),
STDIN_FN_KEY,
stdin_temp);
send(s, scratch, strlen(scratch), 0);
while (bytesread = recv(s, scratch, 1024, 0)) {
fwrite(scratch, 1, bytesread, stdout); }
unlink(stdin_temp); }
close(s); }
|