#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/errno.h>
#include <sys/time.h>
#include <stdio.h>

int errno;
extern char *sprintf();	/* to keep lint happy */

main(argc, argv)
  int argc;
  char *argv[];
{
  int sock, sum, mlength, addin, buffp, cllength;
  struct sockaddr_in server, client;
  char buff_in[512], buff_out[514];
  struct timeval tp;
  (void) gettimeofday(&tp, (struct timezone *)0);
  (void) srand((int) tp.tv_usec);

  sum = 0;
  if (argc>1)
    sum = htons(atoi(argv[1]));
  if (sum==0)
    sum = htons(19090);

  sock = socket(AF_INET, SOCK_DGRAM, 0);

  server.sin_family = AF_INET;
  server.sin_addr.s_addr = INADDR_ANY;
  server.sin_port = htons(sum);

  if (bind(sock, (struct sockaddr *) &server, sizeof(server))) {
    if (errno==EADDRINUSE) {
      (void) fprintf(stderr, "Server port %d already in use.\n", sum);
      (void) fprintf(stderr, "Kill all other adders.\n"); }
    else
      perror("adder: bind");
    exit(1); }

  while(1) {
    cllength = sizeof(client);
    mlength = recvfrom(sock, buff_in, sizeof buff_in, 0,
		       (struct sockaddr *) &client, &cllength) ;
    if (mlength==-1) {
      perror("adder: recvfrom");
      (void) fprintf(stderr, "Ignoring lost message.\n");
      (void) fflush(stderr);
      continue; }
    addin = 0;
    buffp = 0;
    while (buffp < mlength && '0' <= buff_in[buffp] && buff_in[buffp] <= '9') {
      addin = addin*10 + (int) buff_in[buffp] - (int) '0' ;
      buffp++; }
    if (0<mlength && mlength<7 && buffp==mlength && addin<1000000) {
      (void) sprintf(buff_out, "%d+%d=%d", sum, addin, (sum+addin)%1000000);
      sum = (sum + addin)%1000000;
      mlength=strlen(buff_out);
      if ((sendto(sock, buff_out, mlength, 0,
		  (struct sockaddr *) &client,cllength)) !=mlength) {
	perror("adder: sendto");
	(void) fprintf(stderr, "Host %s, port %d.\n",
		       inet_ntoa(client.sin_addr), client.sin_port);
	(void) fflush(stderr); } } } }



