SHARE
TWEET

Linvstblast 0.1

a guest Nov 14th, 2017 60 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/usr/bin/env tclsh
  2.  
  3. # execute in wish from path \
  4. #exec wish "$0" ${1+"$@"}
  5.  
  6. # ======================== LINVST BLASTER =========================
  7. # ==================== LINVST DLL BATCH LINKER ====================
  8. # by a linvst user
  9. #
  10. # READ THIS INTRODUCTION BEFORE ATTEMPTING TO USE IT
  11. #
  12. # IF YOU DON'T RUN LINUX, THIS IS NONE OF YOUR BUSINESS
  13. #
  14. # ==================== HOW TO USE IT ===============================
  15. # This is a Tcl script. You must have Tcl 8.4.6 or later to use it.
  16. # Older versions of Tcl may work, but I am not sure they will.
  17. #
  18. # First, 'cd' to the directory that contains the DLL files of the
  19. # Windows plugins and run the command. All the *.dll files in the  
  20. # working directory will be found and linked RECURSIVELY. Yes,
  21. # recursively, so make sure you're happy with the directory location
  22. # and structure before you run this script.
  23. #
  24. # Example:
  25. # $ cd /some/directory/with/a/truckload/of/plugins
  26. # $ linvstblast
  27. #
  28. # Tip: some file managers such as pcmanfm or spacefm let you press F4
  29. # to launch a terminal session in whatever directory it is displaying,
  30. # so you don't even have to 'cd' manually.
  31. #
  32. # After you run the command, a temporary file may be opened in a text
  33. # editor. I use Vim, but it is easy to edit the USER OPTIONS section
  34. # of this script and change it to another editor of your preference.
  35. # That will be your chance to edit the list of plugins that will be
  36. # linked to linvst. You can change that list or not. Your call.
  37. #
  38. # Unlike airwave (another Windows plugin DLL bridge for Linux), linvst
  39. # doesn't let you link to the plugins with some kind of alias or
  40. # alternative name. The name of the bridge .so file must be EXACTLY the
  41. # same as the name of the original .dll file. If you really must change
  42. # names, you will have to rename the .dll files first. Up to you. Most
  43. # plugins will work fine after being renamed. It's possible that one
  44. # or another will refuse to work, but that should be extremely rare.
  45. # Renaming is an awful lot of work though, hardly worth the trouble.
  46. #
  47. # Anyway,
  48. #
  49. # Your first providence before using this script is making sure you
  50. # have a copy of the linvst.so file stored in a predictable path. For
  51. # the sake of instruction, this documentation assumes you keep that
  52. # file as /usr/local/bin/linvst.so
  53. # Then you navigate to a target directory that contains many Windows
  54. # plugin .dll files and run the script.
  55. # linvstblast (this script) will then recursively traverse that target
  56. # directory and find all .dll files in it. Note that not all .dll files
  57. # are plugins, and the script will handle that problem to some extent.
  58. # More on that later.
  59. # For every .dll file that is found, the script will copy your linvst.so
  60. # file from /usr/local/bin/ over to the same directory as the .dll file
  61. # and rename that brand new copy of the linvst.so file so that it has
  62. # the exact same name as the .dll file except the extension will be .so
  63. # rather than .dll. That is just how linvst works.
  64. #
  65. # POSSIBLE CONFLICTS
  66. # When copying the linvst.so file over to each directory where a .dll
  67. # file is found, linvstblast performs two checks:
  68. #
  69. # 1) There is a USER OPTIONS section in the beginning of this script,
  70. # right after these instructions. You are the one supposed to maintain
  71. # it. Yes, you. Don't look around, I am talking to you. That section
  72. # contains a blacklist. It is a list of .dll files that might exist
  73. # inside any given directory inside the target directory and are
  74. # required by their parent plugins, but are not plugins themselves
  75. # therefore they must never be linked to linvst in any way.
  76. # Those little buggers are easy to spot once you try to add them to a
  77. # DAW thinking that you're adding plugins and they fail, and their names
  78. # also should give them away if you know anything about software.
  79. # It's too bad neither clue can be identified automatically by this
  80. # script. They're unpredictable. So our only recourse is to maintain a
  81. # blacklist. Once you find one of those pesky .dll files, add it to
  82. # the blacklist HERE, IN THIS SCRIPT, in the USER OPTIONS section of
  83. # this script so you never have to worry about that particular file
  84. # again, even if the same target directory is selected over and over
  85. # (because you have added new directories and plugins to it).
  86. # When copying the linvst.so file over to each directory where a .dll
  87. # file is found, linvstblast checks if the .dll file is included in the
  88. # blacklist, in which case the .dll file is excluded from the entire
  89. # operation.
  90. # Note: the blacklist check procedure is case insensitive, and the .dll
  91. # extensions are optional. You can write the extensions, but they are
  92. # always assumed anyway.
  93. #
  94. # 2) If linvstblast finds that a PLUGIN-NAME.so file already exists
  95. # whose name matches that of PLUGIN-NAME.dll, linvstblast checks
  96. # whether PLUGIN-NAME.so is a copy of the /usr/local/bin/linvst.so file.
  97. # If it is indeed a copy, then that plugin is already taken care of and
  98. # will be ignored. Such occurrence is never mentioned in any reports
  99. # or requests for confirmation. That would be very annoying.
  100. # If PLUGIN-NAME.so is not a copy of the /usr/local/bin/linvst.so file,
  101. # that occurrence will be added to a conflict report presented to you
  102. # before the end of the procedure and you will be offered the chance to
  103. # decide what to do about it.
  104. # The report will tell you exactly what to do. Just follow the
  105. # instructions on it, and everything will be fine.
  106. # The only caveat is that I only test these things on Vim. If you use
  107. # another text editor and it fails, you might want to try to inform me
  108. # of the problem. Who knows, I might even fix it. Or not.
  109. # Or you can just stick to Vim and stay out of trouble. It's what
  110. # grownups do.
  111. # If you use pico, Ok, I'll be merciful to you.
  112. # If you use emacs, bleh, you can fix the situation on your own. You
  113. # brought this fate upon yourself.
  114. #
  115. # OUTCOME
  116. # After running this highfallutin script, open your DAW and have it
  117. # refresh the list of plugins -- assuming it's already configured to
  118. # find plugins in the same target directory that you selected in the
  119. # beginning of the procedure. That's it. The DAW will detect the new
  120. # plugins in that directory and add them to its internal catalogue.
  121. #
  122. # OTHER FEATURES
  123. # This script can operate in three modes: normal, express and remove.
  124. # Modes are triggered by the presence or absence of arguments.
  125. # If neither the "express" or "remove" argument is used, "normal" mode
  126. # is assumed automatically. Only one mode can be used at a time.
  127. # If you try to use more than one argument, the script aborts all
  128. # operation and outputs a warning.
  129. #
  130. # NORMAL MODE
  131. # Already described in the previous sections of this documentation.
  132. #
  133. # EXPRESS MODE
  134. # In express mode, the script skips the confirmation stage entirely.
  135. # You will never be given the chance to edit anything in a text
  136. # editor. Items that match your blacklist and potential conflicts will
  137. # be properly skipped, and you will be given a brief report on standard
  138. # output.
  139. #
  140. # How to use:
  141. # $ cd /some/directory/with/a/truckload/of/plugins
  142. # $ linvstblast express
  143. #
  144. # REMOVE MODE
  145. # The remove mode will remove all copies of the linvst.so file in the
  146. # working directory, recursively. Don't worry, you will be presented
  147. # with a list in your file editor that you can edit before the
  148. # procedure is run, so you can be sure that you're only removing the
  149. # ones you want. There is no express mode for this operation.
  150. # Also note that .so files are only removed if they are an exact copy
  151. # of your matrix linvst.so file, so if you have any old copies of
  152. # linvst.so lingering around, they will be preserved and will probably
  153. # be detected as potential conflicts in subsequent runs.
  154. #
  155. # How to use:
  156. # $ cd /some/directory/with/a/truckload/of/plugins
  157. # $ linvstblast remove
  158. #
  159. # This script is placed in the public domain.
  160. # No guarantees are included whatsoever. If it blows up in your face,
  161. # eats your files or teaches profanity to your parrot, no one will be
  162. # responsible.
  163. # If you find a bug in my precious script, fix it for your own good.
  164. # That's open source for ya! Har. If you don't find any bugs, rejoice.
  165. # Ignorance is bliss.
  166. #
  167. # ==================================================================
  168.  
  169. # USER OPTIONS SECTION. YOU MUST CHECK AND POSSIBLY EDIT THESE.
  170.  
  171. # This is the location of the linvst.so file that will be copied to all
  172. # the directories where a plugin DLL is found. Make sure it is correct.
  173. set _linvst "/usr/local/bin/linvst.so"
  174.  
  175. # Specify the full path of the editor you want to use. I've only tested
  176. # it with vim. Other editors may fail. Sorry!
  177. set _editor "/usr/bin/vim"
  178.  
  179. # Sometimes a plugin's directory contains other DLL files that are not
  180. # plugins and should be ignored, but this script is not smart enough
  181. # to figure them out on its own. You may add such undesirable DLL files
  182. # to this list, so they will always be ignored.
  183. # NOTE: this check is case insensitive and the '.dll' extension part is
  184. # optional. If '.dll' is omitted, it's still assumed, though.
  185.  
  186. set _blackList  {
  187. d2d1.dll
  188. msvcr120.dll
  189. msvcr140
  190. msvcp120
  191. msvcp140.dll
  192. }
  193.  
  194. # ==================================================================
  195. # END OF THE USER OPTIONS SECTION.
  196. # ==================================================================
  197.  
  198. # ==================================================================
  199. # SCRIPT BEGINS HERE. DON'T CHANGE ANYTHING BELOW THIS POINT
  200. # UNLESS YOU KNOW WHAT YOU'RE DOING.
  201. # ==================================================================
  202.  
  203. # ==================================================================
  204. # CHECKS AND PREPARATIONS
  205. # ==================================================================
  206. if  {$argc > 1} {
  207.     puts "ERROR! Only one argument, please."
  208.     puts ""
  209.     exit
  210. }
  211. # --------------------------------
  212. if  {$argc == 1}    {
  213.     if  {[lindex $argv 0] == "remove"}  {
  214.         set _mode "remove"
  215.     } elseif    {[lindex $argv 0] == "express"} {
  216.         set _mode "express"
  217.     } {
  218.         puts "ERROR! Incorrect argument \"[lindex $argv 0]\""
  219.         puts ""
  220.         exit
  221.     }
  222. } else {set _mode "normal"}
  223.  
  224. # --------------------------------
  225. if  {![file isfile $_linvst]}   {
  226.     puts "ERROR! Choice of linvst.so does not exist."
  227.     puts "Please fix first line in the USER OPTIONS section of the script."
  228.     puts ""
  229.     exit
  230. }
  231.  
  232. # --------------------------------
  233. set _found_dlls_tmpfile [file normalize "/tmp/found_dlls.txt"]
  234. file delete $_found_dlls_tmpfile
  235.  
  236. # --------------------------------
  237. set ::hashMethod tcllib
  238. foreach i {sha512sum sha384sum sha256sum sha224sum sha1sum md5sum} {
  239.     if  {[catch {set ::hashMethod [exec which $i]} _catchError]}    {
  240.         continue
  241.     } else  {break}
  242. }
  243.  
  244. if  {$::hashMethod == "tcllib"} {
  245.     if  {[catch {package require sha256} _catchError]}      {
  246.         puts "ERROR! Impossible to proceed. Please install at least one of these packages: "
  247.         puts "sha512sum, sha384sum, sha256sum, sha224sum, sha1sum, md5sum, or tcllib."
  248.         puts "Note: tcllib is considerably slower than all the others."
  249.         puts ""
  250.         exit
  251.     }
  252. }
  253. proc p.compare {arg1 arg2}  {
  254.     if  {$::hashMethod == "tcllib"} {
  255.         package require sha256
  256.         set arg1 [::sha2::sha256 -hex -file $arg1]
  257.         set arg2 [::sha2::sha256 -hex -file $arg2]
  258.         if  {$arg1 == $arg2} {return 1} else {return 0}
  259.     } else {
  260.         set arg1 [lindex [exec $::hashMethod $arg1] 0]
  261.         set arg2 [lindex [exec $::hashMethod $arg2] 0]
  262.         if  {$arg1 == $arg2} {return 1} else {return 0}
  263.     }  
  264. }
  265.  
  266. # ==================================================================
  267. # END OF CHECKS AND PREPARATIONS
  268. # ==================================================================
  269.  
  270. # ==================================================================
  271. # REMOVE MODE
  272. # ==================================================================
  273. if  {$_mode == "remove"}    {
  274.     set _found_sos [exec find [pwd] -iname "*.so"]
  275.  
  276.     if  {[llength $_found_sos] == 0}    {
  277.         puts "-> Done! No .so files found whatsoever."
  278.         puts "Are you sure you're running this in the right directory?"
  279.         puts ""
  280.         exit
  281.     }
  282.     foreach i [split $_found_sos "\n"]  {
  283.         if  {[p.compare "$i" "$_linvst"] == 1}  {lappend _found_sos_confirmed $i}
  284.     }
  285.     if  {![info exists _found_sos_confirmed]}   {
  286.         puts "-> Done! Some .so files were found, but none of them is a copy of "
  287.         puts "$_linvst, so nothing has been done this time. Here they are:"
  288.         foreach i [split $_found_sos "\n"]  {puts $i}
  289.         puts ""
  290.         exit
  291.     }
  292.        
  293.     set _fp [open $_found_dlls_tmpfile w]
  294.         puts $_fp "# All these .so files are confirmed to be copies of $_linvst "
  295.         puts $_fp "# and will be removed. If you don't want any of them to be removed, delete "
  296.         puts $_fp "# its corresponding line in this document before saving and closing the document."
  297.         puts $_fp "# You can obviously delete all lines then save and close, which has the same effect "
  298.         puts $_fp "# as cancelling the whole operation altogether."
  299.         puts $_fp ""
  300.         foreach i [split $_found_sos "\n"]  {
  301.             if  {[p.compare $i $_linvst]}   {
  302.                 puts $_fp $i
  303.             }
  304.         }
  305.     close $_fp
  306.  
  307.     eval "exec $::_editor $::_found_dlls_tmpfile <@stdin >@stdout"
  308.  
  309.     set _count 0
  310.     set _fp [open $_found_dlls_tmpfile r]
  311.         while   {-1 != [gets $_fp _line]}  {
  312.             if  {[file isfile $_line]}  {
  313.                 file delete $_line
  314.                 incr _count
  315.             }
  316.         }
  317.     close $_fp
  318.     puts "-> Done! $_count files removed."
  319.     exit
  320. }
  321. # ==================================================================
  322. # END OF REMOVE MODE
  323. # ==================================================================
  324.  
  325. # ==================================================================
  326. # NORMAL AND EXPRESS MODE
  327. # ==================================================================
  328. set _found_dlls [exec find [pwd] -iname "*.dll"]
  329.  
  330. foreach i $_blackList   {
  331.     lappend _blackList_cleaned [file rootname $i]
  332. }
  333.  
  334. foreach i [split $_found_dlls "\n"] {
  335.     if  {[lsearch -nocase $_blackList_cleaned [file rootname [file tail $i]]] >= 0} {
  336.         lappend _blacklisted $i
  337.         continue
  338.     }
  339.  
  340.     set _dir [file dirname $i]
  341.     if  {[file isfile $_dir/[file rootname [file tail $i]].so]} {
  342.         if  {![p.compare $_dir/[file rootname [file tail $i]].so $_linvst]} {
  343.             lappend _conflicts $i
  344.         }
  345.         continue
  346.     }
  347.    
  348.     lappend _dll_final_list $i
  349. }
  350.  
  351. if  {![info exists _blacklisted] && ![info exists _conflicts] && ![info exists _dll_final_list]}    {
  352.     puts ""
  353.     puts "No .dll files without a proper .so counterpart found."
  354.     puts "No conflicts or blacklist matches either."
  355.     puts "Nothing to do now. Maybe next time."
  356.     puts ""
  357.     exit
  358. }
  359.  
  360. set _fp [open $_found_dlls_tmpfile w]
  361.     puts $_fp "# Once you save and close this document, the operation will be executed "
  362.     puts $_fp "# automatically."
  363.     puts $_fp "# If you want to cancel/abort the entire operation, just delete all lines "
  364.     puts $_fp "# in this document, save and close."
  365.     puts $_fp ""
  366.  
  367.     if  {[info exists _blacklisted]}    {
  368.         puts $_fp "# Here is the list of files that will NOT be linked to linvst "
  369.         puts $_fp "# because they match at least one of the items in your blacklist: "
  370.         puts $_fp ""
  371.         foreach i $_blacklisted {puts $_fp "#$i"}
  372.         puts $_fp ""
  373.         puts $_fp "# If you think that any of the files above has been blacklisted in error "
  374.         puts $_fp "# and should be linked to linvst, just delete the # symbol at the beginning of its line "
  375.         puts $_fp "# before you save the document and close the text editor."
  376.         puts $_fp ""
  377.         puts $_fp "# --------------------------------"
  378.         puts $_fp ""
  379.     }
  380.  
  381.     if  {[info exists _conflicts]}  {
  382.         puts $_fp "# This is the list of '.dll' files that already have their own '.so' counterpart, "
  383.         puts $_fp "# but the .so file is not a copy of your linvst file. If you think they should be overwritten "
  384.         puts $_fp "# with your linvst.so file, just remove the # symbol at the beginning of their respective lines. "
  385.         puts $_fp "# BE CAREFUL with that decision. You may overwrite a file that is provided by the plugin "
  386.         puts $_fp "# vendor/developer and is required for proper operation of the plugin."
  387.         puts $_fp ""
  388.         foreach i $_conflicts   {puts $_fp "#$i"}
  389.         puts $_fp ""
  390.         puts $_fp "# --------------------------------"
  391.     }
  392.  
  393.     if  {[info exists _dll_final_list]} {
  394.         puts $_fp "# This is the list of files that WILL be linked to linvst."
  395.         puts $_fp "# After inspecting the list, save the document and close the text editor."
  396.         puts $_fp "# If you want to exclude any of the files below, delete it from the list here "
  397.         puts $_fp "# before saving the document and closing the text editor."
  398.         puts $_fp "# If you don't want to have to exclude it manually again in the future, "
  399.         puts $_fp "# add it to the blacklist in the USER OPTIONS section of the script."
  400.         puts $_fp ""
  401.  
  402.         foreach i $_dll_final_list  {puts $_fp "$i"}
  403.     }
  404.  
  405. close $_fp
  406.  
  407. if  {$_mode != "express"}   {eval "exec $::_editor $::_found_dlls_tmpfile <@stdin >@stdout"}
  408.  
  409. set _count 0
  410. set _fp [open $_found_dlls_tmpfile r]
  411.     while   {-1 != [gets $_fp _line]}  {
  412.         if  {[regexp "^\s*#" $_line]}   {continue}
  413.         if  {[file isfile $_line]}  {
  414.             file copy -force $_linvst [file dirname $_line]/[file rootname [file tail $_line]].so
  415.             incr _count
  416.         }
  417.         if  {[info exists _blacklisted]}    {
  418.             set _lsearch    [lsearch -nocase $_blacklisted $_line]
  419.             if  {$_lsearch >= 0}    {
  420.                 lappend _overridden $_line
  421.                 set _blacklisted [lreplace $_blacklisted $_lsearch $_lsearch]
  422.             }
  423.             if  {[llength $_blacklisted] == 0}  {unset _blacklisted}
  424.         }
  425.         if  {[info exists _conflicts]}  {
  426.             set _lsearch    [lsearch -nocase $_conflicts $_line]
  427.             if  {$_lsearch >= 0}    {
  428.                 lappend _overridden $_line
  429.                 set _conflicts [lreplace $_conflicts $_lsearch $_lsearch]
  430.             }
  431.             if  {[llength $_conflicts] == 0}    {unset _conflicts}
  432.         }
  433.     }
  434. close $_fp
  435.  
  436. # ==================================================================
  437. # FINAL OUTPUT
  438. # ==================================================================
  439. puts ""
  440. if  {[info exists _dll_final_list]} {
  441.     puts "-> Done. $_count new .dll to .so copies were performed."
  442. }
  443. if  {[info exists _blacklisted]}    {
  444.     puts "-> Excluded by blacklisting:"
  445.     foreach i $_blacklisted {puts $i}
  446. }
  447. if  {[info exists _overridden]} {
  448.     puts "-> These files were blacklisted, but were copied because you chose to override the blacklist:"
  449.     foreach i $_overridden  {puts $i}
  450. }
  451. if  {[info exists _conflicts]}  {
  452.     puts "-> Excluded due to name conflicts:"
  453.     foreach i $_conflicts   {puts $i}
  454. }
  455. puts ""
  456. exit
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top