/* * palin server program * */ #include #include #include #include #include #include #include #include #include #include "uici.h" #define INPORT 7995 #define OUTPORT 7996 #define BLKSIZE 1024 /* The maximum number of undone (available) dataunits you want to have in * your list file. This should probably be at least 4 times the number of * simultaneous clients you plan to have. Note that if the list file has * more undone dataunits than this the program will crash when reading the * dataunits in from the listfile. */ #define UNITMAX 128 /* After ISSUEMAX dataunit issues to the clients, reread the list file. * This number needs to be more than the number of simultaneous clients * by a safe margin, but it also should not be more than half the undone * dataunits from the list file. */ #define ISSUEMAX 16 int copy_from_network_to_file(int commfd, int filefd) { int bytes_read; int bytes_written; int bytes_to_write; int total_bytes = 0; char buf[BLKSIZE]; char *bufp; for ( ; ; ) { if ((bytes_read = u_read(commfd, buf, BLKSIZE)) < 0) { u_error("Server read error"); break; } else if (bytes_read == 0) { fprintf(stderr, "Network end-of-file\n"); break; } else { /* allow for interruption of write by signal */ for (bufp = buf, bytes_to_write = bytes_read; bytes_to_write > 0; bufp += bytes_written, bytes_to_write -= bytes_written){ bytes_written = write(filefd, bufp, bytes_to_write); if ((bytes_written) == -1 && (errno != EINTR)){ perror("Server write error"); break; } else if (bytes_written == -1) bytes_written = 0; total_bytes += bytes_written; } if (bytes_written == -1) break; } } return total_bytes; } void* listen_to_inport() { u_port_t portnumber; int listenfd, commfd, outfd; char client[MAX_CANON]; int bytes_copied, child; FILE *fp; char *str; portnumber = (u_port_t)INPORT; if ((listenfd = u_open(portnumber)) == -1) { u_error("Unable to establish port connection"); exit(1); } while ((commfd = u_listen(listenfd, client)) != -1) { /* fprintf(stderr, "[%ld]: A connection has been made to %s\n", * (long)getpid(), client); */ if ((child = fork()) == -1) { fprintf(stderr, "Could not fork a child\n"); break; } if (child == 0) { /* child code */ close(listenfd); fprintf(stderr, "[%ld]: A connection has been made to %s\n", (long)getpid(), client); if ((outfd = open("/tmp/distpalin.tmp", O_CREAT|O_WRONLY, S_IRUSR|S_IWUSR)) == -1) { fprintf(stderr, "Cannot open file /tmp/distpalin.tmp\n"); outfd = STDOUT_FILENO; } bytes_copied = copy_from_network_to_file(commfd, outfd); close(outfd); close(commfd); fprintf(stderr, "[%ld]: Bytes transferred = %d\n", (long)getpid(), bytes_copied); /*****************************************************************************/ execv("distpalind.pl", NULL); /*****************************************************************************/ exit(0); } else { /* parent code */ close(commfd); while (waitpid(-1, NULL, WNOHANG) > 0); } } /* while */ } void* listen_to_outport() { u_port_t portnumber; int listenfd, commfd, outfd; char client[MAX_CANON]; int bytes_copied, child; FILE *fp; char *code, *half; char str[80]; char dataunit[UNITMAX][80]; int i, issue, j, totalunits; char buf[BLKSIZE]; /* Read list file and create an array of strings that are not "done" */ if ((fp = fopen("list", "r")) == NULL) { fprintf(stderr, "Cannot open list file.\n"); exit(1); } i = 0; totalunits = -1; while (!feof(fp)) { if (fgets(str, 79, fp)) { /* Look for the "n" in "done" to determine if the work unit is done */ if (strchr(str, 'n') == NULL) { for (j=0; j<80; j++) dataunit[i][j] = str[j]; fprintf(stderr, "dataunit[%d]: %s", i, dataunit[i]); totalunits = i; i++; } } } fclose(fp); /* Now set issue to the last data unit from the .lastunit * file. This is so that if the server is stopped and restarted, the * server doesn't reissue all the same work units. */ if ((fp = fopen(".lastunit", "r")) != NULL) { while (!feof(fp)) { if (fgets(str, 80, fp)) { issue=atoi(str); } } fclose(fp); } else { issue=0; } if ((issue<0) || (issue>totalunits)) { i=0; } /* Open OUTPORT for listening (and writing to when a connection is received) */ portnumber = (u_port_t)OUTPORT; if ((listenfd = u_open(portnumber)) == -1) { u_error("Unable to establish port connection"); exit(1); } while ((commfd = u_listen(listenfd, client)) != -1) { /* fprintf(stderr, "[%ld]: A connection has been made to %s\n", * (long)getpid(), client); */ if ((child = fork()) == -1) { fprintf(stderr, "Could not fork a child\n"); break; } if (child == 0) { /* child code */ close(listenfd); fprintf(stderr, "[%ld]: A connection has been made to %s\n", (long)getpid(), client); /* Now get the next work unit data */ /* Copy the dataunit[issue] into str */ for (j=0; j<80; j++) str[j] = dataunit[issue][j]; /* Now write str to socket */ bytes_copied = strlen(str); fprintf(stderr, "Sent dataunit[%d] : %s", issue, str, "\n"); if (bytes_copied != u_write(commfd, str, (size_t)bytes_copied)) { u_error("Client write_error"); } close(commfd); fprintf(stderr, "[%ld]: Bytes transferred = %d\n", (long)getpid(), bytes_copied); exit(0); } else { /* parent code */ close(commfd); /* Increment issue because the child just issued another dataunit. */ issue++; /* Write dataunit increment (i) to .lastunit */ if ((fp = fopen(".lastunit", "w")) == NULL) { fprintf(stderr, "Cannot open .lastunit file.\n");; exit(1); } /* fprintf issue value to the file */ fprintf(fp, "%d\n", issue); fclose(fp); if ((issue>totalunits) || ((issue%ISSUEMAX) == 0)) { /* Re-read list file of work units not "done" */ if ((fp = fopen("list", "r")) == NULL) { fprintf(stderr, "Cannot open list file.\n"); exit(1); } i = 0; totalunits = -1; while (!feof(fp)) { if (fgets(str, 79, fp)) { if (strchr(str, 'n') == NULL) { for (j=0; j<80; j++) dataunit[i][j] = str[j]; fprintf(stderr, "dataunit[%d]: %s", i, dataunit[i]); totalunits = i; i++; } } } fclose(fp); if (issue>totalunits) issue = 0; } while (waitpid(-1, NULL, WNOHANG) > 0); } } /* while */ } int main() { int child; pthread_t listen_tid1; pthread_t listen_tid2; /* Create a thread to go off and listen to the INPORT. */ if (pthread_create(&listen_tid1, NULL, listen_to_inport, NULL)) { fprintf(stderr, "INPORT thread creation was not successful\n"); exit(0); } /* Create a thread to go off and listen to the OUTPORT. */ if (pthread_create(&listen_tid2, NULL, listen_to_outport, NULL)) { fprintf(stderr, "OUTPORT thread creation was not successful\n"); exit(0); } while (1) { /* Sleep in the background */ sleep(60); } }