home *** CD-ROM | disk | FTP | other *** search
/ MikeOS 4.5 / mikeos.iso / mikeos.flp / archive.bas < prev    next >
BASIC Source File  |  2014-12-21  |  10KB  |  551 lines

  1. if $1 = "" then goto help
  2. d = ramstart
  3.  
  4. main:
  5.   rem >>> Collect command, help if invalid <<<
  6.   gosub collect_parameter
  7.   if $2 = "HELP" then goto help
  8.   if $2 = "CREATE" then goto create_archive
  9.   if $2 = "ADD" then goto add_file
  10.   if $2 = "REMOVE" then goto remove_file
  11.   if $2 = "EXTRACT" then goto extract_file
  12.   if $2 = "EXTRACTALL" then goto extract_all
  13.   if $2 = "LIST" then goto archive_list
  14. goto help
  15.  
  16. collect_parameter:
  17.   rem >>> Collects a parameter separated by a space to $2 <<<
  18.   rem >>> Offset(P) updated each time <<<
  19.   x = & $1
  20.   x = x + p
  21.   do
  22.     x = x + 1
  23.     peek v x
  24.     if v = 0 then v = 32
  25.   loop until v = 32
  26.   poke 0 x
  27.   x = & $1
  28.   x = x + p
  29.   string load $2 x
  30.   len $2 v
  31.   p = p + v + 1
  32.   case upper $2
  33. return
  34.  
  35. collect_list_item:
  36.   rem >>> Collect an item from a comma separated list $2 to $3 <<<
  37.   rem >>> offset in Q, returns null if list finished <<<
  38.   if q = 255 then $3 = ""
  39.   if q = 255 then return
  40.   x = & $2
  41.   x = x + q
  42.   do
  43.     x = x + 1
  44.     peek v x
  45.     if v = 0 then v = 44
  46.     if v = 32 then v = 44
  47.   loop until v = 44
  48.   peek v x
  49.   poke 0 x
  50.   x = & $2
  51.   x = x + q
  52.   string load $3 x
  53.   if v < 33 then q = 255
  54.   len $3 v
  55.   if q < 255 then q = q + v + 1
  56.   case upper $3
  57. return
  58.  
  59. find_free_block:
  60.   rem >>> Find a free block big enough for filesize S <<<
  61.   rem >>> Returns N = block number, M = number of blocks <<<
  62.  
  63.   if s = 0 then return
  64.  
  65.   x = d + 14
  66.   peek y x
  67.  
  68.   rem turn raw size into a number of 512 byte blocks
  69.   m = s / 512
  70.   v = s % 512
  71.   if v > 0 then m = m + 1
  72.   w = 0
  73.   z = 0
  74.  
  75.   x = d + 5
  76.   peekint v x
  77.   x = d + v
  78.  
  79.   rem search the allocation map for free space
  80.   do
  81.     peek v x
  82.     x = x + 1
  83.     if v = 0 then w = w + 1
  84.     if v > 0 then w = 0
  85.     z = z + 1
  86.     rem if we exceed the allocation map there is no space
  87.     if z > y then print "There is no area large enough for this file."
  88.     if z > y then end
  89.   loop until w = m
  90.  
  91.   n = z - m
  92. return
  93.  
  94. allocate_file_entry:
  95.   rem >>> Create a file entry with filename $3, size S and the used block <<<
  96.   rem >>> Must run find_free_block first to get file area <<<
  97.  
  98.   rem check the maximum files is not reached
  99.   x = d + 11
  100.   peek v x
  101.   x = d + 12
  102.   peek w x
  103.   if v = w then print "No free file entries."
  104.   if v = w then end
  105.   rem increase files in archive
  106.   v = v + 1
  107.   x = d + 11  
  108.   poke v x
  109.   
  110.   x = d + 7
  111.   peekint v x
  112.   x = v + d
  113.   z = 0
  114.   rem search the file list for blank entries
  115.   do
  116.     peek v x
  117.     x = x + 17
  118.     z = z + 1
  119.     if z > w then print "No free file entries."
  120.     if z > w then end
  121.   loop until v = 0
  122.   x = x - 17
  123.  
  124.   w = d + 9
  125.   peekint z w
  126.   
  127.   rem store information in entry
  128.   string store $3 x
  129.   x = x + 13
  130.   o = n * 512 + z
  131.   pokeint o x
  132.   x = x + 2
  133.   pokeint s x
  134. return
  135.  
  136. allocate_free_block:
  137.   rem >>> Allocate free block found with find_free_block <<<
  138.  
  139.   x = d + 5
  140.   peekint v x
  141.   x = d + v + n
  142.  
  143.   rem store area as allocated
  144.   w = m
  145.   do
  146.     poke 1 x
  147.     x = x + 1
  148.     w = w - 1
  149.   loop until w = 0
  150.  
  151.   rem if the last block allocate is more than highest block, update
  152.   w = n + m - 1
  153.   x = d + 13
  154.   peek v x
  155.   if w > v then v = w
  156.   poke v x
  157. return
  158.  
  159. collect_file_data:
  160.   rem >>> find filename $3 in the file list and get offset(O) and size(S) <<<
  161.   x = d + 12
  162.   peek z x
  163.  
  164.   x = d + 7
  165.   peekint v x
  166.   x = d + v
  167.  
  168.   rem search file entries until we find a match
  169.   w = 0
  170.   y = 0
  171.   do
  172.     string load $4 x
  173.     if $4 = $3 then w = 1
  174.     x = x + 17
  175.     y = y + 1
  176.     if y = z then print "File does not exist."
  177.     if y = z then end
  178.   loop until w = 1
  179.   
  180.   rem collect information
  181.   x = x - 17
  182.   x = x + 13
  183.   peekint o x
  184.   x = x + 2
  185.   peekint s x
  186. return
  187.  
  188. deallocate_block:
  189.   rem >>> Deallocate block used by a file <<<
  190.   rem >>> Run collect_file_info first <<<
  191.  
  192.   x = d + 9
  193.   peekint v x
  194.  
  195.   rem figure out block number and amount from offset and size
  196.   n = o - v / 512
  197.   m = s / 512
  198.   v = s % 512
  199.   if v > 0 then m = m + 1
  200.   if m = 0 then return
  201.  
  202.   x = d + 5
  203.   peekint v x
  204.   x = v + n + d
  205.   y = m
  206.   rem store blocks as unused
  207.   do
  208.     poke 0 x
  209.     x = x + 1
  210.     y = y - 1
  211.   loop until y = 0
  212.  
  213.   x = d + 14  
  214.   peek z x
  215.   x = d + 5
  216.   peekint v x
  217.   x = d + v + z - 1
  218.   
  219.   rem find the new highest block and update
  220.   z = z + 1
  221.   do
  222.     peek v x
  223.     x = x - 1
  224.     z = z - 1
  225.     if z = 0 then v = 1
  226.   loop until v = 1 
  227.  
  228.   x = d + 13
  229.   poke z x
  230. return
  231.  
  232. deallocate_file_entry:
  233.   rem >>> Remove file entry with name $3 <<<
  234.   rem >>> Must run collect_file_data first <<<
  235.  
  236.   rem reduce files in archive
  237.   x = d + 11
  238.   peek v x
  239.   v = v - 1
  240.   poke v x
  241.  
  242.   x = d + 7
  243.   peekint v x
  244.   x = d + v
  245.   
  246.   rem find file entry
  247.   w = 0
  248.   do
  249.     string load $4 x
  250.     x = x + 17
  251.     if $4 = $3 then w = 1
  252.   loop until w = 1
  253.  
  254.   rem blank file entry
  255.   x = x - 17
  256.   for y = 1 to 17
  257.     poke 0 x
  258.     x = x + 1
  259.   next y
  260. return
  261.   
  262. load_archive:
  263.   rem >>> load and verify archive <<<
  264.  
  265.   print "Opening Archive..."
  266.   rem get name off the commandline parameters
  267.   gosub collect_parameter
  268.   load $2 d
  269.   rem preserve opened name
  270.   $8 = $2
  271.  
  272.   rem make sure file is valid
  273.   if s = 0 then print "Archive file is blank."
  274.   if s = 0 then end
  275.  
  276.   if r = 1 then print "Archive file does not exist."
  277.   if r = 1 then end
  278.  
  279.   rem check for archive header
  280.   string load $4 d
  281.   if $4 = "MFA" then rem
  282.   else print "Not an archive file."
  283.   else end
  284.  
  285.   rem check version is current
  286.   x = d + 4
  287.   peek v x
  288.   if v > 1 then print "Archive version not supported."
  289.   if v > 1 then end
  290. return
  291.  
  292. save_archive:
  293.   rem >>> calculate size and store archive <<<
  294.  
  295.   print "Saving Archive..."
  296.   rem header size
  297.   z = 14
  298.   
  299.   rem allocate block size
  300.   x = d + 14
  301.   peek v x
  302.   z = z + v
  303.  
  304.   rem file list size
  305.   x = d + 12
  306.   peek v x
  307.   v = v * 17
  308.   z = z + v
  309.  
  310.   rem save only up to the last allocated block of data
  311.   x = d + 13
  312.   peek v x
  313.   v = v + 1
  314.   v = v * 512
  315.   z = z + v
  316.  
  317.   rem save per existing name, overwrite
  318.   delete $8
  319.   save $8 d z
  320. return
  321.  
  322. help:
  323.   rem present is no arguments, help argument or invalid argument
  324.   print "============================"
  325.   print "ARCHIVE: File archiving tool"
  326.   print "============================"
  327.   print "Version 1.0.0"
  328.   print "Copyright (C) Joshua Beck"
  329.   print "Email: mikeosdeveloper@gmail.com"
  330.   print "Licenced under the GNU General Public Licence v3"
  331.   print ""
  332.   print "Syntax: ARCHIVE (command) (archive filename) [comma separated list]"
  333.   print ""
  334.   print "Commands:"
  335.   print "    Create - Create an empty archive"
  336.   print "    Add - Added listed files to archive"
  337.   print "    Remove - Remove listed files from archive"
  338.   print "    Extract - Extract listed files from archive"
  339.   print "    ExtractAll - Extract all files from archive"
  340.   print "    List - List files in an  archive"
  341.   print "    Help - Display this help screen"
  342.   print ""
  343. end
  344.  
  345. create_archive:
  346.   rem >>> create new archive <<<
  347.  
  348.   rem file identifier
  349.   d = ramstart
  350.   $4 = "MFA"
  351.   string store $4 d
  352.  
  353.   rem file version
  354.   x = d + 4
  355.   poke 1 x
  356.  
  357.   rem allocation map offset
  358.   x = d + 5
  359.   pokeint 15 x
  360.  
  361.   rem file list offset
  362.   x = d + 7
  363.   pokeint 45 x
  364.  
  365.   rem data offset
  366.   x = d + 9
  367.   pokeint 385 x
  368.  
  369.   rem files in archive
  370.   x = d + 11
  371.   poke 0 x
  372.  
  373.   rem file list entries
  374.   x = d + 12
  375.   poke 20 x
  376.  
  377.   rem highest allocated block
  378.   x = d + 13
  379.   poke 0 x
  380.  
  381.   rem blocks (512 bytes) in allocation map
  382.   x = d + 14
  383.   poke 40 x
  384.  
  385.   rem create blank allocation map
  386.   x = d + 15
  387.   for y = 1 to 40
  388.     poke 0 x
  389.     x = x + 1
  390.   next y
  391.  
  392.   rem create blank file list
  393.   x = d + 45
  394.   for y = 1 to 340
  395.     poke 0 x
  396.     x = x + 1
  397.   next y
  398.  
  399.   rem collect filename off parameter list
  400.   gosub collect_parameter
  401.   $8 = $2
  402.   gosub save_archive
  403.   print "File created."
  404. end
  405.  
  406. add_file:
  407.   gosub load_archive
  408.  
  409.   gosub collect_parameter
  410.   gosub collect_list_item
  411.  
  412.   t = 0
  413.   do
  414.     $4 = "Adding file: " + $3
  415.     print $4
  416.  
  417.     size $3 
  418.     gosub find_free_block
  419.     gosub allocate_file_entry
  420.     gosub allocate_free_block  
  421.  
  422.     v = d + o
  423.     load $3 v
  424.     if r = 1 then print "File does not exist."
  425.     if r = 1 then end
  426.  
  427.     gosub collect_list_item
  428.     if $3 = "" then t = 1
  429.   loop until t = 1
  430.  
  431.   gosub save_archive
  432.   print "All files added successfully."
  433. end
  434.  
  435. remove_file:
  436.   gosub load_archive
  437.  
  438.   gosub collect_parameter
  439.   gosub collect_list_item
  440.  
  441.   t = 0
  442.   do
  443.     $4 = "Removing file: " + $3
  444.     print $4
  445.  
  446.     gosub collect_file_data
  447.     gosub deallocate_block
  448.     gosub deallocate_file_entry
  449.  
  450.     gosub collect_list_item
  451.     if $3 = "" then t = 1
  452.   loop until t = 1
  453.  
  454.   gosub save_archive
  455.   print "All files successfully removed."
  456. end
  457.  
  458. extract_file:
  459.   gosub load_archive
  460.  
  461.   gosub collect_parameter
  462.   gosub collect_list_item
  463.  
  464.   t = 0
  465.   do
  466.     $4 = "Extracting file: " + $3
  467.     print $4
  468.  
  469.     gosub collect_file_data
  470.     v = o + d
  471.     delete $3
  472.     save $3 v s
  473.     if r > 0 then print "Invalid filename or read-only disk."
  474.     if r > 0 then end
  475.  
  476.     gosub collect_list_item
  477.     if $3 = "" then t = 1
  478.   loop until t = 1
  479.  
  480.   print "All files extracted successfully."
  481. end
  482.  
  483. extract_all:
  484.   gosub load_archive
  485.   
  486.   x = d + 12
  487.   peek w x
  488.   w = w * 17
  489.   x = d + 7
  490.   peekint t x
  491.   t = t + d
  492.   u = t + w
  493.  
  494.   do
  495.     string load $3 t
  496.     t = t + 17
  497.  
  498.     $4 = "Extracting file: " + $3
  499.     if $3 = "" then rem
  500.     else print $4
  501.  
  502.     gosub collect_file_data
  503.     v = o + d
  504.     if $3 = "" then rem
  505.     else delete $3
  506.     else save $3 v s
  507.  
  508.     if r = 1 then print "Invalid filename or read-only disk."
  509.     if r = 1 then end
  510.   loop until t = u
  511.  
  512.   print "All files extracted successfully."
  513. end
  514.  
  515. archive_list:
  516.   gosub load_archive
  517.  
  518.   x = d + 11
  519.   peek a x
  520.   $4 = "File in archive: " + a
  521.   x = d + 12
  522.   peek b x  
  523.  
  524.   $4 = "Files in archive:   " + a
  525.   $5 = "Maximum files:      " + b
  526.   $6 = "Archive size:       " + s
  527.  
  528.   print "Mega File Archive - Version 1"
  529.   print $4
  530.   print $5
  531.   print $6
  532.   print "File list:"
  533.   if v = 0 then end
  534.  
  535.   x = d + 12
  536.   peek w x
  537.   x = d + 7
  538.   peekint v x
  539.   x = d + v
  540.   
  541.   do
  542.     string load $4 x
  543.     if $4 = "" then rem
  544.     else print $4
  545.     x = x + 17
  546.     w = w - 1
  547.   loop until w = 0
  548. end
  549.  
  550.  
  551.