├── .cvsignore ├── Arc521.doc ├── Arcinfo ├── COPYING ├── Changelog ├── LICENSE ├── Makefile ├── PATCHLEVEL ├── Readme ├── Sysvarcstuf ├── arc.1 ├── arc.c ├── arc.h ├── arcadd.c ├── arccode.c ├── arccvt.c ├── arcdata.c ├── arcdel.c ├── arcdos.c ├── arcext.c ├── arcio.c ├── arclst.c ├── arclzw.c ├── arcmatch.c ├── arcmisc.c ├── arcpack.c ├── arcrun.c ├── arcs.h ├── arcsq.c ├── arcsvc.c ├── arctst.c ├── arcunp.c ├── arcusq.c ├── marc.1 ├── marc.c ├── proto.h └── tmclock.c /.cvsignore: -------------------------------------------------------------------------------- 1 | arc 2 | marc 3 | arc-*tar.gz 4 | *.o 5 | -------------------------------------------------------------------------------- /Arcinfo: -------------------------------------------------------------------------------- 1 | 2 | ARC-FILE.INF, created by Keith Petersen, W8SDZ, 21-Sep-86, extracted 3 | from UNARC.INF by Robert A. Freed. 4 | 5 | From: Robert A. Freed 6 | Subject: Technical Information for ARC files 7 | Date: June 24, 1986 8 | 9 | Note: In the following discussion, UNARC refers to my CP/M-80 program 10 | for extracting files from MSDOS ARCs. The definitions of the ARC file 11 | format are based on MSDOS ARC512.EXE. 12 | 13 | ARCHIVE FILE FORMAT 14 | ------------------- 15 | 16 | Component files are stored sequentially within an archive. Each entry 17 | is preceded by a 29-byte header, which contains the directory 18 | information. There is no wasted space between entries. (This is in 19 | contrast to the centralized directory used by Novosielski libraries. 20 | Although random access to subfiles within an archive can be noticeably 21 | slower than with libraries, archives do have the advantage of not 22 | requiring pre-allocation of directory space.) 23 | 24 | Archive entries are normally maintained in sorted name order. The 25 | format of the 29-byte archive header is as follows: 26 | 27 | Byte 1: 1A Hex. 28 | This marks the start of an archive header. If this byte is not found 29 | when expected, UNARC will scan forward in the file (up to 64K bytes) 30 | in an attempt to find it (followed by a valid compression version). 31 | If a valid header is found in this manner, a warning message is 32 | issued and archive file processing continues. Otherwise, the file is 33 | assumed to be an invalid archive and processing is aborted. (This is 34 | compatible with MS-DOS ARC version 5.12). Note that a special 35 | exception is made at the beginning of an archive file, to accomodate 36 | "self-unpacking" archives (see below). 37 | 38 | Byte 2: Compression version, as follows: 39 | 40 | 0 = end of file marker (remaining bytes not present) 41 | 1 = unpacked (obsolete) 42 | 2 = unpacked 43 | 3 = packed 44 | 4 = squeezed (after packing) 45 | 5 = crunched (obsolete) 46 | 6 = crunched (after packing) (obsolete) 47 | 7 = crunched (after packing, using faster hash algorithm) (obsolete) 48 | 8 = crunched (after packing, using dynamic LZW variations) 49 | 50 | Bytes 3-15: ASCII file name, nul-terminated. 51 | 52 | (All of the following numeric values are stored low-byte first.) 53 | 54 | Bytes 16-19: Compressed file size in bytes. 55 | 56 | Bytes 20-21: File date, in 16-bit MS-DOS format: 57 | Bits 15:9 = year - 1980 58 | Bits 8:5 = month of year 59 | Bits 4:0 = day of month 60 | (All zero means no date.) 61 | 62 | Bytes 22-23: File time, in 16-bit MS-DOS format: 63 | Bits 15:11 = hour (24-hour clock) 64 | Bits 10:5 = minute 65 | Bits 4:0 = second/2 (not displayed by UNARC) 66 | 67 | Bytes 24-25: Cyclic redundancy check (CRC) value (see below). 68 | 69 | Bytes 26-29: Original (uncompressed) file length in bytes. 70 | (This field is not present for version 1 entries, byte 2 = 1. 71 | I.e., in this case the header is only 25 bytes long. Because 72 | version 1 files are uncompressed, the value normally found in 73 | this field may be obtained from bytes 16-19.) 74 | 75 | 76 | SELF-UNPACKING ARCHIVES 77 | ----------------------- 78 | 79 | A "self-unpacking" archive is one which can be renamed to a .COM file 80 | and executed as a program. An example of such a file is the MS-DOS 81 | program ARC512.COM, which is a standard archive file preceded by a 82 | three-byte jump instruction. The first entry in this file is a simple 83 | "bootstrap" program in uncompressed form, which loads the subfile 84 | ARC.EXE (also uncompressed) into memory and passes control to it. In 85 | anticipation of a similar scheme for future distribution of UNARC, the 86 | program permits up to three bytes to precede the first header in an 87 | archive file (with no error message). 88 | 89 | 90 | CRC COMPUTATION 91 | --------------- 92 | 93 | Archive files use a 16-bit cyclic redundancy check (CRC) for error 94 | control. The particular CRC polynomial used is x^16 + x^15 + x^2 + 1, 95 | which is commonly known as "CRC-16" and is used in many data 96 | transmission protocols (e.g. DEC DDCMP and IBM BSC), as well as by 97 | most floppy disk controllers. Note that this differs from the CCITT 98 | polynomial (x^16 + x^12 + x^5 + 1), which is used by the XMODEM-CRC 99 | protocol and the public domain CHEK program (although these do not 100 | adhere strictly to the CCITT standard). The MS-DOS ARC program does 101 | perform a mathematically sound and accurate CRC calculation. (We 102 | mention this because it contrasts with some unfortunately popular 103 | public domain programs we have witnessed, which from time immemorial 104 | have based their calculation on an obscure magazine article which 105 | contained a typographical error!) 106 | 107 | Additional note (while we are on the subject of CRC's): The validity 108 | of using a 16-bit CRC for checking an entire file is somewhat 109 | questionable. Many people quote the statistics related to these 110 | functions (e.g. "all two-bit errors, all single burst errors of 16 or 111 | fewer bits, 99.997% of all single 17-bit burst errors, etc."), without 112 | realizing that these claims are valid only if the total number of bits 113 | checked is less than 32767 (which is why they are used in small-packet 114 | data transmission protocols). I.e., for file sizes in excess of about 115 | 4K bytes, a 16-bit CRC is not really as good as what is often claimed. 116 | This is not to say that it is bad, but there are more reliable methods 117 | available (e.g. the 32-bit AUTODIN-II polynomial). (End of lecture!) 118 | 119 | Bob Freed 120 | 62 Miller Road 121 | Newton Centre, MA 02159 122 | Telephone (617) 332-3533 123 | 124 | 125 | -------------------------------------------------------------------------------- /COPYING: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. 5 | 59 Temple Place, Suite 330, Boston, MA 02111-1307 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 | Unreleased changes: 2 | 3 | Klaus Reimer , 01 Jan 2011: 4 | * Corrected spelling error in arc man page. 5 | * Version in binaries now comes from VERSION variable in Makefile. 6 | * Changed man page sections from 1L to 1. 7 | 8 | 9 | CHANGES IN VERSION 5.21p 10 | (Klaus Reimer , 07 Aug 2010) 11 | 12 | Replaced mktemp with mkstemp. 13 | Set correct version number and updated creation date in command-line help. 14 | Corrected content of PATCHLEVEL file. 15 | Added man page for marc. 16 | Added install make target. 17 | Added -Wall compiler flag. 18 | 19 | 20 | CHANGES IN VERSION 5.21o 21 | (Howard Chu , 12 Oct 2005) 22 | 23 | Silence warnings about unused results. 24 | 25 | 26 | CHANGES IN VERSION 5.21n 27 | (Howard Chu , 08 Oct 2005) 28 | 29 | Better fix for temporary file creations, previous patch did not fix marc. 30 | Silence all gcc-4.0.0 -Wall warnings. 31 | 32 | 33 | CHANGES IN VERSION 5.21m 34 | (Klaus Reimer , 21 Sep 2005) 35 | 36 | Applied patch from Joey Schulze fixing the following problems: 37 | 38 | - Fixed insecure permissions of a temporary file [arcsvc.c, CAN-2005-2945] 39 | - Fixed insecure temporary file creation [arcsvc.c, CAN-2005-2992] 40 | 41 | 42 | 43 | CHANGES IN VERSION 5.21l 44 | (Klaus Reimer , 13 Mar 2005) 45 | 46 | Fixed warnings because missing inclusion of string.h and fixed a gcc-4.0 47 | problem with marc.c (Missing declaration of makefnam). 48 | 49 | 50 | 51 | CHANGES IN VERSION 5.21k 52 | (Klaus Reimer , 6 Nov 2004) 53 | 54 | Ulf Harnhammar found some buffer overflows causing segfaults and provided a 55 | patch which is now applied to arc to close these bugs. 56 | 57 | 58 | 59 | CHANGES IN VERSION 5.21 60 | 61 | 62 | The following changes have been made in ARC version 5.21, but have not 63 | yet been included in the manual: 64 | 65 | o When adding files to an archive, ARC now shows the stowage facter 66 | achieved on each file. 67 | 68 | o A bug was found that would keep an archive entry from being 69 | encrypted if it was stored without compression. This has now been 70 | fixed. 71 | 72 | o If changes are made to a corrupted archive, the corrupted entries 73 | are discarded. This makes it possible to lose data accidentally. 74 | ARC will now only make changes to a corrupted archive if the W 75 | (suppress Warnings) option has been given. 76 | 77 | o The N (suppress Notes) option now suppresses the "Creating 78 | archive" note when a new archive is being created. 79 | 80 | o The N (suppress Notes) option formerly did nothing useful when 81 | used with the L (List files) command. It now causes a terse 82 | listing of filenames only, suitable for use with pipes and 83 | redirection. 84 | 85 | o The list of filenames given to ARC may now include indirect 86 | references. If a filename begins with an "at sign" ("@"), it is 87 | taken to be the name of a file which contains a list of file 88 | names. The list of file names may include further indirection. 89 | If no extension is given, ".CMD" is assumed. For example, the 90 | command: 91 | 92 | arc a waste junk.txt @trash 93 | 94 | would cause ARC to add JUNK.TXT plus all files listed in the file 95 | TRASH.CMD to an archive named WASTE.ARC. If no file is specified, 96 | then the list is read from standard input. For example, the 97 | command: 98 | 99 | arc ln waste | arc a trash @ 100 | 101 | would cause ARC to add files to TRASH.ARC based on the names of 102 | the files stored in WASTE.ARC. It is probably a good idea to give 103 | the O (Overwrite) option if you are extracting files this way. 104 | 105 | Version 5.21 of MARC also allows for indirection. 106 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | On 15 Sep 2003 Thom Henderson, the original author of arc, agreed to put 2 | arc under a free license. On 7 Oct 2003 Howard Chu, the maintainer of the 3 | unix version of arc decided to put it under the GNU General Public License 4 | (See COPYING for license details). -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # $Header: /cvsroot/arc/arc/Makefile,v 1.9 2011/01/01 13:02:30 k_reimer Exp $ 2 | # Makefile for portable ARC 3 | # 4 | # Originals from Dan Lanciani, James Turner, and others... 5 | # This Makefile supports Atari ST and all Unix versions. 6 | 7 | # The installation prefix 8 | PREFIX = /usr/local 9 | 10 | # This version is needed for the dist target 11 | VERSION = 5.21p 12 | # 13 | # I put SRCDIR on a real disk on the ST, but copy the makefile to a 14 | # RAMdisk and compile from there. Makes things go a bit quicker... 15 | # This has to be done in the shell, to get the trailing backslash 16 | # specified correctly. e.g., setenv SRCDIR='d:\src\arc\' 17 | SRCDIR = 18 | 19 | HEADER = $(SRCDIR)arc.h $(SRCDIR)arcs.h 20 | 21 | # Add a ".TTP" suffix to the executable files on an ST. 22 | #PROG = .ttp 23 | PROG = 24 | 25 | # SYSTEM defines your operating system: 26 | # MSDOS for IBM PCs or other MSDOS machines 27 | # GEMDOS for Atari ST (Predefined by MWC, so you don't need to define it.) 28 | # BSD for Berkeley Unix 29 | # SYSV for AT&T System V Unix or GNU/Linux 30 | # (_MTS for Michigan Terminal System, which requires a different makefile) 31 | # (_MTS also requires one of USEGFINFO or USECATSCAN for directory search) 32 | # NEEDMEMSET if your C library does not have the memset() routine and/or 33 | # your system include doesn't have (Most current systems don't 34 | # need this.) 35 | # NEED_TIMEVAL if you need struct timeval defined. 36 | # NEED_ALPHASORT if your C library doesn't provide it. 37 | # 38 | # On Solaris, use -DSYSV=1 -DNEED_ALPHASORT and set SYSVOBJ=scandir.o 39 | # (See the Sysvarcstuf shar file) 40 | #SYSTEM = -DGEMDOS=1 -fstrength-reduce -fomit-frame-pointer -finline-functions -fdefer-pop -mpcrel 41 | #SYSTEM = -DBSD=1 42 | SYSTEM = -DSYSV=1 43 | 44 | OPT = -O -Wall 45 | # For MWC 3.0 on the Atari ST, use: 46 | #CFLAGS = -VCOMPAC -VPEEP 47 | CFLAGS = $(OPT) $(SYSTEM) -DVERSION=\"$(VERSION)\" 48 | 49 | # GNU's gcc is very nice, if you've got it. Otherwise just cc. 50 | #CC = cgcc -mshort -mbaserel 51 | CC = cc 52 | 53 | # tmclock is only needed on Unix systems... 54 | TMCLOCK = tmclock.o 55 | 56 | # Integer-only stdio routines for Atari ST. 57 | #LIBS=-liio16 58 | 59 | # Files needed for System V 60 | #SYSVOBJ = getwd.o rename.o scandir.o utimes.o 61 | SYSVOBJ = 62 | 63 | OBJS = arc.o arcadd.o arccode.o arccvt.o arcdata.o arcdel.o arcdos.o \ 64 | arcext.o arcio.o arclst.o arclzw.o arcmatch.o arcpack.o arcrun.o \ 65 | arcsq.o arcsvc.o arctst.o arcunp.o arcusq.o arcmisc.o $(SYSVOBJ) 66 | 67 | MOBJ = marc.o arcdata.o arcdos.o arcio.o arcmatch.o arcmisc.o $(SYSVOBJ) 68 | 69 | all: arc$(PROG) marc$(PROG) 70 | 71 | arc$(PROG): $(OBJS) $(TMCLOCK) 72 | $(CC) $(OPT) -o arc$(PROG) $(OBJS) $(TMCLOCK) $(LIBS) 73 | 74 | marc$(PROG): $(MOBJ) $(TMCLOCK) 75 | $(CC) $(OPT) -o marc$(PROG) $(MOBJ) $(TMCLOCK) $(LIBS) 76 | 77 | clean: 78 | rm -f *.o arc$(PROG) marc$(PROG) 79 | 80 | arc.o: $(SRCDIR)arc.c $(HEADER) 81 | $(CC) $(CFLAGS) -c $(SRCDIR)arc.c 82 | marc.o: $(SRCDIR)marc.c $(HEADER) 83 | $(CC) $(CFLAGS) -c $(SRCDIR)marc.c 84 | arcadd.o: $(SRCDIR)arcadd.c $(HEADER) 85 | $(CC) $(CFLAGS) -c $(SRCDIR)arcadd.c 86 | arccode.o: $(SRCDIR)arccode.c $(HEADER) 87 | $(CC) $(CFLAGS) -c $(SRCDIR)arccode.c 88 | arccvt.o: $(SRCDIR)arccvt.c $(HEADER) 89 | $(CC) $(CFLAGS) -c $(SRCDIR)arccvt.c 90 | arcdata.o: $(SRCDIR)arcdata.c $(HEADER) 91 | $(CC) $(CFLAGS) -c $(SRCDIR)arcdata.c 92 | arcdel.o: $(SRCDIR)arcdel.c $(HEADER) 93 | $(CC) $(CFLAGS) -c $(SRCDIR)arcdel.c 94 | arcdir.o: $(SRCDIR)arcdir.c $(HEADER) 95 | $(CC) $(CFLAGS) -c $(SRCDIR)arcdir.c 96 | arcdos.o: $(SRCDIR)arcdos.c $(HEADER) 97 | $(CC) $(CFLAGS) -c $(SRCDIR)arcdos.c 98 | arcext.o: $(SRCDIR)arcext.c $(HEADER) 99 | $(CC) $(CFLAGS) -c $(SRCDIR)arcext.c 100 | arcio.o: $(SRCDIR)arcio.c $(HEADER) 101 | $(CC) $(CFLAGS) -c $(SRCDIR)arcio.c 102 | arclst.o: $(SRCDIR)arclst.c $(HEADER) 103 | $(CC) $(CFLAGS) -c $(SRCDIR)arclst.c 104 | arclzw.o: $(SRCDIR)arclzw.c $(HEADER) 105 | $(CC) $(CFLAGS) -c $(SRCDIR)arclzw.c 106 | arcmatch.o: $(SRCDIR)arcmatch.c $(HEADER) 107 | $(CC) $(CFLAGS) -c $(SRCDIR)arcmatch.c 108 | arcmisc.o: $(SRCDIR)arcmisc.c $(HEADER) 109 | $(CC) $(CFLAGS) -c $(SRCDIR)arcmisc.c 110 | arcpack.o: $(SRCDIR)arcpack.c $(HEADER) 111 | $(CC) $(CFLAGS) -c $(SRCDIR)arcpack.c 112 | arcrun.o: $(SRCDIR)arcrun.c $(HEADER) 113 | $(CC) $(CFLAGS) -c $(SRCDIR)arcrun.c 114 | arcsq.o: $(SRCDIR)arcsq.c $(HEADER) 115 | $(CC) $(CFLAGS) -c $(SRCDIR)arcsq.c 116 | arcsvc.o: $(SRCDIR)arcsvc.c $(HEADER) 117 | $(CC) $(CFLAGS) -c $(SRCDIR)arcsvc.c 118 | arctst.o: $(SRCDIR)arctst.c $(HEADER) 119 | $(CC) $(CFLAGS) -c $(SRCDIR)arctst.c 120 | arcunp.o: $(SRCDIR)arcunp.c $(HEADER) 121 | $(CC) $(CFLAGS) -c $(SRCDIR)arcunp.c 122 | arcusq.o: $(SRCDIR)arcusq.c $(HEADER) 123 | $(CC) $(CFLAGS) -c $(SRCDIR)arcusq.c 124 | 125 | tmclock.o: $(SRCDIR)tmclock.c 126 | $(CC) $(CFLAGS) -c $(SRCDIR)tmclock.c 127 | 128 | dist: clean 129 | mkdir -p .dist/arc-$(VERSION) 130 | cp -rf * .dist/arc-$(VERSION) 131 | rm -rf .dist/arc-$(VERSION)/CVS .dist/arc-$(VERSION)/*.tar.gz 132 | cd .dist; tar cfz ../arc-$(VERSION).tar.gz arc-$(VERSION) 133 | rm -rf .dist 134 | 135 | install: all 136 | install -s -m 0755 -D arc $(DESTDIR)$(PREFIX)/bin/arc 137 | install -s -m 0755 -D marc $(DESTDIR)$(PREFIX)/bin/marc 138 | install -m 0644 -D arc.1 $(DESTDIR)$(PREFIX)/share/man/man1/arc.1 139 | install -m 0644 -D marc.1 $(DESTDIR)$(PREFIX)/share/man/man1/marc.1 140 | -------------------------------------------------------------------------------- /PATCHLEVEL: -------------------------------------------------------------------------------- 1 | 16 2 | -------------------------------------------------------------------------------- /Readme: -------------------------------------------------------------------------------- 1 | Notes for ARC 5.21e October 31, 1991 2 | 3 | ARC 5.21 for Unix is currently at patch level 6. The code provided 4 | here has been used on 4.3 BSD based Unix systems and on the Atari ST. (The 5 | GNU C compiler, version 1.40, was used to make the ST version. It should 6 | still compile with Mark Williams C, but I haven't bothered to try it.) The 7 | current version is over twice as fast as previous releases, for all file 8 | compression and decompression operations. It also fixes longstanding bugs 9 | in the squash code and in the tmclock DST code. 10 | 11 | The Arcinfo file describes the ARC 5.xx directory format. The 6.xx 12 | format contains additional information that is not supported here. 13 | 14 | System V support in the shar file Sysvarcstuf was provided by Jon 15 | Zeeff, Janet Walz, and Rich Salz. You will probably also need the dirent 16 | directory library written by Doug Gwyn; this can be obtained from uunet or 17 | many other comp.sources.unix archive sites. 18 | 19 | The tmclock.c file was stolen from Jef Poskanzer's tws library, 20 | as distributed in PHOON, PHase of the mOON, and slightly hacked by me. 21 | 22 | The man page was originally from Leo Wilson, with updates by me. 23 | 24 | / Howard Chu 25 | ___ /_ , ,_. Jet Propulsion Laboratory 26 | / /(_/(__ hyc@hanauma.jpl.nasa.gov 27 | / 28 | 29 | Notes for ARC 5.21 June 6, 1988 30 | 31 | This program is based on the MSDOS ARC program, version 5.21, plus 32 | a few enhancements... 33 | 34 | o ARC also performs Huffman Squeezing on data. The Huffman Squeeze 35 | algorithm was removed from MSDOS ARC after version 5.12. It turns 36 | out to be more efficient than Lempel-Ziv style compression when 37 | compressing graphic images. Squeeze analysis is always done now, 38 | and the best of packing, squeezing, or crunching is used. 39 | 40 | o Compresses and extracts Squashed files. "Squashing" was created 41 | by Phil Katz in his PKxxx series of ARC utility programs for 42 | MSDOS. Dan Lanciani wrote the original modifications to ARC's 43 | Crunch code to handle Squashing. I've made minor changes since 44 | then, mostly to reduce the amount of memory required. The 'q' 45 | option flag must be specified to Squash files. The Squashing 46 | algorithm will be used instead of the usual Crunch algorithm, 47 | and will be compared against packing and squeezing, as before. 48 | 49 | System specific notes: 50 | 51 | On MTS, an additional option flag, 'i' for "image mode," was 52 | used. ARC assumes files are text, by default, and will translate 53 | MTS files from EBCDIC to ASCII before storing in an archive, and 54 | translates from ASCII to EBCDIC upon extraction. Specifying the 55 | 'i' flag will inhibit this translation. This would most commonly 56 | be used when shipping binary images such as TeX DVI files, other 57 | .ARC files stored within an archive, etc... The 'r' (run) command 58 | is omitted. It just doesn't seem very useful. Also, ARC cannot 59 | restore MTS files with their original time stamps. (Maybe in a 60 | future release...) 61 | 62 | On Unix(tm) systems, the 'i' flag is also present. Unix ARC 63 | assumes a binary file, by default. Here the only translation 64 | involved is in end-of-line processing. When storing text files, ARC will 65 | change '\n' to '\r\n', and does the opposite when extracting files. 66 | Carriage returns in any other location are preserved when extracting. 67 | This translation only occurs if the 'i' flag is given. 68 | 69 | On the Atari ST, the 'h' (for "hold screen") option is present, 70 | which simply delays exiting the program. This is typically used when 71 | executing ARC from the desktop, to allow reading all of ARC's output 72 | before the screen is cleared and the desktop is redrawn. The program 73 | will prompt and wait for a keypress before exiting. Note that since 74 | there are no "options" for the MARC program, the "hold screen" option 75 | is always active for MARC. 76 | 77 | On both Unix and Atari systems, ARC & MARC will search for an 78 | environment variable named "ARCTEMP" or "TMPDIR." If present, any 79 | temporary files will be created in the specified directory. This is 80 | probably insignificant for Unix users, but can be handy on the Atari, 81 | in combination with a RAMdisk. Highly recommended for floppy users. 82 | (Unfortunately, you can only take advantage of this when running some 83 | form of command shell that allows setting environment variables. Thus, 84 | you won't see any speed gains when running from the desktop.) 85 | 86 | That about covers things. The enclosed documentation is taken directly 87 | from the MSDOS distribution of ARC. Unless specified differently here, 88 | the programs behave indentically. Note that ARC521.DOC is identical to 89 | ARC520.DOC - the differences between the two versions are described in 90 | the file CHANGES.521. 91 | 92 | Oh yeah - this program may be distributed freely so long as you don't 93 | modify it in any way. You may not charge for distributing it. (Don't 94 | feel bad, I can't charge for it either. }-) It'd be nice if you kept 95 | this and the other enclosed doc files with it when distributing, but 96 | I'm not going to make a fuss about it. Most people are so familiar 97 | with the program by now that it wouldn't matter much anyway. You 98 | should keep this README file around, so bug reports & such will find 99 | their way back to me. (Bugs? What bugs? Nah, there aren't any bugs...) 100 | 101 | / Howard Chu 102 | ___ /_ , ,_. University of Michigan 103 | / /(_/(__ hyc@umix.cc.umich.edu 104 | / umix!hyc 105 | ' 106 | -------------------------------------------------------------------------------- /Sysvarcstuf: -------------------------------------------------------------------------------- 1 | #--------------------------------CUT HERE------------------------------------- 2 | #! /bin/sh 3 | # 4 | # This is a shell archive. Save this into a file, edit it 5 | # and delete all lines above this comment. Then give this 6 | # file to sh by executing the command "sh file". The files 7 | # will be extracted into the current directory owned by 8 | # you with default permissions. 9 | # 10 | # The files contained herein are: 11 | # 12 | # -rw-r--r-- 1 hyc 539 Jul 22 16:30 README 13 | # -rw-r--r-- 1 hyc 787 Jul 22 15:10 getwd.c 14 | # -rw-r--r-- 1 hyc 280 Jul 22 16:14 rename.c 15 | # -rw-r--r-- 1 hyc 2353 Jul 22 15:55 scandir.3 16 | # -rw-r--r-- 1 hyc 1875 Jul 22 15:55 scandir.c 17 | # -rw-r--r-- 1 hyc 397 Jul 22 15:10 utimes.c 18 | # 19 | echo 'x - README' 20 | if test -f README; then echo 'shar: not overwriting README'; else 21 | sed 's/^X//' << '________This_Is_The_END________' > README 22 | XThe enclosed files should be sufficient for bringing up ARC on a Sys V R3 23 | Xsystem. As Jon mentions, Doug Gwyn's directory routines are needed for 24 | XSys V R2. The enclosed copy of scandir is new, as far as I can tell, and 25 | XI've removed the (unneeded) ftw.? files. Also added a rename() routine, 26 | Xcourtesy of Janet Walz. (And an addition from Rich Salz.) 27 | X 28 | X[see comp.sources.unix, volume 9, for gwyn-dir-lib...] 29 | X 30 | XThanks again to Jon Zeeff, Janet Walz, and Rich Salz for their help. 31 | X -- Howard Chu 32 | X hyc@umix.cc.umich.edu 33 | X {uunet,rutgers}!umix!hyc 34 | ________This_Is_The_END________ 35 | if test `wc -c < README` -ne 539; then 36 | echo 'shar: README was damaged during transit (should have been 539 bytes)' 37 | fi 38 | fi ; : end of overwriting check 39 | echo 'x - getwd.c' 40 | if test -f getwd.c; then echo 'shar: not overwriting getwd.c'; else 41 | sed 's/^X//' << '________This_Is_The_END________' > getwd.c 42 | X/* 43 | X * 4.2bsd getwd simulation for Sys V.3 44 | X */ 45 | X 46 | X#include 47 | X 48 | X#define SYSV3 49 | X 50 | X#define MAXWD 1024 /* limited by 4.2 getwd(2) */ 51 | X 52 | X#ifdef SYSV3 53 | X 54 | Xchar *getcwd(); 55 | X 56 | Xchar * 57 | Xgetwd(path) 58 | Xchar *path; 59 | X{ 60 | X return(getcwd(path,MAXWD)); 61 | X} 62 | X 63 | X#else 64 | X 65 | X/* 66 | X * 4.2bsd getwd simulation for Sys V.2 67 | X */ 68 | X 69 | X#include 70 | X 71 | X#define MAXWD 1024 /* limited by 4.2 getwd(2) */ 72 | X 73 | Xchar * 74 | Xgetwd(path) 75 | Xchar *path; 76 | X{ 77 | X char *nlp; 78 | X FILE *fp; 79 | X FILE *popen(); 80 | X char *strrchr(); 81 | X 82 | X putenv("IFS= \t\n"); 83 | X fp = popen("PATH=/bin:/usr/bin pwd", "r"); 84 | X if (fp == NULL) 85 | X return 0; 86 | X if (fgets(path, MAXWD, fp) == NULL) { 87 | X (void) pclose(fp); 88 | X return 0; 89 | X } 90 | X if ((nlp = strrchr(path, '\n')) != NULL) 91 | X *nlp = '\0'; 92 | X (void) pclose(fp); 93 | X return path; 94 | X} 95 | X#endif 96 | X 97 | ________This_Is_The_END________ 98 | if test `wc -c < getwd.c` -ne 787; then 99 | echo 'shar: getwd.c was damaged during transit (should have been 787 bytes)' 100 | fi 101 | fi ; : end of overwriting check 102 | echo 'x - rename.c' 103 | if test -f rename.c; then echo 'shar: not overwriting rename.c'; else 104 | sed 's/^X//' << '________This_Is_The_END________' > rename.c 105 | X/* 106 | X * substitute for BSD/SVR3 rename() system call, from 107 | X * Janet Walz, walz@mimsy.umd.edu & Rich Salz, rsalz@pineapple.bbn.com 108 | X */ 109 | X 110 | Xint rename(oldname,newname) 111 | Xchar *oldname,*newname; 112 | X{ 113 | X (void)unlink(newname); 114 | X if(link(oldname,newname)) 115 | X return(-1); 116 | X return(unlink(oldname)); 117 | X} 118 | ________This_Is_The_END________ 119 | if test `wc -c < rename.c` -ne 280; then 120 | echo 'shar: rename.c was damaged during transit (should have been 280 bytes)' 121 | fi 122 | fi ; : end of overwriting check 123 | echo 'x - scandir.3' 124 | if test -f scandir.3; then echo 'shar: not overwriting scandir.3'; else 125 | sed 's/^X//' << '________This_Is_The_END________' > scandir.3 126 | X.TH SCANDIR 3 127 | X.\" $Header: /cvsroot/arc/arc/Sysvarcstuf,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 128 | X.SH NAME 129 | Xscandir, alphasort \- scan a directory 130 | X.SH SYNOPSIS 131 | X.nf 132 | X.ft B 133 | X#include 134 | X#include 135 | X 136 | Xint 137 | Xscandir(name, list, selector, sorter) 138 | X.in +4n 139 | Xchar *name; 140 | Xstruct dirent ***list; 141 | Xint (*selector)(); 142 | Xint (*sorter)(); 143 | X.in -4n 144 | X 145 | Xint 146 | Xalphasort(d1, d2) 147 | X.in +4n 148 | Xstruct dirent **d1; 149 | Xstruct dirent **d2; 150 | X.in -4n 151 | X.ft R 152 | X.fi 153 | X.SH DESCRIPTION 154 | X.I Scandir 155 | Xreads the directory 156 | X.I name 157 | Xand builds a NULL\-terminated array of pointers to the entries found 158 | Xin that directory. 159 | XThis array is put into the location pointed to by the 160 | X.I list 161 | Xparameter. 162 | X.PP 163 | XIf the 164 | X.I selector 165 | Xparameter is non\-NULL, it is taken to be a pointer to a function called 166 | Xwith each entry, to determine whether or not it should be included in 167 | Xthe returned list. 168 | XIf the parameter is NULL, all entries are included. 169 | X.PP 170 | XAs an added feature, the entries can be sorted (with 171 | X.IR qsort (3)) 172 | Xbefore the list is returned. 173 | XIf the 174 | X.I sorter 175 | Xparameter is non\-NULL, it is passed to qsort to use as the comparison 176 | Xfunction. 177 | XThe 178 | X.I alphasort 179 | Xroutine is provided to sort the array alphabetically. 180 | X.PP 181 | XThe array pointed to by 182 | X.I list 183 | Xand the items it points to are all space obtained through 184 | X.IR malloc (3), 185 | Xand their storage can be reclaimed as shown in the example below. 186 | X.SH "EXAMPLE" 187 | XHere is a small 188 | X.IR ls (1)\-like 189 | Xprogram: 190 | X.ne 50 191 | X.RS 192 | X.nf 193 | X#include 194 | X#include 195 | X#include 196 | X#include 197 | X 198 | Xextern int alphasort(); 199 | X 200 | Xstatic int 201 | Xfilesonly(e) 202 | X struct dirent *e; 203 | X{ 204 | X struct stat sb; 205 | X 206 | X return(stat(e->d_name, &sb) >= 0 && (sb.st_mode & S_IFMT) == S_IFREG); 207 | X} 208 | X 209 | Xmain(ac, av) 210 | X int ac; 211 | X char *av[]; 212 | X{ 213 | X register int i; 214 | X register int j; 215 | X struct dirent **list; 216 | X 217 | X if (ac != 2) { 218 | X fprintf(stderr, "usage: %s dirname\n", av[0]); 219 | X exit(1); 220 | X } 221 | X if (chdir(av[1]) < 0) { 222 | X perror(av[1]); 223 | X exit(1); 224 | X } 225 | X if ((i = scandir(".", &list, filesonly, alphasort)) < 0) { 226 | X perror("Error reading directory"); 227 | X exit(1); 228 | X } 229 | X for (j = 0; j < i; j++) 230 | X printf("%s\n", list[j]->d_name); 231 | X for (j = 0; j < i; j++) 232 | X free((char *)list[j]); 233 | X free((char *)list); 234 | X exit(0); 235 | X} 236 | X.fi 237 | X.RE 238 | X.SH "SEE ALSO" 239 | Xdirectory(3), qsort(3) 240 | X.SH DIAGNOSTICS 241 | XReturns the number of entries in the ``list,'' or \-1 if the directory 242 | Xcould not be opened or a memory allocation failed. 243 | X.SH BUGS 244 | XThe routine can be slightly wasteful of space. 245 | ________This_Is_The_END________ 246 | if test `wc -c < scandir.3` -ne 2353; then 247 | echo 'shar: scandir.3 was damaged during transit (should have been 2353 bytes)' 248 | fi 249 | fi ; : end of overwriting check 250 | echo 'x - scandir.c' 251 | if test -f scandir.c; then echo 'shar: not overwriting scandir.c'; else 252 | sed 's/^X//' << '________This_Is_The_END________' > scandir.c 253 | X/* 254 | X** SCANDIR 255 | X** Scan a directory, collecting all (selected) items into a an array. 256 | X*/ 257 | X#include 258 | X#include 259 | X#include 260 | X 261 | X#ifdef RCSID 262 | Xstatic char RCS[] = "$Header: /cvsroot/arc/arc/Sysvarcstuf,v 1.2 2003/10/31 02:22:36 highlandsun Exp $"; 263 | X#endif /* RCSID */ 264 | X 265 | X/* Initial guess at directory size. */ 266 | X#define INITIAL_SIZE 20 267 | X 268 | X/* A convenient shorthand. */ 269 | Xtypedef struct dirent ENTRY; 270 | X 271 | X#define DIRSIZ(d) (sizeof(struct dirent) + strlen(d->d_name) + 1) 272 | X 273 | X/* Linked in later. */ 274 | Xextern char *malloc(); 275 | Xextern char *realloc(); 276 | Xextern char *strcpy(); 277 | X 278 | X 279 | Xint 280 | Xscandir(Name, List, Selector, Sorter) 281 | X char *Name; 282 | X ENTRY ***List; 283 | X int (*Selector)(); 284 | X int (*Sorter)(); 285 | X{ 286 | X register ENTRY **names; 287 | X register ENTRY *E; 288 | X register DIR *Dp; 289 | X register int i; 290 | X register int size; 291 | X 292 | X /* Get initial list space and open directory. */ 293 | X size = INITIAL_SIZE; 294 | X if ((names = (ENTRY **)malloc(size * sizeof names[0])) == NULL 295 | X || (Dp = opendir(Name)) == NULL) 296 | X return(-1); 297 | X 298 | X /* Read entries in the directory. */ 299 | X for (i = 0; E = readdir(Dp); ) 300 | X if (Selector == NULL || (*Selector)(E)) { 301 | X /* User wants them all, or he wants this one. */ 302 | X if (++i >= size) { 303 | X size <<= 1; 304 | X names = (ENTRY **)realloc((char *)names, size * sizeof names[0]); 305 | X if (names == NULL) { 306 | X closedir(Dp); 307 | X return(-1); 308 | X } 309 | X } 310 | X 311 | X /* Copy the entry. */ 312 | X if ((names[i - 1] = (ENTRY *)malloc(DIRSIZ(E))) == NULL) { 313 | X closedir(Dp); 314 | X return(-1); 315 | X } 316 | X names[i - 1]->d_ino = E->d_ino; 317 | X names[i - 1]->d_reclen = E->d_reclen; 318 | X /* names[i - 1]->d_namlen = E->d_namlen; */ 319 | X (void)strcpy(names[i - 1]->d_name, E->d_name); 320 | X } 321 | X 322 | X /* Close things off. */ 323 | X names[i] = NULL; 324 | X *List = names; 325 | X closedir(Dp); 326 | X 327 | X /* Sort? */ 328 | X if (i && Sorter) 329 | X qsort((char *)names, i, sizeof names[0], Sorter); 330 | X 331 | X return(i); 332 | X} 333 | ________This_Is_The_END________ 334 | if test `wc -c < scandir.c` -ne 1875; then 335 | echo 'shar: scandir.c was damaged during transit (should have been 1875 bytes)' 336 | fi 337 | fi ; : end of overwriting check 338 | echo 'x - utimes.c' 339 | if test -f utimes.c; then echo 'shar: not overwriting utimes.c'; else 340 | sed 's/^X//' << '________This_Is_The_END________' > utimes.c 341 | X 342 | X/* bsd utimes emulation for Sys V */ 343 | X/* by Jon Zeeff */ 344 | X 345 | X#include 346 | X 347 | Xstruct utimbuf { 348 | X time_t actime; 349 | X time_t modtime; 350 | X}; 351 | X 352 | Xstruct timeval { 353 | X long tv_sec; 354 | X long tv_usec; 355 | X}; 356 | X 357 | Xutimes(path,tvp) 358 | Xchar *path; 359 | Xstruct timeval tvp[2]; 360 | X{ 361 | X 362 | Xstruct utimbuf times; 363 | X 364 | Xtimes.actime = (time_t) tvp[0].tv_sec; 365 | Xtimes.modtime = (time_t) tvp[1].tv_sec; 366 | X 367 | Xreturn utime(path,times); 368 | X 369 | X} 370 | ________This_Is_The_END________ 371 | if test `wc -c < utimes.c` -ne 397; then 372 | echo 'shar: utimes.c was damaged during transit (should have been 397 bytes)' 373 | fi 374 | fi ; : end of overwriting check 375 | exit 0 376 | -------------------------------------------------------------------------------- /arc.1: -------------------------------------------------------------------------------- 1 | .TH ARC 1 "11 Nov 1991" "Howard Chu@JPL" "LOCAL COMMANDS" 2 | .SH NAME 3 | arc \- pc archive utility 4 | .SH SYNOPSIS 5 | .B arc 6 | a|m|u|f|d|x|e|r|p|l|v|t|c [ biswnoq ] [ g\fIpassword\fR ] 7 | .I archive 8 | [ \fIfilename\fR ...] 9 | .SH DESCRIPTION 10 | .I Arc 11 | is a general archive and file compression utility, used to maintain 12 | a compressed archive of files. 13 | An 14 | .I archive 15 | is a single file that combines many files, reducing storage space 16 | and allowing multiple files to be handled as one. 17 | .I Arc 18 | uses one of several compression methods for each file within the 19 | .IR archive , 20 | based on whichever method yields the smallest result. 21 | .SH INSTRUCTIONS 22 | Execute 23 | .I arc 24 | with no arguments for fairly verbose, usable instructions. 25 | .SH COMMAND SWITCHES 26 | .TP 3 27 | a 28 | add files to archive. Copies the indicated files to the archive. 29 | .TP 30 | m 31 | move files to archive. Same as 'a' switch except 32 | that the files are deleted from the directory as 33 | they are moved to the archive. 34 | .TP 35 | u 36 | update files in archive. This switch will replace archived 37 | files when the named file is newer than the archived copy. 38 | New files will be added automatically. 39 | .TP 40 | f 41 | freshen files in archive. Same as 'u' except that 42 | new files will not be added. 43 | .TP 44 | d 45 | delete files in archive. The named files are removed from the archive. 46 | .TP 47 | x,e 48 | extract files from archive. The named files are extracted 49 | from the archive and created in the current directory 50 | in an uncompressed state. 51 | .TP 52 | r 53 | run one file with arguments from archive. Any 54 | program may be executed directly from the archive. 55 | The parameters given after the program name are passed to 56 | the program without modification. 57 | .TP 58 | p 59 | copy files from archive to standard output. Useful 60 | with I/O redirection. A form-feed is appended after each file, 61 | to ease use with printers. 62 | .TP 63 | l 64 | list files in archive. Limited information listing 65 | of files contained in an archive. Displays the 66 | filename, original length, and date last modified. 67 | If the 'n' option (see below) is used, only the 68 | filename is displayed. 69 | .TP 70 | v 71 | verbose listing of files in archive. Complete 72 | information listing of files contained in an archive. 73 | Displays the filename, original length, storage method, 74 | storage factor (% savings), compressed size, date, time, 75 | and CRC. 76 | .TP 77 | t 78 | test archive integrity. Computes CRC values for each member of 79 | the archive and compares against the previously saved value. 80 | .TP 81 | c 82 | convert entry to new packing method. Convert files 83 | stored with older methods to newer methods that are 84 | more efficient. Also useful for files previously 85 | archived with the 's' option. 86 | .SH OPTIONS 87 | .TP 3 88 | b 89 | retain backup copy of archive. Keep the original 90 | archive file and rename to .BAK. 91 | This switch may be used with the 92 | following commands: a, m, u, f, d, c. 93 | .TP 94 | i 95 | suppress image mode. This switch causes files to 96 | be treated as text files, and will translate their 97 | end-of-line sequence. (Unix's '\\n' vs. '\\r\\n' used 98 | on many other systems.) The default is to perform 99 | no translation when compressing or extracting files. 100 | This option makes dealing with text files much nicer, 101 | though the 'tr' command can also be used. ('\\r' in 102 | makefiles and C source code is such a nuisance...) 103 | .TP 104 | s 105 | suppress compression. This forces new files to be 106 | saved using Method 2 (no compression). This switch 107 | may be used with the following commands: a, m, u, f, c. 108 | .TP 109 | w 110 | suppress warning messages. This switch will keep 111 | warning messages from being displayed which is the default. 112 | Most warnings concern the deletion or existence of 113 | files with the same name. 114 | .TP 115 | n 116 | suppress notes and comments. This switch will keep 117 | useful notes from being displayed which is the default. 118 | Most notes indicate what stage of compression is 119 | being run (analyze, compaction, storage). 120 | .TP 121 | o 122 | overwrite existing files when extracting. This switch 123 | will make existing files silently get overwritten, instead 124 | of asking for confirmation, which is the default. 125 | .TP 126 | q 127 | force Squash compression method. This switch causes 128 | the Squash compression method to be used, instead of 129 | Crunch, which is the default. 130 | .TP 131 | g 132 | encrypt/decrypt archive entry. This is used to encode 133 | files so that others may not read them. BE CAREFUL! 134 | This must be the last parameter in the switches because 135 | everything following is part of the password. 136 | .SH PROGRAMMING NOTES 137 | .I Arc 138 | Version 2 differs from version 1 in that archive entries 139 | are automatically compressed when they are added to the archive, 140 | making a separate compression step unnecessary. The nature of the 141 | compression is indicated by the header version number placed in 142 | each archive entry, as follows: 143 | .nf 144 | 1 = Old style, no compression 145 | 2 = New style, no compression 146 | 3 = Compression of repeated characters only 147 | 4 = Compression of repeated characters plus Huffman SQueezing 148 | 5 = Lempel-Zev packing of repeated strings (old style) 149 | 6 = Lempel-Zev packing of repeated strings (new style) 150 | 7 = Lempel-Zev Williams packing with improved hash function 151 | 8 = Dynamic Lempel-Zev packing with adaptive reset 152 | 9 = Squashing 153 | .fi 154 | 155 | Type 5, Lempel-Zev packing, was added as of version 4.0 156 | 157 | Type 6 is Lempel-Zev packing where runs of repeated characters 158 | have been collapsed, and was added as of version 4.1 159 | 160 | Type 7 is a variation of Lempel-Zev using a different hash 161 | function which yields speed improvements of 20-25%, and was 162 | added as of version 4.6 163 | 164 | Type 8 is a different implementation of Lempel-Zev, using a 165 | variable code size and an adaptive block reset, and was added 166 | as of version 5.0 167 | 168 | Type 9 is another variation of Lempel-Zev, using a larger 169 | hash table. This method was developed by Phil Katz, and is 170 | not supported by the "official" \fBARC\fP programs. 171 | 172 | .I Arc 173 | will look for environment variables named \fIARCTEMP\fP or 174 | \fITMPDIR\fP, which, if present, indicates the pathname 175 | where temporary files should be created. This is typically 176 | the location of a RAMdisk on a microcomputer, "/tmp/" or 177 | left unset. 178 | 179 | See the included documentation file for more details. 180 | .SH HISTORY 181 | \fIArc\fP has been in use in the CP/M and MSDOS world for many years. 182 | Thom Henderson developed the original version, but it is important to note that 183 | \fIarc\fP is based on the file compression theories developed by Huffman, Welch, 184 | Knott, Knuth, and many other scientists. This implementation is based on 185 | version 5.21 of the MSDOS program. 186 | .SH BUGS 187 | \fIArc\fP behaves just like the PC version of the program; all functions 188 | of the "usage" display are working. 189 | Full compatibility with PC ARC files is maintained, the price for which is 190 | that \fIarc\fP doesn't like long filenames, and can only archive files with 191 | names of up to 12 characters. 192 | It will *sometimes* do The Right Thing with them, but I suggest 193 | you put long-winded filenames in a "shar" before 194 | .IR arc ing 195 | them. 196 | 197 | There shouldn't be any problems, (hah!) but if you find any, please 198 | send them to me at: 199 | 200 | hyc@hanauma.jpl.nasa.gov 201 | 202 | .SH AUTHORS 203 | Original MSDOS program by Thom Henderson 204 | .br 205 | COPYRIGHT(C) 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED 206 | 207 | Original Lempel-Zev code derived from compress 4.0. 208 | Modified to support Squashing by Dan Lanciani (ddl@harvard.edu) 209 | Ported from MSDOS by Howard Chu, 210 | with help from John Gilmore (hoptoad!gnu), James Turner (daisy!turner) 211 | and others. 212 | -------------------------------------------------------------------------------- /arc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arc.c,v 1.7 2011/01/01 13:02:30 k_reimer Exp $ 3 | */ 4 | 5 | /* ARC - Archive utility 6 | 7 | Version 5.21, created on 04/22/87 at 15:05:21 8 | 9 | (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED 10 | 11 | By: Thom Henderson 12 | 13 | Description: 14 | This program is a general archive utility, and is used to maintain 15 | an archive of files. An "archive" is a single file that combines 16 | many files, reducing storage space and allowing multiple files to 17 | be handled as one. 18 | 19 | Instructions: 20 | Run this program with no arguments for complete instructions. 21 | 22 | Programming notes: 23 | ARC Version 2 differs from version 1 in that archive entries 24 | are automatically compressed when they are added to the archive, 25 | making a separate compression step unecessary. The nature of the 26 | compression is indicated by the header version number placed in 27 | each archive entry, as follows: 28 | 29 | 1 = Old style, no compression 30 | 2 = New style, no compression 31 | 3 = Compression of repeated characters only 32 | 4 = Compression of repeated characters plus Huffman SQueezing 33 | 5 = Lempel-Zev packing of repeated strings (old style) 34 | 6 = Lempel-Zev packing of repeated strings (new style) 35 | 7 = Lempel-Zev Williams packing with improved hash function 36 | 8 = Dynamic Lempel-Zev packing with adaptive reset 37 | 9 = Dynamic Lempel-Zev packing, larger hash table 38 | 39 | Type 5, Lempel-Zev packing, was added as of version 4.0 40 | 41 | Type 6 is Lempel-Zev packing where runs of repeated characters 42 | have been collapsed, and was added as of version 4.1 43 | 44 | Type 7 is a variation of Lempel-Zev using a different hash 45 | function which yields speed improvements of 20-25%, and was 46 | added as of version 4.6 47 | 48 | Type 8 is a different implementation of Lempel-Zev, using a 49 | variable code size and an adaptive block reset, and was added 50 | as of version 5.0 51 | 52 | Type 9 is a slight modification of type 8, first used by Phil 53 | Katz in his PKARC utilites. The primary difference is the use 54 | of a hash table twice as large as for type 8, and that this 55 | algorithm called Squashing, doesn't perform run-length encoding 56 | on the input data. 57 | 58 | Verion 4.3 introduced a temporary file for holding the result 59 | of the first crunch pass, thus speeding up crunching. 60 | 61 | Version 4.4 introduced the ARCTEMP environment string, so that 62 | the temporary crunch file may be placed on a ramdisk. Also 63 | added was the distinction bewteen Adding a file in all cases, 64 | and Updating a file only if the disk file is newer than the 65 | corresponding archive entry. 66 | 67 | The compression method to use is determined when the file is 68 | added, based on whichever method yields the smallest result. 69 | 70 | Language: 71 | Computer Innovations Optimizing C86 72 | */ 73 | #include 74 | #include "arc.h" 75 | 76 | #if UNIX 77 | #include 78 | #include 79 | #include 80 | #include 81 | #endif 82 | 83 | #include 84 | #if BSD 85 | #include 86 | #endif 87 | 88 | #if !__STDC__ 89 | char *calloc(), *malloc(), *realloc(); 90 | #endif 91 | 92 | VOID addarc(), delarc(), extarc(), lstarc(), tstarc(), cvtarc(), runarc(); 93 | VOID arcdie(); 94 | static VOID expandlst(); 95 | #if _MTS 96 | VOID etoa(); 97 | #endif 98 | #if GEMDOS 99 | long _stksize = 30720; 100 | #endif 101 | char *makefnam(); /* filename fixup routine */ 102 | 103 | /* Block I/O buffers */ 104 | 105 | u_char *pinbuf, *pakbuf, *outbuf, *outend; 106 | 107 | static char **lst; /* files list */ 108 | static int lnum; /* length of files list */ 109 | 110 | int 111 | main(num, arg) /* system entry point */ 112 | int num; /* number of arguments */ 113 | char *arg[]; /* pointers to arguments */ 114 | { 115 | char opt = 0;/* selected action */ 116 | char *a; /* option pointer */ 117 | VOID upper();/* case conversion routine */ 118 | char *envfind(); /* environment searcher */ 119 | int n; /* index */ 120 | char *arctemp2; 121 | #if GEMDOS 122 | VOID exitpause(); 123 | int append; 124 | #endif 125 | #if _MTS 126 | fortran VOID guinfo(); 127 | char gotinf[4]; 128 | #endif 129 | #if UNIX 130 | struct stat sbuf; 131 | #endif 132 | 133 | if (num < 3) { 134 | printf("ARC - Archive utility, Version %s, created on 08/07/2010\n", VERSION); 135 | /* printf("(C) COPYRIGHT 1985,86,87 by System Enhancement Associates;"); 136 | printf(" ALL RIGHTS RESERVED\n\n"); 137 | printf("Please refer all inquiries to:\n\n"); 138 | printf(" System Enhancement Associates\n"); 139 | printf(" 21 New Street, Wayne NJ 07470\n\n"); 140 | printf("You may copy and distribute this program freely,"); 141 | printf(" provided that:\n"); 142 | printf(" 1) No fee is charged for such copying and"); 143 | printf(" distribution, and\n"); 144 | printf(" 2) It is distributed ONLY in its original,"); 145 | printf(" unmodified state.\n\n"); 146 | printf("If you like this program, and find it of use, then your"); 147 | printf(" contribution will\n"); 148 | printf("be appreciated. You may not use this product in a"); 149 | printf(" commercial environment\n"); 150 | printf("or a governmental organization without paying a license"); 151 | printf(" fee of $35. Site\n"); 152 | printf("licenses and commercial distribution licenses are"); 153 | printf(" available. A program\n"); 154 | printf("disk and printed documentation are available for $50.\n"); 155 | printf("\nIf you fail to abide by the terms of this license, "); 156 | printf(" then your conscience\n"); 157 | printf("will haunt you for the rest of your life.\n\n"); */ 158 | #if MSDOS 159 | printf("Usage: ARC {amufdxerplvtc}[bswnoq][g]"); 160 | #endif 161 | #if GEMDOS 162 | printf("Usage: ARC {amufdxerplvtc}[bhswnoq][g]"); 163 | #endif 164 | #if UNIX 165 | printf("Usage: arc {amufdxerplvtc}[biswnoq][g]"); 166 | #endif 167 | #if _MTS 168 | printf("Parameters: {amufdxeplvtc}[biswnoq][g]"); 169 | #endif 170 | printf(" [ . . .]\n"); 171 | printf("Where: a = add files to archive\n"); 172 | printf(" m = move files to archive\n"); 173 | printf(" u = update files in archive\n"); 174 | printf(" f = freshen files in archive\n"); 175 | printf(" d = delete files from archive\n"); 176 | printf(" x,e = extract files from archive\n"); 177 | #if !_MTS 178 | printf(" r = run files from archive\n"); 179 | #endif 180 | printf(" p = copy files from archive to"); 181 | printf(" standard output\n"); 182 | printf(" l = list files in archive\n"); 183 | printf(" v = verbose listing of files in archive\n"); 184 | printf(" t = test archive integrity\n"); 185 | printf(" c = convert entry to new packing method\n"); 186 | printf(" b = retain backup copy of archive\n"); 187 | #if GEMDOS 188 | printf(" h = hold screen after finishing\n"); 189 | #endif 190 | #if _MTS 191 | printf(" i = suppress ASCII/EBCDIC translation\n"); 192 | #endif 193 | #if UNIX 194 | printf(" i = suppress image mode (translate EOL)\n"); 195 | #endif 196 | printf(" s = suppress compression (store only)\n"); 197 | printf(" w = suppress warning messages\n"); 198 | printf(" n = suppress notes and comments\n"); 199 | printf(" o = overwrite existing files when"); 200 | printf(" extracting\n"); 201 | printf(" q = squash instead of crunching\n"); 202 | printf(" g = Encrypt/decrypt archive entry\n"); 203 | printf("\nAdapted from MSDOS by Howard Chu\n"); 204 | /* 205 | * printf("\nPlease refer to the program documentation for"); 206 | * printf(" complete instructions.\n"); 207 | */ 208 | #if GEMDOS 209 | exitpause(); 210 | #endif 211 | return 1; 212 | } 213 | /* see where temp files go */ 214 | #if !_MTS 215 | arctemp = calloc(1, STRLEN); 216 | if (!(arctemp2 = envfind("ARCTEMP"))) 217 | arctemp2 = envfind("TMPDIR"); 218 | if (arctemp2) { 219 | strncpy(arctemp, arctemp2, STRLEN - 16); 220 | arctemp[STRLEN - 17] = '\0'; 221 | n = strlen(arctemp); 222 | if (arctemp[n - 1] != CUTOFF) 223 | arctemp[n] = CUTOFF; 224 | } 225 | #if UNIX 226 | else strcpy(arctemp, "/tmp/"); 227 | #endif 228 | #if !MSDOS 229 | { 230 | strcat(arctemp, "AXXXXXX"); 231 | int fd = mkstemp(arctemp); 232 | if (fd == -1) 233 | { 234 | fprintf(stderr, "Unable to create temporary files: %s\n", strerror(errno)); 235 | exit(235); 236 | } 237 | close(fd); 238 | unlink(arctemp); 239 | } 240 | #else 241 | strcat(arctemp, "$ARCTEMP"); 242 | #endif 243 | #else 244 | guinfo("SHFSEP ", gotinf); 245 | sepchr[0] = gotinf[0]; 246 | guinfo("SCRFCHAR", gotinf); 247 | tmpchr[0] = gotinf[0]; 248 | arctemp = "-$$$"; 249 | arctemp[0] = tmpchr[0]; 250 | #endif 251 | arctemp2 = NULL; 252 | 253 | #if !UNIX 254 | /* avoid any case problems with arguments */ 255 | 256 | for (n = 1; n < num; n++) /* for each argument */ 257 | upper(arg[n]); /* convert it to uppercase */ 258 | #else 259 | /* avoid case problems with command options */ 260 | upper(arg[1]); /* convert to uppercase */ 261 | #endif 262 | 263 | for (n = 1; n < num; n++) 264 | if (strlen(arg[n]) > (STRLEN - 16)) 265 | { 266 | fprintf(stderr, "Too long argument: %s\n", arg[n]); 267 | exit(235); 268 | } 269 | 270 | /* create archive names, supplying defaults */ 271 | #if UNIX 272 | if (!stat(arg[2],&sbuf)) { 273 | if ((sbuf.st_mode & S_IFMT) == S_IFDIR) 274 | makefnam(arg[2],".arc",arcname); 275 | else 276 | strcpy(arcname,arg[2]); 277 | } else 278 | makefnam(arg[2],".arc",arcname); 279 | #else 280 | makefnam(arg[2], ".ARC", arcname); 281 | #endif 282 | /* makefnam(".$$$",arcname,newname); */ 283 | sprintf(newname, "%s.arc", arctemp); 284 | makefnam(".BAK", arcname, bakname); 285 | 286 | /* now scan the command and see what we are to do */ 287 | 288 | for (a = arg[1]; *a; a++) { /* scan the option flags */ 289 | #if !_MTS 290 | if (index("AMUFDXEPLVTCR", *a)) { /* if a known command */ 291 | #else 292 | if (index("AMUFDXEPLVTC", *a)) { 293 | #endif 294 | if (opt)/* do we have one yet? */ 295 | arcdie("Cannot mix %c and %c", opt, *a); 296 | opt = *a; /* else remember it */ 297 | } else if (*a == 'B') /* retain backup copy */ 298 | keepbak = 1; 299 | 300 | else if (*a == 'W') /* suppress warnings */ 301 | warn = 0; 302 | #if !DOS 303 | else if (*a == 'I') /* image mode, no ASCII/EBCDIC x-late */ 304 | image = !image; 305 | #endif 306 | #if GEMDOS 307 | else if (*a == 'H') /* pause before exit */ 308 | hold = 1; 309 | #endif 310 | 311 | else if (*a == 'N') /* suppress notes and comments */ 312 | note = 0; 313 | 314 | else if (*a == 'O') /* overwrite file on extract */ 315 | overlay = 1; 316 | 317 | else if (*a == 'G') { /* garble */ 318 | password = a + 1; 319 | while (*a) 320 | a++; 321 | a--; 322 | #if _MTS 323 | etoa(password, strlen(password)); 324 | #endif 325 | } else if (*a == 'S') /* storage kludge */ 326 | nocomp = 1; 327 | 328 | else if (*a == 'K') /* special kludge */ 329 | kludge = 1; 330 | 331 | else if (*a == 'Q') /* use squashing */ 332 | dosquash = 1; 333 | 334 | else if (*a == '-' || *a == '/') /* UNIX and PC-DOS 335 | * option markers */ 336 | ; 337 | 338 | else 339 | arcdie("%c is an unknown command", *a); 340 | } 341 | 342 | if (!opt) 343 | arcdie("I have nothing to do!"); 344 | 345 | /* get the files list set up */ 346 | 347 | lnum = num - 3; /* initial length of list */ 348 | lst = (char **) calloc((lnum==0) ? 1:lnum, 349 | sizeof(char *)); /* initial list */ 350 | for (n = 3; n < num; n++) 351 | lst[n - 3] = arg[n]; 352 | 353 | for (n = 0; n < lnum;) {/* expand indirect references */ 354 | if (*lst[n] == '@') 355 | expandlst(n); 356 | #if GEMDOS /* redirect stdout from the desktop...*/ 357 | else if (*lst[n] == '>') { 358 | arctemp2 = (++lst[n]); 359 | lst[n] = lst[--lnum]; /* delete this entry */ 360 | if (arctemp2[0] == '>') { 361 | append = 1; 362 | arctemp2++; 363 | } 364 | else append = 0; 365 | } 366 | #endif 367 | else 368 | n++; 369 | } 370 | #if GEMDOS 371 | if (arctemp2) 372 | freopen(arctemp2,append ? "a" : "w",stdout); 373 | #endif 374 | 375 | /* Allocate space to I/O buffers */ 376 | 377 | if (!(pinbuf = malloc(MYBUF))) 378 | arcdie("Not enough memory for input buffer."); 379 | if (!(outbuf = malloc(MYBUF))) 380 | arcdie("Not enough memory for output buffer."); 381 | if (!(pakbuf = malloc(2L*MYBUF))) 382 | arcdie("Not enough memory for packing buffer."); 383 | outend = outbuf + MYBUF - 1; 384 | 385 | 386 | /* act on whatever action command was given */ 387 | 388 | switch (opt) { /* action depends on command */ 389 | case 'A': /* Add */ 390 | case 'M': /* Move */ 391 | case 'U': /* Update */ 392 | case 'F': /* Freshen */ 393 | addarc(lnum, lst, (opt == 'M'), (opt == 'U'), (opt == 'F')); 394 | break; 395 | 396 | case 'D': /* Delete */ 397 | delarc(lnum, lst); 398 | break; 399 | 400 | case 'E': /* Extract */ 401 | case 'X': /* eXtract */ 402 | case 'P': /* Print */ 403 | extarc(lnum, lst, (opt == 'P')); 404 | break; 405 | 406 | case 'V': /* Verbose list */ 407 | bose = 1; 408 | case 'L': /* List */ 409 | lstarc(lnum, lst); 410 | break; 411 | 412 | case 'T': /* Test */ 413 | tstarc(); 414 | break; 415 | 416 | case 'C': /* Convert */ 417 | cvtarc(lnum, lst); 418 | break; 419 | #if !_MTS 420 | case 'R': /* Run */ 421 | runarc(lnum, lst); 422 | break; 423 | #endif 424 | default: 425 | arcdie("I don't know how to do %c yet!", opt); 426 | } 427 | #if GEMDOS 428 | if (hold) 429 | exitpause(); 430 | #endif 431 | return nerrs; 432 | } 433 | static VOID 434 | expandlst(n) /* expand an indirect reference */ 435 | int n; /* number of entry to expand */ 436 | { 437 | FILE *lf, *fopen(); /* list file, opener */ 438 | char buf[100]; /* input buffer */ 439 | int x; /* index */ 440 | char *p = lst[n] + 1; /* filename pointer */ 441 | 442 | if (*p) { /* use name if one was given */ 443 | makefnam(p, ".CMD", buf); 444 | if (!(lf = fopen(buf, "r"))) 445 | arcdie("Cannot read list of files in %s", buf); 446 | } else 447 | lf = stdin; /* else use standard input */ 448 | 449 | for (x = n + 1; x < lnum; x++) /* drop reference from the list */ 450 | lst[x - 1] = lst[x]; 451 | lnum--; 452 | 453 | while (fscanf(lf, "%99s", buf) > 0) { /* read in the list */ 454 | if (!(lst =(char **)realloc(lst, (lnum + 1) * sizeof(char *)))) 455 | arcdie("too many file references"); 456 | 457 | lst[lnum] = malloc(strlen(buf) + 1); 458 | strcpy(lst[lnum], buf); /* save the name */ 459 | lnum++; 460 | } 461 | 462 | if (lf != stdin) /* avoid closing standard input */ 463 | fclose(lf); 464 | } 465 | -------------------------------------------------------------------------------- /arc.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arc.h,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | #undef DOS /* Just in case... */ 6 | #undef UNIX 7 | 8 | /* 9 | * Assumptions: 10 | * char = 8 bits 11 | * short = 16 bits 12 | * long = 32 bits 13 | * int >= 16 bits 14 | */ 15 | 16 | #if MSDOS || GEMDOS 17 | #define DOS 1 18 | #define CUTOFF '\\' 19 | #define OPEN_R "rb" 20 | #define OPEN_W "wb" 21 | #if __GNUC__ 22 | #include 23 | #include 24 | #endif 25 | #endif 26 | 27 | #if !MSDOS 28 | #define envfind getenv 29 | #define setmem(a, b, c) memset(a, c, b) 30 | #endif 31 | 32 | #if BSD || SYSV 33 | #define UNIX 1 34 | #define CUTOFF '/' 35 | #define OPEN_R "r" 36 | #define OPEN_W "w" 37 | #include 38 | #include 39 | #endif 40 | 41 | #if _MTS 42 | #define CUTOFF sepchr[0] 43 | #define OPEN_R "rb" 44 | #define OPEN_W "wb" 45 | #endif 46 | 47 | #define MYBUF 32766 /* Used for fopens and filecopy() */ 48 | 49 | #if _MTS || SYSV 50 | #define rindex strrchr 51 | #define index strchr 52 | #endif 53 | 54 | #if __STDC__ 55 | #include 56 | #define VOID void 57 | #define PROTO(args) args 58 | #else 59 | #define VOID int 60 | #define PROTO(args) () 61 | #endif 62 | 63 | /* ARC - Archive utility - ARC Header 64 | 65 | Version 2.17, created on 04/22/87 at 13:09:43 66 | 67 | (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED 68 | 69 | By: Thom Henderson 70 | 71 | Description: 72 | This is the header file for the ARC archive utility. It defines 73 | global parameters and the references to the external data. 74 | 75 | 76 | Language: 77 | Computer Innovations Optimizing C86 78 | */ 79 | 80 | #define ARCMARK 26 /* special archive marker */ 81 | #define ARCVER 9 /* archive header version code */ 82 | #define STRLEN 100 /* system standard string length */ 83 | #define FNLEN 13 /* file name length */ 84 | #define MAXARG 400 /* maximum number of arguments */ 85 | 86 | #if !UNIX 87 | typedef unsigned int u_int; 88 | #ifndef __GNUC__ 89 | typedef unsigned char u_char; 90 | typedef unsigned short u_short; 91 | #endif 92 | #endif 93 | #define reg register 94 | 95 | #ifndef DONT_DEFINE /* Defined by arcdata.c */ 96 | #include "arcs.h" 97 | 98 | extern int keepbak; /* true if saving the old archive */ 99 | #if !DOS 100 | extern int image; /* true to suppress CRLF/LF x-late */ 101 | #endif 102 | #if _MTS 103 | extern char sepchr[2]; /* Shared file separator, default = ':' */ 104 | extern char tmpchr[2]; /* Temporary file prefix, default = '-' */ 105 | #endif 106 | #if GEMDOS 107 | extern int hold; /* hold screen before exiting */ 108 | #endif 109 | extern int warn; /* true to print warnings */ 110 | extern int note; /* true to print comments */ 111 | extern int bose; /* true to be verbose */ 112 | extern int nocomp; /* true to suppress compression */ 113 | extern int overlay; /* true to overlay on extract */ 114 | extern int kludge; /* kludge flag */ 115 | extern char *arctemp; /* arc temp file prefix */ 116 | extern char *password; /* encryption password pointer */ 117 | extern int nerrs; /* number of errors encountered */ 118 | extern int changing; /* true if archive being modified */ 119 | 120 | extern char hdrver; /* header version */ 121 | 122 | extern FILE *arc; /* the old archive */ 123 | extern FILE *new; /* the new archive */ 124 | extern char arcname[STRLEN];/* storage for archive name */ 125 | extern char bakname[STRLEN];/* storage for backup copy name */ 126 | extern char newname[STRLEN];/* storage for new archive name */ 127 | extern u_short arcdate; /* archive date stamp */ 128 | extern u_short arctime; /* archive time stamp */ 129 | extern u_short olddate; /* old archive date stamp */ 130 | extern u_short oldtime; /* old archive time stamp */ 131 | extern int dosquash; /* squash instead of crunch */ 132 | #endif /* DONT_DEFINE */ 133 | -------------------------------------------------------------------------------- /arcadd.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcadd.c,v 1.4 2005/10/12 15:22:18 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCADD 7 | * 8 | * Version 3.40, created on 06/18/86 at 13:10:18 9 | * 10 | * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to add files to an archive. 15 | * 16 | * Language: Computer Innovations Optimizing C86 17 | */ 18 | #include 19 | #include "arc.h" 20 | #if _MTS 21 | #include 22 | #include 23 | #endif 24 | #include 25 | #if BSD 26 | #include 27 | #endif 28 | 29 | static int addfile(); 30 | int readhdr(), unlink(); 31 | #if UNIX 32 | int izadir(); 33 | #endif 34 | VOID writehdr(), filecopy(), getstamp(); 35 | VOID pack(), closearc(), openarc(), arcdie(); 36 | 37 | #ifndef __STDC__ 38 | char *malloc(), *realloc(); /* memory allocators */ 39 | #ifndef _AIX 40 | VOID free(); 41 | #endif 42 | #endif 43 | 44 | VOID 45 | addarc(num, arg, move, update, fresh) /* add files to archive */ 46 | int num; /* number of arguments */ 47 | char *arg[]; /* pointers to arguments */ 48 | int move; /* true if moving file */ 49 | int update; /* true if updating */ 50 | int fresh; /* true if freshening */ 51 | { 52 | char *d, *dir(); /* directory junk */ 53 | char buf[STRLEN]; /* pathname buffer */ 54 | char **path; /* pointer to pointers to paths */ 55 | char **name; /* pointer to pointers to names */ 56 | int nfiles = 0; /* number of files in lists */ 57 | int notemp; /* true until a template works */ 58 | int nowork = 1; /* true until files are added */ 59 | char *i; /* string indexing junk */ 60 | int n; /* index */ 61 | #if MSDOS 62 | unsigned int coreleft(); /* remaining memory reporter */ 63 | #endif 64 | int addbunch(); 65 | 66 | if (num < 1) { /* if no files named */ 67 | num = 1; /* then fake one */ 68 | #if DOS 69 | arg[0] = "*.*"; /* add everything */ 70 | #endif 71 | #if UNIX 72 | arg[0] = "*"; 73 | #endif 74 | #if _MTS 75 | arg[0] = "?"; 76 | #endif 77 | } 78 | path = (char **) malloc(sizeof(char **)); 79 | name = (char **) malloc(sizeof(char **)); 80 | 81 | 82 | for (n = 0; n < num; n++) { /* for each template supplied */ 83 | strcpy(buf, arg[n]); /* get ready to fix path */ 84 | #if !_MTS 85 | if (!(i = rindex(buf, '\\'))) 86 | if (!(i = rindex(buf, '/'))) 87 | if (!(i = rindex(buf, ':'))) 88 | i = buf - 1; 89 | #else 90 | if (!(i = rindex(buf, sepchr[0]))) 91 | if (buf[0] != tmpchr[0]) 92 | i = buf - 1; 93 | else 94 | i = buf; 95 | #endif 96 | i++; /* pointer to where name goes */ 97 | 98 | notemp = 1; /* reset files flag */ 99 | for (d = dir(arg[n]); d; d = dir(NULL)) { 100 | notemp = 0; /* template is giving results */ 101 | nfiles++; /* add each matching file */ 102 | path = (char **) realloc(path, nfiles * sizeof(char **)); 103 | name = (char **) realloc(name, nfiles * sizeof(char **)); 104 | strcpy(i, d); /* put name in path */ 105 | path[nfiles - 1] = malloc(strlen(buf) + 1); 106 | strcpy(path[nfiles - 1], buf); 107 | name[nfiles - 1] = d; /* save name */ 108 | #if MSDOS 109 | if (coreleft() < 5120) { 110 | nfiles = addbunch(nfiles, path, name, move, update, fresh); 111 | nowork = nowork && !nfiles; 112 | while (nfiles) { 113 | free(path[--nfiles]); 114 | free(name[nfiles]); 115 | } 116 | free(path); 117 | free(name); 118 | path = name = NULL; 119 | } 120 | #endif 121 | } 122 | if (notemp && warn) 123 | printf("No files match: %s\n", arg[n]); 124 | } 125 | 126 | if (nfiles) { 127 | nfiles = addbunch(nfiles, path, name, move, update, fresh); 128 | nowork = nowork && !nfiles; 129 | while (nfiles) { 130 | free(path[--nfiles]); 131 | free(name[nfiles]); 132 | } 133 | free(path); 134 | free(name); 135 | } 136 | if (nowork && warn) 137 | printf("No files were added.\n"); 138 | } 139 | 140 | int 141 | addbunch(nfiles, path, name, move, update, fresh) /* add a bunch of files */ 142 | int nfiles; /* number of files to add */ 143 | char **path; /* pointers to pathnames */ 144 | char **name; /* pointers to filenames */ 145 | int move; /* true if moving file */ 146 | int update; /* true if updating */ 147 | int fresh; /* true if freshening */ 148 | { 149 | int m, n; /* indices */ 150 | char *d; /* swap pointer */ 151 | struct heads hdr; /* file header data storage */ 152 | 153 | for (n = 0; n < nfiles - 1; n++) { /* sort the list of names */ 154 | for (m = n + 1; m < nfiles; m++) { 155 | if (strcmp(name[n], name[m]) > 0) { 156 | d = path[n]; 157 | path[n] = path[m]; 158 | path[m] = d; 159 | d = name[n]; 160 | name[n] = name[m]; 161 | name[m] = d; 162 | } 163 | } 164 | } 165 | 166 | for (n = 0; n < nfiles - 1;) { /* consolidate the list of names */ 167 | if (!strcmp(path[n], path[n + 1]) /* if duplicate names */ 168 | ||!strcmp(path[n], arcname) /* or this archive */ 169 | #if UNIX 170 | ||izadir(path[n]) /* or a directory */ 171 | #endif 172 | ||!strcmp(path[n], newname) /* or the new version */ 173 | ||!strcmp(path[n], bakname)) { /* or its backup */ 174 | free(path[n]); /* then forget the file */ 175 | free(name[n]); 176 | for (m = n; m < nfiles - 1; m++) { 177 | path[m] = path[m + 1]; 178 | name[m] = name[m + 1]; 179 | } 180 | nfiles--; 181 | } else 182 | n++; /* else test the next one */ 183 | } 184 | 185 | if (!strcmp(path[n], arcname) /* special check for last file */ 186 | ||!strcmp(path[n], newname) /* courtesy of Rick Moore */ 187 | #if UNIX 188 | ||izadir(path[n]) 189 | #endif 190 | || !strcmp(path[n], bakname)) { 191 | free(path[n]); 192 | free(name[n]); 193 | nfiles--; 194 | } 195 | if (!nfiles) /* make sure we got some */ 196 | return 0; 197 | 198 | for (n = 0; n < nfiles - 1; n++) { /* watch out for duplicate 199 | * names */ 200 | if (!strcmp(name[n], name[n + 1])) 201 | arcdie("Duplicate filenames:\n %s\n %s", path[n], path[n + 1]); 202 | } 203 | openarc(1); /* open archive for changes */ 204 | 205 | for (n = 0; n < nfiles;) { /* add each file in the list */ 206 | if (addfile(path[n], name[n], update, fresh) < 0) { 207 | free(path[n]); /* remove this name if */ 208 | free(name[n]); /* it wasn't added */ 209 | for (m = n; m < nfiles-1 ; m++) { 210 | path[m] = path[m+1]; 211 | name[m] = name[m+1]; 212 | } 213 | nfiles--; 214 | } else n++; 215 | } 216 | 217 | /* now we must copy over all files that follow our additions */ 218 | 219 | while (readhdr(&hdr, arc)) { /* while more entries to copy */ 220 | writehdr(&hdr, new); 221 | filecopy(arc, new, hdr.size); 222 | } 223 | hdrver = 0; /* archive EOF type */ 224 | writehdr(&hdr, new); /* write out our end marker */ 225 | closearc(1); /* close archive after changes */ 226 | 227 | if (move) { /* if this was a move */ 228 | for (n = 0; n < nfiles; n++) { /* then delete each file 229 | * added */ 230 | if (unlink(path[n]) && warn) { 231 | printf("Cannot unsave %s\n", path[n]); 232 | nerrs++; 233 | } 234 | } 235 | } 236 | return nfiles; /* say how many were added */ 237 | } 238 | 239 | static int 240 | addfile(path, name, update, fresh) /* add named file to archive */ 241 | char *path; /* path name of file to add */ 242 | char *name; /* name of file to add */ 243 | int update; /* true if updating */ 244 | int fresh; /* true if freshening */ 245 | { 246 | struct heads nhdr; /* data regarding the new file */ 247 | struct heads ohdr; /* data regarding an old file */ 248 | FILE *f, *fopen(); /* file to add, opener */ 249 | long starts, ftell(); /* file locations */ 250 | int upd = 0;/* true if replacing an entry */ 251 | 252 | #if !_MTS 253 | if (!(f = fopen(path, OPEN_R))) 254 | #else 255 | if (image) 256 | f = fopen(path, OPEN_R); 257 | else 258 | f = fopen(path, "r"); 259 | if (!f) 260 | #endif 261 | { 262 | if (warn) { 263 | printf("Cannot read file: %s\n", path); 264 | nerrs++; 265 | } 266 | return(-1); 267 | } 268 | #if !DOS 269 | if (strlen(name) >= FNLEN) { 270 | if (warn) { 271 | char buf[STRLEN]; 272 | printf("WARNING: File %s name too long!\n", name); 273 | name[FNLEN-1]='\0'; 274 | while(1) { 275 | char *dummy; 276 | printf(" Truncate to %s (y/n)? ", name); 277 | fflush(stdout); 278 | dummy = fgets(buf, STRLEN, stdin); 279 | *buf = toupper(*buf); 280 | if (*buf == 'Y' || *buf == 'N') 281 | break; 282 | } 283 | if (*buf == 'N') { 284 | printf("Skipping...\n"); 285 | fclose(f); 286 | return(-1); 287 | } 288 | } 289 | else { 290 | if (note) 291 | printf("Skipping file: %s - name too long.\n", 292 | name); 293 | fclose(f); 294 | return(-1); 295 | } 296 | } 297 | #endif 298 | strcpy(nhdr.name, name);/* save name */ 299 | nhdr.size = 0; /* clear out size storage */ 300 | nhdr.crc = 0; /* clear out CRC check storage */ 301 | #if !_MTS 302 | getstamp(f, &nhdr.date, &nhdr.time); 303 | #else 304 | { 305 | int inlen; 306 | struct GDDSECT *region; 307 | 308 | region=gdinfo(f->_fd._fdub); 309 | inlen=region->GDINLEN; 310 | buf=malloc(inlen); /* maximum line length */ 311 | setbuffer(f,buf,inlen); 312 | f->_mods|=_NOIC; /* Don't do "$continue with" */ 313 | f->_mods&=~_IC; /* turn it off, if set... */ 314 | } 315 | getstamp(path, &nhdr.date, &nhdr.time); 316 | #endif 317 | 318 | /* position archive to spot for new file */ 319 | 320 | if (arc) { /* if adding to existing archive */ 321 | starts = ftell(arc); /* where are we? */ 322 | while (readhdr(&ohdr, arc)) { /* while more files to check */ 323 | if (!strcmp(ohdr.name, nhdr.name)) { 324 | upd = 1; /* replace existing entry */ 325 | if (update || fresh) { /* if updating or 326 | * freshening */ 327 | if (nhdr.date < ohdr.date 328 | || (nhdr.date == ohdr.date && nhdr.time <= ohdr.time)) { 329 | fseek(arc, starts, 0); 330 | fclose(f); 331 | return(0);/* skip if !newer */ 332 | } 333 | } 334 | } 335 | if (strcmp(ohdr.name, nhdr.name) >= 0) 336 | break; /* found our spot */ 337 | 338 | writehdr(&ohdr, new); /* entry preceeds update; 339 | * keep it */ 340 | filecopy(arc, new, ohdr.size); 341 | starts = ftell(arc); /* now where are we? */ 342 | } 343 | 344 | if (upd) { /* if an update */ 345 | if (note) { 346 | printf("Updating file: %-12s ", name); 347 | fflush(stdout); 348 | } 349 | fseek(arc, ohdr.size, 1); 350 | } else if (fresh) { /* else if freshening */ 351 | fseek(arc, starts, 0); /* then do not add files */ 352 | fclose(f); 353 | return(0); 354 | } else { /* else adding a new file */ 355 | if (note) { 356 | printf("Adding file: %-12s ", name); 357 | fflush(stdout); 358 | } 359 | fseek(arc, starts, 0); /* reset for next time */ 360 | } 361 | } else { /* no existing archive */ 362 | if (fresh) { /* cannot freshen nothing */ 363 | fclose(f); 364 | return(0); 365 | } else if (note) { /* else adding a file */ 366 | printf("Adding file: %-12s ", name); 367 | fflush(stdout); 368 | } 369 | } 370 | 371 | starts = ftell(new); /* note where header goes */ 372 | hdrver = ARCVER; /* anything but end marker */ 373 | writehdr(&nhdr, new); /* write out header skeleton */ 374 | #if _MTS 375 | atoe(nhdr.name, FNLEN); /* writehdr translated this... */ 376 | #endif 377 | pack(f, new, &nhdr); /* pack file into archive */ 378 | fseek(new, starts, 0); /* move back to header skeleton */ 379 | writehdr(&nhdr, new); /* write out real header */ 380 | fseek(new, nhdr.size, 1); /* skip over data to next header */ 381 | fclose(f); /* all done with the file */ 382 | return(0); 383 | } 384 | -------------------------------------------------------------------------------- /arccode.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arccode.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCCODE 7 | * 8 | * Version 1.02, created on 01/20/86 at 13:33:35 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to encrypt and decrypt data 15 | * in an archive. The encryption method is nothing fancy, being just a 16 | * routine XOR, but it is used on the packed data, and uses a variable length 17 | * key. The end result is something that is in theory crackable, but I'd 18 | * hate to try it. It should be more than sufficient for casual use. 19 | * 20 | * Language: Computer Innovations Optimizing C86 21 | */ 22 | #include 23 | #include "arc.h" 24 | 25 | static char *p; /* password pointer */ 26 | 27 | VOID 28 | setcode() 29 | { /* get set for encoding/decoding */ 30 | p = password; /* reset password pointer */ 31 | } 32 | 33 | VOID 34 | codebuf(buf, len) /* encrypt a buffer */ 35 | reg char *buf; 36 | u_int len; 37 | { 38 | reg u_int i; 39 | reg char *pasptr = p; 40 | 41 | for (i = 0; i < len; i++) { 42 | if (!*pasptr) 43 | pasptr = password; 44 | *buf++ ^= *pasptr++; 45 | } 46 | p = pasptr; 47 | } 48 | -------------------------------------------------------------------------------- /arccvt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arccvt.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCCVT 7 | * 8 | * Version 1.16, created on 02/03/86 at 22:53:02 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to convert archives to use 15 | * newer file storage methods. 16 | * 17 | * Language: Computer Innovations Optimizing C86 18 | */ 19 | #include 20 | #if _MTS 21 | #include 22 | #endif 23 | #include "arc.h" 24 | 25 | int match(), readhdr(), unpack(), unlink(); 26 | VOID openarc(), rempath(), closearc(), arcdie(), pack(); 27 | VOID writehdr(), filecopy(); 28 | static VOID cvtfile(); 29 | 30 | static char tempname[STRLEN]; /* temp file name */ 31 | 32 | VOID 33 | cvtarc(num, arg) /* convert archive */ 34 | int num; /* number of arguments */ 35 | char *arg[]; /* pointers to arguments */ 36 | { 37 | struct heads hdr; /* file header */ 38 | int cvt; /* true to convert current file */ 39 | int did[MAXARG];/* true when argument was used */ 40 | int n; /* index */ 41 | char *makefnam(); /* filename fixer */ 42 | FILE *fopen();/* file opener */ 43 | 44 | if (arctemp) /* use temp area if specified */ 45 | sprintf(tempname, "%s.CVT", arctemp); 46 | else 47 | makefnam("$ARCTEMP.CVT", arcname, tempname); 48 | #if !DOS 49 | image = 1; 50 | #endif 51 | 52 | openarc(1); /* open archive for changes */ 53 | 54 | for (n = 0; n < num; n++) /* for each argument */ 55 | did[n] = 0; /* reset usage flag */ 56 | rempath(num, arg); /* strip off paths */ 57 | 58 | if (num) { /* if files were named */ 59 | while (readhdr(&hdr, arc)) { /* while more files to check */ 60 | cvt = 0;/* reset convert flag */ 61 | for (n = 0; n < num; n++) { /* for each template 62 | * given */ 63 | if (match(hdr.name, arg[n])) { 64 | cvt = 1; /* turn on convert flag */ 65 | did[n] = 1; /* turn on usage flag */ 66 | break; /* stop looking */ 67 | } 68 | } 69 | 70 | if (cvt)/* if converting this one */ 71 | cvtfile(&hdr); /* then do it */ 72 | else { /* else just copy it */ 73 | writehdr(&hdr, new); 74 | filecopy(arc, new, hdr.size); 75 | } 76 | } 77 | } else 78 | while (readhdr(&hdr, arc)) /* else convert all files */ 79 | cvtfile(&hdr); 80 | 81 | hdrver = 0; /* archive EOF type */ 82 | writehdr(&hdr, new); /* write out our end marker */ 83 | closearc(1); /* close archive after changes */ 84 | 85 | if (note) { 86 | for (n = 0; n < num; n++) { /* report unused args */ 87 | if (!did[n]) { 88 | printf("File not found: %s\n", arg[n]); 89 | nerrs++; 90 | } 91 | } 92 | } 93 | } 94 | 95 | static VOID 96 | cvtfile(hdr) /* convert a file */ 97 | struct heads *hdr; /* pointer to header data */ 98 | { 99 | long starts, ftell(); /* where the file goes */ 100 | FILE *tmp, *fopen(); /* temporary file */ 101 | 102 | if (!(tmp = fopen(tempname, "w+b"))) 103 | arcdie("Unable to create temporary file %s", tempname); 104 | 105 | if (note) { 106 | printf("Converting file: %-12s reading, ", hdr->name); 107 | fflush(stdout); 108 | } 109 | unpack(arc, tmp, hdr); /* unpack the entry */ 110 | fseek(tmp, 0L, 0); /* reset temp for reading */ 111 | 112 | starts = ftell(new); /* note where header goes */ 113 | hdrver = ARCVER; /* anything but end marker */ 114 | writehdr(hdr, new); /* write out header skeleton */ 115 | #if _MTS 116 | atoe(hdr->name, FNLEN); /* writehdr translated this... */ 117 | #endif 118 | pack(tmp, new, hdr); /* pack file into archive */ 119 | fseek(new, starts, 0); /* move back to header skeleton */ 120 | writehdr(hdr, new); /* write out real header */ 121 | fseek(new, hdr->size, 1); /* skip over data to next header */ 122 | fclose(tmp); /* all done with the file */ 123 | if (unlink(tempname) && warn) { 124 | printf("Cannot unsave %s\n", tempname); 125 | nerrs++; 126 | } 127 | } 128 | -------------------------------------------------------------------------------- /arcdata.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcdata.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* ARC - Archive utility - ARCDATA 6 | 7 | Version 2.17, created on 04/22/87 at 13:09:43 8 | 9 | (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED 10 | 11 | By: Thom Henderson 12 | 13 | Description: 14 | This file defines the external data storage used by the ARC 15 | archive utility. 16 | 17 | 18 | Language: 19 | Computer Innovations Optimizing C86 20 | */ 21 | #include 22 | 23 | #define DONT_DEFINE 24 | #include "arc.h" 25 | 26 | int keepbak = 0; /* true if saving the old archive */ 27 | #if UNIX 28 | int image = 1; /* true to suppress CRLF/LF x-late */ 29 | #endif 30 | #if _MTS 31 | int image = 0; /* true to suppress EBCDIC/ASCII x-late */ 32 | char sepchr[2] = ":";/* Shared file separator */ 33 | char tmpchr[2] = "-";/* Temporary file prefix */ 34 | #endif 35 | #if GEMDOS 36 | int hold = 0; /* true to pause before exit */ 37 | #endif 38 | int warn = 1; /* true to print warnings */ 39 | int note = 1; /* true to print comments */ 40 | int bose = 0; /* true to be verbose */ 41 | int nocomp = 0; /* true to suppress compression */ 42 | int overlay = 0; /* true to overlay on extract */ 43 | int kludge = 0; /* kludge flag */ 44 | char *arctemp = NULL; /* arc temp file prefix */ 45 | char *password = NULL;/* encryption password pointer */ 46 | int nerrs = 0; /* number of errors encountered */ 47 | int changing = 0; /* true if archive being modified */ 48 | 49 | char hdrver; /* header version */ 50 | 51 | FILE *arc; /* the old archive */ 52 | FILE *new; /* the new archive */ 53 | char arcname[STRLEN]; /* storage for archive name */ 54 | char bakname[STRLEN]; /* storage for backup copy name */ 55 | char newname[STRLEN]; /* storage for new archive name */ 56 | unsigned short arcdate = 0; /* archive date stamp */ 57 | unsigned short arctime = 0; /* archive time stamp */ 58 | unsigned short olddate = 0; /* old archive date stamp */ 59 | unsigned short oldtime = 0; /* old archive time stamp */ 60 | int dosquash = 0; /* true to squash instead of crunch */ 61 | -------------------------------------------------------------------------------- /arcdel.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcdel.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCDEL 7 | * 8 | * Version 2.09, created on 02/03/86 at 22:53:27 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to delete entries in an 15 | * archive. 16 | * 17 | * Language: Computer Innovations Optimizing C86 18 | */ 19 | #include 20 | #include "arc.h" 21 | 22 | VOID arcdie(), rempath(), openarc(), closearc(), writehdr(), filecopy(); 23 | int match(), readhdr(); 24 | 25 | VOID 26 | delarc(num, arg) /* remove files from archive */ 27 | int num; /* number of arguments */ 28 | char *arg[]; /* pointers to arguments */ 29 | { 30 | struct heads hdr; /* header data */ 31 | int del; /* true to delete a file */ 32 | int did[MAXARG];/* true when argument used */ 33 | int n; /* index */ 34 | 35 | if (!num) /* she must specify which */ 36 | arcdie("You must tell me which files to delete!"); 37 | 38 | for (n = 0; n < num; n++) /* for each argument */ 39 | did[n] = 0; /* reset usage flag */ 40 | rempath(num, arg); /* strip off paths */ 41 | 42 | openarc(1); /* open archive for changes */ 43 | 44 | while (readhdr(&hdr, arc)) { /* while more entries in archive */ 45 | del = 0; /* reset delete flag */ 46 | for (n = 0; n < num; n++) { /* for each template given */ 47 | if (match(hdr.name, arg[n])) { 48 | del = 1; /* turn on delete flag */ 49 | did[n] = 1; /* turn on usage flag */ 50 | break; /* stop looking */ 51 | } 52 | } 53 | 54 | if (del) { /* skip over unwanted files */ 55 | fseek(arc, hdr.size, 1); 56 | if (note) 57 | printf("Deleting file: %s\n", hdr.name); 58 | } else { /* else copy over file data */ 59 | writehdr(&hdr, new); /* write out header and file */ 60 | filecopy(arc, new, hdr.size); 61 | } 62 | } 63 | 64 | hdrver = 0; /* special end of archive type */ 65 | writehdr(&hdr, new); /* write out archive end marker */ 66 | closearc(1); /* close archive after changes */ 67 | 68 | if (note) { 69 | for (n = 0; n < num; n++) { /* report unused arguments */ 70 | if (!did[n]) { 71 | printf("File not found: %s\n", arg[n]); 72 | nerrs++; 73 | } 74 | } 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /arcdos.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcdos.c,v 1.3 2003/10/31 02:32:19 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCDOS 7 | * 8 | * Version 1.44, created on 07/25/86 at 14:17:38 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains certain DOS level routines that assist in 15 | * doing fancy things with an archive, primarily reading and setting the date 16 | * and time last modified. 17 | * 18 | * These are, by nature, system dependant functions. But they are also, by 19 | * nature, very expendable. 20 | * 21 | * Language: Computer Innovations Optimizing C86 22 | */ 23 | #include 24 | #include "arc.h" 25 | 26 | #ifdef __CYGWIN__ 27 | # include 28 | #endif 29 | 30 | #if MSDOS 31 | #include "fileio2.h" /* needed for filehand */ 32 | #endif 33 | 34 | #if UNIX 35 | #include 36 | #include 37 | #if BSD 38 | #include 39 | #else 40 | #include /* Sys V. Bleah. */ 41 | #if NEED_TIMEVAL 42 | struct timeval { 43 | long tv_sec; 44 | long tv_usec; 45 | }; 46 | #endif 47 | #endif /* BSD vs SYSV */ 48 | #endif 49 | 50 | #if GEMDOS 51 | #include 52 | #endif 53 | 54 | #include 55 | #ifndef __STDC__ 56 | char *malloc(); 57 | #endif 58 | 59 | VOID 60 | getstamp(f, date, time) /* get a file's date/time stamp */ 61 | #if !_MTS 62 | FILE *f; /* file to get stamp from */ 63 | #else 64 | char *f; /* filename "" "" */ 65 | #endif 66 | unsigned short *date, *time; /* storage for the stamp */ 67 | { 68 | #if MSDOS 69 | struct { 70 | int ax, bx, cx, dx, si, di, ds, es; 71 | } reg; 72 | 73 | reg.ax = 0x5700; /* get date/time */ 74 | reg.bx = filehand(f); /* file handle */ 75 | if (sysint21(®, ®) & 1) /* DOS call */ 76 | printf("Get timestamp fail (%d)\n", reg.ax); 77 | 78 | *date = reg.dx; /* save date/time */ 79 | *time = reg.cx; 80 | #endif 81 | #if GEMDOS 82 | int fd, ret[2]; 83 | 84 | fd = fileno(f); 85 | Fdatime(ret, fd, 0); 86 | *date = ret[1]; 87 | *time = ret[0]; 88 | #endif 89 | #if UNIX 90 | struct stat buf; 91 | struct tm *localtime(), *t; 92 | 93 | fstat(fileno(f), &buf); 94 | t=localtime(&(buf.st_mtime)); 95 | *date = (unsigned short) (((t->tm_year - 80) << 9) + 96 | ((t->tm_mon + 1) << 5) + t->tm_mday); 97 | *time = (unsigned short) ((t->tm_hour << 11) + 98 | (t->tm_min << 5) + t->tm_sec / 2); 99 | #endif 100 | #if _MTS 101 | fortran timein(), 102 | #if USEGFINFO 103 | gfinfo(); 104 | #else 105 | fileinfo(); 106 | #endif 107 | int stclk[2]; 108 | char name[24]; 109 | struct bigtime { 110 | int greg; 111 | int year; 112 | int mon; 113 | int day; 114 | int hour; 115 | int min; 116 | int sec; 117 | int usec; 118 | int week; 119 | int toff; 120 | int tzn1; 121 | int tzn2; 122 | } tvec; 123 | #if USEGFINFO 124 | static int gfflag = 0x0009, gfdummy[2] = { 125 | 0, 0 126 | }; 127 | int gfcinfo[18]; 128 | #else 129 | static int cattype = 2; 130 | #endif 131 | 132 | strcpy(name, f); 133 | strcat(name, " "); 134 | #if USEGFINFO 135 | gfcinfo[0] = 18; 136 | gfinfo(name, name, &gfflag, gfcinfo, gfdummy, gfdummy); 137 | timein("*IBM MICROSECONDS*", &gfcinfo[16], &tvec); 138 | #else 139 | fileinfo(name, &cattype, "CILCCT ", stclk); 140 | timein("*IBM MICROSECONDS*", stclk, &tvec); 141 | #endif 142 | 143 | *date = (unsigned short) (((tvec.year - 1980) << 9) + ((tvec.mon) << 5) + tvec.day); 144 | *time = (unsigned short) ((tvec.hour << 11) + (tvec.min << 5) + tvec.sec / 2); 145 | #endif 146 | } 147 | 148 | VOID 149 | setstamp(f, date, time) /* set a file's date/time stamp */ 150 | char *f; /* filename to stamp */ 151 | unsigned short date, time; /* desired date, time */ 152 | { 153 | #if MSDOS 154 | FILE *ff; 155 | struct { 156 | int ax, bx, cx, dx, si, di, ds, es; 157 | } reg; 158 | 159 | ff = fopen(f, "w+"); /* How else can I get a handle? */ 160 | 161 | reg.ax = 0x5701; /* set date/time */ 162 | reg.bx = filehand(f); /* file handle */ 163 | reg.cx = time; /* desired time */ 164 | reg.dx = date; /* desired date */ 165 | if (sysint21(®, ®) & 1) /* DOS call */ 166 | printf("Set timestamp fail (%d)\n", reg.ax); 167 | fclose(ff); 168 | #endif 169 | #if GEMDOS 170 | int fd, set[2]; 171 | 172 | fd = Fopen(f, 0); 173 | set[0] = time; 174 | set[1] = date; 175 | Fdatime(set, fd, 1); 176 | Fclose(fd); 177 | #endif 178 | #if UNIX 179 | struct tm tm; 180 | struct timeval tvp[2]; 181 | int utimes(); 182 | long tmclock(); 183 | tm.tm_sec = (time & 31) * 2; 184 | tm.tm_min = (time >> 5) & 63; 185 | tm.tm_hour = (time >> 11); 186 | tm.tm_mday = date & 31; 187 | tm.tm_mon = ((date >> 5) & 15) - 1; 188 | tm.tm_year = (date >> 9) + 80; 189 | tvp[0].tv_sec = tmclock(&tm); 190 | tvp[1].tv_sec = tvp[0].tv_sec; 191 | tvp[0].tv_usec = tvp[1].tv_usec = 0; 192 | utimes(f, tvp); 193 | #endif 194 | } 195 | 196 | #if MSDOS 197 | int 198 | filehand(stream) /* find handle on a file */ 199 | struct bufstr *stream; /* file to grab onto */ 200 | { 201 | return stream->bufhand; /* return DOS 2.0 file handle */ 202 | } 203 | #endif 204 | 205 | #if UNIX 206 | int 207 | izadir(filename) /* Is filename a directory? */ 208 | char *filename; 209 | { 210 | struct stat buf; 211 | 212 | if (stat(filename, &buf) != 0) 213 | return (0); /* Ignore if stat fails since */ 214 | else 215 | return (buf.st_mode & S_IFDIR); /* bad files trapped later */ 216 | } 217 | #endif 218 | -------------------------------------------------------------------------------- /arcext.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcext.c,v 1.5 2005/10/12 15:22:18 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCEXT 7 | * 8 | * Version 2.19, created on 10/24/86 at 14:53:32 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to extract files from an 15 | * archive. 16 | * 17 | * Language: Computer Innovations Optimizing C86 18 | */ 19 | #include 20 | #include "arc.h" 21 | #if !MSDOS 22 | #include 23 | #endif 24 | #include 25 | #if BSD 26 | #include 27 | #endif 28 | 29 | VOID openarc(), closearc(), setstamp(); 30 | int match(), readhdr(), unpack(); 31 | static VOID extfile(); 32 | 33 | #ifndef __STDC__ 34 | char *malloc(); 35 | #ifndef _AIX 36 | VOID free(); 37 | #endif 38 | #endif 39 | 40 | VOID 41 | extarc(num, arg, prt) /* extract files from archive */ 42 | int num; /* number of arguments */ 43 | char *arg[]; /* pointers to arguments */ 44 | int prt; /* true if printing */ 45 | { 46 | struct heads hdr; /* file header */ 47 | int save; /* true to save current file */ 48 | int did[MAXARG];/* true when argument was used */ 49 | char *i; /* string index */ 50 | char **name; /* name pointer list */ 51 | int n; /* index */ 52 | 53 | name = (char **) malloc(num * sizeof(char *)); /* get storage for name 54 | * pointers */ 55 | 56 | for (n = 0; n < num; n++) { /* for each argument */ 57 | did[n] = 0; /* reset usage flag */ 58 | #if !_MTS 59 | if (!(i = rindex(arg[n], '\\'))) /* find start of name */ 60 | if (!(i = rindex(arg[n], '/'))) 61 | if (!(i = rindex(arg[n], ':'))) 62 | i = arg[n] - 1; 63 | #else 64 | if (!(i = rindex(arg[n], sepchr[0]))) 65 | if (arg[n][0] != tmpchr[0]) 66 | i = arg[n] - 1; 67 | else 68 | i = arg[n]; 69 | #endif 70 | name[n] = i + 1; 71 | } 72 | 73 | 74 | openarc(0); /* open archive for reading */ 75 | 76 | if (num) { /* if files were named */ 77 | while (readhdr(&hdr, arc)) { /* while more files to check */ 78 | save = 0; /* reset save flag */ 79 | for (n = 0; n < num; n++) { /* for each template 80 | * given */ 81 | if (match(hdr.name, name[n])) { 82 | save = 1; /* turn on save flag */ 83 | did[n] = 1; /* turn on usage flag */ 84 | break; /* stop looking */ 85 | } 86 | } 87 | 88 | if (save) /* extract if desired, else skip */ 89 | extfile(&hdr, arg[n], prt); 90 | else 91 | fseek(arc, hdr.size, 1); 92 | } 93 | } else 94 | while (readhdr(&hdr, arc)) /* else extract all files */ 95 | extfile(&hdr, "", prt); 96 | 97 | closearc(0); /* close archive after reading */ 98 | 99 | if (note) { 100 | for (n = 0; n < num; n++) { /* report unused args */ 101 | if (!did[n]) { 102 | printf("File not found: %s\n", arg[n]); 103 | nerrs++; 104 | } 105 | } 106 | } 107 | free(name); 108 | } 109 | 110 | static VOID 111 | extfile(hdr, path, prt) /* extract a file */ 112 | struct heads *hdr; /* pointer to header data */ 113 | char *path; /* pointer to path name */ 114 | int prt; /* true if printing */ 115 | { 116 | FILE *f, *fopen(); /* extracted file, opener */ 117 | char buf[STRLEN]; /* input buffer */ 118 | char fix[STRLEN]; /* fixed name buffer */ 119 | char *i; /* string index */ 120 | 121 | if (prt) { /* printing is much easier */ 122 | unpack(arc, stdout, hdr); /* unpack file from archive */ 123 | printf("\f"); /* eject the form */ 124 | return; /* see? I told you! */ 125 | } 126 | strcpy(fix, path); /* note path name template */ 127 | #if !_MTS 128 | if (*path) { 129 | if (!(i = rindex(fix, '\\'))) /* find start of name */ 130 | if (!(i = rindex(fix, '/'))) 131 | if (!(i = rindex(fix, ':'))) 132 | i = fix - 1; 133 | } else i = fix -1; 134 | #else 135 | if (!(i = rindex(fix, sepchr[0]))) 136 | if (fix[0] != tmpchr[0]) 137 | i = fix - 1; 138 | else 139 | i = fix; 140 | #endif 141 | strcpy(i + 1, hdr->name); /* replace template with name */ 142 | 143 | if (note) 144 | printf("Extracting file: %s\n", fix); 145 | 146 | if (warn && !overlay) { 147 | if ((f = fopen(fix, "r"))) { /* see if it exists */ 148 | fclose(f); 149 | printf("WARNING: File %s already exists!", fix); 150 | fflush(stdout); 151 | while (1) { 152 | char *dummy; 153 | printf(" Overwrite it (y/n)? "); 154 | fflush(stdout); 155 | dummy = fgets(buf, STRLEN, stdin); 156 | *buf = toupper(*buf); 157 | if (*buf == 'Y' || *buf == 'N') 158 | break; 159 | } 160 | if (*buf == 'N') { 161 | printf("%s not extracted.\n", fix); 162 | fseek(arc, hdr->size, 1); 163 | return; 164 | } 165 | } 166 | } 167 | #if !_MTS 168 | if (!(f = fopen(fix, OPEN_W))) 169 | #else 170 | { 171 | fortran create(); 172 | VOID memset(); 173 | char c_name[256]; 174 | struct crsize { 175 | short maxsize, cursize; 176 | } c_size; 177 | char c_vol[6]; 178 | int c_type; 179 | strcpy(c_name, fix); 180 | strcat(c_name, " "); 181 | c_size.maxsize = 0; 182 | c_size.cursize = hdr->length / 4096 + 1; 183 | memset(c_vol, 0, sizeof(c_vol)); 184 | c_type = 0x100; 185 | create(c_name, &c_size, c_vol, &c_type); 186 | } 187 | if (image) { 188 | f = fopen(fix, OPEN_W); 189 | } else 190 | f = fopen(fix, "w"); 191 | if (!f) 192 | #endif 193 | { 194 | if (warn) { 195 | printf("Cannot create %s\n", fix); 196 | nerrs++; 197 | } 198 | fseek(arc, hdr->size, 1); 199 | return; 200 | } 201 | 202 | /* now unpack the file */ 203 | 204 | unpack(arc, f, hdr); /* unpack file from archive */ 205 | fclose(f); /* all done writing to file */ 206 | #if !_MTS 207 | setstamp(fix, hdr->date, hdr->time); /* use filename for stamp */ 208 | #endif 209 | } 210 | -------------------------------------------------------------------------------- /arcio.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcio.c,v 1.4 2005/10/12 15:22:18 highlandsun Exp $ 3 | */ 4 | 5 | /* ARC - Archive utility - ARCIO 6 | 7 | Version 2.50, created on 04/22/87 at 13:25:20 8 | 9 | (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED 10 | 11 | By: Thom Henderson 12 | 13 | Description: 14 | This file contains the file I/O routines used to manipulate 15 | an archive. 16 | 17 | Language: 18 | Computer Innovations Optimizing C86 19 | */ 20 | #include 21 | #include "arc.h" 22 | #if _MTS 23 | #include 24 | #endif 25 | #include 26 | 27 | VOID arcdie(); 28 | 29 | int 30 | readhdr(hdr, f) /* read a header from an archive */ 31 | struct heads *hdr; /* storage for header */ 32 | FILE *f; /* archive to read header from */ 33 | { 34 | #if !MSDOS 35 | unsigned char dummy[28]; 36 | int i; 37 | #endif 38 | char name[FNLEN]; /* filename buffer */ 39 | int try = 0;/* retry counter */ 40 | static int first = 1; /* true only on first read */ 41 | 42 | if (!f) /* if archive didn't open */ 43 | return 0; /* then pretend it's the end */ 44 | hdrver = fgetc(f); 45 | if (feof(f)) /* if no more data */ 46 | return 0; /* then signal end of archive */ 47 | 48 | if (hdrver != ARCMARK) { /* check archive validity */ 49 | if (warn) { 50 | printf("An entry in %s has a bad header.\n", arcname); 51 | nerrs++; 52 | } 53 | printf("hdrver: %x\n", hdrver); 54 | while (!feof(f)) { 55 | try++; 56 | if (fgetc(f) == ARCMARK) { 57 | int dummy; 58 | /* ungetc is guaranteed to succeed for a single char, 59 | * no need to check result 60 | */ 61 | dummy = ungetc(hdrver = fgetc(f), f); 62 | if (!(hdrver & 0x80) && hdrver <= ARCVER) 63 | break; 64 | } 65 | } 66 | 67 | if (feof(f) && first) 68 | arcdie("%s is not an archive", arcname); 69 | 70 | if (changing && warn) 71 | arcdie("%s is corrupted -- changes disallowed", arcname); 72 | 73 | if (warn) 74 | printf(" %d bytes skipped.\n", try); 75 | 76 | if (feof(f)) 77 | return 0; 78 | } 79 | hdrver = fgetc(f); /* get header version */ 80 | if (hdrver & 0x80) /* sign bit? negative? */ 81 | arcdie("Invalid header in archive %s", arcname); 82 | if (hdrver == 0) 83 | return 0; /* note our end of archive marker */ 84 | if (hdrver > ARCVER) { 85 | if (fread(name, sizeof(char), FNLEN, f) != FNLEN) 86 | arcdie("%s was truncated", arcname); 87 | #if _MTS 88 | atoe(name, strlen(name)); 89 | #endif 90 | printf("I don't know how to handle file %s in archive %s\n", 91 | name, arcname); 92 | printf("I think you need a newer version of ARC.\n"); 93 | exit(1); 94 | } 95 | /* amount to read depends on header type */ 96 | 97 | if (hdrver == 1) { /* old style is shorter */ 98 | if (fread(hdr, sizeof(struct heads) - sizeof(long int), 1, f) != 1) 99 | arcdie("%s was truncated", arcname); 100 | hdrver = 2; /* convert header to new format */ 101 | hdr->length = hdr->size; /* size is same when not 102 | * packed */ 103 | } else 104 | #if MSDOS 105 | if (fread(hdr, sizeof(struct heads), 1, f) != 1) 106 | arcdie("%s was truncated", arcname); 107 | #else 108 | if (fread(dummy, 27, 1, f) != 1) 109 | arcdie("%s was truncated", arcname); 110 | 111 | for (i = 0; i < FNLEN; hdr->name[i] = dummy[i], i++); 112 | #if _MTS 113 | (void) atoe(hdr->name, strlen(hdr->name)); 114 | #endif 115 | for (i = 0, hdr->size=0; i<4; hdr->size<<=8, hdr->size += dummy[16-i], i++); 116 | hdr->date = (short) ((dummy[18] << 8) + dummy[17]); 117 | hdr->time = (short) ((dummy[20] << 8) + dummy[19]); 118 | hdr->crc = (short) ((dummy[22] << 8) + dummy[21]); 119 | for (i = 0, hdr->length=0; i<4; hdr->length<<=8, hdr->length += dummy[26-i], i++); 120 | #endif 121 | 122 | if (hdr->date > olddate 123 | || (hdr->date == olddate && hdr->time > oldtime)) { 124 | olddate = hdr->date; 125 | oldtime = hdr->time; 126 | } 127 | first = 0; 128 | return 1; /* we read something */ 129 | } 130 | 131 | VOID 132 | put_int(number, f) /* write a 2 byte integer */ 133 | short number; 134 | FILE *f; 135 | { 136 | fputc((char) (number & 255), f); 137 | fputc((char) (number >> 8), f); 138 | } 139 | 140 | VOID 141 | put_long(number, f) /* write a 4 byte integer */ 142 | long number; 143 | FILE *f; 144 | { 145 | put_int((short) (number & 0xFFFF), f); 146 | put_int((short) (number >> 16), f); 147 | } 148 | 149 | VOID 150 | writehdr(hdr, f) /* write a header to an archive */ 151 | struct heads *hdr; /* header to write */ 152 | FILE *f; /* archive to write to */ 153 | { 154 | fputc(ARCMARK, f); /* write out the mark of ARC */ 155 | fputc(hdrver, f); /* write out the header version */ 156 | if (!hdrver) /* if that's the end */ 157 | return; /* then write no more */ 158 | #if MSDOS 159 | if (fwrite(hdr, sizeof(struct heads), 1, f) != 1) 160 | arcdie("%s out of space", arcname); 161 | #else 162 | /* byte/word ordering hassles... */ 163 | #if _MTS 164 | etoa(hdr->name, strlen(hdr->name)); 165 | #endif 166 | if (fwrite(hdr->name, 1, FNLEN, f) != FNLEN) 167 | arcdie("%s out of space", arcname); 168 | put_long(hdr->size, f); 169 | put_int(hdr->date, f); 170 | put_int(hdr->time, f); 171 | put_int(hdr->crc, f); 172 | put_long(hdr->length, f); 173 | #endif 174 | 175 | /* note the newest file for updating the archive timestamp */ 176 | 177 | if (hdr->date > arcdate 178 | || (hdr->date == arcdate && hdr->time > arctime)) { 179 | arcdate = hdr->date; 180 | arctime = hdr->time; 181 | } 182 | } 183 | 184 | extern char *pinbuf; /* general purpose input buffer */ 185 | 186 | /* 187 | * NOTE: The filecopy() function is used to move large numbers of bytes from 188 | * one file to another. This particular version has been modified to improve 189 | * performance in Computer Innovations C86 version 2.3 in the small memory 190 | * model. It may not work as expected with other compilers or libraries, or 191 | * indeed with different versions of the CI-C86 compiler and library, or with 192 | * the same version in a different memory model. 193 | * 194 | * The following is a functional equivalent to the filecopy() routine that 195 | * should work properly on any system using any compiler, albeit at the cost 196 | * of reduced performance: 197 | * 198 | * filecopy(f,t,size) 199 | * FILE *f, *t; long size; 200 | * { 201 | * while(size--) 202 | * putc_tst(fgetc(f),t); 203 | * } 204 | */ 205 | #if MSDOS 206 | #include 207 | 208 | filecopy(f, t, size) /* bulk file copier */ 209 | FILE *f, *t; /* files from and to */ 210 | long size; /* bytes to copy */ 211 | { 212 | unsigned int bufl; /* buffer length */ 213 | unsigned int coreleft(); /* space available reporter */ 214 | unsigned int cpy; /* bytes being copied */ 215 | long floc, tloc, fseek(); /* file pointers, setter */ 216 | struct regval reg; /* registers for DOS calls */ 217 | 218 | bufl = (MYBUF > size) ? (u_int) size : MYBUF; 219 | 220 | floc = fseek(f, 0L, 1); /* reset I/O system */ 221 | tloc = fseek(t, 0L, 1); 222 | 223 | segread(®.si); /* set segment registers for DOS */ 224 | 225 | while (size > 0) { /* while more to copy */ 226 | reg.ax = 0x3F00;/* read from handle */ 227 | reg.bx = filehand(f); 228 | reg.cx = bufl < size ? bufl : size; /* amount to read */ 229 | reg.dx = pinbuf; 230 | if (sysint21(®, ®) & 1) 231 | arcdie("Read fail"); 232 | 233 | cpy = reg.ax; /* amount actually read */ 234 | reg.ax = 0x4000;/* write to handle */ 235 | reg.bx = filehand(t); 236 | reg.cx = cpy; 237 | reg.dx = pinbuf; 238 | sysint21(®, ®); 239 | 240 | if (reg.ax != cpy) 241 | arcdie("Write fail (disk full?)"); 242 | 243 | size -= (long) cpy; 244 | } 245 | } 246 | #else 247 | 248 | VOID 249 | filecopy(f, t, size) /* bulk file copier */ 250 | FILE *f, *t; /* files from and to */ 251 | long size; /* bytes to copy */ 252 | { 253 | unsigned int bufl; /* buffer length */ 254 | unsigned int cpy; /* bytes being copied */ 255 | 256 | bufl = (MYBUF > size) ? (u_int) size : MYBUF; 257 | 258 | while (size > 0) { 259 | cpy = fread(pinbuf, sizeof(char), bufl, f); 260 | if (fwrite(pinbuf, sizeof(char), cpy, t) != cpy) 261 | arcdie("Write fail (no space?)"); 262 | size -= cpy; 263 | if (bufl > size) 264 | bufl = size; 265 | if (ferror(f)) 266 | arcdie("Unexpected EOF copying archive"); 267 | if (!cpy) break; 268 | } 269 | } 270 | #endif 271 | -------------------------------------------------------------------------------- /arclst.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arclst.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* ARC - Archive utility - ARCLST 6 | 7 | Version 2.39, created on 04/22/87 at 13:48:29 8 | 9 | (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED 10 | 11 | By: Thom Henderson 12 | 13 | Description: 14 | This file contains the routines used to list the contents 15 | of an archive. 16 | 17 | Language: 18 | Computer Innovations Optimizing C86 19 | */ 20 | #include 21 | #include "arc.h" 22 | 23 | VOID rempath(), openarc(), closearc(); 24 | int readhdr(), match(); 25 | static VOID lstfile(); 26 | 27 | VOID 28 | lstarc(num, arg) /* list files in archive */ 29 | int num; /* number of arguments */ 30 | char *arg[]; /* pointers to arguments */ 31 | { 32 | struct heads hdr; /* header data */ 33 | int list; /* true to list a file */ 34 | int did[MAXARG]; /* true when argument was used */ 35 | long tnum, tlen, tsize; /* totals */ 36 | int n; /* index */ 37 | 38 | tnum = tlen = tsize = 0;/* reset totals */ 39 | 40 | for (n = 0; n < num; n++) /* for each argument */ 41 | did[n] = 0; /* reset usage flag */ 42 | rempath(num, arg); /* strip off paths */ 43 | 44 | if (note && !kludge) { 45 | printf("Name Length "); 46 | if (bose) 47 | printf(" Stowage SF Size now"); 48 | printf(" Date "); 49 | if (bose) 50 | printf(" Time CRC"); 51 | printf("\n"); 52 | 53 | printf("============ ========"); 54 | if (bose) 55 | printf(" ======== ==== ========"); 56 | printf(" ========="); 57 | if (bose) 58 | printf(" ====== ===="); 59 | printf("\n"); 60 | } 61 | openarc(0); /* open archive for reading */ 62 | 63 | if (num) { /* if files were named */ 64 | while (readhdr(&hdr, arc)) { /* process all archive files */ 65 | list = 0; /* reset list flag */ 66 | for (n = 0; n < num; n++) { /* for each template 67 | * given */ 68 | if (match(hdr.name, arg[n])) { 69 | list = 1; /* turn on list flag */ 70 | did[n] = 1; /* turn on usage flag */ 71 | break; /* stop looking */ 72 | } 73 | } 74 | 75 | if (list) { /* if this file is wanted */ 76 | if (!kludge) 77 | lstfile(&hdr); /* then tell about it */ 78 | tnum++; /* update totals */ 79 | tlen += hdr.length; 80 | tsize += hdr.size; 81 | } 82 | fseek(arc, hdr.size, 1); /* move to next header */ 83 | } 84 | } else 85 | while (readhdr(&hdr, arc)) { /* else report on all files */ 86 | if (!kludge) 87 | lstfile(&hdr); 88 | tnum++; /* update totals */ 89 | tlen += hdr.length; 90 | tsize += hdr.size; 91 | fseek(arc, hdr.size, 1); /* skip to next header */ 92 | } 93 | 94 | closearc(0); /* close archive after reading */ 95 | 96 | if (note && !kludge) { 97 | printf(" ==== ========"); 98 | if (bose) 99 | printf(" ==== ========"); 100 | printf("\n"); 101 | } 102 | if (note) { 103 | printf("Total %6ld %8ld", tnum, tlen); 104 | if (bose) { 105 | if (tlen) 106 | printf(" %3ld%%", 100L - (100L * tsize) / tlen); 107 | else 108 | printf(" ---"); 109 | printf(" %8ld", tsize); 110 | } 111 | printf("\n"); 112 | 113 | for (n = 0; n < num; n++) { /* report unused args */ 114 | if (!did[n]) { 115 | printf("File not found: %s\n", arg[n]); 116 | nerrs++; 117 | } 118 | } 119 | } 120 | } 121 | 122 | static VOID 123 | lstfile(hdr) /* tell about a file */ 124 | struct heads *hdr; /* pointer to header data */ 125 | { 126 | int yr, mo, dy; /* parts of a date */ 127 | int hh, mm; /* parts of a time */ 128 | 129 | static char *mon[] = /* month abbreviations */ 130 | {"???", /* For month == 0 */ 131 | "Jan", "Feb", "Mar", "Apr", 132 | "May", "Jun", "Jul", "Aug", 133 | "Sep", "Oct", "Nov", "Dec" 134 | }; 135 | 136 | if (!note) { /* no notes means short listing */ 137 | printf("%s\n", hdr->name); 138 | return; 139 | } 140 | 141 | yr = (hdr->date >> 9) & 0x7f; /* dissect the date */ 142 | mo = (hdr->date >> 5) & 0x0f; 143 | if (mo > 12) /* just in case... */ 144 | mo = 0; 145 | dy = hdr->date & 0x1f; 146 | 147 | hh = (hdr->time >> 11) & 0x1f; /* dissect the time */ 148 | mm = (hdr->time >> 5) & 0x3f; 149 | /* ss = (hdr->time & 0x1f) * 2; seconds, not used. */ 150 | 151 | printf("%-12s %8ld ", hdr->name, hdr->length); 152 | 153 | if (bose) { 154 | switch (hdrver) { 155 | case 1: 156 | case 2: 157 | printf(" -- "); 158 | break; 159 | case 3: 160 | printf(" Packed "); 161 | break; 162 | case 4: 163 | printf("Squeezed"); 164 | break; 165 | case 5: 166 | case 6: 167 | case 7: 168 | printf("crunched"); 169 | break; 170 | case 8: 171 | printf("Crunched"); 172 | break; 173 | case 9: 174 | printf("Squashed"); 175 | break; 176 | default: 177 | printf("Unknown!"); 178 | } 179 | 180 | if (hdr->length) 181 | printf(" %3ld%%", 100L - (100L * hdr->size) / hdr->length); 182 | else 183 | printf(" ---"); 184 | printf(" %8ld ", hdr->size); 185 | } 186 | printf("%2d %3s %02d", dy, mon[mo], (yr + 80) % 100); 187 | 188 | if (bose) 189 | printf(" %2d:%02d%c %04x", 190 | (hh > 12 ? hh - 12 : hh), mm, (hh > 11 ? 'p' : 'a'), 191 | hdr->crc & 0xffff); 192 | 193 | printf("\n"); 194 | } 195 | -------------------------------------------------------------------------------- /arcmatch.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcmatch.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCMATCH 7 | * 8 | * Version 2.17, created on 12/17/85 at 20:32:18 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains service routines needed to maintain an 15 | * archive. 16 | * 17 | * Language: Computer Innovations Optimizing C86 18 | */ 19 | #include 20 | #include "arc.h" 21 | 22 | #include 23 | #if BSD 24 | #include 25 | #endif 26 | 27 | VOID arcdie(); 28 | 29 | int 30 | match(n, t) /* test name against template */ 31 | char *n; /* name to test */ 32 | char *t; /* template to test against */ 33 | { 34 | #if _MTS 35 | fortran patbuild(), patmatch(), patfree(); 36 | static int patlen = (-1); 37 | static int patwork = 0; 38 | static int patswch = 0; 39 | char patccid[4]; 40 | static char patchar[2] = "?"; 41 | static char oldtemp[16] = 0; 42 | int namlen, RETCODE; 43 | 44 | if (strcmp(t, oldtemp)) { 45 | if (patwork) 46 | patfree(&patwork); 47 | strcpy(oldtemp, t); 48 | patlen = strlen(oldtemp); 49 | patbuild(oldtemp, &patlen, &patwork, &patswch, patccid, patchar, _retcode RETCODE); 50 | if (RETCODE > 8) { 51 | printf("MTS: patbuild returned %d\n", RETCODE); 52 | arcdie("bad wildcard in filename"); 53 | } 54 | } 55 | namlen = strlen(n); 56 | patmatch(n, &namlen, &patwork, _retcode RETCODE); 57 | switch (RETCODE) { 58 | case 0: 59 | return (1); 60 | case 4: 61 | return (0); 62 | default: 63 | arcdie("wildcard pattern match failed"); 64 | } 65 | } 66 | 67 | #else 68 | #if !UNIX 69 | upper(n); 70 | upper(t); /* avoid case problems */ 71 | #endif /* UNIX */ 72 | 73 | /* first match name part */ 74 | 75 | while ((*n && *n != '.') || (*t && *t != '.')) { 76 | if (*n != *t && *t != '?') { /* match fail? */ 77 | if (*t != '*') /* wildcard fail? */ 78 | return 0; /* then no match */ 79 | else { /* else jump over wildcard */ 80 | while (*n && *n != '.') 81 | n++; 82 | while (*t && *t != '.') 83 | t++; 84 | break; /* name part matches wildcard */ 85 | } 86 | } else { /* match good for this char */ 87 | n++; /* advance to next char */ 88 | t++; 89 | } 90 | } 91 | 92 | if (*n && *n == '.') 93 | n++; /* skip extension delimiters */ 94 | if (*t && *t == '.') 95 | t++; 96 | 97 | /* now match name part */ 98 | 99 | while (*n || *t) { 100 | if (*n != *t && *t != '?') { /* match fail? */ 101 | if (*t != '*') /* wildcard fail? */ 102 | return 0; /* then no match */ 103 | else 104 | return 1; /* else good enough */ 105 | } else { /* match good for this char */ 106 | n++; /* advance to next char */ 107 | t++; 108 | } 109 | } 110 | 111 | return 1; /* match worked */ 112 | } 113 | #endif 114 | 115 | VOID 116 | rempath(nargs, arg) /* remove paths from filenames */ 117 | int nargs; /* number of names */ 118 | char *arg[]; /* pointers to names */ 119 | { 120 | char *i; /* string index */ 121 | int n; /* index */ 122 | 123 | for (n = 0; n < nargs; n++) { /* for each supplied name */ 124 | if (!(i = rindex(arg[n], '\\'))) /* search for end of 125 | * path */ 126 | if (!(i = rindex(arg[n], '/'))) 127 | i = rindex(arg[n], ':'); 128 | if (i) /* if path was found */ 129 | arg[n] = i + 1; /* then skip it */ 130 | } 131 | } 132 | -------------------------------------------------------------------------------- /arcmisc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Miscellaneous routines to get ARC running on non-MSDOS systems... 3 | * $Header: /cvsroot/arc/arc/arcmisc.c,v 1.4 2005/10/09 01:38:22 highlandsun Exp $ 4 | */ 5 | 6 | #include 7 | #include 8 | #include "arc.h" 9 | 10 | #include 11 | #if BSD 12 | #include 13 | #endif 14 | 15 | #if MSDOS 16 | #include 17 | #include 18 | #endif 19 | 20 | #if GEMDOS 21 | #include 22 | #include 23 | #include 24 | 25 | VOID 26 | exitpause() 27 | { 28 | while (Cconis()) 29 | Cnecin(); 30 | fprintf(stderr, "Press any key to continue: "); 31 | fflush(stderr); 32 | Cnecin(); 33 | fprintf(stderr, "\n"); 34 | } 35 | 36 | int 37 | chdir(dirname) 38 | char *dirname; 39 | { 40 | char *i; 41 | int drv; 42 | 43 | i = dirname; 44 | if ((i = index(dirname, ':')) != NULL) { 45 | drv = i[-1]; 46 | i++; /* Move past device spec */ 47 | if (drv > '\'') 48 | drv -= 'a'; 49 | else 50 | drv -= 'A'; 51 | if (drv >= 0 && drv < 16) 52 | Dsetdrv(drv); 53 | } 54 | if (*i != '\0') 55 | return (Dsetpath(i)); 56 | } 57 | #endif 58 | 59 | #if UNIX 60 | #include 61 | #if SYSV 62 | #include 63 | #define DIRECT dirent 64 | #else 65 | #include 66 | #define DIRECT direct 67 | #endif 68 | #include 69 | int rename(), unlink(); 70 | #include 71 | #endif 72 | 73 | #if NEEDMEMSET 74 | char * 75 | memset(s, c, n) /* This came from SVR2? */ 76 | char *s; 77 | int c, n; 78 | { 79 | register int i; 80 | for(i=0;i 86 | #endif 87 | 88 | #ifndef __STDC__ 89 | char *malloc(); 90 | #ifndef _AIX 91 | int free(); 92 | #endif 93 | #endif 94 | int match(); 95 | 96 | /* Safe open for temp files */ 97 | FILE * 98 | tmpopen(path) 99 | char *path; 100 | { 101 | int fd = open(path, O_CREAT | O_WRONLY | O_EXCL, S_IRUSR | S_IWUSR); 102 | if (fd < 0 ) 103 | return NULL; 104 | return fdopen(fd, OPEN_W); 105 | } 106 | 107 | int 108 | move(oldnam, newnam) 109 | char *oldnam, *newnam; 110 | { 111 | FILE *fopen(), *old, *new; 112 | #if !_MTS 113 | struct stat oldstat; 114 | #endif 115 | VOID filecopy(); 116 | #if GEMDOS 117 | if (Frename(0, oldnam, newnam)) 118 | #else 119 | if (rename(oldnam, newnam)) 120 | #endif 121 | #if !_MTS 122 | { 123 | if (stat(oldnam, &oldstat)) /* different partition? */ 124 | return (-1); 125 | old = fopen(oldnam, OPEN_R); 126 | if (old == NULL) 127 | return (-1); 128 | new = fopen(newnam, OPEN_W); 129 | if (new == NULL) 130 | return (-1); 131 | filecopy(old, new, oldstat.st_size); 132 | return(unlink(oldnam)); 133 | } 134 | return 0; 135 | #else 136 | return(-1); 137 | #endif 138 | } 139 | 140 | static VOID 141 | _makefn(source, dest) 142 | char *source; 143 | char *dest; 144 | { 145 | int j; 146 | #if MSDOS 147 | char *setmem(); 148 | #endif 149 | 150 | setmem(dest, 17, 0); /* clear result field */ 151 | for (j = 0; *source && *source != '.'; ++source) 152 | if (j < 8) 153 | dest[j++] = *source; 154 | for (j = 9; *source; ++source) 155 | if (j < 13) 156 | dest[j++] = *source; 157 | } 158 | /* 159 | * make a file name using a template 160 | */ 161 | 162 | char * 163 | makefnam(rawfn, template, result) 164 | char *rawfn; /* the original file name */ 165 | char *template; /* the template data */ 166 | char *result; /* where to place the result */ 167 | { 168 | char et[17], er[17], rawbuf[STRLEN], *i; 169 | 170 | *rawbuf = 0; 171 | strcpy(rawbuf, rawfn); 172 | #if _MTS 173 | i = rawbuf; 174 | if (rawbuf[0] == tmpchr[0]) { 175 | i++; 176 | strcpy(rawfn, i); 177 | } else 178 | #endif 179 | if ((i = rindex(rawbuf, CUTOFF))) { 180 | i++; 181 | strcpy(rawfn, i); 182 | } 183 | #if DOS 184 | else if ((i = rindex(rawbuf, ':'))) { 185 | i++; 186 | strcpy(rawfn, i); 187 | } 188 | #endif 189 | if (i) 190 | *i = 0; 191 | else 192 | *rawbuf = 0; 193 | 194 | _makefn(template, et); 195 | _makefn(rawfn, er); 196 | *result = 0; /* assure no data */ 197 | strcat(result, rawbuf); 198 | strcat(result, er[0] ? er : et); 199 | strcat(result, er[9] ? er + 9 : et + 9); 200 | return ((char *) &result[0]); 201 | } 202 | 203 | #if NEED_ALPHASORT 204 | 205 | int 206 | alphasort(dirptr1, dirptr2) 207 | struct DIRECT **dirptr1, **dirptr2; 208 | { 209 | return (strcmp((*dirptr1)->d_name, (*dirptr2)->d_name)); 210 | } 211 | 212 | #endif 213 | 214 | VOID 215 | upper(string) 216 | char *string; 217 | { 218 | char *p; 219 | 220 | for (p = string; *p; p++) 221 | if (islower(*p)) 222 | *p = toupper(*p); 223 | } 224 | /* VARARGS1 */ 225 | VOID 226 | arcdie(s, arg1, arg2, arg3) 227 | char *s; 228 | { 229 | fprintf(stderr, "ARC: "); 230 | fprintf(stderr, s, arg1, arg2, arg3); 231 | fprintf(stderr, "\n"); 232 | #if UNIX 233 | perror("UNIX"); 234 | #endif 235 | #if GEMDOS 236 | exitpause(); 237 | #endif 238 | exit(1); 239 | } 240 | 241 | #if !_MTS 242 | 243 | char * 244 | gcdir(dirname) 245 | char *dirname; 246 | 247 | { 248 | char *getcwd(); 249 | #if GEMDOS 250 | int drv; 251 | char *buf; 252 | #endif 253 | if (dirname == NULL || strlen(dirname) == 0) 254 | dirname = (char *) malloc(1024); 255 | 256 | #if !GEMDOS 257 | getcwd(dirname, 1024); 258 | #else 259 | buf = dirname; 260 | *buf++ = (drv = Dgetdrv()) + 'A'; 261 | *buf++ = ':'; 262 | Dgetpath(buf, 0); 263 | #endif 264 | return (dirname); 265 | } 266 | 267 | #if UNIX 268 | char *pattern; /* global so that fmatch can use it */ 269 | #endif 270 | 271 | char * 272 | dir(filename) /* get files, one by one */ 273 | char *filename; /* template, or NULL */ 274 | { 275 | #if GEMDOS 276 | static int Nnum = 0; 277 | #if __GNUC__ 278 | #define d_fname dta_name /* Wish these libraries would agree on names */ 279 | #define DMABUFFER _DTA 280 | #endif 281 | static DMABUFFER dbuf, *saved; 282 | char *name; 283 | if (Nnum == 0) { /* first call */ 284 | saved = (DMABUFFER *) Fgetdta(); 285 | Fsetdta(&dbuf); 286 | if (Fsfirst(filename, 0) == 0) { 287 | name = malloc(FNLEN); 288 | strcpy(name, dbuf.d_fname); 289 | Nnum++; 290 | return (name); 291 | } else { 292 | Fsetdta(saved); 293 | return (NULL); 294 | } 295 | } else { 296 | if (Fsnext() == 0) { 297 | name = malloc(FNLEN); 298 | strcpy(name, dbuf.d_fname); 299 | return (name); 300 | } else { 301 | Nnum = 0; 302 | Fsetdta(saved); 303 | return (NULL); 304 | } 305 | } 306 | } 307 | #else 308 | static struct DIRECT **namelist; 309 | static char **NameList; 310 | static char namecopy[STRLEN], *dirname; 311 | #if UNIX 312 | int alphasort(); 313 | int scandir(); 314 | #endif /* UNIX */ 315 | int fmatch(); 316 | static int Nnum = 0, ii; 317 | 318 | 319 | if (Nnum == 0) { /* first call */ 320 | strcpy(namecopy,filename); 321 | if((pattern=rindex(namecopy,CUTOFF))) { 322 | *pattern = 0; 323 | pattern++; 324 | dirname = namecopy; 325 | } else { 326 | pattern = filename; 327 | dirname = "."; 328 | } 329 | Nnum = scandir(dirname, &namelist, fmatch, alphasort); 330 | NameList = (char **) malloc(Nnum * sizeof(char *)); 331 | for (ii = 0; ii < Nnum; ii++) { 332 | (NameList)[ii] = malloc(strlen(namelist[ii]->d_name) + 1); 333 | strcpy((NameList)[ii], namelist[ii]->d_name); 334 | } 335 | ii = 0; 336 | } 337 | if (ii >= Nnum) { /* all out of files */ 338 | if (Nnum) { /* there were some files found */ 339 | for (ii = 0; ii < Nnum; ii++) 340 | free(namelist[ii]); 341 | free(namelist); 342 | } 343 | Nnum = 0; 344 | return (NULL); 345 | } else { 346 | return ((NameList)[ii++]); 347 | } 348 | } 349 | 350 | /* 351 | * Filename match - here, * matches everything 352 | */ 353 | 354 | int 355 | fmatch(direntry) 356 | struct DIRECT *direntry; 357 | { 358 | char *string; 359 | 360 | string = direntry->d_name; 361 | 362 | if (!strcmp(pattern, "") || !strcmp(pattern, "*.*") || !strcmp(pattern, "*")) 363 | return (1); 364 | return (match(string, pattern)); 365 | } 366 | #endif /* GEMDOS */ 367 | #else 368 | /* dir code for MTS under Bell Labs C... */ 369 | 370 | char * 371 | dir(filepattern) 372 | char *filepattern; /* template or NULL */ 373 | { 374 | #if USECATSCAN 375 | fortran VOID catscan(), fileinfo(); 376 | 377 | struct catname { 378 | short len; 379 | char name[257]; 380 | } pattern; 381 | 382 | struct catval { 383 | int maxlen; 384 | int actlen; 385 | char name[257]; 386 | } catreturn; 387 | 388 | char *i; 389 | int j, RETCODE; 390 | 391 | static int catptr = 0; 392 | static int catflag = 0x200; 393 | static int cattype = 1; 394 | static int patflag = 0; 395 | 396 | catreturn.maxlen = 256; 397 | 398 | if (patflag) { 399 | patflag = 0; 400 | catptr = 0; 401 | return (NULL); 402 | } 403 | if (filepattern) { 404 | strcpy(pattern.name, filepattern); 405 | pattern.len = strlen(filepattern); 406 | if (!index(filepattern, '?')) 407 | patflag = 1; 408 | } 409 | if (patflag) { 410 | fileinfo(&pattern, &cattype, "CINAME ", &catreturn, _retcode RETCODE); 411 | catptr = RETCODE ? 0 : 1; 412 | } else 413 | catscan(&pattern, &catflag, &cattype, &catreturn, &catptr); 414 | 415 | if (!catptr) 416 | return (NULL); 417 | else { 418 | char *k; 419 | 420 | /* k = index(catreturn.name, ' '); 421 | if (k) 422 | *k = 0; 423 | else { This seems unnecessary now */ 424 | j = catreturn.actlen; 425 | catreturn.name[j] = 0; 426 | /* } */ 427 | k = catreturn.name; 428 | if (*k == tmpchr[0]) 429 | k++; 430 | else if ((k = index(catreturn.name, sepchr[0]))) 431 | k++; 432 | else 433 | k = catreturn.name; 434 | j = strlen(k); 435 | i = malloc(++j); 436 | strcpy(i, k); 437 | return (i); 438 | } 439 | #else 440 | fortran VOID gfinfo(); 441 | static char gfname[24]; 442 | static char pattern[20]; 443 | static int gfdummy[2] = { 444 | 0, 0 445 | }, gfflags; 446 | int i, RETCODE; 447 | char *j, *k; 448 | 449 | if (filepattern) { 450 | strcpy(pattern, filepattern); 451 | strcat(pattern, " "); 452 | for (i = 20; i < 24; i++) 453 | gfname[i] = '\0'; 454 | if (index(pattern, '?')) 455 | gfflags = 0x0C; 456 | else 457 | gfflags = 0x09; 458 | } else if (gfflags == 0x09) 459 | return (NULL); 460 | 461 | gfinfo(pattern, gfname, &gfflags, gfdummy, gfdummy, gfdummy, _retcode RETCODE); 462 | if (RETCODE) 463 | return (NULL); 464 | else { 465 | k = index(gfname, ' '); 466 | *k = '\0'; 467 | k = gfname; 468 | if (gfname[0] == tmpchr[0]) 469 | k++; 470 | else if ((k = index(gfname, sepchr[0]))) 471 | k++; 472 | else 473 | k = gfname; 474 | i = strlen(k); 475 | j = malloc(++i); 476 | strcpy(j, k); 477 | return (j); 478 | } 479 | #endif 480 | } 481 | 482 | int 483 | unlink(path) 484 | char *path; /* name of file to delete */ 485 | { 486 | fortran VOID destroy(); 487 | int RETCODE; 488 | 489 | char name[258]; 490 | 491 | strcpy(name, path); 492 | strcat(name, " "); 493 | destroy(name, _retcode RETCODE); 494 | if (RETCODE) 495 | return (-1); 496 | else 497 | return (0); 498 | } 499 | #endif 500 | -------------------------------------------------------------------------------- /arcpack.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcpack.c,v 1.3 2005/10/09 02:14:47 highlandsun Exp $ 3 | */ 4 | 5 | /* ARC - Archive utility - ARCPACK 6 | 7 | Version 3.49, created on 04/21/87 at 11:26:51 8 | 9 | (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED 10 | 11 | By: Thom Henderson 12 | 13 | Description: 14 | This file contains the routines used to compress a file 15 | when placing it in an archive. 16 | 17 | Language: 18 | Computer Innovations Optimizing C86 19 | */ 20 | #include 21 | #include "arc.h" 22 | #if _MTS 23 | #include 24 | #endif 25 | 26 | #include "proto.h" 27 | 28 | VOID setcode(), init_cm(), codebuf(); 29 | VOID arcdie(), init_sq(), flsh_cm(); 30 | int crcbuf(); 31 | u_int ncr_buf(); 32 | 33 | int lastc; 34 | 35 | /* stuff for non-repeat packing */ 36 | 37 | #define DLE 0x90 /* repeat sequence marker */ 38 | 39 | u_char state; /* current packing state */ 40 | 41 | /* non-repeat packing states */ 42 | 43 | #define NOHIST 0 /* don't consider previous input */ 44 | #define SENTCHAR 1 /* lastchar set, no lookahead yet */ 45 | 46 | extern u_char *pinbuf; 47 | extern u_char *pakbuf; /* worst case, 2*inbuf */ 48 | 49 | /* packing results */ 50 | 51 | long stdlen; /* length for standard packing */ 52 | short crcval; /* CRC check value */ 53 | 54 | VOID 55 | pack(f, t, hdr) /* pack file into an archive */ 56 | FILE *f, *t; /* source, destination */ 57 | struct heads *hdr; /* pointer to header data */ 58 | { 59 | long ncrlen; /* length after packing */ 60 | long huflen; /* length after squeezing */ 61 | long lzwlen; /* length after crunching */ 62 | long pred_sq(), head_sq(), huf_buf(); /* stuff for squeezing */ 63 | long pred_cm(); /* dynamic crunching cleanup */ 64 | long tloc, ftell(); /* start of output */ 65 | u_int inbytes = 0, pakbytes = 0; 66 | 67 | /* first pass - see which method is best */ 68 | 69 | tloc = ftell(t); /* note start of output */ 70 | 71 | if (!nocomp) { /* if storage kludge not active */ 72 | if (note) { 73 | printf(" analyzing, "); 74 | fflush(stdout); 75 | } 76 | state = NOHIST; /* initialize ncr packing */ 77 | stdlen = ncrlen = 0; /* reset size counters */ 78 | huflen = lzwlen = 0; 79 | crcval = 0; /* initialize CRC check value */ 80 | setcode(); /* initialize encryption */ 81 | init_sq(); /* initialize for squeeze scan */ 82 | 83 | inbytes = getbuf(f); 84 | if (inbytes) { 85 | 86 | init_cm(pinbuf); 87 | 88 | for (;; inbytes = getbuf(f)) { 89 | pakbytes = ncr_buf(inbytes); 90 | ncrlen += pakbytes; 91 | hufb_tab(pakbuf, pakbytes); 92 | if (dosquash) 93 | lzw_buf(pinbuf, inbytes, t); 94 | else 95 | lzw_buf(pakbuf, pakbytes, t); 96 | if (inbytes < MYBUF) 97 | break; 98 | } 99 | lzwlen = pred_cm(t); 100 | huflen = pred_sq(); 101 | } 102 | } else { /* else kludge the method */ 103 | stdlen = 0; /* make standard look best */ 104 | ncrlen = huflen = lzwlen = 1; 105 | } 106 | 107 | /* standard set-ups common to all methods */ 108 | 109 | hdr->crc = crcval; /* note CRC check value */ 110 | hdr->length = stdlen; /* set actual file length */ 111 | if (stdlen > MYBUF) { 112 | fseek(f, 0L, 0);/* rewind input */ 113 | state = NOHIST; /* reinitialize ncr packing */ 114 | setcode(); /* reinitialize encryption */ 115 | } else 116 | inbytes = stdlen; 117 | 118 | /* choose and use the shortest method */ 119 | 120 | if (kludge && note) 121 | printf("\n\tS:%ld P:%ld S:%ld C:%ld,\t ", 122 | stdlen, ncrlen, huflen, lzwlen); 123 | 124 | if (stdlen <= ncrlen && stdlen <= huflen && stdlen <= lzwlen) { 125 | if (note) { 126 | printf("storing, "); /* store without compression */ 127 | fflush(stdout); 128 | } 129 | hdrver = 2; /* note packing method */ 130 | fseek(t, tloc, 0); /* reset output for new method */ 131 | if (nocomp || (stdlen > MYBUF)) { 132 | stdlen = crcval = 0; 133 | while ((inbytes = getbuf(f)) != 0) 134 | putb_pak(pinbuf, inbytes, t); /* store it straight */ 135 | } else 136 | putb_pak(pinbuf, inbytes, t); 137 | hdr->crc = crcval; 138 | hdr->length = hdr->size = stdlen; 139 | } else if (ncrlen < lzwlen && ncrlen < huflen) { 140 | if (note) { 141 | printf("packing, "); /* pack with repeat */ 142 | fflush(stdout); /* suppression */ 143 | } 144 | hdrver = 3; /* note packing method */ 145 | hdr->size = ncrlen; /* set data length */ 146 | fseek(t, tloc, 0); /* reset output for new method */ 147 | if (stdlen > MYBUF) { 148 | do { 149 | inbytes = getbuf(f); 150 | pakbytes = ncr_buf(inbytes); 151 | putb_pak(pakbuf, pakbytes, t); 152 | } while (inbytes != 0); 153 | } else 154 | putb_pak(pakbuf, pakbytes, t); 155 | } else if (huflen < lzwlen) { 156 | if (note) { 157 | printf("squeezing, "); 158 | fflush(stdout); 159 | } 160 | hdrver = 4; /* note packing method */ 161 | fseek(t, tloc, 0); /* reset output for new method */ 162 | huflen = head_sq(); 163 | if (stdlen > MYBUF) { 164 | do { 165 | inbytes = getbuf(f); 166 | pakbytes = ncr_buf(inbytes); 167 | huflen += huf_buf(pakbuf, pakbytes, inbytes, t); 168 | } while (inbytes != 0); 169 | } else 170 | huflen += huf_buf(pakbuf, pakbytes, 0, t); 171 | 172 | hdr->size = huflen; /* note final size */ 173 | } else { 174 | if (note) 175 | printf(dosquash ? "squashed, " : "crunched, "); 176 | flsh_cm(t); 177 | hdrver = dosquash ? 9 : 8; 178 | hdr->size = lzwlen; /* size should not change */ 179 | } 180 | 181 | /* standard cleanups common to all methods */ 182 | 183 | if (note) 184 | printf("done. (%ld%%)\n", hdr->length == 0 ? 185 | 0L : 100L - (100L * hdr->size) / hdr->length); 186 | } 187 | 188 | /* 189 | * Non-repeat compression - text is passed through normally, except that a 190 | * run of more than two is encoded as: 191 | * 192 | * 193 | * 194 | * Special case: a count of zero indicates that the DLE is really a DLE, not a 195 | * repeat marker. 196 | */ 197 | 198 | u_int 199 | ncr_buf(inbytes) 200 | u_int inbytes; /* number of bytes in inbuf */ 201 | { 202 | u_int i; 203 | int c; 204 | reg u_char *inptr, *pakptr; 205 | static int cnt; 206 | 207 | inptr = pinbuf; 208 | pakptr = pakbuf; 209 | 210 | if (state == NOHIST) { 211 | lastc = (-1); 212 | cnt = 1; 213 | state = SENTCHAR; 214 | } 215 | for (i = 0; i < inbytes; i++) { 216 | c = *inptr++; 217 | if (c == lastc && cnt < 255) 218 | cnt++; 219 | else { 220 | if (cnt == 2) { 221 | *pakptr++ = lastc; 222 | } else if (cnt > 2) { 223 | *pakptr++ = DLE; 224 | *pakptr++ = cnt; 225 | } 226 | *pakptr++ = c; 227 | lastc = c; 228 | cnt = 1; 229 | } 230 | if (c == DLE) { 231 | *pakptr++ = '\0'; 232 | lastc = (-1); 233 | } 234 | } 235 | if (inbytes < MYBUF && cnt > 1) { /* trailing stuff */ 236 | if (cnt == 2) 237 | *pakptr++ = lastc; 238 | else { 239 | *pakptr++ = DLE; 240 | *pakptr++ = cnt; 241 | } 242 | } 243 | return (pakptr - pakbuf); 244 | } 245 | 246 | u_int 247 | getbuf(f) 248 | FILE *f; 249 | { 250 | u_int i; 251 | #if !DOS 252 | int c; 253 | static int cr = 0; 254 | register u_char *ptr; 255 | if (image) { 256 | #endif 257 | i = fread(pinbuf, 1, MYBUF, f); 258 | #if !DOS 259 | } else { 260 | ptr = pinbuf; 261 | for (i = 0, c = 0; (c != EOF) && (i < MYBUF); i++) { 262 | if (cr) { 263 | c = '\n'; 264 | cr = 0; 265 | } else { 266 | c = fgetc(f); 267 | if (c == EOF) 268 | break; 269 | else if (c == '\n') { 270 | c = '\r'; 271 | cr = 1; 272 | } 273 | } 274 | *ptr++ = c; 275 | } 276 | #if _MTS 277 | etoa(pinbuf, i); 278 | #endif /* _MTS */ 279 | } 280 | #endif /* !DOS */ 281 | crcval = crcbuf(crcval, i, pinbuf); 282 | stdlen += i; 283 | return (i); 284 | } 285 | 286 | VOID 287 | putb_pak(buf, len, f) 288 | u_char *buf; 289 | u_int len; 290 | FILE *f; 291 | { 292 | u_int i; 293 | 294 | if (f && len) { 295 | if (password) 296 | codebuf(buf, len); 297 | i = fwrite(buf, 1, len, f); 298 | if (i != len) 299 | arcdie("Write failed"); 300 | } 301 | } 302 | -------------------------------------------------------------------------------- /arcrun.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcrun.c,v 1.8 2005/10/12 15:22:18 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCRUN 7 | * 8 | * Version 1.20, created on 03/24/86 at 19:34:31 9 | * 10 | * (C) COPYRIGHT 1985,85 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to "run" a file which is 15 | * stored in an archive. At present, all we really do is (a) extract a 16 | * temporary file, (b) give its name as a system command, and then (c) delete 17 | * the file. 18 | * 19 | * Language: Computer Innovations Optimizing C86 20 | */ 21 | #include 22 | #include 23 | #include "arc.h" 24 | #if UNIX 25 | #include 26 | #include 27 | #endif 28 | 29 | VOID rempath(), openarc(), closearc(), arcdie(); 30 | int readhdr(), match(), unpack(); 31 | static VOID runfile(); 32 | FILE *tmpopen(); 33 | 34 | VOID 35 | runarc(num, arg) /* run file from archive */ 36 | int num; /* number of arguments */ 37 | char *arg[]; /* pointers to arguments */ 38 | { 39 | struct heads hdr; /* file header */ 40 | char *makefnam(); /* filename fixer */ 41 | char buf[STRLEN]; /* filename buffer */ 42 | FILE *fopen();/* file opener */ 43 | char *dummy[2]; 44 | 45 | dummy[0]="dummy"; 46 | dummy[1]=NULL; 47 | rempath(num, arg); /* strip off paths */ 48 | 49 | openarc(0); /* open archive for reading */ 50 | 51 | if (num) { /* if files were named */ 52 | while (readhdr(&hdr, arc)) { /* while more files to check */ 53 | if (match(hdr.name, makefnam(arg[0], ".*", buf))) 54 | runfile(&hdr, num, arg); 55 | else 56 | fseek(arc, hdr.size, 1); 57 | } 58 | } else 59 | while (readhdr(&hdr, arc)) /* else run all files */ 60 | runfile(&hdr, 1, dummy); 61 | 62 | closearc(0); /* close archive after changes */ 63 | } 64 | 65 | static VOID 66 | runfile(hdr, num, arg) /* run a file */ 67 | struct heads *hdr; /* pointer to header data */ 68 | int num; /* number of arguments */ 69 | char *arg[]; /* pointers to arguments */ 70 | { 71 | FILE *tmp, *fopen(); /* temporary file */ 72 | char buf[STRLEN], *makefnam(); /* temp file name, fixer */ 73 | #if DOS 74 | char nbuf[64], *i, *rindex(); 75 | #endif 76 | #if !GEMDOS 77 | int n; /* index */ 78 | char sys[STRLEN]; /* invocation command buffer */ 79 | #endif 80 | 81 | /* makefnam("$ARCTEMP",hdr->name,buf); */ 82 | #if UNIX 83 | sprintf(buf, "%s.RUN", arctemp); 84 | strcpy(sys, buf); 85 | #else 86 | strcpy(nbuf, arctemp); 87 | makefnam(nbuf,hdr->name,buf); 88 | i = rindex(buf,'.'); 89 | #endif 90 | #if MSDOS 91 | if (!strcmp(i, ".BAS")) { 92 | strcpy(sys, "BASICA "); 93 | strcat(sys, buf); 94 | } 95 | else if (!strcmp(i, ".BAT") 96 | || !strcmp(i, ".COM") 97 | || !strcmp(i, ".EXE")) 98 | strcpy(sys, buf); 99 | 100 | else { 101 | if (warn) { 102 | printf("File %s is not a .BAS, .BAT, .COM, or .EXE\n", 103 | hdr->name); 104 | nerrs++; 105 | } 106 | fseek(arc, hdr->size, 1); /* skip this file */ 107 | return; 108 | } 109 | #endif 110 | #if GEMDOS 111 | if (strcmp(i, ".PRG") 112 | && strcmp(i, ".TTP") 113 | && strcmp(i, ".TOS")) 114 | { 115 | if (warn) { 116 | printf("File %s is not a .PRG, .TOS, or .TTP\n", 117 | hdr->name); 118 | nerrs++; 119 | } 120 | fseek(arc, hdr->size, 1); /* skip this file */ 121 | return; 122 | } 123 | #endif 124 | 125 | if (warn) 126 | if ((tmp = fopen(buf, "r"))) 127 | arcdie("Temporary file %s already exists", buf); 128 | if (!(tmp = tmpopen(buf))) 129 | arcdie("Unable to create temporary file %s", buf); 130 | 131 | if (note) 132 | printf("Invoking file: %s\n", hdr->name); 133 | 134 | unpack(arc, tmp, hdr); /* unpack the entry */ 135 | fclose(tmp); /* release the file */ 136 | #if UNIX 137 | chmod(buf, 0700); /* make it executable */ 138 | #endif 139 | #if GEMDOS 140 | execve(buf, arg, NULL); 141 | #else 142 | for (n = 1; n < num; n++) { /* add command line arguments */ 143 | strcat(sys, " "); 144 | strcat(sys, arg[n]); 145 | } 146 | if (system(buf)) /* try to invoke it */ 147 | arcdie("Execution failed for %s", buf); 148 | #endif 149 | if (unlink(buf) && warn) { 150 | printf("Cannot unsave temporary file %s\n", buf); 151 | nerrs++; 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /arcs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcs.h,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - Archive file header format 7 | * 8 | * Version 2.12, created on 12/17/85 at 14:40:26 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file defines the format of an archive file header, 15 | * excluding the archive marker and the header version number. 16 | * 17 | * Each entry in an archive begins with a one byte archive marker, which is set 18 | * to 26. The marker is followed by a one byte header type code, from zero 19 | * to 7. 20 | * 21 | * If the header type code is zero, then it is an end marker, and no more data 22 | * should be read from the archive. 23 | * 24 | * If the header type code is in the range 2 to 7, then it is followed by a 25 | * standard archive header, which is defined below. 26 | * 27 | * If the header type code is one, then it is followed by an older format 28 | * archive header. The older format header does not contain the true length. 29 | * A header should be read for a length of sizeof(struct heads)-sizeof(long). 30 | * Then set length equal to size and change the header version to 2. 31 | * 32 | * Programming note: The crc value given in the header is based on the unpacked 33 | * data. 34 | * 35 | * Language: Computer Innovations Optimizing C86 36 | */ 37 | 38 | struct heads { /* archive entry header format */ 39 | char name[FNLEN]; /* file name */ 40 | long size; /* size of file, in bytes */ 41 | unsigned short date; /* creation date */ 42 | unsigned short time; /* creation time */ 43 | short crc; /* cyclic redundancy check */ 44 | long length; /* true file length */ 45 | }; 46 | -------------------------------------------------------------------------------- /arcsq.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcsq.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCSQ 7 | * 8 | * Version 3.10, created on 01/30/86 at 20:10:46 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to squeeze a file when 15 | * placing it in an archive. 16 | * 17 | * Language: Computer Innovations Optimizing C86 18 | * 19 | * Programming notes: Most of the routines used for the Huffman squeezing 20 | * algorithm were lifted from the SQ program by Dick Greenlaw, as adapted to 21 | * CI-C86 by Robert J. Beilstein. 22 | */ 23 | #include 24 | #include "arc.h" 25 | 26 | #include "proto.h" 27 | 28 | /* stuff for Huffman squeezing */ 29 | 30 | #define TRUE 1 31 | #define FALSE 0 32 | #define ERROR (-1) 33 | #define SPEOF 256 /* special endfile token */ 34 | #define NOCHILD (-1) /* marks end of path through tree */ 35 | #define NUMVALS 257 /* 256 data values plus SPEOF */ 36 | #define NUMNODES (NUMVALS+NUMVALS-1) /* number of nodes */ 37 | #define MAXCOUNT (u_short) 65535/* biggest unsigned integer */ 38 | 39 | /* 40 | * The following array of structures are the nodes of the binary trees. The 41 | * first NUMVALS nodes become the leaves of the final tree and represent the 42 | * values of the data bytes being encoded and the special endfile, SPEOF. The 43 | * remaining nodes become the internal nodes of the final tree. 44 | */ 45 | 46 | struct nd { /* shared by unsqueezer */ 47 | u_short weight; /* number of appearances */ 48 | short tdepth; /* length on longest path in tree */ 49 | short lchild, rchild; /* indices to next level */ 50 | } node[NUMNODES]; /* use large buffer */ 51 | 52 | static int dctreehd; /* index to head of final tree */ 53 | 54 | /* 55 | * This is the encoding table: The bit strings have first bit in low bit. 56 | * Note that counts were scaled so code fits unsigned integer. 57 | */ 58 | 59 | static int codelen[NUMVALS]; /* number of bits in code */ 60 | static u_short code[NUMVALS]; /* code itself, right adjusted */ 61 | static u_short tcode; /* temporary code value */ 62 | static long valcount[NUMVALS]; /* actual count of times seen */ 63 | 64 | /* Variables used by encoding process */ 65 | 66 | int curin; /* value currently being encoded */ 67 | static int cbitsrem; /* # of code string bits left */ 68 | static u_short ccode; /* current code right justified */ 69 | 70 | static VOID scale(), heap(), adjust(), bld_tree(), init_enc(); 71 | static int cmptrees(), buildenc(); 72 | 73 | extern u_char *outbuf, *outbeg, *outend; 74 | 75 | VOID 76 | init_sq() 77 | { /* prepare for scanning pass */ 78 | int i; /* node index */ 79 | 80 | /* 81 | * Initialize all nodes to single element binary trees with zero 82 | * weight and depth. 83 | */ 84 | 85 | for (i = 0; i < NUMNODES; ++i) { 86 | node[i].weight = 0; 87 | node[i].tdepth = 0; 88 | node[i].lchild = NOCHILD; 89 | node[i].rchild = NOCHILD; 90 | } 91 | 92 | for (i = 0; i < NUMVALS; i++) 93 | valcount[i] = 0; 94 | } 95 | 96 | VOID 97 | hufb_tab(buf, len) /* add a byte to the tables */ 98 | u_char *buf; 99 | u_int len; 100 | { 101 | for (; len > 0; len--) { 102 | 103 | /* Build frequency info in tree */ 104 | 105 | if (node[*buf].weight != MAXCOUNT) 106 | node[*buf].weight++; /* bump weight counter */ 107 | 108 | valcount[*buf++]++; /* bump byte counter */ 109 | } 110 | } 111 | 112 | long 113 | pred_sq() 114 | { /* predict size of squeezed file */ 115 | int i; 116 | int btlist[NUMVALS]; /* list of intermediate 117 | * b-trees */ 118 | int listlen;/* length of btlist */ 119 | u_short ceiling;/* limit for scaling */ 120 | long size = 0; /* predicted size */ 121 | int numnodes; /* # of nodes in simplified tree */ 122 | 123 | node[SPEOF].weight = 1; /* signal end of input */ 124 | valcount[SPEOF] = 1; 125 | 126 | ceiling = MAXCOUNT; 127 | 128 | /* Keep trying to scale and encode */ 129 | 130 | do { 131 | scale(ceiling); 132 | ceiling /= 2; /* in case we rescale */ 133 | 134 | /* 135 | * Build list of single node binary trees having leaves for 136 | * the input values with non-zero counts 137 | */ 138 | 139 | for (i = listlen = 0; i < NUMVALS; ++i) { 140 | if (node[i].weight != 0) { 141 | node[i].tdepth = 0; 142 | btlist[listlen++] = i; 143 | } 144 | } 145 | 146 | /* 147 | * Arrange list of trees into a heap with the entry indexing 148 | * the node with the least weight at the top. 149 | */ 150 | 151 | heap(btlist, listlen); 152 | 153 | /* Convert the list of trees to a single decoding tree */ 154 | 155 | bld_tree(btlist, listlen); 156 | 157 | /* Initialize the encoding table */ 158 | 159 | init_enc(); 160 | 161 | /* 162 | * Try to build encoding table. Fail if any code is > 16 bits 163 | * long. 164 | */ 165 | } while (buildenc(0, dctreehd) == ERROR); 166 | 167 | /* Initialize encoding variables */ 168 | 169 | cbitsrem = 0; /* force initial read */ 170 | curin = 0; /* anything but endfile */ 171 | 172 | for (i = 0; i < NUMVALS; i++) /* add bits for each code */ 173 | size += valcount[i] * codelen[i]; 174 | 175 | size = (size + 7) / 8; /* reduce to number of bytes */ 176 | 177 | numnodes = dctreehd < NUMVALS ? 0 : dctreehd - (NUMVALS - 1); 178 | 179 | size += sizeof(short) + 2 * numnodes * sizeof(short); 180 | 181 | return size; 182 | } 183 | 184 | /* 185 | * The count of number of occurrances of each input value have already been 186 | * prevented from exceeding MAXCOUNT. Now we must scale them so that their 187 | * sum doesn't exceed ceiling and yet no non-zero count can become zero. This 188 | * scaling prevents errors in the weights of the interior nodes of the 189 | * Huffman tree and also ensures that the codes will fit in an unsigned 190 | * integer. Rescaling is used if necessary to limit the code length. 191 | */ 192 | 193 | static VOID 194 | scale(ceil) 195 | u_short ceil; /* upper limit on total weight */ 196 | { 197 | register int i; 198 | int ovflw, divisor; 199 | u_short w, sum; 200 | unsigned char increased; /* flag */ 201 | 202 | do { 203 | for (i = sum = ovflw = 0; i < NUMVALS; ++i) { 204 | if (node[i].weight > (ceil - sum)) 205 | ++ovflw; 206 | sum += node[i].weight; 207 | } 208 | 209 | divisor = ovflw + 1; 210 | 211 | /* Ensure no non-zero values are lost */ 212 | 213 | increased = FALSE; 214 | for (i = 0; i < NUMVALS; ++i) { 215 | w = node[i].weight; 216 | if (w < divisor && w != 0) { /* Don't fail to provide 217 | * a code if it's used 218 | * at all */ 219 | 220 | node[i].weight = divisor; 221 | increased = TRUE; 222 | } 223 | } 224 | } while (increased); 225 | 226 | /* Scaling factor chosen, now scale */ 227 | 228 | if (divisor > 1) 229 | for (i = 0; i < NUMVALS; ++i) 230 | node[i].weight /= divisor; 231 | } 232 | 233 | /* 234 | * heap() and adjust() maintain a list of binary trees as a heap with the top 235 | * indexing the binary tree on the list which has the least weight or, in 236 | * case of equal weights, least depth in its longest path. The depth part is 237 | * not strictly necessary, but tends to avoid long codes which might provoke 238 | * rescaling. 239 | */ 240 | 241 | static VOID 242 | heap(list, length) 243 | int list[], length; 244 | { 245 | register int i; 246 | 247 | for (i = (length - 2) / 2; i >= 0; --i) 248 | adjust(list, i, length - 1); 249 | } 250 | 251 | /* Make a heap from a heap with a new top */ 252 | 253 | static VOID 254 | adjust(list, top, bottom) 255 | int list[], top, bottom; 256 | { 257 | register int k, temp; 258 | 259 | k = 2 * top + 1; /* left child of top */ 260 | temp = list[top]; /* remember root node of top tree */ 261 | 262 | if (k <= bottom) { 263 | if (k < bottom && cmptrees(list[k], list[k + 1])) 264 | ++k; 265 | 266 | /* k indexes "smaller" child (in heap of trees) of top */ 267 | /* now make top index "smaller" of old top and smallest child */ 268 | 269 | if (cmptrees(temp, list[k])) { 270 | list[top] = list[k]; 271 | list[k] = temp; 272 | 273 | /* Make the changed list a heap */ 274 | 275 | adjust(list, k, bottom); /* recursive */ 276 | } 277 | } 278 | } 279 | 280 | /* 281 | * Compare two trees, if a > b return true, else return false. Note 282 | * comparison rules in previous comments. 283 | */ 284 | 285 | static int 286 | cmptrees(a, b) 287 | int a, b; /* root nodes of trees */ 288 | { 289 | if (node[a].weight > node[b].weight) 290 | return TRUE; 291 | if (node[a].weight == node[b].weight) 292 | if (node[a].tdepth > node[b].tdepth) 293 | return TRUE; 294 | return FALSE; 295 | } 296 | 297 | /* 298 | * HUFFMAN ALGORITHM: develops the single element trees into a single binary 299 | * tree by forming subtrees rooted in interior nodes having weights equal to 300 | * the sum of weights of all their descendents and having depth counts 301 | * indicating the depth of their longest paths. 302 | * 303 | * When all trees have been formed into a single tree satisfying the heap 304 | * property (on weight, with depth as a tie breaker) then the binary code 305 | * assigned to a leaf (value to be encoded) is then the series of left (0) 306 | * and right (1) paths leading from the root to the leaf. Note that trees are 307 | * removed from the heaped list by moving the last element over the top 308 | * element and reheaping the shorter list. 309 | */ 310 | 311 | #define MAXCHAR(a,b) ((a > b) ? a : b) 312 | 313 | static VOID 314 | bld_tree(list, len) 315 | int list[]; 316 | int len; 317 | { 318 | register int freenode; /* next free node in tree */ 319 | register struct nd *frnp; /* free node pointer */ 320 | int lch, rch; /* temps for left, right children */ 321 | 322 | /* 323 | * Initialize index to next available (non-leaf) node. Lower numbered 324 | * nodes correspond to leaves (data values). 325 | */ 326 | 327 | freenode = NUMVALS; 328 | 329 | while (len > 1) { /* Take from list two btrees with least 330 | * weight and build an interior node pointing 331 | * to them. This forms a new tree. */ 332 | 333 | lch = list[0]; /* This one will be left child */ 334 | 335 | /* delete top (least) tree from the list of trees */ 336 | 337 | list[0] = list[--len]; 338 | adjust(list, 0, len - 1); 339 | 340 | /* Take new top (least) tree. Reuse list slot later */ 341 | 342 | rch = list[0]; /* This one will be right child */ 343 | 344 | /* 345 | * Form new tree from the two least trees using a free node 346 | * as root. Put the new tree in the list. 347 | */ 348 | 349 | frnp = &node[freenode]; /* address of next free node */ 350 | list[0] = freenode++; /* put at top for now */ 351 | frnp->lchild = lch; 352 | frnp->rchild = rch; 353 | frnp->weight = node[lch].weight + node[rch].weight; 354 | frnp->tdepth = 1 + MAXCHAR(node[lch].tdepth, node[rch].tdepth); 355 | 356 | /* reheap list to get least tree at top */ 357 | 358 | adjust(list, 0, len - 1); 359 | } 360 | dctreehd = list[0]; /* head of final tree */ 361 | } 362 | 363 | static VOID 364 | init_enc() 365 | { 366 | register int i; 367 | 368 | /* Initialize encoding table */ 369 | 370 | for (i = 0; i < NUMVALS; ++i) 371 | codelen[i] = 0; 372 | } 373 | 374 | /* 375 | * Recursive routine to walk the indicated subtree and level and maintain the 376 | * current path code in bstree. When a leaf is found the entire code string 377 | * and length are put into the encoding table entry for the leaf's data value. 378 | * 379 | * Returns ERROR if codes are too long. 380 | */ 381 | 382 | static int 383 | buildenc(level, root) 384 | int level; /* level of tree being examined, from zero */ 385 | int root; /* root of subtree is also data value if leaf */ 386 | { 387 | register int l, r; 388 | 389 | l = node[root].lchild; 390 | r = node[root].rchild; 391 | 392 | if (l == NOCHILD && r == NOCHILD) { /* Leaf. Previous path 393 | * determines bit string code 394 | * of length level (bits 0 to 395 | * level - 1). Ensures unused 396 | * code bits are zero. */ 397 | 398 | codelen[root] = level; 399 | code[root] = tcode & (((u_short) ~ 0) >> (16 - level)); 400 | return (level > 16) ? ERROR : 0; 401 | } else { 402 | if (l != NOCHILD) { /* Clear path bit and continue deeper */ 403 | 404 | tcode &= ~(1 << level); 405 | if (buildenc(level + 1, l) == ERROR) 406 | return ERROR; /* pass back bad statuses */ 407 | } 408 | if (r != NOCHILD) { /* Set path bit and continue deeper */ 409 | 410 | tcode |= 1 << level; 411 | if (buildenc(level + 1, r) == ERROR) 412 | return ERROR; /* pass back bad statuses */ 413 | } 414 | } 415 | return 0; /* it worked if we reach here */ 416 | } 417 | 418 | #define OUT_INT(n) \ 419 | *outbeg++ = n & 0xff; /* first the low byte */ \ 420 | *outbeg++ = n >> 8; /* then the high byte */ 421 | 422 | /* Write out the header of the compressed file */ 423 | 424 | long 425 | head_sq() 426 | { 427 | register int l, r; 428 | int i, k; 429 | int numnodes; /* # of nodes in simplified tree */ 430 | 431 | outbeg = outbuf; 432 | 433 | /* 434 | * Write out a simplified decoding tree. Only the interior nodes are 435 | * written. When a child is a leaf index (representing a data value) 436 | * it is recoded as -(index + 1) to distinguish it from interior 437 | * indexes which are recoded as positive indexes in the new tree. 438 | * 439 | * Note that this tree will be empty for an empty file. 440 | */ 441 | 442 | numnodes = dctreehd < NUMVALS ? 0 : dctreehd - (NUMVALS - 1); 443 | OUT_INT(numnodes) 444 | for (k = 0, i = dctreehd; k < numnodes; ++k, --i) { 445 | l = node[i].lchild; 446 | r = node[i].rchild; 447 | l = l < NUMVALS ? -(l + 1) : dctreehd - l; 448 | r = r < NUMVALS ? -(r + 1) : dctreehd - r; 449 | OUT_INT(l) 450 | OUT_INT(r) 451 | } 452 | 453 | return sizeof(short) + numnodes * 2 * sizeof(short); 454 | } 455 | 456 | /* 457 | * This routine is used to perform the actual squeeze operation. It can only 458 | * be called after the file has been scanned. It returns the true length of 459 | * the squeezed entry. 460 | * 461 | * There are two unsynchronized bit-byte relationships here. The input stream 462 | * bytes are converted to bit strings of various lengths via the static 463 | * variables named c... These bit strings are concatenated without padding to 464 | * become the stream of encoded result bytes, which this function returns one 465 | * at a time. The EOF (end of file) is converted to SPEOF for convenience and 466 | * encoded like any other input value. True EOF is returned after that. 467 | */ 468 | 469 | long 470 | huf_buf(pbuf, plen, len, ob) 471 | u_char *pbuf; /* ncr'd input buffer */ 472 | u_int plen; /* length of pack buffer */ 473 | u_int len; /* length of input buffer */ 474 | FILE *ob; /* output file */ 475 | { 476 | int rbyte; /* Result byte value */ 477 | int need; /* number of bits */ 478 | long size = 0; 479 | 480 | if (len == 0) /* Account for EOF/SPEOF */ 481 | plen++; 482 | 483 | while (plen != 0) { 484 | if (outbeg > outend) { 485 | putb_pak(outbuf, (u_int) (outbeg-outbuf), ob); 486 | outbeg = outbuf; 487 | } 488 | rbyte = 0; 489 | need = 8; /* build one byte per call */ 490 | 491 | /* 492 | * Loop to build a byte of encoded data. 493 | */ 494 | 495 | loop: 496 | if (cbitsrem >= need) { /* if current code is big enough */ 497 | if (need == 0) { 498 | *outbeg++ = rbyte; 499 | size++; 500 | continue; 501 | } 502 | rbyte |= ccode << (8 - need); /* take what we need */ 503 | ccode >>= need; /* and leave the rest */ 504 | cbitsrem -= need; 505 | *outbeg++ = rbyte & 0xff; 506 | size++; 507 | continue; 508 | } 509 | /* We need more than current code */ 510 | 511 | if (cbitsrem > 0) { 512 | rbyte |= ccode << (8 - need); /* take what there is */ 513 | need -= cbitsrem; 514 | } 515 | /* No more bits in current code string */ 516 | 517 | if (curin == SPEOF) { /* The end of file token has been 518 | * encoded. Save result byte. */ 519 | cbitsrem = 0; 520 | if (need != 8) { 521 | *outbeg++ = rbyte; 522 | size++; 523 | } 524 | break; 525 | } 526 | /* Get an input byte */ 527 | 528 | if (plen == 1 && len == 0) 529 | curin = SPEOF; /* convenient for encoding */ 530 | else if (plen == 0) 531 | { 532 | /* Here we may have the situation where 8-need > cbitsrem. 533 | That is, we have more information in the local variable 534 | than in the 'bits remaining' global variable. Just 535 | returning would cause us bit loss. 536 | What we can do, is put everything in the local variable 537 | back on the small 16 bits queue. 538 | */ 539 | cbitsrem = 8-need; 540 | ccode = rbyte; 541 | break; 542 | } 543 | else 544 | curin = *pbuf++; 545 | plen--; 546 | 547 | ccode = code[curin]; /* get the new byte's code */ 548 | cbitsrem = codelen[curin]; 549 | 550 | goto loop; 551 | } 552 | if (len == 0) 553 | putb_pak(outbuf, (u_int) (outbeg - outbuf), ob); 554 | return (size); 555 | } 556 | -------------------------------------------------------------------------------- /arcsvc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcsvc.c,v 1.4 2005/10/09 01:38:22 highlandsun Exp $ 3 | */ 4 | 5 | /* ARC - Archive utility - ARCSVC 6 | 7 | Version 2.23, created on 04/22/87 at 13:10:10 8 | 9 | (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED 10 | 11 | By: Thom Henderson 12 | 13 | Description: 14 | This file contains service routines needed to maintain an archive. 15 | 16 | Language: 17 | Computer Innovations Optimizing C86 18 | */ 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include "arc.h" 24 | #if _MTS 25 | #include 26 | #endif 27 | 28 | #include "proto.h" 29 | 30 | VOID arcdie(), setstamp(); 31 | int unlink(); 32 | 33 | VOID 34 | openarc(chg) /* open archive */ 35 | int chg; /* true to open for changes */ 36 | { 37 | FILE *fopen();/* file opener */ 38 | 39 | if (!(arc = fopen(arcname, OPEN_R))) { 40 | if (chg) { 41 | if (note) 42 | printf("Creating new archive: %s\n", arcname); 43 | } 44 | else 45 | arcdie("Archive not found: %s", arcname); 46 | } 47 | #if _MTS /* allow reading archives of max MTS record length */ 48 | { 49 | char *buf, *malloc(); 50 | int inlen; 51 | struct GDDSECT *region; 52 | 53 | region=gdinfo(arc->_fd._fdub); 54 | inlen=region->GDINLEN; 55 | buf=malloc(inlen); 56 | setbuffer(arc, buf, inlen); 57 | } 58 | #endif 59 | if (chg) { /* if opening for changes */ 60 | if (!(new = tmpopen(newname))) 61 | arcdie("Cannot create archive copy: %s", newname); 62 | 63 | changing = chg; /* note if open for changes */ 64 | } 65 | } 66 | 67 | VOID 68 | closearc(chg) /* close an archive */ 69 | int chg; /* true if archive was changed */ 70 | { 71 | if (arc) { /* if we had an initial archive */ 72 | fclose(arc); 73 | #if !_MTS 74 | if (kludge) /* kludge to update timestamp */ 75 | setstamp(arcname, olddate, oldtime); 76 | #endif 77 | } 78 | if (chg) { /* if things have changed */ 79 | fclose(new); /* close the new copy */ 80 | if (arc) { /* if we had an original archive */ 81 | #if _MTS 82 | { 83 | fortran VOID permit(); 84 | char what[FNLEN+2]; 85 | /* copy permissions */ char who[FNLEN+6]; 86 | /* of old archive to */ int how,whotyp,wholen,info; 87 | /* new copy... */ strcpy(what, newname); 88 | strcat(what," "); 89 | whotyp=9; 90 | sprintf(who,"like %s",arcname); 91 | wholen=strlen(who); 92 | info=0; 93 | permit(what,&how,&whotyp,&wholen,who,&info); 94 | } 95 | #endif 96 | if (keepbak) { /* if a backup is wanted */ 97 | unlink(bakname); /* erase any old copies */ 98 | if (move(arcname, bakname)) 99 | arcdie("Cannot rename %s to %s", arcname, bakname); 100 | printf("Keeping backup archive: %s\n", bakname); 101 | } else if (unlink(arcname)) 102 | arcdie("Cannot delete old archive: %s", arcname); 103 | } 104 | if (move(newname, arcname)) 105 | arcdie("Cannot move %s to %s", newname, arcname); 106 | #if !_MTS 107 | setstamp(arcname, arcdate, arctime); 108 | #endif 109 | } 110 | } 111 | 112 | /* 113 | * CRC computation logic 114 | * 115 | * The logic for this method of calculating the CRC 16 bit polynomial is taken 116 | * from an article by David Schwaderer in the April 1985 issue of PC Tech 117 | * Journal. 118 | */ 119 | 120 | static short crctab[] = /* CRC lookup table */ 121 | { 122 | 0x0000, 0xC0C1, 0xC181, 0x0140, 0xC301, 0x03C0, 0x0280, 0xC241, 123 | 0xC601, 0x06C0, 0x0780, 0xC741, 0x0500, 0xC5C1, 0xC481, 0x0440, 124 | 0xCC01, 0x0CC0, 0x0D80, 0xCD41, 0x0F00, 0xCFC1, 0xCE81, 0x0E40, 125 | 0x0A00, 0xCAC1, 0xCB81, 0x0B40, 0xC901, 0x09C0, 0x0880, 0xC841, 126 | 0xD801, 0x18C0, 0x1980, 0xD941, 0x1B00, 0xDBC1, 0xDA81, 0x1A40, 127 | 0x1E00, 0xDEC1, 0xDF81, 0x1F40, 0xDD01, 0x1DC0, 0x1C80, 0xDC41, 128 | 0x1400, 0xD4C1, 0xD581, 0x1540, 0xD701, 0x17C0, 0x1680, 0xD641, 129 | 0xD201, 0x12C0, 0x1380, 0xD341, 0x1100, 0xD1C1, 0xD081, 0x1040, 130 | 0xF001, 0x30C0, 0x3180, 0xF141, 0x3300, 0xF3C1, 0xF281, 0x3240, 131 | 0x3600, 0xF6C1, 0xF781, 0x3740, 0xF501, 0x35C0, 0x3480, 0xF441, 132 | 0x3C00, 0xFCC1, 0xFD81, 0x3D40, 0xFF01, 0x3FC0, 0x3E80, 0xFE41, 133 | 0xFA01, 0x3AC0, 0x3B80, 0xFB41, 0x3900, 0xF9C1, 0xF881, 0x3840, 134 | 0x2800, 0xE8C1, 0xE981, 0x2940, 0xEB01, 0x2BC0, 0x2A80, 0xEA41, 135 | 0xEE01, 0x2EC0, 0x2F80, 0xEF41, 0x2D00, 0xEDC1, 0xEC81, 0x2C40, 136 | 0xE401, 0x24C0, 0x2580, 0xE541, 0x2700, 0xE7C1, 0xE681, 0x2640, 137 | 0x2200, 0xE2C1, 0xE381, 0x2340, 0xE101, 0x21C0, 0x2080, 0xE041, 138 | 0xA001, 0x60C0, 0x6180, 0xA141, 0x6300, 0xA3C1, 0xA281, 0x6240, 139 | 0x6600, 0xA6C1, 0xA781, 0x6740, 0xA501, 0x65C0, 0x6480, 0xA441, 140 | 0x6C00, 0xACC1, 0xAD81, 0x6D40, 0xAF01, 0x6FC0, 0x6E80, 0xAE41, 141 | 0xAA01, 0x6AC0, 0x6B80, 0xAB41, 0x6900, 0xA9C1, 0xA881, 0x6840, 142 | 0x7800, 0xB8C1, 0xB981, 0x7940, 0xBB01, 0x7BC0, 0x7A80, 0xBA41, 143 | 0xBE01, 0x7EC0, 0x7F80, 0xBF41, 0x7D00, 0xBDC1, 0xBC81, 0x7C40, 144 | 0xB401, 0x74C0, 0x7580, 0xB541, 0x7700, 0xB7C1, 0xB681, 0x7640, 145 | 0x7200, 0xB2C1, 0xB381, 0x7340, 0xB101, 0x71C0, 0x7080, 0xB041, 146 | 0x5000, 0x90C1, 0x9181, 0x5140, 0x9301, 0x53C0, 0x5280, 0x9241, 147 | 0x9601, 0x56C0, 0x5780, 0x9741, 0x5500, 0x95C1, 0x9481, 0x5440, 148 | 0x9C01, 0x5CC0, 0x5D80, 0x9D41, 0x5F00, 0x9FC1, 0x9E81, 0x5E40, 149 | 0x5A00, 0x9AC1, 0x9B81, 0x5B40, 0x9901, 0x59C0, 0x5880, 0x9841, 150 | 0x8801, 0x48C0, 0x4980, 0x8941, 0x4B00, 0x8BC1, 0x8A81, 0x4A40, 151 | 0x4E00, 0x8EC1, 0x8F81, 0x4F40, 0x8D01, 0x4DC0, 0x4C80, 0x8C41, 152 | 0x4400, 0x84C1, 0x8581, 0x4540, 0x8701, 0x47C0, 0x4680, 0x8641, 153 | 0x8201, 0x42C0, 0x4380, 0x8341, 0x4100, 0x81C1, 0x8081, 0x4040 154 | }; 155 | 156 | /* 157 | * Update a CRC check on the given buffer. 158 | */ 159 | 160 | int 161 | crcbuf(crc, len, buf) 162 | register int crc; /* running CRC value */ 163 | register u_int len; 164 | register u_char *buf; 165 | { 166 | register u_int i; 167 | 168 | for (i=0; i> 8) & 0xff) ^ crctab[(crc ^ *buf++) & 0xff]; 170 | 171 | return (crc); 172 | } 173 | -------------------------------------------------------------------------------- /arctst.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arctst.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCTST 7 | * 8 | * Version 2.12, created on 02/03/86 at 23:00:40 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to test archive integrity. 15 | * 16 | * Language: Computer Innovations Optimizing C86 17 | */ 18 | #include 19 | #include "arc.h" 20 | 21 | VOID openarc(); 22 | int readhdr(), unpack(); 23 | 24 | VOID 25 | tstarc() 26 | { /* test integrity of an archive */ 27 | struct heads hdr; /* file header */ 28 | long arcsize, ftell(); /* archive size */ 29 | 30 | openarc(0); /* open archive for reading */ 31 | fseek(arc, 0L, 2); /* move to end of archive */ 32 | arcsize = ftell(arc); /* see how big it is */ 33 | fseek(arc, 0L, 0); /* return to top of archive */ 34 | 35 | while (readhdr(&hdr, arc)) { 36 | if (ftell(arc) + hdr.size > arcsize) { 37 | printf("Archive truncated in file %s\n", hdr.name); 38 | nerrs++; 39 | break; 40 | } else { 41 | printf("Testing file: %-12s ", hdr.name); 42 | fflush(stdout); 43 | if (unpack(arc, NULL, &hdr)) 44 | nerrs++; 45 | else 46 | printf("okay\n"); 47 | } 48 | } 49 | 50 | if (nerrs < 1) 51 | printf("No errors detected\n"); 52 | else if (nerrs == 1) 53 | printf("One error detected\n"); 54 | else 55 | printf("%d errors detected\n", nerrs); 56 | } 57 | -------------------------------------------------------------------------------- /arcunp.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcunp.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCUNP 7 | * 8 | * Version 3.17, created on 02/13/86 at 10:20:08 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to expand a file when 15 | * taking it out of an archive. 16 | * 17 | * Language: Computer Innovations Optimizing C86 18 | */ 19 | #include 20 | #include "arc.h" 21 | #if _MTS 22 | #include 23 | #endif 24 | 25 | VOID setcode(), init_usq(), init_ucr(), decomp(); 26 | VOID arcdie(), codebuf(); 27 | 28 | #include "proto.h" 29 | 30 | /* stuff for repeat unpacking */ 31 | 32 | #define DLE 0x90 /* repeat byte flag */ 33 | 34 | extern u_char state; /* repeat unpacking state */ 35 | extern int lastc; 36 | 37 | /* repeat unpacking states */ 38 | 39 | #define NOHIST 0 /* no relevant history */ 40 | #define INREP 1 /* sending a repeated value */ 41 | 42 | short crcval; /* CRC check value */ 43 | long stdlen; /* bytes to read */ 44 | #if !DOS 45 | static int gotcr; /* got a carriage return? */ 46 | #endif 47 | 48 | extern u_char *pinbuf, *pakbuf, *outbuf; 49 | 50 | int 51 | unpack(f, t, hdr) /* unpack an archive entry */ 52 | FILE *f, *t; /* source, destination */ 53 | struct heads *hdr; /* pointer to file header data */ 54 | { 55 | u_int len; 56 | 57 | /* setups common to all methods */ 58 | #if !DOS 59 | gotcr = 0; 60 | #endif 61 | crcval = 0; /* reset CRC check value */ 62 | stdlen = hdr->size; /* set input byte counter */ 63 | state = NOHIST; /* initial repeat unpacking state */ 64 | setcode(); /* set up for decoding */ 65 | 66 | /* use whatever method is appropriate */ 67 | 68 | switch (hdrver) { /* choose proper unpack method */ 69 | case 1: /* standard packing */ 70 | case 2: 71 | do { 72 | len = getb_unp(f); 73 | putb_unp(pinbuf, len, t); 74 | } while (len == MYBUF); 75 | break; 76 | 77 | case 3: /* non-repeat packing */ 78 | do { 79 | len = getb_unp(f); 80 | putb_ncr(pinbuf, len, t); 81 | } while (len == MYBUF); 82 | break; 83 | 84 | case 4: /* Huffman squeezing */ 85 | init_usq(f); 86 | do { 87 | len = getb_usq(f); 88 | putb_ncr(outbuf, len, t); 89 | } while (len == MYBUF); 90 | break; 91 | 92 | case 5: /* Lempel-Zev compression */ 93 | init_ucr(0, f); 94 | do { 95 | len = getb_ucr(f); 96 | putb_unp(outbuf, len, t); 97 | } while (len == MYBUF); 98 | break; 99 | 100 | case 6: /* Lempel-Zev plus non-repeat */ 101 | init_ucr(0, f); 102 | do { 103 | len = getb_ucr(f); 104 | putb_ncr(outbuf, len, t); 105 | } while (len == MYBUF); 106 | break; 107 | 108 | case 7: /* L-Z plus ncr with new hash */ 109 | init_ucr(1, f); 110 | do { 111 | len = getb_ucr(f); 112 | putb_ncr(outbuf, len, t); 113 | } while (len == MYBUF); 114 | break; 115 | 116 | case 8: /* dynamic Lempel-Zev */ 117 | decomp(0, f, t); 118 | break; 119 | 120 | case 9: /* Squashing */ 121 | decomp(1, f, t); 122 | break; 123 | 124 | default: /* unknown method */ 125 | if (warn) { 126 | printf("I don't know how to unpack file %s\n", hdr->name); 127 | printf("I think you need a newer version of ARC\n"); 128 | nerrs++; 129 | } 130 | fseek(f, hdr->size, 1); /* skip over bad file */ 131 | return 1; /* note defective file */ 132 | } 133 | 134 | /* cleanups common to all methods */ 135 | 136 | if (crcval != hdr->crc) { 137 | if (warn || kludge) { 138 | printf("WARNING: File %s fails CRC check\n", hdr->name); 139 | nerrs++; 140 | } 141 | return 1; /* note defective file */ 142 | } 143 | return 0; /* file is okay */ 144 | } 145 | 146 | /* 147 | * This routine is used to put bytes in the output file. It also performs 148 | * various housekeeping functions, such as maintaining the CRC check value. 149 | */ 150 | 151 | VOID 152 | putb_unp(buf, len, t) 153 | u_char *buf; 154 | u_int len; 155 | FILE *t; 156 | { 157 | u_int i, j; 158 | 159 | crcval = crcbuf(crcval, len, buf); 160 | 161 | if (!t) 162 | return; 163 | #if !DOS 164 | if (!image) { 165 | #if _MTS 166 | atoe(buf, len); 167 | #endif 168 | if (gotcr) { 169 | gotcr = 0; 170 | if (buf[0] != '\n') 171 | putc('\r', t); 172 | } 173 | 174 | for (i=0,j=0; i 197 | * 198 | * With a special case that a count of zero indicates a DLE as data, not as a 199 | * repeat marker. 200 | */ 201 | 202 | VOID 203 | putb_ncr(buf, len, t) /* put NCR coded bytes */ 204 | u_char *buf; 205 | u_int len; 206 | FILE *t; /* file to receive data */ 207 | { 208 | u_char *pakptr=pakbuf; 209 | u_int i; 210 | 211 | for (i=0; i MYBUF) { 227 | putb_unp(pakbuf, (u_int) (pakptr-pakbuf), t); 228 | pakptr = pakbuf; 229 | } 230 | } 231 | putb_unp(pakbuf, (u_int) (pakptr-pakbuf), t); 232 | } 233 | 234 | /* 235 | * This routine reads a buffer of data from an archive. 236 | */ 237 | 238 | u_int 239 | getb_unp(f) 240 | FILE *f; 241 | { 242 | register u_int len; 243 | 244 | if (stdlen) { 245 | len = (stdlen < MYBUF) ? stdlen : MYBUF; 246 | 247 | len = fread(pinbuf, 1, len, f); 248 | 249 | if (password) 250 | codebuf(pinbuf, len); 251 | 252 | stdlen -= len; 253 | } else 254 | len = 0; 255 | 256 | return (len); 257 | } 258 | -------------------------------------------------------------------------------- /arcusq.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/arcusq.c,v 1.2 2003/10/31 02:22:36 highlandsun Exp $ 3 | */ 4 | 5 | /* 6 | * ARC - Archive utility - ARCUSQ 7 | * 8 | * Version 3.14, created on 07/25/86 at 13:04:19 9 | * 10 | * (C) COPYRIGHT 1985 by System Enhancement Associates; ALL RIGHTS RESERVED 11 | * 12 | * By: Thom Henderson 13 | * 14 | * Description: This file contains the routines used to expand a file which was 15 | * packed using Huffman squeezing. 16 | * 17 | * Most of this code is taken from an USQ program by Richard Greenlaw, which was 18 | * adapted to CI-C86 by Robert J. Beilstein. 19 | * 20 | * Language: Computer Innovations Optimizing C86 21 | */ 22 | #include 23 | #include "arc.h" 24 | 25 | #include "proto.h" 26 | 27 | VOID arcdie(); 28 | 29 | /* stuff for Huffman unsqueezing */ 30 | 31 | #define ERROR (-1) 32 | 33 | #define SPEOF 256 /* special endfile token */ 34 | #define NUMVALS 257 /* 256 data values plus SPEOF */ 35 | 36 | extern struct nd { /* decoding tree */ 37 | int child[2]; /* left, right */ 38 | } node[NUMVALS]; /* use large buffer */ 39 | 40 | extern char *pinbuf; 41 | extern u_char *outbuf, *outbeg, *outend; 42 | 43 | static int bpos; /* last bit position read */ 44 | extern int curin; /* last byte value read */ 45 | static int numnodes; /* number of nodes in decode tree */ 46 | 47 | extern char *inbeg, *inend; 48 | 49 | /* get a 16bit integer */ 50 | #define GET_INT(x) \ 51 | { x = (u_char) (*inbeg++); \ 52 | x |= *inbeg++ << 8;} 53 | 54 | VOID 55 | init_usq(f) /* initialize Huffman unsqueezing */ 56 | FILE *f; /* file containing squeezed data */ 57 | { 58 | int i; /* node index */ 59 | u_int inlen; 60 | 61 | bpos = 99; /* force initial read */ 62 | 63 | inlen = getb_unp(f); 64 | inbeg = pinbuf; 65 | inend = &pinbuf[inlen]; 66 | 67 | GET_INT(numnodes); 68 | 69 | if (numnodes < 0 || numnodes >= NUMVALS) 70 | arcdie("File has an invalid decode tree"); 71 | 72 | /* initialize for possible empty tree (SPEOF only) */ 73 | 74 | node[0].child[0] = -(SPEOF + 1); 75 | node[0].child[1] = -(SPEOF + 1); 76 | 77 | for (i = 0; i < numnodes; ++i) { /* get decoding tree from 78 | * file */ 79 | GET_INT(node[i].child[0]); 80 | GET_INT(node[i].child[1]); 81 | } 82 | } 83 | 84 | u_int 85 | getb_usq(f) /* get byte from squeezed file */ 86 | FILE *f; /* file containing squeezed data */ 87 | { 88 | int i; /* tree index */ 89 | u_int j; 90 | 91 | outbeg = outbuf; 92 | for (j = 0; j < MYBUF; j++) { 93 | /* follow bit stream in tree to a leaf */ 94 | 95 | for (i = 0; i >= 0;) { /* work down(up?) from root */ 96 | if (++bpos > 7) { 97 | if (inbeg >= inend) { 98 | inend = &pinbuf[getb_unp(f)]; 99 | inbeg = pinbuf; 100 | if (inend == inbeg) { 101 | if (!curin) 102 | j--; 103 | return(j); 104 | } 105 | } 106 | curin = *inbeg++; 107 | bpos = 0; 108 | 109 | /* move a level deeper in tree */ 110 | i = node[i].child[1 & curin]; 111 | } else 112 | i = node[i].child[1 & (curin >>= 1)]; 113 | } 114 | 115 | /* decode fake node index to original data value */ 116 | 117 | i = -(i + 1); 118 | 119 | if (i != SPEOF) 120 | *outbeg++ = i; 121 | else 122 | break; 123 | } 124 | /*NOTREACHED*/ 125 | return (j); 126 | } 127 | -------------------------------------------------------------------------------- /marc.1: -------------------------------------------------------------------------------- 1 | .TH MARC 1 "25 Nov 1992" "Howard Chu@JPL" "LOCAL COMMANDS" 2 | .SH NAME 3 | marc \- archive merger 4 | .SH SYNOPSIS 5 | .B marc 6 | \fItgtarc\fR \fIsrcarc\fR [ \fIfiles\fR ... ] 7 | .SH DESCRIPTION 8 | Reads \fIfiles\fR from the arc archive \fIsrcarc\fR and add them to the 9 | arc archive \fItgtarc\fR. 10 | .SH HISTORY 11 | \fIArc\fP has been in use in the CP/M and MSDOS world for many years. 12 | Thom Henderson developed the original version, but it is important to note that 13 | \fIarc\fP is based on the file compression theories developed by Huffman, Welch, 14 | Knott, Knuth, and many other scientists. This implementation is based on 15 | version 5.21 of the MSDOS program. 16 | .SH BUGS 17 | \fIArc\fP behaves just like the PC version of the program; all functions 18 | of the "usage" display are working. 19 | Full compatibility with PC ARC files is maintained, the price for which is 20 | that \fIarc\fP doesn't like long filenames, and can only archive files with 21 | names of up to 12 characters. 22 | It will *sometimes* do The Right Thing with them, but I suggest 23 | you put long-winded filenames in a "shar" before 24 | .IR arc ing 25 | them. 26 | 27 | There shouldn't be any problems, (hah!) but if you find any, please 28 | send them to me at: 29 | 30 | hyc@hanauma.jpl.nasa.gov 31 | 32 | .SH AUTHORS 33 | Original MSDOS program by Thom Henderson 34 | .br 35 | COPYRIGHT(C) 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED 36 | 37 | Original Lempel-Zev code derived from compress 4.0. 38 | Modified to support Squashing by Dan Lanciani (ddl@harvard.edu) 39 | Ported from MSDOS by Howard Chu, 40 | with help from John Gilmore (hoptoad!gnu), James Turner (daisy!turner) 41 | and others. 42 | -------------------------------------------------------------------------------- /marc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * $Header: /cvsroot/arc/arc/marc.c,v 1.7 2011/01/01 13:02:30 k_reimer Exp $ 3 | */ 4 | 5 | /* MARC - Archive merge utility 6 | 7 | Version 5.21, created on 04/22/87 at 15:05:10 8 | 9 | (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED 10 | 11 | By: Thom Henderson 12 | 13 | Description: 14 | This program is used to "merge" archives. That is, to move 15 | files from one archive to another with no data conversion. 16 | Please refer to the ARC source for a description of archives 17 | and archive formats. 18 | 19 | Instructions: 20 | Run this program with no arguments for complete instructions. 21 | 22 | Language: 23 | Computer Innovations Optimizing C86 24 | */ 25 | #include 26 | #include 27 | #include "arc.h" 28 | 29 | #if UNIX 30 | #include 31 | #include 32 | #include 33 | #include 34 | #endif 35 | 36 | #include "proto.h" 37 | 38 | #ifndef __STDC__ 39 | char *calloc(), *malloc(), *realloc(); /* memory managers */ 40 | #endif 41 | int gethdr(), match(), readhdr(); 42 | VOID arcdie(), filecopy(), setstamp(), writehdr(); 43 | static VOID copyfile(), expandlst(), merge(); 44 | 45 | FILE *src; /* source archive */ 46 | char srcname[STRLEN]; /* source archive name */ 47 | char *pinbuf; /* block input buffer */ 48 | 49 | static char **lst; /* files list */ 50 | static int lnum; /* length of files list */ 51 | 52 | int 53 | main(nargs,arg) /* system entry point */ 54 | int nargs; /* number of arguments */ 55 | char *arg[]; /* pointers to arguments */ 56 | { 57 | char *makefnam(); 58 | char *envfind(); 59 | #if !_MTS 60 | char *arctemp2; /* temp file stuff */ 61 | #endif 62 | #if GEMDOS 63 | VOID exitpause(); 64 | #endif 65 | int n; /* index */ 66 | #if UNIX 67 | struct stat sbuf; 68 | #endif 69 | 70 | 71 | if(nargs<3) 72 | { printf("MARC - Archive merger, Version %s, created on 08/07/2010\n", VERSION); 73 | /* printf("(C) COPYRIGHT 1985,86,87 by System Enhancement Associates;"); 74 | printf(" ALL RIGHTS RESERVED\n\n"); 75 | printf("Please refer all inquiries to:\n\n"); 76 | printf(" System Enhancement Associates\n"); 77 | printf(" 21 New Street, Wayne NJ 07470\n\n"); 78 | printf("You may copy and distribute this program freely,"); 79 | printf(" provided that:\n"); 80 | printf(" 1) No fee is charged for such copying and"); 81 | printf(" distribution, and\n"); 82 | printf(" 2) It is distributed ONLY in its original,"); 83 | printf(" unmodified state.\n\n"); 84 | printf("If you like this program, and find it of use, then your"); 85 | printf(" contribution will\n"); 86 | printf("be appreciated. You may not use this product in a"); 87 | printf(" commercial environment\n"); 88 | printf("or a governmental organization without paying a license"); 89 | printf(" fee of $35. Site\n"); 90 | printf("licenses and commercial distribution licenses are"); 91 | printf(" available. A program\n"); 92 | printf("disk and printed documentation are available for $50.\n"); 93 | printf("\nIf you fail to abide by the terms of this license, "); 94 | printf(" then your conscience\n"); 95 | printf("will haunt you for the rest of your life.\n\n"); 96 | */ 97 | printf("Usage: MARC [ . . .]\n"); 98 | printf("Where: is the archive to add files to,\n"); 99 | printf(" is the archive to get files from, and\n"); 100 | printf(" is zero or more file names to get.\n"); 101 | printf("\nAdapted from MSDOS by Howard Chu\n"); 102 | #if GEMDOS 103 | exitpause(); 104 | #endif 105 | return 1; 106 | } 107 | 108 | /* see where temp files go */ 109 | #if !_MTS 110 | arctemp = calloc(1, STRLEN); 111 | if (!(arctemp2 = envfind("ARCTEMP"))) 112 | arctemp2 = envfind("TMPDIR"); 113 | if (arctemp2) { 114 | strncpy(arctemp, arctemp2, STRLEN - 16); 115 | arctemp[STRLEN - 17] = '\0'; 116 | n = strlen(arctemp); 117 | if (arctemp[n - 1] != CUTOFF) 118 | arctemp[n] = CUTOFF; 119 | } 120 | #if UNIX 121 | else strcpy(arctemp, "/tmp/"); 122 | #endif 123 | #if !MSDOS 124 | { 125 | strcat(arctemp, "AXXXXXX"); 126 | int fd = mkstemp(arctemp); 127 | if (fd == -1) 128 | { 129 | fprintf(stderr, "Unable to create temporary files: %s\n", strerror(errno)); 130 | exit(235); 131 | } 132 | close(fd); 133 | unlink(arctemp); 134 | } 135 | #else 136 | strcat(arctemp, "$ARCTEMP"); 137 | #endif 138 | #else 139 | guinfo("SHFSEP ", gotinf); 140 | sepchr[0] = gotinf[0]; 141 | guinfo("SCRFCHAR", gotinf); 142 | tmpchr[0] = gotinf[0]; 143 | arctemp = "-$$$"; 144 | arctemp[0] = tmpchr[0]; 145 | #endif 146 | 147 | for (n = 1; n < nargs; n++) 148 | if (strlen(arg[n]) > (STRLEN - 16)) 149 | { 150 | fprintf(stderr, "Too long argument: %s\n", arg[n]); 151 | exit(235); 152 | } 153 | 154 | #if UNIX 155 | if (!stat(arg[1],&sbuf)) 156 | strcpy(arcname,arg[1]); 157 | else 158 | makefnam(arg[1],".arc",arcname); 159 | if (!stat(arg[2],&sbuf)) 160 | strcpy(srcname,arg[2]); 161 | else 162 | makefnam(arg[2],".arc",srcname); 163 | #else 164 | makefnam(arg[1],".ARC",arcname); /* fix up archive names */ 165 | makefnam(arg[2],".ARC",srcname); 166 | /* makefnam(".$$$",arcname,newname);*/ 167 | #endif 168 | sprintf(newname,"%s.arc",arctemp); 169 | 170 | arc = fopen(arcname,OPEN_R); /* open the archives */ 171 | if(!(src=fopen(srcname,OPEN_R))) 172 | arcdie("Cannot read source archive %s",srcname); 173 | if(!(new=tmpopen(newname))) 174 | arcdie("Cannot create new archive %s",newname); 175 | 176 | if(!arc) 177 | printf("Creating new archive %s\n",arcname); 178 | 179 | /* get the files list set up */ 180 | 181 | lnum = nargs-3; /* initial length of list */ 182 | if(lnum<1) /* phoney for default case */ 183 | { lnum = 1; 184 | lst = (char **) calloc(1,sizeof(char *)); 185 | lst[0] = "*.*"; 186 | } 187 | else /* else use filenames given */ 188 | { lst = (char **) calloc(lnum,sizeof(char *)); 189 | for(n=3; n0) 237 | { copyfile(arc,&arch,gotarc); 238 | gotarc = gethdr(arc,&arch); 239 | } 240 | 241 | else if(strcmp(srch.name,arch.name)<0) 242 | { copy = 0; 243 | for(n=0; narch.date) 260 | || (srch.date==arch.date && srch.time>arch.time)) 261 | { for(n=0; nname; /* string index */ 298 | int n; /* index */ 299 | 300 | for(n=0; nsize); /* copy over the data */ 319 | } 320 | 321 | static VOID 322 | expandlst(n) /* expand an indirect reference */ 323 | int n; /* number of entry to expand */ 324 | { 325 | FILE *lf, *fopen(); /* list file, opener */ 326 | char buf[100]; /* input buffer */ 327 | int x; /* index */ 328 | char *p = lst[n]+1; /* filename pointer */ 329 | char *makefnam(); 330 | 331 | if(*p) /* use name if one was given */ 332 | { makefnam(p,".CMD",buf); 333 | upper(buf); 334 | if(!(lf=fopen(buf,"r"))) 335 | arcdie("Cannot read list of files in %s",buf); 336 | } 337 | else lf = stdin; /* else use standard input */ 338 | 339 | for(x=n+1; x0) /* read in the list */ 344 | { if(!(lst=(char **) realloc(lst,(lnum+1)*sizeof(char *)))) 345 | arcdie("too many file references"); 346 | 347 | lst[lnum] = malloc(strlen(buf)+1); 348 | strcpy(lst[lnum],buf); /* save the name */ 349 | lnum++; 350 | } 351 | 352 | if(lf!=stdin) /* avoid closing standard input */ 353 | fclose(lf); 354 | } 355 | -------------------------------------------------------------------------------- /proto.h: -------------------------------------------------------------------------------- 1 | u_int getbuf PROTO ((FILE *f)); 2 | u_int getb_ucr PROTO ((FILE *f)); 3 | u_int getb_usq PROTO ((FILE *f)); 4 | u_int getb_unp PROTO ((FILE *f)); 5 | VOID hufb_tab PROTO ((u_char *buf, u_int len)); 6 | VOID lzw_buf PROTO ((u_char *buf, u_int len, FILE *f)); 7 | VOID putb_unp PROTO ((u_char *buf, u_int len, FILE *f)); 8 | VOID putb_ncr PROTO ((u_char *buf, u_int len, FILE *f)); 9 | VOID putb_pak PROTO ((u_char *buf, u_int len, FILE *f)); 10 | VOID upper PROTO ((char *string)); 11 | int move PROTO ((char *oldnam, char *newnam)); 12 | int crcbuf PROTO ((int, u_int, u_char *)); 13 | FILE * tmpopen PROTO ((char *path)); 14 | -------------------------------------------------------------------------------- /tmclock.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Stolen from Jef Poskanzer's tws time library, which was stolen from 3 | * Marshall Rose's MH Message Handling system... 4 | * 5 | * tmclock() will convert time from a tm struct back to a clock value. 6 | * tmjuliandate() converts a tm struct to its julian day number. 7 | * tmsubdayclock() takes hours, minutes, and seconds from a tm struct 8 | * and returns the number of seconds since midnight of that day. (?) 9 | * -- Howard Chu, August 1 1988 hyc@umix.cc.umich.edu, umix!hyc 10 | */ 11 | 12 | /* $Header: /cvsroot/arc/arc/tmclock.c,v 1.3 2003/10/31 02:31:24 highlandsun Exp $ */ 13 | 14 | /* Julian day number of the Unix* clock's origin, 01 Jan 1970. */ 15 | #define JD1970 2440587L 16 | #define CENTURY 19 17 | #if BSD 18 | #include 19 | #else 20 | #include 21 | extern long timezone; /* should be in , but isn't on Sun */ 22 | #endif 23 | 24 | long tzone; 25 | 26 | long 27 | tmjuliandate( tm ) 28 | struct tm *tm; 29 | { 30 | register int mday, mon, year; 31 | register long a, b; 32 | double jd; 33 | 34 | if ( (mday = tm -> tm_mday) < 1 || mday > 31 || 35 | (mon = tm -> tm_mon + 1) < 1 || mon > 12 || 36 | (year = tm -> tm_year) < 1 || year > 10000 ) 37 | return ( -1L ); 38 | if ( year < 1583 ) 39 | year += CENTURY * 100; 40 | 41 | if ( mon == 1 || mon == 2 ) 42 | { 43 | --year; 44 | mon += 12; 45 | } 46 | if ( year < 1583 ) 47 | return ( -1L ); 48 | a = year / 100; 49 | b = 2 - a + a / 4; 50 | b += (long) ( (double) year * 365.25 ); 51 | b += (long) ( 30.6001 * ( (double) mon + 1.0 ) ); 52 | jd = mday + b + 1720994.5; 53 | return ( (long) jd ); 54 | } 55 | 56 | 57 | long 58 | tmsubdayclock( tm ) 59 | struct tm *tm; 60 | { 61 | register int sec, min, hour; 62 | register long result; 63 | #if BSD 64 | { 65 | struct timezone tzp; 66 | 67 | gettimeofday(0L, &tzp); 68 | tzone = tzp.tz_minuteswest*(-60); 69 | } 70 | #else 71 | tzone=timezone; 72 | #endif 73 | if ( (sec = tm -> tm_sec) < 0 || sec > 59 || 74 | (min = tm -> tm_min) < 0 || min > 59 || 75 | (hour = tm -> tm_hour) < 0 || hour > 23 ) 76 | return ( -1L ); 77 | 78 | result = ( hour * 60 + min ) * 60 + sec; 79 | result -= tzone; 80 | 81 | return ( result ); 82 | } 83 | 84 | 85 | long 86 | tmclock( tm ) 87 | struct tm *tm; 88 | { 89 | register long jd, sdc; 90 | long result; 91 | 92 | if ( ( jd = tmjuliandate( tm ) ) == -1L ) 93 | return ( -1L ); 94 | if ( ( sdc = tmsubdayclock( tm ) ) == -1L ) 95 | return ( -1L ); 96 | 97 | result = ( jd - JD1970 ) * 24 * 60 * 60 + sdc; 98 | 99 | if ( localtime( &result )->tm_isdst ) 100 | result -= 60L * 60L; 101 | 102 | return ( result ); 103 | } 104 | --------------------------------------------------------------------------------