home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / pmmtomr2.zip / PMMtoMR2.CMD < prev    next >
OS/2 REXX Batch file  |  1995-12-29  |  61KB  |  935 lines

  1. /***********************************************************************/
  2. /*                                                                     */
  3. /* (c) Copyright DynaComp Solutions 1995 - All rights reserved.        */
  4. /*                                                                     */
  5. /***********************************************************************/
  6. /*                                                                     */
  7. /* Written and maintained by David J. Martin (djmartin@nando.net).     */
  8. /*                                                                     */
  9. /***********************************************************************/
  10. version = '1.3 29 Dec 95'  /* PMMTOMR2.CMD                             */
  11. /***********************************************************************/
  12. /*                                                                     */
  13. /* Converts PMMail address and group information to MR2Ice format.     */
  14. /* Will also create folders in MR2Ice for all of your existing PMMail  */
  15. /* folders and move or copy all of your existing mail into MR2Ice.     */
  16. /*                                                                     */
  17. /***********************************************************************/
  18. /*                                                                     */
  19. /* Change History:                                                     */
  20. /*                                                                     */
  21. /*  Change                                                             */
  22. /*   Date   Int Ver Description                                        */
  23. /* -------- --- --- -------------------------------------------------- */
  24. /* 12/24/95 DJM 1.0 First release.                                     */
  25. /* 12/26/95 DJM 1.1 Added code to change the file extension of mail    */
  26. /*                  depending on whether or not a piece of mail was    */
  27. /*                  sent or received.                                  */
  28. /* 12/27/95 DJM 1.2 Fixed bug that would cause a failure if only 1     */
  29. /*                  drive is installed.  Left a trailing blank in the  */
  30. /*                  list of drives after removing the colon(s).        */
  31. /* 12/29/95 DJM 1.3 Fixed a bug in the PMMailNicks subroutine that     */
  32. /*                  could cause problems elsewhere in the code.  I had */
  33. /*                  forgotten to close each of the PMMail address      */
  34. /*                  books as I processed them.  Same close problem     */
  35. /*                  when processing PMMail group files.                */
  36. /*                                                                     */
  37. /***********************************************************************/
  38. trace 'OFF'                       /* we don't want or need any tracing */
  39. '@ECHO OFF'                       /* suppress echoing of host commands */
  40. call RxFuncAdd 'SysCls'            , 'RexxUtil' , 'SysCls'
  41. call RxFuncAdd 'SysCurPos'         , 'RexxUtil' , 'SysCurPos'
  42. call RxFuncAdd 'SysCurState'       , 'RexxUtil' , 'SysCurState'
  43. call RxFuncAdd 'SysDriveInfo'      , 'RexxUtil' , 'SysDriveInfo'
  44. call RxFuncAdd 'SysDriveMap'       , 'RexxUtil' , 'SysDriveMap'
  45. call RxFuncAdd 'SysFileDelete'     , 'RexxUtil' , 'SysFileDelete'
  46. call RxFuncAdd 'SysFileTree'       , 'RexxUtil' , 'SysFileTree'
  47. call RxFuncAdd 'SysGetKey'         , 'RexxUtil' , 'SysGetKey'
  48. call RxFuncAdd 'SysMkDir'          , 'RexxUtil' , 'SysMkDir'
  49. call RxFuncAdd 'SysPutEA'          , 'RexxUtil' , 'SysPutEA'
  50. call RxFuncAdd 'SysRmDir'          , 'RexxUtil' , 'SysRmDir'
  51. call RxFuncAdd 'SysTextScreenRead' , 'RexxUtil' , 'SysTextScreenRead'
  52. parse source . . ourname .           /* find out our name to use later */
  53. lpos = lastpos('\',ourname)                 /* find the last backslash */
  54. ourname = substr(ourname,lpos + 1)                    /* just our name */
  55. parse var ourname ourname '.' .            /* drop the cmd portion too */
  56. logfile = ourname || '.log'                 /* log file for any errors */
  57. cleanup = 0          /* assume we won't be moving mail and cleaning up */
  58. eol     = x2c('0D0A')                          /* end of line sequence */
  59. hex01   = '01'x                         /* constant to delimit entries */
  60. hexDE   = 'DE'x                         /* constant to delimit entries */
  61. keys    = '0D 43 4D 51 63 6D 71'     /* keys for Move/Copy/Quit prompt */
  62. title   = 'PMMail to MR2Ice Migration Aid'             /* screen title */
  63. call SysFileDelete logfile              /* erase any leftover log file */
  64. call AnsiColor                        /* set things up for using color */
  65. drives = SysDriveMap(,'LOCAL')                 /* list of local drives */
  66. drives = translate(drives,'',':')                     /* remove colons */
  67. /***********************************************************************/
  68. /* Find out where PMMail has been installed.                           */
  69. /***********************************************************************/
  70. if words(drives) = 1                             /* only 1 local drive */
  71.   then do
  72.          pmmdrive = strip(drives)           /* move into real variable */
  73.          signal no_pmm_drive     /* don't ask the user where PMMail is */
  74.        end                                     /* if words(drives) = 1 */
  75. call SysCurState 'ON'                            /* turn on the cursor */
  76. call SysCls                                        /* clear the screen */
  77. call build_box 5,7,20,36
  78. call show_title 3 7 63
  79. call SysCurPos 6,22
  80. call charout , pfcolor || 'What drive is PMMail installed on?' || ,
  81.                s.normvid
  82. call SysCurPos 11,22
  83. call charout , pfcolor || 'Enter QUIT if you want to stop now' || ,
  84.                s.normvid
  85. pmm_drive_again:           /* label for branch if the entry is invalid */
  86. call SysCurPos 9,28
  87. call charout , s.blink || s.revvid || 'PMMail Drive ==> ____'
  88. call SysCurPos 9,45
  89. pmmdrive = translate(strip(translate(linein(),'',':')))
  90. call charout , s.normvid
  91. select                        /* decide what to do based on the entry */
  92.   when pmmdrive = 'QUIT'                    /* user wants to stop now */
  93.       then call stopping 'Stopping this program at your request.  Bye' ,
  94.                          'for now...'
  95.   when wordpos(pmmdrive,drives) == 0             /* not a valid drive */
  96.       then do
  97.              out = s.blink || s.revvid || 'Invalid choice.  Must be'
  98.              do lp = 1 to words(drives)      /* add each drive letter */
  99.                out = out word(drives,lp) || ','   /* add drive letter */
  100.              end                     /* of do lp = 1 to words(drives) */
  101.              out = out 'or Quit.  Please try again.' || s.normvid
  102.              call SysCurPos 13,0
  103.              call charout , center(out,92)            /* show message */
  104.              signal drive_again  /* go back and give them another try */
  105.            end              /* of when wordpos(mr2idrive,drives) == 0 */
  106.   otherwise nop         /* what was entered is at least a valid drive */
  107. end                              /* of select based on the entry made */
  108. no_pmm_drive:         /* we'll come here if there's only 1 hard drive */
  109. call SysFileTree pmmdrive || ':\PMMAIL.INI','temp','FSO' /* chk 4 ini */
  110. select    /* decide how to proceed based on what we found (or didn't) */
  111.   when temp.0 == 0               /* couldn't find the MR2Ice ini file */
  112.       then do
  113.              msg = 'Could not find PMMAIL.INI.  Please make sure that' ,
  114.                    'you entered the correct drive letter and that you' ,
  115.                    'have installed and configured PMMAIL before using' ,
  116.                    'the' ourname 'command.'
  117.              call Logger logfile,msg,,1
  118.              call stopping msg
  119.            end                                 /* of when temp.0 == 0 */
  120.   when temp.0 > 1
  121.       then do
  122.              out = ''                     /* clear variable for output */
  123.              do lp = 1 to temp.0                /* go through each hit */
  124.                last1 = lastpos('\',temp.lp)     /* find last backslash */
  125.                out = out substr(temp.lp,3,last1 - 3)  /* just the path */
  126.              end                             /* of do lp = 1 to temp.0 */
  127.              msg = 'There appears to be multiple copies of PMMail'      ,
  128.                    'installed on the' pmmdrive 'drive.  Before using'   ,
  129.                     ourname 'please rename PMMAIL.INI in the PMMAIL'    ,
  130.                    'directory that you do NOT want migrated to MR2Ice. ',
  131.                    'I found a PMMAIL.INI file in the following'         ,
  132.                    'directories:' out
  133.              call Logger logfile,msg,,1
  134.              call stopping msg
  135.            end                                   /* of when temp.0 > 1 */
  136.   otherwise pmmroot = temp.1         /* looks OK so stash the location */
  137. end                         /* of select based on results of searching */
  138. pmmroot = substr(pmmroot,1,lastpos('\',pmmroot))     /* directory info */
  139. /***********************************************************************/
  140. /* Tell user to hang on while we gather some data for later use.       */
  141. /***********************************************************************/
  142. call SysCurState 'OFF'                          /* turn off the cursor */
  143. call charout , s.normvid  /* make sure video is normal before we go on */
  144. call SysCls                                        /* clear the screen */
  145. call build_box 9,13,7,64
  146. call show_title 3 7 64
  147. call SysCurPos 10,9
  148. call charout , pfcolor || 'Please stand by while I determine your' ,
  149.                'PMMail folder names as ' || s.normvid
  150. call SysCurPos 11,9
  151. call charout , pfcolor || 'well as how much disk space the mail you' ,
  152.                'currently have stored' || s.normvid
  153. call SysCurPos 12,9
  154. call charout , pfcolor || 'in PMMail occupies.  This make take a' ,
  155.                             'minute or 2.            ' || s.normvid
  156. call SysCurPos 12,57
  157. call PMMailFolders    /* gather PMMail folder info and mail byte count */
  158. /***********************************************************************/
  159. /* When we come back from PMMailFolders the stem PMMFOLDERS will       */
  160. /* contain entries for each PMMail folder name that exists.  The       */
  161. /* variable PMMBYTES will contain the number of bytes of mail that is  */
  162. /* currently stored in ALL of the PMMail folders.  The stem            */
  163. /* PMMDIRNAMES will have the directory name of each PMMail folders.    */
  164. /***********************************************************************/
  165. /* While we've got a message displayed get PMMail nickname details.    */
  166. /***********************************************************************/
  167. call PMMailNicks                     /* gather PMMail nickname details */
  168. /***********************************************************************/
  169. /* When we come back from PMMailNicks the stem PMMNICKS will contain   */
  170. /* all of the information in the PMMail address and group books.       */
  171. /***********************************************************************/
  172. /* Now find out where MR2Ice has been installed.                       */
  173. /***********************************************************************/
  174. if words(drives) = 1                             /* only 1 local drive */
  175.   then do
  176.          mr2idrive = strip(drives)          /* move into real variable */
  177.          signal no_mr2i_drive    /* don't ask the user where MR2Ice is */
  178.        end                                     /* if words(drives) = 1 */
  179. call SysCurState 'ON'                            /* turn on the cursor */
  180. call SysCls                                        /* clear the screen */
  181. call build_box 5,7,20,36
  182. call show_title 3 7 63
  183. call SysCurPos 6,22
  184. call charout , pfcolor || 'What drive is MR2Ice installed on?' || ,
  185.                s.normvid
  186. call SysCurPos 11,22
  187. call charout , pfcolor || 'Enter QUIT if you want to stop now' || ,
  188.                s.normvid
  189. mr2i_drive_again:         /* label for branch if the entry is invalid */
  190. call SysCurPos 9,28
  191. call charout , s.blink || s.revvid || 'MR2Ice Drive ==> ____'
  192. call SysCurPos 9,45
  193. mr2idrive = translate(strip(translate(linein(),'',':')))
  194. call charout , s.normvid
  195. select                        /* decide what to do based on the entry */
  196.   when mr2idrive = 'QUIT'                   /* user wants to stop now */
  197.       then call stopping 'Stopping this program at your request.  Bye' ,
  198.                          'for now...'
  199.   when wordpos(mr2idrive,drives) == 0            /* not a valid drive */
  200.       then do
  201.              out = s.blink || s.revvid || 'Invalid choice.  Must be'
  202.              do lp = 1 to words(drives)      /* add each drive letter */
  203.                out = out word(drives,lp) || ','   /* add drive letter */
  204.              end                     /* of do lp = 1 to words(drives) */
  205.              out = out 'or Quit.  Please try again.' || s.normvid
  206.              call SysCurPos 13,0
  207.              call charout , center(out,92)            /* show message */
  208.              signal mr2i_drive_again /* go back & give em another try */
  209.            end              /* of when wordpos(mr2idrive,drives) == 0 */
  210.   otherwise nop         /* what was entered is at least a valid drive */
  211. end                              /* of select based on the entry made */
  212. no_mr2i_drive:        /* we'll come here if there's only 1 hard drive */
  213. call SysFileTree mr2idrive || ':\MR2IC.INI','temp','FSO' /* chk 4 ini */
  214. select    /* decide how to proceed based on what we found (or didn't) */
  215.   when temp.0 == 0               /* couldn't find the MR2Ice ini file */
  216.       then do
  217.              msg = 'Could not find MR2IC.INI.  Please make sure that'  ,
  218.                    'you entered the correct drive letter and that you' ,
  219.                    'have installed and configured MR2Ice before using' ,
  220.                    'the' ourname 'command.  To install and configure'  ,
  221.                    'MR2Ice just run MR2I once after unzipping the code.'
  222.              call Logger logfile,msg,,1
  223.              call stopping msg
  224.            end                                 /* of when temp.0 == 0 */
  225.   when temp.0 > 1
  226.       then do
  227.              out = ''                     /* clear variable for output */
  228.              do lp = 1 to temp.0                /* go through each hit */
  229.                last1 = lastpos('\',temp.lp)
  230.                out = out substr(temp.lp,3,last1 - 3)
  231.              end                             /* of do lp = 1 to temp.0 */
  232.              msg = 'There appears to be multiple copies of MR2Ice'     ,
  233.                    'installed on the' mr2idrive 'drive.  Before using' ,
  234.                     ourname 'please rename MR2IC.INI in the MR2Ice'    ,
  235.                    'directory that you do NOT want PMMail information' ,
  236.                    'migrated to.  I found a MR2IC.INI file in the'     ,
  237.                    'following directories:' out
  238.              call Logger logfile,msg,,1
  239.              call stopping msg
  240.            end                                   /* of when temp.0 > 1 */
  241.   otherwise mr2loc = temp.1          /* looks OK so stash the location */
  242. end                         /* of select based on results of searching */
  243. mr2loc = substr(mr2loc,1,lastpos('\',mr2loc))   /* just directory info */
  244. /***********************************************************************/
  245. /* Make sure there's enough room on target drive to copy/move stuff.   */
  246. /***********************************************************************/
  247. mr2driveleft = SysDriveInfo(mr2idrive)         /* get info about drive */
  248. parse var mr2driveleft . mr2driveleft .        /* just need bytes free */
  249. if mr2driveleft - pmmbytes < 5000000  /* leave at least 5 meg on drive */
  250.   then do
  251.          msg = 'There is not enough room on the' mr2idrive 'drive to'   ,
  252.                'move or copy the mail you already have filed in'        ,
  253.                'PMMail.  You may make more space available on the'      ,
  254.                 mr2idrive 'drive or install MR2Ice on a disk with more' ,
  255.                'space then run' ourname 'again.'
  256.          call Logger logfile,msg,,1
  257.          call stopping msg
  258.        end                  /* of if mr2driveleft - pmmbytes < 5000000 */
  259. /***********************************************************************/
  260. /* Set up full file paths to everything we'll need.                    */
  261. /***********************************************************************/
  262. mr2iadr  = mr2loc || 'MR2I.ADR'                   /* address book file */
  263. mr2igrp  = mr2loc || 'MR2I.GRP'                          /* group file */
  264. mr2inew  = mr2loc || 'MAIL\'          /* new directories go under here */
  265. mr2indx  = mr2loc || 'MAIL\FOLDERS.NDX'         /* MR2Ice folder index */
  266. /***********************************************************************/
  267. /* Now find out if we'll be moving notes or copying them.              */
  268. /***********************************************************************/
  269. call SysCurState 'ON'                            /* turn on the cursor */
  270. call SysCls                                  /* clear the screen again */
  271. call build_box 9,12,18,44
  272. call show_title 3 7 63
  273. call SysCurPos 10,20
  274. call charout , pfcolor || 'Do you want to '    || s.blink || s.revvid || ,
  275.                    'C' || pfcolor || 'opy or ' || s.blink || s.revvid || ,
  276.                    'M' || pfcolor || 'ove your mail from' || s.normvid
  277. call SysCurPos 11,20
  278. call charout , pfcolor || 'PMMail folders into MR2Ice folders?      ' || ,
  279.                           ' ' || s.normvid
  280. call SysCurPos 14,32
  281. call charout , s.blink || s.revvid || 'Your Choice ==> C'  || s.normvid
  282. call SysCurPos 16,24
  283. call charout , pfcolor || 'Enter a' s.blink || s.revvid || 'Q' || ,
  284.                pfcolor    'if you want to stop now.' || s.normvid
  285. call charout , s.blink || s.revvid
  286. key = translate(Get_key(14 48))                  /* go get a keystroke */
  287. call charout , s.normvid                            /* reset the color */
  288. select                                /* decide what we're going to do */
  289.   when key = 'Q'
  290.       then call stopping 'Stopping this program at your request.  Bye' ,
  291.                          'for now...'
  292.   when key = 'C'
  293.       then do
  294.              dowhat  = 'COPY'
  295.              dowhate = 'Copying'
  296.            end
  297.   when key = 'M'
  298.       then do
  299.              dowhat  = 'MOVE'
  300.              dowhate = 'Moving'
  301.              call ask_about_cleanup
  302.            end
  303.   otherwise nop            /* should never hit here because of Get_Key */
  304. end                                                       /* of select */
  305. call SysCurState 'OFF'                    /* make the cursor disappear */
  306. /***********************************************************************/
  307. /* Finally;  Get things going by creating the MR2Ice nickname entries. */
  308. /* We need to stuff whatever we've already found into the nickinf.     */
  309. /* stem for the routine we'll call to write the stuff for MR2Ice.      */
  310. /***********************************************************************/
  311. do lp = 1 to pmmnicks.0 /* go through each PMMail nickname/group entry */
  312.   nickinf.lp = pmmnicks.lp                /* copy over to correct stem */
  313. end                                      /* of do lp = 1 to pmmnicks.0 */
  314. nickinf.0 = pmmnicks.0                /* copy the total count over too */
  315. call SysCls
  316. call build_box 8,12,11,54
  317. call show_title 3 7 63
  318. call SysCurPos 9,13
  319. call charout , pfcolor || 'Migration of PMMail addresses' ,
  320.                           'to MR2Ice has started.' || s.normvid
  321. call SysCurPos 11,13
  322. call charout , pfcolor || center('A total of' nickinf.0 'entries will' ,
  323.                           'be written.',52) || s.normvid
  324. if WriteMR2Ice()   /* write nicknames; non-zero return means a problem */
  325.   then do
  326.          msg = 'An error occurred while opening or writing to the'      ,
  327.                'address book or group files for MR2Ice.  Please report' ,
  328.                'this error to the author and provide as many details'   ,
  329.                'about your setup as possible.'
  330.          call Logger logfile,msg,,1
  331.          call stopping msg
  332.        end                                      /* of if WriteMR2Ice() */
  333. call SysCurPos 11,0
  334. /***********************************************************************/
  335. /* And now on with building folders and moving/copying existing mail.  */
  336. /***********************************************************************/
  337. call SysCurPos 9,13
  338. call charout , pfcolor || center('Building MR2Ice folders and' dowhate ,
  339.                                'mail',52) || s.normvid
  340. call syscurpos 20,0
  341. /***********************************************************************/
  342. /*                                                                     */
  343. /* Each line of the folders.ndx file for MR2Ice is composed of 4       */
  344. /* parts.  The 4 parts are:                                            */
  345. /*                                                                     */
  346. /*    Name of folder - displayed on the main folder tab                */
  347. /*    Name on tab    - tab name used when folder is open               */
  348. /*    Directory name - this is the actual name of the directory        */
  349. /*    Y/N            - Y for auto open - N don't auto open             */
  350. /*                                                                     */
  351. /* Each value is separated by '01'x.  Directory names start with upper */
  352. /* case F followed by a right adjusted, zero filled, number that is    */
  353. /* incremented with each new folder.                                   */
  354. /*                                                                     */
  355. /* Since PMMail has no tab names for folders all we can do is plug in  */
  356. /* the actual folder name as the tab name.  Of course the user may     */
  357. /* change the tab name later if they want to.                          */
  358. /*                                                                     */
  359. /* Before we start going through the PMMail folders we need to read    */
  360. /* and process the existing folders.ndx if it exists so we don't get a */
  361. /* directory clash.                                                    */
  362. /*                                                                     */
  363. /***********************************************************************/
  364. call MR2IceFolderInfo  /* get highest folder number already being used */
  365. frc = stream(mr2indx,'c','open write')             /* open output file */
  366. if substr(frc,1,5) \= 'READY'            /* something bad has happened */
  367.   then do
  368.          msg = 'Unexpected return code of' frc 'trying to open' mr2indx ,
  369.                'for writing.'
  370.          call Logger logfile,msg,,1
  371.          call stopping msg
  372.        end                         /* of if substr(frc,1,5) \= 'READY' */
  373. if length(pmmfolders.0) < 3                   /* less than 100 folders */
  374.   then foldlong = 3       /* default to 3 positions in directory names */
  375.   else foldlong = length(pmmfolders.0)   /* else max digits for length */
  376. do lp = 1 to pmmfolders.0  /* go through each folder we need to create */
  377.   pmmf  = translate(pmmfolders.lp)   /* get a folder name & upper case */
  378.   call SysCurPos 11,13
  379.   call charout , pfcolor || center('Building folder' pmmf 'and' ,
  380.                                     dowhate 'mail items',52) ||    ,
  381.                  s.normvid
  382.   out.0 = 0                              /* clear stem of index output */
  383.   newdir = 'F' || right(mr2ilast + lp,foldlong,'0')    /* new dir name */
  384.   call lineout mr2indx,pmmf || hex01 || pmmf || hex01 || newdir || ,
  385.                                hex01 || 'N'      /* update folders.ndx */
  386.   call SysMkDir mr2inew || newdir          /* create the new directory */
  387.   pmmindex    = pmmroot || pmmdirnames.lp || '.BAG'    /* PMMail index */
  388.   fromdir     = pmmroot || 'FOLDERS\' || pmmdirnames.lp || '\'
  389.   pdir        = mr2inew || newdir             /* MR2Ice directory name */
  390.   folderindex = pdir    || '\FOLDER.NDX'      /* same name in each dir */
  391.   call SysFileTree pmmindex,'temp','F'          /* get index file info */
  392.   if temp.0 == 0                      /* no index file for some reason */
  393.     then iterate lp                              /* next folder please */
  394.   parse var temp.1 . . fbytes .    /* we just need the number of bytes */
  395.   ndxin = charin(pmmindex,1,fbytes)                /* read entire file */
  396.   call stream pmmindex,'c','close'                 /* close index file */
  397.   parse var ndxin mcount (eol) ndxin        /* drop first line (count) */
  398.   if mcount == 0     /* no mail in this folder; just need place holder */
  399.     then call stream folderindex,'c','open write'  /* for 0 byte index */
  400.     else call Build_Index      /* build MR2Ice index from PMMail index */
  401.   /* The out. stem is filled in the Build_Index subroutine if it's     */
  402.   /* been called.  Otherwise out.0 will be 0 and nothing will get      */
  403.   /* written.                                                          */
  404.   do ilp = 1 to out.0                   /* go through each output line */
  405.     call lineout folderindex,out.ilp          /* write the index entry */
  406.   end                                        /* of do ilp = 1 to out.0 */
  407.   call stream folderindex,'c','close'       /* close folder index file */
  408.   folderea = 'FEFF0400'x || build_eas(out.0)    /* build EAs for index */
  409.   call SysPutEA folderindex,'MessageCtr',folderea         /* store EAs */
  410. end                                    /* of do lp = 1 to pmmfolders.0 */
  411. call stream mr2indx,'c','close'              /* close folders.ndx file */
  412. /* We're all done so show the closing screen before we leave for good. */
  413. call SysCls
  414. call build_box 6,14,2,74
  415. call show_title 3 7 63
  416. call SysCurPos 7,4
  417. call charout , pfcolor || center('A total of' pmmnicks.0 'nicknames' ,
  418.                                 'were written',72) || s.normvid
  419. call SysCurPos 9,4
  420. call charout , pfcolor || center('A total of' pmmfolders.0 'folders' ,
  421.                                  'were created',72) || s.normvid
  422. call SysCurPos 11,4
  423. call charout , s.blink || s.revvid || center('Conversion of PMMail'   ,
  424.                'nicknames and folders to MR2Ice format is'            ,
  425.                'complete.',72) || s.normvid
  426. call SysCurPos 13,4
  427. call charout , s.blink || s.revvid || center('Please restart MR2Ice to' ,
  428.                'see your nicknames and folders.',72) || s.normvid
  429. call SysCurPos 16,0
  430. common_exit:                                   /* single point of exit */
  431. exit                                               /* that's all folks */
  432. /***********************************************************************/
  433. stopping:             /* we've encountered an error and can't continue */
  434.   parse arg errmsg                  /* get the message to be displayed */
  435.   call SysFileTree logfile,'temp','FO'              /* log file exist? */
  436.   if temp.0 \= 0                                          /* sure does */
  437.     then errmsg = errmsg ' The file' ourname'.log also contains the' ,
  438.                          'text of this message for reference.'
  439.   call SysCls                                      /* clear the screen */
  440.   say                                                    /* blank line */
  441.   say                                                    /* blank line */
  442.   say '****************************************************************'
  443.   say '*                                                              *'
  444.   outlength = 61                       /* maximum record length plus 1 */
  445.   errmsg = errmsg' '             /* make sure there's a trailing blank */
  446.   do forever until errmsg = ''       /* go until we run out of message */
  447.     xpos = outlength               /* so set the length to the maximum */
  448.     xpos = min(xpos,lastpos(' ',errmsg,outlength))    /* where's blank */
  449.     say '*' left(substr(errmsg,1,xpos - 1),outlength) || '*'
  450.     errmsg = delstr(errmsg,1,xpos)                      /* remove text */
  451.   end                               /* of do forever until errmsg = '' */
  452.   do lp = 1 to 3                             /* sound a warble 3 times */
  453.     call beep 262,050                                     /* low  note */
  454.     call beep 523,150                                     /* high note */
  455.   end                                             /* of do lp = 1 to 3 */
  456.   say '*                                                              *'
  457.   say '****************************************************************'
  458.   say                                                    /* blank line */
  459.   say                                                    /* blank line */
  460.   signal common_exit                /* branch to the common exit point */
  461. return                               /* end of the STOPPING subroutine */
  462. /***********************************************************************/
  463. build_eas: procedure          /* build correct EA value for folder.ndx */
  464.   parse arg ncount .  /* we get passed the numb of notes in the folder */
  465.   nchex    = d2x(ncount,8)                 /* convert the count to hex */
  466.   folderea = ''                              /* clear our return value */
  467.   do lp = (length(nchex)-1) to 1 by -2    /* backwards through the hex */
  468.     folderea = folderea || substr(nchex,lp,2)         /* back to front */
  469.   end                       /* of do lp = (length(nchex)-1) to 1 by -2 */
  470. return x2c(folderea)                /* end of the BUILD_EAS subroutine */
  471. /***********************************************************************/
  472. ask_about_cleanup: /* if moving see if we should clean up dirs and ndx */
  473.                    /* cleanup is initialize to 0 when we get here      */
  474.   call SysCls                                /* clear the screen again */
  475.   call build_box 6,13,9,60
  476.   call show_title 3 7 63
  477.   call SysCurPos 7,11
  478.   call charout , pfcolor || 'You have decided to MOVE all of your' ,
  479.                             'PMMail data over to  ' || s.normvid
  480.   call SysCurPos 8,11
  481.   call charout , pfcolor || 'MR2Ice.  Do you want me to clean up your' ,
  482.                             'PMMail folders as' || s.normvid
  483.   call SysCurPos 9,11
  484.   call charout , pfcolor || 'mail is being moved?  Cleaning up' ,
  485.                             'includes removing the   ' || s.normvid
  486.   call SysCurPos 10,11
  487.   call charout , pfcolor || 'PMMail directories as well as the PMMail' ,
  488.                             'index files.     ' || s.normvid
  489.   call SysCurPos 12,33
  490.   call charout , s.blink || s.revvid || 'Y(es) or N(o) _'  || s.normvid
  491.   call SysCurPos 15,24
  492.   call charout , pfcolor || 'Enter a' s.blink || s.revvid || 'Q' || ,
  493.                  pfcolor    'if you want to stop now.' || s.normvid
  494.   clean_again:                    /* label for branch if invalid entry */
  495.   call charout , s.blink || s.revvid
  496.   call SysCurPos 12,47
  497.   key = translate(substr(linein(),1)) /* get 1 character from keyboard */
  498.   call charout , s.normvid
  499.   if key = 'Q'
  500.     then call stopping 'Stopping this program at your request.  Bye' ,
  501.                        'for now...'
  502.   if key \= 'Y' & key \= 'N'                          /* not yes or no */
  503.     then do
  504.            call SysCurPos 17,12
  505.            call charout , s.blink || s.revvid || 'Invalid choice. ' ,
  506.                           'Must be Y, N, or Q.  Please try again.' || ,
  507.                           s.normvid
  508.            signal clean_again                  /* back for another key */
  509.          end                          /* of if key \= 'Y' & key \= 'N' */
  510.   if key = 'Y'            /* wants us to clean up the PMMail structure */
  511.     then cleanup = 1             /* turn on the cleanup flag for later */
  512. return                      /* end of the ASK_ABOUT_CLEANUP subroutine */
  513. /***********************************************************************/
  514. build_box: procedure expose box. c. s.
  515.   /*        1st row , last row , 1st column , column length            */
  516.   parse arg srow , erow , scol , long
  517.   call SysCurPos srow,scol                          /* position cursor */
  518.   call charout , s.revvid || c.fcyan || c.bblack
  519.   call charout , box.uplc || copies(box.hside,long) || box.uprc
  520.   do lp = (srow + 1) to (erow - 1)
  521.     call SysCurPos lp,scol                          /* position cursor */
  522.     call charout , box.vside || copies(' ',long) || box.vside
  523.   end
  524.   call SysCurPos erow,scol                          /* position cursor */
  525.   call charout , box.lolc || copies(box.hside,long) || box.lorc
  526.   call charout , s.normvid
  527. return                              /* end of the BUILD_BOX subroutine */
  528. /***********************************************************************/
  529. show_title: procedure expose title s.           /* show our title line */
  530.   parse arg row start long           /* what row, start col, box width */
  531.   tcol = ((long - length(title)) % 2) + start           /* calc column */
  532.   call SysCurPos row,tcol                           /* position cursor */
  533.   call charout , s.blink || s.revvid title s.normvid     /* show title */
  534. return                             /* end of the SHOW_TITLE subroutine */
  535. /***********************************************************************/
  536. get_key: procedure expose keys          /* get a key from the keyboard */
  537.   /* Waits for a valid key to be entered.  Valid keys are listed in    */
  538.   /* the variable named KEYS which is exposed on entry to this routine.*/
  539.   /* The row and column where we'll look for the key are passed to     */
  540.   /* this routine as arguments.  The Enter key is the only valid       */
  541.   /* action key that will cause this routine to return.  On return the */
  542.   /* character that was entered will be returned so the caller can do  */
  543.   /* something based on what was entered.                              */
  544.   parse arg krow kcol                            /* key row and column */
  545.   more_keys:                          /* label to wait for another key */
  546.   call SysCurPos krow,kcol                      /* position the cursor */
  547.   key = c2x(SysGetKey('noecho'))       /* wait for a key to be pressed */
  548.   if key = '00'                                        /* extended key */
  549.     then key = '00' || c2x(SysGetKey('noecho'))        /* get 2nd byte */
  550.   if key = 'E0'                                        /* extended key */
  551.     then key = '00' || c2x(SysGetKey('noecho'))        /* get 2nd byte */
  552.   if wordpos(key,keys) = 0                              /* invalid key */
  553.     then do
  554.            call beep 523,150                              /* high note */
  555.            call beep 262,050                              /* low  note */
  556.            signal more_keys                 /* go back for another key */
  557.          end                            /* of if wordpos(key,keys) = 0 */
  558.   call SysCurPos krow,kcol                        /* reposition cursor */
  559.   call charout , x2c(key)                     /* show what was entered */
  560.   if key \= '0D'                                  /* not the enter key */
  561.     then signal more_keys                /* go back and wait for enter */
  562. return SysTextScreenRead(krow,kcol,1) /* end of the GET_KEY subroutine */
  563. /***********************************************************************/
  564. AnsiColor:                       /* set things up for the use of color */
  565. 'ANSI ON | RXQUEUE'                /* make sure ANSI is on and enabled */
  566. 'RXQUEUE /clear'         /* trash anything that might have been queued */
  567. esccode    = '1B'x   || "["          /* escape sequence for ANSI codes */
  568. s.blink    = esccode || "5m"                                  /* Blink */
  569. s.revvid   = esccode || "7m"                          /* Reverse video */
  570. s.normvid  = esccode || "0m"                     /* All attributes off */
  571. c.bcyan    = esccode || "36m"                       /* background cyan */
  572. c.fcyan    = esccode || "46m"                       /* foreground cyan */
  573. c.bblack   = esccode || "30m"                      /* background black */
  574. c.fgreen   = esccode || "42m"                      /* foreground green */
  575. Box.UpLc   = 'DA'x                      /* upper left corner  of a box */
  576. Box.LoLc   = 'C0'x                      /* lower left corner  of a box */
  577. Box.UpRc   = 'BF'x                      /* upper right corner of a box */
  578. Box.LoRc   = 'D9'x                      /* lower right corner of a box */
  579. Box.HSide  = 'C4'x                      /* horizontal side    of a box */
  580. Box.VSide  = 'B3'x                      /* vertical side      of a box */
  581. entryfield = s.revvid || c.fcyan || c.bblack      /* entry field color */
  582. pfcolor    = s.blink || s.revvid || c.fgreen            /* F key color */
  583. return                              /* end of the AnsiColor subroutine */
  584. /***********************************************************************/
  585. Build_Index:         /* build MR2Ice index file from PMMail index file */
  586.   /*********************************************************************/
  587.   /* The first line of the PMMail folder index files has a count of    */
  588.   /* how many index entries there are.  We'll ignore that line.  The   */
  589.   /* delimiter between the values is hex DE ('DE'x).  The lines are    */
  590.   /* laid out as follows:                                              */
  591.   /*                                                                   */
  592.   /* Date      - in yy-mm-dd format                                    */
  593.   /* Time      - in hh:mm:ss format                                    */
  594.   /* Subject   - Free form                                             */
  595.   /* From/To   - Who the note was from/to                              */
  596.   /* Name      - Persons name                                          */
  597.   /* File info - filename.ext of the note                              */
  598.   /* Read flag - Y for yes it's been read - we'll force read to Yes    */
  599.   /*                                                                   */
  600.   /* Immediately following the read flag is the value hex E1 ('E1'x).  */
  601.   /*                                                                   */
  602.   /*********************************************************************/
  603.   do forever until ndxin == ''          /* go until we run out of data */
  604.     parse var ndxin idate (hexDE) ,                  /* date           */
  605.                     itime (hexDE) ,                  /* time           */
  606.                     isubj (hexDE) ,                  /* subject        */
  607.                     ifrom (hexDE) ,                  /* from/to        */
  608.                     iname (hexDE) ,                  /* persons name   */
  609.                     ifile (hexDE) ,                  /* note file name */
  610.                     . (eol) ndxin                    /* end-of-line    */
  611.     idate = strip(translate(idate,'/','-'))   /* change date separator */
  612.     parse upper var ifile fn '.' ft  /* break up file name & extension */
  613.     if ft == 'SNT' | ,                   /* sent mail (from PMMail) or */
  614.        ft == ''                          /* sent mail (from LaMail)    */
  615.       then oft = 'out'                           /* use OUT for MR2Ice */
  616.       else oft = 'rcv'                           /* use RCV for MR2Ice */
  617.     ofile = pdir || '\' || fn || '.' || oft   /* build output file inf */
  618.     ndxout = copies(' ',26) ,              /* build MR2Ice index entry */
  619.              left(fn,8)     ,
  620.              left(oft,3)    ,
  621.              copies(' ',12) ,
  622.              idate          ,
  623.              itime          ,
  624.              copies(' ',8)  ,
  625.              'Y    '        ,
  626.              iname ||       ,
  627.              hex01 ||       ,
  628.              isubj ||       ,
  629.              hex01 ||       ,
  630.              hex01 ||       ,
  631.              ifrom
  632.     out.0 = out.0 + 1                    /* bump count of output lines */
  633.     point = out.0              /* move new count into the stem pointer */
  634.     out.point = ndxout                  /* stash data where it belongs */
  635.     '@COPY' fromdir || ifile ofile '/V > NUL 2>NUL'     /* always copy */
  636.     if rc \= 0           /* something happened trying to copy the file */
  637.       then call Logger logfile,'Error: Return code' rc dowhate ,
  638.                                       fromdir || ifile 'to' ofile,,1
  639.       else if dowhat = 'MOVE'                   /* we're moving things */
  640.              then call SysFileDelete fromdir || ifile   /* delete orig */
  641.   end                               /* of do forever until ndxin == '' */
  642.   if cleanup                     /* we're moving stuff and cleaning up */
  643.     then do
  644.            call SysFileDelete pmmindex            /* remove index file */
  645.            call SysRmDir pmmroot || '\FOLDERS\' || pmmdirnames.lp
  646.            if rc \= 0
  647.              then call Logger logfile,'Error: Return code' rc ,
  648.                                             'removing' pmmfolders || ,
  649.                                             '\' || pmmdirnames.lp,,1
  650.          end                                          /* of if cleanup */
  651. return                            /* end of the Build_Index subroutine */
  652. /***********************************************************************/
  653. PMMailFolders: procedure expose pmmroot pmmfolders. pmmbytes pmmdirnames.
  654. call RxFuncAdd 'SysFileTree','RexxUtil','SysFileTree'
  655. if substr(pmmroot,length(pmmroot),1) \= '\'   /* no trailing backslash */
  656.   then pmmroot = pmmroot || '\'                          /* so add one */
  657. eol           = x2c('0D0A')                    /* end of line sequence */
  658. pmmbytes      = 0          /* number of bytes mail is currently taking */
  659. pmmfolders.   = ''                  /* initialize stem of folder names */
  660. pmmfolders.0  = 0     /* zero element will have count of what we found */
  661. pmmdirnames.  = ''        /* initialize stem of folder directory names */
  662. pmmdirnames.0 = 0     /* zero element will have count of what we found */
  663. pmmfldini = pmmroot || 'FOLDERS.INI'                /* folder ini file */
  664. call SysFileTree pmmfldini,'temp.','f'      /* get folders.ini details */
  665. if temp.0 == 0          /* doesn't look like PMMail has ever been used */
  666.   then signal exit_PMMailFolders                          /* leave now */
  667. parse var temp.1 . . fbytes .      /* we just need the number of bytes */
  668. fldin = charin(pmmfldini,1,fbytes)                 /* read entire file */
  669. call stream pmmfldini,'c','close'            /* close folders.ini file */
  670. do forever until fldin == ''            /* go until we run out of data */
  671.   parse var fldin name (eol) dirnam (eol) . (eol) fldin   /* data 4 us */
  672.   if translate(dirnam) == 'INBOX'    | ,   /* don't count the inbox or */
  673.      translate(dirnam) == 'OUTQUEUE' | ,             /* the out box or */
  674.      translate(dirnam) == 'SENT'               /* the sent already box */
  675.     then iterate                          /* next group of info please */
  676.   pmmfolders.0 = pmmfolders.0 + 1               /* bump count of names */
  677.   pointer      = pmmfolders.0                 /* pointer into the stem */
  678.   pmmfolders.pointer  = name                  /* stash the folder name */
  679.   pmmdirnames.pointer = dirnam             /* stash the directory name */
  680. end                                 /* of do forever until fldin == '' */
  681. pmmdirnames.0 = pmmfolders.0    /* copy count of folders to other stem */
  682. do lp = 1 to pmmdirnames.0           /* go through each directory name */
  683.   pmmdir = pmmroot || 'FOLDERS\' || pmmdirnames.lp
  684.   call SysFileTree pmmdir || '\*.*','temp.','f'   /* list of all files */
  685.   if temp.0 == 0                                     /* no files there */
  686.     then iterate                              /* next directory please */
  687.   do ilp = 1 to temp.0                /* go through each file we found */
  688.     parse var temp.ilp . . fbytes .        /* just the number of bytes */
  689.     pmmbytes = pmmbytes + fbytes        /* add it to the overall total */
  690.   end                                       /* of do ilp = 1 to temp.0 */
  691. end                                   /* of do lp = 1 to pmmdirnames.0 */
  692. exit_PMMailFolders:               /* label for branch to leave quickly */
  693. return                          /* end of the PMMailFolders subroutine */
  694. /***********************************************************************/
  695. PMMailNicks: procedure expose pmmroot pmmnicks.
  696. call RxFuncAdd 'SysFileTree','RexxUtil','SysFileTree'
  697. if substr(pmmroot,length(pmmroot),1) \= '\'   /* no trailing backslash */
  698.   then pmmroot = pmmroot || '\'                          /* so add one */
  699. adrbooks.  = ''            /* initialize stem of address books we find */
  700. adrbooks.0 = 0    /* the count will be in the zero element of the stem */
  701. hex01      = '01'x                      /* constant to delimit entries */
  702. eol        = x2c('0D0A')                       /* end of line sequence */
  703. pmmadrini  = pmmroot || 'ADDRESS\ADDRBOOK.INI'     /* address book ini */
  704. pmmgrpini  = pmmroot || 'ADDRESS\GROUP.INI'          /* group list ini */
  705. pmmnicks.  = ''                /* initialize stem of info we'll gather */
  706. pmmnicks.0 = 0                  /* count of entries we find and gather */
  707. call SysFileTree pmmadrini,'temp.','f'     /* get addrbook.ini details */
  708. if temp.0 == 0                           /* no addrbook.ini file found */
  709.   then signal exit_PMMailNicks                     /* we can leave now */
  710. parse var temp.1 . . fbytes .      /* we just need the number of bytes */
  711. adrin = charin(pmmadrini,1,fbytes)                 /* read entire file */
  712. call stream pmmadrini,'c','close'           /* close addrbook.ini file */
  713. do forever until adrin == ''            /* go until we run out of data */
  714.   parse var adrin line (eol) adrin         /* break off a line of data */
  715.   parse upper var line w1 '\' adrname    /* break up the line a little */
  716.   if w1 \= 'ADDRESS'          /* this must be a address book name line */
  717.     then iterate                                   /* next line please */
  718.   adrbooks.0 = adrbooks.0 + 1       /* bump count of books we've found */
  719.   pointer    = adrbooks.0                     /* pointer into the stem */
  720.   adrbooks.pointer = pmmroot || line        /* stash full name of book */
  721. end                                 /* of do forever until adrin == '' */
  722. do lp = 1 to adrbooks.0   /* now go through each address book we found */
  723.   adrbk = adrbooks.lp            /* fully qualified path and file name */
  724.   call SysFileTree adrbk,'temp.','f'       /* get address book details */
  725.   parse var temp.1 . . fbytes .    /* we just need the number of bytes */
  726.   adrin = charin(adrbk,1,fbytes)                   /* read entire file */
  727.   call stream adrbk,'c','close'              /* close the address book */
  728.   do forever until adrin == ''          /* go until we run out of data */
  729.     parse var adrin name (eol) addr (eol) comp (eol) fone (eol) note ,
  730.                          (eol) adrin
  731.     parse var addr uid '@' host                    /* break up address */
  732.     if comp \= ''                          /* company name isn't blank */
  733.       then note = note 'Company name:' comp     /* add it to the notes */
  734.     pmmnicks.0 = pmmnicks.0 + 1                          /* bump count */
  735.     pointer    = pmmnicks.0                       /* pointer into stem */
  736.     pmmnicks.pointer =         hex01 || ,      /* no nickname or alias */
  737.                        uid  || hex01 || ,   /* user ID part of address */
  738.                        host || hex01 || ,      /* host part of address */
  739.                        name || hex01 || ,                 /* full name */
  740.                        fone || hex01 || ,              /* phone number */
  741.                        note || hex01 || ,                     /* notes */
  742.                                hex01
  743.   end                               /* of do forever until adrin == '' */
  744. end                                      /* of do lp = 1 to adrbooks.0 */
  745. /* Now that we're done with address books process the groups (if any)  */
  746. call SysFileTree pmmgrpini,'temp.','f'        /* get group.ini details */
  747. if temp.0 == 0          /* no group ini file found (no groups defined) */
  748.   then signal exit_PMMailNicks                     /* we can leave now */
  749. parse var temp.1 . . fbytes .      /* we just need the number of bytes */
  750. grpin = charin(pmmgrpini,1,fbytes)                 /* read entire file */
  751. call stream pmmgrpini,'c','close'           /* close addrbook.ini file */
  752. do forever until grpin == ''            /* go until we run out of data */
  753.   parse var grpin line (eol) grpin         /* break off a line of data */
  754.   parse upper var line w1 '\' .              /* get first word of line */
  755.   if w1 \= 'ADDRESS'                 /* this must be a group name line */
  756.     then do
  757.            parse var line grpname .      /* respect case of group name */
  758.            pmmnicks.0 = pmmnicks.0 + 1                   /* bump count */
  759.            pointer    = pmmnicks.0                /* pointer into stem */
  760.            pmmnicks.pointer = grpname || hex01 || hex01 || hex01 || ,
  761.                               grpname || hex01 || hex01 || hex01
  762.            iterate                               /* read the next line */
  763.          end                                  /* of if w1 \= 'ADDRESS' */
  764.   groupfile = pmmroot || line              /* stash full name of group */
  765.   call SysFileTree groupfile,'temp.','f'     /* get group file details */
  766.   parse var temp.1 . . fbytes .    /* we just need the number of bytes */
  767.   group = charin(groupfile,1,fbytes)               /* read entire file */
  768.   call stream groupfile,'c','close'            /* close the group file */
  769.   names = ''            /* initialize variable to hold group addresses */
  770.   do forever until group == ''          /* go until we run out of data */
  771.     parse var group addr (eol) group /* each line should be an address */
  772.     names = names addr                  /* add the address to the list */
  773.   end                               /* of do forever until group == '' */
  774.   pmmnicks.pointer = pmmnicks.pointer || strip(names,'L') || hex01
  775. end                                 /* of do forever until grpin == '' */
  776. exit_PMMailNicks:                 /* label for branch to leave quickly */
  777. return                            /* end of the PMMailNicks subroutine */
  778. /***********************************************************************/
  779. WriteMR2Ice: procedure expose mr2iadr mr2igrp nickinf.
  780. out.     = ' '                         /* start off with a clean slate */
  781. sendback = 0                           /* assume everything will go OK */
  782. written  = 0                  /* initialize count of nicknames written */
  783. frc = stream(mr2iadr,'c','open write')             /* open output file */
  784. if substr(frc,1,5) \= 'READY'            /* something bad has happened */
  785.   then do
  786.          sendback = 1      /* turn on flag to show there was a problem */
  787.          signal exit_WriteMR2Ice                          /* leave now */
  788.        end                         /* of if substr(frc,1,5) \= 'READY' */
  789. frc = stream(mr2igrp,'c','open write')             /* open output file */
  790. if substr(frc,1,5) \= 'READY'            /* something bad has happened */
  791.   then do
  792.          sendback = 1      /* turn on flag to show there was a problem */
  793.          signal exit_WriteMR2Ice                          /* leave now */
  794.        end                         /* of if substr(frc,1,5) \= 'READY' */
  795. do lp = 1 to nickinf.0            /* go through each line passed to us */
  796.   parse var nickinf.lp alias '01'x ,      /* break up the line of data */
  797.                        user  '01'x ,
  798.                        host  '01'x ,
  799.                        name  '01'x ,
  800.                        phone '01'x ,
  801.                        notes '01'x ,
  802.                        group '01'x .
  803.   if group \= ''                /* must be a distribution list (group) */
  804.     then do
  805.            out = '!'   || ,                                /* constant */
  806.                  alias || ,                        /* alias (nickname) */
  807.                  '\'   || ,                                /* constant */
  808.                  name  || ,  /* name for To: line of distribution list */
  809.                  '\'   || ,                                /* constant */
  810.                  'N'                /* No display on RMB (our default) */
  811.            if lineout(mr2igrp,out)   /* write a line to the group file */
  812.              then do
  813.                     sendback = 1               /* turn on problem flag */
  814.                     signal exit_WriteMR2Ice               /* leave now */
  815.                   end                       /* if lineout(mr2igrp,out) */
  816.            out = ''             /* clear the output field for a moment */
  817.            if phone \= ''                    /* we have a phone number */
  818.              then out = 'Phone number:' phone   /* describe what it is */
  819.            if note \= ''           /* there are some notes to be added */
  820.              then out = out notes                     /* add the notes */
  821.            out = strip(out,'L')           /* remove any leading blanks */
  822.            if out \= ''    /* looks like we've got some notes to write */
  823.              then do
  824.                     nlong = length(out) /* how many bytes in the notes */
  825.                     if lineout(mr2igrp,'#' || nlong)   /* notes length */
  826.                       then do
  827.                              sendback = 1  /* turn on the problem flag */
  828.                              signal exit_WriteMR2Ice      /* leave now */
  829.                            end             /* if lineout(mr2igrp,blah) */
  830.                     if lineout(mr2igrp,out)         /* write the notes */
  831.                       then do
  832.                              sendback = 1  /* turn on the problem flag */
  833.                              signal exit_WriteMR2Ice      /* leave now */
  834.                            end              /* if lineout(mr2igrp,out) */
  835.                   end                               /* of if out \= '' */
  836.            do ilp = 1 to words(group)       /* go through each address */
  837.              if lineout(mr2igrp,'+' || word(group,ilp))  /* write addr */
  838.                then do
  839.                       sendback = 1         /* turn on the problem flag */
  840.                       signal exit_WriteMR2Ice             /* leave now */
  841.                     end                    /* if lineout(mr2igrp,blah) */
  842.            end               /* of do ilp = 1 to words(group) */
  843.            iterate lp                   /* go to the next line of data */
  844.          end                                    /* of when group \= '' */
  845.   /* If we got here the entry wasn't a list of IDs (group) so we'll    */
  846.   /* create a "normal" entry in the address book.                      */
  847.   out = name || '\' || ,                               /* persons name */
  848.         user || '@' || ,                                    /* user ID */
  849.         host || '\' || ,                                  /* host name */
  850.         'N'  || '\' || ,             /* default to not show on the RMB */
  851.         alias                               /* nickname for this entry */
  852.   if lineout(mr2iadr,out)          /* write a line to the address book */
  853.     then do
  854.            sendback = 1    /* turn on flag to show there was a problem */
  855.            signal exit_WriteMR2Ice                        /* leave now */
  856.          end                                /* if lineout(mr2iadr,out) */
  857.   out = ''                      /* clear the output field for a moment */
  858.   if phone \= ''                             /* we have a phone number */
  859.     then out = 'Phone number:' phone          /* describe what this is */
  860.   if notes \= ''                   /* there are some notes to be added */
  861.     then out = out notes                              /* add the notes */
  862.   out = strip(out,'L')                    /* remove any leading blanks */
  863.   if out \= ''             /* looks like we've got some notes to write */
  864.     then do
  865.            nlong = length(out)          /* how many bytes in the notes */
  866.            if lineout(mr2iadr,'01'x || nlong)     /* notes length info */
  867.              then do
  868.                     sendback = 1           /* turn on the problem flag */
  869.                     signal exit_WriteMR2Ice               /* leave now */
  870.                   end                      /* if lineout(mr2iadr,blah) */
  871.            if lineout(mr2iadr,out)            /* and finally the notes */
  872.              then do
  873.                     sendback = 1           /* turn on the problem flag */
  874.                     signal exit_WriteMR2Ice               /* leave now */
  875.                   end                       /* if lineout(mr2iadr,out) */
  876.          end                                        /* of if out \= '' */
  877. end                                       /* of do lp = 1 to nickinf.0 */
  878. exit_WriteMR2Ice:          /* label for branch if we run into problems */
  879. call stream mr2iadr,'c','close'         /* close the address book file */
  880. call stream mr2igrp,'c','close'                /* close the group file */
  881. return sendback                   /* end of the WriteMR2Ice subroutine */
  882. /***********************************************************************/
  883. MR2IceFolderInfo: procedure expose mr2ilast mr2indx
  884. hex01    = '01'x                        /* constant to delimit entries */
  885. eol      = x2c('0D0A')                         /* end of line sequence */
  886. mr2ilast = 0                /* assume no folders created in MR2Ice yet */
  887. call RxFuncAdd 'SysFileTree','RexxUtil','SysFileTree'
  888. call SysFileTree mr2indx,'temp.','f'             /* index file details */
  889. if temp.0 == 0                               /* no folders created yet */
  890.   then signal exit_MR2IceFolderInfo                /* we can leave now */
  891. parse var temp.1 . . fbytes .      /* we just need the number of bytes */
  892. ndxin = charin(mr2indx,1,fbytes)                   /* read entire file */
  893. call stream mr2indx,'c','close'             /* close folder index file */
  894. do forever until ndxin == ''            /* go until we run out of data */
  895.   parse var ndxin . (hex01) . (hex01) foldnum (hex01) (eol) ndxin
  896.   foldnum = substr(foldnum,2)  /* just the numeric part of folder name */
  897.   if foldnum > mr2ilast                  /* highest we've seen so far? */
  898.     then mr2ilast = foldnum               /* sure is so keep the value */
  899. end                                 /* of do forever until ndxin == '' */
  900. exit_MR2IceFolderInfo:              /* label for branch for quick exit */
  901. return                       /* end of the MR2IceFolderInfo subroutine */
  902. /***********************************************************************/
  903. logger: procedure               /* writes a line of data to a log file */
  904. parse arg outfile , outmsg , splitat , closeit        /* get arguments */
  905. if arg(3,'Omitted')                          /* split value not passed */
  906.   then splitat = 0                                /* trigger for later */
  907. if arg(4,'Omitted')              /* whether or not to close not passed */
  908.   then closeit = 0                /* default to not close the log file */
  909. sendback = 0           /* assume we'll write the message without error */
  910. if closeit \= 0 & ,                    /* closeit value isn't zero and */
  911.    closeit \= 1                                        /* it isn't one */
  912.   then do
  913.          sendback = 1      /* turn on return flag to indicate an error */
  914.          signal exit_logger                               /* leave now */
  915.        end                        /* of if closeit \= 0 & closeit \= 1 */
  916. timestamp = date('S') time()    /* consistent time stamp for log lines */
  917. if splitat = 0                         /* we don't need to split lines */
  918.   then do
  919.          call lineout outfile , timestamp outmsg  /* write the message */
  920.          signal exit_logger                               /* leave now */
  921.        end                                         /* of if slitat = 0 */
  922. outmsg = outmsg' '               /* make sure there's a trailing blank */
  923. do forever until outmsg = ''         /* go until we run out of message */
  924.   xpos = splitat                      /* set the length to the maximum */
  925.   xpos = min(xpos,lastpos(' ',outmsg,splitat))   /* where's the blank? */
  926.   call lineout outfile , timestamp ,           /* write a line of data */
  927.                          left(substr(outmsg,1,xpos - 1),splitat)
  928.   outmsg = delstr(outmsg,1,xpos)               /* remove what we wrote */
  929. end                                 /* of do forever until outmsg = '' */
  930. exit_logger:                      /* label for branch to leave quickly */
  931. if closeit                  /* flag to close the log file is turned on */
  932.   then call stream outfile , 'C' , 'Close'           /* close the file */
  933. return sendback                        /* end of the LOGGER subroutine */
  934. /***********************************************************************/
  935.