home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 18 REXX / 18-REXX.zip / rxjiscmd.zip / PMMLSEND.CMD < prev   
OS/2 REXX Batch file  |  1996-06-20  |  12KB  |  367 lines

  1. /* product name: RXJIS                                                */
  2. /* Version:      0.85                                                 */
  3. /* author:       YANO Takashi                                         */
  4. /* target:       OS/2 Warp J3.0+                                      */
  5. /* module name:  MIMESEND.CMD                                         */
  6. /* source name:  MIMESEND.CMD                                         */
  7. /* compiler:     N.A.                                                 */
  8. /* address:      tyano@ca2.so-net.or.jp or tyano@yamato.ibm.co.jp     */
  9. /* comment:      RXJIS is a utility functions for REXX.               */
  10. /*               It encodes and decodes JIS 7 bit strings and MIME    */
  11. /*               format strings.                                      */
  12. /*                                                                    */
  13. /*               MIMESEND.CMD is a sample program how to use          */
  14. /*               RXJIS. I am using it with PostRoadMailer 1.03a.      */
  15. /*               It converts a mail message with PC Kanji codes       */
  16. /*               into MIME or JIS7bit mail message.                   */
  17. /*                                                                    */
  18. /* how to use:   MIMESEND fn                                          */
  19. /*               fn is a mail message file. The converted result is   */
  20. /*               in fn. The original is lost.                         */
  21. /*                                                                    */
  22. /* history:      1996-2-5 initial release                             */
  23. /*               1996-2-14 0.10 fix small bugs                        */
  24. /*                         missing REXXUTIL loading.                  */
  25. /*                         if NOMIME is missing, novalue occurs.      */
  26. /*               1996-2-19 remove trace                               */
  27. /*               1996-10-20 Avoid to put duplicated headers.          */
  28. /*                                                                    */
  29. /*               02/14/96 Modified by K.Wakamiya for PMMail and       */
  30. /*                        rename from mimesend.cmd to pmmlsend.cmd    */
  31. /*                        modify 'CONTENT-TYPE:' header handling to   */
  32. /*                        be able to send attach mail                 */
  33. /*                        modify 'REPLY-TO:' header handling          */
  34. /*                                                                    */
  35. /*                                                                    */
  36. /*                                                                    */
  37. arg fn
  38. signal on novalue
  39. call rxfuncadd 'SysLoadFuncs', 'REXXUTIL', 'SysLoadFuncs' /* A@0.10 */
  40. call SysLoadFuncs                                         /* A@0.10 */
  41. call rxfuncdrop 'RxJisLoadFuncs'
  42. call rxfuncadd 'RxJisLoadFuncs', 'RXJIS', 'RxJisLoadFuncs'
  43. call RxJisLoadFuncs
  44. if stream(fn, 'c', 'query exists') = '' then exit
  45. call LoadHeader fn
  46. call LoadBody fn
  47. call stream fn, 'c', 'close'
  48. call CheckIfNomimeHost
  49. i = 1
  50. j = 1
  51. newheader.1 = 'MIME-Version: 1.0'
  52. do while i <= header.0
  53.    select
  54.       when translate(word(header.i, 1)) = 'SUBJECT:' then parse value processsubject(i, j) with i j
  55.       when translate(word(header.i, 1)) = 'REPLY-TO:' then parse value processreplyto(i, j) with i j
  56.       when translate(word(header.i, 1)) = 'FROM:' then parse value processaddress(i, j) with i j
  57.       when translate(word(header.i, 1)) = 'TO:' then parse value processaddress(i, j) with i j
  58.       when translate(word(header.i, 1)) = 'CC:' then parse value processaddress(i, j) with i j
  59.       when translate(word(header.i, 1)) = 'BCC:' then parse value processaddress(i, j) with i j
  60.       when wordpos(translate(word(header.i, 1)), 'MIME-VERSION: CONTENT-TRANSFER-ENCODING:') > 0 then i = i + 1 /* A@0.85 */
  61.    otherwise
  62.       j = j + 1
  63.       newheader.j = header.i
  64.       if wordpos(translate(word(header.i, 1)), 'CONTENT-TYPE:') > 0 then content_type_pos = j    /* 02/14/96 */
  65.       i = i + 1
  66.    end  /* select */
  67. end /* do */
  68. if iso2022jp then do
  69.    if wordpos( 'TEXT/PLAIN;', translate(newheader.content_type_pos)) > 0 then do    /* 02/14/97 */
  70.       newheader.content_type_pos = 'Content-Type: text/plain; charset="ISO-2022-JP"'
  71.    end
  72.    j = j + 1
  73.    newheader.j = 'Content-Transfer-Encoding: 7bit'
  74.    do i = 1 to body.0
  75.       if body.i <> '' then do
  76.          if wordpos(translate(word(body.i, 1)), 'CONTENT-TYPE:') > 0 & wordpos('TEXT/PLAIN;', translate(body.i)) > 0 then do    /* 02/14/97 */
  77.             body.i = 'Content-Type: text/plain; charset="ISO-2022-JP"'
  78.          end
  79.          body.i = RxJisToJis(body.i)
  80.       end
  81.    end /* do */
  82. end  /* Do */
  83. else do
  84.    if wordpos('TEXT/PLAIN;', translate(newheader.content_type_pos)) > 0 then do    /* 02/14/97 */
  85.       newheader.content_type_pos = 'Content-Type: text/plain; charset="US-ASCII"'
  86.    end
  87.    j = j + 1
  88.    newheader.j = 'Content-Transfer-Encoding: 7bit'
  89. end  /* Do */
  90. newheader.0 = j
  91. tfn = value('TMP', , 'OS2ENVIRONMENT')
  92. if tfn = '' then tfn = workingdir
  93. if right(tfn, 1) <> '\' then tfn = tfn || '\'
  94. tfn = SysTempFileName(tfn || '????')
  95. do i = 1 to newheader.0
  96.    call lineout tfn, newheader.i
  97. end /* do */
  98. call lineout tfn, ''
  99. do i = 1 to body.0
  100.    call lineout tfn, body.i
  101. end /* do */
  102. call stream tfn, 'C', 'CLOSE'
  103. '@COPY' tfn fn
  104. call SysFileDelete tfn
  105. exit
  106.  
  107. processreplyto: procedure expose header. newheader. nomimeisrequired
  108. arg i, j
  109. c = words(header.i)
  110. h = word(header.i, 1)
  111. a = word(header.i, c)
  112.  
  113. /* 02/14/97 */
  114. m = word(header.i, 2)
  115. if (m = '*' | m = '"*"') & (a = '*' | a = '<*>') then return i + 1 j
  116. /* 02/14/97 */
  117.  
  118. j = j + 1
  119. if words(header.i) = 2 then newheader.j = h a
  120. else do
  121.    c = wordindex(header.i, words(header.i))
  122.    m = wordindex(header.i, 2)
  123.    n = strip(substr(header.i, m, c - m))
  124.    if dbvalidate(header.i) = 0 then do
  125.       if left(n, 1) <> '"' & n <> '' then n = '"' || n || '"'
  126.    end  /* Do */
  127.    else do
  128.       options 'EXMODE'
  129.       if dbwidth(n) <> length(n) then do
  130.          n = RxJisToJis(n)
  131.          if nomimeisrequired = 0 then n = '=?ISO-2022-JP?B?' || RxJisToBase64(n) || '?='
  132.       end  /* Do */
  133.       if n <> '' then n = '"' || n || '"'
  134.    end  /* Do */
  135.    newheader.j = h n a
  136. end  /* Do */
  137. return i + 1 j
  138.  
  139. CheckIfNomimeHost: procedure expose header. nomimeaddress. nomimeisrequired workingdir errorlog
  140. parse source . . a
  141. workingdir = filespec('D', a) || filespec('P', a)
  142. errorlog = workingdir || 'errorlog.log'
  143. f = workingdir || 'NOMIME'
  144. nomimeisrequired = 0 /* A@0.10 */
  145. if stream(f, 'c', 'query exists') = '' then return
  146. nomimeaddress = ''
  147. i = 0
  148. do while lines(f)
  149.    parse upper value linein(f) with a
  150.    a = strip(a)
  151.    if a = '' then iterate
  152.    if pos(left(a, 1), '#;*') > 0 then iterate
  153.    i = i + 1
  154.    nomimeaddress.i = word(a, 1)
  155. end /* do */
  156. call stream f, 'c', 'close'
  157. nomimeaddress.0 = i
  158. i = 1
  159. do while i <= header.0
  160.    select
  161.       when translate(word(header.i, 1)) = 'TO:' then i = checkdestaddress(i)
  162.       when translate(word(header.i, 1)) = 'CC:' then i = checkdestaddress(i)
  163.       when translate(word(header.i, 1)) = 'BCC:' then i = checkdestaddress(i)
  164.    otherwise
  165.       i = i + 1
  166.    end  /* select */
  167. end /* do */
  168. return
  169.  
  170. checkdestaddress: procedure expose header. nomimeaddress. nomimeisrequired
  171. arg i
  172. line = header.i
  173. i = i + 1
  174. do while i <= header.0
  175.    a = header.i
  176.    if left(a, 1) <> ' ' then leave
  177.    i = i + 1
  178.    line = line a
  179. end /* do */
  180. do j = 1 to nomimeaddress.0
  181.    n = pos(nomimeaddress.j, translate(line))
  182.    if n = 0 then iterate
  183.    nomimeisrequired = 1
  184.    leave
  185. end /* do */
  186. if nomimeisrequired = 0 then return i
  187. line = translate(subword(line, 2), ' ', '09'x)
  188. do while line <> ''
  189.    do j = 1 by 1
  190.       t = gettoken()
  191.       if t = '' | t = ',' then leave
  192.       t.j = t
  193.    end /* do */
  194.    j = j - 1
  195.    parse var t.j with '<' a '>'
  196.    if a = '' then a = t.j
  197.    do z = 1 to nomimeaddress.0
  198.       if translate(right(a, length(nomimeaddress.z))) = nomimeaddress.z then return i
  199.    end /* do */
  200. end /* do */
  201. nomimeisrequired = 0
  202. return i
  203.  
  204. gettoken: procedure expose line
  205. parse value strip(line) with t line
  206. if left(t, 1) = ',' then do
  207.    parse var t 2 a
  208.    line = a line
  209.    return t
  210. end  /* Do */
  211. zdsl = '"<'
  212. zdsr = '">'  
  213. i = pos(left(t, 1), zdsl)
  214. if i = 0 then do
  215.    i = pos(',', t)
  216.    if i = 0 then return t
  217.    if i > 1 then do
  218.       line = substr(t, i) line
  219.       t = left(t, i - 1)
  220.    end  /* Do */
  221.    else do
  222.       t = left(t, 1)
  223.       line = substr(t, 2) line
  224.    end  /* Do */
  225.    return t
  226. end  /* Do */
  227. zd = substr(zdsr, i, 1)
  228. i = 2
  229. line = t line
  230. t = ''
  231. do while line <> ''
  232.    i = pos(zd, line, i)
  233.    if i = 0 then do
  234.       t = t || line
  235.       line = ''
  236.       leave
  237.    end  /* Do */
  238.    if i = 1 then do
  239.       parse var line a 2 line
  240.       t = t || a
  241.       leave
  242.    end  /* Do */
  243.    if substr(line, i - 1, 1) <> '\' then do
  244.       a = left(line, i)
  245.       line = substr(line, i + 1)
  246.       t = t || a
  247.       if pos(left(line, 1), ' ,') > 0 then leave
  248.       t = t || gettoken()
  249.       leave
  250.    end  /* Do */
  251.    i = i + 1
  252. end /* do */
  253. return t
  254.  
  255. LoadHeader: procedure expose header.
  256. arg fn
  257. do i = 1 by 1 while lines(fn)
  258.    header.i = linein(fn)
  259.    if header.i = '' then do
  260.       header.0 = i - 1
  261.       leave
  262.    end  /* Do */
  263. end /* do */
  264. return
  265.  
  266. LoadBody: procedure expose body. iso2022jp
  267. arg fn
  268. options 'EXMODE'
  269. iso2022jp = 0
  270. do i = 1 by 1 while lines(fn)
  271.    body.i = linein(fn)
  272.    if dbvalidate(body.i) = 0 then iterate
  273.    if dbwidth(body.i) = length(body.i) then iterate
  274.    iso2022jp = 1
  275. end /* do */
  276. body.0 = i - 1
  277. return
  278.  
  279. processaddress: procedure expose nomimeisrequired header. newheader.
  280. arg i, j
  281. zi = i
  282. line = header.i
  283. i = i + 1
  284. do while i <= header.0
  285.    a = header.i
  286.    if left(a, 1) <> ' ' then leave
  287.    i = i + 1
  288.    line = line a
  289. end /* do */
  290. if dbvalidate(line) = 0 then do
  291.    do m = zi to i - 1
  292.       j = j + 1
  293.       newheader.j = header.m
  294.    end /* do */
  295.    return i j
  296. end  /* Do */
  297. options 'EXMODE'
  298. zh = word(line, 1)
  299. line = translate(subword(line, 2), ' ', '09'x)
  300. do m = 1 by 1 while line <> ''
  301.    do z = 1 by 1
  302.       t = gettoken()
  303.       if t = '' then leave
  304.       if t = ',' & z > 2 then leave
  305.       if t = ',' & z = 2 then do
  306.          if pos('@', t.1) > 0 then leave
  307.       end  /* Do */
  308.       t.z = t
  309.    end /* do */
  310.    t.0 = z - 1
  311.    n = ''
  312.    do z = 1 to t.0 - 1
  313.       if z = 2 & t.2 = ',' then n = n || t.z
  314.       else n = n t.z
  315.       say 1 t.z
  316.    end /* do */
  317.    n = strip(n)
  318.    if left(n, 1) <> '"' & n <> '' then n = '"' || n || '"'
  319.    a = t.z t
  320.    if dbwidth(n) <> length(n) then do
  321.       n = RxJisToJis(n)
  322.       if nomimeisrequired = 0 then n = '=?ISO-2022-JP?B?' || RxJisToBase64(n) || '?='
  323.    end  /* Do */
  324.    j = j + 1
  325.    if m = 1 then newheader.j = zh n a
  326.    else newheader.j = copies(' ', length(zh)) n a
  327. end /* do */
  328. return i j
  329.  
  330. processsubject: procedure expose nomimeisrequired header. newheader.
  331. parse arg i, j
  332. options 'EXMODE'
  333. do n = 1 by 1
  334.    if i > header.0 then leave
  335.    if n > 1 & left(header.i, 1) <> '' then leave
  336.    if dbvalidate(header.i) = 0 then do
  337.       j = j + 1
  338.       newheader.j = header.i
  339.       i = i + 1
  340.       iterate
  341.    end  /* Do */
  342.    if dbwidth(header.i) = length(header.i) then do
  343.       j = j + 1
  344.       newheader.j = header.i
  345.       i = i + 1
  346.       iterate
  347.    end  /* Do */
  348.    if n = 1 then parse var header.i h b
  349.    else do
  350.       h = ' '
  351.       b = header.i
  352.    end  /* Do */
  353.    b = RxJisToJis(strip(b))
  354.    j = j + 1
  355.    if nomimeisrequired then newheader.j = h b
  356.    else newheader.j = h '=?ISO-2022-JP?B?' || RxJisToBase64(b) || '?='
  357.    i = i + 1
  358. end /* do */
  359. return i j
  360.  
  361. novalue:
  362. call lineout errorlog, date('S') time() condition('C') '@' sigl
  363. call lineout errorlog, date('S') time() condition('D')
  364. call lineout errorlog, date('S') time() condition('I')
  365. call stream errorlog, 'c', 'close'
  366. exit
  367.