TIP: Click on subject to list as thread! ANSI
echo: os2prog
to: Brett Maxfield
from: Thomas Seeling
date: 1996-07-06 16:44:42
subject: sockets with emx/gcc & warp

Hallo, Brett!

*** Am Freitag 05. Juli 1996 um 09:55 schrieb Brett Maxfield an All:

 BM> I was wondering if anybody is familiar with building tcp/ip servers
 BM> with warp, specifically using the emx/bsd programming interface.
That's correct, you call bind(), listen() and accept() in a server,
and depending on the settings for listen, either you accept a connection
from a certain ip address or from any address. You can find out the
hostname, but you should be aware that gethostbyaddr is not threadsafe
from my experience (tcp/ip 2.0 and un64092). Therefore a mutex semaphore
should be used to encapsulate the call.

 BM>     7. spawn or fork a process to handle that connection
You should fire up a thread instead. Avoid fork() whereever possible.
This is a kludge with OS/2 and very inefficient. Use it only when
porting Unix pieces to get it run quickly, then think about how to
replace the fork() by threads.

BTW: this can be very hard, and in case you develop commercially, not worth
the time you invest.


These are cuts from my www server. You have to fill in some gaps
(proxy, caching, security :-) ), but it definitely works (then).



=== Cut ===
#ifndef WWW_H
#define WWW_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#include "dirutil.h"
#include "util.h"
#include "base64.h"

#define MAXCONN 32

#define FALSE 0
#define TRUE 1

#define CRLF "\r\n"

#define CR  '\r'
#define LF  '\n'
#define TAB '\t'

#define SPACE ' '

#define KILOBYTE 1024
#define MEGABYTE (KILOBYTE*KILOBYTE)
#define GIGABYTE (MEGABYTE*KILOBYTE)

#endif

char *dupdirstr(char *);
char *pathunix(char *);
char *pathos2(char *);
char *findhdr(char **, char *);
int   initserver(int, int);
int   initclient(char *, int);
int   waitconnection(struct sockaddr_in *, int);
int initserver(int port, int maxconn) {
=== Cut ===
#ifndef TSHTTPD_H
#define TSHTTPD_H

#define INCL_DOSQUEUES
#define INCL_DOSFILEMGR
#define INCL_DOSPROCESS
#define INCL_DOSSEMAPHORES
#define INCL_DOSMODULEMGR
#define INCL_DOSERRORS
#include 

#include 
#include 
#include 
#include 

#include "www.h"

#define SERVER "TShttpd/1.0 alpha"
#define MAIL \
"<ths{at}texbox.lahn.de>"">mailto:ths{at}texbox.lahn.de\"><ths{at}texbox.lahn.de>"

#define STACK 32768

const char *crypt(const char *key, const char *salt);
=== Cut ===
  struct sockaddr_in server;
  int                one=1,sock;

  sock=socket(AF_INET, SOCK_STREAM, 0);
  if (sock < 0) {
    perror("socket");
    exit(1);
  }
  if ((setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,
    (char*)&one,sizeof(one)))==-1) {
    fprintf(stderr, "couldn't set socket option\n");
  }
  server.sin_family=AF_INET;
  server.sin_port=htons(port);
  server.sin_addr.s_addr=INADDR_ANY;
  if (bind(sock, (struct sockaddr *) &server, sizeof(server)) < 0) {
    perror("bind socket");
    exit(1);
  }
  if (listen(sock, maxconn) < 0) {
    perror("listen");
    exit(1);
  }
  return sock;
}

int initclient(char *host, int port) {
  struct sockaddr_in addr;
  struct hostent    *hp;
  int                sock;

  sock=socket(AF_INET,SOCK_STREAM,0);
  if (sock<0) {
    perror("socket failed");
    return -1;
  }

  addr.sin_family=AF_INET;
  addr.sin_port=htons(0);
  addr.sin_addr.s_addr=htonl(0);

  if (bind(sock,(struct sockaddr *)&addr,sizeof(addr))<0) {
    perror("bind failed");
    return -1;
  }

  if (host && (hp=gethostbyname(host))!=NULL) {
    memcpy(&addr.sin_addr,hp->h_addr,hp->h_length);
    addr.sin_port=htons(port);
  }
  else {
    perror("unknown host");
    return -1;
  }

  if (connect(sock,(struct sockaddr *)&addr,sizeof(addr))<0) {
    perror("connect failed");
    return -1;
  }
  return sock;
}

