Article 126871 of comp.os.vms: Newsgroups: comp.os.vms,comp.unix.admin Path: nntpd.lkg.dec.com!pa.dec.com!decuac.dec.com!haven.umd.edu!purdue!lerc.nasa.gov!magnus.acs.ohio-state.edu!math.ohio-state.edu!uwm.edu!fnnews.fnal.gov!usenet.eel.ufl.edu!news.mathworks.com!uunet!in2.uu.net!psinntp!psinntp!psinntp!psinntp!bristol.com!handel!dan From: dan@bristol.com (J. Daniel Smith) Subject: Re: Extract all messages from VMS mailbox to a unix sendmail file format? Sender: usenet@bristol.com (USENET News System) Organization: Bristol Technology Inc. References: <40bue9$kds@daffy.anet.uwrf.edu> Message-ID: Date: Thu, 10 Aug 1995 19:57:07 GMT Lines: 325 Xref: nntpd.lkg.dec.com comp.os.vms:126871 comp.unix.admin:37793 In <40bue9$kds@daffy.anet.uwrf.edu> MN01@taz.acc.uwrf.edu (Marlys A. Nelson) writes: >machine. I'm looking for a program or DCL procedure that can run on the >OpenVMS machine to dump all mail messages in the OpenVMS mail file (from all >folders) to a disk file which can then be moved to the unix machine and >[...] Here's a program I saved away a long time ago...its only 300+ lines, so I hope I don't upset anyone by posting source. 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 http://www.bristol.com/~dan Bristol Technology Inc. +1 203 438 6969, 438-5013 (FAX) Ridgefield, Connecticut (USA) {info,jobs}@bristol.com