#include #include #include #include #include #include #include #include #include #include #include typedef unsigned long long ull; typedef struct tag_Job { char *fname; char *buf; unsigned len; unsigned maxlen; unsigned tries; unsigned case_no; unsigned error; } Job; static void xit(int rc, const char *msg, ...) { va_list v; va_start(v, msg); vfprintf(rc ? stderr : stdout, msg, v); exit(rc); va_end(v); } static int parse_buf(const char *buf, unsigned *case_no, unsigned *tries, unsigned *error) { const char *p; int dummy; p = strstr(buf, "# Tries"); if (p == 0 || sscanf(p+7, "%u", tries) != 1) return 1; p = strstr(buf, "# Error"); if (p == 0 || sscanf(p+7, "%u => %d", &dummy, error) != 2) return 2; p = strstr(buf, "# Case"); if (p == 0 || sscanf(p+6, "%u", case_no) != 1) return 3; return 0; } static int pick_job(int old, int curr, double fuzz) { double p; if (old >= curr) return 1; if (fuzz <= 0) return 0; p = exp((old-curr)/fuzz); return random() < RAND_MAX*p; } int main( int argc, char *argv[] ) { int i; int sockfd; int buf_sz = 0; char *buf = 0; struct sockaddr_in serv_addr, cli_addr; unsigned port = 5000; char *dirname = "."; Job *jobs = 0; int n_jobs = 0; double fuzz = -1; for (i = 1; i < argc; i++) { if (!strcmp(argv[i],"--help")) { xit(0, "server [--port=FLOAT] [--dir=PATH] [--fuzz=FLOAT]\n"); } else if (!strcmp(argv[i],"--version")) { xit(0, "1.0\n"); } else if (!strncmp(argv[i],"--port=", 7)) { sscanf(argv[i]+7, "%u", &port); } else if (!strncmp(argv[i],"--fuzz=", 7)) { sscanf(argv[i]+7, "%lf", &fuzz); } else if (!strncmp(argv[i],"--dir=", 6)) { dirname = argv[i]+6; } else { xit(1, "Unknown argument: %s\n", argv[i]); } } { // Reading job directory struct dirent *dir; int sz_jobs = 0; DIR *d = opendir(dirname); if (d) { int dirlen = strlen(dirname); while ((dir = readdir(d)) != NULL) { if (dir->d_type == DT_REG ) { int len = strlen(dir->d_name); if (len >= 4 && !strcmp(dir->d_name+len-4, ".srg")) { if (n_jobs >= sz_jobs) { sz_jobs = 5*sz_jobs/4 + 8; jobs = realloc(jobs, sizeof(Job)*sz_jobs); if (jobs == 0) xit(1, "realloc() failed"); } jobs[n_jobs].fname = malloc(strlen(dir->d_name) + dirlen + 2); if (jobs[n_jobs].fname == 0) xit(1, "malloc() failed"); if (dirlen) { memcpy(jobs[n_jobs].fname, dirname, dirlen); if (dirname[dirlen-1] != '/') { jobs[n_jobs].fname[dirlen] = '/'; strcpy(&jobs[n_jobs].fname[dirlen+1], dir->d_name); } else { strcpy(&jobs[n_jobs].fname[dirlen], dir->d_name); } } else { strcpy(jobs[n_jobs].fname, dir->d_name); } n_jobs++; } } } closedir(d); } else { xit(1, "Can't enumerate '%s'", dirname); } } if (n_jobs == 0) xit(1, "No jobs to process\n"); {// Loading jobs int i; struct stat st; for (i=0; i 1024*1024) { printf("Too much data to read; Ignoring.\n"); goto close; } buf = realloc(buf, new_sz); if (buf == 0) xit(1, "realloc(..., %d) failed\n", new_sz); buf_sz = new_sz; } n = read(fd, buf+recd, buf_sz-recd); printf("%d ", n); if (n == 0) break; if (n < 0) { printf("ERROR reading from socket"); goto close; } recd += n; } printf("total=%d\n", recd); buf[recd]=0; rc = parse_buf(buf, &case_no, &dummy, &error); if (rc == 0) { for (i=0; i= error) printf("Progress %u: %u => %u\n",jobs[i].case_no, jobs[i].error, error); else printf("Regress %u: %u => %u\n",jobs[i].case_no, jobs[i].error, error); jobs[i].error = error; if (jobs[i].maxlen > recd + 1) { FILE *f; memcpy(jobs[i].buf, buf, recd + 1); jobs[i].len = recd; f = fopen(jobs[i].fname,"wb"); if (f) { if (fwrite(buf, 1, recd, f) != recd) fprintf(stderr,"Writing failed: %ss\n", jobs[i].fname); fclose(f); } else { fprintf(stderr,"fopen failed: %s\n", jobs[i].fname); } } else { fprintf(stderr,"Unexpectedly long job ignored, len=%d maxlen=%d\n",recd + 1,jobs[i].maxlen); } } else { printf("No progress %u: %u =| %u\n",jobs[i].case_no, jobs[i].error, error); } } else { fprintf(stderr, "Unknown case_no=%u is ignored\n", case_no); } } else { fprintf(stderr, "Unparsable job rc=%d\n", rc); } } else { fprintf(stderr, "Unknown message=%s\n", msg); } close:; shutdown(fd, SHUT_RDWR); close(fd); } return 0; }