├── .gitattributes ├── .gitignore ├── AUTHORS ├── COPYING ├── ChangeLog ├── INSTALL ├── LICENSE ├── Makefile.am ├── Makefile.in ├── NEWS ├── README ├── README.md ├── ac-macros ├── ac_python_module.m4 └── ax_cflags_gcc_option.m4 ├── acinclude.m4 ├── aclocal.m4 ├── build-aux ├── compile ├── config.guess ├── config.sub ├── depcomp ├── install-sh └── missing ├── configure ├── configure.ac ├── contrib ├── freeze.sh ├── melt.sh └── poorZFS.py ├── docs └── README.RS32 └── src ├── Makefile.am ├── Makefile.in ├── rs.c ├── rs.h ├── rs32.c ├── rs32.h ├── rs32asm.s ├── rsbep.c └── rsbep_chopper.c /.gitattributes: -------------------------------------------------------------------------------- 1 | contrib/*.sh linguist-vendored 2 | ac-macros/* linguist-vendored 3 | build-aux/* linguist-vendored 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | Makefile 2 | config.log 3 | config.status 4 | src/.deps/ 5 | src/Makefile 6 | autom4te.cache/ 7 | src/rsbep 8 | src/rsbep-rs.o 9 | src/rsbep-rsbep.o 10 | src/rsbep_chopper 11 | src/rsbep_chopper.o 12 | -------------------------------------------------------------------------------- /AUTHORS: -------------------------------------------------------------------------------- 1 | Robert Morelos-Zaragoza (robert@spectra.eng.hawaii.edu), Aug 1995 2 | Hari Thirumoorthy (harit@spectra.eng.hawaii.edu), Aug 1995 3 | 4 | Phil Karn (karn@ka9q.ampr.org), August 1997 5 | 6 | Guido Fiala (gfiala@s.netic.de), July 2001 7 | 8 | Swen Thuemmler 9 | 10 | Thanassis Tsiodras (ttsiodras@gmail.com), July 2008/March 2009 11 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 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 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Library General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License 307 | along with this program; if not, write to the Free Software 308 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 309 | 310 | 311 | Also add information on how to contact you by electronic and paper mail. 312 | 313 | If the program is interactive, make it output a short notice like this 314 | when it starts in an interactive mode: 315 | 316 | Gnomovision version 69, Copyright (C) year name of author 317 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 318 | This is free software, and you are welcome to redistribute it 319 | under certain conditions; type `show c' for details. 320 | 321 | The hypothetical commands `show w' and `show c' should show the appropriate 322 | parts of the General Public License. Of course, the commands you use may 323 | be called something other than `show w' and `show c'; they could even be 324 | mouse-clicks or menu items--whatever suits your program. 325 | 326 | You should also get your employer (if you work as a programmer) or your 327 | school, if any, to sign a "copyright disclaimer" for the program, if 328 | necessary. Here is a sample; alter the names: 329 | 330 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 331 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 332 | 333 | , 1 April 1989 334 | Ty Coon, President of Vice 335 | 336 | This General Public License does not permit incorporating your program into 337 | proprietary programs. If your program is a subroutine library, you may 338 | consider it more useful to permit linking proprietary applications with the 339 | library. If this is what you want to do, use the GNU Library General 340 | Public License instead of this License. 341 | -------------------------------------------------------------------------------- /ChangeLog: -------------------------------------------------------------------------------- 1 | 2009-03-09: ttsiodras@gmail.com (Thanassis Tsiodras) 2 | 3 | - This version detects during ./configure whether to use 4 | x86 ASM or not - it also comes with a Python FUSE script 5 | that allows you to mount Reed-Solomon protected filesystems. 6 | 7 | 2008-07-30: ttsiodras@gmail.com (Thanassis Tsiodras) 8 | 9 | CHANGES from original rsbep: 10 | 11 | - gravy (autoconf/automake), ... 12 | - This version doesn't write the 3 parameters of rsbep as a 13 | single line before the data, as this makes the stream fragile 14 | (if this information is lost, decoding fails...) 15 | - It uses a default value of 16*255=4080 for parameter D, 16 | and it can thus tolerate 4080*16=65280 consecutive bytes 17 | to be lost anywhere in the stream, and still recover... 18 | - It comes with two very simple scripts (freeze.sh, melt.sh) 19 | that keep track of the input size, and thus offer a complete 20 | interface for standalone file "shielding". 21 | 22 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | Installation Instructions 2 | ************************* 3 | 4 | Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005, 5 | 2006 Free Software Foundation, Inc. 6 | 7 | This file is free documentation; the Free Software Foundation gives 8 | unlimited permission to copy, distribute and modify it. 9 | 10 | Basic Installation 11 | ================== 12 | 13 | Briefly, the shell commands `./configure; make; make install' should 14 | configure, build, and install this package. The following 15 | more-detailed instructions are generic; see the `README' file for 16 | instructions specific to this package. 17 | 18 | The `configure' shell script attempts to guess correct values for 19 | various system-dependent variables used during compilation. It uses 20 | those values to create a `Makefile' in each directory of the package. 21 | It may also create one or more `.h' files containing system-dependent 22 | definitions. Finally, it creates a shell script `config.status' that 23 | you can run in the future to recreate the current configuration, and a 24 | file `config.log' containing compiler output (useful mainly for 25 | debugging `configure'). 26 | 27 | It can also use an optional file (typically called `config.cache' 28 | and enabled with `--cache-file=config.cache' or simply `-C') that saves 29 | the results of its tests to speed up reconfiguring. Caching is 30 | disabled by default to prevent problems with accidental use of stale 31 | cache files. 32 | 33 | If you need to do unusual things to compile the package, please try 34 | to figure out how `configure' could check whether to do them, and mail 35 | diffs or instructions to the address given in the `README' so they can 36 | be considered for the next release. If you are using the cache, and at 37 | some point `config.cache' contains results you don't want to keep, you 38 | may remove or edit it. 39 | 40 | The file `configure.ac' (or `configure.in') is used to create 41 | `configure' by a program called `autoconf'. You need `configure.ac' if 42 | you want to change it or regenerate `configure' using a newer version 43 | of `autoconf'. 44 | 45 | The simplest way to compile this package is: 46 | 47 | 1. `cd' to the directory containing the package's source code and type 48 | `./configure' to configure the package for your system. 49 | 50 | Running `configure' might take a while. While running, it prints 51 | some messages telling which features it is checking for. 52 | 53 | 2. Type `make' to compile the package. 54 | 55 | 3. Optionally, type `make check' to run any self-tests that come with 56 | the package. 57 | 58 | 4. Type `make install' to install the programs and any data files and 59 | documentation. 60 | 61 | 5. You can remove the program binaries and object files from the 62 | source code directory by typing `make clean'. To also remove the 63 | files that `configure' created (so you can compile the package for 64 | a different kind of computer), type `make distclean'. There is 65 | also a `make maintainer-clean' target, but that is intended mainly 66 | for the package's developers. If you use it, you may have to get 67 | all sorts of other programs in order to regenerate files that came 68 | with the distribution. 69 | 70 | Compilers and Options 71 | ===================== 72 | 73 | Some systems require unusual options for compilation or linking that the 74 | `configure' script does not know about. Run `./configure --help' for 75 | details on some of the pertinent environment variables. 76 | 77 | You can give `configure' initial values for configuration parameters 78 | by setting variables in the command line or in the environment. Here 79 | is an example: 80 | 81 | ./configure CC=c99 CFLAGS=-g LIBS=-lposix 82 | 83 | *Note Defining Variables::, for more details. 84 | 85 | Compiling For Multiple Architectures 86 | ==================================== 87 | 88 | You can compile the package for more than one kind of computer at the 89 | same time, by placing the object files for each architecture in their 90 | own directory. To do this, you can use GNU `make'. `cd' to the 91 | directory where you want the object files and executables to go and run 92 | the `configure' script. `configure' automatically checks for the 93 | source code in the directory that `configure' is in and in `..'. 94 | 95 | With a non-GNU `make', it is safer to compile the package for one 96 | architecture at a time in the source code directory. After you have 97 | installed the package for one architecture, use `make distclean' before 98 | reconfiguring for another architecture. 99 | 100 | Installation Names 101 | ================== 102 | 103 | By default, `make install' installs the package's commands under 104 | `/usr/local/bin', include files under `/usr/local/include', etc. You 105 | can specify an installation prefix other than `/usr/local' by giving 106 | `configure' the option `--prefix=PREFIX'. 107 | 108 | You can specify separate installation prefixes for 109 | architecture-specific files and architecture-independent files. If you 110 | pass the option `--exec-prefix=PREFIX' to `configure', the package uses 111 | PREFIX as the prefix for installing programs and libraries. 112 | Documentation and other data files still use the regular prefix. 113 | 114 | In addition, if you use an unusual directory layout you can give 115 | options like `--bindir=DIR' to specify different values for particular 116 | kinds of files. Run `configure --help' for a list of the directories 117 | you can set and what kinds of files go in them. 118 | 119 | If the package supports it, you can cause programs to be installed 120 | with an extra prefix or suffix on their names by giving `configure' the 121 | option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. 122 | 123 | Optional Features 124 | ================= 125 | 126 | Some packages pay attention to `--enable-FEATURE' options to 127 | `configure', where FEATURE indicates an optional part of the package. 128 | They may also pay attention to `--with-PACKAGE' options, where PACKAGE 129 | is something like `gnu-as' or `x' (for the X Window System). The 130 | `README' should mention any `--enable-' and `--with-' options that the 131 | package recognizes. 132 | 133 | For packages that use the X Window System, `configure' can usually 134 | find the X include and library files automatically, but if it doesn't, 135 | you can use the `configure' options `--x-includes=DIR' and 136 | `--x-libraries=DIR' to specify their locations. 137 | 138 | Specifying the System Type 139 | ========================== 140 | 141 | There may be some features `configure' cannot figure out automatically, 142 | but needs to determine by the type of machine the package will run on. 143 | Usually, assuming the package is built to be run on the _same_ 144 | architectures, `configure' can figure that out, but if it prints a 145 | message saying it cannot guess the machine type, give it the 146 | `--build=TYPE' option. TYPE can either be a short name for the system 147 | type, such as `sun4', or a canonical name which has the form: 148 | 149 | CPU-COMPANY-SYSTEM 150 | 151 | where SYSTEM can have one of these forms: 152 | 153 | OS KERNEL-OS 154 | 155 | See the file `config.sub' for the possible values of each field. If 156 | `config.sub' isn't included in this package, then this package doesn't 157 | need to know the machine type. 158 | 159 | If you are _building_ compiler tools for cross-compiling, you should 160 | use the option `--target=TYPE' to select the type of system they will 161 | produce code for. 162 | 163 | If you want to _use_ a cross compiler, that generates code for a 164 | platform different from the build platform, you should specify the 165 | "host" platform (i.e., that on which the generated programs will 166 | eventually be run) with `--host=TYPE'. 167 | 168 | Sharing Defaults 169 | ================ 170 | 171 | If you want to set default values for `configure' scripts to share, you 172 | can create a site shell script called `config.site' that gives default 173 | values for variables like `CC', `cache_file', and `prefix'. 174 | `configure' looks for `PREFIX/share/config.site' if it exists, then 175 | `PREFIX/etc/config.site' if it exists. Or, you can set the 176 | `CONFIG_SITE' environment variable to the location of the site script. 177 | A warning: not all `configure' scripts look for a site script. 178 | 179 | Defining Variables 180 | ================== 181 | 182 | Variables not defined in a site shell script can be set in the 183 | environment passed to `configure'. However, some packages may run 184 | configure again during the build, and the customized values of these 185 | variables may be lost. In order to avoid this problem, you should set 186 | them in the `configure' command line, using `VAR=value'. For example: 187 | 188 | ./configure CC=/usr/local2/bin/gcc 189 | 190 | causes the specified `gcc' to be used as the C compiler (unless it is 191 | overridden in the site shell script). 192 | 193 | Unfortunately, this technique does not work for `CONFIG_SHELL' due to 194 | an Autoconf bug. Until the bug is fixed you can use this workaround: 195 | 196 | CONFIG_SHELL=/bin/bash /bin/bash ./configure CONFIG_SHELL=/bin/bash 197 | 198 | `configure' Invocation 199 | ====================== 200 | 201 | `configure' recognizes the following options to control how it operates. 202 | 203 | `--help' 204 | `-h' 205 | Print a summary of the options to `configure', and exit. 206 | 207 | `--version' 208 | `-V' 209 | Print the version of Autoconf used to generate the `configure' 210 | script, and exit. 211 | 212 | `--cache-file=FILE' 213 | Enable the cache: use and save the results of the tests in FILE, 214 | traditionally `config.cache'. FILE defaults to `/dev/null' to 215 | disable caching. 216 | 217 | `--config-cache' 218 | `-C' 219 | Alias for `--cache-file=config.cache'. 220 | 221 | `--quiet' 222 | `--silent' 223 | `-q' 224 | Do not print messages saying which checks are being made. To 225 | suppress all normal output, redirect it to `/dev/null' (any error 226 | messages will still be shown). 227 | 228 | `--srcdir=DIR' 229 | Look for the package's source code in directory DIR. Usually 230 | `configure' can determine that directory automatically. 231 | 232 | `configure' also accepts some other, not widely useful, options. Run 233 | `configure --help' for more details. 234 | 235 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | DISTCLEANFILES = *~ *.~* 2 | 3 | SUBDIRS = src 4 | 5 | bin_SCRIPTS = contrib/melt.sh contrib/freeze.sh contrib/poorZFS.py 6 | 7 | doc_DATA = README.md COPYING INSTALL AUTHORS NEWS ChangeLog docs/README.RS32 8 | 9 | EXTRA_DIST = README.md COPYING INSTALL AUTHORS NEWS ChangeLog contrib/freeze.sh contrib/melt.sh contrib/poorZFS.py docs/README.RS32 10 | -------------------------------------------------------------------------------- /NEWS: -------------------------------------------------------------------------------- 1 | 2009-03-09: 2 | Added automatic detection for x86 ASM support, as well as a 3 | Python-FUSE for dead-easy deployment. 4 | 5 | 2008-07-30: 6 | Cleaned up my rsbep-related work a bit, so that others can use 7 | the things I built to provide error-resiliency to their files... 8 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | WHAT IS THIS? 2 | ============= 3 | 4 | This is a slightly modified version of rsbep0.0.5 which I have 5 | been using to create error-resilient backups of data (able to 6 | survive hard disks' bad sectors, scratched CD/DVD backups, etc) 7 | 8 | I've written a full blog post about it [here](https://www.thanassis.space/rsbep.html). 9 | 10 | INSTALL 11 | ======= 12 | 13 | ./configure 14 | make 15 | make install 16 | 17 | ...will copy binaries and scripts into your /usr/local/bin/ 18 | directory. For reference, some additional docs (including this 19 | README) will be copied inside a documentation directory: 20 | /usr/local/share/doc/rsbep/. If you wish to change the prefix 21 | from /usr/local/ to "/path/to/whatever", use... 22 | 23 | ./configure --prefix=/path/to/whatever 24 | make 25 | make install 26 | 27 | ...and remember to add /path/to/whatever/bin to your PATH. 28 | Read INSTALL for more details, if you wish. 29 | 30 | DATA RECOVERY 31 | ============= 32 | 33 | Here's an example of data recovery via the "freeze.sh" and 34 | "melt.sh" scripts: 35 | 36 | home:/var/tmp/recovery$ ls -la 37 | total 4108 38 | drwxr-xr-x 2 ttsiod ttsiod 4096 2008-07-30 22:21 . 39 | drwxrwxrwt 5 root root 4096 2008-07-30 22:21 .. 40 | -rw-r--r-- 1 ttsiod ttsiod 4194304 2008-07-30 22:21 data 41 | 42 | home:/var/tmp/recovery$ freeze.sh data > data.shielded 43 | home:/var/tmp/recovery$ ls -la 44 | total 9204 45 | drwxr-xr-x 2 ttsiod ttsiod 4096 2008-07-30 22:21 . 46 | drwxrwxrwt 5 root root 4096 2008-07-30 22:21 .. 47 | -rw-r--r-- 1 ttsiod ttsiod 4194304 2008-07-30 22:21 data 48 | -rw-r--r-- 1 ttsiod ttsiod 5202000 2008-07-30 22:21 data.shielded 49 | 50 | home:/var/tmp/recovery$ melt.sh data.shielded > data2 51 | home:/var/tmp/recovery$ md5sum data data2 52 | 9440c7d2ff545de1ff340e7a81a53efb data 53 | 9440c7d2ff545de1ff340e7a81a53efb data2 54 | 55 | home:/var/tmp/recovery$ # We just survived a 'round trip'. 56 | home:/var/tmp/recovery$ # Now let's create artificial corruption 57 | home:/var/tmp/recovery$ # of 127 times 512 which is 65024 bytes 58 | 59 | home:/var/tmp/recovery$ dd if=/dev/zero of=data.shielded bs=512 count=127 conv=notrunc 60 | 127+0 records in 61 | 127+0 records out 62 | 65024 bytes (65 kB) copied, 0,00026734 seconds, 243 MB/s 63 | 64 | home:/var/tmp/recovery$ melt.sh data.shielded > data3 65 | 66 | rsbep: number of corrected failures : 64764 67 | rsbep: number of uncorrectable blocks : 0 68 | 69 | home:/var/tmp/recovery$ md5sum data data2 data3 70 | 9440c7d2ff545de1ff340e7a81a53efb data 71 | 9440c7d2ff545de1ff340e7a81a53efb data2 72 | 9440c7d2ff545de1ff340e7a81a53efb data3 73 | 74 | home:/var/tmp/recovery$ # Look, ma! We recovered... 75 | 76 | FUSE-based filesystem using this 77 | ================================ 78 | 79 | These tools allowed an easy implementation of a Reed-Solomon 80 | protected filesystem, using Python FUSE bindings: 81 | 82 | bash$ poorZFS.py -f /reed-solomoned-data /strong 83 | 84 | This command will mount a FUSE-based filesystem in "/strong" (using 85 | the "/reed-solomoned-data" directory to store the actual files and 86 | their "shielded" versions). Any file you create in /strong, will 87 | in fact exist under "/reed-solomoned-data", and will also be shielded 88 | there (via "freeze.sh"). When opening for reading any file in /strong, 89 | data corruption is detected (via "melt.sh") and in case of corruption 90 | the file will be corrected using the Reed-Solomon "shielded" version 91 | of the file (which is stored alongside the original, and named as 92 | originalFilename.frozen.RS). 93 | 94 | I coded this using Python-FUSE in a couple of hours on a boring Sunday 95 | afternoon, so don't trust your bank account data with it... It's just 96 | a proof of concept (not to mention dog-slow). Still, if your machine 97 | is only equipped with one drive, this will in fact transparently shield 98 | you against any sudden appearance of your drive's bad sectors. 99 | 100 | And just note that I coded this filesystem adding 20 or so lines of 101 | Python (spawning my freeze/melt scripts) into the Python FUSE basic 102 | example. Anyone who has ever coded a filesystem driver for Windows knows 103 | why this justifies a heart attack - FUSE (and Python FUSE) rock! 104 | 105 | CHANGES from original rsbep 106 | =========================== 107 | 108 | - The original version wrote 3 parameters of the Reed-Solomon algorithm 109 | as a single line before the "shielded" data, and this made the stream 110 | fragile (if this information was lost, decoding failed...) 111 | 112 | - It uses a default value of 16x255=4080 for parameter R, 113 | and it can thus tolerate 4080x16=65280 consecutive bytes 114 | to be lost anywhere in the stream, and still recover... 115 | 116 | - It adds file size information in the shielded stream, so the recovery 117 | process re-creates an exact copy of the original. 118 | 119 | - I added autoconf/automake support, to detect whether a fast 32bit x86 120 | asm version can be used and otherwise fall back to a plain C (slow) 121 | implementation. The tools thus compile and install cleanly on many 122 | operating systems (Linux, Mac OS/X, Free/Net/OpenBSD, even Windows 123 | with Cygwin). 124 | 125 | - Python-FUSE support. 126 | 127 | UPDATE, many years later: Streaming support, a hands-on corruption, and dd options 128 | ================================================================================== 129 | While answering some questions I received about usage of rsbep for streaming processes, 130 | I realized I could demonstrate `dd`'s recovery from actual corruption at raw device level, 131 | via the functionality offered by dmsetup’s `error`. This is a mandatory part that `rsbep` 132 | depends on, i.e. that when errors happen during reading, we still get *some* data, 133 | *any* data for them. We - i.e. the algorithm - can then recover the lost data. 134 | 135 | Let's first establish what are the correct options to use to recover via `dd` 136 | while reading from bad devices. The example below will create a device formed 137 | from two loop devices, with an erroneous zone between them. 138 | 139 | First, we create the two loop devices, serializing their data into two 1MB files: 140 | 141 | # mkdir example 142 | # cd example 143 | # truncate -s 1M a.img b.img 144 | # losetup -f a.img 145 | # losetup -f b.img 146 | # losetup -a 147 | 148 | /dev/loop1: [65024]:7984102 (/home/ttsiod/tmp/Milan/b.img) 149 | /dev/loop0: [65024]:7984101 (/home/ttsiod/tmp/Milan/a.img) 150 | 151 | Now let's fill up the devices with data: 152 | 153 | # i=0; while printf 'A%06d' $i ; do i=$((i+1)) ; done > /dev/loop0 154 | -bash: printf: write error: No space left on device 155 | 156 | # i=0; while printf 'B%06d' $i ; do i=$((i+1)) ; done > /dev/loop1 157 | -bash: printf: write error: No space left on device 158 | 159 | This wrote a series of counters in them, one after the other: 160 | 161 | # hexdump -C /dev/loop0 | head -3 162 | 00000000 41 30 30 30 30 30 30 41 30 30 30 30 30 31 41 30 |A000000A000001A0| 163 | 00000010 30 30 30 30 32 41 30 30 30 30 30 33 41 30 30 30 |00002A000003A000| 164 | 00000020 30 30 34 41 30 30 30 30 30 35 41 30 30 30 30 30 |004A000005A00000| 165 | 166 | Now let's create the joined-and-errored device: 167 | 168 | # dmsetup create DeviceWithBadSectors << EOF 169 | 0 2000 linear /dev/loop0 0 170 | 2000 96 error 171 | 2096 2000 linear /dev/loop1 48 172 | EOF 173 | 174 | # blockdev --getsz /dev/mapper/DeviceWithBadSectors 175 | 4096 176 | 177 | This new device (`/dev/mapper/DeviceWithBadSectors`) is made of the first 178 | 2000 sectors of `/dev/loop0`, followed by 96 bad sectors; and then by the 179 | last 2000 sectors from `/dev/loop1`. This, as we saw above, makes up 180 | for a device with a total of 4096 sectors, 96 of which - in the middle - are 181 | bad. 182 | 183 | Now let's try reading the data of this device - first, with `ddrescue`, a tool 184 | specifically made to read from bad devices: 185 | 186 | # ddrescue /dev/mapper/DeviceWithBadSectors recovered 187 | GNU ddrescue 1.25 188 | Press Ctrl-C to interrupt 189 | ipos: 1072 kB, non-trimmed: 0 B, current rate: 2048 kB/s 190 | opos: 1072 kB, non-scraped: 0 B, average rate: 2048 kB/s 191 | non-tried: 0 B, bad-sector: 49152 B, error rate: 139 kB/s 192 | rescued: 2048 kB, bad areas: 1, run time: 0s 193 | pct rescued: 97.65%, read errors: 98, remaining time: 0s 194 | time since last successful read: n/a 195 | Finished 196 | 197 | # ls -l recovered 198 | -rw-r--r-- 1 root root 2097152 Oct 10 13:41 recovered 199 | 200 | # blockdev --getsz recovered 201 | 4096 202 | 203 | Indeed, we got data for all 4096 sectors - including the 96 bad ones, for which 204 | `ddrescue` will have placed zeroes in the output. This is exactly what `rsbep` 205 | needs to happen for the Reed-Solomon algorithm to function properly; i.e. we 206 | need the data from the bad sectors to be there - bad, but in their place. 207 | We can't afford to miss them! 208 | 209 | OK - but `ddrescue` writes into a file. What about streaming operations? 210 | And also, most people won't have it installed - can't we use `dd` for the 211 | same purpose? 212 | 213 | Let's establish what is the output data we want - what is the MD5 checksum 214 | of the recovered data? 215 | 216 | # md5sum recovered 217 | d2ae90b3a830d34c7e92717e8549b909 recovered 218 | 219 | Now let's see what happens with `dd` - used with the proper options: 220 | 221 | # dd if=/dev/mapper/DeviceWithBadSectors conv=noerror,sync bs=512 > /dev/null 222 | ... 223 | dd: error reading '/dev/mapper/DeviceWithBadSectors': Input/output error 224 | 2000+95 records in 225 | 2095+0 records out 226 | 1072640 bytes (1.1 MB, 1.0 MiB) copied, 0.00982337 s, 109 MB/s 227 | 4000+96 records in 228 | 4096+0 records out 229 | 2097152 bytes (2.1 MB, 2.0 MiB) copied, 0.024313 s, 86.3 MB/s 230 | 231 | # dd if=/dev/mapper/DeviceWithBadSectors conv=noerror,sync bs=512 2>/dev/null | wc -c 232 | 2097152 233 | 234 | # dd if=/dev/mapper/DeviceWithBadSectors conv=noerror,sync bs=512 2>/dev/null | md5sum 235 | d2ae90b3a830d34c7e92717e8549b909 236 | 237 | So we see that `dd` read the same data as `ddrescue` - the MD5 checksum is good, 238 | and we have indeed read 2097152 bytes - i.e. 4096 sectors of 512 bytes each. 239 | This means `rsbep` will be able to perfectly recover, even though we are 240 | streaming the data out. 241 | 242 | The "magic" options for `dd`, are, as shown above: 243 | 244 | - `noerror`: don't stop on hard drive read error, and 245 | - `sync`: pad every input block with NULs to input block size 246 | 247 | So, we now have all the ingredients to use `rsbep` in a streaming scenario... 248 | e.g. sending data over SSH to another machine, or whatever. 249 | 250 | Here's a standalone example via tar - first, creating a backup: 251 | 252 | # cd /path/to/backup 253 | # tar cpf - ./ | xz | \ 254 | rsbep -B 255 -D 223 -R 4080 > /var/tmp/shielded.data.xz.rsbep 255 | 256 | And here's recovering: 257 | 258 | # cd /path/to/restore 259 | # dd if=/var/tmp/shielded.data.xz.rsbep conv=noerror,sync bs=512 | \ 260 | rsbep -d -B 255 -D 223 -R 4080 | tar Jtvf - 261 | 262 | FEEDBACK 263 | ======== 264 | Feel free to fork this. It works as is for me, if you don't like it, 265 | fix it to suit your needs! 266 | 267 | It proved useful to me over the years; hope it is useful to you too... 268 | 269 | Thanassis Tsiodras. 270 | -------------------------------------------------------------------------------- /ac-macros/ac_python_module.m4: -------------------------------------------------------------------------------- 1 | ##### http://autoconf-archive.cryp.to/ac_python_module.html 2 | # 3 | # SYNOPSIS 4 | # 5 | # AC_PYTHON_MODULE(modname[, fatal]) 6 | # 7 | # DESCRIPTION 8 | # 9 | # Checks for Python module. 10 | # 11 | # If fatal is non-empty then absence of a module will trigger an 12 | # error. 13 | # 14 | # LAST MODIFICATION 15 | # 16 | # 2007-01-09 17 | # 18 | # COPYLEFT 19 | # 20 | # Copyright (c) 2007 Andrew Collier 21 | # 22 | # Copying and distribution of this file, with or without 23 | # modification, are permitted in any medium without royalty provided 24 | # the copyright notice and this notice are preserved. 25 | 26 | AC_DEFUN([AC_PYTHON_MODULE],[ 27 | if test -z $PYTHON; 28 | then 29 | PYTHON="python" 30 | fi 31 | PYTHON_NAME=`basename $PYTHON` 32 | AC_MSG_CHECKING($PYTHON_NAME module: $1) 33 | $PYTHON -c "import $1" 2>/dev/null 34 | if test $? -eq 0; 35 | then 36 | AC_MSG_RESULT(yes) 37 | eval AS_TR_CPP(HAVE_PYMOD_$1)=yes 38 | else 39 | AC_MSG_RESULT(no) 40 | eval AS_TR_CPP(HAVE_PYMOD_$1)=no 41 | # 42 | if test -n "$2" 43 | then 44 | AC_MSG_ERROR(failed to find required module $1) 45 | exit 1 46 | fi 47 | fi 48 | ]) 49 | -------------------------------------------------------------------------------- /ac-macros/ax_cflags_gcc_option.m4: -------------------------------------------------------------------------------- 1 | ##### http://autoconf-archive.cryp.to/ax_cflags_gcc_option.html 2 | # 3 | # SYNOPSIS 4 | # 5 | # AX_CFLAGS_GCC_OPTION (optionflag [,[shellvar][,[A][,[NA]]]) 6 | # 7 | # DESCRIPTION 8 | # 9 | # AX_CFLAGS_GCC_OPTION(-fvomit-frame) would show a message as like 10 | # "checking CFLAGS for gcc -fvomit-frame ... yes" and adds the 11 | # optionflag to CFLAGS if it is understood. You can override the 12 | # shellvar-default of CFLAGS of course. The order of arguments stems 13 | # from the explicit macros like AX_CFLAGS_WARN_ALL. 14 | # 15 | # The cousin AX_CXXFLAGS_GCC_OPTION would check for an option to add 16 | # to CXXFLAGS - and it uses the autoconf setup for C++ instead of C 17 | # (since it is possible to use different compilers for C and C++). 18 | # 19 | # The macro is a lot simpler than any special AX_CFLAGS_* macro (or 20 | # ac_cxx_rtti.m4 macro) but allows to check for arbitrary options. 21 | # However, if you use this macro in a few places, it would be great 22 | # if you would make up a new function-macro and submit it to the 23 | # ac-archive. 24 | # 25 | # - $1 option-to-check-for : required ("-option" as non-value) 26 | # - $2 shell-variable-to-add-to : CFLAGS (or CXXFLAGS in the other case) 27 | # - $3 action-if-found : add value to shellvariable 28 | # - $4 action-if-not-found : nothing 29 | # 30 | # note: in earlier versions, $1-$2 were swapped. We try to detect the 31 | # situation and accept a $2=~/-/ as being the old 32 | # option-to-check-for. 33 | # 34 | # also: there are other variants that emerged from the original macro 35 | # variant which did just test an option to be possibly added. 36 | # However, some compilers accept an option silently, or possibly for 37 | # just another option that was not intended. Therefore, we have to do 38 | # a generic test for a compiler family. For gcc we check "-pedantic" 39 | # being accepted which is also understood by compilers who just want 40 | # to be compatible with gcc even when not being made from gcc 41 | # sources. 42 | # 43 | # see also: 44 | # 45 | # AX_CFLAGS_SUN_OPTION AX_CFLAGS_HPUX_OPTION 46 | # AX_CFLAGS_AIX_OPTION AX_CFLAGS_IRIX_OPTION 47 | # 48 | # LAST MODIFICATION 49 | # 50 | # 2006-12-12 51 | # 52 | # COPYLEFT 53 | # 54 | # Copyright (c) 2006 Guido U. Draheim 55 | # 56 | # This program is free software; you can redistribute it and/or 57 | # modify it under the terms of the GNU General Public License as 58 | # published by the Free Software Foundation; either version 2 of the 59 | # License, or (at your option) any later version. 60 | # 61 | # This program is distributed in the hope that it will be useful, but 62 | # WITHOUT ANY WARRANTY; without even the implied warranty of 63 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 64 | # General Public License for more details. 65 | # 66 | # You should have received a copy of the GNU General Public License 67 | # along with this program; if not, write to the Free Software 68 | # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 69 | # 02111-1307, USA. 70 | # 71 | # As a special exception, the respective Autoconf Macro's copyright 72 | # owner gives unlimited permission to copy, distribute and modify the 73 | # configure scripts that are the output of Autoconf when processing 74 | # the Macro. You need not follow the terms of the GNU General Public 75 | # License when using or distributing such scripts, even though 76 | # portions of the text of the Macro appear in them. The GNU General 77 | # Public License (GPL) does govern all other use of the material that 78 | # constitutes the Autoconf Macro. 79 | # 80 | # This special exception to the GPL applies to versions of the 81 | # Autoconf Macro released by the Autoconf Macro Archive. When you 82 | # make and distribute a modified version of the Autoconf Macro, you 83 | # may extend this special exception to the GPL to apply to your 84 | # modified version as well. 85 | 86 | AC_DEFUN([AX_CFLAGS_GCC_OPTION_OLD], [dnl 87 | AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl 88 | AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$2])dnl 89 | AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], 90 | VAR,[VAR="no, unknown" 91 | AC_LANG_SAVE 92 | AC_LANG_C 93 | ac_save_[]FLAGS="$[]FLAGS" 94 | for ac_arg dnl 95 | in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC 96 | "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC 97 | # 98 | do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` 99 | AC_TRY_COMPILE([],[return 0;], 100 | [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) 101 | done 102 | FLAGS="$ac_save_[]FLAGS" 103 | AC_LANG_RESTORE 104 | ]) 105 | case ".$VAR" in 106 | .ok|.ok,*) m4_ifvaln($3,$3) ;; 107 | .|.no|.no,*) m4_ifvaln($4,$4) ;; 108 | *) m4_ifvaln($3,$3,[ 109 | if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null 110 | then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) 111 | else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) 112 | m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" 113 | fi ]) ;; 114 | esac 115 | AS_VAR_POPDEF([VAR])dnl 116 | AS_VAR_POPDEF([FLAGS])dnl 117 | ]) 118 | 119 | 120 | dnl the only difference - the LANG selection... and the default FLAGS 121 | 122 | AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_OLD], [dnl 123 | AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl 124 | AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$2])dnl 125 | AC_CACHE_CHECK([m4_ifval($1,$1,FLAGS) for gcc m4_ifval($2,$2,-option)], 126 | VAR,[VAR="no, unknown" 127 | AC_LANG_SAVE 128 | AC_LANG_CPLUSPLUS 129 | ac_save_[]FLAGS="$[]FLAGS" 130 | for ac_arg dnl 131 | in "-pedantic -Werror % m4_ifval($2,$2,-option)" dnl GCC 132 | "-pedantic % m4_ifval($2,$2,-option) %% no, obsolete" dnl new GCC 133 | # 134 | do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` 135 | AC_TRY_COMPILE([],[return 0;], 136 | [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) 137 | done 138 | FLAGS="$ac_save_[]FLAGS" 139 | AC_LANG_RESTORE 140 | ]) 141 | case ".$VAR" in 142 | .ok|.ok,*) m4_ifvaln($3,$3) ;; 143 | .|.no|.no,*) m4_ifvaln($4,$4) ;; 144 | *) m4_ifvaln($3,$3,[ 145 | if echo " $[]m4_ifval($1,$1,FLAGS) " | grep " $VAR " 2>&1 >/dev/null 146 | then AC_RUN_LOG([: m4_ifval($1,$1,FLAGS) does contain $VAR]) 147 | else AC_RUN_LOG([: m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR"]) 148 | m4_ifval($1,$1,FLAGS)="$m4_ifval($1,$1,FLAGS) $VAR" 149 | fi ]) ;; 150 | esac 151 | AS_VAR_POPDEF([VAR])dnl 152 | AS_VAR_POPDEF([FLAGS])dnl 153 | ]) 154 | 155 | dnl ------------------------------------------------------------------------- 156 | 157 | AC_DEFUN([AX_CFLAGS_GCC_OPTION_NEW], [dnl 158 | AS_VAR_PUSHDEF([FLAGS],[CFLAGS])dnl 159 | AS_VAR_PUSHDEF([VAR],[ac_cv_cflags_gcc_option_$1])dnl 160 | AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], 161 | VAR,[VAR="no, unknown" 162 | AC_LANG_SAVE 163 | AC_LANG_C 164 | ac_save_[]FLAGS="$[]FLAGS" 165 | for ac_arg dnl 166 | in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC 167 | "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC 168 | # 169 | do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` 170 | AC_TRY_COMPILE([],[return 0;], 171 | [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) 172 | done 173 | FLAGS="$ac_save_[]FLAGS" 174 | AC_LANG_RESTORE 175 | ]) 176 | case ".$VAR" in 177 | .ok|.ok,*) m4_ifvaln($3,$3) ;; 178 | .|.no|.no,*) m4_ifvaln($4,$4) ;; 179 | *) m4_ifvaln($3,$3,[ 180 | if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null 181 | then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) 182 | else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) 183 | m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" 184 | fi ]) ;; 185 | esac 186 | AS_VAR_POPDEF([VAR])dnl 187 | AS_VAR_POPDEF([FLAGS])dnl 188 | ]) 189 | 190 | 191 | dnl the only difference - the LANG selection... and the default FLAGS 192 | 193 | AC_DEFUN([AX_CXXFLAGS_GCC_OPTION_NEW], [dnl 194 | AS_VAR_PUSHDEF([FLAGS],[CXXFLAGS])dnl 195 | AS_VAR_PUSHDEF([VAR],[ac_cv_cxxflags_gcc_option_$1])dnl 196 | AC_CACHE_CHECK([m4_ifval($2,$2,FLAGS) for gcc m4_ifval($1,$1,-option)], 197 | VAR,[VAR="no, unknown" 198 | AC_LANG_SAVE 199 | AC_LANG_CPLUSPLUS 200 | ac_save_[]FLAGS="$[]FLAGS" 201 | for ac_arg dnl 202 | in "-pedantic -Werror % m4_ifval($1,$1,-option)" dnl GCC 203 | "-pedantic % m4_ifval($1,$1,-option) %% no, obsolete" dnl new GCC 204 | # 205 | do FLAGS="$ac_save_[]FLAGS "`echo $ac_arg | sed -e 's,%%.*,,' -e 's,%,,'` 206 | AC_TRY_COMPILE([],[return 0;], 207 | [VAR=`echo $ac_arg | sed -e 's,.*% *,,'` ; break]) 208 | done 209 | FLAGS="$ac_save_[]FLAGS" 210 | AC_LANG_RESTORE 211 | ]) 212 | case ".$VAR" in 213 | .ok|.ok,*) m4_ifvaln($3,$3) ;; 214 | .|.no|.no,*) m4_ifvaln($4,$4) ;; 215 | *) m4_ifvaln($3,$3,[ 216 | if echo " $[]m4_ifval($2,$2,FLAGS) " | grep " $VAR " 2>&1 >/dev/null 217 | then AC_RUN_LOG([: m4_ifval($2,$2,FLAGS) does contain $VAR]) 218 | else AC_RUN_LOG([: m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR"]) 219 | m4_ifval($2,$2,FLAGS)="$m4_ifval($2,$2,FLAGS) $VAR" 220 | fi ]) ;; 221 | esac 222 | AS_VAR_POPDEF([VAR])dnl 223 | AS_VAR_POPDEF([FLAGS])dnl 224 | ]) 225 | 226 | AC_DEFUN([AX_CFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, 227 | [AX_CFLAGS_GCC_OPTION_NEW($@)],[AX_CFLAGS_GCC_OPTION_OLD($@)])]) 228 | 229 | AC_DEFUN([AX_CXXFLAGS_GCC_OPTION],[ifelse(m4_bregexp([$2],[-]),-1, 230 | [AX_CXXFLAGS_GCC_OPTION_NEW($@)],[AX_CXXFLAGS_GCC_OPTION_OLD($@)])]) 231 | -------------------------------------------------------------------------------- /acinclude.m4: -------------------------------------------------------------------------------- 1 | m4_include([ac-macros/ac_python_module.m4]) 2 | m4_include([ac-macros/ax_cflags_gcc_option.m4]) 3 | -------------------------------------------------------------------------------- /build-aux/compile: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Wrapper for compilers which do not understand `-c -o'. 3 | 4 | scriptversion=2005-05-14.22 5 | 6 | # Copyright (C) 1999, 2000, 2003, 2004, 2005 Free Software Foundation, Inc. 7 | # Written by Tom Tromey . 8 | # 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | # 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | # 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 22 | 23 | # As a special exception to the GNU General Public License, if you 24 | # distribute this file as part of a program that contains a 25 | # configuration script generated by Autoconf, you may include it under 26 | # the same distribution terms that you use for the rest of that program. 27 | 28 | # This file is maintained in Automake, please report 29 | # bugs to or send patches to 30 | # . 31 | 32 | case $1 in 33 | '') 34 | echo "$0: No command. Try \`$0 --help' for more information." 1>&2 35 | exit 1; 36 | ;; 37 | -h | --h*) 38 | cat <<\EOF 39 | Usage: compile [--help] [--version] PROGRAM [ARGS] 40 | 41 | Wrapper for compilers which do not understand `-c -o'. 42 | Remove `-o dest.o' from ARGS, run PROGRAM with the remaining 43 | arguments, and rename the output as expected. 44 | 45 | If you are trying to build a whole package this is not the 46 | right script to run: please start by reading the file `INSTALL'. 47 | 48 | Report bugs to . 49 | EOF 50 | exit $? 51 | ;; 52 | -v | --v*) 53 | echo "compile $scriptversion" 54 | exit $? 55 | ;; 56 | esac 57 | 58 | ofile= 59 | cfile= 60 | eat= 61 | 62 | for arg 63 | do 64 | if test -n "$eat"; then 65 | eat= 66 | else 67 | case $1 in 68 | -o) 69 | # configure might choose to run compile as `compile cc -o foo foo.c'. 70 | # So we strip `-o arg' only if arg is an object. 71 | eat=1 72 | case $2 in 73 | *.o | *.obj) 74 | ofile=$2 75 | ;; 76 | *) 77 | set x "$@" -o "$2" 78 | shift 79 | ;; 80 | esac 81 | ;; 82 | *.c) 83 | cfile=$1 84 | set x "$@" "$1" 85 | shift 86 | ;; 87 | *) 88 | set x "$@" "$1" 89 | shift 90 | ;; 91 | esac 92 | fi 93 | shift 94 | done 95 | 96 | if test -z "$ofile" || test -z "$cfile"; then 97 | # If no `-o' option was seen then we might have been invoked from a 98 | # pattern rule where we don't need one. That is ok -- this is a 99 | # normal compilation that the losing compiler can handle. If no 100 | # `.c' file was seen then we are probably linking. That is also 101 | # ok. 102 | exec "$@" 103 | fi 104 | 105 | # Name of file we expect compiler to create. 106 | cofile=`echo "$cfile" | sed -e 's|^.*/||' -e 's/\.c$/.o/'` 107 | 108 | # Create the lock directory. 109 | # Note: use `[/.-]' here to ensure that we don't use the same name 110 | # that we are using for the .o file. Also, base the name on the expected 111 | # object file name, since that is what matters with a parallel build. 112 | lockdir=`echo "$cofile" | sed -e 's|[/.-]|_|g'`.d 113 | while true; do 114 | if mkdir "$lockdir" >/dev/null 2>&1; then 115 | break 116 | fi 117 | sleep 1 118 | done 119 | # FIXME: race condition here if user kills between mkdir and trap. 120 | trap "rmdir '$lockdir'; exit 1" 1 2 15 121 | 122 | # Run the compile. 123 | "$@" 124 | ret=$? 125 | 126 | if test -f "$cofile"; then 127 | mv "$cofile" "$ofile" 128 | elif test -f "${cofile}bj"; then 129 | mv "${cofile}bj" "$ofile" 130 | fi 131 | 132 | rmdir "$lockdir" 133 | exit $ret 134 | 135 | # Local Variables: 136 | # mode: shell-script 137 | # sh-indentation: 2 138 | # eval: (add-hook 'write-file-hooks 'time-stamp) 139 | # time-stamp-start: "scriptversion=" 140 | # time-stamp-format: "%:y-%02m-%02d.%02H" 141 | # time-stamp-end: "$" 142 | # End: 143 | -------------------------------------------------------------------------------- /build-aux/depcomp: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # depcomp - compile a program generating dependencies as side-effects 3 | 4 | scriptversion=2006-10-15.18 5 | 6 | # Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006 Free Software 7 | # Foundation, Inc. 8 | 9 | # This program is free software; you can redistribute it and/or modify 10 | # it under the terms of the GNU General Public License as published by 11 | # the Free Software Foundation; either version 2, or (at your option) 12 | # any later version. 13 | 14 | # This program is distributed in the hope that it will be useful, 15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 | # GNU General Public License for more details. 18 | 19 | # You should have received a copy of the GNU General Public License 20 | # along with this program; if not, write to the Free Software 21 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 22 | # 02110-1301, USA. 23 | 24 | # As a special exception to the GNU General Public License, if you 25 | # distribute this file as part of a program that contains a 26 | # configuration script generated by Autoconf, you may include it under 27 | # the same distribution terms that you use for the rest of that program. 28 | 29 | # Originally written by Alexandre Oliva . 30 | 31 | case $1 in 32 | '') 33 | echo "$0: No command. Try \`$0 --help' for more information." 1>&2 34 | exit 1; 35 | ;; 36 | -h | --h*) 37 | cat <<\EOF 38 | Usage: depcomp [--help] [--version] PROGRAM [ARGS] 39 | 40 | Run PROGRAMS ARGS to compile a file, generating dependencies 41 | as side-effects. 42 | 43 | Environment variables: 44 | depmode Dependency tracking mode. 45 | source Source file read by `PROGRAMS ARGS'. 46 | object Object file output by `PROGRAMS ARGS'. 47 | DEPDIR directory where to store dependencies. 48 | depfile Dependency file to output. 49 | tmpdepfile Temporary file to use when outputing dependencies. 50 | libtool Whether libtool is used (yes/no). 51 | 52 | Report bugs to . 53 | EOF 54 | exit $? 55 | ;; 56 | -v | --v*) 57 | echo "depcomp $scriptversion" 58 | exit $? 59 | ;; 60 | esac 61 | 62 | if test -z "$depmode" || test -z "$source" || test -z "$object"; then 63 | echo "depcomp: Variables source, object and depmode must be set" 1>&2 64 | exit 1 65 | fi 66 | 67 | # Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po. 68 | depfile=${depfile-`echo "$object" | 69 | sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`} 70 | tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`} 71 | 72 | rm -f "$tmpdepfile" 73 | 74 | # Some modes work just like other modes, but use different flags. We 75 | # parameterize here, but still list the modes in the big case below, 76 | # to make depend.m4 easier to write. Note that we *cannot* use a case 77 | # here, because this file can only contain one case statement. 78 | if test "$depmode" = hp; then 79 | # HP compiler uses -M and no extra arg. 80 | gccflag=-M 81 | depmode=gcc 82 | fi 83 | 84 | if test "$depmode" = dashXmstdout; then 85 | # This is just like dashmstdout with a different argument. 86 | dashmflag=-xM 87 | depmode=dashmstdout 88 | fi 89 | 90 | case "$depmode" in 91 | gcc3) 92 | ## gcc 3 implements dependency tracking that does exactly what 93 | ## we want. Yay! Note: for some reason libtool 1.4 doesn't like 94 | ## it if -MD -MP comes after the -MF stuff. Hmm. 95 | ## Unfortunately, FreeBSD c89 acceptance of flags depends upon 96 | ## the command line argument order; so add the flags where they 97 | ## appear in depend2.am. Note that the slowdown incurred here 98 | ## affects only configure: in makefiles, %FASTDEP% shortcuts this. 99 | for arg 100 | do 101 | case $arg in 102 | -c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;; 103 | *) set fnord "$@" "$arg" ;; 104 | esac 105 | shift # fnord 106 | shift # $arg 107 | done 108 | "$@" 109 | stat=$? 110 | if test $stat -eq 0; then : 111 | else 112 | rm -f "$tmpdepfile" 113 | exit $stat 114 | fi 115 | mv "$tmpdepfile" "$depfile" 116 | ;; 117 | 118 | gcc) 119 | ## There are various ways to get dependency output from gcc. Here's 120 | ## why we pick this rather obscure method: 121 | ## - Don't want to use -MD because we'd like the dependencies to end 122 | ## up in a subdir. Having to rename by hand is ugly. 123 | ## (We might end up doing this anyway to support other compilers.) 124 | ## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like 125 | ## -MM, not -M (despite what the docs say). 126 | ## - Using -M directly means running the compiler twice (even worse 127 | ## than renaming). 128 | if test -z "$gccflag"; then 129 | gccflag=-MD, 130 | fi 131 | "$@" -Wp,"$gccflag$tmpdepfile" 132 | stat=$? 133 | if test $stat -eq 0; then : 134 | else 135 | rm -f "$tmpdepfile" 136 | exit $stat 137 | fi 138 | rm -f "$depfile" 139 | echo "$object : \\" > "$depfile" 140 | alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz 141 | ## The second -e expression handles DOS-style file names with drive letters. 142 | sed -e 's/^[^:]*: / /' \ 143 | -e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile" 144 | ## This next piece of magic avoids the `deleted header file' problem. 145 | ## The problem is that when a header file which appears in a .P file 146 | ## is deleted, the dependency causes make to die (because there is 147 | ## typically no way to rebuild the header). We avoid this by adding 148 | ## dummy dependencies for each header file. Too bad gcc doesn't do 149 | ## this for us directly. 150 | tr ' ' ' 151 | ' < "$tmpdepfile" | 152 | ## Some versions of gcc put a space before the `:'. On the theory 153 | ## that the space means something, we add a space to the output as 154 | ## well. 155 | ## Some versions of the HPUX 10.20 sed can't process this invocation 156 | ## correctly. Breaking it into two sed invocations is a workaround. 157 | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" 158 | rm -f "$tmpdepfile" 159 | ;; 160 | 161 | hp) 162 | # This case exists only to let depend.m4 do its work. It works by 163 | # looking at the text of this script. This case will never be run, 164 | # since it is checked for above. 165 | exit 1 166 | ;; 167 | 168 | sgi) 169 | if test "$libtool" = yes; then 170 | "$@" "-Wp,-MDupdate,$tmpdepfile" 171 | else 172 | "$@" -MDupdate "$tmpdepfile" 173 | fi 174 | stat=$? 175 | if test $stat -eq 0; then : 176 | else 177 | rm -f "$tmpdepfile" 178 | exit $stat 179 | fi 180 | rm -f "$depfile" 181 | 182 | if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files 183 | echo "$object : \\" > "$depfile" 184 | 185 | # Clip off the initial element (the dependent). Don't try to be 186 | # clever and replace this with sed code, as IRIX sed won't handle 187 | # lines with more than a fixed number of characters (4096 in 188 | # IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines; 189 | # the IRIX cc adds comments like `#:fec' to the end of the 190 | # dependency line. 191 | tr ' ' ' 192 | ' < "$tmpdepfile" \ 193 | | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \ 194 | tr ' 195 | ' ' ' >> $depfile 196 | echo >> $depfile 197 | 198 | # The second pass generates a dummy entry for each header file. 199 | tr ' ' ' 200 | ' < "$tmpdepfile" \ 201 | | sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \ 202 | >> $depfile 203 | else 204 | # The sourcefile does not contain any dependencies, so just 205 | # store a dummy comment line, to avoid errors with the Makefile 206 | # "include basename.Plo" scheme. 207 | echo "#dummy" > "$depfile" 208 | fi 209 | rm -f "$tmpdepfile" 210 | ;; 211 | 212 | aix) 213 | # The C for AIX Compiler uses -M and outputs the dependencies 214 | # in a .u file. In older versions, this file always lives in the 215 | # current directory. Also, the AIX compiler puts `$object:' at the 216 | # start of each line; $object doesn't have directory information. 217 | # Version 6 uses the directory in both cases. 218 | stripped=`echo "$object" | sed 's/\(.*\)\..*$/\1/'` 219 | tmpdepfile="$stripped.u" 220 | if test "$libtool" = yes; then 221 | "$@" -Wc,-M 222 | else 223 | "$@" -M 224 | fi 225 | stat=$? 226 | 227 | if test -f "$tmpdepfile"; then : 228 | else 229 | stripped=`echo "$stripped" | sed 's,^.*/,,'` 230 | tmpdepfile="$stripped.u" 231 | fi 232 | 233 | if test $stat -eq 0; then : 234 | else 235 | rm -f "$tmpdepfile" 236 | exit $stat 237 | fi 238 | 239 | if test -f "$tmpdepfile"; then 240 | outname="$stripped.o" 241 | # Each line is of the form `foo.o: dependent.h'. 242 | # Do two passes, one to just change these to 243 | # `$object: dependent.h' and one to simply `dependent.h:'. 244 | sed -e "s,^$outname:,$object :," < "$tmpdepfile" > "$depfile" 245 | sed -e "s,^$outname: \(.*\)$,\1:," < "$tmpdepfile" >> "$depfile" 246 | else 247 | # The sourcefile does not contain any dependencies, so just 248 | # store a dummy comment line, to avoid errors with the Makefile 249 | # "include basename.Plo" scheme. 250 | echo "#dummy" > "$depfile" 251 | fi 252 | rm -f "$tmpdepfile" 253 | ;; 254 | 255 | icc) 256 | # Intel's C compiler understands `-MD -MF file'. However on 257 | # icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c 258 | # ICC 7.0 will fill foo.d with something like 259 | # foo.o: sub/foo.c 260 | # foo.o: sub/foo.h 261 | # which is wrong. We want: 262 | # sub/foo.o: sub/foo.c 263 | # sub/foo.o: sub/foo.h 264 | # sub/foo.c: 265 | # sub/foo.h: 266 | # ICC 7.1 will output 267 | # foo.o: sub/foo.c sub/foo.h 268 | # and will wrap long lines using \ : 269 | # foo.o: sub/foo.c ... \ 270 | # sub/foo.h ... \ 271 | # ... 272 | 273 | "$@" -MD -MF "$tmpdepfile" 274 | stat=$? 275 | if test $stat -eq 0; then : 276 | else 277 | rm -f "$tmpdepfile" 278 | exit $stat 279 | fi 280 | rm -f "$depfile" 281 | # Each line is of the form `foo.o: dependent.h', 282 | # or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'. 283 | # Do two passes, one to just change these to 284 | # `$object: dependent.h' and one to simply `dependent.h:'. 285 | sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile" 286 | # Some versions of the HPUX 10.20 sed can't process this invocation 287 | # correctly. Breaking it into two sed invocations is a workaround. 288 | sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" | 289 | sed -e 's/$/ :/' >> "$depfile" 290 | rm -f "$tmpdepfile" 291 | ;; 292 | 293 | hp2) 294 | # The "hp" stanza above does not work with aCC (C++) and HP's ia64 295 | # compilers, which have integrated preprocessors. The correct option 296 | # to use with these is +Maked; it writes dependencies to a file named 297 | # 'foo.d', which lands next to the object file, wherever that 298 | # happens to be. 299 | # Much of this is similar to the tru64 case; see comments there. 300 | dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` 301 | test "x$dir" = "x$object" && dir= 302 | base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` 303 | if test "$libtool" = yes; then 304 | tmpdepfile1=$dir$base.d 305 | tmpdepfile2=$dir.libs/$base.d 306 | "$@" -Wc,+Maked 307 | else 308 | tmpdepfile1=$dir$base.d 309 | tmpdepfile2=$dir$base.d 310 | "$@" +Maked 311 | fi 312 | stat=$? 313 | if test $stat -eq 0; then : 314 | else 315 | rm -f "$tmpdepfile1" "$tmpdepfile2" 316 | exit $stat 317 | fi 318 | 319 | for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" 320 | do 321 | test -f "$tmpdepfile" && break 322 | done 323 | if test -f "$tmpdepfile"; then 324 | sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile" 325 | # Add `dependent.h:' lines. 326 | sed -ne '2,${; s/^ *//; s/ \\*$//; s/$/:/; p;}' "$tmpdepfile" >> "$depfile" 327 | else 328 | echo "#dummy" > "$depfile" 329 | fi 330 | rm -f "$tmpdepfile" "$tmpdepfile2" 331 | ;; 332 | 333 | tru64) 334 | # The Tru64 compiler uses -MD to generate dependencies as a side 335 | # effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'. 336 | # At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put 337 | # dependencies in `foo.d' instead, so we check for that too. 338 | # Subdirectories are respected. 339 | dir=`echo "$object" | sed -e 's|/[^/]*$|/|'` 340 | test "x$dir" = "x$object" && dir= 341 | base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'` 342 | 343 | if test "$libtool" = yes; then 344 | # With Tru64 cc, shared objects can also be used to make a 345 | # static library. This mechanism is used in libtool 1.4 series to 346 | # handle both shared and static libraries in a single compilation. 347 | # With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d. 348 | # 349 | # With libtool 1.5 this exception was removed, and libtool now 350 | # generates 2 separate objects for the 2 libraries. These two 351 | # compilations output dependencies in $dir.libs/$base.o.d and 352 | # in $dir$base.o.d. We have to check for both files, because 353 | # one of the two compilations can be disabled. We should prefer 354 | # $dir$base.o.d over $dir.libs/$base.o.d because the latter is 355 | # automatically cleaned when .libs/ is deleted, while ignoring 356 | # the former would cause a distcleancheck panic. 357 | tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4 358 | tmpdepfile2=$dir$base.o.d # libtool 1.5 359 | tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5 360 | tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504 361 | "$@" -Wc,-MD 362 | else 363 | tmpdepfile1=$dir$base.o.d 364 | tmpdepfile2=$dir$base.d 365 | tmpdepfile3=$dir$base.d 366 | tmpdepfile4=$dir$base.d 367 | "$@" -MD 368 | fi 369 | 370 | stat=$? 371 | if test $stat -eq 0; then : 372 | else 373 | rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" 374 | exit $stat 375 | fi 376 | 377 | for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4" 378 | do 379 | test -f "$tmpdepfile" && break 380 | done 381 | if test -f "$tmpdepfile"; then 382 | sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile" 383 | # That's a tab and a space in the []. 384 | sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile" 385 | else 386 | echo "#dummy" > "$depfile" 387 | fi 388 | rm -f "$tmpdepfile" 389 | ;; 390 | 391 | #nosideeffect) 392 | # This comment above is used by automake to tell side-effect 393 | # dependency tracking mechanisms from slower ones. 394 | 395 | dashmstdout) 396 | # Important note: in order to support this mode, a compiler *must* 397 | # always write the preprocessed file to stdout, regardless of -o. 398 | "$@" || exit $? 399 | 400 | # Remove the call to Libtool. 401 | if test "$libtool" = yes; then 402 | while test $1 != '--mode=compile'; do 403 | shift 404 | done 405 | shift 406 | fi 407 | 408 | # Remove `-o $object'. 409 | IFS=" " 410 | for arg 411 | do 412 | case $arg in 413 | -o) 414 | shift 415 | ;; 416 | $object) 417 | shift 418 | ;; 419 | *) 420 | set fnord "$@" "$arg" 421 | shift # fnord 422 | shift # $arg 423 | ;; 424 | esac 425 | done 426 | 427 | test -z "$dashmflag" && dashmflag=-M 428 | # Require at least two characters before searching for `:' 429 | # in the target name. This is to cope with DOS-style filenames: 430 | # a dependency such as `c:/foo/bar' could be seen as target `c' otherwise. 431 | "$@" $dashmflag | 432 | sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile" 433 | rm -f "$depfile" 434 | cat < "$tmpdepfile" > "$depfile" 435 | tr ' ' ' 436 | ' < "$tmpdepfile" | \ 437 | ## Some versions of the HPUX 10.20 sed can't process this invocation 438 | ## correctly. Breaking it into two sed invocations is a workaround. 439 | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" 440 | rm -f "$tmpdepfile" 441 | ;; 442 | 443 | dashXmstdout) 444 | # This case only exists to satisfy depend.m4. It is never actually 445 | # run, as this mode is specially recognized in the preamble. 446 | exit 1 447 | ;; 448 | 449 | makedepend) 450 | "$@" || exit $? 451 | # Remove any Libtool call 452 | if test "$libtool" = yes; then 453 | while test $1 != '--mode=compile'; do 454 | shift 455 | done 456 | shift 457 | fi 458 | # X makedepend 459 | shift 460 | cleared=no 461 | for arg in "$@"; do 462 | case $cleared in 463 | no) 464 | set ""; shift 465 | cleared=yes ;; 466 | esac 467 | case "$arg" in 468 | -D*|-I*) 469 | set fnord "$@" "$arg"; shift ;; 470 | # Strip any option that makedepend may not understand. Remove 471 | # the object too, otherwise makedepend will parse it as a source file. 472 | -*|$object) 473 | ;; 474 | *) 475 | set fnord "$@" "$arg"; shift ;; 476 | esac 477 | done 478 | obj_suffix="`echo $object | sed 's/^.*\././'`" 479 | touch "$tmpdepfile" 480 | ${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@" 481 | rm -f "$depfile" 482 | cat < "$tmpdepfile" > "$depfile" 483 | sed '1,2d' "$tmpdepfile" | tr ' ' ' 484 | ' | \ 485 | ## Some versions of the HPUX 10.20 sed can't process this invocation 486 | ## correctly. Breaking it into two sed invocations is a workaround. 487 | sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile" 488 | rm -f "$tmpdepfile" "$tmpdepfile".bak 489 | ;; 490 | 491 | cpp) 492 | # Important note: in order to support this mode, a compiler *must* 493 | # always write the preprocessed file to stdout. 494 | "$@" || exit $? 495 | 496 | # Remove the call to Libtool. 497 | if test "$libtool" = yes; then 498 | while test $1 != '--mode=compile'; do 499 | shift 500 | done 501 | shift 502 | fi 503 | 504 | # Remove `-o $object'. 505 | IFS=" " 506 | for arg 507 | do 508 | case $arg in 509 | -o) 510 | shift 511 | ;; 512 | $object) 513 | shift 514 | ;; 515 | *) 516 | set fnord "$@" "$arg" 517 | shift # fnord 518 | shift # $arg 519 | ;; 520 | esac 521 | done 522 | 523 | "$@" -E | 524 | sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \ 525 | -e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' | 526 | sed '$ s: \\$::' > "$tmpdepfile" 527 | rm -f "$depfile" 528 | echo "$object : \\" > "$depfile" 529 | cat < "$tmpdepfile" >> "$depfile" 530 | sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile" 531 | rm -f "$tmpdepfile" 532 | ;; 533 | 534 | msvisualcpp) 535 | # Important note: in order to support this mode, a compiler *must* 536 | # always write the preprocessed file to stdout, regardless of -o, 537 | # because we must use -o when running libtool. 538 | "$@" || exit $? 539 | IFS=" " 540 | for arg 541 | do 542 | case "$arg" in 543 | "-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI") 544 | set fnord "$@" 545 | shift 546 | shift 547 | ;; 548 | *) 549 | set fnord "$@" "$arg" 550 | shift 551 | shift 552 | ;; 553 | esac 554 | done 555 | "$@" -E | 556 | sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::echo "`cygpath -u \\"\1\\"`":p' | sort | uniq > "$tmpdepfile" 557 | rm -f "$depfile" 558 | echo "$object : \\" > "$depfile" 559 | . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile" 560 | echo " " >> "$depfile" 561 | . "$tmpdepfile" | sed 's% %\\ %g' | sed -n '/^\(.*\)$/ s::\1\::p' >> "$depfile" 562 | rm -f "$tmpdepfile" 563 | ;; 564 | 565 | none) 566 | exec "$@" 567 | ;; 568 | 569 | *) 570 | echo "Unknown depmode $depmode" 1>&2 571 | exit 1 572 | ;; 573 | esac 574 | 575 | exit 0 576 | 577 | # Local Variables: 578 | # mode: shell-script 579 | # sh-indentation: 2 580 | # eval: (add-hook 'write-file-hooks 'time-stamp) 581 | # time-stamp-start: "scriptversion=" 582 | # time-stamp-format: "%:y-%02m-%02d.%02H" 583 | # time-stamp-end: "$" 584 | # End: 585 | -------------------------------------------------------------------------------- /build-aux/install-sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | # install - install a program, script, or datafile 3 | 4 | scriptversion=2006-10-14.15 5 | 6 | # This originates from X11R5 (mit/util/scripts/install.sh), which was 7 | # later released in X11R6 (xc/config/util/install.sh) with the 8 | # following copyright and license. 9 | # 10 | # Copyright (C) 1994 X Consortium 11 | # 12 | # Permission is hereby granted, free of charge, to any person obtaining a copy 13 | # of this software and associated documentation files (the "Software"), to 14 | # deal in the Software without restriction, including without limitation the 15 | # rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 16 | # sell copies of the Software, and to permit persons to whom the Software is 17 | # furnished to do so, subject to the following conditions: 18 | # 19 | # The above copyright notice and this permission notice shall be included in 20 | # all copies or substantial portions of the Software. 21 | # 22 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 23 | # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 24 | # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 25 | # X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 26 | # AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC- 27 | # TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 28 | # 29 | # Except as contained in this notice, the name of the X Consortium shall not 30 | # be used in advertising or otherwise to promote the sale, use or other deal- 31 | # ings in this Software without prior written authorization from the X Consor- 32 | # tium. 33 | # 34 | # 35 | # FSF changes to this file are in the public domain. 36 | # 37 | # Calling this script install-sh is preferred over install.sh, to prevent 38 | # `make' implicit rules from creating a file called install from it 39 | # when there is no Makefile. 40 | # 41 | # This script is compatible with the BSD install script, but was written 42 | # from scratch. 43 | 44 | nl=' 45 | ' 46 | IFS=" "" $nl" 47 | 48 | # set DOITPROG to echo to test this script 49 | 50 | # Don't use :- since 4.3BSD and earlier shells don't like it. 51 | doit="${DOITPROG-}" 52 | if test -z "$doit"; then 53 | doit_exec=exec 54 | else 55 | doit_exec=$doit 56 | fi 57 | 58 | # Put in absolute file names if you don't have them in your path; 59 | # or use environment vars. 60 | 61 | mvprog="${MVPROG-mv}" 62 | cpprog="${CPPROG-cp}" 63 | chmodprog="${CHMODPROG-chmod}" 64 | chownprog="${CHOWNPROG-chown}" 65 | chgrpprog="${CHGRPPROG-chgrp}" 66 | stripprog="${STRIPPROG-strip}" 67 | rmprog="${RMPROG-rm}" 68 | mkdirprog="${MKDIRPROG-mkdir}" 69 | 70 | posix_glob= 71 | posix_mkdir= 72 | 73 | # Desired mode of installed file. 74 | mode=0755 75 | 76 | chmodcmd=$chmodprog 77 | chowncmd= 78 | chgrpcmd= 79 | stripcmd= 80 | rmcmd="$rmprog -f" 81 | mvcmd="$mvprog" 82 | src= 83 | dst= 84 | dir_arg= 85 | dstarg= 86 | no_target_directory= 87 | 88 | usage="Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE 89 | or: $0 [OPTION]... SRCFILES... DIRECTORY 90 | or: $0 [OPTION]... -t DIRECTORY SRCFILES... 91 | or: $0 [OPTION]... -d DIRECTORIES... 92 | 93 | In the 1st form, copy SRCFILE to DSTFILE. 94 | In the 2nd and 3rd, copy all SRCFILES to DIRECTORY. 95 | In the 4th, create DIRECTORIES. 96 | 97 | Options: 98 | -c (ignored) 99 | -d create directories instead of installing files. 100 | -g GROUP $chgrpprog installed files to GROUP. 101 | -m MODE $chmodprog installed files to MODE. 102 | -o USER $chownprog installed files to USER. 103 | -s $stripprog installed files. 104 | -t DIRECTORY install into DIRECTORY. 105 | -T report an error if DSTFILE is a directory. 106 | --help display this help and exit. 107 | --version display version info and exit. 108 | 109 | Environment variables override the default commands: 110 | CHGRPPROG CHMODPROG CHOWNPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG 111 | " 112 | 113 | while test $# -ne 0; do 114 | case $1 in 115 | -c) shift 116 | continue;; 117 | 118 | -d) dir_arg=true 119 | shift 120 | continue;; 121 | 122 | -g) chgrpcmd="$chgrpprog $2" 123 | shift 124 | shift 125 | continue;; 126 | 127 | --help) echo "$usage"; exit $?;; 128 | 129 | -m) mode=$2 130 | shift 131 | shift 132 | case $mode in 133 | *' '* | *' '* | *' 134 | '* | *'*'* | *'?'* | *'['*) 135 | echo "$0: invalid mode: $mode" >&2 136 | exit 1;; 137 | esac 138 | continue;; 139 | 140 | -o) chowncmd="$chownprog $2" 141 | shift 142 | shift 143 | continue;; 144 | 145 | -s) stripcmd=$stripprog 146 | shift 147 | continue;; 148 | 149 | -t) dstarg=$2 150 | shift 151 | shift 152 | continue;; 153 | 154 | -T) no_target_directory=true 155 | shift 156 | continue;; 157 | 158 | --version) echo "$0 $scriptversion"; exit $?;; 159 | 160 | --) shift 161 | break;; 162 | 163 | -*) echo "$0: invalid option: $1" >&2 164 | exit 1;; 165 | 166 | *) break;; 167 | esac 168 | done 169 | 170 | if test $# -ne 0 && test -z "$dir_arg$dstarg"; then 171 | # When -d is used, all remaining arguments are directories to create. 172 | # When -t is used, the destination is already specified. 173 | # Otherwise, the last argument is the destination. Remove it from $@. 174 | for arg 175 | do 176 | if test -n "$dstarg"; then 177 | # $@ is not empty: it contains at least $arg. 178 | set fnord "$@" "$dstarg" 179 | shift # fnord 180 | fi 181 | shift # arg 182 | dstarg=$arg 183 | done 184 | fi 185 | 186 | if test $# -eq 0; then 187 | if test -z "$dir_arg"; then 188 | echo "$0: no input file specified." >&2 189 | exit 1 190 | fi 191 | # It's OK to call `install-sh -d' without argument. 192 | # This can happen when creating conditional directories. 193 | exit 0 194 | fi 195 | 196 | if test -z "$dir_arg"; then 197 | trap '(exit $?); exit' 1 2 13 15 198 | 199 | # Set umask so as not to create temps with too-generous modes. 200 | # However, 'strip' requires both read and write access to temps. 201 | case $mode in 202 | # Optimize common cases. 203 | *644) cp_umask=133;; 204 | *755) cp_umask=22;; 205 | 206 | *[0-7]) 207 | if test -z "$stripcmd"; then 208 | u_plus_rw= 209 | else 210 | u_plus_rw='% 200' 211 | fi 212 | cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;; 213 | *) 214 | if test -z "$stripcmd"; then 215 | u_plus_rw= 216 | else 217 | u_plus_rw=,u+rw 218 | fi 219 | cp_umask=$mode$u_plus_rw;; 220 | esac 221 | fi 222 | 223 | for src 224 | do 225 | # Protect names starting with `-'. 226 | case $src in 227 | -*) src=./$src ;; 228 | esac 229 | 230 | if test -n "$dir_arg"; then 231 | dst=$src 232 | dstdir=$dst 233 | test -d "$dstdir" 234 | dstdir_status=$? 235 | else 236 | 237 | # Waiting for this to be detected by the "$cpprog $src $dsttmp" command 238 | # might cause directories to be created, which would be especially bad 239 | # if $src (and thus $dsttmp) contains '*'. 240 | if test ! -f "$src" && test ! -d "$src"; then 241 | echo "$0: $src does not exist." >&2 242 | exit 1 243 | fi 244 | 245 | if test -z "$dstarg"; then 246 | echo "$0: no destination specified." >&2 247 | exit 1 248 | fi 249 | 250 | dst=$dstarg 251 | # Protect names starting with `-'. 252 | case $dst in 253 | -*) dst=./$dst ;; 254 | esac 255 | 256 | # If destination is a directory, append the input filename; won't work 257 | # if double slashes aren't ignored. 258 | if test -d "$dst"; then 259 | if test -n "$no_target_directory"; then 260 | echo "$0: $dstarg: Is a directory" >&2 261 | exit 1 262 | fi 263 | dstdir=$dst 264 | dst=$dstdir/`basename "$src"` 265 | dstdir_status=0 266 | else 267 | # Prefer dirname, but fall back on a substitute if dirname fails. 268 | dstdir=` 269 | (dirname "$dst") 2>/dev/null || 270 | expr X"$dst" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ 271 | X"$dst" : 'X\(//\)[^/]' \| \ 272 | X"$dst" : 'X\(//\)$' \| \ 273 | X"$dst" : 'X\(/\)' \| . 2>/dev/null || 274 | echo X"$dst" | 275 | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ 276 | s//\1/ 277 | q 278 | } 279 | /^X\(\/\/\)[^/].*/{ 280 | s//\1/ 281 | q 282 | } 283 | /^X\(\/\/\)$/{ 284 | s//\1/ 285 | q 286 | } 287 | /^X\(\/\).*/{ 288 | s//\1/ 289 | q 290 | } 291 | s/.*/./; q' 292 | ` 293 | 294 | test -d "$dstdir" 295 | dstdir_status=$? 296 | fi 297 | fi 298 | 299 | obsolete_mkdir_used=false 300 | 301 | if test $dstdir_status != 0; then 302 | case $posix_mkdir in 303 | '') 304 | # Create intermediate dirs using mode 755 as modified by the umask. 305 | # This is like FreeBSD 'install' as of 1997-10-28. 306 | umask=`umask` 307 | case $stripcmd.$umask in 308 | # Optimize common cases. 309 | *[2367][2367]) mkdir_umask=$umask;; 310 | .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; 311 | 312 | *[0-7]) 313 | mkdir_umask=`expr $umask + 22 \ 314 | - $umask % 100 % 40 + $umask % 20 \ 315 | - $umask % 10 % 4 + $umask % 2 316 | `;; 317 | *) mkdir_umask=$umask,go-w;; 318 | esac 319 | 320 | # With -d, create the new directory with the user-specified mode. 321 | # Otherwise, rely on $mkdir_umask. 322 | if test -n "$dir_arg"; then 323 | mkdir_mode=-m$mode 324 | else 325 | mkdir_mode= 326 | fi 327 | 328 | posix_mkdir=false 329 | case $umask in 330 | *[123567][0-7][0-7]) 331 | # POSIX mkdir -p sets u+wx bits regardless of umask, which 332 | # is incompatible with FreeBSD 'install' when (umask & 300) != 0. 333 | ;; 334 | *) 335 | tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ 336 | trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 337 | 338 | if (umask $mkdir_umask && 339 | exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 340 | then 341 | if test -z "$dir_arg" || { 342 | # Check for POSIX incompatibilities with -m. 343 | # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or 344 | # other-writeable bit of parent directory when it shouldn't. 345 | # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. 346 | ls_ld_tmpdir=`ls -ld "$tmpdir"` 347 | case $ls_ld_tmpdir in 348 | d????-?r-*) different_mode=700;; 349 | d????-?--*) different_mode=755;; 350 | *) false;; 351 | esac && 352 | $mkdirprog -m$different_mode -p -- "$tmpdir" && { 353 | ls_ld_tmpdir_1=`ls -ld "$tmpdir"` 354 | test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" 355 | } 356 | } 357 | then posix_mkdir=: 358 | fi 359 | rmdir "$tmpdir/d" "$tmpdir" 360 | else 361 | # Remove any dirs left behind by ancient mkdir implementations. 362 | rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null 363 | fi 364 | trap '' 0;; 365 | esac;; 366 | esac 367 | 368 | if 369 | $posix_mkdir && ( 370 | umask $mkdir_umask && 371 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir" 372 | ) 373 | then : 374 | else 375 | 376 | # The umask is ridiculous, or mkdir does not conform to POSIX, 377 | # or it failed possibly due to a race condition. Create the 378 | # directory the slow way, step by step, checking for races as we go. 379 | 380 | case $dstdir in 381 | /*) prefix=/ ;; 382 | -*) prefix=./ ;; 383 | *) prefix= ;; 384 | esac 385 | 386 | case $posix_glob in 387 | '') 388 | if (set -f) 2>/dev/null; then 389 | posix_glob=true 390 | else 391 | posix_glob=false 392 | fi ;; 393 | esac 394 | 395 | oIFS=$IFS 396 | IFS=/ 397 | $posix_glob && set -f 398 | set fnord $dstdir 399 | shift 400 | $posix_glob && set +f 401 | IFS=$oIFS 402 | 403 | prefixes= 404 | 405 | for d 406 | do 407 | test -z "$d" && continue 408 | 409 | prefix=$prefix$d 410 | if test -d "$prefix"; then 411 | prefixes= 412 | else 413 | if $posix_mkdir; then 414 | (umask=$mkdir_umask && 415 | $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break 416 | # Don't fail if two instances are running concurrently. 417 | test -d "$prefix" || exit 1 418 | else 419 | case $prefix in 420 | *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;; 421 | *) qprefix=$prefix;; 422 | esac 423 | prefixes="$prefixes '$qprefix'" 424 | fi 425 | fi 426 | prefix=$prefix/ 427 | done 428 | 429 | if test -n "$prefixes"; then 430 | # Don't fail if two instances are running concurrently. 431 | (umask $mkdir_umask && 432 | eval "\$doit_exec \$mkdirprog $prefixes") || 433 | test -d "$dstdir" || exit 1 434 | obsolete_mkdir_used=true 435 | fi 436 | fi 437 | fi 438 | 439 | if test -n "$dir_arg"; then 440 | { test -z "$chowncmd" || $doit $chowncmd "$dst"; } && 441 | { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } && 442 | { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false || 443 | test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1 444 | else 445 | 446 | # Make a couple of temp file names in the proper directory. 447 | dsttmp=$dstdir/_inst.$$_ 448 | rmtmp=$dstdir/_rm.$$_ 449 | 450 | # Trap to clean up those temp files at exit. 451 | trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 452 | 453 | # Copy the file name to the temp name. 454 | (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && 455 | 456 | # and set any options; do chmod last to preserve setuid bits. 457 | # 458 | # If any of these fail, we abort the whole thing. If we want to 459 | # ignore errors from any of these, just make sure not to ignore 460 | # errors from the above "$doit $cpprog $src $dsttmp" command. 461 | # 462 | { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } \ 463 | && { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } \ 464 | && { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } \ 465 | && { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } && 466 | 467 | # Now rename the file to the real destination. 468 | { $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null \ 469 | || { 470 | # The rename failed, perhaps because mv can't rename something else 471 | # to itself, or perhaps because mv is so ancient that it does not 472 | # support -f. 473 | 474 | # Now remove or move aside any old file at destination location. 475 | # We try this two ways since rm can't unlink itself on some 476 | # systems and the destination file might be busy for other 477 | # reasons. In this case, the final cleanup might fail but the new 478 | # file should still install successfully. 479 | { 480 | if test -f "$dst"; then 481 | $doit $rmcmd -f "$dst" 2>/dev/null \ 482 | || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null \ 483 | && { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }; }\ 484 | || { 485 | echo "$0: cannot unlink or rename $dst" >&2 486 | (exit 1); exit 1 487 | } 488 | else 489 | : 490 | fi 491 | } && 492 | 493 | # Now rename the file to the real destination. 494 | $doit $mvcmd "$dsttmp" "$dst" 495 | } 496 | } || exit 1 497 | 498 | trap '' 0 499 | fi 500 | done 501 | 502 | # Local variables: 503 | # eval: (add-hook 'write-file-hooks 'time-stamp) 504 | # time-stamp-start: "scriptversion=" 505 | # time-stamp-format: "%:y-%02m-%02d.%02H" 506 | # time-stamp-end: "$" 507 | # End: 508 | -------------------------------------------------------------------------------- /build-aux/missing: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # Common stub for a few missing GNU programs while installing. 3 | 4 | scriptversion=2006-05-10.23 5 | 6 | # Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003, 2004, 2005, 2006 7 | # Free Software Foundation, Inc. 8 | # Originally by Fran,cois Pinard , 1996. 9 | 10 | # This program is free software; you can redistribute it and/or modify 11 | # it under the terms of the GNU General Public License as published by 12 | # the Free Software Foundation; either version 2, or (at your option) 13 | # any later version. 14 | 15 | # This program is distributed in the hope that it will be useful, 16 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 17 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 | # GNU General Public License for more details. 19 | 20 | # You should have received a copy of the GNU General Public License 21 | # along with this program; if not, write to the Free Software 22 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 23 | # 02110-1301, USA. 24 | 25 | # As a special exception to the GNU General Public License, if you 26 | # distribute this file as part of a program that contains a 27 | # configuration script generated by Autoconf, you may include it under 28 | # the same distribution terms that you use for the rest of that program. 29 | 30 | if test $# -eq 0; then 31 | echo 1>&2 "Try \`$0 --help' for more information" 32 | exit 1 33 | fi 34 | 35 | run=: 36 | sed_output='s/.* --output[ =]\([^ ]*\).*/\1/p' 37 | sed_minuso='s/.* -o \([^ ]*\).*/\1/p' 38 | 39 | # In the cases where this matters, `missing' is being run in the 40 | # srcdir already. 41 | if test -f configure.ac; then 42 | configure_ac=configure.ac 43 | else 44 | configure_ac=configure.in 45 | fi 46 | 47 | msg="missing on your system" 48 | 49 | case $1 in 50 | --run) 51 | # Try to run requested program, and just exit if it succeeds. 52 | run= 53 | shift 54 | "$@" && exit 0 55 | # Exit code 63 means version mismatch. This often happens 56 | # when the user try to use an ancient version of a tool on 57 | # a file that requires a minimum version. In this case we 58 | # we should proceed has if the program had been absent, or 59 | # if --run hadn't been passed. 60 | if test $? = 63; then 61 | run=: 62 | msg="probably too old" 63 | fi 64 | ;; 65 | 66 | -h|--h|--he|--hel|--help) 67 | echo "\ 68 | $0 [OPTION]... PROGRAM [ARGUMENT]... 69 | 70 | Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an 71 | error status if there is no known handling for PROGRAM. 72 | 73 | Options: 74 | -h, --help display this help and exit 75 | -v, --version output version information and exit 76 | --run try to run the given command, and emulate it if it fails 77 | 78 | Supported PROGRAM values: 79 | aclocal touch file \`aclocal.m4' 80 | autoconf touch file \`configure' 81 | autoheader touch file \`config.h.in' 82 | autom4te touch the output file, or create a stub one 83 | automake touch all \`Makefile.in' files 84 | bison create \`y.tab.[ch]', if possible, from existing .[ch] 85 | flex create \`lex.yy.c', if possible, from existing .c 86 | help2man touch the output file 87 | lex create \`lex.yy.c', if possible, from existing .c 88 | makeinfo touch the output file 89 | tar try tar, gnutar, gtar, then tar without non-portable flags 90 | yacc create \`y.tab.[ch]', if possible, from existing .[ch] 91 | 92 | Send bug reports to ." 93 | exit $? 94 | ;; 95 | 96 | -v|--v|--ve|--ver|--vers|--versi|--versio|--version) 97 | echo "missing $scriptversion (GNU Automake)" 98 | exit $? 99 | ;; 100 | 101 | -*) 102 | echo 1>&2 "$0: Unknown \`$1' option" 103 | echo 1>&2 "Try \`$0 --help' for more information" 104 | exit 1 105 | ;; 106 | 107 | esac 108 | 109 | # Now exit if we have it, but it failed. Also exit now if we 110 | # don't have it and --version was passed (most likely to detect 111 | # the program). 112 | case $1 in 113 | lex|yacc) 114 | # Not GNU programs, they don't have --version. 115 | ;; 116 | 117 | tar) 118 | if test -n "$run"; then 119 | echo 1>&2 "ERROR: \`tar' requires --run" 120 | exit 1 121 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 122 | exit 1 123 | fi 124 | ;; 125 | 126 | *) 127 | if test -z "$run" && ($1 --version) > /dev/null 2>&1; then 128 | # We have it, but it failed. 129 | exit 1 130 | elif test "x$2" = "x--version" || test "x$2" = "x--help"; then 131 | # Could not run --version or --help. This is probably someone 132 | # running `$TOOL --version' or `$TOOL --help' to check whether 133 | # $TOOL exists and not knowing $TOOL uses missing. 134 | exit 1 135 | fi 136 | ;; 137 | esac 138 | 139 | # If it does not exist, or fails to run (possibly an outdated version), 140 | # try to emulate it. 141 | case $1 in 142 | aclocal*) 143 | echo 1>&2 "\ 144 | WARNING: \`$1' is $msg. You should only need it if 145 | you modified \`acinclude.m4' or \`${configure_ac}'. You might want 146 | to install the \`Automake' and \`Perl' packages. Grab them from 147 | any GNU archive site." 148 | touch aclocal.m4 149 | ;; 150 | 151 | autoconf) 152 | echo 1>&2 "\ 153 | WARNING: \`$1' is $msg. You should only need it if 154 | you modified \`${configure_ac}'. You might want to install the 155 | \`Autoconf' and \`GNU m4' packages. Grab them from any GNU 156 | archive site." 157 | touch configure 158 | ;; 159 | 160 | autoheader) 161 | echo 1>&2 "\ 162 | WARNING: \`$1' is $msg. You should only need it if 163 | you modified \`acconfig.h' or \`${configure_ac}'. You might want 164 | to install the \`Autoconf' and \`GNU m4' packages. Grab them 165 | from any GNU archive site." 166 | files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}` 167 | test -z "$files" && files="config.h" 168 | touch_files= 169 | for f in $files; do 170 | case $f in 171 | *:*) touch_files="$touch_files "`echo "$f" | 172 | sed -e 's/^[^:]*://' -e 's/:.*//'`;; 173 | *) touch_files="$touch_files $f.in";; 174 | esac 175 | done 176 | touch $touch_files 177 | ;; 178 | 179 | automake*) 180 | echo 1>&2 "\ 181 | WARNING: \`$1' is $msg. You should only need it if 182 | you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'. 183 | You might want to install the \`Automake' and \`Perl' packages. 184 | Grab them from any GNU archive site." 185 | find . -type f -name Makefile.am -print | 186 | sed 's/\.am$/.in/' | 187 | while read f; do touch "$f"; done 188 | ;; 189 | 190 | autom4te) 191 | echo 1>&2 "\ 192 | WARNING: \`$1' is needed, but is $msg. 193 | You might have modified some files without having the 194 | proper tools for further handling them. 195 | You can get \`$1' as part of \`Autoconf' from any GNU 196 | archive site." 197 | 198 | file=`echo "$*" | sed -n "$sed_output"` 199 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 200 | if test -f "$file"; then 201 | touch $file 202 | else 203 | test -z "$file" || exec >$file 204 | echo "#! /bin/sh" 205 | echo "# Created by GNU Automake missing as a replacement of" 206 | echo "# $ $@" 207 | echo "exit 0" 208 | chmod +x $file 209 | exit 1 210 | fi 211 | ;; 212 | 213 | bison|yacc) 214 | echo 1>&2 "\ 215 | WARNING: \`$1' $msg. You should only need it if 216 | you modified a \`.y' file. You may need the \`Bison' package 217 | in order for those modifications to take effect. You can get 218 | \`Bison' from any GNU archive site." 219 | rm -f y.tab.c y.tab.h 220 | if test $# -ne 1; then 221 | eval LASTARG="\${$#}" 222 | case $LASTARG in 223 | *.y) 224 | SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'` 225 | if test -f "$SRCFILE"; then 226 | cp "$SRCFILE" y.tab.c 227 | fi 228 | SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'` 229 | if test -f "$SRCFILE"; then 230 | cp "$SRCFILE" y.tab.h 231 | fi 232 | ;; 233 | esac 234 | fi 235 | if test ! -f y.tab.h; then 236 | echo >y.tab.h 237 | fi 238 | if test ! -f y.tab.c; then 239 | echo 'main() { return 0; }' >y.tab.c 240 | fi 241 | ;; 242 | 243 | lex|flex) 244 | echo 1>&2 "\ 245 | WARNING: \`$1' is $msg. You should only need it if 246 | you modified a \`.l' file. You may need the \`Flex' package 247 | in order for those modifications to take effect. You can get 248 | \`Flex' from any GNU archive site." 249 | rm -f lex.yy.c 250 | if test $# -ne 1; then 251 | eval LASTARG="\${$#}" 252 | case $LASTARG in 253 | *.l) 254 | SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'` 255 | if test -f "$SRCFILE"; then 256 | cp "$SRCFILE" lex.yy.c 257 | fi 258 | ;; 259 | esac 260 | fi 261 | if test ! -f lex.yy.c; then 262 | echo 'main() { return 0; }' >lex.yy.c 263 | fi 264 | ;; 265 | 266 | help2man) 267 | echo 1>&2 "\ 268 | WARNING: \`$1' is $msg. You should only need it if 269 | you modified a dependency of a manual page. You may need the 270 | \`Help2man' package in order for those modifications to take 271 | effect. You can get \`Help2man' from any GNU archive site." 272 | 273 | file=`echo "$*" | sed -n "$sed_output"` 274 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 275 | if test -f "$file"; then 276 | touch $file 277 | else 278 | test -z "$file" || exec >$file 279 | echo ".ab help2man is required to generate this page" 280 | exit 1 281 | fi 282 | ;; 283 | 284 | makeinfo) 285 | echo 1>&2 "\ 286 | WARNING: \`$1' is $msg. You should only need it if 287 | you modified a \`.texi' or \`.texinfo' file, or any other file 288 | indirectly affecting the aspect of the manual. The spurious 289 | call might also be the consequence of using a buggy \`make' (AIX, 290 | DU, IRIX). You might want to install the \`Texinfo' package or 291 | the \`GNU make' package. Grab either from any GNU archive site." 292 | # The file to touch is that specified with -o ... 293 | file=`echo "$*" | sed -n "$sed_output"` 294 | test -z "$file" && file=`echo "$*" | sed -n "$sed_minuso"` 295 | if test -z "$file"; then 296 | # ... or it is the one specified with @setfilename ... 297 | infile=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'` 298 | file=`sed -n ' 299 | /^@setfilename/{ 300 | s/.* \([^ ]*\) *$/\1/ 301 | p 302 | q 303 | }' $infile` 304 | # ... or it is derived from the source name (dir/f.texi becomes f.info) 305 | test -z "$file" && file=`echo "$infile" | sed 's,.*/,,;s,.[^.]*$,,'`.info 306 | fi 307 | # If the file does not exist, the user really needs makeinfo; 308 | # let's fail without touching anything. 309 | test -f $file || exit 1 310 | touch $file 311 | ;; 312 | 313 | tar) 314 | shift 315 | 316 | # We have already tried tar in the generic part. 317 | # Look for gnutar/gtar before invocation to avoid ugly error 318 | # messages. 319 | if (gnutar --version > /dev/null 2>&1); then 320 | gnutar "$@" && exit 0 321 | fi 322 | if (gtar --version > /dev/null 2>&1); then 323 | gtar "$@" && exit 0 324 | fi 325 | firstarg="$1" 326 | if shift; then 327 | case $firstarg in 328 | *o*) 329 | firstarg=`echo "$firstarg" | sed s/o//` 330 | tar "$firstarg" "$@" && exit 0 331 | ;; 332 | esac 333 | case $firstarg in 334 | *h*) 335 | firstarg=`echo "$firstarg" | sed s/h//` 336 | tar "$firstarg" "$@" && exit 0 337 | ;; 338 | esac 339 | fi 340 | 341 | echo 1>&2 "\ 342 | WARNING: I can't seem to be able to run \`tar' with the given arguments. 343 | You may want to install GNU tar or Free paxutils, or check the 344 | command line arguments." 345 | exit 1 346 | ;; 347 | 348 | *) 349 | echo 1>&2 "\ 350 | WARNING: \`$1' is needed, and is $msg. 351 | You might have modified some files without having the 352 | proper tools for further handling them. Check the \`README' file, 353 | it often tells you about the needed prerequisites for installing 354 | this package. You may also peek at any GNU archive site, in case 355 | some other package would contain this missing \`$1' program." 356 | exit 1 357 | ;; 358 | esac 359 | 360 | exit 0 361 | 362 | # Local variables: 363 | # eval: (add-hook 'write-file-hooks 'time-stamp) 364 | # time-stamp-start: "scriptversion=" 365 | # time-stamp-format: "%:y-%02m-%02d.%02H" 366 | # time-stamp-end: "$" 367 | # End: 368 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | AC_INIT([rsbep], [0.2.0-ttsiodras], [ttsiodras@gmail.com]) 2 | 3 | AC_CONFIG_MACRO_DIR([ac-macros]) 4 | 5 | # Don't clutter this dir, store in build-aux 6 | AC_CONFIG_AUX_DIR([build-aux]) 7 | 8 | # Detect the canonical host and target build environment 9 | AC_CANONICAL_HOST 10 | AC_CANONICAL_TARGET 11 | 12 | AM_INIT_AUTOMAKE([-Wall -Werror]) 13 | 14 | AC_PROG_CC 15 | 16 | AC_LANG(C) 17 | 18 | # Stuff provided by autoscan 19 | AC_CHECK_FUNCS([bzero]) 20 | AC_CHECK_FUNCS([memset]) 21 | AC_CHECK_HEADERS([malloc.h]) 22 | AC_CHECK_HEADERS([stdlib.h]) 23 | AC_CHECK_HEADERS([string.h]) 24 | AC_CHECK_HEADERS([unistd.h]) 25 | AC_C_INLINE 26 | AC_FUNC_MALLOC 27 | AC_HEADER_STDC 28 | AC_PREREQ 29 | 30 | AM_PROG_AS 31 | AM_PROG_CC_C_O 32 | 33 | AX_CFLAGS_GCC_OPTION(-Wall) 34 | 35 | AC_MSG_CHECKING(for native x86 asm support) 36 | if AC_TRY_COMMAND($CC -c src/rs32asm.s) >/dev/null 2>&1; then 37 | X86ASM=yes 38 | else 39 | X86ASM=no 40 | fi 41 | AC_MSG_RESULT($X86ASM) 42 | AM_CONDITIONAL([HAVE_X86ASM], [test x$X86ASM = xyes]) 43 | if test x$X86ASM != xyes; then 44 | AC_MSG_WARN([*** Can't use native x86 asm version... it will be slow...]) 45 | fi 46 | 47 | # Check for Python FUSE support 48 | AC_PYTHON_MODULE(fuse) 49 | if test x$HAVE_PYMOD_FUSE != xyes; then 50 | AC_MSG_WARN([*** Python FUSE was not found so you won't be able to mount "shielded" filesystems.]) 51 | fi 52 | 53 | # Finally create all the generated files 54 | AC_CONFIG_FILES([Makefile src/Makefile]) 55 | AC_OUTPUT 56 | -------------------------------------------------------------------------------- /contrib/freeze.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $# -ne 1 ] ; then 3 | echo Usage: $0 filename \(... will output to stdout\) 4 | exit 1 5 | fi 6 | if [ ! -f "$1" ] ; then echo \"$1\" is not a regular file\! ; exit 1 ; fi 7 | # stat -c doesn't work under OS/X 8 | # SIZE=`stat -c '%s' "$1"` 9 | SIZE=`ls -l "$1" | awk '{print $5}'` 10 | { echo MAGIC_TTSIOD_RS ; echo $SIZE ; cat "$1"; } | rsbep -B 255 -D 223 -R 4080 11 | -------------------------------------------------------------------------------- /contrib/melt.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | if [ $# -ne 1 ] ; then 3 | echo Usage: $0 filename \(...will output to stdout\) 4 | exit 1 5 | fi 6 | if [ ! -f "$1" ] ; then echo $1 is not a regular file\! ; exit 1 ; fi 7 | 8 | dd if="$1" conv=noerror,sync 2>/dev/null | rsbep -d -B 255 -D 223 -R 4080 | { 9 | read SIG 10 | if [ "$SIG" != "MAGIC_TTSIOD_RS" ] ; then 11 | echo "Beyond capacity to correct... Sorry." > /dev/stderr 12 | exit 1 13 | fi 14 | read SIZE 15 | rsbep_chopper $SIZE 16 | } 17 | -------------------------------------------------------------------------------- /contrib/poorZFS.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # Copyright (C) 2001 Jeff Epler 4 | # Copyright (C) 2006 Csaba Henk 5 | # Copyright (C) 2009 Thanassis Tsiodras 6 | # 7 | # This program can be distributed under the terms of the GNU LGPL. 8 | # See the file COPYING. 9 | # 10 | # ttsiodras comments: 11 | # 12 | # Last summer an article of mine got Slashdotted (http://ttsiodras.googlepages.com/rsbep.html). 13 | # It described a simple technique that uses Reed-Solomon codes to make files resilient 14 | # to data corruption. Using a python-fuse example (xmp.py) as a base, I added the 15 | # necessary code to have a FUSE-mounted directory automatically have these Reed-Solomon 16 | # "shields" calculated. In plain words, you can execute... 17 | # 18 | # ./poorZFS.py -f /reed-solomoned-data /strong 19 | # 20 | # This command will mount a FUSE-based filesystem in /strong (using the /reed-solomoned-data 21 | # directory to store the actual files and their "shielded" versions). Any file you create 22 | # in /strong, will in fact exist under /reed-solomoned-data, and will also be shielded there. 23 | # Upon reading any file in /strong, any data corruption is detected and it will be 24 | # corrected using the Reed-Solomon "shielded" version (stored alongside the original file, 25 | # and named originalFilename.frozen.RS file). 26 | # 27 | # I coded this using Python-fuse in a couple of hours on a boring Sunday afternoon, so don't 28 | # trust your bank account data with it... It's not supposed to be anything other than a proof 29 | # of concept. 30 | 31 | import os, sys, signal 32 | from errno import * 33 | from stat import * 34 | import fcntl 35 | from hashlib import md5 36 | from subprocess import Popen, PIPE 37 | 38 | import fuse 39 | from fuse import Fuse 40 | 41 | if not hasattr(fuse, '__version__'): 42 | raise RuntimeError, \ 43 | "your fuse-py doesn't know of fuse.__version__, probably it's too old." 44 | 45 | fuse.fuse_python_api = (0, 2) 46 | 47 | fuse.feature_assert('stateful_files', 'has_init') 48 | 49 | def CreateRS(path): 50 | print "Creating Reed-solomon version of file " + path + " ..." 51 | os.system("freeze.sh '" + path + "' > '" + path + ".frozen.RS'") 52 | print "Created." 53 | 54 | def CheckCRC(path): 55 | print "Checking CRC of file " + path 56 | rsMD5 = md5() 57 | signal.signal(signal.SIGPIPE, signal.SIG_IGN) 58 | rsMD5.update(Popen("melt.sh '" + path + ".frozen.RS'", shell=True, stdout=PIPE).stdout.read()) 59 | signal.signal(signal.SIGPIPE, signal.SIG_DFL) 60 | fileMD5 = md5() 61 | fileMD5.update(open(path, 'rb').read()) 62 | if fileMD5.hexdigest() != rsMD5.hexdigest(): 63 | print "Data corrupted inside file '" + path + "'... fixing..." 64 | os.system("melt.sh '" + path + ".frozen.RS' > '" + path + "'") 65 | else: 66 | print "CRC is OK" 67 | 68 | def flag2mode(flags): 69 | md = {os.O_RDONLY: 'r', os.O_WRONLY: 'w', os.O_RDWR: 'w+'} 70 | m = md[flags & (os.O_RDONLY | os.O_WRONLY | os.O_RDWR)] 71 | 72 | if flags | os.O_APPEND: 73 | m = m.replace('w', 'a', 1) 74 | 75 | return m 76 | 77 | 78 | class Xmp(Fuse): 79 | 80 | def __init__(self, *args, **kw): 81 | 82 | Fuse.__init__(self, *args, **kw) 83 | 84 | # do stuff to set up your filesystem here, if you want 85 | #import thread 86 | #thread.start_new_thread(self.mythread, ()) 87 | self.root = None 88 | 89 | # def mythread(self): 90 | # 91 | # """ 92 | # The beauty of the FUSE python implementation is that with the python interp 93 | # running in foreground, you can have threads 94 | # """ 95 | # print "mythread: started" 96 | # while 1: 97 | # time.sleep(120) 98 | # print "mythread: ticking" 99 | 100 | def getattr(self, path): 101 | return os.lstat("." + path) 102 | 103 | def readlink(self, path): 104 | return os.readlink("." + path) 105 | 106 | def readdir(self, path, offset): 107 | for e in os.listdir("." + path): 108 | if not e.endswith(".frozen.RS"): 109 | yield fuse.Direntry(e) 110 | 111 | def unlink(self, path): 112 | os.unlink("." + path) 113 | os.unlink("." + path + ".frozen.RS") 114 | 115 | def rmdir(self, path): 116 | os.rmdir("." + path) 117 | 118 | def symlink(self, path, path1): 119 | os.symlink(path, "." + path1) 120 | os.symlink(path+".frozen.RS", "."+path1+".frozen.RS") 121 | 122 | def rename(self, path, path1): 123 | os.rename("." + path, "." + path1) 124 | os.rename("." + path + ".frozen.RS", "." + path1 + ".frozen.RS") 125 | 126 | def link(self, path, path1): 127 | os.link("." + path, "." + path1) 128 | os.link("." + path + ".frozen.RS", "." + path1 + ".frozen.RS") 129 | 130 | def chmod(self, path, mode): 131 | os.chmod("." + path, mode) 132 | if os.path.exists("." + path + ".frozen.RS"): 133 | os.chmod("." + path + ".frozen.RS", mode) 134 | 135 | def chown(self, path, user, group): 136 | os.chown("." + path, user, group) 137 | if os.path.exists("." + path + ".frozen.RS"): 138 | os.chown("." + path + ".frozen.RS", user, group) 139 | 140 | def truncate(self, path, len): 141 | f = open("." + path, "a") 142 | f.truncate(len) 143 | f.close() 144 | CreateRS("."+path) 145 | 146 | def mknod(self, path, mode, dev): 147 | os.mknod("." + path, mode, dev) 148 | 149 | def mkdir(self, path, mode): 150 | os.mkdir("." + path, mode) 151 | 152 | def utime(self, path, times): 153 | os.utime("." + path, times) 154 | 155 | # The following utimens method would do the same as the above utime method. 156 | # We can't make it better though as the Python stdlib doesn't know of 157 | # subsecond preciseness in acces/modify times. 158 | # 159 | # def utimens(self, path, ts_acc, ts_mod): 160 | # os.utime("." + path, (ts_acc.tv_sec, ts_mod.tv_sec)) 161 | 162 | def access(self, path, mode): 163 | if not os.access("." + path, mode): 164 | return -EACCES 165 | 166 | # This is how we could add stub extended attribute handlers... 167 | # (We can't have ones which aptly delegate requests to the underlying fs 168 | # because Python lacks a standard xattr interface.) 169 | # 170 | # def getxattr(self, path, name, size): 171 | # val = name.swapcase() + '@' + path 172 | # if size == 0: 173 | # # We are asked for size of the value. 174 | # return len(val) 175 | # return val 176 | # 177 | # def listxattr(self, path, size): 178 | # # We use the "user" namespace to please XFS utils 179 | # aa = ["user." + a for a in ("foo", "bar")] 180 | # if size == 0: 181 | # # We are asked for size of the attr list, ie. joint size of attrs 182 | # # plus null separators. 183 | # return len("".join(aa)) + len(aa) 184 | # return aa 185 | 186 | def statfs(self): 187 | """ 188 | Should return an object with statvfs attributes (f_bsize, f_frsize...). 189 | Eg., the return value of os.statvfs() is such a thing (since py 2.2). 190 | If you are not reusing an existing statvfs object, start with 191 | fuse.StatVFS(), and define the attributes. 192 | 193 | To provide usable information (ie., you want sensible df(1) 194 | output, you are suggested to specify the following attributes: 195 | 196 | - f_bsize - preferred size of file blocks, in bytes 197 | - f_frsize - fundamental size of file blcoks, in bytes 198 | [if you have no idea, use the same as blocksize] 199 | - f_blocks - total number of blocks in the filesystem 200 | - f_bfree - number of free blocks 201 | - f_files - total number of file inodes 202 | - f_ffree - nunber of free file inodes 203 | """ 204 | 205 | return os.statvfs(".") 206 | 207 | def fsinit(self): 208 | os.chdir(self.root) 209 | 210 | class XmpFile(object): 211 | 212 | def __init__(self, path, flags, *mode): 213 | self.mypath = "." + path 214 | self.openflags = flag2mode(flags) 215 | if ( self.openflags == 'r'): 216 | CheckCRC(self.mypath) 217 | self.file = os.fdopen(os.open("." + path, flags, *mode), self.openflags) 218 | self.fd = self.file.fileno() 219 | self.direct_io = False 220 | self.keep_cache = False 221 | 222 | def read(self, length, offset): 223 | self.file.seek(offset) 224 | return self.file.read(length) 225 | 226 | def write(self, buf, offset): 227 | self.file.seek(offset) 228 | self.file.write(buf) 229 | return len(buf) 230 | 231 | def release(self, flags): 232 | self.file.close() 233 | if ( self.openflags != 'r'): 234 | CreateRS(self.mypath) 235 | 236 | def _fflush(self): 237 | if 'w' in self.file.mode or 'a' in self.file.mode: 238 | self.file.flush() 239 | 240 | def fsync(self, isfsyncfile): 241 | self._fflush() 242 | if isfsyncfile and hasattr(os, 'fdatasync'): 243 | os.fdatasync(self.fd) 244 | else: 245 | os.fsync(self.fd) 246 | 247 | def flush(self): 248 | self._fflush() 249 | # cf. xmp_flush() in fusexmp_fh.c 250 | os.close(os.dup(self.fd)) 251 | 252 | def fgetattr(self): 253 | return os.fstat(self.fd) 254 | 255 | def ftruncate(self, len): 256 | self.file.truncate(len) 257 | CreateRS(self.mypath) 258 | 259 | def lock(self, cmd, owner, **kw): 260 | # The code here is much rather just a demonstration of the locking 261 | # API than something which actually was seen to be useful. 262 | 263 | # Advisory file locking is pretty messy in Unix, and the Python 264 | # interface to this doesn't make it better. 265 | # We can't do fcntl(2)/F_GETLK from Python in a platfrom independent 266 | # way. The following implementation *might* work under Linux. 267 | # 268 | # if cmd == fcntl.F_GETLK: 269 | # import struct 270 | # 271 | # lockdata = struct.pack('hhQQi', kw['l_type'], os.SEEK_SET, 272 | # kw['l_start'], kw['l_len'], kw['l_pid']) 273 | # ld2 = fcntl.fcntl(self.fd, fcntl.F_GETLK, lockdata) 274 | # flockfields = ('l_type', 'l_whence', 'l_start', 'l_len', 'l_pid') 275 | # uld2 = struct.unpack('hhQQi', ld2) 276 | # res = {} 277 | # for i in xrange(len(uld2)): 278 | # res[flockfields[i]] = uld2[i] 279 | # 280 | # return fuse.Flock(**res) 281 | 282 | # Convert fcntl-ish lock parameters to Python's weird 283 | # lockf(3)/flock(2) medley locking API... 284 | op = { fcntl.F_UNLCK : fcntl.LOCK_UN, 285 | fcntl.F_RDLCK : fcntl.LOCK_SH, 286 | fcntl.F_WRLCK : fcntl.LOCK_EX }[kw['l_type']] 287 | if cmd == fcntl.F_GETLK: 288 | return -EOPNOTSUPP 289 | elif cmd == fcntl.F_SETLK: 290 | if op != fcntl.LOCK_UN: 291 | op |= fcntl.LOCK_NB 292 | elif cmd == fcntl.F_SETLKW: 293 | pass 294 | else: 295 | return -EINVAL 296 | 297 | fcntl.lockf(self.fd, op, kw['l_start'], kw['l_len']) 298 | 299 | 300 | def main(self, *a, **kw): 301 | 302 | self.file_class = self.XmpFile 303 | 304 | return Fuse.main(self, *a, **kw) 305 | 306 | 307 | def main(): 308 | 309 | usage = """ 310 | Userspace nullfs-alike: mirror the filesystem tree from some point on. 311 | 312 | """ + Fuse.fusage 313 | 314 | server = Xmp(version="%prog " + fuse.__version__, 315 | usage=usage, 316 | dash_s_do='setsingle') 317 | 318 | # Disable multithreading: if you want to use it, protect all method of 319 | # XmlFile class with locks, in order to prevent race conditions 320 | server.multithreaded = False 321 | 322 | server.parse(values=server, errex=1) 323 | 324 | if len(server.parser.largs) != 2: 325 | print "Usage:" + sys.argv[0] + " directoryWithShieldData mountDirectory" 326 | sys.exit(1) 327 | 328 | server.root = server.parser.largs[0] 329 | 330 | print "Shielding directory '"+server.root+"' (mounted in '" + server.parser.largs[1] + "')" 331 | 332 | try: 333 | if server.fuse_args.mount_expected(): 334 | os.chdir(server.root) 335 | except OSError: 336 | print >> sys.stderr, "can't enter root of underlying filesystem" 337 | sys.exit(1) 338 | 339 | server.main() 340 | 341 | 342 | if __name__ == '__main__': 343 | main() 344 | -------------------------------------------------------------------------------- /docs/README.RS32: -------------------------------------------------------------------------------- 1 | This package is a special version of the Reed-Solomon package. It is 2 | hardwired for the (255,223) code over GF(256). The encoder is implemented 3 | entirely in optimized assembler for the Intel 386 series CPU, and the 4 | decoder has an assembler assist for computing the syndrome components. 5 | 6 | The result is a much faster encoder/decoder for this particular code 7 | than the general C version. The encoding speed on a 133 MHz Pentium is 8 | about 30 Mb/s. The decoding speed on a block without any errors is 9 | about 16 Mb/s. 10 | 11 | Phil Karn 12 | karn@ka9q.ampr.org 13 | August 1997 14 | -------------------------------------------------------------------------------- /src/Makefile.am: -------------------------------------------------------------------------------- 1 | bin_PROGRAMS = rsbep rsbep_chopper 2 | 3 | if HAVE_X86ASM 4 | rsbep_CFLAGS = -DASM_I386 5 | rsbep_SOURCES = rsbep.c rs32.c rs32asm.s rs32.h 6 | else 7 | rsbep_CFLAGS = 8 | rsbep_SOURCES = rsbep.c rs.c rs.h 9 | endif 10 | 11 | rsbep_chopper = chopper.c 12 | 13 | -------------------------------------------------------------------------------- /src/Makefile.in: -------------------------------------------------------------------------------- 1 | # Makefile.in generated by automake 1.16.1 from Makefile.am. 2 | # @configure_input@ 3 | 4 | # Copyright (C) 1994-2018 Free Software Foundation, Inc. 5 | 6 | # This Makefile.in is free software; the Free Software Foundation 7 | # gives unlimited permission to copy and/or distribute it, 8 | # with or without modifications, as long as this notice is preserved. 9 | 10 | # This program is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY, to the extent permitted by law; without 12 | # even the implied warranty of MERCHANTABILITY or FITNESS FOR A 13 | # PARTICULAR PURPOSE. 14 | 15 | @SET_MAKE@ 16 | 17 | VPATH = @srcdir@ 18 | am__is_gnu_make = { \ 19 | if test -z '$(MAKELEVEL)'; then \ 20 | false; \ 21 | elif test -n '$(MAKE_HOST)'; then \ 22 | true; \ 23 | elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ 24 | true; \ 25 | else \ 26 | false; \ 27 | fi; \ 28 | } 29 | am__make_running_with_option = \ 30 | case $${target_option-} in \ 31 | ?) ;; \ 32 | *) echo "am__make_running_with_option: internal error: invalid" \ 33 | "target option '$${target_option-}' specified" >&2; \ 34 | exit 1;; \ 35 | esac; \ 36 | has_opt=no; \ 37 | sane_makeflags=$$MAKEFLAGS; \ 38 | if $(am__is_gnu_make); then \ 39 | sane_makeflags=$$MFLAGS; \ 40 | else \ 41 | case $$MAKEFLAGS in \ 42 | *\\[\ \ ]*) \ 43 | bs=\\; \ 44 | sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ 45 | | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ 46 | esac; \ 47 | fi; \ 48 | skip_next=no; \ 49 | strip_trailopt () \ 50 | { \ 51 | flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ 52 | }; \ 53 | for flg in $$sane_makeflags; do \ 54 | test $$skip_next = yes && { skip_next=no; continue; }; \ 55 | case $$flg in \ 56 | *=*|--*) continue;; \ 57 | -*I) strip_trailopt 'I'; skip_next=yes;; \ 58 | -*I?*) strip_trailopt 'I';; \ 59 | -*O) strip_trailopt 'O'; skip_next=yes;; \ 60 | -*O?*) strip_trailopt 'O';; \ 61 | -*l) strip_trailopt 'l'; skip_next=yes;; \ 62 | -*l?*) strip_trailopt 'l';; \ 63 | -[dEDm]) skip_next=yes;; \ 64 | -[JT]) skip_next=yes;; \ 65 | esac; \ 66 | case $$flg in \ 67 | *$$target_option*) has_opt=yes; break;; \ 68 | esac; \ 69 | done; \ 70 | test $$has_opt = yes 71 | am__make_dryrun = (target_option=n; $(am__make_running_with_option)) 72 | am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) 73 | pkgdatadir = $(datadir)/@PACKAGE@ 74 | pkgincludedir = $(includedir)/@PACKAGE@ 75 | pkglibdir = $(libdir)/@PACKAGE@ 76 | pkglibexecdir = $(libexecdir)/@PACKAGE@ 77 | am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd 78 | install_sh_DATA = $(install_sh) -c -m 644 79 | install_sh_PROGRAM = $(install_sh) -c 80 | install_sh_SCRIPT = $(install_sh) -c 81 | INSTALL_HEADER = $(INSTALL_DATA) 82 | transform = $(program_transform_name) 83 | NORMAL_INSTALL = : 84 | PRE_INSTALL = : 85 | POST_INSTALL = : 86 | NORMAL_UNINSTALL = : 87 | PRE_UNINSTALL = : 88 | POST_UNINSTALL = : 89 | build_triplet = @build@ 90 | host_triplet = @host@ 91 | target_triplet = @target@ 92 | bin_PROGRAMS = rsbep$(EXEEXT) rsbep_chopper$(EXEEXT) 93 | subdir = src 94 | ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 95 | am__aclocal_m4_deps = $(top_srcdir)/acinclude.m4 \ 96 | $(top_srcdir)/ac-macros/ac_python_module.m4 \ 97 | $(top_srcdir)/ac-macros/ax_cflags_gcc_option.m4 \ 98 | $(top_srcdir)/configure.ac 99 | am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 100 | $(ACLOCAL_M4) 101 | DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) 102 | mkinstalldirs = $(install_sh) -d 103 | CONFIG_CLEAN_FILES = 104 | CONFIG_CLEAN_VPATH_FILES = 105 | am__installdirs = "$(DESTDIR)$(bindir)" 106 | PROGRAMS = $(bin_PROGRAMS) 107 | am__rsbep_SOURCES_DIST = rsbep.c rs.c rs.h rs32.c rs32asm.s rs32.h 108 | @HAVE_X86ASM_FALSE@am_rsbep_OBJECTS = rsbep-rsbep.$(OBJEXT) \ 109 | @HAVE_X86ASM_FALSE@ rsbep-rs.$(OBJEXT) 110 | @HAVE_X86ASM_TRUE@am_rsbep_OBJECTS = rsbep-rsbep.$(OBJEXT) \ 111 | @HAVE_X86ASM_TRUE@ rsbep-rs32.$(OBJEXT) rs32asm.$(OBJEXT) 112 | rsbep_OBJECTS = $(am_rsbep_OBJECTS) 113 | rsbep_LDADD = $(LDADD) 114 | rsbep_LINK = $(CCLD) $(rsbep_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ 115 | $(LDFLAGS) -o $@ 116 | rsbep_chopper_SOURCES = rsbep_chopper.c 117 | rsbep_chopper_OBJECTS = rsbep_chopper.$(OBJEXT) 118 | rsbep_chopper_LDADD = $(LDADD) 119 | AM_V_P = $(am__v_P_@AM_V@) 120 | am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) 121 | am__v_P_0 = false 122 | am__v_P_1 = : 123 | AM_V_GEN = $(am__v_GEN_@AM_V@) 124 | am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) 125 | am__v_GEN_0 = @echo " GEN " $@; 126 | am__v_GEN_1 = 127 | AM_V_at = $(am__v_at_@AM_V@) 128 | am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) 129 | am__v_at_0 = @ 130 | am__v_at_1 = 131 | DEFAULT_INCLUDES = -I.@am__isrc@ 132 | depcomp = $(SHELL) $(top_srcdir)/build-aux/depcomp 133 | am__maybe_remake_depfiles = depfiles 134 | am__depfiles_remade = ./$(DEPDIR)/rsbep-rs.Po \ 135 | ./$(DEPDIR)/rsbep-rs32.Po ./$(DEPDIR)/rsbep-rsbep.Po \ 136 | ./$(DEPDIR)/rsbep_chopper.Po 137 | am__mv = mv -f 138 | AM_V_lt = $(am__v_lt_@AM_V@) 139 | am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 140 | am__v_lt_0 = --silent 141 | am__v_lt_1 = 142 | COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 143 | $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 144 | AM_V_CC = $(am__v_CC_@AM_V@) 145 | am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) 146 | am__v_CC_0 = @echo " CC " $@; 147 | am__v_CC_1 = 148 | CCLD = $(CC) 149 | LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 150 | AM_V_CCLD = $(am__v_CCLD_@AM_V@) 151 | am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) 152 | am__v_CCLD_0 = @echo " CCLD " $@; 153 | am__v_CCLD_1 = 154 | CCASCOMPILE = $(CCAS) $(AM_CCASFLAGS) $(CCASFLAGS) 155 | AM_V_CCAS = $(am__v_CCAS_@AM_V@) 156 | am__v_CCAS_ = $(am__v_CCAS_@AM_DEFAULT_V@) 157 | am__v_CCAS_0 = @echo " CCAS " $@; 158 | am__v_CCAS_1 = 159 | SOURCES = $(rsbep_SOURCES) rsbep_chopper.c 160 | DIST_SOURCES = $(am__rsbep_SOURCES_DIST) rsbep_chopper.c 161 | am__can_run_installinfo = \ 162 | case $$AM_UPDATE_INFO_DIR in \ 163 | n|no|NO) false;; \ 164 | *) (install-info --version) >/dev/null 2>&1;; \ 165 | esac 166 | am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) 167 | # Read a list of newline-separated strings from the standard input, 168 | # and print each of them once, without duplicates. Input order is 169 | # *not* preserved. 170 | am__uniquify_input = $(AWK) '\ 171 | BEGIN { nonempty = 0; } \ 172 | { items[$$0] = 1; nonempty = 1; } \ 173 | END { if (nonempty) { for (i in items) print i; }; } \ 174 | ' 175 | # Make sure the list of sources is unique. This is necessary because, 176 | # e.g., the same source file might be shared among _SOURCES variables 177 | # for different programs/libraries. 178 | am__define_uniq_tagged_files = \ 179 | list='$(am__tagged_files)'; \ 180 | unique=`for i in $$list; do \ 181 | if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ 182 | done | $(am__uniquify_input)` 183 | ETAGS = etags 184 | CTAGS = ctags 185 | am__DIST_COMMON = $(srcdir)/Makefile.in \ 186 | $(top_srcdir)/build-aux/depcomp 187 | DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) 188 | ACLOCAL = @ACLOCAL@ 189 | AMTAR = @AMTAR@ 190 | AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 191 | AUTOCONF = @AUTOCONF@ 192 | AUTOHEADER = @AUTOHEADER@ 193 | AUTOMAKE = @AUTOMAKE@ 194 | AWK = @AWK@ 195 | CC = @CC@ 196 | CCAS = @CCAS@ 197 | CCASDEPMODE = @CCASDEPMODE@ 198 | CCASFLAGS = @CCASFLAGS@ 199 | CCDEPMODE = @CCDEPMODE@ 200 | CFLAGS = @CFLAGS@ 201 | CPP = @CPP@ 202 | CPPFLAGS = @CPPFLAGS@ 203 | CYGPATH_W = @CYGPATH_W@ 204 | DEFS = @DEFS@ 205 | DEPDIR = @DEPDIR@ 206 | ECHO_C = @ECHO_C@ 207 | ECHO_N = @ECHO_N@ 208 | ECHO_T = @ECHO_T@ 209 | EGREP = @EGREP@ 210 | EXEEXT = @EXEEXT@ 211 | GREP = @GREP@ 212 | INSTALL = @INSTALL@ 213 | INSTALL_DATA = @INSTALL_DATA@ 214 | INSTALL_PROGRAM = @INSTALL_PROGRAM@ 215 | INSTALL_SCRIPT = @INSTALL_SCRIPT@ 216 | INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 217 | LDFLAGS = @LDFLAGS@ 218 | LIBOBJS = @LIBOBJS@ 219 | LIBS = @LIBS@ 220 | LTLIBOBJS = @LTLIBOBJS@ 221 | MAKEINFO = @MAKEINFO@ 222 | MKDIR_P = @MKDIR_P@ 223 | OBJEXT = @OBJEXT@ 224 | PACKAGE = @PACKAGE@ 225 | PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ 226 | PACKAGE_NAME = @PACKAGE_NAME@ 227 | PACKAGE_STRING = @PACKAGE_STRING@ 228 | PACKAGE_TARNAME = @PACKAGE_TARNAME@ 229 | PACKAGE_URL = @PACKAGE_URL@ 230 | PACKAGE_VERSION = @PACKAGE_VERSION@ 231 | PATH_SEPARATOR = @PATH_SEPARATOR@ 232 | SET_MAKE = @SET_MAKE@ 233 | SHELL = @SHELL@ 234 | STRIP = @STRIP@ 235 | VERSION = @VERSION@ 236 | abs_builddir = @abs_builddir@ 237 | abs_srcdir = @abs_srcdir@ 238 | abs_top_builddir = @abs_top_builddir@ 239 | abs_top_srcdir = @abs_top_srcdir@ 240 | ac_ct_CC = @ac_ct_CC@ 241 | am__include = @am__include@ 242 | am__leading_dot = @am__leading_dot@ 243 | am__quote = @am__quote@ 244 | am__tar = @am__tar@ 245 | am__untar = @am__untar@ 246 | bindir = @bindir@ 247 | build = @build@ 248 | build_alias = @build_alias@ 249 | build_cpu = @build_cpu@ 250 | build_os = @build_os@ 251 | build_vendor = @build_vendor@ 252 | builddir = @builddir@ 253 | datadir = @datadir@ 254 | datarootdir = @datarootdir@ 255 | docdir = @docdir@ 256 | dvidir = @dvidir@ 257 | exec_prefix = @exec_prefix@ 258 | host = @host@ 259 | host_alias = @host_alias@ 260 | host_cpu = @host_cpu@ 261 | host_os = @host_os@ 262 | host_vendor = @host_vendor@ 263 | htmldir = @htmldir@ 264 | includedir = @includedir@ 265 | infodir = @infodir@ 266 | install_sh = @install_sh@ 267 | libdir = @libdir@ 268 | libexecdir = @libexecdir@ 269 | localedir = @localedir@ 270 | localstatedir = @localstatedir@ 271 | mandir = @mandir@ 272 | mkdir_p = @mkdir_p@ 273 | oldincludedir = @oldincludedir@ 274 | pdfdir = @pdfdir@ 275 | prefix = @prefix@ 276 | program_transform_name = @program_transform_name@ 277 | psdir = @psdir@ 278 | runstatedir = @runstatedir@ 279 | sbindir = @sbindir@ 280 | sharedstatedir = @sharedstatedir@ 281 | srcdir = @srcdir@ 282 | sysconfdir = @sysconfdir@ 283 | target = @target@ 284 | target_alias = @target_alias@ 285 | target_cpu = @target_cpu@ 286 | target_os = @target_os@ 287 | target_vendor = @target_vendor@ 288 | top_build_prefix = @top_build_prefix@ 289 | top_builddir = @top_builddir@ 290 | top_srcdir = @top_srcdir@ 291 | @HAVE_X86ASM_FALSE@rsbep_CFLAGS = 292 | @HAVE_X86ASM_TRUE@rsbep_CFLAGS = -DASM_I386 293 | @HAVE_X86ASM_FALSE@rsbep_SOURCES = rsbep.c rs.c rs.h 294 | @HAVE_X86ASM_TRUE@rsbep_SOURCES = rsbep.c rs32.c rs32asm.s rs32.h 295 | rsbep_chopper = chopper.c 296 | all: all-am 297 | 298 | .SUFFIXES: 299 | .SUFFIXES: .c .o .obj .s 300 | $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) 301 | @for dep in $?; do \ 302 | case '$(am__configure_deps)' in \ 303 | *$$dep*) \ 304 | ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ 305 | && { if test -f $@; then exit 0; else break; fi; }; \ 306 | exit 1;; \ 307 | esac; \ 308 | done; \ 309 | echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/Makefile'; \ 310 | $(am__cd) $(top_srcdir) && \ 311 | $(AUTOMAKE) --gnu src/Makefile 312 | Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status 313 | @case '$?' in \ 314 | *config.status*) \ 315 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ 316 | *) \ 317 | echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ 318 | cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ 319 | esac; 320 | 321 | $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) 322 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 323 | 324 | $(top_srcdir)/configure: $(am__configure_deps) 325 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 326 | $(ACLOCAL_M4): $(am__aclocal_m4_deps) 327 | cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh 328 | $(am__aclocal_m4_deps): 329 | install-binPROGRAMS: $(bin_PROGRAMS) 330 | @$(NORMAL_INSTALL) 331 | @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ 332 | if test -n "$$list"; then \ 333 | echo " $(MKDIR_P) '$(DESTDIR)$(bindir)'"; \ 334 | $(MKDIR_P) "$(DESTDIR)$(bindir)" || exit 1; \ 335 | fi; \ 336 | for p in $$list; do echo "$$p $$p"; done | \ 337 | sed 's/$(EXEEXT)$$//' | \ 338 | while read p p1; do if test -f $$p \ 339 | ; then echo "$$p"; echo "$$p"; else :; fi; \ 340 | done | \ 341 | sed -e 'p;s,.*/,,;n;h' \ 342 | -e 's|.*|.|' \ 343 | -e 'p;x;s,.*/,,;s/$(EXEEXT)$$//;$(transform);s/$$/$(EXEEXT)/' | \ 344 | sed 'N;N;N;s,\n, ,g' | \ 345 | $(AWK) 'BEGIN { files["."] = ""; dirs["."] = 1 } \ 346 | { d=$$3; if (dirs[d] != 1) { print "d", d; dirs[d] = 1 } \ 347 | if ($$2 == $$4) files[d] = files[d] " " $$1; \ 348 | else { print "f", $$3 "/" $$4, $$1; } } \ 349 | END { for (d in files) print "f", d, files[d] }' | \ 350 | while read type dir files; do \ 351 | if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ 352 | test -z "$$files" || { \ 353 | echo " $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(bindir)$$dir'"; \ 354 | $(INSTALL_PROGRAM_ENV) $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(bindir)$$dir" || exit $$?; \ 355 | } \ 356 | ; done 357 | 358 | uninstall-binPROGRAMS: 359 | @$(NORMAL_UNINSTALL) 360 | @list='$(bin_PROGRAMS)'; test -n "$(bindir)" || list=; \ 361 | files=`for p in $$list; do echo "$$p"; done | \ 362 | sed -e 'h;s,^.*/,,;s/$(EXEEXT)$$//;$(transform)' \ 363 | -e 's/$$/$(EXEEXT)/' \ 364 | `; \ 365 | test -n "$$list" || exit 0; \ 366 | echo " ( cd '$(DESTDIR)$(bindir)' && rm -f" $$files ")"; \ 367 | cd "$(DESTDIR)$(bindir)" && rm -f $$files 368 | 369 | clean-binPROGRAMS: 370 | -test -z "$(bin_PROGRAMS)" || rm -f $(bin_PROGRAMS) 371 | 372 | rsbep$(EXEEXT): $(rsbep_OBJECTS) $(rsbep_DEPENDENCIES) $(EXTRA_rsbep_DEPENDENCIES) 373 | @rm -f rsbep$(EXEEXT) 374 | $(AM_V_CCLD)$(rsbep_LINK) $(rsbep_OBJECTS) $(rsbep_LDADD) $(LIBS) 375 | 376 | rsbep_chopper$(EXEEXT): $(rsbep_chopper_OBJECTS) $(rsbep_chopper_DEPENDENCIES) $(EXTRA_rsbep_chopper_DEPENDENCIES) 377 | @rm -f rsbep_chopper$(EXEEXT) 378 | $(AM_V_CCLD)$(LINK) $(rsbep_chopper_OBJECTS) $(rsbep_chopper_LDADD) $(LIBS) 379 | 380 | mostlyclean-compile: 381 | -rm -f *.$(OBJEXT) 382 | 383 | distclean-compile: 384 | -rm -f *.tab.c 385 | 386 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsbep-rs.Po@am__quote@ # am--include-marker 387 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsbep-rs32.Po@am__quote@ # am--include-marker 388 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsbep-rsbep.Po@am__quote@ # am--include-marker 389 | @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rsbep_chopper.Po@am__quote@ # am--include-marker 390 | 391 | $(am__depfiles_remade): 392 | @$(MKDIR_P) $(@D) 393 | @echo '# dummy' >$@-t && $(am__mv) $@-t $@ 394 | 395 | am--depfiles: $(am__depfiles_remade) 396 | 397 | .c.o: 398 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< 399 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 400 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 401 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 402 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< 403 | 404 | .c.obj: 405 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` 406 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po 407 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ 408 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 409 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 410 | 411 | rsbep-rsbep.o: rsbep.c 412 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -MT rsbep-rsbep.o -MD -MP -MF $(DEPDIR)/rsbep-rsbep.Tpo -c -o rsbep-rsbep.o `test -f 'rsbep.c' || echo '$(srcdir)/'`rsbep.c 413 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsbep-rsbep.Tpo $(DEPDIR)/rsbep-rsbep.Po 414 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rsbep.c' object='rsbep-rsbep.o' libtool=no @AMDEPBACKSLASH@ 415 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 416 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -c -o rsbep-rsbep.o `test -f 'rsbep.c' || echo '$(srcdir)/'`rsbep.c 417 | 418 | rsbep-rsbep.obj: rsbep.c 419 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -MT rsbep-rsbep.obj -MD -MP -MF $(DEPDIR)/rsbep-rsbep.Tpo -c -o rsbep-rsbep.obj `if test -f 'rsbep.c'; then $(CYGPATH_W) 'rsbep.c'; else $(CYGPATH_W) '$(srcdir)/rsbep.c'; fi` 420 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsbep-rsbep.Tpo $(DEPDIR)/rsbep-rsbep.Po 421 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rsbep.c' object='rsbep-rsbep.obj' libtool=no @AMDEPBACKSLASH@ 422 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 423 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -c -o rsbep-rsbep.obj `if test -f 'rsbep.c'; then $(CYGPATH_W) 'rsbep.c'; else $(CYGPATH_W) '$(srcdir)/rsbep.c'; fi` 424 | 425 | rsbep-rs.o: rs.c 426 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -MT rsbep-rs.o -MD -MP -MF $(DEPDIR)/rsbep-rs.Tpo -c -o rsbep-rs.o `test -f 'rs.c' || echo '$(srcdir)/'`rs.c 427 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsbep-rs.Tpo $(DEPDIR)/rsbep-rs.Po 428 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rs.c' object='rsbep-rs.o' libtool=no @AMDEPBACKSLASH@ 429 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 430 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -c -o rsbep-rs.o `test -f 'rs.c' || echo '$(srcdir)/'`rs.c 431 | 432 | rsbep-rs.obj: rs.c 433 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -MT rsbep-rs.obj -MD -MP -MF $(DEPDIR)/rsbep-rs.Tpo -c -o rsbep-rs.obj `if test -f 'rs.c'; then $(CYGPATH_W) 'rs.c'; else $(CYGPATH_W) '$(srcdir)/rs.c'; fi` 434 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsbep-rs.Tpo $(DEPDIR)/rsbep-rs.Po 435 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rs.c' object='rsbep-rs.obj' libtool=no @AMDEPBACKSLASH@ 436 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 437 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -c -o rsbep-rs.obj `if test -f 'rs.c'; then $(CYGPATH_W) 'rs.c'; else $(CYGPATH_W) '$(srcdir)/rs.c'; fi` 438 | 439 | rsbep-rs32.o: rs32.c 440 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -MT rsbep-rs32.o -MD -MP -MF $(DEPDIR)/rsbep-rs32.Tpo -c -o rsbep-rs32.o `test -f 'rs32.c' || echo '$(srcdir)/'`rs32.c 441 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsbep-rs32.Tpo $(DEPDIR)/rsbep-rs32.Po 442 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rs32.c' object='rsbep-rs32.o' libtool=no @AMDEPBACKSLASH@ 443 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 444 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -c -o rsbep-rs32.o `test -f 'rs32.c' || echo '$(srcdir)/'`rs32.c 445 | 446 | rsbep-rs32.obj: rs32.c 447 | @am__fastdepCC_TRUE@ $(AM_V_CC)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -MT rsbep-rs32.obj -MD -MP -MF $(DEPDIR)/rsbep-rs32.Tpo -c -o rsbep-rs32.obj `if test -f 'rs32.c'; then $(CYGPATH_W) 'rs32.c'; else $(CYGPATH_W) '$(srcdir)/rs32.c'; fi` 448 | @am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/rsbep-rs32.Tpo $(DEPDIR)/rsbep-rs32.Po 449 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='rs32.c' object='rsbep-rs32.obj' libtool=no @AMDEPBACKSLASH@ 450 | @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 451 | @am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(rsbep_CFLAGS) $(CFLAGS) -c -o rsbep-rs32.obj `if test -f 'rs32.c'; then $(CYGPATH_W) 'rs32.c'; else $(CYGPATH_W) '$(srcdir)/rs32.c'; fi` 452 | 453 | .s.o: 454 | $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ $< 455 | 456 | .s.obj: 457 | $(AM_V_CCAS)$(CCASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 458 | 459 | ID: $(am__tagged_files) 460 | $(am__define_uniq_tagged_files); mkid -fID $$unique 461 | tags: tags-am 462 | TAGS: tags 463 | 464 | tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 465 | set x; \ 466 | here=`pwd`; \ 467 | $(am__define_uniq_tagged_files); \ 468 | shift; \ 469 | if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ 470 | test -n "$$unique" || unique=$$empty_fix; \ 471 | if test $$# -gt 0; then \ 472 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ 473 | "$$@" $$unique; \ 474 | else \ 475 | $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ 476 | $$unique; \ 477 | fi; \ 478 | fi 479 | ctags: ctags-am 480 | 481 | CTAGS: ctags 482 | ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) 483 | $(am__define_uniq_tagged_files); \ 484 | test -z "$(CTAGS_ARGS)$$unique" \ 485 | || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ 486 | $$unique 487 | 488 | GTAGS: 489 | here=`$(am__cd) $(top_builddir) && pwd` \ 490 | && $(am__cd) $(top_srcdir) \ 491 | && gtags -i $(GTAGS_ARGS) "$$here" 492 | cscopelist: cscopelist-am 493 | 494 | cscopelist-am: $(am__tagged_files) 495 | list='$(am__tagged_files)'; \ 496 | case "$(srcdir)" in \ 497 | [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ 498 | *) sdir=$(subdir)/$(srcdir) ;; \ 499 | esac; \ 500 | for i in $$list; do \ 501 | if test -f "$$i"; then \ 502 | echo "$(subdir)/$$i"; \ 503 | else \ 504 | echo "$$sdir/$$i"; \ 505 | fi; \ 506 | done >> $(top_builddir)/cscope.files 507 | 508 | distclean-tags: 509 | -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags 510 | 511 | distdir: $(BUILT_SOURCES) 512 | $(MAKE) $(AM_MAKEFLAGS) distdir-am 513 | 514 | distdir-am: $(DISTFILES) 515 | @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 516 | topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ 517 | list='$(DISTFILES)'; \ 518 | dist_files=`for file in $$list; do echo $$file; done | \ 519 | sed -e "s|^$$srcdirstrip/||;t" \ 520 | -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ 521 | case $$dist_files in \ 522 | */*) $(MKDIR_P) `echo "$$dist_files" | \ 523 | sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ 524 | sort -u` ;; \ 525 | esac; \ 526 | for file in $$dist_files; do \ 527 | if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ 528 | if test -d $$d/$$file; then \ 529 | dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ 530 | if test -d "$(distdir)/$$file"; then \ 531 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 532 | fi; \ 533 | if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ 534 | cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ 535 | find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ 536 | fi; \ 537 | cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ 538 | else \ 539 | test -f "$(distdir)/$$file" \ 540 | || cp -p $$d/$$file "$(distdir)/$$file" \ 541 | || exit 1; \ 542 | fi; \ 543 | done 544 | check-am: all-am 545 | check: check-am 546 | all-am: Makefile $(PROGRAMS) 547 | installdirs: 548 | for dir in "$(DESTDIR)$(bindir)"; do \ 549 | test -z "$$dir" || $(MKDIR_P) "$$dir"; \ 550 | done 551 | install: install-am 552 | install-exec: install-exec-am 553 | install-data: install-data-am 554 | uninstall: uninstall-am 555 | 556 | install-am: all-am 557 | @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am 558 | 559 | installcheck: installcheck-am 560 | install-strip: 561 | if test -z '$(STRIP)'; then \ 562 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 563 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 564 | install; \ 565 | else \ 566 | $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ 567 | install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ 568 | "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ 569 | fi 570 | mostlyclean-generic: 571 | 572 | clean-generic: 573 | 574 | distclean-generic: 575 | -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) 576 | -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) 577 | 578 | maintainer-clean-generic: 579 | @echo "This command is intended for maintainers to use" 580 | @echo "it deletes files that may require special tools to rebuild." 581 | clean: clean-am 582 | 583 | clean-am: clean-binPROGRAMS clean-generic mostlyclean-am 584 | 585 | distclean: distclean-am 586 | -rm -f ./$(DEPDIR)/rsbep-rs.Po 587 | -rm -f ./$(DEPDIR)/rsbep-rs32.Po 588 | -rm -f ./$(DEPDIR)/rsbep-rsbep.Po 589 | -rm -f ./$(DEPDIR)/rsbep_chopper.Po 590 | -rm -f Makefile 591 | distclean-am: clean-am distclean-compile distclean-generic \ 592 | distclean-tags 593 | 594 | dvi: dvi-am 595 | 596 | dvi-am: 597 | 598 | html: html-am 599 | 600 | html-am: 601 | 602 | info: info-am 603 | 604 | info-am: 605 | 606 | install-data-am: 607 | 608 | install-dvi: install-dvi-am 609 | 610 | install-dvi-am: 611 | 612 | install-exec-am: install-binPROGRAMS 613 | 614 | install-html: install-html-am 615 | 616 | install-html-am: 617 | 618 | install-info: install-info-am 619 | 620 | install-info-am: 621 | 622 | install-man: 623 | 624 | install-pdf: install-pdf-am 625 | 626 | install-pdf-am: 627 | 628 | install-ps: install-ps-am 629 | 630 | install-ps-am: 631 | 632 | installcheck-am: 633 | 634 | maintainer-clean: maintainer-clean-am 635 | -rm -f ./$(DEPDIR)/rsbep-rs.Po 636 | -rm -f ./$(DEPDIR)/rsbep-rs32.Po 637 | -rm -f ./$(DEPDIR)/rsbep-rsbep.Po 638 | -rm -f ./$(DEPDIR)/rsbep_chopper.Po 639 | -rm -f Makefile 640 | maintainer-clean-am: distclean-am maintainer-clean-generic 641 | 642 | mostlyclean: mostlyclean-am 643 | 644 | mostlyclean-am: mostlyclean-compile mostlyclean-generic 645 | 646 | pdf: pdf-am 647 | 648 | pdf-am: 649 | 650 | ps: ps-am 651 | 652 | ps-am: 653 | 654 | uninstall-am: uninstall-binPROGRAMS 655 | 656 | .MAKE: install-am install-strip 657 | 658 | .PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ 659 | clean-binPROGRAMS clean-generic cscopelist-am ctags ctags-am \ 660 | distclean distclean-compile distclean-generic distclean-tags \ 661 | distdir dvi dvi-am html html-am info info-am install \ 662 | install-am install-binPROGRAMS install-data install-data-am \ 663 | install-dvi install-dvi-am install-exec install-exec-am \ 664 | install-html install-html-am install-info install-info-am \ 665 | install-man install-pdf install-pdf-am install-ps \ 666 | install-ps-am install-strip installcheck installcheck-am \ 667 | installdirs maintainer-clean maintainer-clean-generic \ 668 | mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ 669 | ps ps-am tags tags-am uninstall uninstall-am \ 670 | uninstall-binPROGRAMS 671 | 672 | .PRECIOUS: Makefile 673 | 674 | 675 | # Tell versions [3.59,3.63) of GNU make to not export all variables. 676 | # Otherwise a system limit (for SysV at least) may be exceeded. 677 | .NOEXPORT: 678 | -------------------------------------------------------------------------------- /src/rs.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Reed-Solomon coding and decoding 3 | * Phil Karn (karn@ka9q.ampr.org) September 1996 4 | * Separate CCSDS version create Dec 1998, merged into this version May 1999 5 | * 6 | * This file is derived from my generic RS encoder/decoder, which is 7 | * in turn based on the program "new_rs_erasures.c" by Robert 8 | * Morelos-Zaragoza (robert@spectra.eng.hawaii.edu) and Hari Thirumoorthy 9 | * (harit@spectra.eng.hawaii.edu), Aug 1995 10 | 11 | * Copyright 1999 Phil Karn, KA9Q 12 | * May be used under the terms of the GNU public license 13 | */ 14 | #include 15 | #include "rs.h" 16 | 17 | #ifdef CCSDS 18 | /* CCSDS field generator polynomial: 1+x+x^2+x^7+x^8 */ 19 | int Pp[MM+1] = { 1, 1, 1, 0, 0, 0, 0, 1, 1 }; 20 | 21 | #else /* not CCSDS */ 22 | /* MM, KK, B0, PRIM are user-defined in rs.h */ 23 | 24 | /* Primitive polynomials - see Lin & Costello, Appendix A, 25 | * and Lee & Messerschmitt, p. 453. 26 | */ 27 | #if(MM == 2)/* Admittedly silly */ 28 | int Pp[MM+1] = { 1, 1, 1 }; 29 | 30 | #elif(MM == 3) 31 | /* 1 + x + x^3 */ 32 | int Pp[MM+1] = { 1, 1, 0, 1 }; 33 | 34 | #elif(MM == 4) 35 | /* 1 + x + x^4 */ 36 | int Pp[MM+1] = { 1, 1, 0, 0, 1 }; 37 | 38 | #elif(MM == 5) 39 | /* 1 + x^2 + x^5 */ 40 | int Pp[MM+1] = { 1, 0, 1, 0, 0, 1 }; 41 | 42 | #elif(MM == 6) 43 | /* 1 + x + x^6 */ 44 | int Pp[MM+1] = { 1, 1, 0, 0, 0, 0, 1 }; 45 | 46 | #elif(MM == 7) 47 | /* 1 + x^3 + x^7 */ 48 | int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 1 }; 49 | 50 | #elif(MM == 8) 51 | /* 1+x^2+x^3+x^4+x^8 */ 52 | int Pp[MM+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 }; 53 | 54 | #elif(MM == 9) 55 | /* 1+x^4+x^9 */ 56 | int Pp[MM+1] = { 1, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; 57 | 58 | #elif(MM == 10) 59 | /* 1+x^3+x^10 */ 60 | int Pp[MM+1] = { 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 }; 61 | 62 | #elif(MM == 11) 63 | /* 1+x^2+x^11 */ 64 | int Pp[MM+1] = { 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 65 | 66 | #elif(MM == 12) 67 | /* 1+x+x^4+x^6+x^12 */ 68 | int Pp[MM+1] = { 1, 1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1 }; 69 | 70 | #elif(MM == 13) 71 | /* 1+x+x^3+x^4+x^13 */ 72 | int Pp[MM+1] = { 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 73 | 74 | #elif(MM == 14) 75 | /* 1+x+x^6+x^10+x^14 */ 76 | int Pp[MM+1] = { 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 }; 77 | 78 | #elif(MM == 15) 79 | /* 1+x+x^15 */ 80 | int Pp[MM+1] = { 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }; 81 | 82 | #elif(MM == 16) 83 | /* 1+x+x^3+x^12+x^16 */ 84 | int Pp[MM+1] = { 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1 }; 85 | 86 | #else 87 | #error "Either CCSDS must be defined, or MM must be set in range 2-16" 88 | #endif 89 | 90 | #endif 91 | 92 | 93 | /* This defines the type used to store an element of the Galois Field 94 | * used by the code. Make sure this is something larger than a char if 95 | * if anything larger than GF(256) is used. 96 | * 97 | * Note: unsigned char will work up to GF(256) but int seems to run 98 | * faster on the Pentium. 99 | */ 100 | typedef int gf; 101 | 102 | /* index->polynomial form conversion table */ 103 | static gf Alpha_to[NN + 1]; 104 | 105 | /* Polynomial->index form conversion table */ 106 | static gf Index_of[NN + 1]; 107 | 108 | /* No legal value in index form represents zero, so 109 | * we need a special value for this purpose 110 | */ 111 | #define A0 (NN) 112 | 113 | /* Generator polynomial g(x) in index form */ 114 | static gf Gg[NN - KK + 1]; 115 | 116 | static int RS_init; /* Initialization flag */ 117 | 118 | /* Compute x % NN, where NN is 2**MM - 1, 119 | * without a slow divide 120 | */ 121 | static inline gf 122 | modnn(int x) 123 | { 124 | while (x >= NN) { 125 | x -= NN; 126 | x = (x >> MM) + (x & NN); 127 | } 128 | return x; 129 | } 130 | 131 | #define min(a,b) ((a) < (b) ? (a) : (b)) 132 | 133 | #define CLEAR(a,n) {\ 134 | int ci;\ 135 | for(ci=(n)-1;ci >=0;ci--)\ 136 | (a)[ci] = 0;\ 137 | } 138 | 139 | #define COPY(a,b,n) {\ 140 | int ci;\ 141 | for(ci=(n)-1;ci >=0;ci--)\ 142 | (a)[ci] = (b)[ci];\ 143 | } 144 | 145 | #define COPYDOWN(a,b,n) {\ 146 | int ci;\ 147 | for(ci=(n)-1;ci >=0;ci--)\ 148 | (a)[ci] = (b)[ci];\ 149 | } 150 | 151 | static void init_rs(void); 152 | 153 | #ifdef CCSDS 154 | /* Conversion lookup tables from conventional alpha to Berlekamp's 155 | * dual-basis representation. Used in the CCSDS version only. 156 | * taltab[] -- convert conventional to dual basis 157 | * tal1tab[] -- convert dual basis to conventional 158 | 159 | * Note: the actual RS encoder/decoder works with the conventional basis. 160 | * So data is converted from dual to conventional basis before either 161 | * encoding or decoding and then converted back. 162 | */ 163 | static unsigned char taltab[NN+1],tal1tab[NN+1]; 164 | 165 | static unsigned char tal[] = { 0x8d, 0xef, 0xec, 0x86, 0xfa, 0x99, 0xaf, 0x7b }; 166 | 167 | /* Generate conversion lookup tables between conventional alpha representation 168 | * (@**7, @**6, ...@**0) 169 | * and Berlekamp's dual basis representation 170 | * (l0, l1, ...l7) 171 | */ 172 | static void 173 | gen_ltab(void) 174 | { 175 | int i,j,k; 176 | 177 | for(i=0;i<256;i++){/* For each value of input */ 178 | taltab[i] = 0; 179 | for(j=0;j<8;j++) /* for each column of matrix */ 180 | for(k=0;k<8;k++){ /* for each row of matrix */ 181 | if(i & (1<polynomial form alpha_to[] contains j=alpha**i; 205 | polynomial form -> index form index_of[j=alpha**i] = i 206 | alpha=2 is the primitive element of GF(2**m) 207 | HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows: 208 | Let @ represent the primitive element commonly called "alpha" that 209 | is the root of the primitive polynomial p(x). Then in GF(2^m), for any 210 | 0 <= i <= 2^m-2, 211 | @^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) 212 | where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation 213 | of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for 214 | example the polynomial representation of @^5 would be given by the binary 215 | representation of the integer "alpha_to[5]". 216 | Similarily, index_of[] can be used as follows: 217 | As above, let @ represent the primitive element of GF(2^m) that is 218 | the root of the primitive polynomial p(x). In order to find the power 219 | of @ (alpha) that has the polynomial representation 220 | a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) 221 | we consider the integer "i" whose binary representation with a(0) being LSB 222 | and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry 223 | "index_of[i]". Now, @^index_of[i] is that element whose polynomial 224 | representation is (a(0),a(1),a(2),...,a(m-1)). 225 | NOTE: 226 | The element alpha_to[2^m-1] = 0 always signifying that the 227 | representation of "@^infinity" = 0 is (0,0,0,...,0). 228 | Similarily, the element index_of[0] = A0 always signifying 229 | that the power of alpha which has the polynomial representation 230 | (0,0,...,0) is "infinity". 231 | 232 | */ 233 | 234 | static void 235 | generate_gf(void) 236 | { 237 | register int i, mask; 238 | 239 | mask = 1; 240 | Alpha_to[MM] = 0; 241 | for (i = 0; i < MM; i++) { 242 | Alpha_to[i] = mask; 243 | Index_of[Alpha_to[i]] = i; 244 | /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */ 245 | if (Pp[i] != 0) 246 | Alpha_to[MM] ^= mask; /* Bit-wise EXOR operation */ 247 | mask <<= 1; /* single left-shift */ 248 | } 249 | Index_of[Alpha_to[MM]] = MM; 250 | /* 251 | * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by 252 | * poly-repr of @^i shifted left one-bit and accounting for any @^MM 253 | * term that may occur when poly-repr of @^i is shifted. 254 | */ 255 | mask >>= 1; 256 | for (i = MM + 1; i < NN; i++) { 257 | if (Alpha_to[i - 1] >= mask) 258 | Alpha_to[i] = Alpha_to[MM] ^ ((Alpha_to[i - 1] ^ mask) << 1); 259 | else 260 | Alpha_to[i] = Alpha_to[i - 1] << 1; 261 | Index_of[Alpha_to[i]] = i; 262 | } 263 | Index_of[0] = A0; 264 | Alpha_to[NN] = 0; 265 | } 266 | 267 | /* 268 | * Obtain the generator polynomial of the TT-error correcting, length 269 | * NN=(2**MM -1) Reed Solomon code from the product of (X+@**(B0+i)), i = 0, 270 | * ... ,(2*TT-1) 271 | * 272 | * Examples: 273 | * 274 | * If B0 = 1, TT = 1. deg(g(x)) = 2*TT = 2. 275 | * g(x) = (x+@) (x+@**2) 276 | * 277 | * If B0 = 0, TT = 2. deg(g(x)) = 2*TT = 4. 278 | * g(x) = (x+1) (x+@) (x+@**2) (x+@**3) 279 | */ 280 | static void 281 | gen_poly(void) 282 | { 283 | register int i, j; 284 | 285 | Gg[0] = 1; 286 | for (i = 0; i < NN - KK; i++) { 287 | Gg[i+1] = 1; 288 | /* 289 | * Below multiply (Gg[0]+Gg[1]*x + ... +Gg[i]x^i) by 290 | * (@**(B0+i)*PRIM + x) 291 | */ 292 | for (j = i; j > 0; j--) 293 | if (Gg[j] != 0) 294 | Gg[j] = Gg[j - 1] ^ Alpha_to[modnn((Index_of[Gg[j]]) + (B0 + i) *PRIM)]; 295 | else 296 | Gg[j] = Gg[j - 1]; 297 | /* Gg[0] can never be zero */ 298 | Gg[0] = Alpha_to[modnn(Index_of[Gg[0]] + (B0 + i) * PRIM)]; 299 | } 300 | /* convert Gg[] to index form for quicker encoding */ 301 | for (i = 0; i <= NN - KK; i++) 302 | Gg[i] = Index_of[Gg[i]]; 303 | } 304 | 305 | 306 | /* 307 | * take the string of symbols in data[i], i=0..(k-1) and encode 308 | * systematically to produce NN-KK parity symbols in bb[0]..bb[NN-KK-1] data[] 309 | * is input and bb[] is output in polynomial form. Encoding is done by using 310 | * a feedback shift register with appropriate connections specified by the 311 | * elements of Gg[], which was generated above. Codeword is c(X) = 312 | * data(X)*X**(NN-KK)+ b(X) 313 | */ 314 | int 315 | encode_rs(dtype data[KK], dtype bb[NN-KK]) 316 | { 317 | register int i, j; 318 | gf feedback; 319 | 320 | #if DEBUG >= 1 && MM != 8 321 | /* Check for illegal input values */ 322 | for(i=0;i NN) 324 | return -1; 325 | #endif 326 | 327 | if(!RS_init) 328 | init_rs(); 329 | 330 | CLEAR(bb,NN-KK); 331 | 332 | #ifdef CCSDS 333 | /* Convert to conventional basis */ 334 | for(i=0;i= 0; i--) { 339 | feedback = Index_of[data[i] ^ bb[NN - KK - 1]]; 340 | if (feedback != A0) { /* feedback term is non-zero */ 341 | for (j = NN - KK - 1; j > 0; j--) 342 | if (Gg[j] != A0) 343 | bb[j] = bb[j - 1] ^ Alpha_to[modnn(Gg[j] + feedback)]; 344 | else 345 | bb[j] = bb[j - 1]; 346 | bb[0] = Alpha_to[modnn(Gg[0] + feedback)]; 347 | } else { /* feedback term is zero. encoder becomes a 348 | * single-byte shifter */ 349 | for (j = NN - KK - 1; j > 0; j--) 350 | bb[j] = bb[j - 1]; 351 | bb[0] = 0; 352 | } 353 | } 354 | #ifdef CCSDS 355 | /* Convert to l-basis */ 356 | for(i=0;i= 1 && MM != 8 403 | /* Check for illegal input values */ 404 | for(i=0;i NN) 406 | return -1; 407 | #endif 408 | /* form the syndromes; i.e., evaluate data(x) at roots of g(x) 409 | * namely @**(B0+i)*PRIM, i = 0, ... ,(NN-KK-1) 410 | */ 411 | for(i=1;i<=NN-KK;i++){ 412 | s[i] = data[0]; 413 | } 414 | for(j=1;j 0) { 441 | /* Init lambda to be the erasure locator polynomial */ 442 | lambda[1] = Alpha_to[modnn(PRIM * eras_pos[0])]; 443 | for (i = 1; i < no_eras; i++) { 444 | u = modnn(PRIM*eras_pos[i]); 445 | for (j = i+1; j > 0; j--) { 446 | tmp = Index_of[lambda[j - 1]]; 447 | if(tmp != A0) 448 | lambda[j] ^= Alpha_to[modnn(u + tmp)]; 449 | } 450 | } 451 | #if DEBUG >= 1 452 | /* Test code that verifies the erasure locator polynomial just constructed 453 | Needed only for decoder debugging. */ 454 | 455 | /* find roots of the erasure location polynomial */ 456 | for(i=1;i<=no_eras;i++) 457 | reg[i] = Index_of[lambda[i]]; 458 | count = 0; 459 | for (i = 1,k=NN-Ldec; i <= NN; i++,k = modnn(NN+k-Ldec)) { 460 | q = 1; 461 | for (j = 1; j <= no_eras; j++) 462 | if (reg[j] != A0) { 463 | reg[j] = modnn(reg[j] + j); 464 | q ^= Alpha_to[reg[j]]; 465 | } 466 | if (q != 0) 467 | continue; 468 | /* store root and error location number indices */ 469 | root[count] = i; 470 | loc[count] = k; 471 | count++; 472 | } 473 | if (count != no_eras) { 474 | printf("\n lambda(x) is WRONG\n"); 475 | count = -1; 476 | goto finish; 477 | } 478 | #if DEBUG >= 2 479 | printf("\n Erasure positions as determined by roots of Eras Loc Poly:\n"); 480 | for (i = 0; i < count; i++) 481 | printf("%d ", loc[i]); 482 | printf("\n"); 483 | #endif 484 | #endif 485 | } 486 | for(i=0;i 0; j--){ 550 | if (reg[j] != A0) { 551 | reg[j] = modnn(reg[j] + j); 552 | q ^= Alpha_to[reg[j]]; 553 | } 554 | } 555 | if (q != 0) 556 | continue; 557 | /* store root (index-form) and error location number */ 558 | root[count] = i; 559 | loc[count] = k; 560 | /* If we've already found max possible roots, 561 | * abort the search to save time 562 | */ 563 | if(++count == deg_lambda) 564 | break; 565 | } 566 | if (deg_lambda != count) { 567 | /* 568 | * deg(lambda) unequal to number of roots => uncorrectable 569 | * error detected 570 | */ 571 | count = -1; 572 | goto finish; 573 | } 574 | /* 575 | * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo 576 | * x**(NN-KK)). in index form. Also find deg(omega). 577 | */ 578 | deg_omega = 0; 579 | for (i = 0; i < NN-KK;i++){ 580 | tmp = 0; 581 | j = (deg_lambda < i) ? deg_lambda : i; 582 | for(;j >= 0; j--){ 583 | if ((s[i + 1 - j] != A0) && (lambda[j] != A0)) 584 | tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])]; 585 | } 586 | if(tmp != 0) 587 | deg_omega = i; 588 | omega[i] = Index_of[tmp]; 589 | } 590 | omega[NN-KK] = A0; 591 | 592 | /* 593 | * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = 594 | * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form 595 | */ 596 | for (j = count-1; j >=0; j--) { 597 | num1 = 0; 598 | for (i = deg_omega; i >= 0; i--) { 599 | if (omega[i] != A0) 600 | num1 ^= Alpha_to[modnn(omega[i] + i * root[j])]; 601 | } 602 | num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)]; 603 | den = 0; 604 | 605 | /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ 606 | for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) { 607 | if(lambda[i+1] != A0) 608 | den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])]; 609 | } 610 | if (den == 0) { 611 | #if DEBUG >= 1 612 | printf("\n ERROR: denominator = 0\n"); 613 | #endif 614 | /* Convert to dual- basis */ 615 | count = -1; 616 | goto finish; 617 | } 618 | /* Apply error to data */ 619 | if (num1 != 0) { 620 | data[loc[j]] ^= Alpha_to[modnn(Index_of[num1] + Index_of[num2] + NN - Index_of[den])]; 621 | } 622 | } 623 | finish: 624 | #ifdef CCSDS 625 | /* Convert to dual- basis */ 626 | for(i=0;i 14 | #include 15 | #include "rs32.h" 16 | 17 | /* Primitive polynomials - see Lin & Costello, Appendix A, 18 | * and Lee & Messerschmitt, p. 453. 19 | */ 20 | 21 | /* 1+x^2+x^3+x^4+x^8 */ 22 | int Pp[MM+1] = { 1, 0, 1, 1, 1, 0, 0, 0, 1 }; 23 | 24 | /* Alpha exponent for the first root of the generator polynomial */ 25 | #define B0 1 26 | 27 | /* index->polynomial form conversion table */ 28 | gf Alpha_to[NN + 1]; 29 | 30 | /* Polynomial->index form conversion table */ 31 | gf Index_of[NN + 1]; 32 | 33 | /* No legal value in index form represents zero, so 34 | * we need a special value for this purpose 35 | */ 36 | #define A0 (NN) 37 | 38 | /* Generator polynomial g(x) 39 | * Degree of g(x) = 2*TT 40 | * has roots @**B0, @**(B0+1), ... ,@^(B0+2*TT-1) 41 | */ 42 | gf Gg[NN - KK + 1]; 43 | 44 | /* Lookup table for multiplying by the 32 generator polynomial terms, 45 | * packed 4 terms to each 32-bit word 46 | */ 47 | unsigned long Gtab[8][256]; 48 | 49 | /* Lookup table for GF multiplication 50 | * Mtab[i][j] = j * alpha^(B0+i) (note limited range of i) 51 | */ 52 | unsigned char Mtab[NN-KK+1][NN+1]; 53 | 54 | /* Compute x % NN, where NN is 2**MM - 1, 55 | * without a slow divide 56 | */ 57 | static inline gf 58 | modnn(int x) 59 | { 60 | while (x >= NN) { 61 | x -= NN; 62 | x = (x >> MM) + (x & NN); 63 | } 64 | return x; 65 | } 66 | 67 | #define min(a,b) ((a) < (b) ? (a) : (b)) 68 | 69 | #define CLEAR(a,n) {\ 70 | int ci;\ 71 | for(ci=(n)-1;ci >=0;ci--)\ 72 | (a)[ci] = 0;\ 73 | } 74 | 75 | #define COPY(a,b,n) {\ 76 | int ci;\ 77 | for(ci=(n)-1;ci >=0;ci--)\ 78 | (a)[ci] = (b)[ci];\ 79 | } 80 | #define COPYDOWN(a,b,n) {\ 81 | int ci;\ 82 | for(ci=(n)-1;ci >=0;ci--)\ 83 | (a)[ci] = (b)[ci];\ 84 | } 85 | 86 | 87 | /* generate GF(2**m) from the irreducible polynomial p(X) in p[0]..p[m] 88 | lookup tables: index->polynomial form alpha_to[] contains j=alpha**i; 89 | polynomial form -> index form index_of[j=alpha**i] = i 90 | alpha=2 is the primitive element of GF(2**m) 91 | HARI's COMMENT: (4/13/94) alpha_to[] can be used as follows: 92 | Let @ represent the primitive element commonly called "alpha" that 93 | is the root of the primitive polynomial p(x). Then in GF(2^m), for any 94 | 0 <= i <= 2^m-2, 95 | @^i = a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) 96 | where the binary vector (a(0),a(1),a(2),...,a(m-1)) is the representation 97 | of the integer "alpha_to[i]" with a(0) being the LSB and a(m-1) the MSB. Thus for 98 | example the polynomial representation of @^5 would be given by the binary 99 | representation of the integer "alpha_to[5]". 100 | Similarily, index_of[] can be used as follows: 101 | As above, let @ represent the primitive element of GF(2^m) that is 102 | the root of the primitive polynomial p(x). In order to find the power 103 | of @ (alpha) that has the polynomial representation 104 | a(0) + a(1) @ + a(2) @^2 + ... + a(m-1) @^(m-1) 105 | we consider the integer "i" whose binary representation with a(0) being LSB 106 | and a(m-1) MSB is (a(0),a(1),...,a(m-1)) and locate the entry 107 | "index_of[i]". Now, @^index_of[i] is that element whose polynomial 108 | representation is (a(0),a(1),a(2),...,a(m-1)). 109 | NOTE: 110 | The element alpha_to[2^m-1] = 0 always signifying that the 111 | representation of "@^infinity" = 0 is (0,0,0,...,0). 112 | Similarily, the element index_of[0] = A0 always signifying 113 | that the power of alpha which has the polynomial representation 114 | (0,0,...,0) is "infinity". 115 | 116 | */ 117 | 118 | static void 119 | generate_gf(void) 120 | { 121 | register int i, mask; 122 | 123 | mask = 1; 124 | Alpha_to[MM] = 0; 125 | for (i = 0; i < MM; i++) { 126 | Alpha_to[i] = mask; 127 | Index_of[Alpha_to[i]] = i; 128 | /* If Pp[i] == 1 then, term @^i occurs in poly-repr of @^MM */ 129 | if (Pp[i] != 0) 130 | Alpha_to[MM] ^= mask; /* Bit-wise EXOR operation */ 131 | mask <<= 1; /* single left-shift */ 132 | } 133 | Index_of[Alpha_to[MM]] = MM; 134 | /* 135 | * Have obtained poly-repr of @^MM. Poly-repr of @^(i+1) is given by 136 | * poly-repr of @^i shifted left one-bit and accounting for any @^MM 137 | * term that may occur when poly-repr of @^i is shifted. 138 | */ 139 | mask >>= 1; 140 | for (i = MM + 1; i < NN; i++) { 141 | if (Alpha_to[i - 1] >= mask) 142 | Alpha_to[i] = Alpha_to[MM] ^ ((Alpha_to[i - 1] ^ mask) << 1); 143 | else 144 | Alpha_to[i] = Alpha_to[i - 1] << 1; 145 | Index_of[Alpha_to[i]] = i; 146 | } 147 | Index_of[0] = A0; 148 | Alpha_to[NN] = 0; 149 | } 150 | 151 | 152 | /* 153 | * Obtain the generator polynomial of the TT-error correcting, length 154 | * NN=(2**MM -1) Reed Solomon code from the product of (X+@**(B0+i)), i = 0, 155 | * ... ,(2*TT-1) 156 | * 157 | * Examples: 158 | * 159 | * If B0 = 1, TT = 1. deg(g(x)) = 2*TT = 2. 160 | * g(x) = (x+@) (x+@**2) 161 | * 162 | * If B0 = 0, TT = 2. deg(g(x)) = 2*TT = 4. 163 | * g(x) = (x+1) (x+@) (x+@**2) (x+@**3) 164 | */ 165 | static void 166 | gen_poly(void) 167 | { 168 | register int i, j; 169 | 170 | Gg[0] = Alpha_to[B0]; 171 | Gg[1] = 1; /* g(x) = (X+@**B0) initially */ 172 | for (i = 2; i <= NN - KK; i++) { 173 | Gg[i] = 1; 174 | /* 175 | * Below multiply (Gg[0]+Gg[1]*x + ... +Gg[i]x^i) by 176 | * (@**(B0+i-1) + x) 177 | */ 178 | for (j = i - 1; j > 0; j--) 179 | if (Gg[j] != 0) 180 | Gg[j] = Gg[j - 1] ^ Alpha_to[modnn((Index_of[Gg[j]]) + B0 + i - 1)]; 181 | else 182 | Gg[j] = Gg[j - 1]; 183 | /* Gg[0] can never be zero */ 184 | Gg[0] = Alpha_to[modnn((Index_of[Gg[0]]) + B0 + i - 1)]; 185 | } 186 | /* convert Gg[] to index form for quicker encoding */ 187 | for (i = 0; i <= NN - KK; i++) 188 | Gg[i] = Index_of[Gg[i]]; 189 | } 190 | 191 | 192 | /* Generate lookup table for fast encoding 193 | * Each table entry contains four packed result per 32-bit word 194 | */ 195 | static void 196 | gen_gtab(void) 197 | { 198 | int i,ii,j,k,val; 199 | 200 | memset(Gtab,0,sizeof(Gtab)); 201 | for(i=1;i<256;i++){ 202 | ii = Index_of[i]; 203 | for(j=0;j<8;j++){ 204 | for(k=3;k>=0;k--){ 205 | val = (Gg[4*j+k] == A0) ? 0 : Alpha_to[modnn(ii+Gg[4*j+k])]; 206 | Gtab[j][i] = (Gtab[j][i] << 8) | val; 207 | } 208 | } 209 | } 210 | } 211 | 212 | /* Generate lookup table for fast syndrome computation in the decoder 213 | * Given a field element x in polynomial form, the table generated here 214 | * when indexed as Mtab[i][x] gives x * alpha**(B0+i) 215 | */ 216 | static void 217 | gen_mtab(void) 218 | { 219 | int i,j; 220 | 221 | for(i=0;i=0;i--) 255 | for(j=0;j<32;j++) 256 | st[j] = data[i] ^ Mtab[j][st[j]]; 257 | #else 258 | extern void rssyndrome(dtype dt[NN], unsigned char uc[NN-KK]); 259 | rssyndrome(data,st); 260 | #endif 261 | /* Convert syndromes to index form, checking for nonzero condition */ 262 | syn_error = 0; 263 | for(i=0;i 0) { 300 | /* Init lambda to be the erasure locator polynomial */ 301 | lambda[1] = Alpha_to[eras_pos[0]]; 302 | for (i = 1; i < no_eras; i++) { 303 | u = eras_pos[i]; 304 | for (j = i+1; j > 0; j--) { 305 | tmp = Index_of[lambda[j - 1]]; 306 | if(tmp != A0) 307 | lambda[j] ^= Alpha_to[modnn(u + tmp)]; 308 | } 309 | } 310 | } 311 | for(i=0;i 0; j--) 375 | if (reg[j] != A0) { 376 | reg[j] = modnn(reg[j] + j); 377 | q ^= Alpha_to[reg[j]]; 378 | } 379 | if (!q) { 380 | /* store root (index-form) and error location number */ 381 | root[count++] = i; 382 | if(count == deg_lambda) 383 | /* Found all possible roots, no point in continuing */ 384 | break; 385 | } 386 | } 387 | 388 | #ifdef DEBUG 389 | printf("\n Final error positions:\t"); 390 | for (i = 0; i < count; i++) 391 | printf("%d ", NN - root[i]); 392 | printf("\n"); 393 | #endif 394 | if (deg_lambda != count) { 395 | /* 396 | * deg(lambda) unequal to number of roots => uncorrectable 397 | * error detected 398 | */ 399 | return -1; 400 | } 401 | /* 402 | * Compute err+eras evaluator poly omega(x) = s(x)*lambda(x) (modulo 403 | * x**(NN-KK)). in index form. Also find deg(omega). 404 | */ 405 | deg_omega = 0; 406 | for (i = 0; i < NN-KK;i++){ 407 | tmp = 0; 408 | j = (deg_lambda < i) ? deg_lambda : i; 409 | for(;j >= 0; j--){ 410 | if ((s[i + 1 - j] != A0) && (lambda[j] != A0)) 411 | tmp ^= Alpha_to[modnn(s[i + 1 - j] + lambda[j])]; 412 | } 413 | if(tmp != 0) 414 | deg_omega = i; 415 | omega[i] = Index_of[tmp]; 416 | } 417 | omega[NN-KK] = A0; 418 | 419 | /* 420 | * Compute error values in poly-form. num1 = omega(inv(X(l))), num2 = 421 | * inv(X(l))**(B0-1) and den = lambda_pr(inv(X(l))) all in poly-form 422 | */ 423 | for (j = count-1; j >=0; j--) { 424 | num1 = 0; 425 | for (i = deg_omega; i >= 0; i--) { 426 | if (omega[i] != A0) 427 | num1 ^= Alpha_to[modnn(omega[i] + i * root[j])]; 428 | } 429 | num2 = Alpha_to[modnn(root[j] * (B0 - 1) + NN)]; 430 | den = 0; 431 | 432 | /* lambda[i+1] for i even is the formal derivative lambda_pr of lambda[i] */ 433 | for (i = min(deg_lambda,NN-KK-1) & ~1; i >= 0; i -=2) { 434 | if(lambda[i+1] != A0) 435 | den ^= Alpha_to[modnn(lambda[i+1] + i * root[j])]; 436 | } 437 | if (den == 0) { 438 | #ifdef DEBUG 439 | printf("\n ERROR: denominator = 0\n"); 440 | #endif 441 | return -1; 442 | } 443 | /* Apply error to data */ 444 | if (num1 != 0) { 445 | data[NN - root[j]] ^= Alpha_to[modnn(Index_of[num1] + Index_of[num2] + NN - Index_of[den])]; 446 | } 447 | } 448 | return count; 449 | } 450 | -------------------------------------------------------------------------------- /src/rs32.h: -------------------------------------------------------------------------------- 1 | /* Global definitions for Reed-Solomon encoder/decoder 2 | * Phil Karn KA9Q, August 1997 3 | * 4 | * The parameters MM and KK specify the Reed-Solomon code parameters. 5 | * 6 | * Set MM to be the size of each code symbol in bits. The Reed-Solomon 7 | * block size will then be NN = 2**M - 1 symbols. Supported values are 8 | * defined in rs.c. 9 | * 10 | * Set KK to be the number of data symbols in each block, which must be 11 | * less than the block size. The code will then be able to correct up 12 | * to NN-KK erasures or (NN-KK)/2 errors, or combinations thereof with 13 | * each error counting as two erasures. 14 | */ 15 | 16 | #ifndef __RS32_H__ 17 | #define __RS32_H__ 18 | 19 | #define MM 8 /* RS code over GF(256) */ 20 | #define KK 223 /* KK = number of information symbols */ 21 | 22 | #define NN ((1 << MM) - 1) 23 | 24 | #if (MM <= 8) 25 | typedef unsigned char dtype; 26 | #else 27 | typedef unsigned int dtype; 28 | #endif 29 | 30 | /* This defines the type used to store an element of the Galois Field 31 | * used by the code. Make sure this is something larger than a char if 32 | * if anything larger than GF(256) is used. 33 | * 34 | * Note: unsigned char will work up to GF(256) but int seems to run 35 | * faster on the Pentium. 36 | */ 37 | typedef int gf; 38 | 39 | /* Initialization function */ 40 | void init_rs(void); 41 | 42 | /* Reed-Solomon encoding 43 | * data[] is the input block, parity symbols are placed in bb[] 44 | * bb[] may lie past the end of the data, e.g., for (255,223): 45 | * encode_rs(&data[0],&data[223]); 46 | */ 47 | int rs32e(dtype data[KK], dtype bb[NN-KK]); 48 | 49 | /* Reed-Solomon erasures-and-errors decoding 50 | * The received block goes into data[], and a list of zero-origin 51 | * erasure positions, if any, goes in eras_pos[] with a count in no_eras. 52 | * 53 | * The decoder corrects the symbols in place, if possible and returns 54 | * the number of corrected symbols. If the codeword is illegal or 55 | * uncorrectible, the data array is unchanged and -1 is returned 56 | */ 57 | int rs32d(dtype data[NN], int eras_pos[], int no_eras); 58 | int rsd32(dtype data[NN], int eras_pos[NN-KK], int no_eras); 59 | #ifdef ASM_I386 60 | int rse32(dtype data[KK], dtype bb[NN-KK]); 61 | #endif 62 | 63 | #endif 64 | -------------------------------------------------------------------------------- /src/rs32asm.s: -------------------------------------------------------------------------------- 1 | /* Assemble this file with "gasp -a rsasm.s | as -o rsasm.o" */ 2 | 3 | /* Fast encoder for (255,223) Reed-Solomon code over GF(256) */ 4 | 5 | /* Called as */ 6 | /* rse32(unsigned char data[223],unsigned char parity[32]); */ 7 | 8 | /* This code started as output of gcc -S, then was heavily hand */ 9 | /* massaged to exploit the Pentium dual pipeline */ 10 | 11 | /* Runs at about 30 megabits/sec on a 133 MHz Pentium */ 12 | 13 | /* Phil Karn, KA9Q July 5, 1997 */ 14 | .comm Gtab,8192,4 15 | 16 | .globl rse32 17 | .type rse32,@function 18 | rse32: 19 | pushl %ebp 20 | movl %esp,%ebp 21 | subl $32,%esp 22 | pushl %edi 23 | pushl %esi 24 | pushl %ebx 25 | movl 8(%ebp),%ebx /* -> data */ 26 | movl 12(%ebp),%esi /* -> output parity bytes */ 27 | 28 | /* init parity bytes to zeroes */ 29 | movl $7,%eax 30 | .L75: movl $0,-32(%ebp,%eax,4) 31 | decl %eax 32 | jns .L75 33 | 34 | movl $222,%edi /* number of data bytes */ 35 | .L80: xorl %eax,%eax 36 | movl -4(%ebp),%ecx /* %ecx = (R31,R30,R29,R28) */ 37 | movb (%edi,%ebx),%al /* %al = data byte */ 38 | roll $8,%ecx /* %ecx = (R30,R29,R28,R31) */ 39 | movl -8(%ebp),%edx /* %edx = (R27,R26,R25,R24) */ 40 | xorb %cl,%al /* %al = R31 ^ data (feedback term) */ 41 | 42 | shll $8,%edx /* %edx = (R26,R25,R24,0) */ 43 | movb -5(%ebp),%cl /* %ecx = (R30,R29,R28,R27) */ 44 | movb -9(%ebp),%dl /* %edx = (R26,R25,R24,R23) */ 45 | xorl Gtab+7168(,%eax,4),%ecx /* %ecx = (R31',R30',R29',R28') */ 46 | xorl Gtab+6144(,%eax,4),%edx /* %edx = (R27',R26',R25',R24') */ 47 | movl %ecx,-4(%ebp) 48 | movl %edx,-8(%ebp) 49 | 50 | movl -12(%ebp),%ecx /* %ecx = (R23,R22,R21,R20) */ 51 | movl -16(%ebp),%edx /* %edx = (R19,R18,R17,R16) */ 52 | shll $8,%ecx /* %ecx = (R22,R21,R20,0) */ 53 | shll $8,%edx /* %edx = (R18,R17,R16,0) */ 54 | movb -13(%ebp),%cl /* %ecx = (R22,R21,R20,R19) */ 55 | movb -17(%ebp),%dl /* %edx = (R18,R17,R16,R15) */ 56 | xorl Gtab+5120(,%eax,4),%ecx 57 | xorl Gtab+4096(,%eax,4),%edx 58 | movl %ecx,-12(%ebp) 59 | movl %edx,-16(%ebp) 60 | 61 | movl -20(%ebp),%ecx /* %ecx = (R15,R14,R13,R12) */ 62 | movl -24(%ebp),%edx /* %edx = (R11,R10,R09,R08) */ 63 | shll $8,%ecx /* %ecx = (R14,R13,R12,0) */ 64 | shll $8,%edx /* %edx = (R10,R09,R08,0) */ 65 | movb -21(%ebp),%cl /* %ecx = (R14,R13,R12,R11) */ 66 | movb -25(%ebp),%dl /* %edx = (R10,R09,R08,R07) */ 67 | xorl Gtab+3072(,%eax,4),%ecx 68 | xorl Gtab+2048(,%eax,4),%edx 69 | movl %ecx,-20(%ebp) 70 | movl %edx,-24(%ebp) 71 | 72 | movl -28(%ebp),%ecx /* %ecx = (R07,R06,R05,R04) */ 73 | movl -32(%ebp),%edx /* %edx = (R03,R02,R01,R00) */ 74 | shll $8,%ecx /* %ecx = (R06,R05,R04,0) */ 75 | shll $8,%edx /* %edx = (R02,R01,R00,0) */ 76 | movb -29(%ebp),%cl /* %ecx = (R06,R05,R04,R03) */ 77 | xorl Gtab(,%eax,4),%edx 78 | xorl Gtab+1024(,%eax,4),%ecx 79 | movl %edx,-32(%ebp) 80 | movl %ecx,-28(%ebp) 81 | 82 | decl %edi 83 | jns .L80 84 | 85 | /* Copy parity bytes to user buffer */ 86 | movl $7,%edx 87 | .L85: movl -32(%ebp,%edx,4),%eax 88 | movl %eax,(%esi,%edx,4) 89 | decl %edx 90 | jns .L85 91 | 92 | xorl %eax,%eax /* return 0 */ 93 | leal -44(%ebp),%esp 94 | popl %ebx 95 | popl %esi 96 | popl %edi 97 | movl %ebp,%esp 98 | popl %ebp 99 | ret 100 | 101 | 102 | /* This macro evaluates the input polynomial (which has 255 elements) */ 103 | /* at four consecutive values of alpha**n and stores the results */ 104 | /* The instructions are ordered to avoid address generation interlocks */ 105 | /* and to encourage parallel execution in the Pentium's two pipelines */ 106 | 107 | /* Input: %esi -> input buffer, 12(%ebp) -> output buffer */ 108 | /* Uses char Mtab[32][256], a multiplication lookup table */ 109 | /* trashes eax, ebx, ecx, edx, edi */ 110 | 111 | .MACRO DOSYN R 112 | xorl %eax,%eax 113 | xorl %ebx,%ebx 114 | xorl %ecx,%ecx 115 | xorl %edx,%edx 116 | 117 | movl $254,%edi 118 | loop\@: movb Mtab+256*(\R+0)(%eax),%al 119 | movb (%edi,%esi),%ah 120 | movb Mtab+256*(\R+1)(%ebx),%bl 121 | movb Mtab+256*(\R+2)(%ecx),%cl 122 | movb Mtab+256*(\R+3)(%edx),%dl 123 | xorb %ah,%al 124 | xorb %ah,%bl 125 | xorb %ah,%cl 126 | xorb %ah,%dl 127 | xorb %ah,%ah 128 | decl %edi 129 | jns loop\@ 130 | movl 12(%ebp),%edi 131 | movb %al,\R(%edi) 132 | movb %bl,\R+1(%edi) 133 | movb %cl,\R+2(%edi) 134 | movb %dl,\R+3(%edi) 135 | .ENDM 136 | 137 | .comm Mtab,8192,1 138 | .text 139 | .globl rssyndrome 140 | .type rssyndrome,@function 141 | rssyndrome: 142 | pushl %ebp 143 | movl %esp,%ebp 144 | pushl %edi 145 | pushl %esi 146 | pushl %ebx 147 | movl 8(%ebp),%esi 148 | 149 | DOSYN 0 150 | DOSYN 4 151 | DOSYN 8 152 | DOSYN 12 153 | DOSYN 16 154 | DOSYN 20 155 | DOSYN 24 156 | DOSYN 28 157 | 158 | popl %ebx 159 | popl %esi 160 | popl %edi 161 | popl %ebp 162 | ret 163 | .END 164 | 165 | 166 | 167 | 168 | -------------------------------------------------------------------------------- /src/rsbep.c: -------------------------------------------------------------------------------- 1 | /*************************************************************************** 2 | rsbep.c - Reed-Solomon & Burst Error Protection 3 | ------------------- 4 | begin : Mon Jul 30 20:27:09 MEST 2001 5 | copyright : (C) 2000 by Guido Fiala 6 | email : gfiala@s.netic.de 7 | ***************************************************************************/ 8 | 9 | /*************************************************************************** 10 | Slightly modified by ttsiodras at removethis gmail dot com 11 | 12 | It doesn't write the 3 parameters of rsbep as a single line before the 13 | data, as this makes the stream fragile (if this information is lost, 14 | decoding fails) 15 | 16 | It uses a default value of 16*255=4080 for parameter D, and it can thus 17 | tolerate 4080*16=65280 consecutive bytes to be lost anywhere in the 18 | stream, and still recover... 19 | ***************************************************************************/ 20 | 21 | /*************************************************************************** 22 | * * 23 | * This program is free software; you can redistribute it and/or modify * 24 | * it under the terms of the GNU General Public License as published by * 25 | * the Free Software Foundation; either version 2 of the License, or * 26 | * (at your option) any later version. * 27 | * * 28 | ***************************************************************************/ 29 | 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | 37 | #ifdef ASM_I386 38 | // the hardcoded i386-asm version only for RS(255,223) 39 | #include "rs32.h" 40 | #else 41 | // plain & slow C version (can also be used for anything different from RS(255,223)) 42 | #include "rs.h" 43 | #define rse32 encode_rs 44 | #define rsd32 eras_dec_rs 45 | #endif 46 | 47 | #define ERR_BURST_LEN (255*16) // default number of blocks: 4080 48 | #define RS_BSIZE 255 // default encoded block size 49 | #define RS_DSIZE 223 // default input block size 50 | #define RSBEP_VERSION "0.0.9" 51 | #define RSBEP_HDR "rsbep" 52 | 53 | union long_byte_union { 54 | long long i; 55 | char b[8]; 56 | }; 57 | 58 | //this function is used to copy src to dst while separating consecutive bytes 59 | //equally distributed over the entire array, it tries to utilize several 60 | //cpu-pipes and as high as possible memory efficiency without using asm. 61 | //(but not several CPU's...anyway -it's only 15% of CPU-time, most is RS) 62 | 63 | // 2010-06-13: Re-written by ttsiod, the old version had memory access errors 64 | inline void distribute(dtype * src, dtype * dst, int rows, int cols, 65 | int reverse) 66 | { 67 | int totalBytes = rows * cols; 68 | int boundary = totalBytes; 69 | int offset = 0; 70 | 71 | if (!reverse) { 72 | while (totalBytes--) { 73 | dst[offset] = *src++; 74 | offset += 4080; 75 | if (offset >= boundary) 76 | offset -= (boundary - 1); 77 | } 78 | } else { 79 | while (totalBytes--) { 80 | *dst++ = src[offset]; 81 | offset += 4080; 82 | if (offset >= boundary) 83 | offset -= (boundary - 1); 84 | } 85 | } 86 | } 87 | 88 | //decode buffer and write to stdout 89 | inline void decode_and_write(char *ec_buf, int rs_bsize, int bep_size, 90 | int rs_dsize, long *sum_of_failures, 91 | long *uncorrectable_failures, char *argv, 92 | int quiet, int verbose) 93 | { 94 | register int i; 95 | int eras_pos[32]; //may once hold positions of erasures... 96 | for (i = 0; i < bep_size; i++) { 97 | int failure = rsd32((unsigned char *)(ec_buf + i * rs_bsize), eras_pos, 0); 98 | if (failure > 0) { 99 | *sum_of_failures += failure; 100 | if (!quiet && verbose) 101 | fprintf(stderr, 102 | "%s: errors corrected: %ld uncorrectable blocks: %ld\r", 103 | argv, *sum_of_failures, *uncorrectable_failures); 104 | } else if (failure == -1) { 105 | (void)*uncorrectable_failures++; 106 | if (!quiet && verbose) 107 | fprintf(stderr, 108 | "%s: errors corrected: %ld uncorrectable blocks: %ld\r", 109 | argv, *sum_of_failures, *uncorrectable_failures); 110 | } 111 | if (rs_dsize != fwrite((ec_buf + i * rs_bsize), sizeof(dtype), rs_dsize, stdout)) { //write decoded data 112 | //perror("serious problem: "); 113 | exit(-1); 114 | } 115 | } 116 | } 117 | 118 | // main-program: reads commandline args and does everything else... 119 | 120 | int main(int argc, char *argv[]) 121 | { 122 | dtype *ec_buf = NULL; // pointer to encoding/decoding buffer 123 | dtype *tr_buf = NULL; // pointer to transmit-buffer (fread/fwrite) 124 | long verbose = 0, decode = 0, quiet = 0, temp = 0, override = 0; 125 | long rs_bsize = 0, rs_dsize = 0, bep_size = 0; 126 | long i = 0; 127 | long sum_of_failures = 0; 128 | long uncorrectable_failures = 0; 129 | extern char *optarg; 130 | 131 | assert(sizeof(dtype) == 1); //anything works only with bytes 132 | 133 | while ((i = getopt(argc, argv, "dvqB:D:R:")) != EOF) { 134 | switch (i) { 135 | case 'd': 136 | decode = 1; 137 | break; 138 | case 'v': /* Be quite verbose */ 139 | verbose = 1; 140 | break; 141 | case 'q': /* Be strictly quiet */ 142 | quiet = 1; 143 | break; 144 | case 'B': /* take rs_bsize */ 145 | temp = atoi(optarg); 146 | if ((temp <= 255) && (temp >= 32)) { 147 | rs_bsize = temp; 148 | override = 1; 149 | } else { 150 | fprintf(stderr, 151 | "%s: illegal RS-block size (32..255), bailing.\n", 152 | argv[0]); 153 | exit(-1); 154 | } 155 | break; 156 | case 'D': /* take rs_dsize */ 157 | temp = atoi(optarg); 158 | if ((temp <= rs_bsize - 2) && (temp >= rs_bsize - 32)) { 159 | rs_dsize = temp; 160 | override = 1; 161 | } else { 162 | fprintf(stderr, 163 | "%s: illegal RS-data size (RS-block-2..-32), bailing.\n", 164 | argv[0]); 165 | exit(-1); 166 | } 167 | break; 168 | case 'R': /* take bep_size */ 169 | temp = atoi(optarg); 170 | if ((temp > rs_bsize) && (temp <= 65535)) //just a sane limit 171 | { 172 | bep_size = temp; 173 | override = 1; 174 | } else { 175 | fprintf(stderr, 176 | "%s: illegal error burst len (has to be >=RS-block size, <65535), bailing.\n", 177 | argv[0]); 178 | exit(-1); 179 | } 180 | break; 181 | default: 182 | printf("rsbep version %s\n", RSBEP_VERSION); 183 | printf("usage: %s [-d] [-v] [-q] [-B x -D y -R z ]\nd=decode," 184 | "v=verbose, q=quiet\nOverride-Settings with:\n" 185 | "x=Reed-Solomon Blocksize, " 186 | "y=Reed-Solomon-Datasize, z=ERR_BURST_LEN\n" 187 | "(defaults to 255,223,765)\n", argv[0]); 188 | exit(1); 189 | } 190 | } 191 | #ifdef ASM_I386 192 | init_rs(); //Initialisiere RS(255)-GF(256) 193 | #else 194 | //c-Version initialises itself... 195 | #endif 196 | if (decode) { 197 | if (!override) { 198 | rs_bsize = RS_BSIZE; 199 | rs_dsize = RS_DSIZE; 200 | bep_size = ERR_BURST_LEN; 201 | } 202 | ec_buf = malloc(rs_bsize * bep_size * sizeof(dtype)); 203 | tr_buf = malloc(rs_bsize * bep_size * sizeof(dtype)); 204 | if (ec_buf == NULL || tr_buf == NULL) { 205 | fprintf(stderr, "%s: out of memory, bailing.\n", argv[0]); 206 | exit(-1); 207 | } 208 | //go on: 209 | while (!feof(stdin)) { 210 | long got = fread(tr_buf, 1, bep_size * rs_bsize, stdin); //read the encoded data 211 | if (!got) 212 | break; 213 | if (got < (bep_size * rs_bsize)) { 214 | bzero((tr_buf + got), (bep_size * rs_bsize) - got); //zero remaining data - should never happen! 215 | } 216 | 217 | distribute(tr_buf, ec_buf, bep_size, rs_bsize, 1); 218 | decode_and_write((char *)ec_buf, rs_bsize, bep_size, rs_dsize, 219 | &sum_of_failures, &uncorrectable_failures, 220 | argv[0], quiet, verbose); 221 | } 222 | if ((sum_of_failures > 0 || uncorrectable_failures > 0 || verbose) 223 | && !quiet) { 224 | fprintf(stderr, "\n%s: number of corrected failures : %ld\n", 225 | argv[0], sum_of_failures); 226 | fprintf(stderr, "%s: number of uncorrectable blocks : %ld\n", 227 | argv[0], uncorrectable_failures); 228 | } 229 | } else { //encode 230 | if (!override) { 231 | rs_bsize = RS_BSIZE; 232 | rs_dsize = RS_DSIZE; 233 | bep_size = ERR_BURST_LEN; 234 | } 235 | //get the buffers we need (here we know how large): 236 | ec_buf = malloc(rs_bsize * bep_size * sizeof(dtype)); 237 | tr_buf = malloc(rs_bsize * bep_size * sizeof(dtype)); 238 | if (ec_buf == NULL || tr_buf == NULL) { 239 | fprintf(stderr, "%s: out of memory, bailing.\n", argv[0]); 240 | exit(-1); 241 | } 242 | //no go on with data 243 | while (!feof(stdin)) { 244 | //now encode and write the block: 245 | for (i = 0; i < bep_size; i++) { 246 | long got = 247 | fread((ec_buf + i * rs_bsize), 1, rs_dsize, stdin); 248 | if (got < rs_dsize) { 249 | bzero((ec_buf + i * rs_bsize + got), rs_dsize - got); //zero remaining data 250 | } 251 | //encode rs_dsize bytes of data, append Parity in row 252 | rse32((ec_buf + i * rs_bsize), 253 | (ec_buf + i * rs_bsize + rs_dsize)); 254 | } 255 | distribute(ec_buf, tr_buf, bep_size, rs_bsize, 0); 256 | if (bep_size * rs_bsize != fwrite(tr_buf, sizeof(dtype), bep_size * rs_bsize, stdout)) { //write the encoded data 257 | perror("serious problem: "); 258 | if (ec_buf) 259 | free(ec_buf); 260 | if (tr_buf) 261 | free(tr_buf); 262 | exit(-1); 263 | } 264 | } 265 | } 266 | //clean up: 267 | if (ec_buf) 268 | free(ec_buf); 269 | if (tr_buf) 270 | free(tr_buf); 271 | return 0; 272 | } 273 | -------------------------------------------------------------------------------- /src/rsbep_chopper.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static char buf[131072]; 6 | 7 | int main(int argc, char *argv[]) 8 | { 9 | if (argc != 2) { 10 | fprintf(stderr, "Usage: %s size\n\twill read size bytes from stdin " 11 | "and print them on stdout\n", argv[0]); 12 | exit(1); 13 | } 14 | long long total = atoll(argv[1]); 15 | if (total) { 16 | long long sofar = 0; 17 | while(sofar