home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Copyright 1989 BBN Systems and Technologies Corporation.
- ** All Rights Reserved.
- ** This is free software, and may be distributed under the terms of the
- ** GNU Public License; see the file COPYING for more details.
- **
- ** Client library routines for VMS with Wollongong 3.0 TCP.
- ** Check the "/INCLUDE" qualifier in descrip.mms.
- **
- ** Our VMS documentation claims some functions exist that really don't,
- ** so we've had to implement them on our own.
- **
- ** Also, Wollongong's header files try to re-specify some of the same
- ** same typedef's that the VMS C RTL specifies. Sigh.
- */
- #include "client.h"
- #include <types.h>
- #include <string.h>
- #include <ssdef.h>
- #include <iodef.h>
- #include <descrip.h>
- #define time_t TWG_time_t
- #define size_t TWG_size_t
- #include "[sys]types2.h"
- #include "[sys]socket.h"
- #include "[netinet]in.h"
- #undef time_t
- #undef size_t
- #ifdef RCSID
- static char RCS[] =
- "$Header: libvms.c,v 2.0 90/04/09 16:29:34 rsalz Exp $";
- #endif /* RCSID */
-
-
- /*
- ** Depending on what version of the C RTL you have, you will need to
- ** edit these.
- */
- #define NEED_UTIME
- #undef NEED_RENAME
- #undef NEED_MEMSET
-
- STATIC int Channel; /* Something to talk with */
-
-
- #ifdef NEED_UTIME
- #include "vmsutime.inc"
- #endif /* NEED_UTIME */
-
-
- /*
- ** This comes from the AT&T public domain getopt handed out at 1985
- ** UNIFORUM and subsequently posted to Usenet.
- */
- int opterr = 1;
- int optind = 1;
- int optopt;
- char *optarg;
- extern char *strchr();
-
- int
- getopt(ac, av, options)
- int ac;
- char **av;
- char *options;
- {
- static int sp = 1;
- REGISTER char *p;
-
- if (sp == 1) {
- if (optind >= ac || av[optind][0] != '-' || av[optind][1] == '\0')
- return EOF;
- if (strcmp(av[optind], "--") == 0) {
- optind++;
- return EOF;
- }
- }
-
- optopt = av[optind][sp];
-
- /* Bogus flag? */
- if (optopt == ':' || (p = strchr(options, optopt)) == NULL) {
- if (opterr)
- (void)fprintf(stderr, "%s: illegal option -- %c\n", av[0], optopt);
- if (av[optind][++sp] == '\0') {
- optind++;
- sp = 1;
- }
- return '?';
- }
-
- /* Flag needs an option? */
- if (*++p == ':') {
- if (av[optind][sp + 1])
- optarg = &av[optind++][sp + 1];
- else if (++optind < ac)
- optarg = av[optind++];
- else {
- if (opterr)
- (void)fprintf(stderr,
- "%s: option requires an argument -- %c\n",
- av[0], optopt);
- sp = 1;
- return '?';
- }
- sp = 1;
- }
- else {
- if (av[optind][++sp] == '\0') {
- sp = 1;
- optind++;
- }
- optarg = NULL;
- }
- return optopt;
- }
-
-
- #ifdef NEED_MEMSET
- /*
- ** Set memory to a value.
- */
- void *
- memset(save, c, count)
- void *save;
- int c;
- unsigned int count;
- {
- char *p;
- register int i;
-
- if ((i = count) != 0)
- for (p = save; --i >= 0; )
- *p++ = c;
-
- return save;
- }
- #endif /* NEED_MEMSET */
-
-
- #ifdef NEED_RENAME
- /*
- ** Turn a nice pretty /unix/path/name into an ugly [.vms.path]name
- */
- STATIC void
- VMSname(path, buffer)
- char *path;
- char *buffer;
- {
- REGISTER char *p;
- REGISTER char *tail;
- char temp[SIZE];
-
- /* Simple case "foo" ==> "foo" */
- (void)strcpy(temp, path);
- if ((tail = strrchr(temp, '/')) == NULL) {
- strcpy(buffer, path);
- return;
- }
-
- /* Split off the last component. */
- *tail++ = '\0';
-
- /* Turn all slashes into periods. */
- for (p = temp; p = strchr(p, '/'); )
- *p++ = '.';
- if (temp[0] == '.')
- (void)sprintf(buffer, "[%s]%s", &temp[1], tail);
- else
- (void)sprintf(buffer, "[.%s]%s", temp, tail);
- }
-
-
- /*
- ** Rename a file.
- */
- int
- rename(from, to)
- char *from;
- char *to;
- {
- struct dsc$descriptor_s Fdesc;
- struct dsc$descriptor_s Tdesc;
- char Fname[SIZE];
- char Tname[SIZE];
-
- VMSname(from, Fname);
- Fdesc.dsc$a_pointer = Fname;
- Fdesc.dsc$w_length = strlen(Fname);
- Fdesc.dsc$b_dtype = DSC$K_DTYPE_T;
- Fdesc.dsc$b_class = DSC$K_CLASS_S;
-
- VMSname(to, Tname);
- Tdesc.dsc$a_pointer = Tname;
- Tdesc.dsc$w_length = strlen(Tname);
- Tdesc.dsc$b_dtype = DSC$K_DTYPE_T;
- Tdesc.dsc$b_class = DSC$K_CLASS_S;
-
- return lib$rename_file(&Fdesc, &Tdesc) == SS$_NORMAL ? 0 : -1;
- }
- #endif /* NEED_RENAME */
-
-
- /*
- ** Remove a file.
- */
- int
- unlink(Name)
- char *Name;
- {
- return delete(Name);
-
- }
-
-
- /*
- ** Do the grundge work of getting us a socket.
- */
- STATIC int
- GetSocket(machine, port)
- char *machine;
- int port;
- {
- unsigned long rhost();
- REGISTER int s;
- char *p;
- struct sockaddr_in sin;
-
- /* Set up the socket. */
- if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
- perror("Socket creation failed");
- return -1;
- }
-
- /* Set up the socket address. */
- (void)memset((void *)&sin, '\0', sizeof sin);
- p = machine;
- if ((sin.sin_addr.s_addr = rhost(&p)) == -1) {
- perror("No such machine");
- return -1;
- }
- sin.sin_family = AF_INET;
- sin.sin_port = htons(port);
-
- /* Connect to the server. */
- if (connect(s, &sin, sizeof sin) < 0) {
- perror("Connect failed");
- netclose(s);
- return -1;
- }
-
- return s;
- }
-
-
- /*
- ** Open connection to server, return FALSE on error.
- */
- int
- SRVopen(machine, port)
- char *machine;
- int port;
- {
- return (Channel = GetSocket(machine, port)) >= 0;
- }
-
-
- /*
- ** Send a QUIT and shut down.
- */
- void
- SRVclose()
- {
- SRVput("QUIT");
- (void)netclose(Channel);
- }
-
-
- /*
- ** Send a line to the server.
- */
- void
- SRVput(p)
- char *p;
- {
- if (SRVtrace)
- (void)printf(">>>%s\n", p);
- netwrite(Channel, p, strlen(p));
- netwrite(Channel, "\r\n", 2);
- }
-
-
- /*
- ** Get a line of text from the server. Strip end-of-line characters.
- */
- int
- SRVget(buff, size)
- char *buff;
- int size;
- {
- REGISTER char *p;
- REGISTER char *bend;
- REGISTER int c;
-
- for (bend = &buff[size - 1]; ; ) {
- for (p = buff; ((c = SRVcget()) != '\n'); ) {
- if (c == EOF)
- return FALSE;
- if (c != '\r' && p < bend)
- *p++ = c;
- }
- *p = '\0';
- if (SRVtrace)
- (void)printf("<<<%s\n", buff);
- if (strncmp(buff, "INF ", 4))
- return TRUE;
- (void)printf("Server message:\n\t%s\n", &buff[4]);
- (void)fflush(stdout);
- }
- }
-
-
- /*
- ** Get a character from the server.
- */
- int
- SRVcget()
- {
- static char buff[1024];
- static int count;
- static int max;
-
- if (count == max) {
- while ((max = netread(Channel, buff, sizeof buff)) == 0)
- ;
- if (max < 0)
- return EOF;
- if (max > sizeof buff)
- (void)abort();
- count = 0;
- }
- return buff[count++];
- }
-
-
- /*
- ** Get a password without echoing.
- */
- void
- GetPassword(buff, size)
- char *buff;
- int size;
- {
- struct dsc$descriptor_s Desc;
- int i;
- int kb;
- int mask;
- int timeout;
- int length;
-
- /* Create a keyboard to read from. */
- if (smg$create_virtual_keyboard(&kb) != SS$_NORMAL) {
- perror("Error creating virtual_keyboard");
- exit(i);
- }
-
- /* Set up the parameters. */
- Desc.dsc$w_length = size;
- Desc.dsc$b_dtype = DSC$K_DTYPE_T;
- Desc.dsc$b_class = DSC$K_CLASS_S;
- Desc.dsc$a_pointer = buff;
- mask = IO$M_NOECHO;
- timeout = 60;
- length = 0;
-
- /* Read it. */
- i = smg$read_string(&kb, &Desc, 0, &size, &mask, &timeout, 0, &length);
- if (i != SS$_NORMAL) {
- perror("Error reading password");
- exit(i);
- }
-
- /* Delete the keyboard. */
- if (smg$delete_virtual_keyboard(&kb) != SS$_NORMAL) {
- perror("Error deleting virtual keyboard");
- exit(i);
- }
-
- /* Clean up and return. */
- (void)printf("\n");
- buff[length] = '\0';
- }
-