From: claudio@chsun.chuug.ch (Claudio Nieder)
Subject: ARexx script for sorting mailsfolders
Organization: CHUUG Swiss Unix Systems Users Group
X-Newsreader: Tin 1.1 PL3
Date: Fri, 4 Sep 1992 20:23:58 GMT

Hi,

this is an ARexx script I just hacked up. It sorts the mails in a mail folder
according to the date found in the Date: line, i.e. the date when the mail
was written. I thought I post it, in case somebody can use it.

#!/bin/sh
# This is a shell archive (produced by shar 3.49)
# To extract the files from this archive, save it to a file, remove
# everything above the "!/bin/sh" line above, and type "sh file_name".
#
# made 09/04/1992 20:23 UTC by claudio@chsun
# Source directory /user1/users/claudio
#
# existing files will NOT be overwritten unless -c is specified
#
# This shar contains:
# length  mode       name
# ------ ---------- ------------------------------------------
#   3924 -rw-r--r-- sortMail
#
# ============= sortMail ==============
if test -f 'sortMail' -a X"$1" != X"-c"; then
	echo 'x - skipping sortMail (File already exists)'
else
echo 'x - extracting sortMail (Text)'
sed 's/^X//' << 'SHAR_EOF' > 'sortMail' &&
/*
X Sort a mail file by date.
X
X Usage: sortMail <mailfolder>
X
X This ARexx script sorts the mails contained in the specified mail folder
X according to the date found in the mailheader "Date: " line. It will first
X rename the folder as "<mailfolder>.bak" and create a new file "<mailfolder>".
X
X Written and put into the public domain by Claudio Nieder 04-Sep-1992.
X
X Do with it whatever you want, use at own risk!
*/
X
/* Get the mail folder name. */
X parse arg name .
X
/*
X Rename a file. This will fail, if already a .bak file exists
*/
X oldname=name||'.bak'
X address command 'rename' name oldname
X if rc~=0 then do
X  say 'error renaming' name 'to' oldname ':' rc
X  exit(30)
X end
X
/*
X Open source and destination files.
*/
X if ~open(f,oldname,'r') then do
X  say 'error opening' oldname
X  exit(30)
X end
X
X if ~open(g,name,'w') then do
X  say 'error creating' name
X  exit(30)
X end
X
/*
X Initialize array for translation of month names.
*/
X month.JAN=01
X month.FEB=02
X month.MAR=03
X month.APR=04
X month.MAY=05
X month.JUN=06
X month.JUL=07
X month.AUG=08
X month.SEP=09
X month.OCT=10
X month.NOV=11
X month.DEC=12
X
/*
X Initialize all arrays needed.
*/
X starts.=0; dates.=0; index.=0
X
/*
X Read in the mail folder. This is actually the slowest part of this
X script, because the file is read in and analyzed line by line to
X find the starting position and the sender date of each mail. If you
X know how to speed up, do it and tell me please.
*/
X currentMail=0;
X do while ~eof(f)
X  startPos=seek(f,0,'c')               /* Remember current position */
X  line=readln(f)                       /* and then read a line.     */
X
X /*
X  Lines starting with "From " introduce a new mail. Remember the position
X  of the beginning of this line.
X */
X  if left(line,5)=="From " then do
X   currentMail=currentMail+1
X   call writech(stdout,'Read '||right(currentMail,5)||'0d'x)
X   starts.currentMail=startPos
X   index.currentMail=currentMail
X  end
X /*
X  When a the first line starting with "Date: " in the current mail is found,
X  the date is stored in yyyymmddHHMM format in the dates array.
X */
X  if (left(line,6)=="Date: ") & (dates.currentMail=0) then do
X   line=delstr(line,1,6)
X
X  /*
X   Figure out the date format. This code covers those formats I have
X   found in my mail folders.
X  */
X   parse var line wday ',' day mon yr time .
X   if day='' then parse var line day mon yr time .
X   if ~datatype(day,'w') then parse var line wday mon day time yr .
X   if yr<100 then yr=yr+1900
X
X   parse var time hr ':' min
X   min=left(min,2)
X   mon=upper(mon)
X   dates.currentMail=yr||month.mon||right(day,2,'0')||right(hr,2,'0')||right(min,2,'0')
X  end
X end
X say
X startPos=seek(f,0,'c')
X tmp=currentMail+1
X starts.tmp=startPos
X
/*
X Sort the dates array, and performs the same move in the index array.
X A simple insertion sort is used. Although not Quicksort, it isn't as
X bad. Although it is a O(n*n) sort, it becomes an O(n) sort if the folder
X is already sorted. The usual case is, that your folder is more or less
X ordered, with some local disorder, e.g. becaus the reply you send on
X a letter is put in the folder ahead of the original mail. In this
X cases insertion sort is pretty fast.
*/
X j=2
X do i=1 to currentMail-1
X  call writech(stdout,'Sort '||right(i,5)||'0d'x)
X  if dates.i>dates.j then do
X   tmpD=dates.j; tmpI=index.j
X   k=i; l=j
X   do until (dates.k<=tmpD)
X    dates.l=dates.k; index.l=index.k
X    k=k-1; l=l-1
X   end
X   dates.l=tmpD; index.l=tmpI
X  end
X  j=j+1
X end
X say 'Sorted '||right(currentMail,5)
X
/*
X Write out all mails to the new file.
*/
X do i=1 to currentMail
X  call writech(stdout,'Write '||right(i,5)||'0d'x)
X  start=index.i; stop=start+1
X  call seek(f,starts.start,'b')
X  mailLen=starts.stop-starts.start
X  do while mailLen>0
X   if mailLen>60000 then len=60000
X   else len=mailLen
X   line=readch(f,len)
X   call writech(g,line)
X   mailLen=mailLen-len
X  end
X end
X say
X
/*
X All done. Close the files.
*/
X call close(g)
X call close(f)
SHAR_EOF
chmod 0644 sortMail ||
echo 'restore of sortMail failed'
Wc_c="`wc -c < 'sortMail'`"
test 3924 -eq "$Wc_c" ||
	echo 'sortMail: original size 3924, current size' "$Wc_c"
fi
exit 0


--