├── .gitignore ├── LICENSE ├── README.md ├── addPolicy.py ├── foreign └── usr │ ├── bin │ └── anypaste │ └── share │ ├── licenses │ └── wgetpaste │ │ └── LICENSE │ ├── wgetpaste │ └── wgetpaste.example │ └── zsh │ └── site-functions │ └── _wgetpaste ├── getlog ├── icons ├── advanced.svg ├── advanced_16x16.png ├── advanced_30x30.png ├── advanced_48x48.png ├── archive.png ├── archive_48x48.png ├── archive_60x60.png ├── backup.png ├── cr_30x30.png ├── cr_48x48.png ├── dlmode.png ├── error.png ├── extract_48x48.png ├── flash_48x48.png ├── flash_60x60.jpg ├── flashkdz_70x48.png ├── flashkdz_93x64.png ├── log_16x16.png ├── ok_64x64.png ├── salt_icon.png ├── salt_logo.png ├── salt_logo_128x128.png ├── salt_logo_30x30.png ├── salt_logo_64x64.png ├── terminal.png ├── terminal_30x30.png ├── terminal_60x60.png ├── update_48x48.png └── warning_64x64.png ├── install-desktop.sh ├── kdzmanager.sh ├── payload-dumper-go ├── reboot ├── salt ├── salt.func ├── salt.hashes └── salt.vars /.gitignore: -------------------------------------------------------------------------------- 1 | *.desktop 2 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU LESSER GENERAL PUBLIC LICENSE 2 | Version 2.1, February 1999 3 | 4 | Copyright (C) 1991, 1999 Free Software Foundation, Inc. 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | [This is the first released version of the Lesser GPL. It also counts 10 | as the successor of the GNU Library Public License, version 2, hence 11 | the version number 2.1.] 12 | 13 | Preamble 14 | 15 | The licenses for most software are designed to take away your 16 | freedom to share and change it. By contrast, the GNU General Public 17 | Licenses are intended to guarantee your freedom to share and change 18 | free software--to make sure the software is free for all its users. 19 | 20 | This license, the Lesser General Public License, applies to some 21 | specially designated software packages--typically libraries--of the 22 | Free Software Foundation and other authors who decide to use it. You 23 | can use it too, but we suggest you first think carefully about whether 24 | this license or the ordinary General Public License is the better 25 | strategy to use in any particular case, based on the explanations below. 26 | 27 | When we speak of free software, we are referring to freedom of use, 28 | not price. Our General Public Licenses are designed to make sure that 29 | you have the freedom to distribute copies of free software (and charge 30 | for this service if you wish); that you receive source code or can get 31 | it if you want it; that you can change the software and use pieces of 32 | it in new free programs; and that you are informed that you can do 33 | these things. 34 | 35 | To protect your rights, we need to make restrictions that forbid 36 | distributors to deny you these rights or to ask you to surrender these 37 | rights. These restrictions translate to certain responsibilities for 38 | you if you distribute copies of the library or if you modify it. 39 | 40 | For example, if you distribute copies of the library, whether gratis 41 | or for a fee, you must give the recipients all the rights that we gave 42 | you. You must make sure that they, too, receive or can get the source 43 | code. If you link other code with the library, you must provide 44 | complete object files to the recipients, so that they can relink them 45 | with the library after making changes to the library and recompiling 46 | it. And you must show them these terms so they know their rights. 47 | 48 | We protect your rights with a two-step method: (1) we copyright the 49 | library, and (2) we offer you this license, which gives you legal 50 | permission to copy, distribute and/or modify the library. 51 | 52 | To protect each distributor, we want to make it very clear that 53 | there is no warranty for the free library. Also, if the library is 54 | modified by someone else and passed on, the recipients should know 55 | that what they have is not the original version, so that the original 56 | author's reputation will not be affected by problems that might be 57 | introduced by others. 58 | 59 | Finally, software patents pose a constant threat to the existence of 60 | any free program. We wish to make sure that a company cannot 61 | effectively restrict the users of a free program by obtaining a 62 | restrictive license from a patent holder. Therefore, we insist that 63 | any patent license obtained for a version of the library must be 64 | consistent with the full freedom of use specified in this license. 65 | 66 | Most GNU software, including some libraries, is covered by the 67 | ordinary GNU General Public License. This license, the GNU Lesser 68 | General Public License, applies to certain designated libraries, and 69 | is quite different from the ordinary General Public License. We use 70 | this license for certain libraries in order to permit linking those 71 | libraries into non-free programs. 72 | 73 | When a program is linked with a library, whether statically or using 74 | a shared library, the combination of the two is legally speaking a 75 | combined work, a derivative of the original library. The ordinary 76 | General Public License therefore permits such linking only if the 77 | entire combination fits its criteria of freedom. The Lesser General 78 | Public License permits more lax criteria for linking other code with 79 | the library. 80 | 81 | We call this license the "Lesser" General Public License because it 82 | does Less to protect the user's freedom than the ordinary General 83 | Public License. It also provides other free software developers Less 84 | of an advantage over competing non-free programs. These disadvantages 85 | are the reason we use the ordinary General Public License for many 86 | libraries. However, the Lesser license provides advantages in certain 87 | special circumstances. 88 | 89 | For example, on rare occasions, there may be a special need to 90 | encourage the widest possible use of a certain library, so that it becomes 91 | a de-facto standard. To achieve this, non-free programs must be 92 | allowed to use the library. A more frequent case is that a free 93 | library does the same job as widely used non-free libraries. In this 94 | case, there is little to gain by limiting the free library to free 95 | software only, so we use the Lesser General Public License. 96 | 97 | In other cases, permission to use a particular library in non-free 98 | programs enables a greater number of people to use a large body of 99 | free software. For example, permission to use the GNU C Library in 100 | non-free programs enables many more people to use the whole GNU 101 | operating system, as well as its variant, the GNU/Linux operating 102 | system. 103 | 104 | Although the Lesser General Public License is Less protective of the 105 | users' freedom, it does ensure that the user of a program that is 106 | linked with the Library has the freedom and the wherewithal to run 107 | that program using a modified version of the Library. 108 | 109 | The precise terms and conditions for copying, distribution and 110 | modification follow. Pay close attention to the difference between a 111 | "work based on the library" and a "work that uses the library". The 112 | former contains code derived from the library, whereas the latter must 113 | be combined with the library in order to run. 114 | 115 | GNU LESSER GENERAL PUBLIC LICENSE 116 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 117 | 118 | 0. This License Agreement applies to any software library or other 119 | program which contains a notice placed by the copyright holder or 120 | other authorized party saying it may be distributed under the terms of 121 | this Lesser General Public License (also called "this License"). 122 | Each licensee is addressed as "you". 123 | 124 | A "library" means a collection of software functions and/or data 125 | prepared so as to be conveniently linked with application programs 126 | (which use some of those functions and data) to form executables. 127 | 128 | The "Library", below, refers to any such software library or work 129 | which has been distributed under these terms. A "work based on the 130 | Library" means either the Library or any derivative work under 131 | copyright law: that is to say, a work containing the Library or a 132 | portion of it, either verbatim or with modifications and/or translated 133 | straightforwardly into another language. (Hereinafter, translation is 134 | included without limitation in the term "modification".) 135 | 136 | "Source code" for a work means the preferred form of the work for 137 | making modifications to it. For a library, complete source code means 138 | all the source code for all modules it contains, plus any associated 139 | interface definition files, plus the scripts used to control compilation 140 | and installation of the library. 141 | 142 | Activities other than copying, distribution and modification are not 143 | covered by this License; they are outside its scope. The act of 144 | running a program using the Library is not restricted, and output from 145 | such a program is covered only if its contents constitute a work based 146 | on the Library (independent of the use of the Library in a tool for 147 | writing it). Whether that is true depends on what the Library does 148 | and what the program that uses the Library does. 149 | 150 | 1. You may copy and distribute verbatim copies of the Library's 151 | complete source code as you receive it, in any medium, provided that 152 | you conspicuously and appropriately publish on each copy an 153 | appropriate copyright notice and disclaimer of warranty; keep intact 154 | all the notices that refer to this License and to the absence of any 155 | warranty; and distribute a copy of this License along with the 156 | Library. 157 | 158 | You may charge a fee for the physical act of transferring a copy, 159 | and you may at your option offer warranty protection in exchange for a 160 | fee. 161 | 162 | 2. You may modify your copy or copies of the Library or any portion 163 | of it, thus forming a work based on the Library, and copy and 164 | distribute such modifications or work under the terms of Section 1 165 | above, provided that you also meet all of these conditions: 166 | 167 | a) The modified work must itself be a software library. 168 | 169 | b) You must cause the files modified to carry prominent notices 170 | stating that you changed the files and the date of any change. 171 | 172 | c) You must cause the whole of the work to be licensed at no 173 | charge to all third parties under the terms of this License. 174 | 175 | d) If a facility in the modified Library refers to a function or a 176 | table of data to be supplied by an application program that uses 177 | the facility, other than as an argument passed when the facility 178 | is invoked, then you must make a good faith effort to ensure that, 179 | in the event an application does not supply such function or 180 | table, the facility still operates, and performs whatever part of 181 | its purpose remains meaningful. 182 | 183 | (For example, a function in a library to compute square roots has 184 | a purpose that is entirely well-defined independent of the 185 | application. Therefore, Subsection 2d requires that any 186 | application-supplied function or table used by this function must 187 | be optional: if the application does not supply it, the square 188 | root function must still compute square roots.) 189 | 190 | These requirements apply to the modified work as a whole. If 191 | identifiable sections of that work are not derived from the Library, 192 | and can be reasonably considered independent and separate works in 193 | themselves, then this License, and its terms, do not apply to those 194 | sections when you distribute them as separate works. But when you 195 | distribute the same sections as part of a whole which is a work based 196 | on the Library, the distribution of the whole must be on the terms of 197 | this License, whose permissions for other licensees extend to the 198 | entire whole, and thus to each and every part regardless of who wrote 199 | it. 200 | 201 | Thus, it is not the intent of this section to claim rights or contest 202 | your rights to work written entirely by you; rather, the intent is to 203 | exercise the right to control the distribution of derivative or 204 | collective works based on the Library. 205 | 206 | In addition, mere aggregation of another work not based on the Library 207 | with the Library (or with a work based on the Library) on a volume of 208 | a storage or distribution medium does not bring the other work under 209 | the scope of this License. 210 | 211 | 3. You may opt to apply the terms of the ordinary GNU General Public 212 | License instead of this License to a given copy of the Library. To do 213 | this, you must alter all the notices that refer to this License, so 214 | that they refer to the ordinary GNU General Public License, version 2, 215 | instead of to this License. (If a newer version than version 2 of the 216 | ordinary GNU General Public License has appeared, then you can specify 217 | that version instead if you wish.) Do not make any other change in 218 | these notices. 219 | 220 | Once this change is made in a given copy, it is irreversible for 221 | that copy, so the ordinary GNU General Public License applies to all 222 | subsequent copies and derivative works made from that copy. 223 | 224 | This option is useful when you wish to copy part of the code of 225 | the Library into a program that is not a library. 226 | 227 | 4. You may copy and distribute the Library (or a portion or 228 | derivative of it, under Section 2) in object code or executable form 229 | under the terms of Sections 1 and 2 above provided that you accompany 230 | it with the complete corresponding machine-readable source code, which 231 | must be distributed under the terms of Sections 1 and 2 above on a 232 | medium customarily used for software interchange. 233 | 234 | If distribution of object code is made by offering access to copy 235 | from a designated place, then offering equivalent access to copy the 236 | source code from the same place satisfies the requirement to 237 | distribute the source code, even though third parties are not 238 | compelled to copy the source along with the object code. 239 | 240 | 5. A program that contains no derivative of any portion of the 241 | Library, but is designed to work with the Library by being compiled or 242 | linked with it, is called a "work that uses the Library". Such a 243 | work, in isolation, is not a derivative work of the Library, and 244 | therefore falls outside the scope of this License. 245 | 246 | However, linking a "work that uses the Library" with the Library 247 | creates an executable that is a derivative of the Library (because it 248 | contains portions of the Library), rather than a "work that uses the 249 | library". The executable is therefore covered by this License. 250 | Section 6 states terms for distribution of such executables. 251 | 252 | When a "work that uses the Library" uses material from a header file 253 | that is part of the Library, the object code for the work may be a 254 | derivative work of the Library even though the source code is not. 255 | Whether this is true is especially significant if the work can be 256 | linked without the Library, or if the work is itself a library. The 257 | threshold for this to be true is not precisely defined by law. 258 | 259 | If such an object file uses only numerical parameters, data 260 | structure layouts and accessors, and small macros and small inline 261 | functions (ten lines or less in length), then the use of the object 262 | file is unrestricted, regardless of whether it is legally a derivative 263 | work. (Executables containing this object code plus portions of the 264 | Library will still fall under Section 6.) 265 | 266 | Otherwise, if the work is a derivative of the Library, you may 267 | distribute the object code for the work under the terms of Section 6. 268 | Any executables containing that work also fall under Section 6, 269 | whether or not they are linked directly with the Library itself. 270 | 271 | 6. As an exception to the Sections above, you may also combine or 272 | link a "work that uses the Library" with the Library to produce a 273 | work containing portions of the Library, and distribute that work 274 | under terms of your choice, provided that the terms permit 275 | modification of the work for the customer's own use and reverse 276 | engineering for debugging such modifications. 277 | 278 | You must give prominent notice with each copy of the work that the 279 | Library is used in it and that the Library and its use are covered by 280 | this License. You must supply a copy of this License. If the work 281 | during execution displays copyright notices, you must include the 282 | copyright notice for the Library among them, as well as a reference 283 | directing the user to the copy of this License. Also, you must do one 284 | of these things: 285 | 286 | a) Accompany the work with the complete corresponding 287 | machine-readable source code for the Library including whatever 288 | changes were used in the work (which must be distributed under 289 | Sections 1 and 2 above); and, if the work is an executable linked 290 | with the Library, with the complete machine-readable "work that 291 | uses the Library", as object code and/or source code, so that the 292 | user can modify the Library and then relink to produce a modified 293 | executable containing the modified Library. (It is understood 294 | that the user who changes the contents of definitions files in the 295 | Library will not necessarily be able to recompile the application 296 | to use the modified definitions.) 297 | 298 | b) Use a suitable shared library mechanism for linking with the 299 | Library. A suitable mechanism is one that (1) uses at run time a 300 | copy of the library already present on the user's computer system, 301 | rather than copying library functions into the executable, and (2) 302 | will operate properly with a modified version of the library, if 303 | the user installs one, as long as the modified version is 304 | interface-compatible with the version that the work was made with. 305 | 306 | c) Accompany the work with a written offer, valid for at 307 | least three years, to give the same user the materials 308 | specified in Subsection 6a, above, for a charge no more 309 | than the cost of performing this distribution. 310 | 311 | d) If distribution of the work is made by offering access to copy 312 | from a designated place, offer equivalent access to copy the above 313 | specified materials from the same place. 314 | 315 | e) Verify that the user has already received a copy of these 316 | materials or that you have already sent this user a copy. 317 | 318 | For an executable, the required form of the "work that uses the 319 | Library" must include any data and utility programs needed for 320 | reproducing the executable from it. However, as a special exception, 321 | the materials to be distributed need not include anything that is 322 | normally distributed (in either source or binary form) with the major 323 | components (compiler, kernel, and so on) of the operating system on 324 | which the executable runs, unless that component itself accompanies 325 | the executable. 326 | 327 | It may happen that this requirement contradicts the license 328 | restrictions of other proprietary libraries that do not normally 329 | accompany the operating system. Such a contradiction means you cannot 330 | use both them and the Library together in an executable that you 331 | distribute. 332 | 333 | 7. You may place library facilities that are a work based on the 334 | Library side-by-side in a single library together with other library 335 | facilities not covered by this License, and distribute such a combined 336 | library, provided that the separate distribution of the work based on 337 | the Library and of the other library facilities is otherwise 338 | permitted, and provided that you do these two things: 339 | 340 | a) Accompany the combined library with a copy of the same work 341 | based on the Library, uncombined with any other library 342 | facilities. This must be distributed under the terms of the 343 | Sections above. 344 | 345 | b) Give prominent notice with the combined library of the fact 346 | that part of it is a work based on the Library, and explaining 347 | where to find the accompanying uncombined form of the same work. 348 | 349 | 8. You may not copy, modify, sublicense, link with, or distribute 350 | the Library except as expressly provided under this License. Any 351 | attempt otherwise to copy, modify, sublicense, link with, or 352 | distribute the Library is void, and will automatically terminate your 353 | rights under this License. However, parties who have received copies, 354 | or rights, from you under this License will not have their licenses 355 | terminated so long as such parties remain in full compliance. 356 | 357 | 9. You are not required to accept this License, since you have not 358 | signed it. However, nothing else grants you permission to modify or 359 | distribute the Library or its derivative works. These actions are 360 | prohibited by law if you do not accept this License. Therefore, by 361 | modifying or distributing the Library (or any work based on the 362 | Library), you indicate your acceptance of this License to do so, and 363 | all its terms and conditions for copying, distributing or modifying 364 | the Library or works based on it. 365 | 366 | 10. Each time you redistribute the Library (or any work based on the 367 | Library), the recipient automatically receives a license from the 368 | original licensor to copy, distribute, link with or modify the Library 369 | subject to these terms and conditions. You may not impose any further 370 | restrictions on the recipients' exercise of the rights granted herein. 371 | You are not responsible for enforcing compliance by third parties with 372 | this License. 373 | 374 | 11. If, as a consequence of a court judgment or allegation of patent 375 | infringement or for any other reason (not limited to patent issues), 376 | conditions are imposed on you (whether by court order, agreement or 377 | otherwise) that contradict the conditions of this License, they do not 378 | excuse you from the conditions of this License. If you cannot 379 | distribute so as to satisfy simultaneously your obligations under this 380 | License and any other pertinent obligations, then as a consequence you 381 | may not distribute the Library at all. For example, if a patent 382 | license would not permit royalty-free redistribution of the Library by 383 | all those who receive copies directly or indirectly through you, then 384 | the only way you could satisfy both it and this License would be to 385 | refrain entirely from distribution of the Library. 386 | 387 | If any portion of this section is held invalid or unenforceable under any 388 | particular circumstance, the balance of the section is intended to apply, 389 | and the section as a whole is intended to apply in other circumstances. 390 | 391 | It is not the purpose of this section to induce you to infringe any 392 | patents or other property right claims or to contest validity of any 393 | such claims; this section has the sole purpose of protecting the 394 | integrity of the free software distribution system which is 395 | implemented by public license practices. Many people have made 396 | generous contributions to the wide range of software distributed 397 | through that system in reliance on consistent application of that 398 | system; it is up to the author/donor to decide if he or she is willing 399 | to distribute software through any other system and a licensee cannot 400 | impose that choice. 401 | 402 | This section is intended to make thoroughly clear what is believed to 403 | be a consequence of the rest of this License. 404 | 405 | 12. If the distribution and/or use of the Library is restricted in 406 | certain countries either by patents or by copyrighted interfaces, the 407 | original copyright holder who places the Library under this License may add 408 | an explicit geographical distribution limitation excluding those countries, 409 | so that distribution is permitted only in or among countries not thus 410 | excluded. In such case, this License incorporates the limitation as if 411 | written in the body of this License. 412 | 413 | 13. The Free Software Foundation may publish revised and/or new 414 | versions of the Lesser General Public License from time to time. 415 | Such new versions will be similar in spirit to the present version, 416 | but may differ in detail to address new problems or concerns. 417 | 418 | Each version is given a distinguishing version number. If the Library 419 | specifies a version number of this License which applies to it and 420 | "any later version", you have the option of following the terms and 421 | conditions either of that version or of any later version published by 422 | the Free Software Foundation. If the Library does not specify a 423 | license version number, you may choose any version ever published by 424 | the Free Software Foundation. 425 | 426 | 14. If you wish to incorporate parts of the Library into other free 427 | programs whose distribution conditions are incompatible with these, 428 | write to the author to ask for permission. For software which is 429 | copyrighted by the Free Software Foundation, write to the Free 430 | Software Foundation; we sometimes make exceptions for this. Our 431 | decision will be guided by the two goals of preserving the free status 432 | of all derivatives of our free software and of promoting the sharing 433 | and reuse of software generally. 434 | 435 | NO WARRANTY 436 | 437 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO 438 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. 439 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR 440 | OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY 441 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE 442 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 443 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE 444 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME 445 | THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 446 | 447 | 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN 448 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY 449 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU 450 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR 451 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE 452 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING 453 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A 454 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF 455 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 456 | DAMAGES. 457 | 458 | END OF TERMS AND CONDITIONS 459 | 460 | How to Apply These Terms to Your New Libraries 461 | 462 | If you develop a new library, and you want it to be of the greatest 463 | possible use to the public, we recommend making it free software that 464 | everyone can redistribute and change. You can do so by permitting 465 | redistribution under these terms (or, alternatively, under the terms of the 466 | ordinary General Public License). 467 | 468 | To apply these terms, attach the following notices to the library. It is 469 | safest to attach them to the start of each source file to most effectively 470 | convey the exclusion of warranty; and each file should have at least the 471 | "copyright" line and a pointer to where the full notice is found. 472 | 473 | 474 | Copyright (C) 475 | 476 | This library is free software; you can redistribute it and/or 477 | modify it under the terms of the GNU Lesser General Public 478 | License as published by the Free Software Foundation; either 479 | version 2.1 of the License, or (at your option) any later version. 480 | 481 | This library is distributed in the hope that it will be useful, 482 | but WITHOUT ANY WARRANTY; without even the implied warranty of 483 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 484 | Lesser General Public License for more details. 485 | 486 | You should have received a copy of the GNU Lesser General Public 487 | License along with this library; if not, write to the Free Software 488 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 489 | USA 490 | 491 | Also add information on how to contact you by electronic and paper mail. 492 | 493 | You should also get your employer (if you work as a programmer) or your 494 | school, if any, to sign a "copyright disclaimer" for the library, if 495 | necessary. Here is a sample; alter the names: 496 | 497 | Yoyodyne, Inc., hereby disclaims all copyright interest in the 498 | library `Frob' (a library for tweaking knobs) written by James Random 499 | Hacker. 500 | 501 | , 1 April 1990 502 | Ty Coon, President of Vice 503 | 504 | That's all there is to it! 505 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SALT 2 | SALT - [S]teadfasterX [A]ll-in-one [L]G [T]ool 3 | -------------------------------------------------------------------------------- /addPolicy.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import sys, os 4 | 5 | path = sys.argv[1] 6 | 7 | policyData = """ 8 | 11 | 12 | 13 | 14 | Tranparent authentication for SALT 15 | 16 | yes 17 | yes 18 | yes 19 | 20 | {} 21 | true 22 | 23 | 24 | """ 25 | 26 | if not os.path.isdir('/usr/share/polkit-1/actions'): 27 | print("The polkit directory does not exist/is not in the expected location. Please add the policy manually") 28 | exit() 29 | if os.path.isfile('/usr/share/polkit-1/actions/it.binbash.pkexec.salt.policy'): 30 | # Possibly an outdated version so we will remove it to be safe 31 | os.remove('/usr/share/polkit-1/actions/it.binbash.pkexec.salt.policy') 32 | 33 | with open('/usr/share/polkit-1/actions/it.binbash.pkexec.salt.policy','w') as policyFile: 34 | policyFile.write(policyData.format(path)) 35 | -------------------------------------------------------------------------------- /foreign/usr/bin/anypaste: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This is anypaste. Authored by Mark Polyakov (see markasoftware.com) 4 | # This software is released under the GPLv3, see gnu.org 5 | # Homepage at anypaste.xyz 6 | 7 | # shellcheck disable=2128 8 | # shellcheck disable=2064 9 | 10 | export ap_version ap_mac ap_path ap_human_name ap_human_name_escaped ap_mime ap_size ap_plugin ap_last_stdout 11 | ap_version_text='Anypaste 1.1.6' 12 | [[ $OSTYPE == darwin* ]] && ap_mac='true' || ap_mac='false' 13 | shopt -s extglob 14 | 15 | # BEGIN PLUGINS 16 | 17 | # COMMON PLUGIN FUNCTIONS 18 | 19 | function check_size { 20 | if ! [[ $ap_size -lt $1 ]] 21 | then 22 | echo "${ap_WARNING}WARNING: File is of compatible type for plugin '$ap_plugin', but is above size limit of $1 bytes${ap_RESET}" >&2 23 | return 1 24 | fi 25 | } 26 | 27 | function curl_form_upload { 28 | local main_field 29 | main_field=$1 30 | shift 31 | curl -#fF "$main_field=@\"$ap_path\";type=$ap_mime" -A "$ap_ua" "$@" || { echo "${ap_ERROR}ERROR: Upload request did not return HTTP 200!${ap_RESET}" >&2 && return 1; } 32 | } 33 | 34 | function curl_file_upload { 35 | # curl supports globby stuff in -T, so we must escape. 36 | local t_arg 37 | t_arg=$2 38 | # I've officially broken emacs indentation 39 | t_arg=${t_arg//[/\\[} 40 | t_arg=${t_arg//]/\\]} 41 | t_arg=${t_arg//{/\\{} 42 | t_arg=${t_arg//\}/\\\}} # honestly no idea how bash parses this right 43 | curl "-X$1" -#fT "$t_arg" -A "$ap_ua" "$3" || { echo "${ap_ERROR}ERROR: Upload request did not return HTTP 200!${ap_RESET}" >&2 && return 1; } 44 | } 45 | 46 | function curl_get { 47 | curl -fsA "$ap_ua" "$1" || { echo "${ap_ERROR}ERROR: GET request did not return HTTP 200!${ap_RESET}" >&2 && return 1; } 48 | } 49 | 50 | # string json, string key -> string value 51 | # make sure shopt -s extglob is on before using 52 | # not standards compliant in any way shape or form, is designed specifically to work around strange 53 | # cases present in anypaste plugins 54 | function json_parse { 55 | local infernal_agony 56 | infernal_agony="$1" 57 | # remove everything before the value, not including the leading quote 58 | eval "infernal_agony=\${infernal_agony##*\\\"$2\\\"*( ):*( )}" 59 | # does it start with a quote? 60 | if [[ $infernal_agony == \"* ]] 61 | then 62 | # remove initial quote 63 | infernal_agony=${infernal_agony:1} 64 | infernal_agony=${infernal_agony%%\"*} 65 | # remove backslashes escaping things such as forward slashes. This breaks if there's a literal backslash because it gets completely removed, but I don't think that's a problem for us... 66 | infernal_agony=${infernal_agony//\\/} 67 | else 68 | # it can only be a number or a boolean, so it can't contain special characters at this point 69 | infernal_agony=${infernal_agony%%[ ,\}]*} 70 | fi 71 | echo "$infernal_agony" 72 | } 73 | 74 | # string -> url-encoded string 75 | # param unencoded string 76 | # @return $ap_url_encode_return the encoded string 77 | # from https://stackoverflow.com/a/10660730 78 | ap_url_encode() { 79 | local strlen=${#1} 80 | ap_url_encode_return='' 81 | local pos c o 82 | 83 | for (( pos=0 ; pos&2 131 | echo "Direct: $ixio_link" 132 | echo 133 | ;; 134 | get_info) 135 | echo '[name]' 136 | echo 'ix.io' 137 | echo '[description]' 138 | echo 'Simple plain-text host with direct links only.' 139 | echo '[tags]' 140 | echo 'permanent' 141 | echo 'direct' 142 | ;; 143 | esac 144 | } 145 | 146 | function pdefault { 147 | case $1 in 148 | check_eligibility) 149 | [[ $ap_mime == text/* ]] # TODO: size? 150 | ;; 151 | upload) 152 | # using curl's @ instead of < causes a problem 153 | pdefault_link=$(curl -#A "$ap_ua" -o /dev/null -sw '%{redirect_url}' -F "code=<$ap_path" https://p.defau.lt/submit.php) || return 1 154 | echo >&2 155 | echo "Link: $pdefault_link" 156 | echo 157 | ;; 158 | get_info) 159 | echo '[name]' 160 | echo 'p.defau.lt' 161 | echo '[description]' 162 | echo 'Austere plain-text hosting site. The links might /seem/ direct, but they are actually html.' 163 | echo '[tags]' 164 | echo 'permanent' 165 | echo 'private' 166 | ;; 167 | esac 168 | } 169 | 170 | function paste2 { 171 | case $1 in 172 | check_eligibility) 173 | [[ $ap_mime == text/* ]] # TODO: size? 174 | ;; 175 | upload) 176 | paste2_link=$(curl -#A "$ap_ua" -o /dev/null -sw '%{redirect_url}' -F "code=<$ap_path" -F description= -F lang=text -F parent= https://paste2.org) || return 1 177 | echo >&2 178 | echo "Link: $paste2_link" 179 | echo 180 | ;; 181 | get_info) 182 | echo '[name]' 183 | echo 'Paste2' 184 | echo '[description]' 185 | echo 'Simple plain-text hosting site.' 186 | echo '[tags]' 187 | echo 'permanent' 188 | echo 'private' 189 | ;; 190 | esac 191 | } 192 | 193 | function pastie { 194 | case $1 in 195 | check_eligibility) 196 | [[ $ap_mime == text/* ]] # TODO: size? 197 | ;; 198 | upload) 199 | pastie_link=$(curl -#A "$ap_ua" -o /dev/null -sw '%{redirect_url}' --data 'language=plaintext' --data-urlencode "content@$ap_path" http://pastie.org/pastes/create) || return 1 200 | echo 'Reminder: Pastie uploads are deleted 24 hours after upload!' >&2 201 | echo >&2 202 | echo "Link: $pastie_link" 203 | echo "Direct: $pastie_link/raw" 204 | echo 205 | ;; 206 | get_info) 207 | echo '[name]' 208 | echo 'Pastie' 209 | echo '[description]' 210 | echo 'Simple plain-text hosting site.' 211 | echo '[tags]' 212 | echo 'private' 213 | echo 'direct' 214 | ;; 215 | esac 216 | } 217 | 218 | function hastebin { 219 | case $1 in 220 | check_eligibility) 221 | [[ $ap_mime == text/* ]] && check_size 400000 222 | ;; 223 | upload) 224 | hastebin_json=$(curl_file_upload 'POST' "$ap_path" 'https://hastebin.skyra.pw/documents') || return 1 225 | hastebin_id=$(json_parse "$hastebin_json" 'key') 226 | echo 'Reminder: hastebin.com uploads are deleted 30 days after their last view!' >&2 227 | echo >&2 228 | echo "Link: https://hastebin.skyra.pw/$hastebin_id" 229 | echo "Direct: https://hastebin.skyra.pw/raw/$hastebin_id" 230 | echo 231 | ;; 232 | get_info) 233 | echo '[name]' 234 | echo 'Hastebin' 235 | echo '[description]' 236 | echo 'Plain-text host with syntax highlighting and forking. The original hastebin.com was changed, so we use hastebin.skyra.pw' 237 | echo '[tags]' 238 | echo 'private' 239 | echo 'direct' 240 | ;; 241 | esac 242 | } 243 | 244 | function fileio { 245 | case $1 in 246 | check_eligibility) 247 | check_size 5000000000 248 | ;; 249 | upload) 250 | fileio_json=$(curl_form_upload 'file' 'https://file.io') || return 1 251 | fileio_link=$(json_parse "$fileio_json" 'link') 252 | echo 'Reminder: file.io uploads are deleted after being download, or 14 days, whichever comes first!' >&2 253 | echo >&2 254 | echo "Direct: $fileio_link" 255 | echo 256 | ;; 257 | get_info) 258 | echo '[name]' 259 | echo 'file.io' 260 | echo '[description]' 261 | echo 'Snapchat for files: They are deleted after their first view. Generic; direct-links only' 262 | echo '[tags]' 263 | echo 'private' 264 | echo 'direct' 265 | ;; 266 | esac 267 | } 268 | 269 | function transfersh { 270 | case $1 in 271 | check_eligibility) 272 | check_size 10000000000 273 | ;; 274 | upload) 275 | transfersh_host=${transfersh_host:-https://transfer.sh} 276 | transfersh_link=$(curl_file_upload 'PUT' "$ap_path" "$transfersh_host/$ap_human_name_escaped") || return 1 277 | echo 'Reminder: transfer.sh uploads are deleted after 14 days!' >&2 278 | echo 'Transfer.sh links are *not* direct if you use a browser, but they can be curled!' >&2; 279 | echo >&2 280 | echo "Direct: $transfersh_link" 281 | echo 282 | ;; 283 | get_info) 284 | echo '[name]' 285 | echo 'transfer.sh' 286 | echo '[description]' 287 | echo 'Generic-file host with a popular, official CLI client. No ads.' 288 | echo '[tags]' 289 | echo 'private' 290 | echo '[config]' 291 | echo 'optional|transfersh_host|Protocol, domain name, and host of a transfer.sh site (default: https://transfer.sh)' 292 | ;; 293 | esac 294 | } 295 | 296 | function keepsh { 297 | case $1 in 298 | check_eligibility) 299 | check_size 500000000 300 | ;; 301 | upload) 302 | # ua spoof required 303 | local ap_ua_save=$ap_ua 304 | ap_ua='curl 7.64.0' 305 | keepsh_link=$(curl_file_upload PUT "$ap_path" "https://free.keep.sh") || return 1 306 | ap_ua=$ap_ua_save 307 | echo 'Reminder: keep.sh uploads are deleted after 24 hours!' >&2 308 | echo "Keep.sh's direct links cannot be curled, but work elsewhere." 309 | echo >&2 310 | echo "Link: $keepsh_link" 311 | echo "Direct: $keepsh_link/download" 312 | echo 313 | ;; 314 | get_info) 315 | echo '[name]' 316 | echo 'keep.sh' 317 | echo '[description]' 318 | echo 'Generic file host that officially supports curl. Free edition.' 319 | echo '[tags]' 320 | echo 'private' 321 | echo 'direct' 322 | echo 'deletable' 323 | ;; 324 | esac 325 | } 326 | 327 | function gofile { 328 | case $1 in 329 | check_eligibility) 330 | # unlimited file size, whatcha think of that? 331 | ;; 332 | upload) 333 | gofile_server_json=$(curl_get https://apiv2.gofile.io/getServer) || return 1 334 | gofile_server=$(json_parse "$gofile_server_json" server) 335 | if [[ -n "$gofile_token" ]] 336 | then 337 | gofile_upload_json=$(curl_form_upload file -F "token=$gofile_token" "https://${gofile_server}.gofile.io/uploadFile") || return 1 338 | else 339 | gofile_upload_json=$(curl_form_upload file "https://${gofile_server}.gofile.io/uploadFile") || return 1 340 | fi 341 | gofile_link=$(json_parse "$gofile_upload_json" downloadPage) 342 | gofile_direct=$(json_parse "$gofile_upload_json" directLink) 343 | [[ -z "$gofile_donor_p" ]] && echo 'Reminder: Gofile uploads are deleted after 10 days of inactivity.' >&2 344 | echo >&2 345 | echo "Link: $gofile_link" 346 | [[ -n "$gofile_donor_p" ]] && echo "Direct: $gofile_direct" 347 | echo 348 | ;; 349 | get_info) 350 | echo '[name]' 351 | echo 'Gofile' 352 | echo '[description]' 353 | echo 'Generic file host with official API and /unlimited/ upload size. Has a paid plan with permanent storage and direct links.' 354 | echo '[tags]' 355 | echo 'private' 356 | [[ -n "$gofile_token" ]] && echo 'deletable' 357 | [[ -n "$gofile_donor_p" ]] && echo 'permanent' 358 | [[ -n "$gofile_donor_p" ]] && echo 'direct' 359 | echo '[config]' 360 | echo 'optional|gofile_token|API token from "my profile" page. Allows editing or deleting uploaded files. If you are a donor, this will make direct links work and make uploads be permanent.' 361 | echo 'optional|gofile_donor_p|Set to a nonempty string to print out direct links, which will work only if you have a paid gofile account.' 362 | esac 363 | } 364 | 365 | function bayfiles { 366 | case $1 in 367 | check_eligibility) 368 | check_size 20000000000 369 | ;; 370 | upload) 371 | bayfiles_json=$(curl_form_upload file https://api.bayfiles.com/upload) || return 1 372 | bayfiles_link=$(json_parse "$bayfiles_json" short) 373 | bayfiles_direct=$(curl_get "$bayfiles_link" | grep -oE 'https://cdn-[0-9]+\.bayfiles\.com/.+?[^\\]">') || return 1 374 | bayfiles_direct=${bayfiles_direct%'"'>} 375 | echo >&2 376 | echo "Link: $bayfiles_link" 377 | echo "Direct: $bayfiles_direct" 378 | echo 379 | ;; 380 | get_info) 381 | echo '[name]' 382 | echo 'Bayfiles' 383 | echo '[description]' 384 | echo 'Generic file hosting site which used to be associated with the pirate bay?' 385 | echo '[tags]' 386 | echo 'private' 387 | echo 'permanent' 388 | echo 'direct' 389 | ;; 390 | esac 391 | } 392 | 393 | function pixhost { 394 | case $1 in 395 | check_eligibility) 396 | [[ $ap_mime == image/@(png|gif|jpeg) ]] && check_size 10000000 397 | ;; 398 | upload) 399 | pixhost_json=$(curl_form_upload img https://api.pixhost.to/images -F content_type=0 -F max_th_size=500) || return 1 400 | pixhost_link_slashed=$(json_parse "$pixhost_json" show_url) 401 | pixhost_thumbnail_slashed=$(json_parse "$pixhost_json" th_url) 402 | # they escape their slashes, monsters! 403 | pixhost_link=${pixhost_link_slashed//\\/} 404 | pixhost_thumbnail=${pixhost_thumbnail_slashed//\\/} 405 | # it's possible to get the actual direct image URL instead of the thumbnail, but they 406 | # clearly don't want hotlinking so I'll respect that. 407 | echo '' 408 | echo >&2 409 | echo "Link: $pixhost_link" 410 | echo "Direct: $pixhost_thumbnail" 411 | echo 412 | ;; 413 | get_info) 414 | echo '[name]' 415 | echo 'Pixhost' 416 | echo '[description]' 417 | echo 'Simple image host with official API. Direct links are scaled-down thumbnails.' 418 | echo '[tags]' 419 | echo 'private' 420 | echo 'permanent' 421 | echo 'direct' # idk if it really counts 422 | esac 423 | } 424 | 425 | function imgur { 426 | case $1 in 427 | check_eligibility) 428 | [[ $ap_mime == image/* ]] && check_size 100000000 429 | ;; 430 | upload) 431 | imgur_json=$(curl -#fF "image=@\"$ap_path\"" -F "name=\"$ap_human_name\"" \ 432 | -H "Authorization: Client-ID ${imgur_client_id:-c7e65b324a5ebe8}" \ 433 | -A "$ap_ua" \ 434 | 'https://api.imgur.com/3/image') || return 1 435 | imgur_json=${imgur_json//\\/} 436 | imgur_id=$(json_parse "$imgur_json" 'id') 437 | imgur_link=$(json_parse "$imgur_json" 'link') 438 | imgur_deletehash=$(json_parse "$imgur_json" 'deletehash') 439 | echo >&2 440 | echo "Link: https://imgur.com/$imgur_id" 441 | echo "Direct: $imgur_link" 442 | echo "Edit: https://imgur.com/edit?deletehash=$imgur_deletehash" 443 | echo "Delete: https://imgur.com/delete/$imgur_deletehash" 444 | echo 445 | ;; 446 | get_info) 447 | echo '[name]' 448 | echo 'Imgur' 449 | echo '[description]' 450 | echo 'The most popular image host in the world. We had to hard-code an API key, but it has rate limits. Use your own key if you plan to upload a lot, please!' 451 | echo '[tags]' 452 | echo 'private' 453 | echo 'editable' 454 | echo 'deletable' 455 | echo 'direct' 456 | echo '[config]' 457 | echo 'optional|imgur_client_id|Your Imgur API client ID. Your secret key is not needed, yay!' 458 | ;; 459 | esac 460 | } 461 | 462 | function streamable { 463 | case $1 in 464 | check_eligibility) 465 | ap_is_video || ap_is_gif || return 1 466 | check_size 10000000000 || return 1 467 | ;; 468 | upload) 469 | # shellcheck disable=2154 470 | streamable_json=$(curl -#fu "$streamable_email:$streamable_password" -F "file=@$ap_path" -A "$ap_ua" https://api.streamable.com/upload) || return 1 471 | streamable_shortcode=$(json_parse "$streamable_json" 'shortcode') 472 | echo >&2 473 | echo "Link: https://streamable.com/$streamable_shortcode" 474 | echo 475 | ;; 476 | get_info) 477 | echo '[name]' 478 | echo 'Streamable' 479 | echo '[description]' 480 | echo 'Video host. Very popular, transcodes for all platforms. Requires authentication (user/password, not API key).' 481 | echo '[tags]' 482 | echo 'private' 483 | echo 'permanent' 484 | echo '[config]' 485 | echo 'required|streamable_email|Account email address.' 486 | echo 'required|streamable_password|Account password.' 487 | ;; 488 | esac 489 | } 490 | 491 | function sendvid { 492 | case $1 in 493 | check_eligibility) 494 | ap_is_video && check_size 1000000000 495 | ;; 496 | upload) 497 | # Sendvid won't upload videos with certain file extensions, but will still encode them 498 | # and function properly if uploaded as a .mp4 499 | # Maybe time for them to switch to mime type checking? 500 | sendvid_json=$(curl -#fF "video=@\"$ap_path\";filename=${ap_human_name%.*}.mp4" -A "$ap_ua" https://sendvid.com/api/v1/videos) || return 1 501 | sendvid_pub=$(json_parse "$sendvid_json" 'slug') 502 | sendvid_priv=$(json_parse "$sendvid_json" 'secret') 503 | echo >&2 504 | echo "Link: https://sendvid.com/$sendvid_pub" 505 | echo "Delete/Edit: https://sendvid.com/$sendvid_pub?secret=$sendvid_priv" 506 | echo 507 | ;; 508 | get_info) 509 | echo '[name]' 510 | echo 'Sendvid' 511 | echo '[description]' 512 | echo 'Video host. Transcodes for all platforms.' 513 | echo '[tags]' 514 | echo 'private' 515 | echo 'permanent' 516 | echo 'editable' 517 | echo 'deletable' 518 | ;; 519 | esac 520 | } 521 | 522 | function gfycat { 523 | case $1 in 524 | check_eligibility) 525 | ap_is_video || ap_is_gif 526 | ;; 527 | upload) 528 | # CHANGE NOTICE: There used to be a gfycat_duplicates variable which skipped waiting for encoding 529 | # at the price of not deduplicating on gfycat's end. However, it seems that this sometimes results 530 | # in URLs which take a *very* long time to encode, even for very short videos. It seems polling status 531 | # might actually speed up the encoding process? I'm not sure. Either way, that's not configurable anymore. 532 | 533 | # this is one of the more complex ones 534 | # get the key/name of the gfy 535 | gfy_init_json=$(curl -sfXPOST -A "$ap_ua" https://api.gfycat.com/v1/gfycats) || { 536 | echo 'Getting gfycat key did not return HTTP 200!' >&2 537 | return 1; 538 | } 539 | gfy_name=$(json_parse "$gfy_init_json" 'gfyname') 540 | # the file being uploaded must have the same name as the key 541 | # since i don't know how to set it using curl options, I'm 542 | # just using a symbolic link with the correct name. 543 | 544 | # quoting is mostly safe here -- no quote characters in gfy names or TMPDIR 545 | gfycat_tmpdir=${TMPDIR:-/tmp} 546 | trap "rm -f '$gfycat_tmpdir/$gfy_name'" EXIT 547 | ln -s "$ap_path" "$gfycat_tmpdir/$gfy_name" 548 | curl_file_upload 'PUT' "$gfycat_tmpdir/$gfy_name" 'https://filedrop.gfycat.com' > /dev/null || return 1 549 | rm -f "$gfycat_tmpdir/$gfy_name" 550 | # We have to wait for encoding (unlike with streamable) because 551 | # during encoding, if it has the same hash as another gfy, it 552 | # returns the (different) link to the original gfy, and the new 553 | # one won't work. It's possible to override this to upload with 554 | # the new URL regardless, but i don't need to use up extra space 555 | # on the gfycat servers. 556 | echo 'Waiting for remote encoding to complete...' >&2 557 | while true 558 | do 559 | sleep 4 560 | gfy_status=$(curl -fs -A "$ap_ua" "https://api.gfycat.com/v1/gfycats/fetch/status/$gfy_name") || { 561 | echo "${ap_ERROR}Status check request did not return HTTP 200!" >&2 562 | echo "Your file might end up here anyway: https://gfycat.com/$gfy_name${ap_RESET}" >&2 563 | return 1; 564 | } 565 | [[ $gfy_status == *complete* ]] && break 566 | done 567 | [[ $gfy_status == *gfyName* ]] && \ 568 | gfy_final_name=$(json_parse "$gfy_status" 'gfyName') || \ 569 | gfy_final_name=$(json_parse "$gfy_status" 'gfyname') 570 | echo >&2 571 | echo "Link: https://gfycat.com/$gfy_final_name" 572 | echo "Direct: https://thumbs.gfycat.com/$gfy_final_name-size_restricted.gif" 573 | echo 574 | ;; 575 | get_info) 576 | echo '[name]' 577 | echo 'Gfycat' 578 | echo '[description]' 579 | echo 'Video/Gif host. Started out as a gif-to-mp4 kind of thing, so it strips out audio and truncates videos to 15 seconds. Otherwise great!' 580 | echo '[tags]' 581 | echo 'private' 582 | echo 'permanent' 583 | echo 'direct' 584 | ;; 585 | esac 586 | } 587 | 588 | function docdroid { 589 | case $1 in 590 | check_eligibility) 591 | [[ $ap_mime =~ 'application/pdf'|'application/msword'|'application/vnd.openxmlformats-officedocument'|'application/vnd.ms'|'application/vnd.oasis.opendocument'|'text/rtf' ]] 592 | ;; 593 | upload) 594 | # shellcheck disable=2154 595 | docdroid_json=$(curl -H "Authorization: Bearer $docdroid_access_token" -#fF "file=@$ap_path" -A "$ap_ua" https://docdroid.net/api/document) 596 | docdroid_id=$(json_parse "$docdroid_json" 'id') 597 | docdroid_filename=$(json_parse "$docdroid_json" 'filename') 598 | echo >&2 599 | echo "Link: http://docdro.id/$docdroid_id" 600 | echo "Direct: https://www.docdroid.net/file/download/$docdroid_id/$docdroid_filename" 601 | echo 602 | ;; 603 | get_info) 604 | echo '[name]' 605 | echo 'Docdroid' 606 | echo '[description]' 607 | echo 'Weird document host, not much of an advantage over any generic direct host. Requires authentication.' 608 | echo '[tags]' 609 | echo 'private' 610 | echo 'permanent' 611 | echo '[config]' 612 | echo 'required|docdroid_access_token|Your Docdroid API key. Must have upload scope enabled.' 613 | esac 614 | } 615 | 616 | function filemail { 617 | case $1 in 618 | check_eligibility) 619 | # 50GB??? I'll believe it when I see it... 620 | check_size 50000000000 621 | ;; 622 | upload) 623 | local id key transfer_global_url transfer_base_url init chunk_count complete link direct 624 | filemail_chunk_size=${filemail_chunk_size:-5242880} 625 | filemail_job_count=${filemail_job_count:-4} 626 | 627 | chunk_count=$(( ap_size / filemail_chunk_size )) 628 | (( ap_size % filemail_chunk_size != 0)) && (( chunk_count++ )) 629 | init=$(curl -sf --data 'sourcedetails=plupload(html5)+%40+https%3A%2F%2Fwww.filemail.com%2F&days=7&confirmation=true' -A "$ap_ua" 'https://www.filemail.com/api/transfer/initialize') 630 | if [[ $? -eq 22 ]] 631 | then 632 | echo >&2 633 | echo "${ap_ERROR}Filemail initialization failed!" >&2 634 | echo "More likely than not, you exceeded your daily limit of two uploads per IP.$ap_RESET" >&2 635 | echo >&2 636 | return 1 637 | fi 638 | id=$(json_parse "$init" 'transferid') 639 | key=$(json_parse "$init" 'transferkey') 640 | transfer_base_url=$(json_parse "$init" 'transferurl') 641 | # Other required fields are per-chunk and set in chunk loop 642 | transfer_global_url="$transfer_base_url?transferid=$id&transferkey=$key&runtime=html5&chunksize=$filemail_chunk_size&thefilename=$ap_human_name_escaped&totalsize=$ap_size&chunks=$chunk_count&retry=0" 643 | echo >&2 644 | # shellcheck disable=2154 645 | seq 0 $(( chunk_count - 1 )) | xargs -L1 -P "$filemail_job_count" bash -c " 646 | chunk_tmp_file=\$(mktemp -t 'anypaste.XXXXXXXXXX') 647 | trap \"rm -f '\$chunk_tmp_file'\" EXIT 648 | echo -ne \"\\rUploading chunk \$(( \$1 + 1 )) of $chunk_count.\" >&2 649 | tail -c \"+\$(( $filemail_chunk_size * \$1 ))\" < '$ap_path' | head -c $filemail_chunk_size > \"\$chunk_tmp_file\" 650 | transfer_local_url='$transfer_global_url&chunk='\$1 651 | curl -sf --data-binary \"@\$chunk_tmp_file\" -H 'Content-Type: application/octet-stream' \"\$transfer_local_url\" -A \"\$ap_ua\" || { echo Chunk upload failed!; exit 255; } 652 | rm -f \"$chunk_tmp_file\" 653 | " filemail_upload_worker 654 | # shellcheck disable=2181 655 | if (( $? != 0 )) 656 | then 657 | echo 'Some chunk uploads failed.' 658 | return 1 659 | fi 660 | echo >&2 661 | echo 'Finishing upload.' >&2 662 | complete=$(curl -sfXPOST --data "transferid=$id&transferkey=$key&failed=false" -A "$ap_ua" 'https://www.filemail.com/api/transfer/complete') 663 | link=$(json_parse "$complete" 'downloadurl') 664 | # file_key includes filekey= at beginning 665 | get_data=$(curl -sfXPOST --data "transferid=$id&skipreg=false&checkhashes=true&filesLimit=3000" -A "$ap_ua" "https://www.filemail.com/api/transfer/get") 666 | direct=$(json_parse "$get_data" 'downloadurl') 667 | echo >&2 668 | echo "Link: $link" 669 | echo "Direct: $direct" 670 | echo 671 | ;; 672 | get_info) 673 | echo '[name]' 674 | echo 'Filemail' 675 | echo '[description]' 676 | echo 'A generic file host supporting up to 50GB files (!!). There is a two upload-per-IP-per-day limit, however, and all uploads are deleted after one week. This plugin supports parallel chunk uploading, just like the official HTML5 client.' 677 | echo '[tags]' 678 | echo 'private' 679 | echo 'direct' 680 | echo '[config]' 681 | echo 'optional|filemail_job_count|The maximum number of chunk uploads to perform in parallel. Defaults to 4.' 682 | echo 'optional|filemail_chunk_size|The maximum chunk size. Defaults to 5242880 and probably should not be changed.' 683 | esac 684 | } 685 | 686 | ################# 687 | ## END PLUGINS ## 688 | ## BEGIN CORE ### 689 | ################# 690 | 691 | # HOOKS 692 | 693 | function ap_copy_hook { 694 | # -m isn't POSIX :( 695 | ap_copy_me=$(grep -E "${ap_copy_regex:-.}" <<< "$ap_last_stdout" | head -n 1) 696 | ap_copy_me="${ap_copy_me##*: }" 697 | if $ap_mac 698 | then 699 | pbcopy <<< "$ap_copy_me" 700 | elif command -v xsel >/dev/null 701 | then 702 | echo -n "$ap_copy_me" | xsel -ib 703 | elif command -v xclip >/dev/null 704 | then 705 | echo -n "$ap_copy_me" | xclip -selection clipboard 706 | else 707 | echo "${ap_WARNING}WARNING: no suitable program to copy text was found on your system. Please report a bug!${ap_RESET}" 708 | fi 709 | } 710 | 711 | function ap_notify_hook { 712 | local notification_title='Anypaste upload complete.' 713 | # for shellcheck 2155 714 | local notification_text 715 | if [[ $ap_hook_policy == greedy ]] 716 | then 717 | notification_text="Uploaded: '$ap_human_name'." 718 | else 719 | notification_text=$( 720 | echo -n 'Uploaded:' 721 | printf " '%s'" "${ap_ok_uls[@]}" 722 | echo -n '.' 723 | ) 724 | fi 725 | if $ap_mac 726 | then 727 | # hahahaha motherfuckers 728 | # say "$notification_text" 729 | osascript -e "display notification \"$notification_text\" with title \"$notification_title\"" 730 | else 731 | command -v notify-send >/dev/null && notify-send -a anypaste -t 8000 "$notification_title" "$notification_text" || \ 732 | echo "${ap_WARNING}WARNING: Install notify-send if you want --notify to work.${ap_RESET}" 733 | fi 734 | } 735 | 736 | # FUNCTIONS 737 | 738 | # @param optionally, a file extension. 739 | # If this ever gets changed, make the change inside the filemail pluin xargs too. 740 | function ap_mktemp { 741 | local result 742 | result=$(mktemp -t "anypaste.XXXXXXXXXX$1") 743 | # quoting is safe as long as tmpdir has no quotes 744 | trap "rm -f '$result'" EXIT 745 | echo "$result" 746 | } 747 | 748 | function ap_color_vars { 749 | ap_RESET=$'\033[0m' 750 | ap_ERROR=$'\033[31m' 751 | ap_SUCCESS=$'\033[32m' 752 | ap_WARNING=$'\033[33m' 753 | ap_NOTE=$'\033[36m' 754 | } 755 | 756 | # note: make sure the plugin exists first (i.e, run it after filter_plugins) 757 | # @param $1: Name of the plugin 758 | # @param $2: Name of the section 759 | # @exit: 1 if that section does not exist, 0 if it does 760 | # @return $ap_get_section_return: the raw section contents 761 | # we use indirection/variable variables instead of Bash's built-in associative arrays 762 | # because they aren't supported on Bash 3, which Mac still uses iirc due to its license. 763 | # Associative arrays are used in a previous commit, which can be used if Mac ever changes 764 | # In theory, we could use a hash function with a normal array, but AAAAHGH 765 | # Variable names are ap_sections_pluginname__sectionname 766 | function ap_get_section { 767 | local requested_key get_info_tmpfile 768 | requested_key="ap_sections_$1__$2" 769 | if [[ -z ${!requested_key} ]] 770 | then 771 | # http://mywiki.wooledge.org/BashFAQ/024 772 | # in other words, we can't use the loop in a pipeline like we "should" because 773 | # it will start a subshell, and we won't be able to get the variables out 774 | # however, we *can* use file redirection. Srsly? 775 | local section 776 | local buffer 777 | local current_key 778 | get_info_tmpfile=$(ap_mktemp) 779 | "$1" get_info > "$get_info_tmpfile" 780 | # we need a "fake" section at the end so that it flushes the final buffer 781 | echo '[dummy]' >> "$get_info_tmpfile" 782 | while IFS= read -r line 783 | do 784 | # skip empty lines 785 | [[ -z $line ]] && continue 786 | 787 | # parse section headers 788 | if [[ $line =~ ^\[.*\]$ ]] 789 | then 790 | current_key="ap_sections_$1__$section" 791 | # greycat describes how to properly assign multiline values to an indirect reference 792 | # here: https://mywiki.wooledge.org/BashFAQ/006 793 | # since there's no security risk, I kind've just want to use eval for simplicity, but NAH 794 | # here strings append a newline automatically 795 | IFS= read -d '' -r "$current_key" <<< "${buffer%%$'\n'}" 796 | buffer= 797 | section="${line//[\[\]]/}" 798 | continue 799 | fi 800 | 801 | # section body 802 | buffer="${buffer}${line} 803 | " 804 | done < "$get_info_tmpfile" 805 | fi 806 | ap_get_section_return=${!requested_key} 807 | [[ -n ${!requested_key} ]] && return 0 || return 1 808 | } 809 | 810 | # Y is always default. Word your questions better. Be positive! 811 | # args: message 812 | function ap_i_yn { 813 | echo -n "$1 [Y/n] " >&2 814 | read -r ap_attempt 815 | [[ "$ap_attempt" != 'n' && "$ap_attempt" != 'N' ]] 816 | } 817 | 818 | # @param ap_search_plugins_arg: array of available plugins 819 | # @param $1: search term 820 | # @return ap_search_plugins_return: Array of plugins containing search term 821 | function ap_search_plugins { 822 | # If the plugin is the exact name of a command, we can use it even if not in config 823 | ap_search_plugins_return=() 824 | for ap_plugin in "${ap_search_plugins_arg[@]}" 825 | do 826 | [[ $ap_plugin == *$1* ]] && ap_search_plugins_return+=("$ap_plugin") 827 | done 828 | } 829 | 830 | # @param ap_i_select_plugin_arg available plugins, filtered as much as possible 831 | # @return ap_i_select_plugin_return single plugin as selected by user 832 | function ap_i_select_plugin { 833 | # fail if no plugins 834 | [[ ${#ap_i_select_plugin_arg[@]} -eq 0 ]] && return 1 835 | if [[ ${#ap_i_select_plugin_arg[@]} -eq 1 ]] 836 | then 837 | echo "Only one compatible plugin was found: $ap_i_select_plugin_arg" >&2 838 | ap_i_select_plugin_return="$ap_i_select_plugin_arg" 839 | return 840 | fi 841 | echo -n 'The following plugins were found:' >&2 842 | printf " '%s'" "${ap_i_select_plugin_arg[@]}" >&2 843 | echo >&2 844 | # keep asking for search terms until we find something 845 | while true 846 | do 847 | echo >&2 848 | echo 'Enter the (partial) name of a plugin, or nothing for automatic selection' >&2 849 | read -r ap_search_term 850 | if [[ -z $ap_search_term ]] 851 | then 852 | ap_i_select_plugin_return="$ap_i_select_plugin_arg" 853 | break 854 | fi 855 | ap_search_plugins_arg=("${ap_i_select_plugin_arg[@]}") 856 | ap_search_plugins "$ap_search_term" 857 | if [[ ${#ap_search_plugins_return[@]} -gt 1 ]] 858 | then 859 | echo -n "${ap_WARNING}Multiple plugins matched that search:" >&2 860 | printf " '%s'" "${ap_search_plugins_return[@]}" >&2 861 | echo -n "${ap_RESET}" >&2 862 | elif [[ ${#ap_search_plugins_return[@]} == 0 ]] 863 | then 864 | echo "${ap_WARNING}No plugins matched that search, try again.${ap_RESET}" >&2 865 | else 866 | ap_i_select_plugin_return="$ap_search_plugins_return" 867 | break 868 | fi 869 | done 870 | } 871 | 872 | # @param $1: char to repeat 873 | # @param $2: number of times to repeat it 874 | # @return $ap_repeat_char_return: repeated string 875 | function ap_repeat_char { 876 | ap_repeat_char_return= 877 | for ((i=0; i<$2; i++)) 878 | do 879 | ap_repeat_char_return="${ap_repeat_char_return}$1" 880 | done 881 | } 882 | 883 | # sets variables related to table printing 884 | # ap_list_[ncs] are the top, middle, and bottom of items 885 | function ap_list_init { 886 | local hr_body 887 | ap_width=$(tput cols) 888 | [[ $ap_width -lt 80 ]] && ap_width=80 889 | [[ $ap_width -gt 140 ]] && ap_width=140 890 | if $ap_unicode 891 | then 892 | ap_list_h_char='─' 893 | ap_list_v_char='│' 894 | else 895 | ap_list_h_char='-' 896 | ap_list_v_char='|' 897 | fi 898 | # we can't use the printf %.0s trick because it doesn't work when the character is '-' 899 | ap_repeat_char "$ap_list_h_char" $((ap_width-2)) 900 | hr_body="$ap_repeat_char_return" 901 | if $ap_unicode 902 | then 903 | ap_list_n="┌${hr_body}┐" 904 | ap_list_c="├${hr_body}┤" 905 | ap_list_s="└${hr_body}┘" 906 | else 907 | ap_list_n="/$hr_body\\" 908 | ap_list_c="|$hr_body|" 909 | ap_list_s="\\$hr_body/" 910 | fi 911 | } 912 | 913 | # prints text, properly wrapping and all 914 | # @param $1: text to be put inside 915 | function ap_list_text { 916 | local pad_str pad_size text_width line 917 | pad_size=1 918 | ap_repeat_char ' ' "$pad_size" 919 | pad_str="$ap_repeat_char_return" 920 | text_width=$((ap_width-2-pad_size*2)) 921 | 922 | echo -n "${1%$'\n'}"$'\n' | fold -w "$text_width" | while IFS= read -r line 923 | do 924 | if [[ ${#line} -lt $text_width ]] 925 | then 926 | ap_repeat_char ' ' $((text_width-${#line})) 927 | line="${line}${ap_repeat_char_return}" 928 | fi 929 | echo "${ap_list_v_char}${pad_str}${line}${pad_str}${ap_list_v_char}" 930 | done 931 | } 932 | 933 | # @param $ap_list_arg: see ap_list 934 | # @param $1: whether to do "raw" output or not. 935 | function ap_list_inner { 936 | local tags config_parts line 937 | ap_list_init 938 | for ap_plugin in "${ap_list_arg[@]}" 939 | do 940 | # no && here, get_info might fail 941 | if $1 942 | then 943 | "$ap_plugin" get_info 944 | echo 945 | continue 946 | fi 947 | echo "$ap_list_n" 948 | ap_get_section "$ap_plugin" 'name' 949 | ap_list_text "$ap_get_section_return" 950 | echo "$ap_list_c" 951 | ap_get_section "$ap_plugin" 'description' 952 | ap_list_text "Description: 953 | $ap_get_section_return" 954 | 955 | ap_get_section "$ap_plugin" 'tags' 956 | if [[ -n $ap_get_section_return ]] 957 | then 958 | echo "$ap_list_c" 959 | tags=$(echo -n "$ap_get_section_return" | tr ' 960 | ' ',') 961 | # make sure to apply trailing newline that was removed above 962 | ap_list_text "Tags: ${tags%%,}" 963 | fi 964 | 965 | ap_get_section "$ap_plugin" 'config' 966 | if [[ -n "$ap_get_section_return" ]] 967 | then 968 | echo "$ap_list_c" 969 | ap_list_text "Configuration options:" 970 | # conveniently, required recommended optional is reverse alphabetical order 971 | echo -n "$ap_get_section_return" | sort -srt '|' -k 1,1 | while read -r line 972 | do 973 | # [0]=opt/rec/req [1]=name [2]=description 974 | IFS='|' read -ra config_parts <<< "$line" 975 | ap_list_text "(${config_parts[0]}) ${config_parts[1]}: ${config_parts[2]}" 976 | done 977 | fi 978 | 979 | echo "$ap_list_s" 980 | echo 981 | done 982 | } 983 | # @param $ap_list_arg: Array of plugin names to list 984 | function ap_list { 985 | if [[ -t 1 ]] 986 | then 987 | ap_list_inner 'false' | ${PAGER:-less} 988 | else 989 | ap_list_inner 'true' 990 | fi 991 | } 992 | 993 | function run_hooks { 994 | for i in "${ap_hooks[@]}" 995 | do 996 | $i 997 | done 998 | } 999 | 1000 | # @param $ap_plugin: name of plugin 1001 | # @param $ap_hook_policy 1002 | function upload_plugin { 1003 | local plugin_exit_code stdout_cache_tmpfile 1004 | echo "Attempting to upload with plugin '$ap_plugin'" >&2 1005 | # TODO: if we ever unit test things, make sure we fall back if a plugin fails 1006 | stdout_cache_tmpfile=$(ap_mktemp) 1007 | $ap_plugin upload | tee "$stdout_cache_tmpfile" 1008 | plugin_exit_code=${PIPESTATUS[0]} 1009 | if [[ $plugin_exit_code == 0 ]] 1010 | then 1011 | ap_last_stdout=$(<"$stdout_cache_tmpfile") 1012 | # shellcheck disable=2154 1013 | [[ $ap_hook_policy == greedy ]] && run_hooks 1014 | echo "${ap_SUCCESS}Upload complete.${ap_RESET}" >&2 1015 | else 1016 | echo "${ap_ERROR}Plugin failed with error code $plugin_exit_code${ap_RESET}" >&2 1017 | return 1 1018 | fi 1019 | } 1020 | 1021 | # LOOP THROUGH PLUGINS 1022 | 1023 | # @param $ap_local_plugins: List of plugins to filter 1024 | # @return $ap_local_plugins: Filtered plugins based on file compatibility 1025 | function ap_filter_local_plugins { 1026 | local line config_parts config_var_name 1027 | ap_filter_plugins_return=() 1028 | for ap_plugin in "${ap_local_plugins[@]}" 1029 | do 1030 | command -v "$ap_plugin" > /dev/null || { echo "${ap_WARNING}WARNING: Plugin $ap_plugin could not be found! You may need to check your config file.${ap_RESET}" >&2 && continue; } 1031 | "$ap_plugin" check_eligibility || continue 1032 | if ap_get_section "$ap_plugin" 'config' 1033 | then 1034 | while read -r line 1035 | do 1036 | IFS='|' read -ra config_parts <<< "$line" 1037 | config_var_name="${config_parts[1]}" 1038 | if [[ -n $line && -z ${!config_var_name} ]] 1039 | then 1040 | case "${config_parts[0]}" in 1041 | "required") 1042 | echo "${ap_WARNING}Missing required config option for '$ap_plugin': '$config_var_name'" >&2 1043 | echo "Run 'anypaste -p $ap_plugin -l' to see more information about this plugin.${ap_RESET}" >&2 1044 | # aaaahhahah 1045 | continue 2 1046 | ;; 1047 | "recommended") 1048 | echo "Missing recommended config option for '$ap_plugin': '$config_var_name' -- continuing anyway" >&2 1049 | echo "Run 'anypaste -p $ap_plugin -l' to see more information about this plugin." >&2 1050 | ;; 1051 | esac 1052 | fi 1053 | done <<< "$ap_get_section_return" 1054 | fi 1055 | ap_filter_plugins_return+=("$ap_plugin") 1056 | done 1057 | ap_local_plugins=("${ap_filter_plugins_return[@]}") 1058 | } 1059 | 1060 | # filters ap_global_plugins in-place based on CLI options 1061 | # @param $ap_global_plugins: Unfiltered plugin list 1062 | # @param $ap_p: user-specified plugins search string 1063 | # @param $ap_t: comma-separated list of required tags 1064 | # @return $ap_global_plugins 1065 | function ap_filter_global_plugins { 1066 | if [[ -n $ap_p ]] 1067 | then 1068 | ap_search_plugins_arg=("${ap_global_plugins[@]}") 1069 | ap_search_plugins "$ap_p" 1070 | ap_global_plugins=("${ap_search_plugins_return[@]}") 1071 | fi 1072 | if [[ -n $ap_t ]] 1073 | then 1074 | IFS=',' read -ra ap_tags <<< "$ap_t" 1075 | for ap_plugin_index in "${!ap_global_plugins[@]}" 1076 | do 1077 | ap_get_section "${ap_global_plugins[$ap_plugin_index]}" 'tags' 1078 | for ap_tag in "${ap_tags[@]}" 1079 | do 1080 | [[ $ap_get_section_return == *$ap_tag* ]] || unset "ap_global_plugins[$ap_plugin_index]" 1081 | done 1082 | done 1083 | # unsparsify, for good luck 1084 | # TODO: maybe remove 1085 | ap_global_plugins=("${ap_global_plugins[@]}") 1086 | fi 1087 | } 1088 | 1089 | # @params: ALL cli options 1090 | # @params: ALL file-specific environment variables 1091 | # @param: ap_local_plugins: list of plugins filtered by global stuff already 1092 | function upload_loop { 1093 | echo "${ap_NOTE}Current file: $ap_user_path${ap_RESET}" >&2 1094 | if $ap_i 1095 | then 1096 | # INTERACTIVE 1097 | ap_i_yn 'Determine compatible plugins automatically?' && \ 1098 | ap_filter_local_plugins 1099 | # keep looping and selecting plugins, removing the previously attempted plugin each time, until we succeed 1100 | # or there are none left 1101 | while true 1102 | do 1103 | ap_i_select_plugin_arg=("${ap_local_plugins[@]}") 1104 | ap_i_select_plugin || return 1 1105 | ap_plugin="$ap_i_select_plugin_return" 1106 | ap_i_yn "Attempt to upload with plugin '$ap_plugin'?" >&2 || continue 1107 | upload_plugin && break 1108 | # we have to use unset to remove the selected one, but it only 1109 | # takes an index :( 1110 | for i in "${!ap_local_plugins[@]}" 1111 | do 1112 | if [[ ${ap_local_plugins[$i]} == "$ap_plugin" ]] 1113 | then 1114 | unset "ap_local_plugins[$i]" 1115 | ap_local_plugins=("${ap_local_plugins[@]}") 1116 | break 1117 | fi 1118 | done 1119 | done 1120 | else 1121 | # NON-INTERACTIVE 1122 | $ap_f || ap_filter_local_plugins 1123 | if $ap_list 1124 | then 1125 | ap_list_arg=("${ap_local_plugins[@]}") 1126 | ap_list 1127 | return 1128 | fi 1129 | for ap_plugin in "${ap_local_plugins[@]}" 1130 | do 1131 | upload_plugin && return 1132 | done 1133 | echo "${ap_ERROR}No compatible plugins found, or all compatible plugins failed.${ap_RESET}" >&2 1134 | return 1 1135 | fi 1136 | } 1137 | 1138 | # @param $1 relative path to a file 1139 | # @return ap_rel_to_abs absolute path to the same file 1140 | function ap_rel_to_abs { 1141 | # we use the prefix and local because we don't want to conflict with the built 1142 | # in function names 1143 | local ap_dirname ap_basename 1144 | ap_dirname=$(dirname "$1") 1145 | ap_basename=$(basename "$1") 1146 | # I'm not convinced we need the || cases here, but shellcheck is. 1147 | pushd "$ap_dirname" >/dev/null || return 1 1148 | ap_rel_to_abs_return="$PWD/$ap_basename" 1149 | popd >/dev/null || return 1 1150 | } 1151 | 1152 | # @param $ap_path full path to file 1153 | # @return $ap_file_info $ap_mime $ap_ffprobe $ap_human_name $ap_size see docs 1154 | function ap_collect_file_metadata { 1155 | # shellcheck disable=2034 1156 | ap_file_info=$(file "$ap_path") 1157 | ap_mime=$(file --mime-type --brief "$ap_path") 1158 | if command -v ffprobe >/dev/null 1159 | then 1160 | ap_ffprobe=$(ffprobe -show_streams -show_format <"$ap_path" 2>&1) || ap_ffprobe= 1161 | else 1162 | ap_ffprobe= 1163 | echo 'NOTE: Ffprobe/ffmpeg is not installed. Compatibility checks for audio/video may be inaccurate.' >&2 1164 | fi 1165 | ap_human_name=${ap_n:-$(basename "$ap_path")} 1166 | ap_url_encode "$ap_human_name" 1167 | ap_human_name_escaped=$ap_url_encode_return 1168 | ap_size=$(wc -c < "$ap_path") 1169 | } 1170 | 1171 | function ap_failed_ul { 1172 | ap_fail_uls+=("$ap_user_path") 1173 | } 1174 | # @param $ap_upload_files_arg: List of "user paths" to files to be uploaded (may be relative) 1175 | # @return $ap_ok_uls: Array of successfully uploaded user paths 1176 | # @return $ap_fail_uls: Array of failed upload user paths 1177 | function ap_upload_files { 1178 | local found_stdin='false' 1179 | for ap_user_path in "${ap_upload_files_arg[@]}" 1180 | do 1181 | # HANDLE WEIRD FILES 1182 | 1183 | # STDIN 1184 | if [[ $ap_user_path == '-' ]] 1185 | then 1186 | if $found_stdin 1187 | then 1188 | echo "${ap_ERROR}You specified stdin more than once!" >&2 1189 | echo "All but the first will be ignored.${ap_RESET}" >&2 1190 | ap_failed_ul 1191 | continue 1192 | fi 1193 | if [[ -t 0 ]] 1194 | then 1195 | echo "${ap_ERROR}Stdin specified, but stdin is a terminal!${ap_RESET}" >&2 1196 | continue 1197 | fi 1198 | ap_path=$(ap_mktemp) 1199 | cat > "$ap_path" 1200 | found_stdin='true' 1201 | # NOT READABLE 1202 | elif [[ ! -r "$ap_user_path" ]] 1203 | then 1204 | echo "${ap_ERROR}$ap_user_path is not readable!" >&2 1205 | echo "Make sure it exists and you have proper permissions for it.${ap_RESET}" >&2 1206 | ap_exit_code=101 1207 | ap_failed_ul 1208 | continue 1209 | # IS A DIRECTORY 1210 | elif [[ -d "$ap_user_path" ]] 1211 | then 1212 | echo "$ap_user_path is a directory, creating tarball..." >&2 1213 | ap_path=$(ap_mktemp .tar.gz) 1214 | tar czf "$ap_path" -C "$ap_user_path" . 1215 | # NOTHING SPECIAL 1216 | else 1217 | ap_rel_to_abs "$ap_user_path" 1218 | ap_path=$ap_rel_to_abs_return 1219 | fi 1220 | ap_local_plugins=("${ap_global_plugins[@]}") 1221 | ap_collect_file_metadata 1222 | if upload_loop 1223 | then 1224 | ap_ok_uls+=("$ap_user_path") 1225 | else 1226 | ap_exit_code=100 1227 | ap_failed_ul 1228 | 1229 | fi 1230 | done 1231 | } 1232 | 1233 | # @param $ap_cfg: path to config file 1234 | function ap_create_config { 1235 | cat > "$ap_cfg" << 'CFG' 1236 | # List of plugins 1237 | # If there are multiple compatible plugins, precedence is determined 1238 | # by which one is listed first in this array 1239 | # You'll need to uncomment (remove # at beginning of line) first 1240 | # ap_plugins=( 1241 | # 'sendvid' 'streamable' 'gfycat' # Videos/Gifs 1242 | # 'imgur' 'pixhost' # Images 1243 | # # Audio 1244 | # 'ixio' 'pdefault' 'hastebin' 'pastie' 'paste2' # Text 1245 | # 'docdroid' # Documents 1246 | # 'bayfiles' 'keepsh' 'gofile' 'transfersh' 'filemail' 'fileio' # Generic 1247 | # ) 1248 | 1249 | # Make sure to use export `boop=whatever` for plugin settings, not just `boop=whatever` 1250 | # Otherwise plugins won't be able to see your variables. 1251 | 1252 | # SETTINGS FOR DEFAULT PLUGINS 1253 | # remember to uncomment them for them to work 1254 | 1255 | # Set both of these to a real account to enable the streamable plugin 1256 | # export streamable_email=mark@example.com 1257 | # export streamable_password=hunter2 1258 | # Create a docdroid.net account, go to settings, and create an API access token 1259 | # export docdroid_access_token=928doebknb80fd38rduroenaudhoenkb283d8pf7230upf8rekb92 1260 | CFG 1261 | echo "Created configuration file at $ap_cfg" >&2 1262 | echo 'It does nothing by default, edit it to make it cool!' >&2 1263 | } 1264 | 1265 | # @param $ap_ok_uls: array of successful upload human names 1266 | # @param $ap_fail_uls: array of failed upload human names 1267 | function ap_summary { 1268 | # SUCCESSES 1269 | echo -n "${ap_SUCCESS}Sucessfully uploaded:" >&2 1270 | if [[ ${#ap_ok_uls[@]} -gt 0 ]] 1271 | then 1272 | printf " '%s'" "${ap_ok_uls[@]}" >&2 1273 | [[ $ap_hook_policy != greedy ]] && run_hooks 1274 | else 1275 | echo -n ' None' >&2 1276 | fi 1277 | 1278 | echo "${ap_RESET}" >&2 1279 | 1280 | # FAILURES 1281 | if [[ ${#ap_fail_uls[@]} -gt 0 ]] 1282 | then 1283 | echo -n "${ap_ERROR}Failed to upload:" >&2 1284 | printf " '%s'" "${ap_fail_uls[@]}" >&2 1285 | echo "${ap_RESET}" >&2 1286 | [[ ${#ap_ok_uls[@]} -gt 0 ]] && ((ap_exit_code+=100)) 1287 | fi 1288 | } 1289 | 1290 | # @param $ap_args: array of command line arguments 1291 | # @return $ap_args: list of remaining cli arguments after removing options 1292 | # @return: lots of individual variables 1293 | function ap_parse_args { 1294 | # janky long option finder, because we can't use GNU getopt. Fuck mac. Wait, did I already say that? 1295 | for i in "${!ap_args[@]}" 1296 | do 1297 | ap_found_long_opt=true 1298 | case "${ap_args[$i]}" in 1299 | '--help') 1300 | ap_help='true' 1301 | ;; 1302 | '--version') 1303 | ap_version='true' 1304 | ;; 1305 | '--copy') ap_copy='true';; 1306 | '--notify') ap_notify='true';; 1307 | '--list') ap_list='true';; 1308 | '--list-raw') 1309 | ap_list='true' 1310 | ;; 1311 | *) ap_found_long_opt='false';; 1312 | esac 1313 | $ap_found_long_opt && unset "ap_args[$i]" 1314 | done 1315 | 1316 | # This is necessary to make the pseudo-shift with OPTIND work later 1317 | ap_args=("${ap_args[@]}") 1318 | 1319 | # the - is so that it ignores long options without error 1320 | # Shellcheck actually checks specifically for getopts options in the case. How cool is that? 1321 | # shellcheck disable=2213 1322 | while getopts 'C-vlxfhsip:c:n:t:' ap_opt "${ap_args[@]}" 1323 | do 1324 | # shellcheck disable=2220 1325 | case $ap_opt in 1326 | h) 1327 | ap_help='true' 1328 | ;; 1329 | i) 1330 | ap_i='true' 1331 | ;; 1332 | p) 1333 | ap_p="$OPTARG" 1334 | ;; 1335 | f) 1336 | ap_f='true' 1337 | ;; 1338 | c) 1339 | ap_cfg="$OPTARG" 1340 | ;; 1341 | C) 1342 | ap_C='true'; 1343 | ;; 1344 | t) 1345 | ap_t="$OPTARG" 1346 | ;; 1347 | l) 1348 | ap_list='true' 1349 | ;; 1350 | v) 1351 | ap_version='true' 1352 | ;; 1353 | n) 1354 | ap_n="$OPTARG" 1355 | ;; 1356 | s) 1357 | exec 2>/dev/null 1358 | ;; 1359 | x) 1360 | ap_copy='true' 1361 | ;; 1362 | esac 1363 | done 1364 | 1365 | ap_args=("${ap_args[@]:$((OPTIND-1))}") 1366 | } 1367 | 1368 | # @return $ap_cfg: path to config file (or where it should be) 1369 | function ap_get_config_path { 1370 | if $ap_mac 1371 | then 1372 | # fuck mac users, they deserve random config files in their home directory because there's nowhere defined to put them 1373 | ap_cfg="$HOME/.anypaste.conf" 1374 | else 1375 | [[ -n "$XDG_CONFIG_HOME" ]] && ap_cfg="$XDG_CONFIG_HOME/anypaste.conf" || ap_cfg="$HOME/.config/anypaste.conf" 1376 | fi 1377 | } 1378 | 1379 | # shellcheck disable=2016 1380 | ap_help_text=' 1381 | Usage: anypaste [-ifh] [-p plugin] [-c config_file_path] [file1 [file2 ...]] 1382 | 1383 | Upload `file`s or stdin to an automatically selected hosting sites. 1384 | You can specify `-` as a file to read from stdin. If no files are 1385 | listed, it will automatically attempt to use stdin. 1386 | 1387 | See https://anypaste.xyz/ for detailed documentation. 1388 | 1389 | OPTIONS: 1390 | 1391 | -i Enable interactive mode. Will prompt for important options. 1392 | Combining this with options intended for non-interactive 1393 | use (e.g, -p) has undefined behavior. If you are reading 1394 | your file from stdin, -i might not work properly. 1395 | -p Specify a plugin instead of automatic selection. Uses fuzzy 1396 | matching (e.g, `gfy` search will match `gfycat` plugin). 1397 | Only searches compatible plugins by default. 1398 | -t Specify required "tags" for plugins, comma separated. You 1399 | can use -l to see what tags plugins have. 1400 | -n Specify the name that will be displayed on the site. Not 1401 | universally supported. Defaults to file basename. 1402 | -l, --list List all installed plugins, and some metadata about each. 1403 | This works in combination with other filtering things; for 1404 | example you can do `anypaste -l myfile.png` to list plugins 1405 | compatible with myfile.png. Will echo raw get_info output 1406 | from each plugin if stdout is not a terminal, cannot be 1407 | overridden :( 1408 | -s Silence everything but links (equivalent to 2>/dev/null) 1409 | -c Use the specified configuration file instead of the default 1410 | one located at $XDG_CONFIG_HOME/anypaste.conf 1411 | -C Create a default configuration file. This is how you should 1412 | initialize a config file if you want to use one. 1413 | -f Do not check plugin compatibility. Without -p, it uses the 1414 | first listed plugin in the config file. Primary meant for 1415 | use with -p 1416 | -x, --copy Copy the link to the clipboard after upload is complete. 1417 | --notify Send a desktop notification (GUI) after upload. 1418 | -v Display Anypaste version 1419 | -h, --help Display this help text. 1420 | 1421 | Plugins may support additional options not listed here. 1422 | ' 1423 | 1424 | function ap_main { 1425 | ap_args=("$@") 1426 | ap_exit_code=0 1427 | # DEFAULT EVERYTHING 1428 | ap_i='false' 1429 | ap_f='false' 1430 | ap_C='false' 1431 | ap_p="" 1432 | ap_cfg="" 1433 | ap_copy='false' 1434 | ap_notify='false' 1435 | ap_list='false' 1436 | ap_help='false' 1437 | ap_version='false' 1438 | ap_plugins=( 1439 | 'sendvid' 'streamable' 'gfycat' 'imgur' 'pixhost' 'ixio' 'pdefault' 'hastebin' 'pastie' 'paste2' 'docdroid' 'bayfiles' 'keepsh' 'gofile' 'transfersh' 'filemail' 'fileio' 1440 | ) 1441 | ap_hooks=() 1442 | ap_hook_policy='lazy' 1443 | ap_unicode='true' 1444 | ap_color='true' 1445 | ap_ua=$ap_version_text 1446 | 1447 | ap_parse_args 1448 | $ap_list && exec 2>/dev/null 1449 | $ap_help && echo "$ap_help_text" && return 1450 | $ap_version && echo "$ap_version_text" && return 1451 | [[ $TMPDIR == *\'* ]] && echo 'Please no single quotes in TMPDIR!' && return 1 1452 | 1453 | [[ -z $ap_cfg ]] && ap_get_config_path 1454 | $ap_C && ap_create_config && return 1455 | 1456 | PATH="$PATH:$HOME/.anypaste-plugins" 1457 | 1458 | # LOAD AND CHECK CONFIGURATION 1459 | 1460 | # this could fail if no config file, hence why 2> /dev/null 1461 | # shellcheck disable=1090 1462 | source "$ap_cfg" 2> /dev/null 1463 | 1464 | $ap_color && ap_color_vars 1465 | 1466 | [[ ${#ap_plugins[@]} == 0 ]] && echo "${ap_ERROR}No plugins listed in config!${ap_RESET}" && return 100 1467 | 1468 | $ap_copy && ap_hooks+=('ap_copy_hook') 1469 | $ap_notify && ap_hooks+=('ap_notify_hook') 1470 | 1471 | # Filter plugins by cli options 1472 | ap_global_plugins=("${ap_plugins[@]}") 1473 | ap_filter_global_plugins 1474 | 1475 | # NO FILES SPECIFIED 1476 | if [[ ${#ap_args[@]} == 0 ]] 1477 | then 1478 | if $ap_list 1479 | then 1480 | ap_list_arg=("${ap_global_plugins[@]}") 1481 | ap_list 1482 | return 1483 | fi 1484 | if [[ -t 0 ]] 1485 | then 1486 | echo "${ap_ERROR}ERROR: No files specified, and stdin is a terminal${ap_RESET}" >&2 1487 | # we put this to stderr despite putting help text on stdout when 1488 | # -h or --help is passed because a program might not expect it here 1489 | echo "$ap_help_text" >&2 1490 | return 102 1491 | fi 1492 | ap_args=('-') 1493 | fi 1494 | 1495 | ap_ok_uls=() 1496 | ap_fail_uls=() 1497 | ap_upload_files_arg=("${ap_args[@]}") 1498 | ap_upload_files 1499 | 1500 | ap_summary 1501 | echo 'All files processed. Have a nice day!' >&2 1502 | return $ap_exit_code 1503 | } 1504 | 1505 | # shellcheck disable=2154 1506 | if [[ -z $ap_test ]] 1507 | then 1508 | ap_main "$@" 1509 | exit "$?" 1510 | fi 1511 | 1512 | # END CORE 1513 | -------------------------------------------------------------------------------- /foreign/usr/share/licenses/wgetpaste/LICENSE: -------------------------------------------------------------------------------- 1 | # A Script that automates pasting to a number of pastebin services 2 | # relying only on bash, sed, coreutils (mktemp/sort/tr/wc/whoami/tee) and wget 3 | # Copyright (c) 2007-2016 Bo Ørsted Andresen 4 | # Distributed in the public domain. Do with it whatever you want. 5 | -------------------------------------------------------------------------------- /foreign/usr/share/wgetpaste/wgetpaste.example: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # add this to /etc/wgetpaste.conf or ~/.wgetpaste.conf to set some defaults 4 | 5 | # set default nick 6 | DEFAULT_NICK=zlin 7 | 8 | # change the default service 9 | DEFAULT_SERVICE="zlin" 10 | 11 | # change default language for the ca and the osl services 12 | DEFAULT_LANGUAGE_ca="Bash" 13 | DEFAULT_LANGUAGE_osl="Diff" 14 | 15 | # change default expiration period for the ca service 16 | DEFAULT_EXPIRATION_ca="1 week" 17 | -------------------------------------------------------------------------------- /foreign/usr/share/zsh/site-functions/_wgetpaste: -------------------------------------------------------------------------------- 1 | #compdef wgetpaste 2 | 3 | # vim: set et sw=2 sts=2 ts=2 ft=zsh : 4 | # ZSH completion for `wgetpaste`, http://wgetpaste.zlin.dk 5 | # Written by Ingmar Vanhassel 6 | 7 | 8 | (( ${+functions[_wgetpaste_services]} )) || 9 | _wgetpaste_services() 10 | { 11 | local -a _services 12 | _services=( $(_call_program service wgetpaste --list-services --completions --verbose 2>/dev/null) ) 13 | _describe -t service 'what service should be used' \ 14 | _services 15 | } 16 | 17 | (( ${+functions[_wgetpaste_languages]} )) || 18 | _wgetpaste_languages() 19 | { 20 | local -a _languages 21 | _languages=( ${(f)"$(_call_program language wgetpaste --list-languages --completions 2>/dev/null)"} ) 22 | _describe -t language 'what language to post as' \ 23 | _languages 24 | } 25 | 26 | (( ${+functions[_wgetpaste_expiration]} )) || 27 | _wgetpaste_expiration() 28 | { 29 | local -a _expiration 30 | _expiration=( ${(f)"$(_call_program expiration wgetpaste --list-expiration --completions 2>/dev/null)"} ) 31 | _describe -t expiration 'when should your paste expire' \ 32 | _expiration 33 | } 34 | 35 | _arguments -s : \ 36 | '(--language -l)'{--language,-l}'[set language]:language:_wgetpaste_languages' \ 37 | '(--description -d)'{--description,-d}'[set description]:description: ' \ 38 | '(--nick -n)'{--nick,-n}'[set nick]:nick:_users' \ 39 | '(--service -s)'{--service,-s}'[set service to use]:service:_wgetpaste_services' \ 40 | '(--expiration -e)'{--expiration,-e}'[set when your paste should expire]:expiration:_wgetpaste_expiration' \ 41 | '(--list-services -S)'{--list-services,-S}'[list supported pastebin services]' \ 42 | '(--list-languages -L)'{--list-languages,-L}'[list languages supported by the specified service]' \ 43 | '(--list-expiration -E)'{--list-expiration,-E}'[list expiration setting supported by the specified service]' \ 44 | '(--tinyurl -u)'{--tinyurl,-u}'[convert input url to tinyurl]:url:_urls' \ 45 | '(--command -c)'{--command,-c}'[paste a command and its output]:command:_command' \ 46 | '(--info -i)'{--info,-i}'[append the output of `emerge --info`]' \ 47 | '(--info-only -I)'{--info-only,-I}'[paste the output of `emerge --info` only]' \ 48 | '(--xcut -x)'{--xcut,-x}'[read input from clipboard]' \ 49 | '(--xpaste -X)'{--xpaste,-X}'[write resulting url to the X primary selection buffer]' \ 50 | '(--xclippaste -C)'{--xclippaste,-C}'[write resulting url to the X clipboard selection buffer]' \ 51 | '(--raw -r)'{--raw,-r}'[show url for the raw paste]' \ 52 | '(--tee -t)'{--tee,-t}'[use tee to show what is being pasted]' \ 53 | '(--verbose -v)'{--verbose,-v}'[show wget stderr output if no url is received]' \ 54 | '--debug[be very verbose]' \ 55 | '(--help -h)'{--help,-h}'[show help and exit]' \ 56 | '(--ignore-configs,-g)'{--ignore-configs,-g}'[ignore /etc/wgetpaste.conf, ~/.wgetpaste.conf etc]' \ 57 | '--version[show version information and exit]' \ 58 | '*:file:_files' && 59 | return 60 | 61 | -------------------------------------------------------------------------------- /getlog: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################ 3 | # SALT - [S]teadfasterX [A]ll-in-one [L]G [T]ool 4 | # 5 | # Copyright (C): 2017-2023, steadfasterX 6 | # 7 | # Log upload wrapper for SALT 8 | # 9 | ################################################################################ 10 | 11 | VARS="${0%/*}/salt.vars" 12 | source $VARS 13 | 14 | FUNCS="${0%/*}/salt.func" 15 | source $FUNCS 16 | 17 | F_LOG "getlog script started" 18 | cat $LOG | $FYAD --title="$YTITLE - DEBUGLOG" --width=1000 --height=800 --wrap --text-info --button="Upload/Paste this log":99 --button=Close:0 19 | 20 | if [ $? -eq 99 ];then 21 | for pastes in haste ix transfer; do 22 | PASTEURL=$($APASTE -s -p $pastes $LOG | grep Link) 23 | PASTEURL=${PASTEURL/Link: /} 24 | echo "${PASTEURL}" | grep -q http 25 | PASTEERR=$? 26 | if [ $PASTEERR -eq 0 ];then 27 | $FYAD --title="$YTITLE - DEBUGLOG" --width=800 --height=350 --image="$SICONS/ok_64x64.png" --text "\n\nLog uploaded successfully!\n\n" \ 28 | --form --columns=2 \ 29 | --field=" Copy the following Paste service link for sharing it":TXT "\n ${PASTEURL}"\ 30 | --button=Close 31 | break 32 | else 33 | F_MSGE 800 "Error in module '$pastes' $PASTEURL while uploading logfile..\nClick EXIT for trying next paste service...\n\n" 34 | fi 35 | done 36 | fi 37 | -------------------------------------------------------------------------------- /icons/advanced.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 17 | 28 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | -------------------------------------------------------------------------------- /icons/advanced_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/advanced_16x16.png -------------------------------------------------------------------------------- /icons/advanced_30x30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/advanced_30x30.png -------------------------------------------------------------------------------- /icons/advanced_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/advanced_48x48.png -------------------------------------------------------------------------------- /icons/archive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/archive.png -------------------------------------------------------------------------------- /icons/archive_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/archive_48x48.png -------------------------------------------------------------------------------- /icons/archive_60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/archive_60x60.png -------------------------------------------------------------------------------- /icons/backup.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/backup.png -------------------------------------------------------------------------------- /icons/cr_30x30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/cr_30x30.png -------------------------------------------------------------------------------- /icons/cr_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/cr_48x48.png -------------------------------------------------------------------------------- /icons/dlmode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/dlmode.png -------------------------------------------------------------------------------- /icons/error.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/error.png -------------------------------------------------------------------------------- /icons/extract_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/extract_48x48.png -------------------------------------------------------------------------------- /icons/flash_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/flash_48x48.png -------------------------------------------------------------------------------- /icons/flash_60x60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/flash_60x60.jpg -------------------------------------------------------------------------------- /icons/flashkdz_70x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/flashkdz_70x48.png -------------------------------------------------------------------------------- /icons/flashkdz_93x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/flashkdz_93x64.png -------------------------------------------------------------------------------- /icons/log_16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/log_16x16.png -------------------------------------------------------------------------------- /icons/ok_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/ok_64x64.png -------------------------------------------------------------------------------- /icons/salt_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/salt_icon.png -------------------------------------------------------------------------------- /icons/salt_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/salt_logo.png -------------------------------------------------------------------------------- /icons/salt_logo_128x128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/salt_logo_128x128.png -------------------------------------------------------------------------------- /icons/salt_logo_30x30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/salt_logo_30x30.png -------------------------------------------------------------------------------- /icons/salt_logo_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/salt_logo_64x64.png -------------------------------------------------------------------------------- /icons/terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/terminal.png -------------------------------------------------------------------------------- /icons/terminal_30x30.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/terminal_30x30.png -------------------------------------------------------------------------------- /icons/terminal_60x60.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/terminal_60x60.png -------------------------------------------------------------------------------- /icons/update_48x48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/update_48x48.png -------------------------------------------------------------------------------- /icons/warning_64x64.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/icons/warning_64x64.png -------------------------------------------------------------------------------- /install-desktop.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################## 3 | # SALT - [S]teadfasterX [A]ll-in-one [L]G [T]ool 4 | # 5 | # Copyright (C): 2017-2023, steadfasterX 6 | # 7 | # install Desktop starter for SALT 8 | # 9 | ################################################################################## 10 | 11 | HERE="$(pwd)" 12 | 13 | MYID=$(id -u) 14 | 15 | [ "$MYID" -ne 0 ] && echo -e "\nCom'on start me with sudo like:\n\n sudo bash $0\n" && exit 16 | 17 | REALUSER=$SUDO_USER 18 | HOME=/home/$SUDO_USER 19 | 20 | echo "$@" | grep -ql help 21 | if [ $? -eq 0 ];then 22 | cat <<_EOFH 23 | 24 | This installer is part of SALT (https://forum.xda-developers.com/t/tool-locked-unlocked-salt-the-lg-up-revolution-begins.3717864/) 25 | 26 | 27 | Usage info 28 | ------------------------ 29 | 30 | no arguments Will run the installer and prompt for installation mode 31 | 32 | --help This output 33 | --remove Will remove all traces of SALT (will prompt before doing so) 34 | 35 | 36 | 37 | _EOFH 38 | exit 0 39 | fi 40 | 41 | echo "$@" | grep -ql remove 42 | if [ $? -eq 0 ];then 43 | echo -e "\nDo you really wanna remove all traces of SALT now?\n" 44 | read -p " " REM 45 | if [ "$REM" == "y" ];then 46 | [ -f "${HOME}/.local/share/applications/SALT.desktop" ] && rm "${HOME}/.local/share/applications/SALT.desktop" && echo "... removed ${HOME}/.local/share/applications/SALT.desktop" 47 | [ -f /usr/share/applications/SALT.desktop ] && rm /usr/share/applications/SALT.desktop && echo "... removed /usr/share/applications/SALT.desktop" 48 | [ -f ${HOME}/.config/user-dirs.dirs ] && source ${HOME}/.config/user-dirs.dirs 49 | [ ! -z "$XDG_DESKTOP_DIR" ] && [ -d "$XDG_DESKTOP_DIR" ] && DESKDIR="$XDG_DESKTOP_DIR" 50 | [ -z "$DESKDIR" ] && DESKDIR="${HOME}/Desktop" 51 | [ -f "${DESKDIR}/SALT.desktop" ] && rm "${DESKDIR}/SALT.desktop" && echo "... removed ${DESKDIR}/SALT.desktop" 52 | [ -f /etc/sudoers.d/salt_sudo ] && rm /etc/sudoers.d/salt_sudo && echo "... removed /etc/sudoers.d/salt_sudo" 53 | [ -f /usr/share/polkit-1/actions/it.binbash.pkexec.salt.policy ] && rm /usr/share/polkit-1/actions/it.binbash.pkexec.salt.policy && echo "... removed /usr/share/polkit-1/actions/it.binbash.pkexec.salt.policy" 54 | echo -e "SALT uninstalled.\nPls remove the install dir MANUALLY." 55 | exit 0 56 | else 57 | echo aborted 58 | exit 4 59 | fi 60 | fi 61 | 62 | echo -e "\n\t1) use pkexec/policyKit (default)\n\t Will also install a SALT policy\n" 63 | echo -e "\t2) use gksudo (not available anymore on many distributions)\n\t Will also install a sudoers config\n" 64 | echo -e "\t3) use a custom auth binary (will ask for a path)\n" 65 | 66 | while [ -z "$ANS" ];do 67 | read -p "Your choice (1, 2 or 3): " ANS 68 | [ -z "$ANS" ] && ANS=1 69 | if [ "$ANS" != 1 -a "$ANS" != 2 -a "$ANS" != 3 ];then 70 | echo -e "\n??? what do you wanna say? only 1, 2 or 3 are valid answers. Try again:" 71 | unset ANS 72 | fi 73 | done 74 | 75 | echo -e "\n" 76 | 77 | case $ANS in 78 | 1) 79 | ./addPolicy.py ${HERE}/salt 80 | if [ $? -eq 0 ];then 81 | echo "... pkexec policy applied" 82 | else 83 | echo -e "\n!!! ERROR while applying pkexec policy! ABORTED\n\n" 84 | exit 3 85 | fi 86 | EXE=pkexec 87 | ;; 88 | 2) 89 | cat >/tmp/salt_sudo << _EOFSU 90 | # SALT (https://forum.xda-developers.com/t/tool-locked-unlocked-salt-the-lg-up-revolution-begins.3717864/) 91 | $REALUSER ALL=(ALL) NOPASSWD: ${HERE}/salt * 92 | _EOFSU 93 | echo -e "... sudo syntax check:" 94 | visudo -c -f /tmp/salt_sudo 95 | if [ $? -eq 0 ];then 96 | mv /tmp/salt_sudo /etc/sudoers.d/ 97 | visudo -c -f /etc/sudoers.d/salt_sudo 98 | [ $? -ne 0 ] && rm /etc/sudoers.d/salt_sudo && echo -e "\n!!! ERROR occured while applying sudo config! changes have been REVERTED! ABORTED.\n\n" && exit 3 99 | echo -e "... sudo config applied" 100 | EXE=gksudo 101 | else 102 | echo -e "\n\nABORTED! NOTHING HAS CHANGED! Error while validating temp sudo file..\n\n" 103 | exit 3 104 | fi 105 | ;; 106 | 3) 107 | echo -e "\n\nYou wanna use a custom auth method. Please specify the full path to the binary." 108 | while [ -z "$EXE" ];do 109 | read -p "full path: " EXE 110 | [ ! -x "$EXE" ] && echo -e "\npff... no way! $EXE is not an executable binary! Try again.." && unset EXE 111 | done 112 | ;; 113 | *) 114 | ;; 115 | esac 116 | 117 | cat > ${HERE}/SALT.desktop </\n\n" 143 | fi 144 | 145 | # install to the standard application store 146 | [ -d /usr/share/applications/ ] && cp ${HERE}/SALT.desktop /usr/share/applications/ 147 | 148 | echo -e "\nAll done! SALT has been installed to your desktop and is available in your start menu as well\n\n" 149 | -------------------------------------------------------------------------------- /kdzmanager.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ########################################################################################## 3 | # 4 | # SALT - [S]teadfasterX [A]ll-in-one [L]G [T]ool 5 | # 6 | # Copyright (C): 2017-2022, steadfasterX 7 | # 8 | # LG KDZ MANAGER 9 | # 10 | ########################################################################################## 11 | 12 | # the vars for the lgup-ng 13 | VARS="${0%/*}/salt.vars" 14 | source $VARS 15 | [ $? -ne 0 ] && "ERROR: Missing requirement <$VARS>." && exit 3 16 | 17 | # the functions for the lglaf GUI 18 | FUNCS="${0%/*}/salt.func" 19 | source $FUNCS 20 | [ $? -ne 0 ] && "ERROR: Missing requirement <$FUNCS>." && exit 3 21 | 22 | F_LOG "KDZMGR started.." 23 | 24 | F_HELP(){ 25 | echo -e "\nCopyright (C) 2017-$(date +%Y): steadfasterX " 26 | echo -e "LICENSE: LGPLv2 (https://www.gnu.org/licenses/old-licenses/lgpl-2.0.txt)\n" 27 | echo -e "\nUsage:\n----------------------------\n" 28 | echo -e "\tactions (one or both):" 29 | echo -e "\t-x | --extract [KDZ FILENAME] extract a kdz file plus the resulting dz file" 30 | echo -e "\t note: the current dir will be used as target dir by default" 31 | echo -e "\t extractedkdz/ and extracteddz/ will be created here" 32 | echo -e "\t-d | --extractdir if you want to specify another target dir for the KDZ" 33 | echo -e "\t-s | --slice ' ' extract only these slices (must be number(s) separated by space and quoted)" 34 | echo 35 | echo -e "\t--flash [PATH TO IMAGE FILES] will flash all image files of that directory (except userdata)" 36 | echo -e "\t[--with-userdata --flash ...] will flash all image files including userdata (like a factory reset)" 37 | echo 38 | echo -e "\n\tgeneral:" 39 | echo -e "\t-h | --help this output" 40 | echo -e "\t-t | --test test mode: will not extract/flash but print what would be done" 41 | echo -e "\t-b | --batch batch mode: no questions - DANGEROUS!" 42 | echo -e "\t-D | --debug debug mode" 43 | echo -e "\n" 44 | echo -e "\n\tExamples:\n" 45 | echo -e "\tkdzmanager.sh -x ~/Downloads/h815v20p.kdz (extract only)" 46 | echo -e "\tkdzmanager.sh --with-userdata --flash extracted (will flash all files from dir extracted - with userdata!)" 47 | echo -e "\tkdzmanager.sh --test --flash my/dir/ (will tell you what would be flashed from my/dir - without flashing!)" 48 | echo -e "\tkdzmanager.sh -x ~/Downloads/h815v20p.kdz --flash ./extracteddz/ (will extract and flash the result in 1 run)" 49 | echo 50 | } 51 | 52 | [ $# -eq 0 ] && F_HELP && exit 53 | 54 | FLASHING=0 55 | EXTRACT=0 56 | TESTMODE=0 57 | UDATA=0 58 | BATCH=0 59 | WCACHE=0 60 | DEBUG=0 61 | LISTMODE=0 62 | 63 | # check the args! 64 | while [ ! -z $1 ];do 65 | case "$1" in 66 | --with-userdata) 67 | UDATA=1 68 | shift 69 | ;; 70 | --with-cache) 71 | WCACHE=1 72 | shift 73 | ;; 74 | --flash) 75 | IMGPATH="$2" 76 | [ -z "$IMGPATH" ] && echo -e "\nextracting requires the full path to your extracted KDZ/DZ! e.g. $0 full/path/to/extracted/" && F_HELP && exit 77 | [ ! -d "$IMGPATH" ] && echo -e "\nERROR!! $IMGPATH DOES NOT EXISTS!?" && F_HELP && exit 78 | if [ ! -d "$LAFPATH" ];then 79 | echo -e "\nERROR: Expected LG LAF NG here: $LAFPATH" 80 | [ "$BATCH" -eq 0 ] && read -p "Should I download it for you? (y/N) " DLLAF 81 | if [ "$DLLAF" == "y" ]||[ "$BATCH" -eq 1 ];then 82 | git clone $LAFGIT $LAFPATH 83 | else 84 | exit 85 | fi 86 | fi 87 | FLASHING=1 88 | shift 2 89 | ;; 90 | -x|--extract) 91 | FULLKDZ="$2" 92 | [ -z "$FULLKDZ" ] && echo -e "\nextracting requires the full path to a KDZ! e.g. $0 full/path/to/kdz/kdzfilename.kdz" && F_HELP && exit 93 | [ ! -f "$FULLKDZ" ] && echo -e "\nERROR!! $FULLKDZ DOES NOT EXISTS!?" && F_HELP && exit 94 | if [ ! -d "$KDZTOOLS" ];then 95 | echo -e "\nERROR: Expected kdztools here: $KDZTOOLS" 96 | [ "$BATCH" -eq 0 ] && read -p "Should I download it for you? (y/N) " DLKDZ 97 | if [ "$DLKDZ" == "y" ]||[ "$BATCH" -eq 1 ];then 98 | git clone $KDZGIT $KDZTOOLS 99 | else 100 | exit 101 | fi 102 | fi 103 | shift 2 104 | EXTRACT=1 105 | ;; 106 | -d|--extractdir) 107 | KDZDIR="$2" 108 | shift 2 109 | ;; 110 | -t|--test) 111 | TESTMODE=1 112 | shift 113 | ;; 114 | -b|--batch) BATCH=1 ; shift ;; 115 | -D|--debug) DEBUG=1 ; shift ;; 116 | -s|--slice) SELPARTS="$2"; shift 2;; 117 | -l|--list) LISTMODE=1; shift;; 118 | *) 119 | F_HELP 120 | exit 121 | ;; 122 | esac 123 | done 124 | 125 | # list partitions of a DZ file 126 | FK_LISTPARTS(){ 127 | DZFILE=$(find "${KDZDIR}/extractedkdz/" -name '*\.dz') 128 | echo "DZFILE is $DZFILE" >> $LOG 129 | if [ "$BATCH" -eq 1 ];then 130 | $PYTHONBIN ${KDZTOOLS}/undz -b -l -f "${DZFILE}" 2>>$LOG 131 | else 132 | $PYTHONBIN ${KDZTOOLS}/undz -l -f "${DZFILE}" 133 | fi 134 | } 135 | 136 | # extract a KDZ file 137 | FK_EXTRACTKDZ(){ 138 | if [ "$BATCH" -eq 1 ];then 139 | $PYTHONBIN ${KDZTOOLS}/unkdz -f "$FULLKDZ" -x -d "${KDZDIR}/extractedkdz" 2>>$LOG 140 | else 141 | $PYTHONBIN ${KDZTOOLS}/unkdz -f "$FULLKDZ" -x -d "${KDZDIR}/extractedkdz" 142 | fi 143 | } 144 | 145 | # extract a DZ 146 | FK_EXTRACTPARTS(){ 147 | DZFILE=$(find "${KDZDIR}/extractedkdz/" -name '*\.dz') 148 | echo "DZFILE is $DZFILE" >> $LOG 149 | if [ "$BATCH" -eq 1 ];then 150 | $PYTHONBIN ${KDZTOOLS}/undz -b -s $SELPARTS -f "${DZFILE}" -d "${KDZDIR}/extracteddz" 151 | else 152 | $PYTHONBIN ${KDZTOOLS}/undz -s $SELPARTS -f "${DZFILE}" -d "${KDZDIR}/extracteddz" 153 | fi 154 | # delete unneeded parse files 155 | find "${KDZDIR}/extracteddz/" -name "*.params" -delete 156 | # rename GPT files to ensure they will not flashed by accident 157 | for gpt in $(find "${KDZDIR}/extracteddz/" -type f |grep -i GPT);do mv -v "$gpt" "${gpt/\.image/.gpt}";done 158 | } 159 | 160 | if [ $LISTMODE -eq 1 ];then 161 | BATCH=1 162 | FK_EXTRACTKDZ 2>&1 >>$LOG 163 | FK_LISTPARTS 2>>$LOG | sort -u -t : -k 2 | sort -t : -k 3| $EGREPBIN -v "(unallocated)" 164 | else 165 | # extract KDZ and DZ 166 | if [ $EXTRACT -eq 1 ];then 167 | [ -z "$KDZDIR" ] && KDZDIR="$(echo ~/Downloads)" 168 | echo -e "\nWill extract all files to: $KDZDIR" 169 | echo -e "\n\n***********\nWARNING:\n***********\nKDZ files contain the userdata image which can be very big (e.g. 23 GB on a LG G4)\nEnsure you have enough free disk space before continuing!\nYou can continue even when you have not enough free space but the result will be incomplete (still enough maybe)\n" 170 | [ "$BATCH" -eq 0 ] && read -p "I understood and want to continue (press ENTER)" DUMMY 171 | 172 | if [ $TESTMODE -eq 0 ];then 173 | DZFILE=$(find "${KDZDIR}/extractedkdz/" -name '*\.dz' 2>/dev/null) 174 | echo "DZFILE is $DZFILE" >> $LOG 175 | [ ! -f "$DZFILE" ] && FK_EXTRACTKDZ 176 | FK_EXTRACTPARTS 177 | # delete userdata partition when not needed 178 | [ "$UDATA" -eq 0 ] && echo "You have selected to delete userdata partition" && rm -rfv "${KDZDIR}/extracteddz/userdata*" 179 | # delete cache partition when not needed 180 | [ "$WCACHE" -eq 0 ] && echo "You have selected to delete cache partition" && rm -rfv "${KDZDIR}/extracteddz/cache*" 181 | # clean DZ file 182 | [ $DEBUG -eq 0 ] && rm -fv "${KDZDIR}/extractedkdz/*.dz" 183 | else 184 | echo "TESTMODE only:" 185 | echo "CMD: $PYTHONBIN ${KDZTOOLS}/unkdz -f $FULLKDZ -x -d ${KDZDIR}/extractedkdz" 186 | echo "CMD: $PYTHONBIN ${KDZTOOLS}/undz -s -f ${KDZDIR}/extractedkdz/*.dz -d ${KDZDIR}/extracteddz" 187 | fi 188 | 189 | echo -e "\n\nALL FINISHED! Your extracted files are in: ${KDZDIR}/extracteddz\n" 190 | fi 191 | 192 | # flash partitions 193 | if [ $FLASHING -eq 1 ];then 194 | # authenticate once 195 | if [ $TESTMODE -eq 0 ];then 196 | sudo $PYTHONBIN ${LAFPATH}/lglaf.py --skip-hello --showproto 197 | else 198 | echo "TESTMODE only:" 199 | echo "CMD: sudo $PYTHONBIN ${LAFPATH}/lglaf.py --skip-hello --showproto" 200 | fi 201 | # check if we want to leave out userdata (default) 202 | # gpt will be handled in a different manner (not ready yet) 203 | if [ $UDATA -eq 0 ];then 204 | GREPOUT="userdata|gpt" 205 | else 206 | GREPOUT="gpt" 207 | fi 208 | 209 | # flash 210 | for part in $(find "$IMGPATH" -maxdepth f -type 0 -name *.image | $EGREPBIN -vi "($GREPOUT)");do 211 | RMPATH="${part##*/}" 212 | REMPART="${RMPATH/\.image/}" 213 | echo -e "... flashing: $part to ${REMPART}" 214 | # redirecting the misleading error output (sorry dirty workaround atm..) 215 | if [ $TESTMODE -eq 0 ];then 216 | sudo $PYTHONBIN ${LAFPATH}/partitions.py --restore "$part" $REMPART 2>/dev/null 217 | else 218 | echo "TESTMODE only:" 219 | echo "CMD: sudo $PYTHONBIN ${LAFPATH}/partitions.py --restore $part $REMPART" 220 | fi 221 | done 222 | fi 223 | fi 224 | [ "$BATCH" -eq 0 ] && echo -e "\n\nAll done.\n\n" 225 | F_LOG "KDZMGR ended.." 226 | -------------------------------------------------------------------------------- /payload-dumper-go: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/steadfasterX/SALT/641b9b23d3b9b63113729ad3517a91cf76474b85/payload-dumper-go -------------------------------------------------------------------------------- /reboot: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################ 3 | 4 | VARS="${0%/*}/salt.vars" 5 | source $VARS 6 | 7 | FUNCS="${0%/*}/salt.func" 8 | source $FUNCS 9 | 10 | F_LOG "Reboot button script started" 11 | $FYAD --title="$YTITLE - REBOOT" --image="$SICONS/warning_64x64.png" --width=400 --text '\n Do you want to really reboot your device now?' --button=Reboot:0 --button=Cancel:1 --button="EDL/QDL":9 12 | ANS=$? 13 | [ $ANS -eq 0 ] && F_LOG "NORMAL REBOOT INITIATED by USER!" && $PYTHONBIN ${LAFPATH}/lglaf.py -c '!CTRL RSET' 14 | [ $ANS -eq 9 ] && F_LOG "REBOOT TO EDL INITIATED by USER!" && $PYTHONBIN ${LAFPATH}/lglaf.py -c '!CTRL AATD' 15 | F_LOG "Reboot button script ended" 16 | -------------------------------------------------------------------------------- /salt: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ################################################################################## 3 | # 4 | # SALT - [S]teadfasterX [A]ll-in-one [L]G [T]ool 5 | # 6 | # Copyright (C): 2017-2023, steadfasterX 7 | # 8 | # Starter for SALT 9 | # 10 | ################################################################################## 11 | 12 | # the vars for SALT 13 | VARS="${0%/*}/salt.vars" 14 | source $VARS 15 | [ $? -ne 0 ] && "ERROR: Missing requirement <$VARS>." && exit 3 16 | 17 | # the functions for the lglaf GUI 18 | FUNCS="${0%/*}/salt.func" 19 | source $FUNCS 20 | [ $? -ne 0 ] && "ERROR: Missing requirement <$FUNCS>." && exit 3 21 | 22 | # perms 23 | chown $REALUSER $LOG 2>&1 >> /dev/null 24 | chown -R $REALUSER $LAFPATH $KDZTOOLS $SDATPATH 2>&1 >> /dev/null 25 | 26 | # start logging 27 | [ -f "$LOG" ] && echo "backing up old logfile...." && cp -f $LOG ${LOG}.old 28 | echo -e "$(date '+%F %T'): Starting $TNAME v${VERSION}!\n****************************************************\n" > $LOG 29 | 30 | # check requirements: 31 | [ ! -x $YAD ] && F_ELOG "FATAL ERROR!! Missing requirement . Install YAD and try again!" && F_EXIT "no-YAD" 3 full 32 | if [ ! -x $LAFTERM ];then F_MSGE 700 "Missing X terminal (usually xterm).\n Install $LAFTERM or check salt.vars file."; F_EXIT "no-xterm" 3 full; fi 33 | if [ ! -x $GIT ];then no-git 3 "\n ERROR!\n\n Missing GIT client.\n Install $GIT or check salt.vars file." ; F_EXIT "no-git" 3 full; fi 34 | if [ ! -x $FBBIN ];then F_MSGE 700 "Missing fastboot!\nInstall $FBBIN first (or better directly consider to use mAid Linux...)!"; F_EXIT "no-fb" 3 full; fi 35 | 36 | $PYTHONBIN -c "import zstandard" 37 | if [ $? -ne 0 ];then F_MSGE 500 "FATAL ERROR!! Missing requirement\n\n python-zstandard (python3)\n\nRead the SALT thread for how to install and try again!" ; F_EXIT "no-zstd" 3 full;fi 38 | 39 | $PYTHONBIN -c "import cryptography" 40 | if [ $? -ne 0 ];then F_MSGE 500 "FATAL ERROR!! Missing requirement\n\n python cryptography module (python3)\n\nRead the SALT thread for how to install and try again!" ; F_EXIT "no-crypto" 3 full;fi 41 | 42 | # set full command for restarting properly 43 | export FULLCMD="$0 $@" 44 | 45 | # check root: 46 | ME=$(id -u) 47 | if [ "$ME" -ne 0 ];then 48 | echo -e '\nI need more POWER! If asked now type in your sudo password to restart with root perms (wait 20s or press CTRL+C to abort)' 49 | sudo $FULLCMD & 50 | sleep 20s 51 | F_LOG "no-root mode ending now" 52 | exit 0 53 | fi 54 | 55 | # check if we are alone 56 | F_EGO 57 | 58 | # catch ctrl+c for a clean exit 59 | trap "F_EXIT 'ctrl+c pressed' 0 full" SIGINT 60 | 61 | # check freshness 62 | F_VCHK 63 | 64 | # remove any previous working path 65 | rm -rf $USUTMPDIR 66 | 67 | # check the base: 68 | if [ ! -d "$LAFPATH" ];then 69 | F_ELOG "First start of SALT? Expected LG LAF NG here: $LAFPATH" 70 | DLLAF=$(F_MSG 400 "\n First start of SALT?\n\n Expected lglaf here:\n ${LAFPATH}\n\n but it is missing..\n\n Should I download it for you now?" "--button=Yes:0 --button=Abort:1") 71 | #DLLAF=$MERR 72 | if [ "$DLLAF" -eq 0 ];then 73 | $GIT clone --progress $LAFGIT $LAFPATH 2>&1 | $FYAD --title="$YTITLE - UPDATING" --text="\n Installing LGLAF ...\n" --height=600 --width=700 --text-info --listen --tail --button=Close 74 | else 75 | F_ERR lafupdate $DLLAF "\n Without this SALT will not work!\n ABORTED. \n" 76 | fi 77 | fi 78 | if [ ! -d "$KDZTOOLS" ];then 79 | F_ELOG "First start of SALT? Expected kdztools here: $KDZTOOLS" 80 | DLKDZ=$(F_MSG 400 "\n First start of SALT?\n\n Expected kdztools here:\n ${KDZTOOLS}\n\n but it is missing..\n\n Should I download it for you now?" "--button=Yes:0 --button=Abort:1") 81 | if [ "$DLKDZ" -eq 0 ];then 82 | $GIT clone --progress $KDZGIT $KDZTOOLS 2>&1 | $FYAD --title="$YTITLE - UPDATING" --text="\n Installing kdztools ...\n" --width=700 --height=600 --text-info --listen --tail --button=Close 83 | else 84 | F_ERR ktoolsupdate $DLKDZ "\n Without this SALT will not work!\n ABORTED. \n" 85 | fi 86 | fi 87 | if [ ! -d "$SDATPATH" ];then 88 | F_ELOG "First start of SALT? Expected sdat2img here: $SDATPATH" 89 | DLSDAT=$(F_MSG 400 "\n First start of SALT?\n\n Expected sdat2img here:\n ${SDATPATH}\n\n but it is missing..\n\n Should I download it for you now?" "--button=Yes:0 --button=Abort:1") 90 | if [ "$DLSDAT" -eq 0 ];then 91 | $GIT clone --progress $SDATGIT $SDATPATH 2>&1 | $FYAD --title="$YTITLE - UPDATING" --text="\n Installing sdat2img ...\n" --width=700 --height=600 --text-info --listen --tail --button=Close 92 | else 93 | F_LOG "sdat2imgsupdate $DLSDAT Without this SALT will not fully work" 94 | fi 95 | fi 96 | 97 | # collect some sys info 98 | F_LOG "OS: $(cat /etc/*-release)" 99 | F_LOG "OS (lsb): $(lsb_release -a)" 100 | F_LOG "yad: $(yad --version)" 101 | F_LOG "summary:\n $(hostnamectl status |grep -v ID)\n" 102 | 103 | # check if device in dl mode connected 104 | DEVCON=99 105 | while [ $DEVCON -ne 0 ];do 106 | [ $DEVCON -eq 11 ] && break 107 | F_LOG "DEVCON before: $DEVCON" 108 | F_CHKDEVCON 109 | DEVCON=$? 110 | # skip=11, retry=22, connected=0 111 | F_LOG "DEVCON after: $DEVCON" 112 | done 113 | 114 | # check how we get started 115 | EXPERIMENTAL=$(echo "$@"|grep -c experimental) 116 | F_LOG "EXPERIMENTAL: $EXPERIMENTAL" 117 | 118 | case $CRMODE in 119 | Auto)export CRBTN="Force CR";; 120 | yes)export CRBTN="Force no CR";; 121 | no)export CRBTN="Set CR Auto";; 122 | esac 123 | 124 | # main func 125 | F_MAIN(){ 126 | if [ $DEVCON -ne 11 ];then 127 | DEVINF=$(F_GETINFO) 128 | for i in $DEVINF;do 129 | case "${i/:*/}" in 130 | imei|serial) F_LOG "parsing ${i/:*/}:xxxxxxxxxxx" ;; 131 | *) F_LOG "parsing ${i/*:/}" ;; 132 | esac 133 | case ${i/:*/} in 134 | usu) 135 | LGUSUA=$(echo "${i}"|cut -d ":" -f2) 136 | USUMODEL=$(echo "${i}"|cut -d ":" -f3) 137 | export LGUSU="no" 138 | [ "$LGUSUA" == "1" ] && export LGUSU="yes" 139 | ;; 140 | arb) 141 | DEVARBVAL=$(echo ${i}| cut -d ":" -f 2) 142 | DEVARBEMPT=$(echo ${i}| cut -d ":" -f 3) 143 | if [ "$DEVARBEMPT" == "0" ];then 144 | DEVARB=$DEVARBVAL 145 | else 146 | DEVARB="ARB_unknown" 147 | fi 148 | ;; 149 | lafver) export LAFVER=${i/*:/};; 150 | imei) LGIMEI=${i/*:/};; 151 | serial) LGSERIAL=${i/*:/};; 152 | target_operator) LGOPER=${i/*:/};; 153 | usu_model) USUMODEL=${i/*:/};; 154 | romcomp) ROMCOMP=${i/*:/};; 155 | battery_level) LGBATT=${i/*:/};; 156 | model_name) LGMODEL=${i/*:/};; 157 | device_sw_version) LGSWV=${i/*:/};; 158 | secure_device) LGSEC=${i/*:/};; 159 | device_factory_version) LGFACV="$(echo ${i/*:/} | sed 's/^-/x/g')";; 160 | target_country) LGCOUNTRY=${i/*:/};; 161 | *) F_ELOG "unknown parameter: $i" ;; 162 | esac 163 | done 164 | fi 165 | [ -z $LAFVER ] && export LAFVER=no_device_found 166 | [ -z $LGUSUA ] && export LGUSU=no_device_found 167 | [ -z $LGIMEI ] && LGIMEI=no_device_found 168 | [ -z $LGSERIAL ] && LGSERIAL=no_device_found 169 | [ -z $LGOPER ] && LGOPER=no_device_found 170 | [ -z $LGMODEL ] && LGMODEL=no_device_found 171 | [ -z $LGSWV ] && LGSWV=no_device_found 172 | [ -z $LGFACV ] && LGFACV=no_info_found 173 | [ -z $LGCOUNTRY ] && LGCOUNTRY=no_device_found 174 | [ -z $LGSEC ] && LGSEC=no_device_found 175 | [ -z $LGBATT ] && LGBATT=no_device_found 176 | [ -z $ROMCOMP ] && ROMCOMP=no_device_found 177 | [ -z $DEVARB ] && DEVARB=no_ARB_info_found 178 | # overwrite model definition when UsU and model info available 179 | [ ! -z $USUMODEL ] && LGMODEL=$USUMODEL && LGSERIAL=${LGSERIAL/LGLS991/$LGMODEL} 180 | 181 | F_LOG "Detected stuff:\nDEVCON=$DEVCON\nLAFVER=$LAFVER\nLGUSU=$LGUSU\nLGSERIAL=$LGSERIAL\nLGOPER=$LGOPER\nLGMODEL=$LGMODEL\nLGSWV=$LGSWV\nLGFACV=$LGFACV\nLGCOUNTRY=$LGCOUNTRY\nLGSEC=$LGSEC\nLGBATT=$LGBATT\nROMCOMP=$ROMCOMP\nDEVARB=$DEVARB" 182 | 183 | # make the decision whcih features should be enabled in the main GUI 184 | #TODO: test all flash parts again then we can enable that one: if [ "$LAFVER" == "1000001" ]||[ $EXPERIMENTAL -eq 1 ];then FLASHMENU=1; else FLASHMENU=0;fi 185 | #if [ "$LAFVER" == "1000001" ]||[ $EXPERIMENTAL -eq 1 ];then FLASHMENU=0; else FLASHMENU=0;fi 186 | if [ $DEVCON -eq 0 ];then 187 | if [ "$LAFVER" != "1000001" ] && [ $EXPERIMENTAL -ne 1 ];then 188 | 189 | shopt -s extglob 190 | case $LGMODEL in 191 | ${LGG4}) 192 | F_MSGW 700 "Your LAF firmware ($LAFVER / $LGMODEL) does not support direct flashing!\n\nFlashing functionality disabled!\n\nActivate flashing functionality by flashing a SALT compatible LAF partition.\nDownload it right here for any G4 model (requires an unlocked device + TWRP):\n\nSALT-compatible-LAF_flash-in-twrp.zip (click here)\n\nYou can still use many of the features SALT offering - just not the flashing part.\n\nThis does NOT affect unlocking the G4!\nJust go on if you want to UsU.." "--fixed --height=300" 193 | ;; 194 | esac 195 | F_LOG "Flashing functionality disabled bc: LAFVER = $LAFVER and/or EXPERIMENTAL = $EXPERIMENTAL" 196 | FLASHMENU=0 197 | else 198 | #ATM: DISABLED! WITHOUT EXPERIMENTAL FLAG NO WAY TO OPEN IT 199 | # FLASHMENU=1 200 | FLASHMENU=0 201 | F_LOG "Flashing functionality enabled bc: LAFVER = $LAFVER and/or EXPERIMENTAL = $EXPERIMENTAL" 202 | F_LOG "HINT: Flashing temporarly NOT auto enabled (until all tests finished)!" 203 | fi 204 | else 205 | F_LOG "Flashing functionality disabled bc: DEVCON = $DEVCON (no device found and skipped pressed)" 206 | FLASHMENU=0 207 | fi 208 | 209 | # main SALT screen depends on experimental flag .. and LAF version .. and model 210 | if [ $FLASHMENU -eq 0 ]&&[ $EXPERIMENTAL -ne 1 ];then 211 | shopt -s extglob 212 | case $LGMODEL in 213 | ${LGG4}) 214 | F_LOG "$FUNCNAME: starting G4 menu" 215 | $FYAD --title="$YTITLE" --width=1100 --height=620 --scroll --image="$SICONS/salt_logo_128x128.png" --text "\n $TFULLNAME\n SALT is a replacement for the windows software LGUP (plus MANY more features!) and brought to you by steadfasterX\n (click here to open the official SALT thread)\n\n The following comes directly from your device:\n (\"no_device_found\" if no device connected)\n" \ 216 | --form --columns=2 \ 217 | --field=" Device model":RO $LGMODEL \ 218 | --field=" Device+Version (by LAFd)":RO $LGSWV \ 219 | --field=" Last STOCK version":RO "$LGFACV" \ 220 | --field=" LAF protocol":RO $LAFVER \ 221 | --field=" REBOOT your device":FBTN "$SALTPATH/reboot" \ 222 | --field=" Battery level":RO $LGBATT \ 223 | --field=" AntiRollBack":RO $DEVARB \ 224 | --field=" IMEI" $LGIMEI \ 225 | --field=" Serial":RO $LGSERIAL \ 226 | --field=" ADVANCED Menu!$SICONS/advanced_16x16.png!This contains tools not for the average user!":FBTN "bash -c 'F_ADVMENU $LGMODEL $ROMCOMP $LGOPER $LGCOUNTRY $LGUSU'" \ 227 | true \ 228 | --buttons-layout=spread \ 229 | --button="!$SICONS/update_48x48.png!Updating SALT (kdztools, lglaf, SALT)":"bash -c F_UPDATE" \ 230 | --button=" Backup!$SICONS/backup.png!Make a full or basic backup while in download mode":"bash -c F_BACKUP" \ 231 | --button="Extract KDZ!$SICONS/extract_48x48.png!Extract a KDZ file. If you want to flash choose Extract+Flash instead":"bash -c F_STARTKDZ" 232 | ;; 233 | *) 234 | F_LOG "$FUNCNAME: starting non-G4 menu" 235 | $FYAD --title="$YTITLE" --width=1100 --height=620 --scroll --image="$SICONS/salt_logo_128x128.png" --text "\n $TFULLNAME\n SALT is a replacement for the windows software LGUP (plus MANY more features!) and brought to you by steadfasterX\n (click here to open the official SALT thread)\n\n The following comes directly from your device:\n (\"no_device_found\" if no device connected)\n" \ 236 | --form --columns=2 \ 237 | --field=" Device model":RO $LGMODEL \ 238 | --field=" Device+Version (by LAFd)":RO $LGSWV \ 239 | --field=" Last STOCK version":RO "$LGFACV" \ 240 | --field=" LAF protocol":RO $LAFVER \ 241 | --field=" REBOOT your device":FBTN "$SALTPATH/reboot" \ 242 | --field=" Battery level":RO $LGBATT \ 243 | --field=" AntiRollBack":RO $DEVARB \ 244 | --field=" IMEI" $LGIMEI \ 245 | --field=" Serial":RO $LGSERIAL \ 246 | --field=" ADVANCED Menu!$SICONS/advanced_16x16.png!This contains tools not for the average user!":FBTN "bash -c 'F_ADVMENU $LGMODEL $ROMCOMP $LGOPER $LGCOUNTRY $LGUSU'" \ 247 | true \ 248 | --buttons-layout=spread \ 249 | --button="!$SICONS/update_48x48.png!Updating SALT (kdztools, lglaf, SALT)":"bash -c F_UPDATE" \ 250 | --button=" Backup!$SICONS/backup.png!Make a full or basic backup while in download mode":"bash -c F_BACKUP" \ 251 | --button="Extract KDZ!$SICONS/extract_48x48.png!Extract a KDZ file. If you want to flash choose Extract+Flash instead":"bash -c F_STARTKDZ" 252 | ;; 253 | esac 254 | else 255 | # when started with --experimental (will be removed one day) 256 | if [ $EXPERIMENTAL -eq 1 ]||[ $FLASHMENU -eq 1 ];then 257 | F_LOG "$FUNCNAME: starting experimental menu" 258 | $FYAD --title="$YTITLE" --width=1100 --height=620 --scroll --image="$SICONS/salt_logo_128x128.png" --text "\n $TFULLNAME\n SALT is a replacement for the windows software LGUP (plus MANY more features!) and brought to you by steadfasterX\n (click here to open the official SALT thread)\n\n The following comes directly from your device:\n (\"no_device_found\" if no device connected)\n" \ 259 | --form --columns=2 \ 260 | --field=" Device model":RO $LGMODEL \ 261 | --field=" Device+Version (by LAFd)":RO $LGSWV \ 262 | --field=" Last STOCK version":RO "$LGFACV" \ 263 | --field=" LAF protocol":RO $LAFVER \ 264 | --field=" REBOOT your device":FBTN "$SALTPATH/reboot" \ 265 | --field=" Battery level":RO $LGBATT \ 266 | --field=" AntiRollBack":RO $DEVARB \ 267 | --field=" IMEI" $LGIMEI \ 268 | --field=" Serial":RO $LGSERIAL \ 269 | --field=" ADVANCED Menu!$SICONS/advanced_16x16.png!This contains tools not for the average user!":FBTN "bash -c 'F_ADVMENU $LGMODEL $ROMCOMP $LGOPER $LGCOUNTRY $LGUSU'" \ 270 | true \ 271 | --buttons-layout=spread \ 272 | --button="!$SICONS/update_48x48.png!Updating SALT (kdztools, lglaf, SALT)":"bash -c F_UPDATE" \ 273 | --button=" Backup!$SICONS/backup.png!Make a full or basic backup while in download mode":"bash -c F_BACKUP" \ 274 | --button="Extract KDZ!$SICONS/extract_48x48.png!Extract a KDZ file. If you want to flash choose Extract+Flash instead":"bash -c F_STARTKDZ" \ 275 | --button="Flash (folder)!$SICONS/flash_48x48.png!This will flash one or multiple partitions from any folder (e.g. from a previous backup)":"bash -c F_FLASHPART"\ 276 | --button=" Flash (kdz)!$SICONS/flashkdz_70x48.png!Extract and Flash like LGUP would do":"bash -c F_STARTKDZFL" 277 | else 278 | F_LOG "ERROR dont know which GUI should be used... :(" 279 | fi 280 | fi 281 | } 282 | F_MAIN 283 | 284 | F_EXIT "main->end" 0 full 285 | -------------------------------------------------------------------------------- /salt.hashes: -------------------------------------------------------------------------------- 1 | # hash table 2 | 3 | # UsU hash for any model 4 | export USUHASH=f8e26b6df293d87aa40ca635a6407291495024bcf413a93302589c95e68b2b6a 5 | 6 | case "$LGMODEL" in 7 | *F500*) 8 | export RRHASH=346f47514751934b04352a6ad9ea8e474f2d35fbcbdcb86e06b1cebc94b66a43 9 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 10 | ;; 11 | *H810*) 12 | export RRHASH=b37195386ad983d2440baf77d7c985577b7d5c8b4ed5cc85e1dea9dc451a59ab 13 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 14 | ;; 15 | *H812*) 16 | export RRHASH=8b25d1aacb1888f073d59701f9119ec1574ebd796245cef5ef7cf7c82566b645 17 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 18 | ;; 19 | *H815*) 20 | export RRHASH=f81757904e8c4f7890c03e35b89a695c4bd48f4256858918c57f9bad33621f77 21 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 22 | ;; 23 | *H818*) 24 | export RRHASH=db13da298df82502ec331b74f46241a676cf03eaba73b4ffcc66800483d46983 25 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 26 | ;; 27 | *H819*) 28 | export RRHASH=22ce9bae27f9f4db2224d137721028bf327a420834b8f97d28d789bc162a5dce 29 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 30 | ;; 31 | *LS991*) 32 | export RRHASH=d38c87a7f68fd03445f24d7a4fafef2a23b578eead73dbafcb2fde82aef96e73 33 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 34 | ;; 35 | *US991*) 36 | export RRHASH=7abeffe9fb582454fc0571a7dfd7c928988751372ad970c28cc0d32e58588bb6 37 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 38 | ;; 39 | *VS986*) 40 | export RRHASH=4803d43a40a88ebab1b2fda6281b240ffa26c500d96b0cb5da705f5b9ac51d5c 41 | export DLMHASH=ee7db724fe1df15f9941ecc474995484f7ab9f91acefb30af17504202abf42c6 42 | ;; 43 | esac 44 | -------------------------------------------------------------------------------- /salt.vars: -------------------------------------------------------------------------------- 1 | ########################################################################## 2 | # 3 | # SALT - [S]teadfasterX [A]ll-in-one [L]G [T]ool 4 | # 5 | # Copyright (C): 2017-2023, steadfasterX 6 | # 7 | # global variables for SALT 8 | # 9 | # include this with: 10 | # source salt.vars 11 | # 12 | # brought to you by: steadfasterX 13 | ########################################################################## 14 | 15 | ## binaries needed in SALT 16 | export YAD="/usr/bin/yad" 17 | export GIT=/usr/bin/git 18 | export LAFTERM="/usr/bin/xterm" 19 | export CURLB="/usr/bin/env curl" 20 | export FBBIN="/usr/bin/fastboot" 21 | export DFBIN="/bin/df" 22 | export AWKBIN="/bin/awk" 23 | export GREPBIN="/bin/grep" 24 | export EGREPBIN="/bin/grep -E" 25 | export TRBIN="/bin/tr" 26 | export TEEBIN="/usr/bin/tee" 27 | 28 | ## salt basic stuff 29 | export LC_ALL=C 30 | export VDIG="3.36-1" 31 | export TNAME="SALT" 32 | export TFULLNAME="$TNAME - [S]teadfasterX's [A]ll-in-one [L]G [T]ool" 33 | export PYTHONUNBUFFERED=1 34 | export VERSION="${VDIG}:STREAM" 35 | export YTITLE="$TNAME - $VERSION" 36 | # comment the following when you get issues: 37 | export LAFARGS="--skip-hello" 38 | # remove the # char from the following for advanced debugging info: 39 | #export LAFARGS="--skip-hello --debug" 40 | 41 | ## user detection 42 | if [ ! -z "$PKEXEC_UID" ];then 43 | export REALUSER=$(id -nu $PKEXEC_UID); export REALHOME=/home/$REALUSER 44 | echo "DEBUG: user $REALUSER identified by pkexec" 45 | else 46 | if [ ! -z "$SUDO_USER" ];then 47 | export REALHOME=/home/$SUDO_USER; export REALUSER=$SUDO_USER 48 | echo "DEBUG: user $REALUSER identified by sudo" 49 | elif [ "$USER" != "root" ];then 50 | export REALHOME=/home/$USER; export REALUSER=$USER 51 | echo "DEBUG: user $REALUSER identified" 52 | else 53 | echo "WARNING: SALT seems to run as REAL root user!" 54 | export REALHOME=$HOME; export REALUSER=root 55 | fi 56 | fi 57 | 58 | ## paths 59 | export SALTPATH="${0%/*}" 60 | export KDZMGR="$SALTPATH/kdzmanager.sh" 61 | export FOREIGNPATH="$SALTPATH/foreign" 62 | export APASTE="$FOREIGNPATH/usr/bin/anypaste" 63 | export LAFPATH=$REALHOME/programs/lglafng 64 | export KDZTOOLS=$REALHOME/programs/kdztools 65 | export SICONS="$SALTPATH/icons" 66 | export SDATPATH=$REALHOME/programs/sdat2img 67 | export SDATBIN="$SDATPATH/sdat2img.py" 68 | export LOG="$REALHOME/salt.log" 69 | export USUTMPDIR=/tmp/UsU 70 | export DUMPER="$SALTPATH/payload-dumper-go" 71 | 72 | ## misc 73 | export FYAD="$YAD --center --window-icon=$SICONS/salt_logo.png" 74 | export KDZGIT="https://github.com/steadfasterX/kdztools.git" 75 | export LAFGIT="https://github.com/steadfasterX/lglaf.git" 76 | export SDATGIT="https://github.com/xpirt/sdat2img.git" 77 | export LOCKFILE=/tmp/salt.lock 78 | export PYTHONBIN="/usr/bin/env python3" 79 | export BROTLI=/usr/bin/brotli 80 | export STDBUF="/usr/bin/stdbuf -o0" # required to disable buffering for progress bars 81 | 82 | # default lglaf CR detection (can be interactively set in SALT -> Advanced Menu -> CR) 83 | # Auto,yes,no 84 | # yes enforces CR, no enforces no CR 85 | [ -z "$CRMODE" ] && export CRMODE=Auto 86 | 87 | # default max partition size in MB (basic backup) 88 | export BMAXDEF=260 89 | 90 | ### partitions info 91 | # unneeded partitions means they contain no or useless data. 92 | # e.g. cache or userdata never needed to flash from a KDZ 93 | export PUNNEEDED="@(cache|grow|userdata)" 94 | 95 | # known to be dangerous to flash (in terms of locking/unlocking state and device specific 96 | # data like IMEI etc 97 | export PDEVICE="@(devinfo|drm|misc|modemst1|modemst2|persist|persistent|sns)" 98 | 99 | # known to be safe to flash 100 | export PSYSTEM="@(apdp|boot|carrier|cust|DDR|dpo|eksst|encrypt|eri|factory|felicia|fota|fsc|fsg|keystore|limits|modem|mpt|msadp|operatorlogging|raw_resources*|rct|recovery|sec|ssd|system)" 101 | 102 | # known to be part of the bootloader plus LAF as that is required to be compatible with the rest of 103 | # the bootloader stack in order to bring up download mode on locked devices! 104 | export PBOOTL="@(aboot|abootbak|hyp|hypbak|laf|pmic|pmicbak|rpm|rpmbak|sbl1|sbl1bak|sdi|sdibak|tz|tzbak)" 105 | 106 | # When extracting a KDZ or using auto mode to extract/flash these are NEVER be flashed (must be separated by a pipe) 107 | export AUTONOEXTRACT="GPT|misc|devinfo|modemst*" 108 | 109 | ## Ignore list for flashing 110 | export FLASHIGNORE="GPT|firehose|zeros" 111 | 112 | ## G4 UsU 113 | # same then AUTONOEXTRACT but when UsU has been detected 114 | export AUTONOEXTRACTUSU="${AUTONOEXTRACT}|aboot*|raw_resources*" 115 | export USUVALIDS="@(LG-G4_UsU|*LS991*|*F500*|*H810*|*H812*|*H811*|*H815*|*H819*|*US991*|*VS986*)" 116 | export FLASHIGNOREUSU="aboot|laf|raw_resources|GPT|firehose|zeros" 117 | 118 | ## LG models 119 | export LGG4="@(LG-G4_UsU|*LS991*|*F500*|*H810*|*H812*|*H811*|*H815*|*H818*|*H819*|*US991*|*VS986*)" 120 | 121 | ## ARB partition(s) 122 | # List of known partition names containing the ARB value 123 | export PARB="aboot|sbl1|xbl1|xbl" 124 | 125 | # shown names when switching/updating 126 | export SALTMODES="STABLE|STREAM" 127 | # git branches: current version 128 | export BR_S_SALT=master 129 | export BR_S_KDZ=master 130 | export BR_S_LAF=stable 131 | # git branches: testing version 132 | export BR_T_SALT=develop 133 | export BR_T_KDZ=develop 134 | export BR_T_LAF=develop 135 | --------------------------------------------------------------------------------