summaryrefslogtreecommitdiffstats
path: root/src/isode/compat/ubcx25.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/isode/compat/ubcx25.c')
-rw-r--r--src/isode/compat/ubcx25.c320
1 files changed, 320 insertions, 0 deletions
diff --git a/src/isode/compat/ubcx25.c b/src/isode/compat/ubcx25.c
new file mode 100644
index 000000000..cdabf6577
--- /dev/null
+++ b/src/isode/compat/ubcx25.c
@@ -0,0 +1,320 @@
+/* ubcx25.c - X.25 abstractions for UBC X25 */
+
+#ifndef lint
+static char *rcsid = "$Header$";
+#endif
+
+/*
+ * $Header$
+ *
+ * Contributed by Julian Onions, Nottingham University in the UK
+ *
+ *
+ * $Log$
+ * Revision 1.1 1994/06/10 03:28:45 eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1 94/06/10 03:17:08 eichin
+ * autoconfed isode for kerberos work
+ *
+ * Revision 1.1 1994/05/31 20:35:04 eichin
+ * reduced-isode release from /mit/isode/isode-subset/src
+ *
+ * Revision 8.0 91/07/17 12:18:22 isode
+ * Release 7.0
+ *
+ *
+ */
+
+/*
+ * NOTICE
+ *
+ * Acquisition, use, and distribution of this module and related
+ * materials are subject to the restrictions of a license agreement.
+ * Consult the Preface in the User's Manual for the full terms of
+ * this agreement.
+ *
+ */
+
+
+/* LINTLIBRARY */
+
+#include <errno.h>
+#include <stdio.h>
+#include "general.h"
+#include "manifest.h"
+#include "tailor.h"
+#include "tpkt.h"
+
+/* 4.[23] UNIX: UBC X25 */
+
+#ifdef X25
+#ifdef UBC_X25
+
+#include "x25.h"
+#include <sys/uio.h>
+
+#define X25_MBIT 0x40
+#define X25_QBIT 0x80
+
+/* */
+
+int start_x25_client (local)
+struct NSAPaddr *local;
+{
+ int sd, pgrp;
+
+ if (local != NULLNA)
+ local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+ if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+ return NOTOK; /* Error can be found in errno */
+ }
+
+ pgrp = getpid();
+ if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+ return NOTOK; /* Error can be found in errno */
+ }
+
+ return sd;
+}
+
+/* */
+
+int start_x25_server (local, backlog, opt1, opt2)
+struct NSAPaddr *local;
+int backlog,
+ opt1,
+ opt2;
+{
+ int sd, pgrp;
+#ifdef notyet
+#ifdef BSD43
+ int onoff;
+#endif
+#endif
+ CONN_DB zsck;
+ CONN_DB *sck = &zsck;
+
+ if ((sd = socket (AF_CCITT, SOCK_STREAM, 0)) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("socket"));
+ return NOTOK; /* Can't get an X.25 socket */
+ }
+
+ pgrp = getpid();
+ if (ioctl(sd, SIOCSPGRP, &pgrp)) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("SIOCSPGRP"));
+ return NOTOK; /* Error can be found in errno */
+ }
+
+ if (local != NULLNA) {
+ local -> na_stack = NA_X25, local -> na_community = ts_comm_x25_default;
+ if (local -> na_dtelen == 0) {
+ (void) strcpy (local -> na_dte, x25_local_dte);
+ local -> na_dtelen = strlen(x25_local_dte);
+ if (local -> na_pidlen == 0 && *x25_local_pid)
+ local -> na_pidlen =
+ str2sel (x25_local_pid, -1, local -> na_pid, NPSIZE);
+ }
+ }
+
+ (void) gen2if (local, sck, ADDR_LISTEN);
+ if (bind (sd, sck, sizeof(CONN_DB)) == NOTOK) {
+ SLOG (compat_log, LLOG_EXCEPTIONS, "failed", ("bind"));
+ (void) close_x25_socket (sd);
+ return NOTOK;
+ }
+
+
+#ifdef notyet /* not sure if these are supported... */
+#ifndef BSD43
+ if (opt1)
+ (void) setsockopt (sd, SOL_SOCKET, opt1, NULLCP, 0);
+ if (opt2)
+ (void) setsockopt (sd, SOL_SOCKET, opt2, NULLCP, 0);
+#else
+ onoff = 1;
+ if (opt1)
+ (void) setsockopt (sd, SOL_SOCKET, opt1, (char *)&onoff, sizeof onoff);
+ if (opt2)
+ (void) setsockopt (sd, SOL_SOCKET, opt2, (char *)&onoff, sizeof onoff);
+#endif
+#endif
+
+ (void) listen (sd, backlog);
+
+ return sd;
+}
+
+/* */
+
+int join_x25_client (fd, remote)
+int fd;
+struct NSAPaddr *remote;
+{
+ CONN_DB sck;
+ int len = sizeof sck;
+ int nfd;
+
+ if((nfd = accept (fd, (struct sockaddr *) &sck, &len)) == NOTOK)
+ return NOTOK;
+ (void) if2gen (remote, &sck, ADDR_REMOTE);
+ return nfd;
+}
+
+int join_x25_server (fd, remote)
+int fd;
+struct NSAPaddr *remote;
+{
+ CONN_DB zsck;
+ CONN_DB *sck = &zsck;
+
+ if (remote == NULLNA || remote -> na_stack != NA_X25)
+ {
+ SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+ ("Invalid type na%d", remote->na_stack));
+ return NOTOK;
+ }
+ (void) gen2if (remote, sck, ADDR_REMOTE);
+ return connect (fd, sck, sizeof (CONN_DB));
+}
+
+int read_x25_socket (fd, buffer, len)
+int fd, len;
+char *buffer;
+{
+ static u_char mode;
+ static struct iovec iov[2] = {
+ (char *)&mode, 1,
+ "", 0
+ };
+ char *p = buffer;
+ int cc, count = 0, total = len;
+
+ do {
+ iov[1].iov_base = p;
+ iov[1].iov_len = total > X25_PACKETSIZE ? X25_PACKETSIZE : total;
+
+ switch (cc = readv (fd, iov, 2)) {
+ /*
+ * for the -1,0 & 1 cases these returns should be ok
+ * if it's the first time through, then they are valid anyway
+ * later stages means the M bit is set so there must
+ * be more data else someone is violating the
+ * protocol badly.
+ */
+
+ case NOTOK:
+ case 0:
+ return cc;
+
+ case 1:
+ SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+ ("strange return from read_x25_socket"));
+ return NOTOK;
+
+ default:
+ cc --; /* discount the info byte */
+ count += cc;
+ p += cc;
+ total -= cc;
+ }
+ } while (len > 0 && (mode & X25_MBIT));
+ DLOG (compat_log, LLOG_DEBUG, ("X25 read, total %d/%d", count, len));
+
+ return count;
+}
+
+#ifdef UBC_X25_WRITEV
+/* God this all very bizarre - iovecs work on read but not write!! */
+
+/*
+ * OK, this is due to a bug in UBC implementation. It may or may not
+ * be fixed in later versions. If writev allows you to write single
+ * bytes in the first vector then use this version. It's much more
+ * efficient.
+ */
+
+int write_x25_socket (fd, buffer, len)
+int fd, len;
+char *buffer;
+{
+ static u_char mode;
+ static struct iovec iov[2] = {
+ (char *)&mode, 1,
+ "", 0
+ };
+ int cc;
+ char *p = buffer;
+ int count, total = 0;
+
+ do {
+ count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len;
+ mode = len > X25_PACKETSIZE ? X25_MBIT : 0;
+ iov[1].iov_base = p;
+ iov[1].iov_len = count;
+ switch (cc = writev (fd, iov, 2))
+ {
+ case NOTOK:
+ case 0:
+ return cc;
+
+ case 1:
+ SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+ ("strange return from write_x25_socket"));
+ return NOTOK;
+
+ default:
+ cc --;
+ len -= cc;
+ p += cc;
+ total += cc;
+ }
+ } while (len > 0);
+ DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len));
+ return total;
+}
+#else
+int write_x25_socket (fd, buffer, len)
+int fd, len;
+char *buffer;
+{
+ char mybuffer[X25_PACKETSIZE+1];
+ char *p = buffer;
+ int count, total = 0;
+ int cc;
+
+ do {
+ count = len > X25_PACKETSIZE ? X25_PACKETSIZE : len;
+ mybuffer[0] = len > X25_PACKETSIZE ? X25_MBIT : 0;
+ bcopy (p, &mybuffer[1], count);
+ switch (cc = write (fd, mybuffer, count + 1))
+ {
+ case NOTOK:
+ case 0:
+ return cc;
+
+ case 1:
+ SLOG (compat_log, LLOG_EXCEPTIONS, NULLCP,
+ ("strange return from write_x25_socket"));
+ return NOTOK;
+
+ default:
+ cc --;
+ len -= cc;
+ p += cc;
+ total += cc;
+ }
+ } while (len > 0);
+ DLOG (compat_log, LLOG_DEBUG, ("X25 write, total %d/%d", total, len));
+ return total;
+}
+#endif
+
+#else /* UBC_X25 */
+int _ubcx25_stub2 () {}
+#endif /* UBC_X25 */
+#else /* X25 */
+int _ubcx25_stub () {}
+#endif /* X25 */