diff options
Diffstat (limited to 'imap/src/osdep/vms')
-rw-r--r-- | imap/src/osdep/vms/build.com | 99 | ||||
-rw-r--r-- | imap/src/osdep/vms/clean.com | 26 | ||||
-rw-r--r-- | imap/src/osdep/vms/dummy.h | 43 | ||||
-rw-r--r-- | imap/src/osdep/vms/dummyvms.c | 295 | ||||
-rw-r--r-- | imap/src/osdep/vms/env_vms.c | 174 | ||||
-rw-r--r-- | imap/src/osdep/vms/env_vms.h | 60 | ||||
-rw-r--r-- | imap/src/osdep/vms/fs_vms.c | 62 | ||||
-rw-r--r-- | imap/src/osdep/vms/ftl_vms.c | 38 | ||||
-rw-r--r-- | imap/src/osdep/vms/link.opt | 1 | ||||
-rw-r--r-- | imap/src/osdep/vms/link_mnt.opt | 1 | ||||
-rw-r--r-- | imap/src/osdep/vms/link_nlb.opt | 1 | ||||
-rw-r--r-- | imap/src/osdep/vms/linkage.c | 37 | ||||
-rw-r--r-- | imap/src/osdep/vms/linkage.h | 36 | ||||
-rw-r--r-- | imap/src/osdep/vms/nl_vms.c | 92 | ||||
-rw-r--r-- | imap/src/osdep/vms/os_vms.c | 76 | ||||
-rw-r--r-- | imap/src/osdep/vms/os_vms.h | 52 | ||||
-rw-r--r-- | imap/src/osdep/vms/pmatch.c | 89 | ||||
-rw-r--r-- | imap/src/osdep/vms/tcp_vms.h | 52 | ||||
-rw-r--r-- | imap/src/osdep/vms/tcp_vmsl.c | 378 | ||||
-rw-r--r-- | imap/src/osdep/vms/tcp_vmsm.c | 479 | ||||
-rw-r--r-- | imap/src/osdep/vms/tcp_vmsn.c | 222 |
21 files changed, 2313 insertions, 0 deletions
diff --git a/imap/src/osdep/vms/build.com b/imap/src/osdep/vms/build.com new file mode 100644 index 00000000..aedbcc82 --- /dev/null +++ b/imap/src/osdep/vms/build.com @@ -0,0 +1,99 @@ +$! ======================================================================== +$! Copyright 1988-2006 University of Washington +$! +$! Licensed under the Apache License, Version 2.0 (the "License"); +$! you may not use this file except in compliance with the License. +$! You may obtain a copy of the License at +$! +$! http://www.apache.org/licenses/LICENSE-2.0 +$! +$! +$! ======================================================================== +$! +$! Program: Portable c-client build for VMS +$! +$! Author: Mark Crispin +$! Networks and Distributed Computing +$! Computing & Communications +$! University of Washington +$! Administration Building, AG-44 +$! Seattle, WA 98195 +$! Internet: MRC@CAC.Washington.EDU +$! +$! Date: 2 August 1994 +$! Last Edited: 30 August 2006 +$! +$! Change this to your local timezone. This value is the number of minutes +$! east of UTC (formerly known as GMT). Sample values: -300 (US east coast), +$! -480 (US west coast), 540 (Japan), 60 (western Europe). +$! VAX C's HELP information says that you should be able to use gmtime(), but +$! it returns 0 for the struct. ftime(), you ask? It, too, returns 0 for a +$! timezone. Nothing sucks like a VAX! +$! +$ CC_TIMEZONE=-480 +$! +$! CC options +$! +$ CC_PREF = "/OPTIMIZE/INCLUDE=[]" +$ CC_PREF = CC_PREF + "/DEFINE=net_getbuffer=NET_GETBUF" +$ CC_PREF = CC_PREF + "/DEFINE=LOCALTIMEZONE='CC_TIMEZONE'" +$! +$! Determine TCP type +$! +$ TCP_TYPE = "VMSN" ! default to none +$ IF F$LOCATE("MULTINET", P1) .LT. F$LENGTH(P1) +$ THEN +$ DEFINE SYS MULTINET_ROOT:[MULTINET.INCLUDE.SYS],sys$library +$ DEFINE NETINET MULTINET_ROOT:[MULTINET.INCLUDE.NETINET] +$ DEFINE ARPA MULTINET_ROOT:[MULTINET.INCLUDE.ARPA] +$ TCP_TYPE = "VMSM" ! Multinet +$ LINK_OPT = ",LINK_MNT/OPTION" +$ ENDIF +$ IF F$LOCATE("NETLIB", P1) .LT. F$LENGTH(P1) +$ THEN +$ DEFINE SYS SYS$LIBRARY: ! normal .H location +$ DEFINE NETINET SYS$LIBRARY: +$ DEFINE ARPA SYS$LIBRARY: +$ LINK_OPT = ",LINK_NLB/OPTION" +$ TCP_TYPE = "VMSL" ! NETLIB +$ ENDIF +$ IF TCP_TYPE .EQS. "VMSN" +$ THEN +$ DEFINE SYS SYS$LIBRARY: ! normal .H location +$ DEFINE NETINET SYS$LIBRARY: +$ DEFINE ARPA SYS$LIBRARY: +$ LINK_OPT = "" +$ ENDIF +$! +$ COPY TCP_'TCP_TYPE'.C TCP_VMS.C; +$! +$ COPY OS_VMS.H OSDEP.H; +$ SET VERIFY +$ CC'CC_PREF' MAIL +$ CC'CC_PREF' IMAP4R1 +$ CC'CC_PREF' SMTP +$ CC'CC_PREF' NNTP +$ CC'CC_PREF' POP3 +$ CC'CC_PREF' DUMMYVMS +$ CC'CC_PREF' RFC822 +$ CC'CC_PREF' MISC +$ CC'CC_PREF' OS_VMS +$ CC'CC_PREF' SMANAGER +$ CC'CC_PREF' FLSTRING +$ CC'CC_PREF' NEWSRC +$ CC'CC_PREF' NETMSG +$ CC'CC_PREF' UTF8 +$ CC'CC_PREF' UTF8AUX +$ CC'CC_PREF' MTEST +$ CC'CC_PREF' MAILUTIL +$! +$ LINK MTEST,OS_VMS,MAIL,IMAP4R1,SMTP,NNTP,POP3,DUMMYVMS,RFC822,MISC,UTF8,- + UTF8AUX,SMANAGER,FLSTRING,NEWSRC,NETMSG,- + SYS$INPUT:/OPTION'LINK_OPT',LINK/OPTION +PSECT=_CTYPE_,NOWRT +$ LINK MAILUTIL,OS_VMS,MAIL,IMAP4R1,SMTP,NNTP,POP3,DUMMYVMS,RFC822,MISC,UTF8,- + UTF8AUX,SMANAGER,FLSTRING,NEWSRC,NETMSG,- + SYS$INPUT:/OPTION'LINK_OPT',LINK/OPTION +PSECT=_CTYPE_,NOWRT +$ SET NOVERIFY +$ EXIT diff --git a/imap/src/osdep/vms/clean.com b/imap/src/osdep/vms/clean.com new file mode 100644 index 00000000..98df0db5 --- /dev/null +++ b/imap/src/osdep/vms/clean.com @@ -0,0 +1,26 @@ +$! ======================================================================== +$! Copyright 1988-2006 University of Washington +$! +$! Licensed under the Apache License, Version 2.0 (the "License"); +$! you may not use this file except in compliance with the License. +$! You may obtain a copy of the License at +$! +$! http://www.apache.org/licenses/LICENSE-2.0 +$! +$! +$! ======================================================================== +$! +$! Program: Portable c-client cleanup for VMS +$! +$! Author: Mark Crispin +$! Networks and Distributed Computing +$! Computing & Communications +$! University of Washington +$! Administration Building, AG-44 +$! Seattle, WA 98195 +$! Internet: MRC@CAC.Washington.EDU +$! +$! Date: 14 June 1995 +$! Last Edited: 30 August 2006 +$! +$ DELETE *.OBJ;*,OSDEP.*;*,TCP_VMS.C;*,MTEST.EXE;*,MAILUTIL.EXE;* diff --git a/imap/src/osdep/vms/dummy.h b/imap/src/osdep/vms/dummy.h new file mode 100644 index 00000000..32650e06 --- /dev/null +++ b/imap/src/osdep/vms/dummy.h @@ -0,0 +1,43 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Dummy routines + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 9 May 1991 + * Last Edited: 30 August 2006 + */ + +/* Exported function prototypes */ + +void dummy_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents); +void dummy_list (MAILSTREAM *stream,char *ref,char *pat); +void dummy_lsub (MAILSTREAM *stream,char *ref,char *pat); +long scan_contents (DRIVER *dtb,char *name,char *contents, + unsigned long csiz,unsigned long fsiz); +long dummy_scan_contents (char *name,char *contents,unsigned long csiz, + unsigned long fsiz); +long dummy_create (MAILSTREAM *stream,char *mailbox); +long dummy_create_path (MAILSTREAM *stream,char *path,long dirmode); +long dummy_delete (MAILSTREAM *stream,char *mailbox); +long dummy_rename (MAILSTREAM *stream,char *old,char *newname); +char *dummy_file (char *dst,char *name); +long dummy_canonicalize (char *tmp,char *ref,char *pat); diff --git a/imap/src/osdep/vms/dummyvms.c b/imap/src/osdep/vms/dummyvms.c new file mode 100644 index 00000000..cfcb45d0 --- /dev/null +++ b/imap/src/osdep/vms/dummyvms.c @@ -0,0 +1,295 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Dummy routines for VMS + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 24 May 1993 + * Last Edited: 30 August 2006 + */ + + +#include <ctype.h> +#include <stdio.h> +#include "mail.h" +#include "osdep.h" +#include "dummy.h" +#include "misc.h" + +/* Function prototypes */ + +DRIVER *dummy_valid (char *name); +void *dummy_parameters (long function,void *value); +MAILSTREAM *dummy_open (MAILSTREAM *stream); +void dummy_close (MAILSTREAM *stream,long options); +long dummy_ping (MAILSTREAM *stream); +void dummy_check (MAILSTREAM *stream); +long dummy_expunge (MAILSTREAM *stream,char *sequence,long options); +long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options); +long dummy_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data); + +/* Dummy routines */ + + +/* Driver dispatch used by MAIL */ + +DRIVER dummydriver = { + "dummy", /* driver name */ + DR_LOCAL|DR_MAIL, /* driver flags */ + (DRIVER *) NIL, /* next driver */ + dummy_valid, /* mailbox is valid for us */ + dummy_parameters, /* manipulate parameters */ + dummy_scan, /* scan mailboxes */ + dummy_list, /* list mailboxes */ + dummy_lsub, /* list subscribed mailboxes */ + NIL, /* subscribe to mailbox */ + NIL, /* unsubscribe from mailbox */ + dummy_create, /* create mailbox */ + dummy_delete, /* delete mailbox */ + dummy_rename, /* rename mailbox */ + mail_status_default, /* status of mailbox */ + dummy_open, /* open mailbox */ + dummy_close, /* close mailbox */ + NIL, /* fetch message "fast" attributes */ + NIL, /* fetch message flags */ + NIL, /* fetch overview */ + NIL, /* fetch message structure */ + NIL, /* fetch header */ + NIL, /* fetch text */ + NIL, /* fetch message data */ + NIL, /* unique identifier */ + NIL, /* message number from UID */ + NIL, /* modify flags */ + NIL, /* per-message modify flags */ + NIL, /* search for message based on criteria */ + NIL, /* sort messages */ + NIL, /* thread messages */ + dummy_ping, /* ping mailbox to see if still alive */ + dummy_check, /* check for new messages */ + dummy_expunge, /* expunge deleted messages */ + dummy_copy, /* copy messages to another mailbox */ + dummy_append, /* append string message to mailbox */ + NIL /* garbage collect stream */ +}; + + + /* prototype stream */ +MAILSTREAM dummyproto = {&dummydriver}; + +/* Dummy validate mailbox + * Accepts: mailbox name + * Returns: our driver if name is valid, NIL otherwise + */ + +DRIVER *dummy_valid (char *name) +{ + char tmp[MAILTMPLEN]; + /* must be valid local mailbox */ + return (name && *name && (*name != '{') && !compare_cstring (name,"INBOX")) ? + &dummydriver : NIL; +} + + +/* Dummy manipulate driver parameters + * Accepts: function code + * function-dependent value + * Returns: function-dependent return value + */ + +void *dummy_parameters (long function,void *value) +{ + return NIL; +} + +/* Dummy scan mailboxes + * Accepts: mail stream + * reference + * pattern to search + * string to scan + */ + +void dummy_scan (MAILSTREAM *stream,char *ref,char *pat,char *contents) +{ + /* return silently */ +} + + +/* Dummy list mailboxes + * Accepts: mail stream + * reference + * pattern to search + */ + +void dummy_list (MAILSTREAM *stream,char *ref,char *pat) +{ + /* return silently */ +} + + +/* Dummy list subscribed mailboxes + * Accepts: mail stream + * reference + * pattern to search + */ + +void dummy_lsub (MAILSTREAM *stream,char *ref,char *pat) +{ + /* return silently */ +} + +/* Dummy create mailbox + * Accepts: mail stream + * mailbox name to create + * driver type to use + * Returns: T on success, NIL on failure + */ + +long dummy_create (MAILSTREAM *stream,char *mailbox) +{ + return NIL; /* always fails */ +} + + +/* Dummy delete mailbox + * Accepts: mail stream + * mailbox name to delete + * Returns: T on success, NIL on failure + */ + +long dummy_delete (MAILSTREAM *stream,char *mailbox) +{ + return NIL; /* always fails */ +} + + +/* Mail rename mailbox + * Accepts: mail stream + * old mailbox name + * new mailbox name + * Returns: T on success, NIL on failure + */ + +long dummy_rename (MAILSTREAM *stream,char *old,char *newname) +{ + return NIL; /* always fails */ +} + +/* Dummy open + * Accepts: stream to open + * Returns: stream on success, NIL on failure + */ + +MAILSTREAM *dummy_open (MAILSTREAM *stream) +{ + char tmp[MAILTMPLEN]; + /* OP_PROTOTYPE call or silence */ + if (!stream || stream->silent) return NIL; + if (compare_cstring (stream->mailbox,"INBOX")) { + sprintf (tmp,"Not a mailbox: %s",stream->mailbox); + mm_log (tmp,ERROR); + return NIL; /* always fails */ + } + if (!stream->silent) { /* only if silence not requested */ + mail_exists (stream,0); /* say there are 0 messages */ + mail_recent (stream,0); + stream->uid_validity = time (0); + } + stream->inbox = T; /* note that it's an INBOX */ + return stream; /* return success */ +} + + +/* Dummy close + * Accepts: MAIL stream + * options + */ + +void dummy_close (MAILSTREAM *stream,long options) +{ + /* return silently */ +} + +/* Dummy ping mailbox + * Accepts: MAIL stream + * Returns: T if stream alive, else NIL + * No-op for readonly files, since read/writer can expunge it from under us! + */ + +long dummy_ping (MAILSTREAM *stream) +{ + return T; +} + + +/* Dummy check mailbox + * Accepts: MAIL stream + * No-op for readonly files, since read/writer can expunge it from under us! + */ + +void dummy_check (MAILSTREAM *stream) +{ + dummy_ping (stream); /* invoke ping */ +} + + +/* Dummy expunge mailbox + * Accepts: MAIL stream + * sequence to expunge if non-NIL + * expunge options + * Returns: T, always + */ + +long dummy_expunge (MAILSTREAM *stream,char *sequence,long options) +{ + return LONGT; +} + +/* Dummy copy message(s) + * Accepts: MAIL stream + * sequence + * destination mailbox + * options + * Returns: T if copy successful, else NIL + */ + +long dummy_copy (MAILSTREAM *stream,char *sequence,char *mailbox,long options) +{ + if ((options & CP_UID) ? mail_uid_sequence (stream,sequence) : + mail_sequence (stream,sequence)) fatal ("Impossible dummy_copy"); + return NIL; +} + + +/* Dummy append message string + * Accepts: mail stream + * destination mailbox + * append callback function + * data for callback + * Returns: T on success, NIL on failure + */ + +long dummy_append (MAILSTREAM *stream,char *mailbox,append_t af,void *data) +{ + char tmp[MAILTMPLEN]; + sprintf (tmp,"Can't append to %s",mailbox); + mm_log (tmp,ERROR); /* pass up error */ + return NIL; /* always fails */ +} diff --git a/imap/src/osdep/vms/env_vms.c b/imap/src/osdep/vms/env_vms.c new file mode 100644 index 00000000..56b7a223 --- /dev/null +++ b/imap/src/osdep/vms/env_vms.c @@ -0,0 +1,174 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: VMS environment routines + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 2 August 1994 + * Last Edited: 30 August 2006 + */ + + +static char *myUserName = NIL; /* user name */ +static char *myLocalHost = NIL; /* local host name */ +static char *myHomeDir = NIL; /* home directory name */ +static char *myNewsrc = NIL; /* newsrc file name */ + +#include "pmatch.c" /* include wildcard pattern matcher */ + +/* Environment manipulate parameters + * Accepts: function code + * function-dependent value + * Returns: function-dependent return value + */ + +void *env_parameters (long function,void *value) +{ + void *ret = NIL; + switch ((int) function) { + case SET_USERNAME: + myUserName = cpystr ((char *) value); + case GET_USERNAME: + ret = (void *) myUserName; + break; + case SET_HOMEDIR: + myHomeDir = cpystr ((char *) value); + case GET_HOMEDIR: + ret = (void *) myHomeDir; + break; + case SET_LOCALHOST: + myLocalHost = cpystr ((char *) value); + case GET_LOCALHOST: + ret = (void *) myLocalHost; + break; + case SET_NEWSRC: + if (myNewsrc) fs_give ((void **) &myNewsrc); + myNewsrc = cpystr ((char *) value); + case GET_NEWSRC: + if (!myNewsrc) { /* set news file name if not defined */ + char tmp[MAILTMPLEN]; + sprintf (tmp,"%s:.newsrc",myhomedir ()); + myNewsrc = cpystr (tmp); + } + ret = (void *) myNewsrc; + break; + } + return ret; +} + +/* Write current time + * Accepts: destination string + * optional format of day-of-week prefix + * format of date and time + */ + +static void do_date (char *date,char *prefix,char *fmt) +{ + time_t tn = time (0); + struct tm *t = localtime (&tn); + int zone = LOCALTIMEZONE + (t->tm_isdst ? 60 : 0); + if (prefix) { /* want day of week? */ + sprintf (date,prefix,days[t->tm_wday]); + date += strlen (date); /* make next sprintf append */ + } + /* output the date */ + sprintf (date,fmt,t->tm_mday,months[t->tm_mon],t->tm_year+1900, + t->tm_hour,t->tm_min,t->tm_sec,zone/60,abs (zone) % 60); +} + + +/* Write current time in RFC 822 format + * Accepts: destination string + */ + +void rfc822_date (char *date) +{ + do_date (date,"%s, ","%d %s %d %02d:%02d:%02d %+03d%02d"); +} + + +/* Write current time in internal format + * Accepts: destination string + */ + +void internal_date (char *date) +{ + do_date (date,NIL,"%02d-%s-%d %02d:%02d:%02d %+03d%02d"); +} + +/* Return my user name + * Returns: my user name + */ + +char *myusername () +{ + struct stat sbuf; + char tmp[MAILTMPLEN]; + + if (!myUserName) { /* get user name if don't have it yet */ + myUserName = cpystr (cuserid (NIL)); + myHomeDir = cpystr ("SYS$LOGIN"); + } + return myUserName; +} + + +/* Return my home directory name + * Returns: my home directory name + */ + +char *myhomedir () +{ + if (!myHomeDir) myusername ();/* initialize if first time */ + return myHomeDir; +} + + +/* Determine default prototype stream to user + * Accepts: type (NIL for create, T for append) + * Returns: default prototype stream + */ + +MAILSTREAM *default_proto (long type) +{ + return NIL; /* no default prototype */ +} + +/* Emulator for BSD syslog() routine + * Accepts: priority + * message + * parameters + */ + +void syslog (int priority,const char *message,...) +{ +} + + +/* Emulator for BSD openlog() routine + * Accepts: identity + * options + * facility + */ + +void openlog (const char *ident,int logopt,int facility) +{ +} diff --git a/imap/src/osdep/vms/env_vms.h b/imap/src/osdep/vms/env_vms.h new file mode 100644 index 00000000..59160a06 --- /dev/null +++ b/imap/src/osdep/vms/env_vms.h @@ -0,0 +1,60 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: VMS environment routines + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 2 August 1994 + * Last Edited: 30 August 2006 + */ + + +#define SUBSCRIPTIONFILE(t) sprintf (t,"%s\\SUBSCRIPTIONS.TXT",myhomedir ()) +#define SUBSCRIPTIONTEMP(t) sprintf (t,"%s\\SUBSCRIPTIONS.TMP",myhomedir ()) + +/* Function prototypes */ + +#include "env.h" + +char *myusername (); + + +/* syslog() emulation */ + +#define LOG_MAIL (2<<3) /* mail system */ +#define LOG_DAEMON (3<<3) /* system daemons */ +#define LOG_AUTH (4<<3) /* security/authorization messages */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but signification condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ +#define LOG_PID 0x01 /* log the pid with each message */ +#define LOG_CONS 0x02 /* log on the console if errors in sending */ +#define LOG_ODELAY 0x04 /* delay open until syslog() is called */ +#define LOG_NDELAY 0x08 /* don't delay open */ +#define LOG_NOWAIT 0x10 /* if forking to log on console, don't wait() */ + +void openlog (const char *ident,int logopt,int facility); +void syslog (int priority,const char *message,...); diff --git a/imap/src/osdep/vms/fs_vms.c b/imap/src/osdep/vms/fs_vms.c new file mode 100644 index 00000000..03908328 --- /dev/null +++ b/imap/src/osdep/vms/fs_vms.c @@ -0,0 +1,62 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Free storage management routines + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 1 August 1988 + * Last Edited: 30 August 2006 + */ + +/* Get a block of free storage + * Accepts: size of desired block + * Returns: free storage block + */ + +void *fs_get (size_t size) +{ + void *block = malloc (size ? size : (size_t) 1); + if (!block) fatal ("Out of memory"); + return (block); +} + + +/* Resize a block of free storage + * Accepts: ** pointer to current block + * new size + */ + +void fs_resize (void **block,size_t size) +{ + if (!(*block = realloc (*block,size ? size : (size_t) 1))) + fatal ("Can't resize memory"); +} + + +/* Return a block of free storage + * Accepts: ** pointer to free storage block + */ + +void fs_give (void **block) +{ + free (*block); + *block = NIL; +} diff --git a/imap/src/osdep/vms/ftl_vms.c b/imap/src/osdep/vms/ftl_vms.c new file mode 100644 index 00000000..9e65ef55 --- /dev/null +++ b/imap/src/osdep/vms/ftl_vms.c @@ -0,0 +1,38 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: DOS/VMS/TOPS-20 crash management routines + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 1 August 1988 + * Last Edited: 30 August 2006 + */ + + +/* Report a fatal error + * Accepts: string to output + */ + +void fatal (char *string) +{ + mm_fatal (string); /* pass up the string */ + abort (); /* die horribly */ +} diff --git a/imap/src/osdep/vms/link.opt b/imap/src/osdep/vms/link.opt new file mode 100644 index 00000000..0f454490 --- /dev/null +++ b/imap/src/osdep/vms/link.opt @@ -0,0 +1 @@ +SYS$SHARE:VAXCRTL/SHARE diff --git a/imap/src/osdep/vms/link_mnt.opt b/imap/src/osdep/vms/link_mnt.opt new file mode 100644 index 00000000..5eb99104 --- /dev/null +++ b/imap/src/osdep/vms/link_mnt.opt @@ -0,0 +1 @@ +MULTINET:MULTINET_SOCKET_LIBRARY/SHARE diff --git a/imap/src/osdep/vms/link_nlb.opt b/imap/src/osdep/vms/link_nlb.opt new file mode 100644 index 00000000..883d2859 --- /dev/null +++ b/imap/src/osdep/vms/link_nlb.opt @@ -0,0 +1 @@ +NETLIB_SHR/SHARE diff --git a/imap/src/osdep/vms/linkage.c b/imap/src/osdep/vms/linkage.c new file mode 100644 index 00000000..14490a0c --- /dev/null +++ b/imap/src/osdep/vms/linkage.c @@ -0,0 +1,37 @@ +/* ======================================================================== + * Copyright 1988-2007 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Default driver linkage + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 13 June 1995 + * Last Edited: 23 May 2007 + */ + + mail_link (&imapdriver); /* link in the imap driver */ + mail_link (&nntpdriver); /* link in the nntp driver */ + mail_link (&pop3driver); /* link in the pop3 driver */ + mail_link (&dummydriver); /* link in the dummy driver */ + auth_link (&auth_ext); /* link in the ext authenticator */ + auth_link (&auth_md5); /* link in the md5 authenticator */ + auth_link (&auth_pla); /* link in the plain authenticator */ + auth_link (&auth_log); /* link in the log authenticator */ + mail_versioncheck (CCLIENTVERSION); /* validate version */ diff --git a/imap/src/osdep/vms/linkage.h b/imap/src/osdep/vms/linkage.h new file mode 100644 index 00000000..7e0eccfa --- /dev/null +++ b/imap/src/osdep/vms/linkage.h @@ -0,0 +1,36 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Default driver linkage + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 13 June 1995 + * Last Edited: 30 August 2006 + */ + +extern DRIVER imapdriver; +extern DRIVER nntpdriver; +extern DRIVER pop3driver; +extern DRIVER dummydriver; +extern AUTHENTICATOR auth_ext; +extern AUTHENTICATOR auth_log; +extern AUTHENTICATOR auth_md5; +extern AUTHENTICATOR auth_pla; diff --git a/imap/src/osdep/vms/nl_vms.c b/imap/src/osdep/vms/nl_vms.c new file mode 100644 index 00000000..b2d5616a --- /dev/null +++ b/imap/src/osdep/vms/nl_vms.c @@ -0,0 +1,92 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: UNIX/VMS newline routines + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 1 August 1988 + * Last Edited: 30 August 2006 + */ + +/* Copy string with CRLF newlines + * Accepts: destination string + * pointer to size of destination string buffer + * source string + * length of source string + * Returns: length of copied string + */ + +unsigned long strcrlfcpy (unsigned char **dst,unsigned long *dstl, + unsigned char *src,unsigned long srcl) +{ + long i = srcl * 2,j; + unsigned char c,*d = src; + if (*dst) { /* candidate destination provided? */ + /* count NLs if doesn't fit worst-case */ + if (i > *dstl) for (i = j = srcl; j; --j) if (*d++ == '\012') i++; + /* still too small, must reset destination */ + if (i > *dstl) fs_give ((void **) dst); + } + /* make a new buffer if needed */ + if (!*dst) *dst = (char *) fs_get ((*dstl = i) + 1); + d = *dst; /* destination string */ + if (srcl) do { /* main copy loop */ + if ((c = *src++) < '\016') { + /* prepend CR to LF */ + if (c == '\012') *d++ = '\015'; + /* unlikely CR */ + else if ((c == '\015') && (srcl > 1) && (*src == '\012')) { + *d++ = c; /* copy the CR */ + c = *src++; /* grab the LF */ + --srcl; /* adjust the count */ + } + } + *d++ = c; /* copy character */ + } while (--srcl); + *d = '\0'; /* tie off destination */ + return d - *dst; /* return length */ +} + +/* Length of string after strcrlfcpy applied + * Accepts: source string + * Returns: length of string + */ + +unsigned long strcrlflen (STRING *s) +{ + unsigned long pos = GETPOS (s); + unsigned long i = SIZE (s); + unsigned long j = i; + while (j--) switch (SNX (s)) {/* search for newlines */ + case '\015': /* unlikely carriage return */ + if (j && (CHR (s) == '\012')) { + SNX (s); /* eat the line feed */ + j--; + } + break; + case '\012': /* line feed? */ + i++; + default: /* ordinary chararacter */ + break; + } + SETPOS (s,pos); /* restore old position */ + return i; +} diff --git a/imap/src/osdep/vms/os_vms.c b/imap/src/osdep/vms/os_vms.c new file mode 100644 index 00000000..cd333ba9 --- /dev/null +++ b/imap/src/osdep/vms/os_vms.c @@ -0,0 +1,76 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Operating-system dependent routines -- VMS version + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 2 August 1994 + * Last Edited: 30 August 2006 + */ + +#include "tcp_vms.h" /* must be before osdep includes tcp.h */ +#include "mail.h" +#include "osdep.h" +#include <stdio.h> +#include <sys/time.h> +#include <sys/stat.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <ctype.h> +#include <errno.h> +extern int errno; /* just in case */ +#include "misc.h" + + +#include "fs_vms.c" +#include "ftl_vms.c" +#include "nl_vms.c" +#include "env_vms.c" +#include "tcp_vms.c" + +#define server_login(user,pass,authuser,argc,argv) NIL +#define authserver_login(user,authuser,argc,argv) NIL +#define myusername() "" /* dummy definition to prevent build errors */ +#define MD5ENABLE "" + +#include "auth_md5.c" +#include "auth_pla.c" +#include "auth_log.c" + + +/* Emulator for UNIX getpass() call + * Accepts: prompt + * Returns: password + */ + +#define PWDLEN 128 /* used by Linux */ + +char *getpass (const char *prompt) +{ + char *s; + static char pwd[PWDLEN]; + fputs (prompt,stdout); + fgets (pwd,PWDLEN-1,stdin); + if (s = strchr (pwd,'\n')) *s = '\0'; + return pwd; +} diff --git a/imap/src/osdep/vms/os_vms.h b/imap/src/osdep/vms/os_vms.h new file mode 100644 index 00000000..1da72f13 --- /dev/null +++ b/imap/src/osdep/vms/os_vms.h @@ -0,0 +1,52 @@ +/* ======================================================================== + * Copyright 1988-2007 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Operating-system dependent routines -- VMS version + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 2 August 1994 + * Last Edited: 30 January 2007 + */ + +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <unixio.h> +#include <file.h> +#include <stat.h> + +#define L_SET SEEK_SET +#define L_INCR SEEK_CUR +#define L_XTND SEEK_END + +#include "env_vms.h" +#include "fs.h" +#include "ftl.h" +#include "nl.h" +#include "tcp.h" + +#define gethostid clock +#define random rand +#define unlink delete + +char *getpass (const char *prompt); + +#define strtok_r(a,b,c) strtok(a,b) diff --git a/imap/src/osdep/vms/pmatch.c b/imap/src/osdep/vms/pmatch.c new file mode 100644 index 00000000..95a0bb86 --- /dev/null +++ b/imap/src/osdep/vms/pmatch.c @@ -0,0 +1,89 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: IMAP Wildcard Matching Routines (case-independent) + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 15 June 2000 + * Last Edited: 30 August 2006 + */ + +/* Wildcard pattern match + * Accepts: base string + * pattern string + * delimiter character + * Returns: T if pattern matches base, else NIL + */ + +long pmatch_full (unsigned char *s,unsigned char *pat,unsigned char delim) +{ + switch (*pat) { + case '%': /* non-recursive */ + /* % at end, OK if no inferiors */ + if (!pat[1]) return (delim && strchr (s,delim)) ? NIL : T; + /* scan remainder of string until delimiter */ + do if (pmatch_full (s,pat+1,delim)) return T; + while ((*s != delim) && *s++); + break; + case '*': /* match 0 or more characters */ + if (!pat[1]) return T; /* * at end, unconditional match */ + /* scan remainder of string */ + do if (pmatch_full (s,pat+1,delim)) return T; + while (*s++); + break; + case '\0': /* end of pattern */ + return *s ? NIL : T; /* success if also end of base */ + default: /* match this character */ + return compare_uchar (*pat,*s) ? NIL : pmatch_full (s+1,pat+1,delim); + } + return NIL; +} + +/* Directory pattern match + * Accepts: base string + * pattern string + * delimiter character + * Returns: T if base is a matching directory of pattern, else NIL + */ + +long dmatch (unsigned char *s,unsigned char *pat,unsigned char delim) +{ + switch (*pat) { + case '%': /* non-recursive */ + if (!*s) return T; /* end of base means have a subset match */ + if (!*++pat) return NIL; /* % at end, no inferiors permitted */ + /* scan remainder of string until delimiter */ + do if (dmatch (s,pat,delim)) return T; + while ((*s != delim) && *s++); + if (*s && !s[1]) return T; /* ends with delimiter, must be subset */ + return dmatch (s,pat,delim);/* do new scan */ + case '*': /* match 0 or more characters */ + return T; /* unconditional match */ + case '\0': /* end of pattern */ + break; + default: /* match this character */ + if (*s) return compare_uchar (*pat,*s) ? NIL : dmatch (s+1,pat+1,delim); + /* end of base, return if at delimiter */ + else if (*pat == delim) return T; + break; + } + return NIL; +} diff --git a/imap/src/osdep/vms/tcp_vms.h b/imap/src/osdep/vms/tcp_vms.h new file mode 100644 index 00000000..ff747016 --- /dev/null +++ b/imap/src/osdep/vms/tcp_vms.h @@ -0,0 +1,52 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: VMS TCP/IP routines + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 1 August 1988 + * Last Edited: 30 August 2006 + */ + + +/* TCP input buffer */ + +#define BUFLEN 8192 + + +/* TCP I/O stream */ + +#define TCPSTREAM struct tcp_stream +TCPSTREAM { + char *host; /* host name */ + unsigned long port; /* port number */ + char *localhost; /* local host name */ + int tcpsi; /* input socket */ + int tcpso; /* output socket */ + int ictr; /* input counter */ + char *iptr; /* input pointer */ + char ibuf[BUFLEN]; /* input buffer */ +}; + + +/* Local function prototypes */ + +long tcp_abort (TCPSTREAM *stream); diff --git a/imap/src/osdep/vms/tcp_vmsl.c b/imap/src/osdep/vms/tcp_vmsl.c new file mode 100644 index 00000000..692c9212 --- /dev/null +++ b/imap/src/osdep/vms/tcp_vmsl.c @@ -0,0 +1,378 @@ +/* ======================================================================== + * Copyright 1988-2008 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: VMS TCP/IP routines for Netlib. + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 2 August 1994 + * Last Edited: 13 January 2008 + */ + +/* Thanks to Yehavi Bourvine at The Hebrew University of Jerusalem who + contributed the original VMS code */ + +#include <descrip.h> + +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size, + long *contd); + +/* TCP/IP manipulate parameters + * Accepts: function code + * function-dependent value + * Returns: function-dependent return value + */ + +void *tcp_parameters (long function,void *value) +{ + return NIL; +} + + +/* TCP/IP open + * Accepts: host name + * contact service name + * contact port number + * Returns: TCP/IP stream if success else NIL + */ + +TCPSTREAM *tcp_open (char *host,char *service,unsigned long port) +{ + TCPSTREAM *stream = NIL; + unsigned long sock; + int status; + char tmp[MAILTMPLEN]; + /* hostname to connect to */ + struct dsc$descriptor HostDesc = { 0, DSC$K_DTYPE_T, DSC$K_CLASS_S, NULL }; + port &= 0xffff; /* erase flags */ + /* assign a local socket */ + if (!((status = net_assign (&sock)) & 0x1)) { + sprintf (tmp,"Unable to assign to net, status=%d",status); + mm_log (tmp,ERROR); + return NIL; + } + if (!((status = net_bind (&sock,1)) & 0x1)) { + sprintf (tmp,"Unable to create local socket, status=%d",status); + mm_log (tmp,ERROR); + return NIL; + } + /* open connection */ + HostDesc.dsc$w_length = strlen (host); + HostDesc.dsc$a_pointer = host; + if (!((status = tcp_connect (&sock,&HostDesc,port)) & 0x1)) { + sprintf (tmp,"Can't connect to %.80s,%lu: %s",host,port,strerror (errno)); + mm_log (tmp,ERROR); + return NIL; + } + /* create TCP/IP stream */ + stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM)); + stream->host = cpystr (host); /* copy official host name */ + /* copy local host name */ + stream->localhost = cpystr (mylocalhost ()); + stream->port = port; /* copy port number */ + /* init sockets */ + stream->tcpsi = stream->tcpso = sock; + stream->ictr = 0; /* init input counter */ + return stream; /* return success */ +} + +/* TCP/IP authenticated open + * Accepts: NETMBX specifier + * service name + * returned user name buffer + * Returns: TCP/IP stream if success else NIL + */ + +TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf) +{ + return NIL; +} + +/* TCP receive line + * Accepts: TCP stream + * Returns: text line string or NIL if failure + */ + +char *tcp_getline (TCPSTREAM *stream) +{ + unsigned long n,contd; + char *ret = tcp_getline_work (stream,&n,&contd); + if (ret && contd) { /* got a line needing continuation? */ + STRINGLIST *stl = mail_newstringlist (); + STRINGLIST *stc = stl; + do { /* collect additional lines */ + stc->text.data = (unsigned char *) ret; + stc->text.size = n; + stc = stc->next = mail_newstringlist (); + ret = tcp_getline_work (stream,&n,&contd); + } while (ret && contd); + if (ret) { /* stash final part of line on list */ + stc->text.data = (unsigned char *) ret; + stc->text.size = n; + /* determine how large a buffer we need */ + for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size; + ret = fs_get (n + 1); /* copy parts into buffer */ + for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next) + memcpy (ret + n,stc->text.data,stc->text.size); + ret[n] = '\0'; + } + mail_free_stringlist (&stl);/* either way, done with list */ + } + return ret; +} + +/* TCP receive line or partial line + * Accepts: TCP stream + * pointer to return size + * pointer to return continuation flag + * Returns: text line string, size and continuation flag, or NIL if failure + */ + +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size, + long *contd) +{ + unsigned long n; + char *s,*ret,c,d; + *contd = NIL; /* assume no continuation */ + /* make sure have data */ + if (!tcp_getdata (stream)) return NIL; + for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) { + d = *stream->iptr++; /* slurp another character */ + if ((c == '\015') && (d == '\012')) { + ret = (char *) fs_get (n--); + memcpy (ret,s,*size = n); /* copy into a free storage string */ + ret[n] = '\0'; /* tie off string with null */ + return ret; + } + } + /* copy partial string from buffer */ + memcpy ((ret = (char *) fs_get (n)),s,*size = n); + /* get more data from the net */ + if (!tcp_getdata (stream)) fs_give ((void **) &ret); + /* special case of newline broken by buffer */ + else if ((c == '\015') && (*stream->iptr == '\012')) { + stream->iptr++; /* eat the line feed */ + stream->ictr--; + ret[*size = --n] = '\0'; /* tie off string with null */ + } + else *contd = LONGT; /* continuation needed */ + return ret; +} + +/* TCP/IP receive buffer + * Accepts: TCP/IP stream + * size in bytes + * buffer to read into + * Returns: T if success, NIL otherwise + */ + +long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer) +{ + unsigned long n; + char *bufptr = buffer; + while (size > 0) { /* until request satisfied */ + if (!tcp_getdata (stream)) return NIL; + n = min (size,stream->ictr);/* number of bytes to transfer */ + /* do the copy */ + memcpy (bufptr,stream->iptr,n); + bufptr += n; /* update pointer */ + stream->iptr +=n; + size -= n; /* update # of bytes to do */ + stream->ictr -=n; + } + bufptr[0] = '\0'; /* tie off string */ + return T; +} + + +/* TCP/IP receive data + * Accepts: TCP/IP stream + * Returns: T if success, NIL otherwise + */ + +long tcp_getdata (TCPSTREAM *stream) +{ + char tmp[MAILTMPLEN]; + int i,status; + /* Note: the doc says we need here dynamic descriptor, but we need static + * one... */ + struct dsc$descriptor BufDesc = {BUFLEN,DSC$K_DTYPE_T,DSC$K_CLASS_S, + stream->ibuf}; + static short iosb[4]; + if (stream->tcpsi < 0) return NIL; + while (stream->ictr < 1) { /* if nothing in the buffer */ + if (!((status = tcp_receive(&(stream->tcpsi), &BufDesc, iosb)) & 0x1)) { + sprintf (tmp,"Error reading from TcpIp/NETLIB, status=%d",status); + mm_log (tmp,ERROR); + return tcp_abort (stream); + } + if (iosb[1] > BUFLEN) i = BUFLEN; + else i = iosb[1]; + if (i < 1) return tcp_abort (stream); + stream->ictr = i; /* set new byte count */ + stream->iptr = stream->ibuf;/* point at TCP buffer */ + } + return T; +} + +/* TCP/IP send string as record + * Accepts: TCP/IP stream + * string pointer + * Returns: T if success else NIL + */ + +long tcp_soutr (TCPSTREAM *stream,char *string) +{ + return tcp_sout (stream,string,(unsigned long) strlen (string)); +} + + +/* TCP/IP send string + * Accepts: TCP/IP stream + * string pointer + * byte count + * Returns: T if success else NIL + */ + +long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size) +{ + int status; + struct dsc$descriptor_s BufDesc = {strlen(string),DSC$K_DTYPE_T, + DSC$K_CLASS_S,string }; + /* 2 = Do not add \r\n */ + return ((status = tcp_send (&(stream->tcpso),&BufDesc,2)) & 0x1) ? T : + tcp_abort (stream); +} + +/* TCP/IP close + * Accepts: TCP/IP stream + */ + +void tcp_close (TCPSTREAM *stream) +{ + tcp_abort (stream); /* nuke the stream */ + /* flush host names */ + fs_give ((void **) &stream->host); + fs_give ((void **) &stream->localhost); + fs_give ((void **) &stream); /* flush the stream */ +} + + +/* TCP/IP abort stream + * Accepts: TCP/IP stream + * Returns: NIL always + */ + +long tcp_abort (TCPSTREAM *stream) +{ + if (stream->tcpsi >= 0) { /* no-op if no socket */ + /* nuke the socket */ + tcp_disconnect (&(stream->tcpsi)); + stream->tcpsi = stream->tcpso = -1; + } + return NIL; +} + +/* TCP/IP get host name + * Accepts: TCP/IP stream + * Returns: host name for this stream + */ + +char *tcp_host (TCPSTREAM *stream) +{ + return stream->host; /* return host name */ +} + + +/* TCP/IP get remote host name + * Accepts: TCP/IP stream + * Returns: host name for this stream + */ + +char *tcp_remotehost (TCPSTREAM *stream) +{ + return stream->host; /* return host name */ +} + + +/* TCP/IP return port for this stream + * Accepts: TCP/IP stream + * Returns: port number for this stream + */ + +unsigned long tcp_port (TCPSTREAM *stream) +{ + return stream->port; /* return port number */ +} + + +/* TCP/IP get local host name + * Accepts: TCP/IP stream + * Returns: local host name + */ + +char *tcp_localhost (TCPSTREAM *stream) +{ + return stream->localhost; /* return local host name */ +} + +/* Return my local host name + * Returns: my local host name + */ + +char *mylocalhost () +{ + int status; + char tmp[MAILTMPLEN]; + if (!myLocalHost) { /* have local host yet? */ + /* receives local host name */ + struct dsc$descriptor LocalhostDesc = {0,DSC$K_DTYPE_T,DSC$K_CLASS_D,NULL}; + if (!((status = net_get_hostname (&LocalhostDesc)) & 0x1)) { + sprintf (tmp,"Can't get local hostname, status=%d",status); + mm_log (tmp,ERROR); + return "UNKNOWN"; + } + strncpy (tmp,LocalhostDesc.dsc$a_pointer,LocalhostDesc.dsc$w_length); + tmp[LocalhostDesc.dsc$w_length] = '\0'; + str$free1_dx (&LocalhostDesc); + myLocalHost = cpystr (tmp); + } + return myLocalHost; +} + +/* TCP/IP return canonical form of host name + * Accepts: host name + * Returns: canonical form of host name + */ + +char *tcp_canonical (char *name) +{ + return name; +} + + +/* TCP/IP get client host name (server calls only) + * Returns: client host name + */ + +char *tcp_clienthost () +{ + return "UNKNOWN"; +} diff --git a/imap/src/osdep/vms/tcp_vmsm.c b/imap/src/osdep/vms/tcp_vmsm.c new file mode 100644 index 00000000..bc9d9ca7 --- /dev/null +++ b/imap/src/osdep/vms/tcp_vmsm.c @@ -0,0 +1,479 @@ +/* ======================================================================== + * Copyright 1988-2008 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: VMS TCP/IP routines for Multinet + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 2 August 1994 + * Last Edited: 13 January 2008 + */ + + +static tcptimeout_t tmoh = NIL; /* TCP timeout handler routine */ +static long ttmo_read = 0; /* TCP timeouts, in seconds */ +static long ttmo_write = 0; + +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size, + long *contd); + +/* TCP/IP manipulate parameters + * Accepts: function code + * function-dependent value + * Returns: function-dependent return value + */ + +void *tcp_parameters (long function,void *value) +{ + void *ret = NIL; + switch ((int) function) { + case SET_TIMEOUT: + tmoh = (tcptimeout_t) value; + case GET_TIMEOUT: + ret = (void *) tmoh; + break; + case SET_READTIMEOUT: + ttmo_read = (long) value; + case GET_READTIMEOUT: + ret = (void *) ttmo_read; + break; + case SET_WRITETIMEOUT: + ttmo_write = (long) value; + case GET_WRITETIMEOUT: + ret = (void *) ttmo_write; + break; + } + return ret; +} + +/* TCP/IP open + * Accepts: host name + * contact service name + * contact port number + * Returns: TCP/IP stream if success else NIL + */ + +TCPSTREAM *tcp_open (char *host,char *service,unsigned long port) +{ + TCPSTREAM *stream = NIL; + int sock; + char *s; + struct sockaddr_in sin; + struct hostent *host_name; + char hostname[MAILTMPLEN]; + char tmp[MAILTMPLEN]; + struct protoent *pt = getprotobyname ("tcp"); + struct servent *sv = NIL; + port &= 0xffff; /* erase flags */ + if (service) { /* service specified? */ + if (*service == '*') { /* yes, special alt driver kludge? */ + sv = getservbyname (service + 1,"tcp"); + } + else sv = getservbyname (service,"tcp"); + } + /* user service name port */ + if (sv) port = ntohs (sin.sin_port = sv->s_port); + /* copy port number in network format */ + else sin.sin_port = htons (port); + /* The domain literal form is used (rather than simply the dotted decimal + as with other Unix programs) because it has to be a valid "host name" + in mailsystem terminology. */ + /* look like domain literal? */ + if (host[0] == '[' && host[(strlen (host))-1] == ']') { + strcpy (hostname,host+1); /* yes, copy number part */ + hostname[(strlen (hostname))-1] = '\0'; + if ((sin.sin_addr.s_addr = inet_addr (hostname)) != -1) { + sin.sin_family = AF_INET; /* family is always Internet */ + strcpy (hostname,host); /* hostname is user's argument */ + } + else { + sprintf (tmp,"Bad format domain-literal: %.80s",host); + mm_log (tmp,ERROR); + return NIL; + } + } + + else { /* lookup host name, note that brain-dead Unix + requires lowercase! */ + strcpy (hostname,host); /* in case host is in write-protected memory */ + if ((host_name = gethostbyname (lcase (hostname)))) { + /* copy address type */ + sin.sin_family = host_name->h_addrtype; + /* copy host name */ + strcpy (hostname,host_name->h_name); + /* copy host addresses */ + memcpy (&sin.sin_addr,host_name->h_addr,host_name->h_length); + } + else { + sprintf (tmp,"No such host as %.80s",host); + mm_log (tmp,ERROR); + return NIL; + } + } + /* get a TCP stream */ + if ((sock = socket (sin.sin_family,SOCK_STREAM,pt ? pt->p_proto : 0)) < 0) { + sprintf (tmp,"Unable to create TCP socket: %s",strerror (errno)); + mm_log (tmp,ERROR); + return NIL; + } +#if 0 + /* Maybe this test is necessary. It depends upon how VMS implements + * fd_set. UNIX-style fd_set needs it; Windows-style does not. + */ + else if (sock >= FD_SETSIZE) {/* unselectable sockets are useless */ + sprintf (tmp,"Unable to create selectable TCP socket (%d >= %d)", + sock,FD_SETSIZE); + close (sock); + return NIL; + } +#endif + /* open connection */ + if (connect (sock,(struct sockaddr *)&sin,sizeof (sin)) < 0) { + sprintf (tmp,"Can't connect to %.80s,%d: %s",hostname,port, + strerror (errno)); + mm_log (tmp,ERROR); + return NIL; + } + /* create TCP/IP stream */ + stream = (TCPSTREAM *) fs_get (sizeof (TCPSTREAM)); + /* copy official host name */ + stream->host = cpystr (hostname); + /* get local name */ + gethostname (tmp,MAILTMPLEN-1); + stream->localhost = cpystr ((host_name = gethostbyname (tmp)) ? + host_name->h_name : tmp); + /* init sockets */ + stream->port = port; /* port number */ + stream->tcpsi = stream->tcpso = sock; + stream->ictr = 0; /* init input counter */ + return stream; /* return success */ +} + +/* TCP/IP authenticated open + * Accepts: NETMBX specifier + * service name + * returned user name buffer + * Returns: TCP/IP stream if success else NIL + */ + +TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf) +{ + return NIL; +} + +/* TCP receive line + * Accepts: TCP stream + * Returns: text line string or NIL if failure + */ + +char *tcp_getline (TCPSTREAM *stream) +{ + unsigned long n,contd; + char *ret = tcp_getline_work (stream,&n,&contd); + if (ret && contd) { /* got a line needing continuation? */ + STRINGLIST *stl = mail_newstringlist (); + STRINGLIST *stc = stl; + do { /* collect additional lines */ + stc->text.data = (unsigned char *) ret; + stc->text.size = n; + stc = stc->next = mail_newstringlist (); + ret = tcp_getline_work (stream,&n,&contd); + } while (ret && contd); + if (ret) { /* stash final part of line on list */ + stc->text.data = (unsigned char *) ret; + stc->text.size = n; + /* determine how large a buffer we need */ + for (n = 0, stc = stl; stc; stc = stc->next) n += stc->text.size; + ret = fs_get (n + 1); /* copy parts into buffer */ + for (n = 0, stc = stl; stc; n += stc->text.size, stc = stc->next) + memcpy (ret + n,stc->text.data,stc->text.size); + ret[n] = '\0'; + } + mail_free_stringlist (&stl);/* either way, done with list */ + } + return ret; +} + +/* TCP receive line or partial line + * Accepts: TCP stream + * pointer to return size + * pointer to return continuation flag + * Returns: text line string, size and continuation flag, or NIL if failure + */ + +static char *tcp_getline_work (TCPSTREAM *stream,unsigned long *size, + long *contd) +{ + unsigned long n; + char *s,*ret,c,d; + *contd = NIL; /* assume no continuation */ + /* make sure have data */ + if (!tcp_getdata (stream)) return NIL; + for (s = stream->iptr, n = 0, c = '\0'; stream->ictr--; n++, c = d) { + d = *stream->iptr++; /* slurp another character */ + if ((c == '\015') && (d == '\012')) { + ret = (char *) fs_get (n--); + memcpy (ret,s,*size = n); /* copy into a free storage string */ + ret[n] = '\0'; /* tie off string with null */ + return ret; + } + } + /* copy partial string from buffer */ + memcpy ((ret = (char *) fs_get (n)),s,*size = n); + /* get more data from the net */ + if (!tcp_getdata (stream)) fs_give ((void **) &ret); + /* special case of newline broken by buffer */ + else if ((c == '\015') && (*stream->iptr == '\012')) { + stream->iptr++; /* eat the line feed */ + stream->ictr--; + ret[*size = --n] = '\0'; /* tie off string with null */ + } + else *contd = LONGT; /* continuation needed */ + return ret; +} + +/* TCP/IP receive buffer + * Accepts: TCP/IP stream + * size in bytes + * buffer to read into + * Returns: T if success, NIL otherwise + */ + +long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer) +{ + unsigned long n; + char *bufptr = buffer; + while (size > 0) { /* until request satisfied */ + if (!tcp_getdata (stream)) return NIL; + n = min (size,stream->ictr);/* number of bytes to transfer */ + /* do the copy */ + memcpy (bufptr,stream->iptr,n); + bufptr += n; /* update pointer */ + stream->iptr +=n; + size -= n; /* update # of bytes to do */ + stream->ictr -=n; + } + bufptr[0] = '\0'; /* tie off string */ + return T; +} + +/* TCP/IP receive data + * Accepts: TCP/IP stream + * Returns: T if success, NIL otherwise + */ + +long tcp_getdata (TCPSTREAM *stream) +{ + int i; + fd_set fds,efds; + struct timeval tmo; + time_t t = time (0); + if (stream->tcpsi < 0) return NIL; + while (stream->ictr < 1) { /* if nothing in the buffer */ + time_t tl = time (0); /* start of request */ + tmo.tv_sec = ttmo_read; /* read timeout */ + tmo.tv_usec = 0; + FD_ZERO (&fds); /* initialize selection vector */ + FD_ZERO (&efds); /* handle errors too */ + FD_SET (stream->tcpsi,&fds);/* set bit in selection vector */ + FD_SET(stream->tcpsi,&efds);/* set bit in error selection vector */ + errno = NIL; /* block and read */ + while (((i = select (getdtablesize (),&fds,0,&efds,ttmo_read ? &tmo:0))<0) + && (errno == EINTR)); + if (!i) { /* timeout? */ + time_t tc = time (0); + if (tmoh && ((*tmoh) (tc - t,tc - tl))) continue; + else return tcp_abort (stream); + } + else if (i < 0) return tcp_abort (stream); + while (((i = socket_read (stream->tcpsi,stream->ibuf,BUFLEN)) < 0) && + (errno == EINTR)); + if (i < 1) return tcp_abort (stream); + stream->iptr = stream->ibuf;/* point at TCP buffer */ + stream->ictr = i; /* set new byte count */ + } + return T; +} + +/* TCP/IP send string as record + * Accepts: TCP/IP stream + * string pointer + * Returns: T if success else NIL + */ + +long tcp_soutr (TCPSTREAM *stream,char *string) +{ + return tcp_sout (stream,string,(unsigned long) strlen (string)); +} + + +/* TCP/IP send string + * Accepts: TCP/IP stream + * string pointer + * byte count + * Returns: T if success else NIL + */ + +long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size) +{ + int i; + fd_set fds; + struct timeval tmo; + time_t t = time (0); + if (stream->tcpso < 0) return NIL; + while (size > 0) { /* until request satisfied */ + time_t tl = time (0); /* start of request */ + tmo.tv_sec = ttmo_write; /* write timeout */ + tmo.tv_usec = 0; + FD_ZERO (&fds); /* initialize selection vector */ + FD_SET (stream->tcpso,&fds);/* set bit in selection vector */ + errno = NIL; /* block and write */ + while (((i = select (getdtablesize (),0,&fds,0,ttmo_write ? &tmo : 0)) < 0) + && (errno == EINTR)); + if (!i) { /* timeout? */ + time_t tc = time (0); + if (tmoh && ((*tmoh) (tc - t,tc - tl))) continue; + else return tcp_abort (stream); + } + else if (i < 0) return tcp_abort (stream); + while (((i = socket_write (stream->tcpso,string,size)) < 0) && + (errno == EINTR)); + if (i < 0) return tcp_abort (stream); + size -= i; /* how much we sent */ + string += i; + } + return T; /* all done */ +} + +/* TCP/IP close + * Accepts: TCP/IP stream + */ + +void tcp_close (TCPSTREAM *stream) +{ + tcp_abort (stream); /* nuke the stream */ + /* flush host names */ + fs_give ((void **) &stream->host); + fs_give ((void **) &stream->localhost); + fs_give ((void **) &stream); /* flush the stream */ +} + + +/* TCP/IP abort stream + * Accepts: TCP/IP stream + * Returns: NIL always + */ + +long tcp_abort (TCPSTREAM *stream) +{ + int i; + if (stream->tcpsi >= 0) { /* no-op if no socket */ + /* nuke the socket */ + socket_close (stream->tcpsi); + if (stream->tcpsi != stream->tcpso) socket_close (stream->tcpso); + stream->tcpsi = stream->tcpso = -1; + } + return NIL; +} + +/* TCP/IP get host name + * Accepts: TCP/IP stream + * Returns: host name for this stream + */ + +char *tcp_host (TCPSTREAM *stream) +{ + return stream->host; /* return host name */ +} + + +/* TCP/IP get remote host name + * Accepts: TCP/IP stream + * Returns: host name for this stream + */ + +char *tcp_remotehost (TCPSTREAM *stream) +{ + return stream->host; /* return host name */ +} + + +/* TCP/IP return port for this stream + * Accepts: TCP/IP stream + * Returns: port number for this stream + */ + +unsigned long tcp_port (TCPSTREAM *stream) +{ + return stream->port; /* return port number */ +} + + +/* TCP/IP get local host name + * Accepts: TCP/IP stream + * Returns: local host name + */ + +char *tcp_localhost (TCPSTREAM *stream) +{ + return stream->localhost; /* return local host name */ +} + +/* Return my local host name + * Returns: my local host name + */ + +char *mylocalhost () +{ + char tmp[MAILTMPLEN]; + struct hostent *hn; + if (!myLocalHost) { /* have local host yet? */ + gethostname(tmp,MAILTMPLEN);/* get local host name */ + myLocalHost = cpystr ((hn = gethostbyname (tmp)) ? hn->h_name : tmp); + } + return myLocalHost; +} + + +/* TCP/IP return canonical form of host name + * Accepts: host name + * Returns: canonical form of host name + */ + +char *tcp_canonical (char *name) +{ + char host[MAILTMPLEN]; + struct hostent *he; + /* look like domain literal? */ + if (name[0] == '[' && name[strlen (name) - 1] == ']') return name; + /* note that Unix requires lowercase! */ + else return (he = gethostbyname (lcase (strcpy (host,name)))) ? + he->h_name : name; +} + + +/* TCP/IP get client host name (server calls only) + * Returns: client host name + */ + +char *tcp_clienthost () +{ + return "UNKNOWN"; +} diff --git a/imap/src/osdep/vms/tcp_vmsn.c b/imap/src/osdep/vms/tcp_vmsn.c new file mode 100644 index 00000000..4648e48d --- /dev/null +++ b/imap/src/osdep/vms/tcp_vmsn.c @@ -0,0 +1,222 @@ +/* ======================================================================== + * Copyright 1988-2006 University of Washington + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * + * ======================================================================== + */ + +/* + * Program: Dummy VMS TCP/IP routines for non-TCP/IP systems + * + * Author: Mark Crispin + * Networks and Distributed Computing + * Computing & Communications + * University of Washington + * Administration Building, AG-44 + * Seattle, WA 98195 + * Internet: MRC@CAC.Washington.EDU + * + * Date: 2 August 1994 + * Last Edited: 30 August 2006 + */ + +/* TCP/IP manipulate parameters + * Accepts: function code + * function-dependent value + * Returns: function-dependent return value + */ + +void *tcp_parameters (long function,void *value) +{ + return NIL; +} + + +/* TCP/IP open + * Accepts: host name + * contact service name + * contact port number + * Returns: TCP/IP stream if success else NIL + */ + +TCPSTREAM *tcp_open (char *host,char *service,unsigned long port) +{ + char tmp[MAILTMPLEN]; + port &= 0xffff; /* erase flags */ + if (port) sprintf (tmp,"Can't connect to %.80s,%d: no TCP",host,port); + else sprintf (tmp,"Can't connect to %.80s,%s: no TCP",host,service); + mm_log (tmp,ERROR); + return NIL; +} + + +/* TCP/IP authenticated open + * Accepts: NETMBX specifier + * service name + * returned user name buffer + * Returns: TCP/IP stream if success else NIL + */ + +TCPSTREAM *tcp_aopen (NETMBX *mb,char *service,char *usrbuf) +{ + return NIL; +} + +/* TCP/IP receive line + * Accepts: TCP/IP stream + * Returns: text line string or NIL if failure + */ + +char *tcp_getline (TCPSTREAM *stream) +{ + return NIL; +} + + +/* TCP/IP receive buffer + * Accepts: TCP/IP stream + * size in bytes + * buffer to read into + * Returns: T if success, NIL otherwise + */ + +long tcp_getbuffer (TCPSTREAM *stream,unsigned long size,char *buffer) +{ + return NIL; +} + + +/* TCP/IP receive data + * Accepts: TCP/IP stream + * Returns: T if success, NIL otherwise + */ + +long tcp_getdata (TCPSTREAM *stream) +{ + return NIL; +} + +/* TCP/IP send string as record + * Accepts: TCP/IP stream + * string pointer + * Returns: T if success else NIL + */ + +long tcp_soutr (TCPSTREAM *stream,char *string) +{ + return NIL; +} + + +/* TCP/IP send string + * Accepts: TCP/IP stream + * string pointer + * byte count + * Returns: T if success else NIL + */ + +long tcp_sout (TCPSTREAM *stream,char *string,unsigned long size) +{ + return NIL; +} + + +/* TCP/IP close + * Accepts: TCP/IP stream + */ + +void tcp_close (TCPSTREAM *stream) +{ +} + + +/* TCP/IP abort stream + * Accepts: TCP/IP stream + * Returns: NIL always + */ + +long tcp_abort (TCPSTREAM *stream) +{ + return NIL; +} + +/* TCP/IP get host name + * Accepts: TCP/IP stream + * Returns: host name for this stream + */ + +char *tcp_host (TCPSTREAM *stream) +{ + return NIL; +} + + +/* TCP/IP get remote host name + * Accepts: TCP/IP stream + * Returns: host name for this stream + */ + +char *tcp_remotehost (TCPSTREAM *stream) +{ + return NIL; +} + + +/* TCP/IP get local host name + * Accepts: TCP/IP stream + * Returns: local host name + */ + +char *tcp_localhost (TCPSTREAM *stream) +{ + return NIL; +} + + +/* TCP/IP return port for this stream + * Accepts: TCP/IP stream + * Returns: port number for this stream + */ + +unsigned long tcp_port (TCPSTREAM *stream) +{ + return 0xffffffff; /* return port number */ +} + + +/* Return my local host name + * Returns: my local host name + */ + +char *mylocalhost () +{ + /* have local host yet? */ + if (!myLocalHost) myLocalHost = cpystr (getenv ("SYS$NODE")); + return myLocalHost; +} + +/* TCP/IP return canonical form of host name + * Accepts: host name + * Returns: canonical form of host name + */ + +char *tcp_canonical (char *name) +{ + return name; +} + + +/* TCP/IP get client host name (server calls only) + * Returns: client host name + */ + +char *tcp_clienthost () +{ + return "UNKNOWN"; +} |