home *** CD-ROM | disk | FTP | other *** search
- ; Routines for manipulating extended attributes.
- ;
- ; EPM's .eaarea field contains a pointer to a buffer containing the
- ; extended attributes for the current file. This is an FEALIST; see
- ; the OS/2 Tech Ref for details. If the file was loaded from disk,
- ; the .eaarea will *always* contain a pointer to an FEALIST. If the
- ; file had no extended attributes, this FEALIST will contain nothing
- ; but a length field indicating an FEALIST length of 4.
- ;
- ; A newly created file in the editor will contain a .eaarea of 0 - i.e.
- ; a null pointer, indicating that the FEALIST does not exist.
- ;
- ; Don't forget - changing the .eaarea field or adding extended attributes
- ; does not affect the .modify field. If you want to ensure that the
- ; attributes are saved, you may want to explicitly increment .modify in
- ; your routines.
- ;
- ; by Larry Margolis
-
- ; Note: This file contains some duplicated and redundant functions; it's a
- ; toolkit of routines for playing with extended attributes. Extract what you
- ; need for your application. The "Dependencies" comment before each routine
- ; tells what other pieces you need from this file. Dependencies on routines
- ; from the base set of macros (e.g., entrybox(), winmessagebox() ) are not
- ; mentioned. Note that some of these routines are included in EPM_EA which
- ; is part of the base set of macros.
- ;
- ; Index:
- ; QEA Tells what the .eaarea is set to
- ; SHOW_EA Displays all extended attributes
- ; GET_EA Tells you the value for a given attribute name
- ; get_ea_value() Returns the value for a given attribute name
- ; get_ea_value2() As above, but uses find_ea() & only handles EAT_ASCII
- ; find_ea() Looks for a given attribute; sets lots of VAR parameters
- ; SET_EA Sets a single name / value pair in an empty .eaarea
- ; SET_EA_MANY Sets a number of name / value pairs in an empty .eaarea
- ; ADD_EA Adds a single name / value pair to an existing EA list
- ; GET_EA2 Like GET_EA, but uses find_ea() instead of get_ea_value()
- ; DELETE_EA Deletes a named extended attribute
- ; delete_ea() Deletes a named extended attribute
- ; TYPE Displays and optionally sets the .TYPE extended attribute
- ; SETFILETYPE Sets the .TYPE extended attribute to anything
- ; SUBJECT Displays and optionally sets the .SUBJECT extended attribute
- ; PUTFIELD Store a field (.filename, .userstring, etc.) in an EA.
- ; GETFIELD Set a field from the value previously saved in the EA.
-
- const -- Some constants
- EAT_BINARY = \254\255 -- FFFE
- EAT_ASCII = \253\255 -- FFFD
- EAT_BITMAP = \251\255 -- FFFB
- EAT_METAFILE = \250\255 -- FFFA
- EAT_ICON = \249\255 -- FFF9
- EAT_EA = \238\255 -- FFEE
- EAT_MVMT = \223\255 -- FFDF
- EAT_MVST = \222\255 -- FFDE
- EAT_ASN1 = \221\255 -- FFDD
-
- -- Just see what the .eaarea is set to.
- ; Dependencies: None
- defc qea = sayerror '.eaarea = '.eaarea '= x'ltoa(atol(.eaarea),16)
-
- ; Dependencies: None
- defc showea, show_ea = -- Show all extended attributes
- if abbrev('FILE', upcase(arg(1)), 1) then -- 'ShowEA F' to dump to a file
- file_flag = 1
- 'xcom e /n'
- if rc<>-282 then sayerror 'Could not open output file!'; return rc; endif
- getfileid fid
- .autosave = 0
- prevfile
- fid.titletext = '.eaarea of "'.filename'"'
- else
- file_flag = 0
- fid = ''
- endif
- ; ea_seg = .eaarea % 65536
- ; ea_ofs = .eaarea // 65536
- ea_long = atol(.eaarea)
- ea_seg = itoa(rightstr(ea_long,2),10)
- ea_ofs = itoa(leftstr(ea_long,2),10)
- if .eaarea then
- ea_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
- ; insertline peek(ea_seg, ea_ofs, min(ea_len,255)), .last+1
- else
- ea_len = 0
- endif
- ea_output(file_flag, '.eaarea = '.eaarea '= x'ltoa(ea_long,16)'; ea_seg =' ea_seg '= x'itoa(atoi(ea_seg),16)'; ea_ofs =' ea_ofs'; ea_len = 'ea_len, fid)
- ea_count = 0
- ea_end = ea_ofs + ea_len
- ea_ofs = ea_ofs + 4 -- Point past length of FEAList
- do while ea_ofs < ea_len
- ea_flag = itoa(peek(ea_seg, ea_ofs, 1)\0,16)
- ea_namelen = asc(peek(ea_seg, ea_ofs+1, 1))
- ea_valuelen = ltoa(peek(ea_seg, ea_ofs+2, 2)\0\0,10)
- ea_name = peekz(ea_seg, ea_ofs+4)
- if ea_valuelen then
- ea_value = peek(ea_seg, ea_ofs+5+ea_namelen,min(ea_valuelen,255))
- ea_datatype = rightstr(itoa(leftstr(ea_value,2),16),4,0)
- ea_datalen = itoa(substr(ea_value,3,2),10)
- ea_data = substr(ea_value,5)
- else
- ea_value = ''
- ea_datatype = '????'
- ea_datalen = 0
- ea_data = ''
- endif
- ea_count = ea_count + 1
- if leftstr(ea_value,2) = EAT_MVMT then
- ea_output(file_flag, 'EA' ea_count 'flag=x'ea_flag 'name('ea_namelen')="'ea_name'"; type=x'ea_datatype' (MVMT); value('ea_valuelen') =', fid)
- ea_codepage = ea_datalen
- ea_numentries = itoa(leftstr(ea_data,2),10)
- if ea_numentries=1 then
- ea_entrylen = itoa(substr(ea_data,5,2),10)
- ea_output(file_flag, 'CP' ea_codepage '1 entry: type=x'rightstr(itoa(substr(ea_data,3,2),16),4,0)'; len='ea_entrylen'; "'substr(ea_data,7,ea_entrylen)'"', fid)
- else
- ea_entry_ofs = ea_ofs+11+ea_namelen
- ea_output(file_flag, 'CP' ea_codepage';' ea_numentries 'entries: (ofs='ea_entry_ofs')', fid)
- do i=1 to ea_numentries
- ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs+2, 2),10)
- ; messageNwait( ' >> peeking at' ea_entry_ofs', entry' i 'type=x'rightstr(itoa(peek(ea_seg,ea_entry_ofs,2),16),4,0))
- ea_entry = peek(ea_seg, ea_entry_ofs,min(ea_entrylen+4,255))
- ea_output(file_flag, ' entry' i 'type=x'rightstr(itoa(leftstr(ea_entry,2),16),4,0)'; len='ea_entrylen'; "'substr(ea_entry,5)'"', fid)
- ea_entry_ofs = ea_entry_ofs + ea_entrylen + 4
- enddo
- endif
- elseif leftstr(ea_value,2) = EAT_MVST then
- ea_output(file_flag, 'EA' ea_count 'flag=x'ea_flag 'name('ea_namelen')="'ea_name'"; type=x'ea_datatype' (MVST); value('ea_valuelen') =', fid)
- ea_codepage = ea_datalen
- ea_numentries = itoa(leftstr(ea_data,2),10)
- if ea_numentries=1 then
- ea_entrylen = itoa(substr(ea_data,5,2),10)
- ea_output(file_flag, 'CP' ea_codepage'; type=x'rightstr(itoa(substr(ea_data,3,2),16),4,0) '1 entry: len='ea_entrylen'; "'substr(ea_data,7,ea_entrylen)'"', fid)
- else
- ea_entry_ofs = ea_ofs+13+ea_namelen
- ea_output(file_flag, 'CP' ea_codepage'; type=x'rightstr(itoa(substr(ea_data,3,2),16),4,0) ea_numentries 'entries: (ofs='ea_entry_ofs')', fid)
- do i=1 to ea_numentries
- ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs, 2),10)
- ; messageNwait( ' >> peeking at' ea_entry_ofs', entry' i
- ea_entry = peek(ea_seg, ea_entry_ofs,min(ea_entrylen+2,255))
- ea_output(file_flag, ' entry' i 'len='ea_entrylen'; "'substr(ea_entry,3)'"', fid)
- ea_entry_ofs = ea_entry_ofs + ea_entrylen + 2
- enddo
- endif
- else
- ea_output(file_flag, 'EA' ea_count 'flag=x'ea_flag 'name('ea_namelen')="'ea_name'"; type=x'ea_datatype'; value('ea_valuelen','ea_datalen') =', fid)
- ea_output(file_flag, '"'ea_data'"', fid)
- endif
- ea_ofs = ea_ofs + ea_namelen + 5 + ea_valuelen -- Point past length of FEAList
- enddo
- if file_flag then
- fid.modify = 0
- nextfile
- endif
-
- defproc ea_output(file_flag, outstr, fid)
- if file_flag then
- insertline outstr, fid.last+1, fid
- else
- sayerror outstr
- endif
-
- ; Dependencies: get_ea_value()
- defc getea, get_ea = -- Tells you the value for a given attribute name
- parse arg name .
- if name='' then
- sayerror 'GET_EA <name> tells you the extended attribute value for the given attribute name.'
- return
- endif
- val = get_ea_value(name)
- if leftstr(val,2)=\253\255 then -- x'FFFD', after byte reversal
- stuff = 'EAT_ASCII ('itoa(substr(val,3,2),10)') '
- val = substr(val,5)
- else
- stuff = ''
- endif
- sayerror name'='stuff'"'val'"'
-
- ; Dependencies: None
- defproc get_ea_value(name) = -- Returns the value for a given attribute name
- ; ea_seg = .eaarea % 65536
- ; ea_ofs = .eaarea // 65536
- ea_long = atol(.eaarea)
- ea_seg = itoa(rightstr(ea_long,2),10)
- ea_ofs = itoa(leftstr(ea_long,2),10)
- if not .eaarea then return ''; endif
- ea_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
- ea_end = ea_ofs + ea_len
- ea_ofs = ea_ofs + 4 -- Point past length of FEAList
- do while ea_ofs < ea_len
- ;; ea_flag = itoa(peek(ea_seg, ea_ofs, 1)\0,16)
- ea_namelen = asc(peek(ea_seg, ea_ofs+1, 1))
- ea_valuelen = itoa(peek(ea_seg, ea_ofs+2, 2),10)
- if name = peekz(ea_seg, ea_ofs+4) then
- if ea_valuelen then
- return peek(ea_seg, ea_ofs+5+ea_namelen,min(ea_valuelen,255))
- else
- leave -- value length = 0; return null string
- endif
- endif
- ea_ofs = ea_ofs + ea_namelen + 5 + ea_valuelen -- Point past length of FEAList
- enddo
-
- ; Dependencies: find_ea
- defproc get_ea_value2(name) = -- Returns the value for a given (EAT_ASCII) attribute name
- if find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
- return peek(ea_seg, ea_ptr2, min(ea_valuelen,255))
- endif
-
- ; Returns 1 if attribute name exists; sets VAR args. EA_SEG, EA_OFS =
- ; start of EA buffer. EA_PTR1, 2 = pointers to start of entry and value,
- ; respectively, if name was found. EA_LEN, EA_ENTRYLEN, EA_VALUELEN = length
- ; of EA area, of entry, and of value, respectively.
- ; Dependencies: None
- 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) =
- ea_long = atol(.eaarea)
- ea_seg = itoa(rightstr(ea_long,2),10)
- ea_ofs = itoa(leftstr(ea_long,2),10)
- if not .eaarea then return ''; endif
- ea_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
- ea_end = ea_ofs + ea_len
- ea_ptr1 = ea_ofs + 4 -- Point past length of FEAList
- do while ea_ptr1 < ea_len
- ; ea_flag = itoa(peek(ea_seg, ea_ptr1, 1)\0,16)
- ea_namelen = asc(peek(ea_seg, ea_ptr1+1, 1))
- ea_valuelen = itoa(peek(ea_seg, ea_ptr1+2, 2),10)
- ea_entrylen = ea_namelen + 5 + ea_valuelen
- if name = peekz(ea_seg, ea_ptr1+4) then
- ea_ptr2 = ea_ptr1+5+ea_namelen -- Point to start of EA value
- return 1
- endif
- ea_ptr1 = ea_ptr1 + ea_entrylen -- Point to start of next entry
- enddo
-
- ; Dependencies: None
- defc setea, set_ea = -- Sets a single name / value pair
- parse arg name data
- if name='' then
- sayerror 'SET_EA <name> <value> sets the extended attribute value for a new file *only*.'
- return
- endif
- name_len = length(name)
- data_len = length(data)
- ea_len = 13 + name_len + data_len
- if .eaarea then
- ea_long = atol(.eaarea)
- ea_seg = itoa(rightstr(ea_long,2),10)
- ea_ofs = itoa(leftstr(ea_long,2),10)
- ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
- if ea_old_len > 4 then
- sayerror '.eaarea already set; this example is only for newly-created edit files.'
- return
- endif
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#38', -- DosReAllocSeg
- atoi(ea_len) || -- Number of bytes requested
- rightstr(ea_long,2) )
- re = 're'
- ea_ptr = ea_seg
- else
- ea_buffer = "00" -- Initialize string pointer.
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#34', -- DosAllocSeg
- atoi(ea_len) || -- Number of bytes requested
- selector(ea_buffer) || -- String selector
- offset(ea_buffer) || -- String offset
- atoi(0) ) -- Share information
- re = ''
- ea_ptr = itoa(ea_buffer,10)
- endif
-
- if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
- poke ea_ptr, 0, atol(ea_len)
- poke ea_ptr, 4, \0 -- Start of EA: flag byte
- poke ea_ptr, 5, chr(name_len)
- poke ea_ptr, 6, atoi(data_len + 4) -- Value length = len(data) + len(data_type) + len(data_len)
- poke ea_ptr, 8, name
- poke ea_ptr, 8+name_len, \0 -- Null byte after name
- poke ea_ptr, 9+name_len, \253\255 -- EAT_ASCII
- poke ea_ptr, 11+name_len, atoi(data_len)
- poke ea_ptr, 13+name_len, data
- .eaarea = mpfrom2short(ea_ptr,0)
-
- ; Dependencies: None
- defc set_ea_many = -- Sets a bunch of attributes.
- if arg(1)='' then
- sayerror 'SET_EA_MANY /<name> <value>/<name> <value>/... sets extended attributes for a new file *only*.'
- return
- endif
- parse arg delim 2 rest
- ea_len = 4 -- Initialize to 4 bytes for FEALIST Length field
- do while rest <> ''
- parse value rest with stuff (delim) rest
- parse value stuff with name data
- ea_len = ea_len + length(name) + length(data) + 9 -- 9 bytes overhead per EA
- enddo
- if .eaarea then
- ea_long = atol(.eaarea)
- ea_seg = itoa(rightstr(ea_long,2),10)
- ea_ofs = itoa(leftstr(ea_long,2),10)
- ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
- if ea_old_len > 4 then
- sayerror '.eaarea already set; this example is only for newly-created edit files.'
- return
- endif
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#38', -- DosReAllocSeg
- atoi(ea_len) || -- Number of bytes requested
- rightstr(ea_long,2) )
- re = 're'
- ea_ptr = ea_seg
- else
- ea_buffer = "00" -- Initialize string pointer.
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#34', -- DosAllocSeg
- atoi(ea_len) || -- Number of bytes requested
- selector(ea_buffer) || -- String selector
- offset(ea_buffer) || -- String offset
- atoi(0) ) -- Share information
- re = ''
- ea_ptr = itoa(ea_buffer,10)
- endif
-
- if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
- poke ea_ptr, 0, atol(ea_len)
-
- parse arg delim 2 rest
- ea_ofs = 4 -- Point to start of EA
- do while rest <> ''
- parse value rest with stuff (delim) rest
- parse value stuff with name data
- name_len = length(name)
- data_len = length(data)
- poke ea_ptr, ea_ofs , \0 -- Start of EA: flag byte
- poke ea_ptr, ea_ofs+1, chr(name_len)
- poke ea_ptr, ea_ofs+2, atoi(data_len + 4) -- Value length = len(data) + len(data_type) + len(data_len)
- poke ea_ptr, ea_ofs+4, name
- poke ea_ptr, ea_ofs+4+name_len, \0 -- Null byte after name
- poke ea_ptr, ea_ofs+5+name_len, EAT_ASCII
- poke ea_ptr, ea_ofs+7+name_len, atoi(data_len)
- poke ea_ptr, ea_ofs+9+name_len, data
- ea_ofs = ea_ofs + name_len + data_len + 9 -- 9 bytes overhead per EA
- enddo
- .eaarea = mpfrom2short(ea_ptr,0)
-
- ; Dependencies: None
- defc addea, add_ea = -- Adds a single name / value pair to an existing EA list
- parse arg name data
- if name='' then
- sayerror 'ADD_EA <name> <value> adds the extended attribute value specified to the current file.'
- return
- endif
- name_len = length(name)
- data_len = length(data)
- ea_len_incr = 9 + name_len + data_len
- if .eaarea then
- ea_long = atol(.eaarea)
- ea_seg = itoa(rightstr(ea_long,2),10)
- ea_ofs = itoa(leftstr(ea_long,2),10)
- ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#38', -- DosReAllocSeg
- atoi(ea_old_len+ea_len_incr) || -- Number of bytes requested
- rightstr(ea_long,2) )
- re = 're'
- ea_ptr = ea_seg
- else
- ea_buffer = "00" -- Initialize string pointer.
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#34', -- DosAllocSeg
- atoi(ea_len_incr+4) || -- Number of bytes requested
- selector(ea_buffer) || -- String selector
- offset(ea_buffer) || -- String offset
- atoi(0) ) -- Share information
- re = ''
- ea_ptr = itoa(ea_buffer,10)
- ea_ofs = 0
- ea_old_len = 4 -- Point past length field
- endif
-
- if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
- poke ea_ptr, ea_ofs, atol(ea_old_len+ea_len_incr)
- ea_ofs = ea_ofs + ea_old_len
- poke ea_ptr, ea_ofs , \0 -- Start of EA: flag byte
- poke ea_ptr, ea_ofs+1, chr(name_len)
- poke ea_ptr, ea_ofs+2, atoi(data_len + 4) -- Value length = len(data) + len(data_type) + len(data_len)
- poke ea_ptr, ea_ofs+4, name
- poke ea_ptr, ea_ofs+4+name_len, \0 -- Null byte after name
- poke ea_ptr, ea_ofs+5+name_len, EAT_ASCII
- poke ea_ptr, ea_ofs+7+name_len, atoi(data_len)
- poke ea_ptr, ea_ofs+9+name_len, data
- .eaarea = mpfrom2short(ea_ptr,0)
-
- ; Dependencies: find_ea()
- defc get_ea2, getea2 = -- Tells you the value for a given attribute name
- parse arg name . -- (This version uses find_ea() instead of get_ea_value().)
- if name='' then
- sayerror 'GET_EA <name> tells you the extended attribute value for the given attribute name.'
- return
- endif
- if find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
- val = peek(ea_seg, ea_ptr2,min(ea_valuelen,255))
- if leftstr(val,2)=\253\255 then -- x'FFFD', after byte reversal
- stuff = 'EAT_ASCII ('itoa(substr(val,3,2),10)') '
- val = substr(val,5)
- else
- stuff = ''
- endif
- sayerror name'='stuff'"'val'"'
- else
- sayerror '<Not found>'
- endif
-
- ; Dependencies: find_ea()
- defc delete_ea, deleteea =
- parse arg name .
- if name='' then
- sayerror 'DELETE_EA <name> deletes the named extended attribute.'
- return
- endif
- if not find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
- sayerror '<Not found>'
- return
- endif
- newlen = ea_len - ea_entrylen
- poke ea_seg, ea_ofs, atol(newlen)
- if ea_ptr1+ea_entrylen < ea_len then -- If in the middle, close it up
- call memcpyx(atoi(ea_ptr1) || atoi(ea_seg), atoi(ea_ptr1+ea_entrylen) || atoi(ea_seg), ea_len - ea_ptr1 - ea_entrylen)
- endif
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#38', -- DosReAllocSeg
- atoi(newlen) || -- Number of bytes requested
- atoi(ea_seg) )
- ;; if r then sayerror 'Error' r 'reallocating memory segment; command halted.'; stop; endif
-
- ; Dependencies: find_ea()
- defproc delete_ea(name) =
- parse arg name .
- if not find_ea(name, ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen) then
- return
- endif
- newlen = ea_len - ea_entrylen
- poke ea_seg, ea_ofs, atol(newlen)
- junk = 'junk' -- Avoid problem due to bug in MEMCPYX in EPM 5.20
- if ea_ptr1+ea_entrylen < ea_len then -- If in the middle, close it up
- call memcpyx(atoi(ea_ptr1) || atoi(ea_seg), atoi(ea_ptr1+ea_entrylen) || atoi(ea_seg), ea_len - ea_ptr1 - ea_entrylen)
- endif
- call dynalink('DOSCALLS', -- Dynamic link library name
- '#38', -- DosReAllocSeg
- atoi(newlen) || -- Number of bytes requested
- atoi(ea_seg) )
-
- ; Dependencies: find_ea(), delete_ea(), add_ea
- defc type =
- found = find_ea('.TYPE', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
- if not found | ea_valuelen=0 then
- answer = winmessagebox('Type', 'File has no type. Would you like to set one?', 16388) -- YESNO + MOVEABLE
- elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
- type = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), 255))
- answer = winmessagebox('Type', 'File has the following type:'\13 type\13\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
- elseif peek(ea_seg, ea_ptr2, 2)=EAT_MVMT then
- ea_numentries = itoa(peek(ea_seg, ea_ptr2+4, 2),10)
- if ea_numentries=1 then
- type = 'File has the following type:'
- else
- type = 'File has types:'
- endif
- ea_entry_ofs = ea_ptr2+6
- do i=1 to ea_numentries
- ea_entrylen = itoa(peek(ea_seg, ea_entry_ofs+2, 2),10)
- if peek(ea_seg, ea_entry_ofs, 2)=EAT_ASCII then
- type = type\13 || peek(ea_seg, ea_entry_ofs+4,min(ea_entrylen,255))
- else
- type = type\13 || '<non-ASCII>'
- endif
- ea_entry_ofs = ea_entry_ofs + ea_entrylen + 4
- enddo
- answer = winmessagebox('Type', type\13\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
- else
- answer = winmessagebox('Type', 'File has non-ASCII data for the type.'\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
- endif
- if answer=6 then
- newtype = listbox('Select type','-Plain Text-OS/2 Command File-DOS Command File-C Code-Pascal Code-BASIC Code-COBOL Code-FORTRAN Code-Assembler Code-')
- if newtype then
- if found then call delete_ea('.TYPE'); endif
- 'add_ea .TYPE' newtype
- endif
- endif
-
- ; Dependencies: delete_ea(), add_ea
- defc setattribute, setfiletype
- call delete_ea('.TYPE')
- 'add_ea .TYPE' arg(1)
-
- ; Dependencies: find_ea(), delete_ea(), add_ea
- defc subject =
- found = find_ea('.SUBJECT', ea_seg, ea_ofs, ea_ptr1, ea_ptr2, ea_len, ea_entrylen, ea_valuelen)
- subj = ''
- if not found | ea_valuelen=0 then
- answer = winmessagebox('Subject', 'File has no subject. Would you like to add one?', 16388) -- YESNO + MOVEABLE
- elseif peek(ea_seg, ea_ptr2, 2)=EAT_ASCII then
- subj = peek(ea_seg, ea_ptr2+4, min(itoa(peek(ea_seg, ea_ptr2+2, 2), 10), 255))
- answer = winmessagebox('Subject', 'File has the following subject:'\13 subj\13\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
- else
- answer = winmessagebox('Subject', 'File has non-ASCII data for the subject.'\13'Would you like to change it?', 16388) -- YESNO + MOVEABLE
- endif
- if answer=6 then
- newsubj = entrybox('Enter subject', '', subj, 40, 40)
- if newsubj then
- if found then call delete_ea('.SUBJECT'); endif
- 'add_ea .SUBJECT' newsubj
- endif
- endif
-
- ; The following routine will put the contents of the current file into the
- ; .EAarea of another file as an MVST EAT_ASCII attribute. If the given
- ; attribute name already exists, it will be replaced (not extended).
- ; Dependencies: delete_ea()
- defproc put_file_as_MVST(source_fid, target_fid, ea_name)
- getfileid start_fid
- activatefile target_fid
- call delete_ea(ea_name)
- if not source_fid.last then -- If nothing to add,
- activatefile start_fid
- return -- we're all done.
- endif
- name_len = length(ea_name)
- value_len = filesize() + 2 * .last + 8 -- Overhead: 2 bytes/rec length, + 2 bytes each EAT_MVST, codepage, numentries, EAT_ASCII
- ea_len_incr = 5 + name_len + value_len -- Overhead: 1 flags, 1 len(name), 2 len(value), 1 null ASCIIZ terminator
- if .eaarea then
- ea_long = atol(.eaarea)
- ea_seg = itoa(rightstr(ea_long,2),10)
- ea_ofs = itoa(leftstr(ea_long,2),10)
- ea_old_len = ltoa(peek(ea_seg, ea_ofs, 4),10)
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#38', -- DosReAllocSeg
- atoi(ea_old_len+ea_len_incr) || -- Number of bytes requested
- rightstr(ea_long,2) )
- re = 're'
- ea_ptr = ea_seg
- else
- ea_buffer = "00" -- Initialize string pointer.
- r = dynalink('DOSCALLS', -- Dynamic link library name
- '#34', -- DosAllocSeg
- atoi(ea_len_incr+4) || -- Number of bytes requested
- selector(ea_buffer) || -- String selector
- offset(ea_buffer) || -- String offset
- atoi(0) ) -- Share information
- re = ''
- ea_ptr = itoa(ea_buffer,10)
- ea_ofs = 0
- ea_old_len = 4 -- Point past length field
- endif
-
- if r then sayerror 'Error' r re'allocating memory segment; command halted.'; stop; endif
- poke ea_ptr, ea_ofs, atol(ea_old_len+ea_len_incr)
- ea_ofs = ea_ofs + ea_old_len
- poke ea_ptr, ea_ofs , \0 -- Start of EA: flag byte
- poke ea_ptr, ea_ofs+1, chr(name_len)
- poke ea_ptr, ea_ofs+2, atoi(value_len)
- poke ea_ptr, ea_ofs+4, ea_name
- poke ea_ptr, ea_ofs+4+name_len, \0 -- Null byte after name
- poke ea_ptr, ea_ofs+5+name_len, EAT_MVST
- poke ea_ptr, ea_ofs+7+name_len, atoi(0) -- Code page
- poke ea_ptr, ea_ofs+9+name_len, atoi(source_fid.last) -- NumEntries
- poke ea_ptr, ea_ofs+11+name_len, EAT_ASCII -- Each entry is of type ASCII
- ea_ofs = ea_ofs + 13 + name_len
- do i=1 to source_fid.last
- getline line, i, source_fid
- poke ea_ptr, ea_ofs, atoi(length(line))
- poke ea_ptr, ea_ofs+2, line
- ea_ofs = ea_ofs + length(line) + 2
- enddo
- .eaarea = mpfrom2short(ea_ptr,0)
- activatefile start_fid
-
- ; EPM.Attributes will save EPM attributes listed in current file into the .EAarea
- defc try_EPM_EA =
- getfileid source_fid
- call put_file_as_MVST(source_fid, source_fid, 'EPM.Attributes')
-
- ; Dependencies: delete_ea(), add_ea
- defc putfield -- Put a field into an EA
- field = upcase(strip(arg(1)))
- if leftstr(field,1)='.' then
- field=substr(field,2)
- endif
- if field = '' then
- Sayerror 'Supported fields are: FIlename MArgins TAbs TItletext Userstring'
- return
- elseif abbrev('FILENAME', field, 2) then
- parse value 'FILENAME' .filename with fieldname fieldvalue
- elseif abbrev('MARGINS', field, 2) then
- parse value 'MARGINS' .margins with fieldname fieldvalue
- elseif abbrev('TABS', field, 2) then
- parse value 'TABS' .tabs with fieldname fieldvalue
- elseif abbrev('TITLETEXT', field, 2) then
- parse value 'TITLETEXT' .titletext with fieldname fieldvalue
- elseif abbrev('USERSTRING', field, 1) then
- parse value 'USERSTRING' .userstring with fieldname fieldvalue
- else
- sayerror 'Unknown or unsupported field: 'field
- return
- endif
- call delete_ea('EPM.'fieldname)
- 'add_ea EPM.'fieldname fieldvalue
-
- ; Dependencies: check_field()
- defc getfield -- Recover a field from an EA
- field = upcase(strip(arg(1)))
- if leftstr(field,1)='.' then
- field=substr(field,2)
- endif
- if abbrev('FILENAME', field, 2) then
- .filename = check_field('FILENAME', .filename)
- elseif abbrev('MARGINS', field, 2) then
- .margins = check_field('MARGINS', .margins)
- elseif abbrev('TABS', field, 2) then
- .tabs = check_field('TABS', .tabs)
- elseif abbrev('TITLETEXT', field, 2) then
- .titletext = check_field('TITLETEXT', .titletext)
- elseif abbrev('USERSTRING', field, 1) then
- .userstring = check_field('USERSTRING', .userstring)
- else
- sayerror 'Unknown or unsupported field: 'field
- return
- endif
-
- ; Dependencies: get_ea_value()
- defproc check_field(fieldname, current_value)
- val = get_ea_value('EPM.'fieldname)
- if leftstr(val,2)=\253\255 then -- x'FFFD', after byte reversal
- return substr(val,5) -- (EAT_ASCII)
- elseif val='' then
- sayerror 'Field value not found in extended attribute area.'
- else
- sayerror 'Saved as unsupported EA type: 'itoa(leftstr(val,2),16)
- endif
- return current_value
-
-