Article 132445 of comp.os.vms:
Newsgroups: comp.os.vms
Path: nntpd.lkg.dec.com!depot.mro.dec.com!jrd.dec.com!news.dec-j!cs.titech!tokyonet.ad.jp!wincgw1!senri-nc!odins-suita!aist-nara!wnoc-kyo-news!kuis-news!kudpc!news.nca5.ad.jp!newssinet!daffy!uwvax!uwm.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!newsfeed.internetmci.com!uunet!in2.uu.net!psinntp!psinntp!psinntp!psinntp!bristol.com!handel!dan
From: dan@bristol.com (J. Daniel Smith)
Subject: Re: WANTED: tool to convert VMS to UNIX mail folders
Sender: usenet@bristol.com (USENET News System)
Organization: Bristol Technology Inc.
References: <kerr.61.0054593F@cass.decnet.ucsd.edu>
Message-ID: <dan.814140076@handel>
Date: Thu, 19 Oct 1995 22:01:16 GMT
Lines: 323

In <kerr.61.0054593F@cass.decnet.ucsd.edu> kerr@cass.decnet.ucsd.edu (Stephen S. Kerr) writes:
>Does anyone know of a tool that can convert a user's existing VMS mail folders 
>into folders that can be copied to a Unix system and handled by Unix mail 
>utilities (elm, Mail, etc.)?  All replies appreciated.

Here's a FORTRAN program that will do the job.

   Dan

