ftp.nice.ch/pub/next/connectivity/infosystems/Ph.3.03.NIHS.bs.tar.gz#/Ph3.03/Utils/makeServices.c

This is makeServices.c in view mode; [Download] [Up]

/*---------------------------------------------------------------------------
makeServices.c -- Utility to create the Ph "services" file.

This program connects to CSO's Qi nameserver port on the hostname specified
on the command line.  The "fields" command is sent to the Qi server.  An
entry is written to the "services" file for each "indexed" field.

Sample run:
     % makeServices nameServerHost.site.domain

Rex Pruess <Rex-Pruess@uiowa.edu>
-----------------------------------------------------------------------------*/

#define DEFAULTPORT 105         /* Default Qi nameservice port */
#define LR_OK       200		/* Qi success value */
#define MAXSIZE     4096        /* Maximum buffer size */
#define NSSERVICE   "ns"	/* Entry in /etc/services */
#define SERVICESFL  "./services.text"

#define FIELDS      "fields\n"
#define QUIT        "quit\n"

#include <ansi/ctype.h>

#include <bsd/c.h>
#include <bsd/strings.h>

#include <sys/types.h>
#include <sys/socket.h>

#include <netinet/in.h>

#include <netdb.h>
#include <stdio.h>

char *checkField (char *record);

main(argc, argv)
int argc;
char *argv[];
{
   char *bp;			/* Pointer which moves thru buf */
   char buf[MAXSIZE];
   int bufCnt;
   char *field;
   FILE *fp;
   int len;
   char lineBuf[MAXSIZE];
   char *nl;			/* Newline pointer (points to '\n' in buf) */
   int servCnt;
   int sock;

   struct hostent *hp;
   struct servent *theNs;
   struct sockaddr_in qiSock;

   /*** Verify correct number of command-line arguments. */

   if (argc != 2) {
      if (argc < 2)
	 fprintf (stderr, "Too few arguments.  ");
      else
	 fprintf (stderr, "Too many arguments.  ");

      fprintf (stderr, "Usage: %s nameServer.site.domain\n", argv[0]);
      exit (99);
   }
   
   /*** Initialization */

   lineBuf[0] = '\0';
   servCnt = 0;

   /*** Create socket */

   sock = socket (AF_INET, SOCK_STREAM, 0);
   if (sock < 0) {
      perror ("Error creating stream socket.");
      exit (99);
   }

   /*** Use the hostname specified on the command line. */

   qiSock.sin_family = AF_INET;
   hp = gethostbyname (argv[1]);
   if (hp == 0) {
      fprintf (stderr, "Error.  Unknown host '%s'.\n", argv[1]);
      exit (99);
   }
   bcopy (hp->h_addr, &qiSock.sin_addr, hp->h_length);

   /*** If possible, use the /etc/services "ns" port.  Otherwise, use the
        DEFAULTPORT port. */

   if ((theNs = getservbyname (NSSERVICE, "tcp")) != NULL)
      qiSock.sin_port = theNs -> s_port;
   else
      qiSock.sin_port = htons (DEFAULTPORT);
   
   if (connect (sock, (struct sockaddr *) & qiSock, sizeof (qiSock)) < 0) {
      perror ("Error connecting stream socket.");
      exit (99);
   }

   /*** Open the services file. */

   if ((fp = fopen (SERVICESFL, "w+")) == NULL) {
      perror ("Unable to open services output file.");
      fprintf (stderr, "Could not open '%s'.\n", SERVICESFL);
      exit (99);
   }

   /*** Send the "fields" command to the Qi nameserver. */

   write (sock, FIELDS, sizeof (FIELDS) - 1);

   /*** Read & process each record from the Qi nameserver. */

   bzero (buf, sizeof (buf));
   
   while ((bufCnt = read (sock, buf, MAXSIZE - 1)) > 0) {

      buf[bufCnt] = '\0';
      bp = buf;

      /*** This loop moves through the buffer a line at a time. */

      while ((nl = index (bp, '\n')) != 0) {
	 len = nl - bp + 1;

	 strncat (lineBuf, bp, MIN (len, MAXSIZE - strlen (lineBuf) - 1));

	 /*** "-" means we've received the last line.  Tell the Qi nameserver
              to quit.  Do some cleanup and exit. */

	 if (atoi (lineBuf) != -LR_OK) {
	    fclose (fp);

	    write (sock,  QUIT, sizeof (QUIT) - 1);
	    close (sock);

	    printf ("%d entries written to '%s'.\n", servCnt, SERVICESFL);
	    exit (0);
	 }
      
	 if ((field = checkField (lineBuf)) != NULL) {
	    writeService (field, fp);
	    servCnt++;
	 }
	 
	 lineBuf[0] = '\0';
	 bp += len;
      }

      /*** The output buffer may still have a partial line in it.  If so,
           assign it to the lineBuf so we don't lose it next time through. */

      if (strlen (bp) == 0)
	 lineBuf[0] = '\0';
      else
	 strcpy (lineBuf, bp);
   }

   fprintf (stderr, "Error.  Unexpected end of file from Qi nameserver.\n");

   fclose (fp);

   write (sock,  QUIT, sizeof (QUIT) - 1);
   close (sock);

   exit (99);
   
}

/*---------------------------------------------------------------------------
checkField: The record is checked to see if it has an indexed entry.  If so,
a pointer to the field is returned, else NULL is returned.
-----------------------------------------------------------------------------*/
char *checkField (record)
char *record;
{
   char *aPtr;
   int fieldNum;
   char *fieldName;
   int theCode;
   int theField;

   if ((aPtr = strtok (record, ":")) == NULL)   /* Code */
      return (NULL);
   
   if ((aPtr = strtok (NULL, ":")) == NULL)      /* Field number */
      return (NULL);

   fieldNum = atoi (aPtr);

   if ((fieldName = strtok (NULL, ":")) == NULL) /* Field name */
      return (NULL);

   if ((aPtr = strtok (NULL, ":")) == NULL)      /* keywords or description */
      return (NULL);

   if (strstr (aPtr, "Indexed") != NULL && strstr (aPtr, "Lookup") != NULL &&
       strstr (aPtr, "Public") != NULL)
      return (fieldName);

   return (NULL);
}

/*---------------------------------------------------------------------------
writeService: This routine is called for each indexed field.  A
services-stylen entry is written for the entry.
-----------------------------------------------------------------------------*/
writeService (field, fp)
char *field;
FILE *fp;
{
   fprintf (fp, "Message: phQueryService\n");
   fprintf (fp, "Port: Ph\n");
   fprintf (fp, "Send Type: NXAsciiPboardType\n");
   fprintf (fp, "Key Equivalent:\n");
   fprintf (fp, "User Data: %s\n", field);

   field[0] = toupper (field[0]);
   fprintf (fp, "Menu Item: Ph Query/%s\n", field);

   fprintf (fp, "\n");
   
   return;
}


These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.