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

  1. /*
  2. **  Copyright 1989 BBN Systems and Technologies Corporation.
  3. **  All Rights Reserved.
  4. **  This is free software, and may be distributed under the terms of the
  5. **  GNU Public License; see the file COPYING for more details.
  6. **
  7. **  Client library routines for VMS with Wollongong 3.0 TCP.
  8. **  Check the "/INCLUDE" qualifier in descrip.mms.
  9. **
  10. **  Our VMS documentation claims some functions exist that really don't,
  11. **  so we've had to implement them on our own.
  12. **
  13. **  Also, Wollongong's header files try to re-specify some of the same
  14. **  same typedef's that the VMS C RTL specifies.  Sigh.
  15. */
  16. #include "client.h"
  17. #include <types.h>
  18. #include <string.h>
  19. #include <ssdef.h>
  20. #include <iodef.h>
  21. #include <descrip.h>
  22. #define time_t    TWG_time_t
  23. #define size_t    TWG_size_t
  24. #include "[sys]types2.h"
  25. #include "[sys]socket.h"
  26. #include "[netinet]in.h"
  27. #undef time_t
  28. #undef size_t
  29. #ifdef    RCSID
  30. static char     RCS[] =
  31.     "$Header: libvms.c,v 2.0 90/04/09 16:29:34 rsalz Exp $";
  32. #endif    /* RCSID */
  33.  
  34.  
  35. /*
  36. **  Depending on what version of the C RTL you have, you will need to
  37. **  edit these.
  38. */
  39. #define NEED_UTIME
  40. #undef NEED_RENAME
  41. #undef NEED_MEMSET
  42.  
  43. STATIC int     Channel;        /* Something to talk with    */
  44.  
  45.  
  46. #ifdef    NEED_UTIME
  47. #include "vmsutime.inc"
  48. #endif    /* NEED_UTIME */
  49.  
  50.  
  51. /*
  52. **  This comes from the AT&T public domain getopt handed out at 1985
  53. **  UNIFORUM and subsequently posted to Usenet.
  54. */
  55. int        opterr = 1;
  56. int        optind = 1;
  57. int        optopt;
  58. char        *optarg;
  59. extern char    *strchr();
  60.  
  61. int
  62. getopt(ac, av, options)
  63.     int            ac;
  64.     char        **av;
  65.     char        *options;
  66. {
  67.     static int        sp = 1;
  68.     REGISTER char    *p;
  69.  
  70.     if (sp == 1) {
  71.     if (optind >= ac || av[optind][0] != '-' || av[optind][1] == '\0')
  72.         return EOF;
  73.     if (strcmp(av[optind], "--") == 0) {
  74.         optind++;
  75.         return EOF;
  76.     }
  77.     }
  78.  
  79.     optopt = av[optind][sp];
  80.  
  81.     /* Bogus flag? */
  82.     if (optopt == ':' || (p = strchr(options, optopt)) == NULL) {
  83.     if (opterr)
  84.         (void)fprintf(stderr, "%s: illegal option -- %c\n", av[0], optopt);
  85.     if (av[optind][++sp] == '\0') {
  86.         optind++;
  87.         sp = 1;
  88.     }
  89.     return '?';
  90.     }
  91.  
  92.     /* Flag needs an option? */
  93.     if (*++p == ':') {
  94.     if (av[optind][sp + 1])
  95.         optarg = &av[optind++][sp + 1];
  96.     else if (++optind < ac)
  97.         optarg = av[optind++];
  98.     else {
  99.         if (opterr)
  100.         (void)fprintf(stderr,
  101.             "%s: option requires an argument -- %c\n",
  102.             av[0], optopt);
  103.         sp = 1;
  104.         return '?';
  105.     }
  106.     sp = 1;
  107.     }
  108.     else {
  109.     if (av[optind][++sp] == '\0') {
  110.         sp = 1;
  111.         optind++;
  112.     }
  113.     optarg = NULL;
  114.     }
  115.     return optopt;
  116. }
  117.  
  118.  
  119. #ifdef    NEED_MEMSET
  120. /*
  121. **  Set memory to a value.
  122. */
  123. void *
  124. memset(save, c, count)
  125.     void        *save;
  126.     int            c;
  127.     unsigned int    count;
  128. {
  129.     char        *p;
  130.     register int     i;
  131.  
  132.     if ((i = count) != 0)
  133.     for (p = save; --i >= 0; )
  134.         *p++ = c;
  135.  
  136.     return save;
  137. }
  138. #endif    /* NEED_MEMSET */
  139.  
  140.  
  141. #ifdef    NEED_RENAME
  142. /*
  143. **  Turn a nice pretty /unix/path/name into an ugly [.vms.path]name
  144. */
  145. STATIC void
  146. VMSname(path, buffer)
  147.     char        *path;
  148.     char        *buffer;
  149. {
  150.     REGISTER char    *p;
  151.     REGISTER char    *tail;
  152.     char        temp[SIZE];
  153.  
  154.     /* Simple case "foo" ==> "foo" */
  155.     (void)strcpy(temp, path);
  156.     if ((tail = strrchr(temp, '/')) == NULL) {
  157.     strcpy(buffer, path);
  158.     return;
  159.     }
  160.  
  161.     /* Split off the last component. */
  162.     *tail++ = '\0';
  163.  
  164.     /* Turn all slashes into periods. */
  165.     for (p = temp; p = strchr(p, '/'); )
  166.     *p++ = '.';
  167.     if (temp[0] == '.')
  168.     (void)sprintf(buffer, "[%s]%s", &temp[1], tail);
  169.     else
  170.     (void)sprintf(buffer, "[.%s]%s", temp, tail);
  171. }
  172.  
  173.  
  174. /*
  175. **  Rename a file.
  176. */
  177. int
  178. rename(from, to)
  179.     char            *from;
  180.     char            *to;
  181. {
  182.     struct dsc$descriptor_s    Fdesc;
  183.     struct dsc$descriptor_s    Tdesc;
  184.     char            Fname[SIZE];
  185.     char            Tname[SIZE];
  186.  
  187.     VMSname(from, Fname);
  188.     Fdesc.dsc$a_pointer = Fname;
  189.     Fdesc.dsc$w_length  = strlen(Fname);
  190.     Fdesc.dsc$b_dtype   = DSC$K_DTYPE_T;
  191.     Fdesc.dsc$b_class   = DSC$K_CLASS_S;
  192.  
  193.     VMSname(to, Tname);
  194.     Tdesc.dsc$a_pointer = Tname;
  195.     Tdesc.dsc$w_length  = strlen(Tname);
  196.     Tdesc.dsc$b_dtype   = DSC$K_DTYPE_T;
  197.     Tdesc.dsc$b_class   = DSC$K_CLASS_S;
  198.  
  199.     return lib$rename_file(&Fdesc, &Tdesc) == SS$_NORMAL ? 0 : -1;
  200. }
  201. #endif    /* NEED_RENAME */
  202.  
  203.  
  204. /*
  205. **  Remove a file.
  206. */
  207. int
  208. unlink(Name)
  209.     char    *Name;
  210. {
  211.     return delete(Name);
  212.  
  213. }
  214.  
  215.  
  216. /*
  217. **  Do the grundge work of getting us a socket.
  218. */
  219. STATIC int
  220. GetSocket(machine, port)
  221.     char        *machine;
  222.     int            port;
  223. {
  224.     unsigned long    rhost();
  225.     REGISTER int    s;
  226.     char        *p;
  227.     struct sockaddr_in    sin;
  228.  
  229.     /* Set up the socket. */
  230.     if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
  231.     perror("Socket creation failed");
  232.     return -1;
  233.     }
  234.  
  235.     /* Set up the socket address. */
  236.     (void)memset((void *)&sin, '\0', sizeof sin);
  237.     p = machine;
  238.     if ((sin.sin_addr.s_addr = rhost(&p)) == -1) {
  239.     perror("No such machine");
  240.     return -1;
  241.     }
  242.     sin.sin_family = AF_INET;
  243.     sin.sin_port = htons(port);
  244.  
  245.     /* Connect to the server. */
  246.     if (connect(s, &sin, sizeof sin) < 0) {
  247.     perror("Connect failed");
  248.     netclose(s);
  249.     return -1;
  250.     }
  251.  
  252.     return s;
  253. }
  254.  
  255.  
  256. /*
  257. **  Open connection to server, return FALSE on error.
  258. */
  259. int
  260. SRVopen(machine, port)
  261.     char    *machine;
  262.     int        port;
  263. {
  264.     return (Channel = GetSocket(machine, port)) >= 0;
  265. }
  266.  
  267.  
  268. /*
  269. **  Send a QUIT and shut down.
  270. */
  271. void
  272. SRVclose()
  273. {
  274.     SRVput("QUIT");
  275.     (void)netclose(Channel);
  276. }
  277.  
  278.  
  279. /*
  280. **  Send a line to the server.
  281. */
  282. void
  283. SRVput(p)
  284.     char    *p;
  285. {
  286.     if (SRVtrace)
  287.     (void)printf(">>>%s\n", p);
  288.     netwrite(Channel, p, strlen(p));
  289.     netwrite(Channel, "\r\n", 2);
  290. }
  291.  
  292.  
  293. /*
  294. **  Get a line of text from the server.  Strip end-of-line characters.
  295. */
  296. int
  297. SRVget(buff, size)
  298.     char        *buff;
  299.     int            size;
  300. {
  301.     REGISTER char    *p;
  302.     REGISTER char    *bend;
  303.     REGISTER int    c;
  304.  
  305.     for (bend = &buff[size - 1]; ; ) {
  306.     for (p = buff; ((c = SRVcget()) != '\n'); ) {
  307.         if (c == EOF)
  308.         return FALSE;
  309.         if (c != '\r' && p < bend)
  310.         *p++ = c;
  311.     }
  312.     *p = '\0';
  313.     if (SRVtrace)
  314.         (void)printf("<<<%s\n", buff);
  315.     if (strncmp(buff, "INF ", 4))
  316.         return TRUE;
  317.     (void)printf("Server message:\n\t%s\n", &buff[4]);
  318.     (void)fflush(stdout);
  319.     }
  320. }
  321.  
  322.  
  323. /*
  324. **  Get a character from the server.
  325. */
  326. int
  327. SRVcget()
  328. {
  329.     static char    buff[1024];
  330.     static int    count;
  331.     static int    max;
  332.  
  333.     if (count == max) {
  334.     while ((max = netread(Channel, buff, sizeof buff)) == 0)
  335.         ;
  336.     if (max < 0)
  337.         return EOF;
  338.     if (max > sizeof buff)
  339.         (void)abort();
  340.     count = 0;
  341.     }
  342.     return buff[count++];
  343. }
  344.  
  345.  
  346. /*
  347. **  Get a password without echoing.
  348. */
  349. void
  350. GetPassword(buff, size)
  351.      char            *buff;
  352.      int            size;
  353. {
  354.     struct dsc$descriptor_s    Desc;
  355.     int                i;
  356.     int                kb;
  357.     int                mask;
  358.     int                timeout;
  359.     int                length;
  360.  
  361.     /* Create a keyboard to read from. */
  362.     if (smg$create_virtual_keyboard(&kb) != SS$_NORMAL) {
  363.     perror("Error creating virtual_keyboard");
  364.     exit(i);
  365.     }
  366.  
  367.     /* Set up the parameters. */
  368.     Desc.dsc$w_length = size;
  369.     Desc.dsc$b_dtype = DSC$K_DTYPE_T;
  370.     Desc.dsc$b_class = DSC$K_CLASS_S;
  371.     Desc.dsc$a_pointer = buff;
  372.     mask = IO$M_NOECHO;
  373.     timeout = 60;
  374.     length = 0;
  375.  
  376.     /* Read it. */
  377.     i = smg$read_string(&kb, &Desc, 0, &size, &mask, &timeout, 0, &length);
  378.     if (i != SS$_NORMAL) {
  379.     perror("Error reading password");
  380.     exit(i);
  381.     }
  382.  
  383.     /* Delete the keyboard. */
  384.     if (smg$delete_virtual_keyboard(&kb) != SS$_NORMAL) {
  385.     perror("Error deleting virtual keyboard");
  386.     exit(i);
  387.     }
  388.  
  389.     /* Clean up and return. */
  390.     (void)printf("\n");
  391.     buff[length] = '\0';
  392. }
  393.