diff --git a/sockclnt.c b/sockclnt.c
new file mode 100644
index 0000000..3e1f9bb
--- /dev/null
+++ b/sockclnt.c
@@ -0,0 +1,352 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <iconv.h>
+#include <signal.h>
+
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/utsname.h>
+#include <arpa/inet.h>
+
+#define BUFFER_SIZE (1024*1024)
+
+typedef struct {
+ int inpbufsz;
+ int outbufsz;
+ short port;
+ char* addr;
+ int debug;
+} parms_t;
+
+char inpbuf[BUFFER_SIZE];
+char outbuf[BUFFER_SIZE];
+char cnvbuf[BUFFER_SIZE]; /* For iconv */
+void pid_printf(const char* msg, ...);
+void pid_perror(char* msg);
+#ifdef __MVS__
+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen);
+#endif
+
+void init_parms(parms_t *parms, int argc, char* argv[])
+{
+ int opt;
+#ifdef __MVS__
+ char* optarg = NULL;
+#endif
+
+ parms->inpbufsz = 0;
+ parms->outbufsz = 0;
+ parms->debug = 0;
+ parms->addr = NULL;
+ parms->port = 15000;
+
+ while ((opt = getopt(argc, argv, ":i:o:p:a:d:")) != -1) {
+ /* printf("%c %s\n", opt, *__opargf()); */
+#ifdef __MVS__
+ optarg = *__opargf();
+#endif
+ switch (opt) {
+ case 'i': /* Input buffer size */
+ parms->inpbufsz = atoi(optarg);
+ break;
+ case 'o': /* Output buffer size */
+ parms->outbufsz = atoi(optarg);
+ break;
+ case 'p': /* Port number */
+ parms->port = (short) atoi(optarg);
+ break;
+ case 'a': /* Listen address */
+ parms->addr = optarg;
+ break;
+ case 'd': /* Enable debug info */
+ printf(optarg);
+ parms->debug = atoi(optarg);
+ break;
+ case ':':
+ printf("Invalid parm value\n!");
+ default:
+ printf("%c\n", opt);
+ }
+ }
+}
+
+in_addr_t convipv4(char* addrstr) {
+
+ char *octet;
+ char* buffer = malloc(strlen(addrstr) + 1);
+
+ if (buffer == NULL) {
+ /* if moc error - give safe response */
+ return htonl(INADDR_ANY);
+ }
+
+ in_addr_t addr = (in_addr_t) 0;
+ strcpy(buffer, addrstr);
+
+ octet = strtok(buffer, ".");
+ while (octet != NULL) {
+ addr = (addr << 8) | (unsigned char) atoi(octet);
+ octet = strtok(NULL, ".");
+ }
+ free(buffer);
+ return htonl(addr);
+}
+
+void handler(int signal) {
+ pid_t pid;
+ int stat;
+ while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+ pid_printf("Child process %d finished\n", pid);
+ }
+
+ return;
+}
+
+int main(int argc, char* argv[]) {
+
+ parms_t parms;
+
+ init_parms(&parms, argc, argv);
+
+ int sock = -1;
+ int count = -1;
+ pid_t pid = 0;
+ pid_t fpid = 0;
+
+#ifdef __MVS__
+ size_t cnvlen;
+ iconv_t cnvinp = iconv_open("IBM-1047", "ISO8859-1");
+ iconv_t cnvout = iconv_open("ISO8859-1" , "IBM-1047");
+#endif
+
+ pid = getpid();
+
+ /* set signal action */
+
+ struct sigaction signew;
+ struct sigaction sigold;
+
+ sigemptyset(&signew.sa_mask);
+
+ signew.sa_flags = SA_NOCLDWAIT; /*SA_NOCLDSTOP;*/
+ signew.sa_flags = 0;
+ signew.sa_handler = handler;
+
+ if (sigaction(SIGCHLD, &signew, &sigold) < 0) {
+ pid_perror("SIGACTION");
+ }
+
+ struct sockaddr_in servaddr, connaddr;
+
+ servaddr.sin_family = AF_INET;
+
+ /* read address from command line */
+ if (parms.addr != NULL) {
+ servaddr.sin_addr.s_addr = convipv4(parms.addr);
+ pid_printf("IP address for connect: %s <0x%8.8X>\n",
+ parms.addr,
+ servaddr.sin_addr.s_addr);
+ }
+ else {
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ pid_printf("IP address for listen: 0.0.0.0 <0x%8.8X>\n",
+ servaddr.sin_addr.s_addr);
+ }
+ servaddr.sin_port = htons(parms.port);
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (sock < 0) {
+ pid_perror("SOCKET: ");
+ exit(1);
+ }
+
+ /* Set size of receive buffer */
+ if (parms.inpbufsz > 0) {
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &parms.inpbufsz, sizeof(parms.inpbufsz)) == -1) {
+ pid_perror("Error in setting socket option:");
+ }
+ else {
+ pid_printf("InpBufSz: %d\n", parms.inpbufsz);
+ }
+ }
+
+ /* Set size of send buffer */
+ if (parms.outbufsz > 0) {
+ if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &parms.outbufsz, sizeof(parms.outbufsz)) == -1) {
+ pid_perror("Error in setting socket option:");
+ }
+ else {
+ pid_printf("OutBufSz: %d\n", parms.outbufsz);
+ }
+ }
+
+ /* Set reuse addr */
+ int reuse = 1;
+
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
+ pid_perror("Error in setting socket option SO_REUSEADDR");
+ }
+
+ if (connect(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {
+ pid_perror("CONNECT");
+ exit(1);
+ }
+
+ char* message = "ala ma kota";
+ count = snprintf(cnvbuf, sizeof(cnvbuf), "%s\n", message);
+#ifdef __MVS__
+ cnvlen = convert(cnvout, (char *) cnvbuf, count, (char *) outbuf, sizeof(outbuf));
+ count = write(sock, outbuf, cnvlen);
+#else
+ count = write(sock, cnvbuf, count);
+#endif
+
+ close(sock);
+
+#ifdef __MVS__
+ iconv_close(cnvinp);
+ iconv_close(cnvout);
+#endif
+
+ pid_printf("Main process finished\n");
+ return 0;
+
+
+}
+
+#ifdef __MVS__
+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen) {
+
+ /* iconv variables */
+ int rc;
+ char* inpptr;
+ char* outptr;
+ size_t inpcnt;
+ size_t outcnt;
+
+ inpptr = inpbuf;
+ outptr = outbuf;
+ inpcnt = inplen;
+ outcnt = outlen;
+#ifdef DEBUG
+ pid_printf("Buffer: ");
+ for (int i = 0; i < inplen; ++i) {
+ printf("%2.2X", inpbuf + i);
+ }
+ printf("\n");
+
+#endif
+
+ rc = iconv(cd, &inpptr, &inpcnt, &outptr, &outcnt);
+
+ outlen = outlen - outcnt;
+
+#ifdef DEBUG
+ pid_printf("Iconv: rc=%d errno=%d inpcnt=%d outcnt=%d\n", rc, errno, inpcnt, outcnt);
+
+ pid_printf("Output: ");
+ for (int i = 0; i < outlen; ++i) {
+ printf("%2.2X", outbuf + i);
+ }
+#endif
+ printf("\n");
+
+ if (rc == ((size_t) -1)) {
+ return (size_t) 0;
+ }
+
+ return (size_t) outlen;
+}
+
+#endif
+
+void example_gethostbyname(char* addr) {
+
+ struct hostent *hostinfo;
+
+ printf("%s\n", addr);
+ hostinfo = gethostbyname(addr);
+ if (hostinfo != NULL) {
+ char* name = NULL;
+ char** p;
+ p = hostinfo->h_aliases;
+ name = *p++;
+ while(name != NULL) {
+ printf("%s\n", name);
+ name = *p++;
+ }
+
+ /* Address list print */
+ char* addr = NULL;
+ p = hostinfo->h_addr_list;
+ addr = *p++;
+ while(addr != NULL) {
+ for (int i = 0; i < 4; ++i) {
+ printf("%2.2X\n", addr[i]);
+ }
+ addr = *p++;
+ }
+ }
+ else {
+#ifdef __MVS__
+ printf("Error(threads): %d\n", *__h_errno());
+#endif
+ printf("Error: %d\n", h_errno);
+ }
+ exit(0);
+}
+
+void pid_printf(const char* format, ...) {
+ pid_t pid = getpid();
+ char* fmtptr = NULL;
+ int fmtlen = 0;
+ char* bufptr = NULL;
+ int buflen = 0;
+ char* fmtpfx = "%8.8X ";
+
+ /*
+ fmtlen = strlen(fmtpfx) + strlen(format) + 1;
+ fmtptr = malloc(fmtlen);
+
+ if (fmtptr) {
+ strncpy(fmtptr, fmtpfx, fmtlen);
+ strncat(fmtptr, format, fmtlen);
+ printf(fmtptr, pid, va_list
+ free(fmtptr);
+ }
+ */
+ printf("%8.8X ", pid);
+ va_list args;
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+
+ fflush(stdout);
+ return;
+}
+
+void pid_perror(char* msg) {
+ pid_t pid = getpid();
+ char* bufptr = NULL;
+ int buflen = 0;
+
+ buflen = 8 + 1 + strlen(msg) + 1;
+ bufptr = malloc(buflen);
+
+ if (bufptr) {
+ snprintf(bufptr, buflen, "%8.8X %s", pid, msg);
+ perror(bufptr);
+ fflush(stderr);
+ free(bufptr);
+ }
+
+
+ return;
+}
\ No newline at end of file
diff --git a/sockserv.c b/sockserv.c
new file mode 100644
index 0000000..6c675ee
--- /dev/null
+++ b/sockserv.c
@@ -0,0 +1,420 @@
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <iconv.h>
+#include <signal.h>
+
+#include <sys/wait.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <sys/utsname.h>
+#include <arpa/inet.h>
+
+#define BUFFER_SIZE (1024*1024)
+
+typedef struct {
+ int inpbufsz;
+ int outbufsz;
+ short port;
+ char* addr;
+ int debug;
+} parms_t;
+
+char inpbuf[BUFFER_SIZE];
+char outbuf[BUFFER_SIZE];
+char cnvbuf[BUFFER_SIZE]; /* For iconv */
+void pid_printf(const char* msg, ...);
+void pid_perror(char* msg);
+#ifdef __MVS__
+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen);
+#endif
+
+void init_parms(parms_t *parms, int argc, char* argv[])
+{
+ int opt;
+#ifdef __MVS__
+ char* optarg = NULL;
+#endif
+
+ parms->inpbufsz = 0;
+ parms->outbufsz = 0;
+ parms->debug = 0;
+ parms->addr = NULL;
+ parms->port = 15000;
+
+ while ((opt = getopt(argc, argv, ":i:o:p:a:d:")) != -1) {
+ /* printf("%c %s\n", opt, *__opargf()); */
+#ifdef __MVS__
+ optarg = *__opargf();
+#endif
+ switch (opt) {
+ case 'i': /* Input buffer size */
+ parms->inpbufsz = atoi(optarg);
+ break;
+ case 'o': /* Output buffer size */
+ parms->outbufsz = atoi(optarg);
+ break;
+ case 'p': /* Port number */
+ parms->port = (short) atoi(optarg);
+ break;
+ case 'a': /* Listen address */
+ parms->addr = optarg;
+ break;
+ case 'd': /* Enable debug info */
+ printf(optarg);
+ parms->debug = atoi(optarg);
+ break;
+ case ':':
+ printf("Invalid parm value\n!");
+ default:
+ printf("%c\n", opt);
+ }
+ }
+}
+
+in_addr_t convipv4(char* addrstr) {
+
+ char *octet;
+ char* buffer = malloc(strlen(addrstr) + 1);
+
+ if (buffer == NULL) {
+ /* if moc error - give safe response */
+ return htonl(INADDR_ANY);
+ }
+
+ in_addr_t addr = (in_addr_t) 0;
+ strcpy(buffer, addrstr);
+
+ octet = strtok(buffer, ".");
+ while (octet != NULL) {
+ addr = (addr << 8) | (unsigned char) atoi(octet);
+ octet = strtok(NULL, ".");
+ }
+ free(buffer);
+ return htonl(addr);
+}
+
+void handler(int signal) {
+ pid_t pid;
+ int stat;
+ while ((pid = waitpid(-1, &stat, WNOHANG)) > 0) {
+ pid_printf("Child process %d finished\n", pid);
+ }
+
+ return;
+}
+
+int main(int argc, char* argv[]) {
+
+ parms_t parms;
+
+ init_parms(&parms, argc, argv);
+
+ int sock = -1;
+ int conn = -1;
+ int count = -1;
+ pid_t pid = 0;
+ pid_t fpid = 0;
+ iconv_t cnvinp;
+ iconv_t cnvout;
+
+ pid = getpid();
+
+ /* set signal action */
+
+ struct sigaction signew;
+ struct sigaction sigold;
+
+ sigemptyset(&signew.sa_mask);
+
+ signew.sa_flags = SA_NOCLDWAIT; /*SA_NOCLDSTOP;*/
+ signew.sa_flags = 0;
+ signew.sa_handler = handler;
+
+ if (sigaction(SIGCHLD, &signew, &sigold) < 0) {
+ pid_perror("SIGACTION");
+ }
+
+ struct sockaddr_in servaddr, connaddr;
+
+ servaddr.sin_family = AF_INET;
+
+ /* read address from command line */
+ if (parms.addr != NULL) {
+ servaddr.sin_addr.s_addr = convipv4(parms.addr);
+ pid_printf("IP address for listen: %s <0x%8.8X>\n",
+ parms.addr,
+ servaddr.sin_addr.s_addr);
+ }
+ else {
+ servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
+ pid_printf("IP address for listen: 0.0.0.0 <0x%8.8X>\n",
+ servaddr.sin_addr.s_addr);
+ }
+ servaddr.sin_port = htons(parms.port);
+
+ sock = socket(AF_INET, SOCK_STREAM, 0);
+
+ if (sock < 0) {
+ pid_perror("SOCKET: ");
+ exit(1);
+ }
+
+ /* Set size of receive buffer */
+ if (parms.inpbufsz > 0) {
+ if (setsockopt(sock, SOL_SOCKET, SO_RCVBUF, &parms.inpbufsz, sizeof(parms.inpbufsz)) == -1) {
+ pid_perror("Error in setting socket option:");
+ }
+ else {
+ pid_printf("InpBufSz: %d\n", parms.inpbufsz);
+ }
+ }
+
+ /* Set size of send buffer */
+ if (parms.outbufsz > 0) {
+ if (setsockopt(sock, SOL_SOCKET, SO_SNDBUF, &parms.outbufsz, sizeof(parms.outbufsz)) == -1) {
+ pid_perror("Error in setting socket option:");
+ }
+ else {
+ pid_printf("OutBufSz: %d\n", parms.outbufsz);
+ }
+ }
+
+ /* Set reuse addr */
+ int reuse = 1;
+
+ if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse)) == -1) {
+ pid_perror("Error in setting socket option SO_REUSEADDR");
+ }
+
+ if (bind(sock, (struct sockaddr *) &servaddr, sizeof(servaddr)) == -1) {
+ pid_perror("BIND");
+ exit(1);
+ }
+
+ if (listen(sock, 10) == -1) {
+ pid_perror("LISTEN");
+ exit(1);
+ }
+
+
+ struct utsname info;
+ char nodename[5] = "----";
+ if (uname(&info) == -1) {
+ pid_perror("Uname error:");
+ } else {
+ strncpy(nodename, info.nodename, sizeof(nodename));
+ }
+
+ cnvinp = iconv_open("IBM-1047", "ISO8859-1");
+ cnvout = iconv_open("ISO8859-1" , "IBM-1047");
+ for ( ; ; ) {
+ size_t cnvlen;
+ socklen_t connsize = sizeof(connaddr);
+
+ conn = accept(sock, (struct sockaddr *) &connaddr, &connsize);
+ if (conn < 0) {
+ if (errno == EINTR) {
+ continue; /* interrupted syscall */
+ } else {
+ pid_perror("ACCEPT:");
+ exit(1);
+ }
+ }
+ fpid = fork();
+ if (fpid == 0) {
+ /* Here inside child process */
+ pid_printf("Forked process initialized\n");
+ close(sock);
+
+
+ pid_printf("IP address for serv: <0x%8.8X>\n", servaddr.sin_addr.s_addr);
+ pid_printf("IP port for serv: <%5d>\n", servaddr.sin_port);
+ pid_printf("IP address for peer: <0x%8.8X>\n", connaddr.sin_addr.s_addr);
+ pid_printf("IP port for peer: <%5d>\n", connaddr.sin_port);
+
+ char locip[256];
+ char rmtip[265];
+ strcpy(locip, inet_ntoa(servaddr.sin_addr));
+ strcpy(rmtip, inet_ntoa(connaddr.sin_addr));
+ count = snprintf(cnvbuf, sizeof(cnvbuf), "%s PID:%8.8X LOC-IP:%s:%05.5d RMT-IP:%s:%05.5d \n",
+ nodename, getpid(), locip, servaddr.sin_port, rmtip, connaddr.sin_port);
+#ifdef __MVS__
+ cnvlen = convert(cnvout, (char *) cnvbuf, count, (char *) outbuf, sizeof(outbuf));
+ count = write(conn, outbuf, cnvlen);
+#else
+ count = write(conn, cnvbuf, count);
+#endif
+
+
+ count = read(conn, inpbuf, sizeof(inpbuf));
+ while (count > 0) {
+ pid_printf("Packet received, size: %d\n", count);
+
+ if (parms.debug != 0) {
+#ifdef __MVS__
+ cnvlen = convert(cnvinp, (char *) inpbuf, count, (char *) cnvbuf, sizeof(cnvbuf));
+ pid_printf("Packet bytes below: \n%.*s\n", cnvlen, cnvbuf);
+#else
+ pid_printf("Packet bytes below: \n%.*s\n", count, inpbuf);
+#endif
+ }
+
+ count = read(conn, inpbuf, sizeof(inpbuf));
+ }
+ if (count == 0) {
+ pid_printf("Forked process will be finished\n");
+ }
+ else if (count < 0 ) {
+ pid_printf("ERRNO: %d\n", fpid, errno);
+ pid_printf("Interrupt\n");
+ }
+
+ exit(0);
+ }
+ close(conn);
+ }
+
+ iconv_close(cnvinp);
+ iconv_close(cnvout);
+ close(sock);
+
+ pid_printf("Main process finished\n");
+ return 0;
+
+
+}
+
+#ifdef __MVS__
+size_t convert(iconv_t cd, char* inpbuf, size_t inplen, char* outbuf, size_t outlen) {
+
+ /* iconv variables */
+ int rc;
+ char* inpptr;
+ char* outptr;
+ size_t inpcnt;
+ size_t outcnt;
+
+ inpptr = inpbuf;
+ outptr = outbuf;
+ inpcnt = inplen;
+ outcnt = outlen;
+#ifdef DEBUG
+ pid_printf("Buffer: ");
+ for (int i = 0; i < inplen; ++i) {
+ printf("%2.2X", inpbuf + i);
+ }
+ printf("\n");
+
+#endif
+
+ rc = iconv(cd, &inpptr, &inpcnt, &outptr, &outcnt);
+
+ outlen = outlen - outcnt;
+
+#ifdef DEBUG
+ pid_printf("Iconv: rc=%d errno=%d inpcnt=%d outcnt=%d\n", rc, errno, inpcnt, outcnt);
+
+ pid_printf("Output: ");
+ for (int i = 0; i < outlen; ++i) {
+ printf("%2.2X", outbuf + i);
+ }
+#endif
+ printf("\n");
+
+ if (rc == ((size_t) -1)) {
+ return (size_t) 0;
+ }
+
+ return (size_t) outlen;
+}
+
+#endif
+
+void example_gethostbyname(char* addr) {
+
+ struct hostent *hostinfo;
+
+ printf("%s\n", addr);
+ hostinfo = gethostbyname(addr);
+ if (hostinfo != NULL) {
+ char* name = NULL;
+ char** p;
+ p = hostinfo->h_aliases;
+ name = *p++;
+ while(name != NULL) {
+ printf("%s\n", name);
+ name = *p++;
+ }
+
+ /* Address list print */
+ char* addr = NULL;
+ p = hostinfo->h_addr_list;
+ addr = *p++;
+ while(addr != NULL) {
+ for (int i = 0; i < 4; ++i) {
+ printf("%2.2X\n", addr[i]);
+ }
+ addr = *p++;
+ }
+ }
+ else {
+#ifdef __MVS__
+ printf("Error(threads): %d\n", *__h_errno());
+#endif
+ printf("Error: %d\n", h_errno);
+ }
+ exit(0);
+}
+
+void pid_printf(const char* format, ...) {
+ pid_t pid = getpid();
+ char* fmtptr = NULL;
+ int fmtlen = 0;
+ char* bufptr = NULL;
+ int buflen = 0;
+ char* fmtpfx = "%8.8X ";
+
+ /*
+ fmtlen = strlen(fmtpfx) + strlen(format) + 1;
+ fmtptr = malloc(fmtlen);
+
+ if (fmtptr) {
+ strncpy(fmtptr, fmtpfx, fmtlen);
+ strncat(fmtptr, format, fmtlen);
+ printf(fmtptr, pid, va_list
+ free(fmtptr);
+ }
+ */
+ printf("%8.8X ", pid);
+ va_list args;
+ va_start(args, format);
+ vprintf(format, args);
+ va_end(args);
+
+ fflush(stdout);
+ return;
+}
+
+void pid_perror(char* msg) {
+ pid_t pid = getpid();
+ char* bufptr = NULL;
+ int buflen = 0;
+
+ buflen = 8 + 1 + strlen(msg) + 1;
+ bufptr = malloc(buflen);
+
+ if (bufptr) {
+ snprintf(bufptr, buflen, "%8.8X %s", pid, msg);
+ perror(bufptr);
+ fflush(stderr);
+ free(bufptr);
+ }
+
+
+ return;
+}
\ No newline at end of file
|