int waitconnection(struct sockaddr_in *source, int sock) {
  int lg,con_sock;

  lg=sizeof(struct sockaddr_in);
  con_sock=accept(sock, (struct sockaddr *) source, &lg);
  if (con_sock <=0) {
    perror("accept failed");
    exit(1);
  }
  return con_sock;
}
=== Cut ===
/* tshttpd 1.02 (c) 1996 Thomas Seeling */


void quithttpd(int sig) {
  shutdown(http_sock,2);
  close(http_sock);
  log_http("End on signal %d",sig);
  exit(sig);
}

void handlereq(void *data) {
#ifdef __MT__
  ULONG              t2;
#endif
  struct sockaddr_in src;
  struct hostent    *host=NULL;
  struct tm          parsetm;
  char               cg;

#ifdef INETD
  if (!inetd)
#endif
    mysock=waitconnection(&src,http_sock);

  signal(SIGPIPE,SIG_IGN);

    log_http("Connection on %d (%s) %d",
      src.sin_port,inet_ntoa(src.sin_addr),mysock);

  t2=src.sin_addr.s_addr;
  log_http("Remote host %08lx",t2);
  host=gethostbyaddr((char *)&t2,sizeof(t2),AF_INET);

  lg=read(mysock,&cg,1);

error:
  close(fd);
  close(mysock);
}

int main(int argc, char **argv) {
  APIRET rc;
  PTIB   ptib;
  PPIB   ppib;
  char  *name;
  char  *tmp;
  int    lg,maxth=1;

  tzset();
  servername[0]=
  domainname[0]=
  configfile[0]='\0';
  rc=DosGetInfoBlocks(&ptib,&ppib);
  if (rc==NO_ERROR) {
    rc=DosQueryModuleName(ppib->pib_hmte,MAXPATHLEN,domainname);
    if (rc==NO_ERROR) {
      char save;

      name=_getname(domainname);
      save=*name;
      *name='\0';
      strcpy(configfile,domainname);
      *name=save;
    }
    else
      fprintf(stderr,"DosQueryModuleName rc=%ld\n",rc);
  }
  else
    fprintf(stderr,"DosQueryInfoBlocks rc=%ld\n",rc);

  homedir=dupdirstr(configfile);
  strcat(configfile,"httpd.cfg");
  wwwdir=dupdirstr(BASE_DIR);
  while ((lg=getopt(argc,argv,"c:d:Dl:m:p:"))!=EOF)
    switch (lg) {
    case 'c':
      strcpy(configfile,optarg);
      break;
    case 'd':
      free(wwwdir);
      wwwdir=dupdirstr(optarg);
      break;
    case 'D':
      debug=TRUE;
      break;
    case 'l':
      logfile=strdup(optarg);
      break;
    case 'm':
      multi=TRUE;
      maxth=atoi(optarg);
      if (maxth<1)
        maxth=1;
      break;
    case 'p':
      http_port=atoi(optarg);
      break;
    default:
      usage();
    }

  signal(SIGTERM, quithttpd);
  signal(SIGQUIT, quithttpd);
  signal(SIGINT,  quithttpd);
  signal(SIGSEGV, quithttpd);
  signal(SIGILL,  quithttpd);
  signal(SIGPIPE, SIG_IGN);

  tmp=getenv("EMXTZ");
  if (!tmp)
    tmp=getenv("TZ");
  if (tmp) {
    strncpy(TZ,tmp,3);
  }

  http_sock=initserver(http_port,MAXCONN);

 tid=_beginthread(handlereq,NULL,STACK,NULL);

  return EXIT_SUCCESS;
}
=== Cut ===


Tschau...Thomas

--- E3-32/1.11-32/2.50+
* Origin: Die TeX-Box +49-6034-930021 V.34 -930022 ISDN 24h (2:244/1130.42)
SEEN-BY: 50/99 270/101 620/243 625/100 711/401 409 410 413 430 808 809 934
SEEN-BY: 711/955 712/407 515 517 628 713/888 800/1
@PATH: 244/1130 24/999 888 396/1 270/101 712/515 711/808 934

SOURCE: echomail via fidonet.ozzmosis.com

Email questions or comments to sysop@ipingthereforeiam.com
All parts of this website painstakingly hand-crafted in the U.S.A.!
IPTIA BBS/MUD/Terminal/Game Server List, © 2025 IPTIA Consulting™.