| /* |
| * SAS_write - mimicking the "write" side of sas |
| * |
| * This program is mimicking the actual SAS backend, it opens a socket and |
| * starts listening on that socket to send data to the database. |
| * |
| * When data a connection is received this starts reading data from stdin |
| * and writing data to the socket. |
| * |
| * The real SAS backend will want to do something more intelligent. |
| * |
| */ |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <string.h> |
| #include <sys/types.h> |
| #include <sys/socket.h> |
| #include <sys/uio.h> |
| #include <netinet/in.h> |
| #include <unistd.h> |
| #include <errno.h> |
| #include <signal.h> |
| |
| /* Define a 1K buffer, probably should be larger in practice */ |
| #define BUFFER_SIZE 1024 |
| char buffer[BUFFER_SIZE]; |
| |
| void sighandler(int sig); |
| |
| int main(int argc, char *argv[]) |
| { |
| int sockfd, newsockfd, portno; |
| struct sockaddr_in serv_addr, cli_addr; |
| socklen_t serv_len = sizeof(serv_addr); |
| socklen_t cli_len = sizeof(cli_addr); |
| int n, total; |
| |
| (void) signal(SIGHUP, sighandler); |
| (void) signal(SIGINT, sighandler); |
| (void) signal(SIGQUIT, sighandler); |
| (void) signal(SIGPIPE, sighandler); |
| |
| /* Get the port number from the arguments */ |
| if (argc != 2) |
| { |
| fprintf(stderr,"usage: %s <port-number>\n", argv[0]); |
| exit(1); |
| } |
| portno = atoi(argv[1]); |
| |
| /* Open a socket and bind to the port */ |
| sockfd = socket(AF_INET, SOCK_STREAM, 0); |
| if (sockfd < 0) |
| { |
| fprintf(stderr, "Error opening socket\n"); |
| exit(1); |
| } |
| bzero((char *) &serv_addr, sizeof(serv_addr)); |
| serv_addr.sin_family = AF_INET; |
| serv_addr.sin_addr.s_addr = INADDR_ANY; |
| serv_addr.sin_port = htons( (int16_t) portno); |
| serv_len = sizeof(serv_addr); |
| if (bind(sockfd, (struct sockaddr *) &serv_addr, serv_len) < 0) |
| { |
| fprintf(stderr, "ERROR binding socket\n"); |
| exit(1); |
| } |
| |
| /* Listen on the socket */ |
| fprintf(stderr, "Listening on port %d...\n", portno); |
| listen(sockfd, 5); |
| newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &cli_len); |
| if (newsockfd < 0) |
| { |
| fprintf(stderr, "ERROR on accept\n"); |
| exit(1); |
| } |
| |
| fprintf(stderr, "Connection established\n"); |
| |
| /* Read data until the connection is closed */ |
| total = 0; |
| do |
| { |
| n = fread(buffer, sizeof(char), BUFFER_SIZE, stdin); |
| fprintf(stderr, "%s: read %d bytes\n", argv[0], n); |
| |
| if (n > 0) |
| { |
| char *buf = buffer; |
| int remaining = n; |
| |
| while (remaining > 0) |
| { |
| int written = write(newsockfd, buf, remaining); |
| if (written < 0) |
| { |
| fprintf(stderr, "%s: error writing to socket\n", argv[0]); |
| exit(1); |
| } |
| total += written; |
| buf += written; |
| remaining -= written; |
| } |
| } |
| } |
| while (n > 0); |
| |
| fprintf(stderr, "%s: wrote %d bytes\n", argv[0], total); |
| |
| /* Close the socket */ |
| if (shutdown(newsockfd, 2) < 0) |
| { |
| fprintf(stderr, "%s: error closing socket\n", argv[0]); |
| fprintf(stderr, "%s (errno = %d)\n", strerror(errno), errno); |
| exit(1); |
| } |
| |
| close(newsockfd); |
| close(sockfd); |
| |
| return 0; |
| } |
| |
| |
| void sighandler(int sig) |
| { |
| fprintf(stderr, "\nInterupped by signal %d\n", sig); |
| exit(sig); |
| } |