home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
unix
/
volume21
/
coda
/
part02
/
libvms.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-04-08
|
7KB
|
393 lines
/*
** 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';
}