/*
tcpget, the poor man's netcat for TOPS-20

Send a string to a host on a port, get the response. Cobbled together
with code examples, compiles on TOPS-20 panda-dist with:

@COMPILE TCPGET.C
@LOAD TCPGET.REL
@SAVE TCPGET.EXE

Use it to get gopher(70), http(80), finger(79), etc. text content.

Usage: tcpget hostname port [string to send] [save as filename]
Examples: tcpget sdf.org 70 "/phlogs/"
         tcpget sdf.org 70 "/phlogs/" output.txt
         tcpget sdf.org 79
         tcpget sdf.org 79 "[email protected]"
         tcpget sdf.org 80 "GET /"

[email protected], 2019, in the public domain
*/

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <fcntl.h>

/* character translations */
#ifndef  __SASC__
#define ntohcs(c) (c)
#define htoncs(c) (c)
#endif

#define TRUE 1
#define FALSE 0
#define RD_BLK_SZ 256
#define OUTB_SZ 2

int main(int argc, char *argv[]) {
  int n, i, s, port;
  char cr = 0x0D, lf = 0x0A;
  char in[RD_BLK_SZ];
  FILE *f;

  struct sockaddr_in sa;
  struct hostent *host;

  if (argc < 3) {
     printf("usage: tcpget hostname port [string to send] [save as filename]\n"
);
     exit(EXIT_FAILURE);
  } else {
     host = gethostbyname(argv[1]);
     port = atoi(argv[2]);
  }

  if (host==NULL) {
      printf("tcpget: host \"%s\" not found\n",argv[1]);
      exit(EXIT_FAILURE);
  }

  memset(&sa,'\0',sizeof(sa));
  sa.sin_family = AF_INET;
  memcpy(&sa.sin_addr,host->h_addr,sizeof(sa.sin_addr));
  sa.sin_port = htons(port);

  s = socket(AF_INET, SOCK_STREAM, 0);
  if (s == -1) {
     perror("tcpget: error on socket()\n");
     exit(EXIT_FAILURE);
  }

  if (connect(s, (struct sockaddr *)&sa, sizeof(sa)) == -1) {
     perror("tcpget: error on connect()\n");
     return(EXIT_FAILURE);
  }

  if (argc > 3) {
     write(s,argv[3],strlen(argv[3]));
  }
  if (argc == 5) {
     f = fopen(argv[4], "w");
     if (f == NULL) {
        printf("tcpget: error opening output file.\n");
        exit(EXIT_FAILURE);
     }
  }

  write(s,&cr,1);
  write(s,&lf,1);

  while (n=read(s,in,RD_BLK_SZ)) {
     for (i=0; i<n ; i++) {
        if (in[i]==cr) continue;
        if (f != NULL && argc == 5) {
           fprintf(f, "%c", ntohcs(in[i]));
        } else {
           putchar(ntohcs(in[i]));
        }
     }
  }

  if (f != NULL && argc == 5) {
     fclose(f);
  }

  close(s);
}