home *** CD-ROM | disk | FTP | other *** search
/ The Developer Connection…ice Driver Kit for OS/2 3 / DEV3-D1.ISO / editors / epm / e_macros / epm_ea.e < prev    next >
Encoding:
Text File  |  1993-08-04  |  15.0 KB  |  376 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 = itoa(peek(ea_seg, ea_ptr1+2, 2),10)
  27.       ea_valuelen = ltoa(peek(ea_seg, ea_ptr1+2, 2)\0\0,10)
  28.       ea_entrylen = ea_namelen + 5 + ea_valuelen
  29.       if name = peekz(ea_seg, ea_ptr1+4) then
  30.          ea_ptr2 = ea_ptr1+5+ea_namelen  -- Point to start of EA value
  31.          return 1
  32.       endif
  33. compile else
  34.       ea_namelen  = asc(peek(ea_seg, ea_ptr1+5, 1))
  35. ;     ea_valuelen = itoa(peek(ea_seg, ea_ptr1+6, 2),10)
  36.       ea_valuelen = ltoa(peek(ea_seg, ea_ptr1+6, 2)\0\0,10)
  37.       ea_entrylen = ltoa(peek(ea_seg, ea_ptr1, 2)\0\0,10)
  38.       if not ea_entrylen then
  39.          ea_entrylen = ea_len - ea_ptr1
  40.       endif
  41.       if name = peekz(ea_seg, ea_ptr1+8) then
  42.          ea_ptr2 = ea_ptr1+9+ea_namelen  -- Point to start of EA value
  43.          return 1
  44.       endif
  45. compile endif
  46.       ea_ptr1 = ea_ptr1 + ea_entrylen       -- Point to start of next entry
  47.    enddo
  48.  
  49.  
  50. ; Dependencies:  None
  51. defc addea, add_ea =                 -- Adds a single name / value pair to an existing EA list
  52.    parse arg name data
  53.    if name='' then
  54.       sayerror 'ADD_EA <name> <value> adds the extended attribute value specified to the current file.'
  55.       return
  56.    endif
  57.    name_len = length(name)
  58.    data_len = length(data)
  59.    ea_len_incr = 9 + name_len + data_len
  60. compile if EVERSION >= '6.00'
  61.    ea_len_incr = ((ea_len_incr+3)%4)*4;  -- align on 32bit boundary
  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.       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_buffer = atol(dynalink32(E_DLL,
  89.                                   'mymalloc',
  90.                                   atol(ea_len_incr+4), 2))
  91.  
  92.       ea_ptr  = ltoa(substr(ea_buffer, 3, 2)\0\0, 10)
  93.  
  94.       r = 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.  
  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.    poke ea_ptr, ea_ofs+4, \0              -- flag byte
  133.    poke ea_ptr, ea_ofs+5, chr(name_len)
  134.    poke ea_ptr, ea_ofs+6, atoi(data_len + 4)     -- Value length = len(data) + len(data_type) + len(data_len)
  135.    poke ea_ptr, ea_ofs+8, name
  136.    poke ea_ptr, ea_ofs+8+name_len, \0     -- Null byte after name
  137.    poke ea_ptr, ea_ofs+9+name_len, EAT_ASCII
  138.    poke ea_ptr, ea_ofs+11+name_len, atoi(data_len)
  139.    poke ea_ptr, ea_ofs+13+name_len, data
  140. compile endif
  141.    .eaarea = mpfrom2short(ea_ptr,0)
  142.  
  143.  
  144. ; Dependencies:  find_ea
  145. defproc get_EAT_ASCII_value(name) =  -- Returns the value for a given attribute name
  146.    if find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
  147.       stuff = peek(ea_seg, ea_ptr2, min(ea_valuelen,4))
  148.       if leftstr(stuff,2) = EAT_ASCII & ea_valuelen > 4 then
  149.          return peek(ea_seg, ea_ptr2+4, min(itoa(substr(stuff,3,2),10),MAXCOL))
  150.       endif
  151.    endif
  152.  
  153.  
  154. ; Dependencies:  find_ea()
  155. defproc delete_ea(name) =
  156.    parse arg name .
  157.    if not find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
  158.       return
  159.    endif
  160.    newlen = ea_len - ea_entrylen
  161.    poke ea_seg, ea_ofs, atol(newlen)
  162. compile if EVERSION < '5.21'
  163.    junk = 'junk'  -- Avoid problem due to bug in MEMCPYX in EPM 5.20
  164. compile endif
  165.    if ea_ptr1+ea_entrylen < ea_len then  -- If in the middle, close it up
  166.       call memcpyx(atoi(ea_ptr1) || atoi(ea_seg), atoi(ea_ptr1+ea_entrylen) || atoi(ea_seg), ea_len - ea_ptr1 - ea_entrylen)
  167.    endif
  168. compile if EPM32
  169. --   call dynalink32('DOSCALLS',
  170. --                   '#305',                -- DosSetMem
  171. --                   atol(ea_seg\0\0) ||
  172. --                   atol(.eaarea) ||
  173. --                   atol(newlen)  ||
  174. --                   atol(19) )             -- PAG_READ | PAG_WRITE | PAG_COMMIT
  175.    call dynalink32(E_DLL,
  176.                   'myrealloc',
  177.                   \0\0 || ea_seg ||
  178.                   atol(newlen) ||
  179.                   atol(0),
  180.                   2)
  181.  
  182.       r = 0
  183. compile else
  184.    call dynalink('DOSCALLS',           -- Dynamic link library name
  185.             '#38',                     -- DosReAllocSeg
  186.             atoi(newlen)           ||  -- Number of bytes requested
  187.             atoi(ea_seg) )
  188. compile endif  -- EPM32
  189.  
  190.  
  191. ; Dependencies:  find_ea(), delete_ea(), add_ea
  192. defc type =
  193.    found = find_ea('.TYPE', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
  194.    if not found | ea_valuelen=0 then
  195.       answer = winmessagebox(TYPE_TITLE__MSG, NO_FILE_TYPE__MSG, 16388) -- YESNO + MOVEABLE
  196.    elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
  197. ;     type = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), MAXCOL))
  198.       type = peek(ea_seg, ea_ptr2+4, min(ltoa(peek(ea_seg, ea_ptr2+2, 2)\0\0, 10), MAXCOL))
  199.       answer = winmessagebox(TYPE_TITLE__MSG, ONE_FILE_TYPE__MSG\13 type\13\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  200.    elseif peek(ea_seg, ea_ptr2, 2)=EAT_MVMT then
  201. ;     ea_numentries = itoa(peek(ea_seg, ea_ptr2+4, 2),10)
  202.       ea_numentries = ltoa(peek(ea_seg, ea_ptr2+4, 2)\0\0,10)
  203.       if ea_numentries=1 then
  204.          type = ONE_FILE_TYPE__MSG
  205.       else
  206.          type = MANY_FILE_TYPES__MSG
  207.       endif
  208.       ea_entry_ofs = ea_ptr2+6
  209.       do i=1 to ea_numentries
  210. ;        ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs+2, 2),10)
  211.          ea_entrylen = ltoa(peek(ea_seg, ea_entry_ofs+2, 2)\0\0,10)
  212.          if peek(ea_seg, ea_entry_ofs, 2)=EAT_ASCII then
  213.             type = type\13 || peek(ea_seg, ea_entry_ofs+4,min(ea_entrylen,MAXCOL))
  214.          else
  215.             type = type\13 || NON_ASCII__MSG
  216.          endif
  217.          ea_entry_ofs = ea_entry_ofs + ea_entrylen + 4
  218.       enddo
  219.       answer = winmessagebox(TYPE_TITLE__MSG, type\13\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  220.    else
  221.       answer = winmessagebox(TYPE_TITLE__MSG, NON_ASCII_TYPE__MSG\13CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  222.    endif
  223.    if answer=6 then
  224. compile if EVERSION < 5.21
  225.       newtype = listbox(SELECT_TYPE__MSG, TYPE_LIST__MSG)
  226.       if newtype then
  227. compile else
  228.       parse value listbox(TYPE_TITLE__MSG, TYPE_LIST__MSG, '/'SET__MSG'/'CANCEL__MSG'/'HELP__MSG, 0, 0, 0, 0,
  229.  compile if EVERSION >= 5.60
  230.                           gethwndc(APP_HANDLE) || atoi(1) || atoi(1) || atoi(6040) ||
  231.  compile else
  232.                           atoi(1) || atoi(1) || atoi(6040) || gethwndc(APP_HANDLE) ||
  233.  compile endif
  234.                           SELECT_TYPE__MSG) with button 2 newtype \0
  235.       if newtype & (button=\1) then
  236. compile endif  -- EVERSION < 5.21
  237.          if found then call delete_ea('.TYPE'); endif
  238.          'add_ea .TYPE' newtype
  239.       endif
  240.    endif
  241.  
  242.  
  243. ; Dependencies:  find_ea(), delete_ea(), add_ea
  244. defc subject =
  245. compile if EPATH = 'LAMPATH'
  246.    universal inboxpath
  247.    parse value .userstring with '(' spid ')'
  248.    if spid='' then
  249. compile endif -- EPATH = 'LAMPATH'
  250.       subj = ''
  251. compile if EPATH = 'LAMPATH'
  252.    else
  253.       subj = find_subj()
  254.    endif
  255. compile endif -- EPATH = 'LAMPATH'
  256.    found = find_ea('.SUBJECT', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
  257.    if arg(1)='' then
  258.       max_len = MAXCOL - length(SUBJECT_IS__MSG) - length(CHANGE_QUERY__MSG) - 5
  259.       if not found | ea_valuelen=0 then
  260. compile if EPATH = 'LAMPATH'
  261.          if subj='' | upcase(subj)='NO SUBJECT' then
  262. compile endif -- EPATH = 'LAMPATH'
  263.             answer = winmessagebox(SUBJ_TITLE__MSG, NO_SUBJECT__MSG, 16388) -- YESNO + MOVEABLE
  264. compile if EPATH = 'LAMPATH'
  265.          else
  266.             newsubj = subj
  267.             if length(subj)>max_len then
  268.                newsubj = leftstr(subj, max_len-3)'...'
  269.             endif
  270.             answer = winmessagebox(SUBJ_TITLE__MSG, SUBJECT_IS__MSG\13 newsubj\13\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  271.          endif
  272. compile endif -- EPATH = 'LAMPATH'
  273.       elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
  274.          subj = peek(ea_seg, ea_ptr2+4, min(ltoa(peek(ea_seg, ea_ptr2+2, 2)\0\0, 10), MAXCOL))
  275.          newsubj = subj
  276.          if length(subj)>max_len then
  277.             newsubj = leftstr(subj, max_len-3)'...'
  278.          endif
  279.          answer = winmessagebox(SUBJ_TITLE__MSG, SUBJECT_IS__MSG\13 newsubj\13\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  280.       else
  281.          answer = winmessagebox(SUBJ_TITLE__MSG, NON_ASCII_SUBJECT__MSG\13||CHANGE_QUERY__MSG, 16388) -- YESNO + MOVEABLE
  282.       endif
  283.    else  -- arg(1) not null
  284.       answer = 6
  285.    endif
  286.    if answer=6 then
  287. compile if EVERSION < 5.21  -- The old way
  288.       if arg(1)='' then
  289.          newsubj = entrybox(SELECT_SUBJECT__MSG, '', subj, 40, 230)
  290.       else
  291.          newsubj = arg(1)
  292.       endif
  293.       if newsubj then
  294. compile else
  295.       if arg(1)='' then
  296.          parse value entrybox(SUBJ_TITLE__MSG, '/'SET__MSG'/'CANCEL__MSG'/'HELP__MSG, subj, 40,
  297.  compile if EVERSION >= 5.60 -- long strings
  298.                 260,
  299.  compile else
  300.                 230,  -- 255 limit on strings; must leave room for 'add_ea...'
  301.  compile endif
  302.                 atoi(1) || atoi(6050) || gethwndc(APP_HANDLE) || SELECT_SUBJECT__MSG) with button 2 newsubj \0
  303.       else
  304.          newsubj = arg(1)
  305.          button = \1
  306.       endif
  307.       if newsubj & (button=\1) then
  308. compile endif
  309.          if found then call delete_ea('.SUBJECT'); endif
  310.          'add_ea .SUBJECT' newsubj
  311. compile if EPATH = 'LAMPATH'
  312.          if spid<>'' then
  313.             if not .modify then 'save /q'; endif  -- If file not modified, save new EA, otherwise, let user save it.
  314.             i = lastpos('\',spid)
  315.             if not i then                -- Unexpected error
  316.                sayerror 'Bad spoolid.'
  317.                return
  318.             endif
  319.             getfileid startid
  320.             path = upcase(leftstr(spid,i-1))
  321.             if path=inboxpath then
  322.                indxname = path'\inbox.ndx'
  323.             else
  324.                indxname = path'.ndx'
  325.             endif
  326.             display -2
  327.             success = lock_index(indxname)
  328.             display 2
  329.             if not success then
  330.                sayerror 'Failed to lock index file.'
  331.                return
  332.             endif
  333.             if rc=sayerror('New file') or rc=sayerror('Lines truncated') or (not rc & not .last) then
  334.                call free_index()
  335.                return
  336.             endif
  337.             getfileid fid
  338.             if rc then
  339.                if startid<>fid then call free_index(); endif
  340.                return
  341.             endif
  342.             getsearch oldsearch
  343.             call psave_mark(savemark)
  344.             0
  345.             call pset_mark(1, .last, 28, 44, 'BLOCK', fid)
  346.             parse value substr(spid,i+1) with filename '.' filetype
  347.             display -2
  348.             'xcom l /'leftstr(filename,8) leftstr(filetype,8)'/cm'
  349.             lrc = rc
  350.             display 2
  351.             call prestore_mark(savemark)
  352.             setsearch oldsearch
  353.             retval = ''
  354.             if not lrc then
  355.                getline line
  356.                subjstart = pos('', line, 84)
  357.                subjend = pos('', line, subjstart+1)
  358.                if subjstart & subjend then
  359.  compile if EVERSION >= 5.60
  360.                   line = insertstr(newsubj, delstr(line, subjstart+1, subjend-subjstart-1), subjstart)
  361.  compile else  -- Must limit index line to 255 characters.
  362.                   line = insertstr(newsubj, delstr(line, subjstart+1, subjend-subjstart-1), subjstart, min(length(newsubj), 255-length(line)+(subjend-subjstart-1)))
  363.  compile endif
  364.                   replaceline line, .line
  365.                   call fn2spoolid(startid.filename, spoolid)
  366.                   call LAM_SPOOL_CMD(5505, spoolid, line)   -- x1581; LAM VIEWED
  367.                   sayerror 'Subject updated in index file.'
  368.                endif
  369.             endif
  370.             call free_index()
  371.             activatefile startid
  372.          endif  -- spid<>''
  373. compile endif -- EPATH = 'LAMPATH'
  374.       endif  -- newsubj
  375.    endif  -- answer = 'YES'
  376.