/* * $Header: /home/gene/library/website/docsrc/sca/src/RCS/counter.c,v 395.1 2008/04/20 17:25:48 gene Exp $ * * Copyright (c) 2006 Gene Michael Stover. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * USA */ /* * This is a simple service, sort of like "echo" except that it * returns a number, not the packet that you send it. */ #include "this.h" /* * Port where we are looking for live hosts. */ static u_short S_port = 0; /* */ static char *S_progname = ""; /* */ enum { ACTION_RUN, ACTION_HELP }; static int S_action = ACTION_RUN; /* */ static int S_CommandLine (int argc, char *argv[]) { int rc = 0; int optind = 1; S_progname = argv[0]; if (optind < argc) { if (sscanf (argv[optind], "%hu", &S_port) == 1) { if (0 < S_port && S_port <= 65535) { ++optind; if (optind < argc) { fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__); fprintf (stderr, " Ignoring extra command line arguments."); } } else { fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__); fprintf (stderr, " %d is out of range for a UDP port.", S_port); S_action = ACTION_HELP; } } else { fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__); fprintf (stderr, " Cannot parse \"%s\" into a port", argv[optind]); fprintf (stderr, " number."); S_action = ACTION_HELP; } } else { fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__); fprintf (stderr, " Missing port number & name of message file"); fprintf (stderr, " on the command line."); S_action = ACTION_HELP; } return rc; } /* */ static int S_Help () { printf ("\nUsage: %s PORT", S_progname); printf ("\nPORT is the UDP port number"); printf ("\n"); return 0; } /* */ static SOCKET S_CloseSocket (SOCKET s) { if (s != INVALID_SOCKET) { #if IS_UNIX close (s); #endif #if IS_WINDERS closesocket (s); #endif } return INVALID_SOCKET; } /* */ static SOCKET S_MakeSocket () { SOCKET s; struct sockaddr_in sin; struct sockaddr *sa; s = socket(PF_INET, SOCK_DGRAM, 0); if (s != INVALID_SOCKET) { bzero (&sin, sizeof sin); sin.sin_family = AF_INET; sin.sin_port = htons (S_port); sin.sin_addr.s_addr = INADDR_ANY; sa = (struct sockaddr *) &sin; if (bind (s, sa, sizeof sin) == 0) { /* good */ } else { fprintf (stderr, "\n"); perror ("bind"); fprintf (stderr, "%s:%d: bind failed", __FILE__, __LINE__); S_CloseSocket (s); s = INVALID_SOCKET; } } else { fprintf (stderr, "\n"); perror ("socket"); fprintf (stderr, "%s:%d: socket failed", __FILE__, __LINE__); } fprintf (stderr, "\n%s:%d: trace: s is %d", __FILE__, __LINE__, s); return s; } /* */ static int S_DoRecv (struct sockaddr_in *sin, SOCKET s) { int rc = 0, i; char buffer[8000]; struct sockaddr *sa; int sin_len; fprintf (stderr, "\n%s:%d: trace: s is %d", __FILE__, __LINE__, s); bzero (sin, sizeof *sin); sin_len = sizeof *sin; sa = (struct sockaddr *) sin; i = recvfrom (s, buffer, sizeof buffer, 0, sa, &sin_len); if (i > 0) { /* good */ } else { fprintf (stderr, "\n"); perror ("recvfrom"); fprintf (stderr, "%s:%d:", __FILE__, __LINE__); fprintf (stderr, " recvfrom failed"); rc = 219; } return rc; } /* */ static int S_DoSend (int count, struct sockaddr_in *sin, SOCKET s) { int rc = 0, i; struct sockaddr *sa; char buffer[12]; sprintf (buffer, "%d\n", count); sa = (struct sockaddr *) sin; i = sendto (s, buffer, strlen (buffer), 0, sa, sizeof *sin); if (i > 0) { /* good */ } else { fprintf (stderr, "\n"); perror ("sendto"); fprintf (stderr, "%s:%d: sendto failed", __FILE__, __LINE__); rc = 219; } return rc; } /* */ static int S_Loop (SOCKET s) { int rc = 0; int count = 0; struct sockaddr_in addy; while (rc == 0) { if (S_DoRecv (&addy, s) == 0) { printf ("\n%s", inet_ntoa (addy.sin_addr)); fflush (stdout); if (S_DoSend (count, &addy, s) == 0) { /* good */ ++count; } else { fprintf (stderr, "\n%s:%d: S_DoSend failed", __FILE__, __LINE__); rc = 3; } } else { fprintf (stderr, "\n%s:%d: S_DoRecv failed", __FILE__, __LINE__); rc = -172; } } return rc; } /* */ static int S_Run () { int rc = 0; SOCKET s; s = S_MakeSocket (); if (s != INVALID_SOCKET) { if (S_Loop (s) == 0) { /* good */ } else { fprintf (stderr, "\n%s:%d: S_Loop failed", __FILE__, __LINE__); rc = 134; } S_CloseSocket (s); } else { fprintf (stderr, "\n%s:%d: S_MakeSocket failed", __FILE__, __LINE__); rc = -116; } return rc; } /* */ static int S_Dispatch () { int rc = 0; switch (S_action) { case ACTION_RUN: rc = S_Run (); break; case ACTION_HELP: rc = S_Help (); break; default: fprintf (stderr, "\n%s:%d:", __FILE__, __LINE__); fprintf (stderr, " S_action is %d.", S_action); fprintf (stderr, " This should never happen!"); rc = 102; } return rc; } int main (int argc, char *argv[]) { int rc = 0; if (S_CommandLine (argc, argv) == 0) { if (S_Dispatch () == 0) { /* good */ } else { fprintf (stderr, "\n%s:%d: S_Dispatchfailed", __FILE__, __LINE__); rc = 234; } } else { fprintf (stderr, "\n%s:%d: S_CommandLine failed", __FILE__, __LINE__); rc = 234; } return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE; } /* --- end of file --- */