home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / epmmac.zip / EPM_EA.E < prev    next >
Text File  |  1995-04-07  |  16KB  |  379 lines

  1. ; Various routines used for manipulating extended attributes.  Used by EPM.
  2.  
  3. const
  4.    EAT_ASCII    = \253\255    -- FFFD
  5.    EAT_MVMT     = \223\255    -- FFDF
  6.  
  7. ;  Returns 1 if attribute name exists; sets VAR args.  EA_SEG, EA_OFS =
  8. ; start of EA buffer.  EA_PTR1, 2 = pointers to start of entry and value,
  9. ; respectively, if name was found.  EA_LEN, EA_ENTRYLEN, EA_VALUELEN = length
  10. ; of EA area, of entry, and of value, respectively.
  11. ; Dependencies:  None
  12. defproc find_ea(name, var ea_seg, var ea_ofs, var ea_ptr1, var ea_ptr2, var ea_len, var ea_entrylen, var ea_valuelen) =
  13.    ea_long = atol(.eaarea)
  14. ;  ea_seg = itoa(rightstr(ea_long,2),10)
  15.    ea_seg = ltoa(rightstr(ea_long,2)\0\0,10)
  16. ;  ea_ofs = itoa(leftstr(ea_long,2),10)
  17.    ea_ofs = ltoa(leftstr(ea_long,2)\0\0,10)
  18.    if not .eaarea then return ''; endif
  19.    ea_len  = ltoa(peek(ea_seg, ea_ofs, 4),10)
  20.    ea_end = ea_ofs + ea_len
  21.    ea_ptr1 = ea_ofs + 4                     -- Point past length of FEAList
  22.    do while ea_ptr1 < ea_len
  23. ;     ea_flag = itoa(peek(ea_seg, ea_ptr1, 1)\0,16)
  24. compile if EVERSION < '6.00'
  25.       ea_namelen  = asc(peek(ea_seg, ea_ptr1+1, 1))
  26.       ea_valuelen = ltoa(peek(ea_seg, ea_ptr1+2, 2)\0\0,10)
  27.       ea_entrylen = ea_namelen + 5 + ea_valuelen
  28.       if name = peekz(ea_seg, ea_ptr1+4) then
  29.          ea_ptr2 = ea_ptr1+5+ea_namelen  -- Point to start of EA value
  30.          return 1
  31.       endif
  32. compile else
  33.       ea_namelen  = asc(peek(ea_seg, ea_ptr1+5, 1))
  34.       ea_valuelen = ltoa(peek(ea_seg, ea_ptr1+6, 2)\0\0,10)
  35. ;     ea_entrylen = ltoa(peek(ea_seg, ea_ptr1, 4),10)
  36. ;     if not ea_entrylen then
  37. ;        ea_entrylen = ea_len - ea_ptr1
  38. ;     endif
  39.       ea_entrylen = (ea_namelen + 12 + ea_valuelen)%4*4  -- ((namelen+9+valuelen)+3)%4*4
  40.       if name = peekz(ea_seg, ea_ptr1+8) then
  41.          ea_ptr2 = ea_ptr1+9+ea_namelen  -- Point to start of EA value
  42.          return 1
  43.       endif
  44. compile endif
  45.       ea_ptr1 = ea_ptr1 + ea_entrylen       -- Point to start of next entry
  46.    enddo
  47.  
  48.  
  49. ; Dependencies:  None
  50. defc addea, add_ea =                 -- Adds a single name / value pair to an existing EA list
  51.    parse arg name data
  52.    if name='' then
  53.       sayerror 'ADD_EA <name> <value> adds the extended attribute value specified to the current file.'
  54.       return
  55.    endif
  56.    name_len = length(name)
  57.    data_len = length(data)
  58. compile if EPM32
  59.    ea_len_incr = ((16 + name_len + data_len)%4)*4;  -- align on 32bit boundary (+13 for overhead +3 for rounding)
  60. compile else
  61.    ea_len_incr = 9 + name_len + data_len
  62. compile endif
  63.    if .eaarea then
  64.       ea_long = atol(.eaarea)
  65. ;     ea_seg = itoa(rightstr(ea_long,2),10)
  66.       ea_seg = ltoa(rightstr(ea_long,2)\0\0,10)
  67. ;     ea_ofs = itoa(leftstr(ea_long,2),10)
  68.       ea_ofs = ltoa(leftstr(ea_long,2)\0\0,10)
  69.       ea_old_len  = ltoa(peek(ea_seg, ea_ofs, 4),10)
  70. compile if EPM32
  71.       call dynalink32(E_DLL,
  72.                       'myrealloc',
  73.                       ea_long ||
  74.                       atol(ea_old_len+ea_len_incr) ||
  75.                       atol(0),
  76.                       2)
  77.  
  78.       r = 0
  79. compile else
  80.       r =  dynalink('DOSCALLS',           -- Dynamic link library name
  81.                '#38',                     -- DosReAllocSeg
  82.                atoi(ea_old_len+ea_len_incr) ||  -- Number of bytes requested
  83.                rightstr(ea_long,2) )
  84. compile endif  -- EPM32
  85.       ea_ptr = ea_seg
  86.    else
  87. compile if EPM32
  88.       ea_ptr = atol(dynalink32(E_DLL,
  89.                                'mymalloc',
  90.                                atol(ea_len_incr+4), 2))
  91. ;compile if not POWERPC
  92.       ea_ptr  = ltoa(substr(ea_ptr, 3, 2)\0\0, 10)
  93. ;compile endif
  94.       r = -270 * (ea_ptr = 0)
  95. compile else
  96.       ea_buffer = "00"                    -- Initialize string pointer.
  97.       r =  dynalink('DOSCALLS',           -- Dynamic link library name
  98.                '#34',                     -- DosAllocSeg
  99.                atoi(ea_len_incr+4)    ||  -- Number of bytes requested
  100.                address(ea_buffer)     ||
  101.                atoi(0) )                  -- Share information
  102. ;     ea_ptr = itoa(ea_buffer,10)
  103.       ea_ptr = ltoa(ea_buffer\0\0,10)
  104. compile endif  -- EPM32
  105.       ea_ofs = 0
  106.       ea_old_len  = 4           -- Point past length field
  107.    endif
  108.  
  109.    if r then sayerror ERROR__MSG r ALLOC_HALTED__MSG; stop; endif
  110.    poke ea_ptr, ea_ofs, atol(ea_old_len+ea_len_incr)
  111.    ea_ofs = ea_ofs + ea_old_len
  112. compile if EVERSION < '6.00'
  113.    poke ea_ptr, ea_ofs  , \0              -- Start of EA:  flag byte
  114.    poke ea_ptr, ea_ofs+1, chr(name_len)
  115.    poke ea_ptr, ea_ofs+2, atoi(data_len + 4)     -- Value length = len(data) + len(data_type) + len(data_len)
  116.    poke ea_ptr, ea_ofs+4, name
  117.    poke ea_ptr, ea_ofs+4+name_len, \0     -- Null byte after name
  118.    poke ea_ptr, ea_ofs+5+name_len, EAT_ASCII
  119.    poke ea_ptr, ea_ofs+7+name_len, atoi(data_len)
  120.    poke ea_ptr, ea_ofs+9+name_len, data
  121. compile else
  122.  compile if 0  -- C code does this internally, when saving.
  123.    -- we need to make sure the last entry is marked with zero length
  124.    --   to find the last entry, just look for
  125.    --   a bogus entry.  "\1\2\4\3\5" seems pretty unlikely.
  126.    call find_ea("\1\2\4\3\5", xx_seg, xx_ofs, xx_ptr1, xx_ptr2, xx_len, xx_entrylen, xx_valuelen);
  127.    if (xx_len>4) and xx_entrylen then
  128.       poke ea_ptr, xx_len-xx_entrylen, atol(xx_entrylen);
  129.    endif
  130.  
  131.    poke ea_ptr, ea_ofs+0, atol(0) -- Start of EA:  size (last one is always marked as zero)
  132.  compile else
  133.  
  134.    poke ea_ptr, ea_ofs, atol(ea_len_incr) -- Start of EA:  size
  135.  compile endif
  136.  
  137.    poke ea_ptr, ea_ofs+4, \0              -- flag byte
  138.    poke ea_ptr, ea_ofs+5, chr(name_len)
  139.    poke ea_ptr, ea_ofs+6, atoi(data_len + 4)     -- Value length = len(data) + len(data_type) + len(data_len)
  140.    poke ea_ptr, ea_ofs+8, name
  141.    poke ea_ptr, ea_ofs+8+name_len, \0     -- Null byte after name
  142.    poke ea_ptr, ea_ofs+9+name_len, EAT_ASCII
  143.    poke ea_ptr, ea_ofs+11+name_len, atoi(data_len)
  144.    poke ea_ptr, ea_ofs+13+name_len, data
  145. compile endif
  146.    .eaarea = mpfrom2short(ea_ptr,0)
  147.  
  148.  
  149. ; Dependencies:  find_ea
  150. defproc get_EAT_ASCII_value(name) =  -- Returns the value for a given attribute name
  151.    if find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
  152.       stuff = peek(ea_seg, ea_ptr2, min(ea_valuelen,4))
  153.       if leftstr(stuff,2) = EAT_ASCII & ea_valuelen > 4 then
  154.          return peek(ea_seg, ea_ptr2+4, min(itoa(substr(stuff,3,2),10),MAXCOL))
  155.       endif
  156.    endif
  157.  
  158.  
  159. ; Dependencies:  find_ea()
  160. defproc delete_ea(name) =
  161.    parse arg name .
  162.    if not find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
  163.       return
  164.    endif
  165.    newlen = ea_len - ea_entrylen
  166.    poke ea_seg, ea_ofs, atol(newlen)
  167. compile if EVERSION < '5.21'
  168.    junk = 'junk'  -- Avoid problem due to bug in MEMCPYX in EPM 5.20
  169. compile endif
  170.    if ea_ptr1+ea_entrylen < ea_len then  -- If in the middle, close it up
  171.       call memcpyx(atoi(ea_ptr1) || atoi(ea_seg), atoi(ea_ptr1+ea_entrylen) || atoi(ea_seg), ea_len - ea_ptr1 - ea_entrylen)
  172.    endif
  173. compile if EPM32
  174. --   call dynalink32('DOSCALLS',
  175. --                   '#305',                -- DosSetMem
  176. --                   atol(ea_seg\0\0) ||
  177. --                   atol(.eaarea) ||
  178. --                   atol(newlen)  ||
  179. --                   atol(19) )             -- PAG_READ | PAG_WRITE | PAG_COMMIT
  180.    call dynalink32(E_DLL,
  181.                   'myrealloc',
  182.                   \0\0 || atoi(ea_seg) ||
  183.                   atol(newlen) ||
  184.                   atol(0),
  185.                   2)
  186. compile else
  187.    call dynalink('DOSCALLS',           -- Dynamic link library name
  188.             '#38',                     -- DosReAllocSeg
  189.             atoi(newlen)           ||  -- Number of bytes requested
  190.             atoi(ea_seg) )
  191. compile endif  -- EPM32
  192.  
  193.  
  194. ; Dependencies:  find_ea(), delete_ea(), add_ea
  195. defc type =
  196.    found = find_ea('.TYPE', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
  197.    if not found | ea_valuelen=0 then
  198.       answer = winmessagebox(TYPE_TITLE__MSG, NO_FILE_TYPE__MSG, 16388) -- YESNO + MOVEABLE
  199.    elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
  200. ;     type = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), MAXCOL))
  201.       type = peek(ea_seg, ea_ptr2+4, min(ltoa(peek(ea_seg, ea_ptr2+2, 2)\0\0, 10), MAXCOL))
  202.       answer = winmessagebox(TYPE_TITLE__MSG, ONE_FILE_TYPE__MSG\13 type\13\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  203.    elseif peek(ea_seg, ea_ptr2, 2)=EAT_MVMT then
  204. ;     ea_numentries = itoa(peek(ea_seg, ea_ptr2+4, 2),10)
  205.       ea_numentries = ltoa(peek(ea_seg, ea_ptr2+4, 2)\0\0,10)
  206.       if ea_numentries=1 then
  207.          type = ONE_FILE_TYPE__MSG
  208.       else
  209.          type = MANY_FILE_TYPES__MSG
  210.       endif
  211.       ea_entry_ofs = ea_ptr2+6
  212.       do i=1 to ea_numentries
  213. ;        ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs+2, 2),10)
  214.          ea_entrylen = ltoa(peek(ea_seg, ea_entry_ofs+2, 2)\0\0,10)
  215.          if peek(ea_seg, ea_entry_ofs, 2)=EAT_ASCII then
  216.             type = type\13 || peek(ea_seg, ea_entry_ofs+4,min(ea_entrylen,MAXCOL))
  217.          else
  218.             type = type\13 || NON_ASCII__MSG
  219.          endif
  220.          ea_entry_ofs = ea_entry_ofs + ea_entrylen + 4
  221.       enddo
  222.       answer = winmessagebox(TYPE_TITLE__MSG, type\13\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  223.    else
  224.       answer = winmessagebox(TYPE_TITLE__MSG, NON_ASCII_TYPE__MSG\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  225.    endif
  226.    if answer=6 then
  227. compile if EVERSION < 5.21
  228.       newtype = listbox(SELECT_TYPE__MSG, TYPE_LIST__MSG)
  229.       if newtype then
  230. compile else
  231.       parse value listbox(TYPE_TITLE__MSG, TYPE_LIST__MSG, '/'SET__MSG'/'CANCEL__MSG'/'HELP__MSG, 0, 0, 0, 0,
  232.  compile if EVERSION >= 5.60
  233.                           gethwndc(APP_HANDLE) || atoi(1) || atoi(1) || atoi(6040) ||
  234.  compile else
  235.                           atoi(1) || atoi(1) || atoi(6040) || gethwndc(APP_HANDLE) ||
  236.  compile endif
  237.                           SELECT_TYPE__MSG) with button 2 newtype \0
  238.       if newtype & (button=\1) then
  239. compile endif  -- EVERSION < 5.21
  240.          if found then call delete_ea('.TYPE'); endif
  241.          'add_ea .TYPE' newtype
  242.       endif
  243.    endif
  244.  
  245.  
  246. ; Dependencies:  find_ea(), delete_ea(), add_ea
  247. defc subject =
  248. compile if EPATH = 'LAMPATH'
  249.    universal inboxpath
  250.    parse value .userstring with '(' spid ')'
  251.    if spid='' then
  252. compile endif -- EPATH = 'LAMPATH'
  253.       subj = ''
  254. compile if EPATH = 'LAMPATH'
  255.    else
  256.       subj = find_subj()
  257.    endif
  258. compile endif -- EPATH = 'LAMPATH'
  259.    found = find_ea('.SUBJECT', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
  260.    if arg(1)='' then
  261.       max_len = MAXCOL - length(SUBJECT_IS__MSG) - length(CHANGE_QUERY__MSG) - 5
  262.       if not found | ea_valuelen=0 then
  263. compile if EPATH = 'LAMPATH'
  264.          if subj='' | upcase(subj)='NO SUBJECT' then
  265. compile endif -- EPATH = 'LAMPATH'
  266.             answer = winmessagebox(SUBJ_TITLE__MSG, NO_SUBJECT__MSG, 16388) -- YESNO + MOVEABLE
  267. compile if EPATH = 'LAMPATH'
  268.          else
  269.             newsubj = subj
  270.             if length(subj)>max_len then
  271.                newsubj = leftstr(subj, max_len-3)'...'
  272.             endif
  273.             answer = winmessagebox(SUBJ_TITLE__MSG, SUBJECT_IS__MSG\13 newsubj\13\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  274.          endif
  275. compile endif -- EPATH = 'LAMPATH'
  276.       elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
  277.          subj = peek(ea_seg, ea_ptr2+4, min(ltoa(peek(ea_seg, ea_ptr2+2, 2)\0\0, 10), MAXCOL))
  278.          newsubj = subj
  279.          if length(subj)>max_len then
  280.             newsubj = leftstr(subj, max_len-3)'...'
  281.          endif
  282.          answer = winmessagebox(SUBJ_TITLE__MSG, SUBJECT_IS__MSG\13 newsubj\13\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  283.       else
  284.          answer = winmessagebox(SUBJ_TITLE__MSG, NON_ASCII_SUBJECT__MSG\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  285.       endif
  286.    else  -- arg(1) not null
  287.       answer = 6
  288.    endif
  289.    if answer=6 then
  290. compile if EVERSION < 5.21  -- The old way
  291.       if arg(1)='' then
  292.          newsubj = entrybox(SELECT_SUBJECT__MSG, '', subj, 40, 230)
  293.       else
  294.          newsubj = arg(1)
  295.       endif
  296.       if newsubj then
  297. compile else
  298.       if arg(1)='' then
  299.          parse value entrybox(SUBJ_TITLE__MSG, '/'SET__MSG'/'CANCEL__MSG'/'HELP__MSG, subj, 40,
  300.  compile if EVERSION >= 5.60 -- long strings
  301.                 260,
  302.  compile else
  303.                 230,  -- 255 limit on strings; must leave room for 'add_ea...'
  304.  compile endif
  305.                 atoi(1) || atoi(6050) || gethwndc(APP_HANDLE) || SELECT_SUBJECT__MSG) with button 2 newsubj \0
  306.       else
  307.          newsubj = arg(1)
  308.          button = \1
  309.       endif
  310.       if newsubj & (button=\1) then
  311. compile endif
  312.          if found then call delete_ea('.SUBJECT'); endif
  313.          'add_ea .SUBJECT' newsubj
  314. compile if EPATH = 'LAMPATH'
  315.          if spid<>'' then
  316.             if not .modify then 'save /q'; endif  -- If file not modified, save new EA, otherwise, let user save it.
  317.             i = lastpos('\',spid)
  318.             if not i then                -- Unexpected error
  319.                sayerror 'Bad spoolid.'
  320.                return
  321.             endif
  322.             getfileid startid
  323.             path = upcase(leftstr(spid,i-1))
  324.             if path=inboxpath then
  325.                indxname = path'\inbox.ndx'
  326.             else
  327.                indxname = path'.ndx'
  328.             endif
  329.             display -2
  330.             success = lock_index(indxname)
  331.             display 2
  332.             if not success then
  333.                sayerror 'Failed to lock index file.'
  334.                return
  335.             endif
  336.             if rc=sayerror('New file') or rc=sayerror('Lines truncated') or (not rc & not .last) then
  337.                call free_index()
  338.                return
  339.             endif
  340.             getfileid fid
  341.             if rc then
  342.                if startid<>fid then call free_index(); endif
  343.                return
  344.             endif
  345.             getsearch oldsearch
  346.             call psave_mark(savemark)
  347.             0
  348.             call pset_mark(1, .last, 28, 44, 'BLOCK', fid)
  349.             parse value substr(spid,i+1) with filename '.' filetype
  350.             display -2
  351.             'xcom l /'leftstr(filename,8) leftstr(filetype,8)'/cm'
  352.             lrc = rc
  353.             display 2
  354.             call prestore_mark(savemark)
  355.             setsearch oldsearch
  356.             retval = ''
  357.             if not lrc then
  358.                getline line
  359.                subjstart = pos('', line, 84)
  360.                subjend = pos('', line, subjstart+1)
  361.                if subjstart & subjend then
  362.  compile if EVERSION >= 5.60
  363.                   line = insertstr(newsubj, delstr(line, subjstart+1, subjend-subjstart-1), subjstart)
  364.  compile else  -- Must limit index line to 255 characters.
  365.                   line = insertstr(newsubj, delstr(line, subjstart+1, subjend-subjstart-1), subjstart, min(length(newsubj), 255-length(line)+(subjend-subjstart-1)))
  366.  compile endif
  367.                   replaceline line, .line
  368.                   call fn2spoolid(startid.filename, spoolid)
  369.                   call LAM_SPOOL_CMD(5505, spoolid, line)   -- x1581; LAM VIEWED
  370.                   sayerror 'Subject updated in index file.'
  371.                endif
  372.             endif
  373.             call free_index()
  374.             activatefile startid
  375.          endif  -- spid<>''
  376. compile endif -- EPATH = 'LAMPATH'
  377.       endif  -- newsubj
  378.    endif  -- answer = 'YES'
  379.