$! ------------------ CUT HERE -----------------------
$ v='f$verify(f$trnlnm("SHARE_VERIFY"))'
$!
$! This archive created by VMS_SHARE Version 7.2-007  22-FEB-1990
$!   On 10-FEB-1992 14:04:20.74   By user ROB 
$!
$! This VMS_SHARE Written by:
$!    Andy Harper, Kings College London UK
$!
$! Acknowledgements to:
$!    James Gray       - Original VMS_SHARE
$!    Michael Bednarek - Original Concept and implementation
$!
$! TO UNPACK THIS SHARE FILE, CONCATENATE ALL PARTS IN ORDER
$! AND EXECUTE AS A COMMAND PROCEDURE  (  @name  )
$!
$! THE FOLLOWING FILE(S) WILL BE CREATED AFTER UNPACKING:
$!       1. V2U_MAIL.FOR;1
$!
$set="set"
$set symbol/scope=(nolocal,noglobal)
$f=f$parse("SHARE_TEMP","SYS$SCRATCH:.TMP_"+f$getjpi("","PID"))
$e="write sys$error  ""%UNPACK"", "
$w="write sys$output ""%UNPACK"", "
$ if f$trnlnm("SHARE_LOG") then $ w = "!"
$ ve=f$getsyi("version")
$ if ve-f$extract(0,1,ve) .ges. "4.4" then $ goto START
$ e "-E-OLDVER, Must run at least VMS 4.4"
$ v=f$verify(v)
$ exit 44
$UNPACK: SUBROUTINE ! P1=filename, P2=checksum
$ if f$search(P1) .eqs. "" then $ goto file_absent
$ e "-W-EXISTS, File ''P1' exists. Skipped."
$ delete 'f'*
$ exit
$file_absent:
$ if f$parse(P1) .nes. "" then $ goto dirok
$ dn=f$parse(P1,,,"DIRECTORY")
$ w "-I-CREDIR, Creating directory ''dn'."
$ create/dir 'dn'
$ if $status then $ goto dirok
$ e "-E-CREDIRFAIL, Unable to create ''dn'. File skipped."
$ delete 'f'*
$ exit
$dirok:
$ w "-I-PROCESS, Processing file ''P1'."
$ if .not. f$verify() then $ define/user sys$output nl:
$ EDIT/TPU/NOSEC/NODIS/COM=SYS$INPUT 'f'/OUT='P1'
PROCEDURE Unpacker ON_ERROR ENDON_ERROR;SET(FACILITY_NAME,"UNPACK");SET(
SUCCESS,OFF);SET(INFORMATIONAL,OFF);f:=GET_INFO(COMMAND_LINE,"file_name");b:=
CREATE_BUFFER(f,f);p:=SPAN(" ")@r&LINE_END;POSITION(BEGINNING_OF(b));
LOOP EXITIF SEARCH(p,FORWARD)=0;POSITION(r);ERASE(r);ENDLOOP;POSITION(
BEGINNING_OF(b));g:=0;LOOP EXITIF MARK(NONE)=END_OF(b);x:=ERASE_CHARACTER(1);
IF g=0 THEN IF x="X" THEN MOVE_VERTICAL(1);ENDIF;IF x="V" THEN APPEND_LINE;
MOVE_HORIZONTAL(-CURRENT_OFFSET);MOVE_VERTICAL(1);ENDIF;IF x="+" THEN g:=1;
ERASE_LINE;ENDIF;ELSE IF x="-" THEN IF INDEX(CURRENT_LINE,"+-+-+-+-+-+-+-+")=
1 THEN g:=0;ENDIF;ENDIF;ERASE_LINE;ENDIF;ENDLOOP;t:="0123456789ABCDEF";
POSITION(BEGINNING_OF(b));LOOP r:=SEARCH("`",FORWARD);EXITIF r=0;POSITION(r);
ERASE(r);x1:=INDEX(t,ERASE_CHARACTER(1))-1;x2:=INDEX(t,ERASE_CHARACTER(1))-1;
COPY_TEXT(ASCII(16*x1+x2));ENDLOOP;WRITE_FILE(b,GET_INFO(COMMAND_LINE,
"output_file"));ENDPROCEDURE;Unpacker;QUIT;
$ delete/nolog 'f'*
$ CHECKSUM 'P1'
$ IF CHECKSUM$CHECKSUM .eqs. P2 THEN $ EXIT
$ e "-E-CHKSMFAIL, Checksum of ''P1' failed."
$ ENDSUBROUTINE
$START:
$ create 'f'
X  `09program v2u_mail
X
Xc`09convert mail files from VMS to UNIX
X
Xc`09V2U_MAIL, a hack by Rob Riepel (rob@ssvax1.ssd.loral.com)
Xc
Xc`09  This program was whipped up to convert my VMSmail to Unix.  I
Xc`09  hope it works for you too.  If you make improvements, please
Xc`09  let me know.  If you're seriously into hackery, use the callable
Xc`09  mail interface to parse through the VMSmail messages, and make
Xc`09  sure the Unix mail headers conform to the relevant RFCs.
X
Xc`09INSTRUCTIONS
Xc`09============
Xc
Xc`09v2u_mail will will read standard VMSmail files and convert them
Xc`09to Unix file files.  To use the program, first compile and link
Xc`09it.
Xc
Xc`09   $ FOR V2U_MAIL
Xc`09   $ LIN V2U_MAIL
Xc
Xc`09Next, assign the logical MAIL_DIR to point to the directory where
Xc`09all your VMSmail is stashed.
Xc
Xc`09   $ ASSIGN SYS$LOGIN_DEVICE:`5BMY_HOME.MAIL`5D MAIL_DIR
Xc
Xc`09Move to the directory where you want the Unix mail folders, and
Xc`09run V2U_MAIL.
Xc
Xc`09   $ SET DEFAULT `5BMY_HOME.UNIX_MAIL`5D
Xc`09   $ RUN `5BMY_HOME.V2U_MAIL`5DV2U_MAIL
Xc
Xc`09A Unix mail file will be created for each folder in your VMSmail.
X
Xc
Xc`09%Id: v2u_mail.for_v 1.2 92/02/10 13:55:22 rob Exp %
Xc
Xc`09%Log:`09v2u_mail.for_v %
Xc`09Revision 1.2  92/02/10  13:55:22  rob
Xc`09Increased buffer sizes to handle long lines, from's, subjects, and cc's.
Xc`09Added comments, including instructions for use.
Xc`09Added RCS keywords.
Xc`09
X
X`09implicit integer*4 (a-z)
X
X`09common`09/count/`09mcount
X
X`09character     `09cbuf*2048
X`09integer*4`09ibuf(2048), mcount /0/
X        integer*2 `09rlen
X`09equivalence`09(cbuf,ibuf)
X
Xc`09open the mail file, twice
X
X `09open(`09unit=10,
X     &`09`09file='mail_dir:mail.mai',
X     &`09`09access='keyed',
X     &`09`09key=(1:8:integer,10:48:character),
X     &`09`09blocksize=2048,
X     &`09`09organization='indexed',
X     &`09`09recordtype='variable',
X     &`09`09form='formatted',
X     &         `09shared,
X     &`09`09readonly,
X     &`09`09status='old')
X
X `09open(`09unit=11,
X     &`09`09file='mail_dir:mail.mai',
X     &`09`09access='keyed',
X     &`09`09key=(1:8:integer,10:48:character),
X     &`09`09blocksize=2048,
X     &`09`09organization='indexed',
X     &`09`09recordtype='variable',
X     &`09`09form='formatted',
X     &         `09shared,
X     &`09`09readonly,
X     &`09`09status='old')
X
Xc`09read and process the first record
X
X`09read(10,'(Q,A2048)',keyge='A',keyid=1)rlen,cbuf
X`09call process_record(ibuf,ibuf,cbuf,rlen)
X
Xc`09process the remaining records
X`09
X`09do while (1 .eq. 1)
X`09    read(10,'(Q,A2048)',end=100)rlen,cbuf
X`09    call process_record(ibuf,ibuf,cbuf,rlen)
X  `09end do
X
Xc`09we're done, write out the last folder's message count and leave
X
X  100`09continue
X`09if (mcount .gt. 0) write(6,10)null,mcount
X   10`09format(a1,i3,' messages')
X`09close(10)
X`09call exit
X`09end
X
X`09subroutine process_record(bbuf,ibuf,cbuf,rlen)
X
Xc`09this is where all the work gets done
X
X`09implicit integer*4 (a-z)
X
X`09common`09/count/`09mcount
X
X`09byte`09     bytes(2), bbuf(2048)
X`09integer*2    dlen
X`09integer*4    ibuf(2048)
X`09character    cbuf*2048, folder*39, null*1, line*2048, name*80
X`09character    from*255, to*255, cc*255, subject*255, date*25
X`09character*3  aday(7) /'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat','Sun'/
X`09character    ctime*80
X`09logical`09     iam
X
X`09equivalence  (dlen,bytes)
X
X`09save folder, flen
X
X`09null = char(0)
X
Xc`09open a new UNIX mail file for each VMS mail folder
X
X`09len = index(cbuf(10:),null)
X`09if (folder(1:flen) .ne. cbuf(10:10+len-1)) then
X`09    close(20)
X`09    flen = len
X`09    folder(1:len) = cbuf(10:10+len-1)
X`09    folder(flen+1:) = '.'
X`09    if (mcount .gt. 0) write(6,10)null,mcount
X   10`09    format(a1,i3,' messages')
X`09    mcount = 0
X`09    write(6,20)folder(1:flen)
X   20`09    format(1x,'Processing folder ',a,t35,'...',$)
X`09    open(20,name=folder(1:flen+1),status='new',recl=2048,
X     &`09`09    carriagecontrol='list')
X`09endif
X
Xc`09count the messages
X
X`09mcount = mcount + 1
X
Xc`09parse out the from, to, subject, etc...
X
X`09base = 91
X`09bytes(1) = bbuf(base)
X`09bytes(2) = bbuf(base+1)
X`09from_len = dlen
X`09from = cbuf(base+2:base+from_len+1)
X`09from_len_short = index(from,' ') - 1
X
X`09base = base + dlen + 4
X`09bytes(1) = bbuf(base)
X`09bytes(2) = bbuf(base+1)
X`09to_len = dlen
X`09to = cbuf(base+2:base+to_len+1)
X
X`09base = base + dlen + 4
X`09bytes(1) = bbuf(base)
X`09bytes(2) = bbuf(base+1)
X`09cc_len = dlen
X`09cc = cbuf(base+2:base+cc_len+1)
X
X`09base = base + dlen + 4
X`09bytes(1) = bbuf(base)
X`09bytes(2) = bbuf(base+1)
X`09subject_len = dlen
X`09subject = cbuf(base+2:base+subject_len+1)
X
Xc`09do the time thing
X
X`09call lib$day_of_week(ibuf(1),day)
X`09call lib$sys_asctim(time_len,ctime,ibuf(1),)
X`09ctime(5:5) = char(ichar(ctime(5:5)) + 32)
X`09ctime(6:6) = char(ichar(ctime(6:6)) + 32)
X`09write(date,30)aday(day),ctime(4:6),ctime(1:2),ctime(13:20),ctime(8:11)
X   30`09format(5(1x,a))
X
Xc`09write out the mail header
X
X`09write(20,60)from(1:from_len_short),date,
X     &`09`09    from(1:from_len_short),date,
X     &`09`09    to(1:to_len)
X`09if (cc_len .gt. 0)write(20,62)cc(1:cc_len)
X`09write(20,64)from(1:from_len),subject(1:subject_len)
X
X   60`09format(    'From ',2a,/,
X     &             'Return-path: <',a,'>'/,
X     &             'Date: ',a,/
X     &             'To: ',a)
X   62`09format(    'Cc: ',a)
X   64`09format(    'From: ',a,/,
X     &             'Subject: ',a,/,
X     &             'Status: RO',/)
X
Xc`09attempt to read the body as a mail file record
Xc`09and write out the records to the new file
X`09
X`09read(11,'(Q,A2048)',keyid=0,key=ibuf(15),err=80)rlen,cbuf
X`09base = 49
X
X`09do while (base .lt. rlen)
X`09    bytes(1) = bbuf(base)
X`09    bytes(2) = bbuf(base+1)
Xd`09    write(6,*)dlen
Xc`09    write(20,'(1x,A)')cbuf(base+2:base+dlen+1)
X`09    write(20,'(A)')cbuf(base+2:base+dlen+1)
X`09    base = base + dlen + 2
X`09end do
X`09write(20,'(/)')
X`09return
X
Xc`09body is in a separte file, open it and copy it to the new
Xc`09mail file
X
X   80`09continue
X`09write(name,100)ibuf(15),ibuf(16)
X  100`09format('mail_dir:mail$',2Z8.8,'.mai')
X`09inquire(file=name,exist=iam)
X`09if(.not.iam)write(name,100)ibuf(16),ibuf(15)
Xd`09write(6,110)name
Xd 110`09format(1x,'>',a,'<')
X`09open(12,name=name,status='old',readonly)
X  120`09continue
X`09    read(12,'(Q,A)',end=140)llen,line
Xd`09    write(6,*)llen
Xc`09    write(20,'(1x,A)')line(1:llen)
X`09    write(20,'(A)')line(1:llen)
X`09go to 120
X
X  140`09continue
X`09write(20,'(/)')
X`09close(12)
X`09return
X`09end
$ CALL UNPACK V2U_MAIL.FOR;1 1897075167
$ v=f$verify(v)
$ EXIT
-- 
--------------------- message is author's opinion only --------------------
J. Daniel Smith <DanS@bristol.com>              http://www.bristol.com/~dan
Bristol Technology Inc.	                    +1 203 438 6969, 438-5013 (FAX)
Ridgefield, Connecticut (USA)                       {info,jobs}@bristol.com


