diff options
202 files changed, 22487 insertions, 0 deletions
diff --git a/COPYING.LIB b/COPYING.LIB new file mode 100644 index 000000000..eb685a5ec --- /dev/null +++ b/COPYING.LIB @@ -0,0 +1,481 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 675 Mass Ave, Cambridge, MA 02139, USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + <one line to give the library's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + <signature of Ty Coon>, 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/Makefile b/Makefile new file mode 100644 index 000000000..bfde99562 --- /dev/null +++ b/Makefile @@ -0,0 +1,63 @@ +DIRS = headers error gtermcap misc stdio2 time getent regexp string termios sysdeps \ +malloc-simple net rpc + +all: libc.a crt0.o + +libc.a: $(DIRS) dummy + m68k-pic-coff-ranlib $@ + +crt0.o: crt + +headers: dummy + if [ ! -L "include/asm" ]; then ln -s ../../linux/include/asm include/asm ; fi + if [ ! -L "include/net" ]; then ln -s ../../linux/include/net include/net ; fi + if [ ! -L "include/linux" ]; then ln -s ../../linux/include/linux include/linux ; fi + +error: dummy + make -C error + +gtermcap: dummy + make -C gtermcap + +misc: dummy + make -C misc + +stdio2: dummy + make -C stdio2 + +time: dummy + make -C time + +getent: dummy + make -C getent + +regexp: dummy + make -C regexp + +string: dummy + make -C string + +termios: dummy + make -C termios + +sysdeps: dummy + make -C sysdeps + +malloc-simple: dummy + make -C malloc-simple + +net: dummy + make -C net + +rpc: dummy + make -C rpc + +crt: dummy + make -C crt + +dummy: + +clean: + -rm `find -name \*.[oa]` `find -name \*~` core + -rm include/asm include/net include/linux + diff --git a/include/a.out.h b/include/a.out.h new file mode 100644 index 000000000..bd58346c1 --- /dev/null +++ b/include/a.out.h @@ -0,0 +1,115 @@ +/* Copyright (C) 1990-1996 + * This file is part of the ld86 command for Linux-86 + * It is distributed under the GNU Library General Public License. + * + * - This may actually be BSD or Minix code, can someone clarify please. -RDB + */ + +#ifndef __AOUT_H +#define __AOUT_H + +struct exec { /* a.out header */ + unsigned char a_magic[2]; /* magic number */ + unsigned char a_flags; /* flags, see below */ + unsigned char a_cpu; /* cpu id */ + unsigned char a_hdrlen; /* length of header */ + unsigned char a_unused; /* reserved for future use */ + unsigned short a_version; /* version stamp (not used at present) */ + long a_text; /* size of text segement in bytes */ + long a_data; /* size of data segment in bytes */ + long a_bss; /* size of bss segment in bytes */ + long a_entry; /* entry point */ + long a_total; /* total memory allocated */ + long a_syms; /* size of symbol table */ + + /* SHORT FORM ENDS HERE */ + long a_trsize; /* text relocation size */ + long a_drsize; /* data relocation size */ + long a_tbase; /* text relocation base */ + long a_dbase; /* data relocation base */ +}; + +#define A_MAGIC0 (unsigned char) 0x01 +#define A_MAGIC1 (unsigned char) 0x03 +#define BADMAG(X) ((X).a_magic[0] != A_MAGIC0 ||(X).a_magic[1] != A_MAGIC1) + +/* CPU Id of TARGET machine (byte order coded in low order two bits) */ +#define A_NONE 0x00 /* unknown */ +#define A_I8086 0x04 /* intel i8086/8088 */ +#define A_M68K 0x0B /* motorola m68000 */ +#define A_NS16K 0x0C /* national semiconductor 16032 */ +#define A_I80386 0x10 /* intel i80386 */ +#define A_SPARC 0x17 /* Sun SPARC */ + +#define A_BLR(cputype) ((cputype&0x01)!=0) /* TRUE if bytes left-to-right */ +#define A_WLR(cputype) ((cputype&0x02)!=0) /* TRUE if words left-to-right */ + +/* Flags. */ +#define A_UZP 0x01 /* unmapped zero page (pages) */ +#define A_PAL 0x02 /* page aligned executable */ +#define A_NSYM 0x04 /* new style symbol table */ +#define A_EXEC 0x10 /* executable */ +#define A_SEP 0x20 /* separate I/D */ +#define A_PURE 0x40 /* pure text */ +#define A_TOVLY 0x80 /* text overlay */ + +/* Offsets of various things. */ +#define A_MINHDR 32 +#define A_TEXTPOS(X) ((long)(X).a_hdrlen) +#define A_DATAPOS(X) (A_TEXTPOS(X) + (X).a_text) +#define A_HASRELS(X) ((X).a_hdrlen > (unsigned char) A_MINHDR) +#define A_HASEXT(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 8)) +#define A_HASLNS(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 16)) +#define A_HASTOFF(X) ((X).a_hdrlen > (unsigned char) (A_MINHDR + 24)) +#define A_TRELPOS(X) (A_DATAPOS(X) + (X).a_data) +#define A_DRELPOS(X) (A_TRELPOS(X) + (X).a_trsize) +#define A_SYMPOS(X) (A_TRELPOS(X) + (A_HASRELS(X) ? \ + ((X).a_trsize + (X).a_drsize) : 0)) + +struct reloc { + long r_vaddr; /* virtual address of reference */ + unsigned short r_symndx; /* internal segnum or extern symbol num */ + unsigned short r_type; /* relocation type */ +}; + +/* r_tyep values: */ +#define R_ABBS 0 +#define R_RELLBYTE 2 +#define R_PCRBYTE 3 +#define R_RELWORD 4 +#define R_PCRWORD 5 +#define R_RELLONG 6 +#define R_PCRLONG 7 +#define R_REL3BYTE 8 +#define R_KBRANCHE 9 + +/* r_symndx for internal segments */ +#define S_ABS ((unsigned short)-1) +#define S_TEXT ((unsigned short)-2) +#define S_DATA ((unsigned short)-3) +#define S_BSS ((unsigned short)-4) + +struct nlist { /* symbol table entry */ + char n_name[8]; /* symbol name */ + long n_value; /* value */ + unsigned char n_sclass; /* storage class */ + unsigned char n_numaux; /* number of auxiliary entries (not used) */ + unsigned short n_type; /* language base and derived type (not used) */ +}; + +/* Low bits of storage class (section). */ +#define N_SECT 07 /* section mask */ +#define N_UNDF 00 /* undefined */ +#define N_ABS 01 /* absolute */ +#define N_TEXT 02 /* text */ +#define N_DATA 03 /* data */ +#define N_BSS 04 /* bss */ +#define N_COMM 05 /* (common) */ + +/* High bits of storage class. */ +#define N_CLASS 0370 /* storage class mask */ +#define C_NULL +#define C_EXT 0020 /* external symbol */ +#define C_STAT 0030 /* static */ + +#endif /* _AOUT_H */ diff --git a/include/ar.h b/include/ar.h new file mode 100644 index 000000000..c6083717d --- /dev/null +++ b/include/ar.h @@ -0,0 +1,18 @@ +#ifndef __AR_H +#define __AR_H + +#define ARMAG "!<arch>\n" +#define SARMAG 8 +#define ARFMAG "`\n" + +struct ar_hdr { + char ar_name[16], + ar_date[12], + ar_uid[6], + ar_gid[6], + ar_mode[8], + ar_size[10], + ar_fmag[2]; +}; + +#endif /* __AR_H */ diff --git a/include/arpa/inet.h b/include/arpa/inet.h new file mode 100644 index 000000000..cf4cd3275 --- /dev/null +++ b/include/arpa/inet.h @@ -0,0 +1,12 @@ +#ifndef __ARPA_INET_H +#define __ARPA_INET_H + +#include <netinet/in.h> + +int inet_aton(const char *cp, struct in_addr *inp); + +unsigned long int inet_addr(const char *cp); + +char *inet_ntoa(struct in_addr in); + +#endif diff --git a/include/arpa/nameser.h b/include/arpa/nameser.h new file mode 100644 index 000000000..ba6014216 --- /dev/null +++ b/include/arpa/nameser.h @@ -0,0 +1,392 @@ +/* + * ++Copyright++ 1983, 1989, 1993 + * - + * Copyright (c) 1983, 1989, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * Portions Copyright (c) 1995 by International Business Machines, Inc. + * + * International Business Machines, Inc. (hereinafter called IBM) grants + * permission under its copyrights to use, copy, modify, and distribute this + * Software with or without fee, provided that the above copyright notice and + * all paragraphs of this notice appear in all copies, and that the name of IBM + * not be used in connection with the marketing of any product incorporating + * the Software or modifications thereof, without specific, written prior + * permission. + * + * To the extent it has a right to do so, IBM grants an immunity from suit + * under its patents, if any, for the use, sale or manufacture of products to + * the extent that such products are used for performing Domain Name System + * dynamic updates in TCP/IP networks by means of the Software. No immunity is + * granted for any product per se or for any other function of any product. + * + * THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A + * PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, + * DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING + * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN + * IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. + * --Copyright-- + */ + +/* + * @(#)nameser.h 8.1 (Berkeley) 6/2/93 + * $Id: nameser.h,v 1.1 2000/05/14 04:16:36 erik Exp $ + */ + +#ifndef _NAMESER_H_ +#define _NAMESER_H_ + +#include <sys/param.h> +#if (!defined(BSD)) || (BSD < 199306) +# include <sys/bitypes.h> +#else +# include <sys/types.h> +#endif +#include <sys/cdefs.h> + +#ifdef _AUX_SOURCE +# include <sys/types.h> +#endif + +/* + * revision information. this is the release date in YYYYMMDD format. + * it can change every day so the right thing to do with it is use it + * in preprocessor commands such as "#if (__BIND > 19931104)". do not + * compare for equality; rather, use it to determine whether your resolver + * is new enough to contain a certain feature. + */ + +#define __BIND 19960801 /* interface version stamp */ + +/* + * Define constants based on rfc883 + */ +#define PACKETSZ 512 /* maximum packet size */ +#define MAXDNAME 1025 /* maximum domain name */ +#define MAXCDNAME 255 /* maximum compressed domain name */ +#define MAXLABEL 63 /* maximum length of domain label */ +#define HFIXEDSZ 12 /* #/bytes of fixed data in header */ +#define QFIXEDSZ 4 /* #/bytes of fixed data in query */ +#define RRFIXEDSZ 10 /* #/bytes of fixed data in r record */ +#define INT32SZ 4 /* for systems without 32-bit ints */ +#define INT16SZ 2 /* for systems without 16-bit ints */ +#define INADDRSZ 4 /* IPv4 T_A */ +#define IN6ADDRSZ 16 /* IPv6 T_AAAA */ + +/* + * Internet nameserver port number + */ +#define NAMESERVER_PORT 53 + +/* + * Currently defined opcodes + */ +#define QUERY 0x0 /* standard query */ +#define IQUERY 0x1 /* inverse query */ +#define STATUS 0x2 /* nameserver status query */ +/*#define xxx 0x3*/ /* 0x3 reserved */ +#define NS_NOTIFY_OP 0x4 /* notify secondary of SOA change */ +/* + * Currently defined response codes + */ +#define NOERROR 0 /* no error */ +#define FORMERR 1 /* format error */ +#define SERVFAIL 2 /* server failure */ +#define NXDOMAIN 3 /* non existent domain */ +#define NOTIMP 4 /* not implemented */ +#define REFUSED 5 /* query refused */ + +/* + * Type values for resources and queries + */ +#define T_A 1 /* host address */ +#define T_NS 2 /* authoritative server */ +#define T_MD 3 /* mail destination */ +#define T_MF 4 /* mail forwarder */ +#define T_CNAME 5 /* canonical name */ +#define T_SOA 6 /* start of authority zone */ +#define T_MB 7 /* mailbox domain name */ +#define T_MG 8 /* mail group member */ +#define T_MR 9 /* mail rename name */ +#define T_NULL 10 /* null resource record */ +#define T_WKS 11 /* well known service */ +#define T_PTR 12 /* domain name pointer */ +#define T_HINFO 13 /* host information */ +#define T_MINFO 14 /* mailbox information */ +#define T_MX 15 /* mail routing information */ +#define T_TXT 16 /* text strings */ +#define T_RP 17 /* responsible person */ +#define T_AFSDB 18 /* AFS cell database */ +#define T_X25 19 /* X_25 calling address */ +#define T_ISDN 20 /* ISDN calling address */ +#define T_RT 21 /* router */ +#define T_NSAP 22 /* NSAP address */ +#define T_NSAP_PTR 23 /* reverse NSAP lookup (deprecated) */ +#define T_SIG 24 /* security signature */ +#define T_KEY 25 /* security key */ +#define T_PX 26 /* X.400 mail mapping */ +#define T_GPOS 27 /* geographical position (withdrawn) */ +#define T_AAAA 28 /* IP6 Address */ +#define T_LOC 29 /* Location Information */ +#define T_NXT 30 /* Next Valid Name in Zone */ +#define T_EID 31 /* Endpoint identifier */ +#define T_NIMLOC 32 /* Nimrod locator */ +#define T_SRV 33 /* Server selection */ +#define T_ATMA 34 /* ATM Address */ +#define T_NAPTR 35 /* Naming Authority PoinTeR */ + /* non standard */ +#define T_UINFO 100 /* user (finger) information */ +#define T_UID 101 /* user ID */ +#define T_GID 102 /* group ID */ +#define T_UNSPEC 103 /* Unspecified format (binary data) */ + /* Query type values which do not appear in resource records */ +#define T_IXFR 251 /* incremental zone transfer */ +#define T_AXFR 252 /* transfer zone of authority */ +#define T_MAILB 253 /* transfer mailbox records */ +#define T_MAILA 254 /* transfer mail agent records */ +#define T_ANY 255 /* wildcard match */ + +/* + * Values for class field + */ + +#define C_IN 1 /* the arpa internet */ +#define C_CHAOS 3 /* for chaos net (MIT) */ +#define C_HS 4 /* for Hesiod name server (MIT) (XXX) */ + /* Query class values which do not appear in resource records */ +#define C_ANY 255 /* wildcard match */ + +/* + * Flags field of the KEY RR rdata + */ +#define KEYFLAG_TYPEMASK 0xC000 /* Mask for "type" bits */ +#define KEYFLAG_TYPE_AUTH_CONF 0x0000 /* Key usable for both */ +#define KEYFLAG_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */ +#define KEYFLAG_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */ +#define KEYFLAG_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */ +/* The type bits can also be interpreted independently, as single bits: */ +#define KEYFLAG_NO_AUTH 0x8000 /* Key not usable for authentication */ +#define KEYFLAG_NO_CONF 0x4000 /* Key not usable for confidentiality */ + +#define KEYFLAG_EXPERIMENTAL 0x2000 /* Security is *mandatory* if bit=0 */ +#define KEYFLAG_RESERVED3 0x1000 /* reserved - must be zero */ +#define KEYFLAG_RESERVED4 0x0800 /* reserved - must be zero */ +#define KEYFLAG_USERACCOUNT 0x0400 /* key is assoc. with a user acct */ +#define KEYFLAG_ENTITY 0x0200 /* key is assoc. with entity eg host */ +#define KEYFLAG_ZONEKEY 0x0100 /* key is zone key for the zone named */ +#define KEYFLAG_IPSEC 0x0080 /* key is for IPSEC use (host or user)*/ +#define KEYFLAG_EMAIL 0x0040 /* key is for email (MIME security) */ +#define KEYFLAG_RESERVED10 0x0020 /* reserved - must be zero */ +#define KEYFLAG_RESERVED11 0x0010 /* reserved - must be zero */ +#define KEYFLAG_SIGNATORYMASK 0x000F /* key can sign DNS RR's of same name */ + +#define KEYFLAG_RESERVED_BITMASK ( KEYFLAG_RESERVED3 | \ + KEYFLAG_RESERVED4 | \ + KEYFLAG_RESERVED10| KEYFLAG_RESERVED11) + +/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */ +#define ALGORITHM_MD5RSA 1 /* MD5 with RSA */ +#define ALGORITHM_EXPIRE_ONLY 253 /* No alg, no security */ +#define ALGORITHM_PRIVATE_OID 254 /* Key begins with OID indicating alg */ + +/* Signatures */ + /* Size of a mod or exp in bits */ +#define MIN_MD5RSA_KEY_PART_BITS 512 +#define MAX_MD5RSA_KEY_PART_BITS 2552 + /* Total of binary mod and exp, bytes */ +#define MAX_MD5RSA_KEY_BYTES ((MAX_MD5RSA_KEY_PART_BITS+7/8)*2+3) + /* Max length of text sig block */ +#define MAX_KEY_BASE64 (((MAX_MD5RSA_KEY_BYTES+2)/3)*4) + +/* + * Status return codes for T_UNSPEC conversion routines + */ +#define CONV_SUCCESS 0 +#define CONV_OVERFLOW (-1) +#define CONV_BADFMT (-2) +#define CONV_BADCKSUM (-3) +#define CONV_BADBUFLEN (-4) + +#ifndef BYTE_ORDER +#if (BSD >= 199103) +# include <machine/endian.h> +#else +#ifdef linux +# include <endian.h> +#else +#define LITTLE_ENDIAN 1234 /* least-significant byte first (vax, pc) */ +#define BIG_ENDIAN 4321 /* most-significant byte first (IBM, net) */ +#define PDP_ENDIAN 3412 /* LSB first in word, MSW first in long (pdp)*/ + +#if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \ + defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \ + defined(__alpha__) || defined(__alpha) +#define BYTE_ORDER LITTLE_ENDIAN +#endif + +#if defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \ + defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \ + defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\ + defined(apollo) || defined(__convex__) || defined(_CRAY) || \ + defined(__hppa) || defined(__hp9000) || \ + defined(__hp9000s300) || defined(__hp9000s700) || \ + defined (BIT_ZERO_ON_LEFT) || defined(m68k) +#define BYTE_ORDER BIG_ENDIAN +#endif +#endif /* linux */ +#endif /* BSD */ +#endif /* BYTE_ORDER */ + +#if !defined(BYTE_ORDER) || \ + (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \ + BYTE_ORDER != PDP_ENDIAN) + /* you must determine what the correct bit order is for + * your compiler - the next line is an intentional error + * which will force your compiles to bomb until you fix + * the above macros. + */ + error "Undefined or invalid BYTE_ORDER"; +#endif + +/* + * Structure for query header. The order of the fields is machine- and + * compiler-dependent, depending on the byte/bit order and the layout + * of bit fields. We use bit fields only in int variables, as this + * is all ANSI requires. This requires a somewhat confusing rearrangement. + */ + +typedef struct { + unsigned id :16; /* query identification number */ +#if BYTE_ORDER == BIG_ENDIAN + /* fields in third byte */ + unsigned qr: 1; /* response flag */ + unsigned opcode: 4; /* purpose of message */ + unsigned aa: 1; /* authoritative answer */ + unsigned tc: 1; /* truncated message */ + unsigned rd: 1; /* recursion desired */ + /* fields in fourth byte */ + unsigned ra: 1; /* recursion available */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ad: 1; /* authentic data from named */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned rcode :4; /* response code */ +#endif +#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN + /* fields in third byte */ + unsigned rd :1; /* recursion desired */ + unsigned tc :1; /* truncated message */ + unsigned aa :1; /* authoritative answer */ + unsigned opcode :4; /* purpose of message */ + unsigned qr :1; /* response flag */ + /* fields in fourth byte */ + unsigned rcode :4; /* response code */ + unsigned cd: 1; /* checking disabled by resolver */ + unsigned ad: 1; /* authentic data from named */ + unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */ + unsigned ra :1; /* recursion available */ +#endif + /* remaining bytes */ + unsigned qdcount :16; /* number of question entries */ + unsigned ancount :16; /* number of answer entries */ + unsigned nscount :16; /* number of authority entries */ + unsigned arcount :16; /* number of resource entries */ +} HEADER; + +/* + * Defines for handling compressed domain names + */ +#define INDIR_MASK 0xc0 + +extern u_int16_t _getshort __P((const u_char *)); +extern u_int32_t _getlong __P((const u_char *)); + +/* + * Inline versions of get/put short/long. Pointer is advanced. + * + * These macros demonstrate the property of C whereby it can be + * portable or it can be elegant but rarely both. + */ +#define GETSHORT(s, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (s) = ((u_int16_t)t_cp[0] << 8) \ + | ((u_int16_t)t_cp[1]) \ + ; \ + (cp) += INT16SZ; \ +} + +#define GETLONG(l, cp) { \ + register u_char *t_cp = (u_char *)(cp); \ + (l) = ((u_int32_t)t_cp[0] << 24) \ + | ((u_int32_t)t_cp[1] << 16) \ + | ((u_int32_t)t_cp[2] << 8) \ + | ((u_int32_t)t_cp[3]) \ + ; \ + (cp) += INT32SZ; \ +} + +#define PUTSHORT(s, cp) { \ + register u_int16_t t_s = (u_int16_t)(s); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_s >> 8; \ + *t_cp = t_s; \ + (cp) += INT16SZ; \ +} + +#define PUTLONG(l, cp) { \ + register u_int32_t t_l = (u_int32_t)(l); \ + register u_char *t_cp = (u_char *)(cp); \ + *t_cp++ = t_l >> 24; \ + *t_cp++ = t_l >> 16; \ + *t_cp++ = t_l >> 8; \ + *t_cp = t_l; \ + (cp) += INT32SZ; \ +} + +#endif /* !_NAMESER_H_ */ diff --git a/include/arpa/telnet.h b/include/arpa/telnet.h new file mode 100644 index 000000000..25085b89a --- /dev/null +++ b/include/arpa/telnet.h @@ -0,0 +1,319 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)telnet.h 8.2 (Berkeley) 12/15/93 + */ + +#ifndef _ARPA_TELNET_H +#define _ARPA_TELNET_H + +/* + * Definitions for the TELNET protocol. + */ +#define IAC 255 /* interpret as command: */ +#define DONT 254 /* you are not to use option */ +#define DO 253 /* please, you use option */ +#define WONT 252 /* I won't use option */ +#define WILL 251 /* I will use option */ +#define SB 250 /* interpret as subnegotiation */ +#define GA 249 /* you may reverse the line */ +#define EL 248 /* erase the current line */ +#define EC 247 /* erase the current character */ +#define AYT 246 /* are you there */ +#define AO 245 /* abort output--but let prog finish */ +#define IP 244 /* interrupt process--permanently */ +#define BREAK 243 /* break */ +#define DM 242 /* data mark--for connect. cleaning */ +#define NOP 241 /* nop */ +#define SE 240 /* end sub negotiation */ +#define EOR 239 /* end of record (transparent mode) */ +#define ABORT 238 /* Abort process */ +#define SUSP 237 /* Suspend process */ +#define xEOF 236 /* End of file: EOF is already used... */ + +#define SYNCH 242 /* for telfunc calls */ + +#ifdef TELCMDS +char *telcmds[] = { + "EOF", "SUSP", "ABORT", "EOR", + "SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC", + "EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC", 0, +}; +#else +extern char *telcmds[]; +#endif + +#define TELCMD_FIRST xEOF +#define TELCMD_LAST IAC +#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \ + (unsigned int)(x) >= TELCMD_FIRST) +#define TELCMD(x) telcmds[(x)-TELCMD_FIRST] + +/* telnet options */ +#define TELOPT_BINARY 0 /* 8-bit data path */ +#define TELOPT_ECHO 1 /* echo */ +#define TELOPT_RCP 2 /* prepare to reconnect */ +#define TELOPT_SGA 3 /* suppress go ahead */ +#define TELOPT_NAMS 4 /* approximate message size */ +#define TELOPT_STATUS 5 /* give status */ +#define TELOPT_TM 6 /* timing mark */ +#define TELOPT_RCTE 7 /* remote controlled transmission and echo */ +#define TELOPT_NAOL 8 /* negotiate about output line width */ +#define TELOPT_NAOP 9 /* negotiate about output page size */ +#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */ +#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */ +#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */ +#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */ +#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */ +#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */ +#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */ +#define TELOPT_XASCII 17 /* extended ascic character set */ +#define TELOPT_LOGOUT 18 /* force logout */ +#define TELOPT_BM 19 /* byte macro */ +#define TELOPT_DET 20 /* data entry terminal */ +#define TELOPT_SUPDUP 21 /* supdup protocol */ +#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */ +#define TELOPT_SNDLOC 23 /* send location */ +#define TELOPT_TTYPE 24 /* terminal type */ +#define TELOPT_EOR 25 /* end or record */ +#define TELOPT_TUID 26 /* TACACS user identification */ +#define TELOPT_OUTMRK 27 /* output marking */ +#define TELOPT_TTYLOC 28 /* terminal location number */ +#define TELOPT_3270REGIME 29 /* 3270 regime */ +#define TELOPT_X3PAD 30 /* X.3 PAD */ +#define TELOPT_NAWS 31 /* window size */ +#define TELOPT_TSPEED 32 /* terminal speed */ +#define TELOPT_LFLOW 33 /* remote flow control */ +#define TELOPT_LINEMODE 34 /* Linemode option */ +#define TELOPT_XDISPLOC 35 /* X Display Location */ +#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */ +#define TELOPT_AUTHENTICATION 37/* Authenticate */ +#define TELOPT_ENCRYPT 38 /* Encryption option */ +#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */ +#define TELOPT_EXOPL 255 /* extended-options-list */ + + +#define NTELOPTS (1+TELOPT_NEW_ENVIRON) +#ifdef TELOPTS +char *telopts[NTELOPTS+1] = { + "BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME", + "STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP", + "NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS", + "NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO", + "DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT", + "SEND LOCATION", "TERMINAL TYPE", "END OF RECORD", + "TACACS UID", "OUTPUT MARKING", "TTYLOC", + "3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW", + "LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION", + "ENCRYPT", "NEW-ENVIRON", + 0, +}; +#define TELOPT_FIRST TELOPT_BINARY +#define TELOPT_LAST TELOPT_NEW_ENVIRON +#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST) +#define TELOPT(x) telopts[(x)-TELOPT_FIRST] +#endif + +/* sub-option qualifiers */ +#define TELQUAL_IS 0 /* option is... */ +#define TELQUAL_SEND 1 /* send option */ +#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */ +#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */ +#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */ + +#define LFLOW_OFF 0 /* Disable remote flow control */ +#define LFLOW_ON 1 /* Enable remote flow control */ +#define LFLOW_RESTART_ANY 2 /* Restart output on any char */ +#define LFLOW_RESTART_XON 3 /* Restart output only on XON */ + +/* + * LINEMODE suboptions + */ + +#define LM_MODE 1 +#define LM_FORWARDMASK 2 +#define LM_SLC 3 + +#define MODE_EDIT 0x01 +#define MODE_TRAPSIG 0x02 +#define MODE_ACK 0x04 +#define MODE_SOFT_TAB 0x08 +#define MODE_LIT_ECHO 0x10 + +#define MODE_MASK 0x1f + +/* Not part of protocol, but needed to simplify things... */ +#define MODE_FLOW 0x0100 +#define MODE_ECHO 0x0200 +#define MODE_INBIN 0x0400 +#define MODE_OUTBIN 0x0800 +#define MODE_FORCE 0x1000 + +#define SLC_SYNCH 1 +#define SLC_BRK 2 +#define SLC_IP 3 +#define SLC_AO 4 +#define SLC_AYT 5 +#define SLC_EOR 6 +#define SLC_ABORT 7 +#define SLC_EOF 8 +#define SLC_SUSP 9 +#define SLC_EC 10 +#define SLC_EL 11 +#define SLC_EW 12 +#define SLC_RP 13 +#define SLC_LNEXT 14 +#define SLC_XON 15 +#define SLC_XOFF 16 +#define SLC_FORW1 17 +#define SLC_FORW2 18 + +#define NSLC 18 + +/* + * For backwards compatability, we define SLC_NAMES to be the + * list of names if SLC_NAMES is not defined. + */ +#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \ + "ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \ + "LNEXT", "XON", "XOFF", "FORW1", "FORW2", 0, +#ifdef SLC_NAMES +char *slc_names[] = { + SLC_NAMELIST +}; +#else +extern char *slc_names[]; +#define SLC_NAMES SLC_NAMELIST +#endif + +#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC) +#define SLC_NAME(x) slc_names[x] + +#define SLC_NOSUPPORT 0 +#define SLC_CANTCHANGE 1 +#define SLC_VARIABLE 2 +#define SLC_DEFAULT 3 +#define SLC_LEVELBITS 0x03 + +#define SLC_FUNC 0 +#define SLC_FLAGS 1 +#define SLC_VALUE 2 + +#define SLC_ACK 0x80 +#define SLC_FLUSHIN 0x40 +#define SLC_FLUSHOUT 0x20 + +#define OLD_ENV_VAR 1 +#define OLD_ENV_VALUE 0 +#define NEW_ENV_VAR 0 +#define NEW_ENV_VALUE 1 +#define ENV_ESC 2 +#define ENV_USERVAR 3 + +/* + * AUTHENTICATION suboptions + */ + +/* + * Who is authenticating who ... + */ +#define AUTH_WHO_CLIENT 0 /* Client authenticating server */ +#define AUTH_WHO_SERVER 1 /* Server authenticating client */ +#define AUTH_WHO_MASK 1 + +/* + * amount of authentication done + */ +#define AUTH_HOW_ONE_WAY 0 +#define AUTH_HOW_MUTUAL 2 +#define AUTH_HOW_MASK 2 + +#define AUTHTYPE_NULL 0 +#define AUTHTYPE_KERBEROS_V4 1 +#define AUTHTYPE_KERBEROS_V5 2 +#define AUTHTYPE_SPX 3 +#define AUTHTYPE_MINK 4 +#define AUTHTYPE_CNT 5 + +#define AUTHTYPE_TEST 99 + +#ifdef AUTH_NAMES +char *authtype_names[] = { + "NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK", 0, +}; +#else +extern char *authtype_names[]; +#endif + +#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT) +#define AUTHTYPE_NAME(x) authtype_names[x] + +/* + * ENCRYPTion suboptions + */ +#define ENCRYPT_IS 0 /* I pick encryption type ... */ +#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */ +#define ENCRYPT_REPLY 2 /* Initial setup response */ +#define ENCRYPT_START 3 /* Am starting to send encrypted */ +#define ENCRYPT_END 4 /* Am ending encrypted */ +#define ENCRYPT_REQSTART 5 /* Request you start encrypting */ +#define ENCRYPT_REQEND 6 /* Request you send encrypting */ +#define ENCRYPT_ENC_KEYID 7 +#define ENCRYPT_DEC_KEYID 8 +#define ENCRYPT_CNT 9 + +#define ENCTYPE_ANY 0 +#define ENCTYPE_DES_CFB64 1 +#define ENCTYPE_DES_OFB64 2 +#define ENCTYPE_CNT 3 + +#ifdef ENCRYPT_NAMES +char *encrypt_names[] = { + "IS", "SUPPORT", "REPLY", "START", "END", + "REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID", + 0, +}; +char *enctype_names[] = { + "ANY", "DES_CFB64", "DES_OFB64", 0, +}; +#else +extern char *encrypt_names[]; +extern char *enctype_names[]; +#endif + + +#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT) +#define ENCRYPT_NAME(x) encrypt_names[x] + +#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT) +#define ENCTYPE_NAME(x) enctype_names[x] +#endif /* _ARPA_TELNET_H */ diff --git a/include/arpa/tftp.h b/include/arpa/tftp.h new file mode 100644 index 000000000..0904407c7 --- /dev/null +++ b/include/arpa/tftp.h @@ -0,0 +1,80 @@ +/* + * Copyright (c) 1983, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)tftp.h 8.1 (Berkeley) 6/2/93 + */ + +#ifndef _ARPA_TFTP_H +#define _ARPA_TFTP_H 1 + +/* + * Trivial File Transfer Protocol (IEN-133) + */ +#define SEGSIZE 512 /* data segment size */ + +/* + * Packet types. + */ +#define RRQ 01 /* read request */ +#define WRQ 02 /* write request */ +#define DATA 03 /* data packet */ +#define ACK 04 /* acknowledgement */ +#define ERROR 05 /* error code */ + +struct tftphdr { + short th_opcode; /* packet type */ + union { + unsigned short tu_block; /* block # */ + short tu_code; /* error code */ + char tu_stuff[1]; /* request packet stuff */ + } th_u; + char th_data[1]; /* data or error string */ +}; + +#define th_block th_u.tu_block +#define th_code th_u.tu_code +#define th_stuff th_u.tu_stuff +#define th_msg th_data + +/* + * Error codes. + */ +#define EUNDEF 0 /* not defined */ +#define ENOTFOUND 1 /* file not found */ +#define EACCESS 2 /* access violation */ +#define ENOSPACE 3 /* disk full or allocation exceeded */ +#define EBADOP 4 /* illegal TFTP operation */ +#define EBADID 5 /* unknown transfer ID */ +#define EEXISTS 6 /* file already exists */ +#define ENOUSER 7 /* no such user */ + +#endif /* arpa/tftp.h */ diff --git a/include/assert.h b/include/assert.h new file mode 100644 index 000000000..aef6cdf08 --- /dev/null +++ b/include/assert.h @@ -0,0 +1,23 @@ +#ifndef __ASSERT_H +#define __ASSERT_H +#include <features.h> + +/* If NDEBUG is defined, do nothing. + If not, and EXPRESSION is zero, print an error message and abort. */ + +#ifdef NDEBUG + +#define assert(expr) ((void) 0) + +#else /* Not NDEBUG. */ + +extern void __assert __P((const char *, const char *, int)); + +#define assert(expr) \ + ((void) ((expr) || \ + (__assert (__STRING(expr), \ + __FILE__, __LINE__), 0))) + +#endif /* NDEBUG. */ + +#endif /* __ASSERT_H */ diff --git a/include/cfgfile.h b/include/cfgfile.h new file mode 100644 index 000000000..1eae1bc94 --- /dev/null +++ b/include/cfgfile.h @@ -0,0 +1,8 @@ +#ifndef __CFGFILE_H__ +#define __CFGFILE_H__ + +#include <stdio.h> +char ** cfgread(FILE *fp); +char ** cfgfind(FILE *fp, char *var); + +#endif /* __CFGFILE_H__ */ diff --git a/include/ctype.h b/include/ctype.h new file mode 100644 index 000000000..ed22ef786 --- /dev/null +++ b/include/ctype.h @@ -0,0 +1,38 @@ +/* + * ctype.h Character classification and conversion + */ + +#ifndef __CTYPE_H +#define __CTYPE_H + +extern unsigned char __ctype[]; + +#define __CT_d 0x01 /* numeric digit */ +#define __CT_u 0x02 /* upper case */ +#define __CT_l 0x04 /* lower case */ +#define __CT_c 0x08 /* control character */ +#define __CT_s 0x10 /* whitespace */ +#define __CT_p 0x20 /* punctuation */ +#define __CT_x 0x40 /* hexadecimal */ + +#define toupper(c) (islower(c) ? (c)^0x20 : (c)) +#define tolower(c) (isupper(c) ? (c)^0x20 : (c)) +#define _toupper(c) ((c)^0x20) +#define _tolower(c) ((c)^0x20) +#define toascii(c) ((c)&0x7F) + +/* Note the '!!' is a cast to 'bool' and even BCC deletes it in an if() */ +#define isalnum(c) (!!(__ctype[(int) c]&(__CT_u|__CT_l|__CT_d))) +#define isalpha(c) (!!(__ctype[(int) c]&(__CT_u|__CT_l))) +#define isascii(c) (!((c)&~0x7F)) +#define iscntrl(c) (!!(__ctype[(int) c]&__CT_c)) +#define isdigit(c) (!!(__ctype[(int) c]&__CT_d)) +#define isgraph(c) (!(__ctype[(int) c]&(__CT_c|__CT_s))) +#define islower(c) (!!(__ctype[(int) c]&__CT_l)) +#define isprint(c) (!(__ctype[(int) c]&__CT_c)) +#define ispunct(c) (!!(__ctype[(int) c]&__CT_p)) +#define isspace(c) (!!(__ctype[(int) c]&__CT_s)) +#define isupper(c) (!!(__ctype[(int) c]&__CT_u)) +#define isxdigit(c) (!!(__ctype[(int) c]&__CT_x)) + +#endif /* __CTYPE_H */ diff --git a/include/dirent.h b/include/dirent.h new file mode 100644 index 000000000..460ba0c5e --- /dev/null +++ b/include/dirent.h @@ -0,0 +1,155 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 5.1.2 Directory Operations <dirent.h> + */ + +#ifndef _DIRENT_H + +#define _DIRENT_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + +#define __need_size_t +#include <stddef.h> + +#include <sys/types.h> +#include <linux/limits.h> +#include <linux/dirent.h> + +#if defined(__USE_GNU) +#define d_fileno d_ino /* glibc compatibility. */ +#if 0 +#define d_namlen d_reclen /* glibc compatibility. */ +#endif +#endif + +#if defined(DIRENT_ILLEGAL_ACCESS) || \ + (defined(__SVR4_I386_ABI_L1__) && !defined(INTERNAL_LINUX_C_LIB)) + +/* Use it at your own risk. */ +typedef struct DIR +{ + /* file descriptor */ + int dd_fd; + + /* offset of the next dir entry in buffer */ + off_t dd_loc; + + /* bytes of valid entries in buffer */ + size_t dd_size; + + /* -> directory buffer */ + struct dirent *dd_buf; +} DIR; + +#else + +/* The internal is hidden from the user. */ +typedef struct DIR DIR; + +#endif + + +/* Open a directory stream on NAME. + Return a DIR stream on the directory, or NULL if it could not be opened. */ +extern DIR *opendir __P ((__const char *__name)); + +/* Close the directory stream DIRP. + Return 0 if successful, -1 if not. */ +extern int closedir __P ((DIR * __dirp)); + +/* Read a directory entry from DIRP. + Return a pointer to a `struct dirent' describing the entry, + or NULL for EOF or error. The storage returned may be overwritten + by a later readdir call on the same DIR stream. */ +extern struct dirent *readdir __P ((DIR * __dirp)); + +/* Rewind DIRP to the beginning of the directory. */ +extern void rewinddir __P ((DIR * __dirp)); + +#if defined(__USE_BSD) || defined(__USE_MISC) + +#ifndef MAXNAMLEN +/* Get the definitions of the POSIX.1 limits. */ +#include <posix1_lim.h> + +/* `MAXNAMLEN' is the BSD name for what POSIX calls `NAME_MAX'. */ +#ifdef NAME_MAX +#define MAXNAMLEN NAME_MAX +#else +#define MAXNAMLEN 255 +#endif +#endif + +#include <gnu/types.h> + +/* Seek to position POS on DIRP. */ +extern void seekdir __P ((DIR * __dirp, __off_t __pos)); + +/* Return the current position of DIRP. */ +extern __off_t telldir __P ((DIR * __dirp)); + +typedef int (*__dir_select_fn_t) __P ((__const struct dirent *)); + +typedef int (*__dir_compar_fn_t) __P (( + __const struct dirent * __const *, + __const struct dirent * __const * + )); + +/* Scan the directory DIR, calling SELECT on each directory entry. + Entries for which SELECT returns nonzero are individually malloc'd, + sorted using qsort with CMP, and collected in a malloc'd array in + *NAMELIST. Returns the number of entries selected, or -1 on error. */ +extern int scandir __P ((__const char *__dir, + struct dirent ***__namelist, + __dir_select_fn_t __dir_select_fn, + __dir_compar_fn_t __dir_compar_fn)); + +/* Function to compare two `struct dirent's alphabetically. */ +extern int alphasort __P (( + __const struct dirent * __const *, + __const struct dirent * __const * + )); + + +/* Read directory entries from FD into BUF, reading at most NBYTES. + Reading starts at offset *BASEP, and *BASEP is updated with the new + position after reading. Returns the number of bytes read; zero when at + end of directory; or -1 for errors. */ +extern __ssize_t __getdirentries __P ((int __fd, char *__buf, + size_t __nbytes, __off_t *__basep)); +extern __ssize_t getdirentries __P ((int __fd, char *__buf, + size_t __nbytes, __off_t *__basep)); + +extern int dirfd __P ((DIR *__dirp)); + +#endif /* Use BSD or misc. */ + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) +extern int readdir_r __P((DIR *__dirp, struct dirent *__entry, + struct dirent **__result)); +#endif + +__END_DECLS + +#endif /* dirent.h */ diff --git a/include/endian.h b/include/endian.h new file mode 100644 index 000000000..593b41963 --- /dev/null +++ b/include/endian.h @@ -0,0 +1,43 @@ +/* Copyright (C) 1992, 1996 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _ENDIAN_H +#define _ENDIAN_H 1 +#include <features.h> + +/* Definitions for byte order, according to significance of bytes, from low + addresses to high addresses. The value is what you get by putting '4' + in the most significant byte, '3' in the second most significant byte, + '2' in the second least significant byte, and '1' in the least + significant byte. */ + +#define __LITTLE_ENDIAN 1234 +#define __BIG_ENDIAN 4321 +#define __PDP_ENDIAN 3412 + +/* This file defines `__BYTE_ORDER' for the particular machine. */ +#include <bytesex.h> + +#ifdef __USE_BSD +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#define BIG_ENDIAN __BIG_ENDIAN +#define PDP_ENDIAN __PDP_ENDIAN +#define BYTE_ORDER __BYTE_ORDER +#endif + +#endif /* endian.h */ diff --git a/include/err.h b/include/err.h new file mode 100644 index 000000000..5bd51ea0d --- /dev/null +++ b/include/err.h @@ -0,0 +1,7 @@ +#ifndef __ERR_H__ +#define __ERR_H__ + +#define warn(X,args...) ({char _buf[128]; sprintf(_buf, X,args); perror(_buf);}) +#define err(X,Y,args...) ({char _buf[128]; sprintf(_buf, Y,##args); perror(_buf); exit(X);}) + +#endif /* __ERR_H__ */ diff --git a/include/errno.h b/include/errno.h new file mode 100644 index 000000000..871c95bef --- /dev/null +++ b/include/errno.h @@ -0,0 +1,25 @@ +#ifndef __ERRNO_H +#define __ERRNO_H + +#include <features.h> +#include <linux/errno.h> + +#ifdef __USE_BSD +extern int sys_nerr; +extern char *sys_errlist[]; +#endif +#ifdef __USE_GNU +extern int _sys_nerr; +extern char *_sys_errlist[]; +#endif + +extern int errno; + +__BEGIN_DECLS + +extern void perror __P ((__const char* __s)); +extern char* strerror __P ((int __errno)); + +__END_DECLS + +#endif diff --git a/include/fcntl.h b/include/fcntl.h new file mode 100644 index 000000000..b9f727216 --- /dev/null +++ b/include/fcntl.h @@ -0,0 +1,20 @@ +#ifndef __FCNTL_H +#define __FCNTL_H + +#include <features.h> +#include <sys/types.h> +#include <linux/fcntl.h> + +#ifndef FNDELAY +#define FNDELAY O_NDELAY +#endif + +__BEGIN_DECLS + +extern int creat __P ((__const char * __filename, mode_t __mode)); +extern int fcntl __P ((int __fildes,int __cmd, ...)); +extern int open __P ((__const char * __filename, int __flags, ...)); + +__END_DECLS + +#endif diff --git a/include/features.h b/include/features.h new file mode 100644 index 000000000..60ecc0a4c --- /dev/null +++ b/include/features.h @@ -0,0 +1,39 @@ + +#ifndef __FEATURES_H +#define __FEATURES_H + +#ifdef __STDC__ + +#define __P(x) x +#define __const const + +/* Almost ansi */ +#if __STDC__ != 1 +#define const +#define volatile +#endif + +#else /* K&R */ + +#define __P(x) () +#define __const +#define const +#define volatile + +#endif + +/* No C++ */ +#define __BEGIN_DECLS +#define __END_DECLS + +/* GNUish things */ +#define __CONSTVALUE +#define __CONSTVALUE2 + +#define _POSIX_THREAD_SAFE_FUNCTIONS + +#include <sys/cdefs.h> + + +#endif + diff --git a/include/getopt.h b/include/getopt.h new file mode 100644 index 000000000..0d71ff6bd --- /dev/null +++ b/include/getopt.h @@ -0,0 +1,17 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#ifndef __GETOPT_H +#define __GETOPT_H + +#include <features.h> + +extern char *optarg; +extern int opterr; +extern int optind; + +extern int getopt __P((int argc, char *const *argv, const char *shortopts)); + +#endif /* __GETOPT_H */ diff --git a/include/grp.h b/include/grp.h new file mode 100644 index 000000000..96b2b4b65 --- /dev/null +++ b/include/grp.h @@ -0,0 +1,37 @@ +#ifndef __GRP_H +#define __GRP_H + +#include <sys/types.h> +#include <features.h> +#include <stdio.h> + +/* The group structure */ +struct group +{ + char *gr_name; /* Group name. */ + char *gr_passwd; /* Password. */ + gid_t gr_gid; /* Group ID. */ + char **gr_mem; /* Member list. */ +}; + +extern void setgrent __P ((void)); +extern void endgrent __P ((void)); +extern struct group * getgrent __P ((void)); + +extern struct group * getgrgid __P ((__const gid_t gid)); +extern struct group * getgrnam __P ((__const char * name)); + +extern struct group * fgetgrent __P ((FILE * file)); + +extern int setgroups __P ((size_t n, __const gid_t * groups)); +extern int initgroups __P ((__const char * user, gid_t gid)); + + +#ifdef __LIBC__ +extern struct group * __getgrent __P ((int grp_fd)); +#endif + +#endif /* _GRP_H */ + + + diff --git a/include/limits.h b/include/limits.h new file mode 100644 index 000000000..8b59c8208 --- /dev/null +++ b/include/limits.h @@ -0,0 +1,140 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.14/2.2.4.2 Limits of integral types <limits.h> + */ + +#ifndef _LIMITS_H + +#define _LIMITS_H 1 +#include <features.h> + +#ifdef __USE_POSIX +/* POSIX adds things to <limits.h>. */ +#include <posix1_lim.h> +#endif + +#ifdef __USE_POSIX2 +#include <posix2_lim.h> +#endif + + +/* Only if gcc 2.x is used and -traditional is not used, we can use + * #include_next. +#if __GNUC__ >= 2 && __STDC__ + */ +#if __GNUC__ >= 2 + + /* Have we done that? */ +# if !defined(_GCC_LIMITS_H_) && !defined(_GCC_LIMITS_H) + /* Get the compiler's limits.h, which defines all the ANSI + * constants. + */ + /* This tells it not to look for another. */ +# define _LIBC_LIMITS_H +# define _LIBC_LIMITS_H_ +# include_next <limits.h> +# endif + +#else /* Not GCC 2. */ + +/* We don't have #include_next. + Define ANSI <limits.h> for standard 32-bit words. */ + +/* These assume 8-bit `char's, 16-bit `short int's, + and 32-bit `int's and `long int's. */ + +/* Number of bits in a `char'. */ +#define CHAR_BIT 8 + +/* Maximum length of any multibyte character in any locale. + Locale-writers should change this as necessary. */ +#define MB_LEN_MAX 1 + +/* Minimum and maximum values a `signed char' can hold. */ +#define SCHAR_MIN (-128) +#define SCHAR_MAX 127 + +/* Maximum value an `unsigned char' can hold. (Minimum is 0.) */ +#ifdef __STDC__ +#define UCHAR_MAX 255U +#else +#define UCHAR_MAX 255 +#endif + +/* Minimum and maximum values a `char' can hold. */ +#ifdef __CHAR_UNSIGNED__ +#define CHAR_MIN 0 +#define CHAR_MAX UCHAR_MAX +#else +#define CHAR_MIN SCHAR_MIN +#define CHAR_MAX SCHAR_MAX +#endif + +/* Minimum and maximum values a `signed short int' can hold. */ +#define SHRT_MIN (-32768) +#define SHRT_MAX 32767 + +/* Maximum value an `unsigned short int' can hold. (Minimum is 0.) */ +#define USHRT_MAX 65535 + +/* Minimum and maximum values a `signed int' can hold. */ +#define INT_MIN (- INT_MAX - 1) +#define INT_MAX 2147483647 + +/* Maximum value an `unsigned int' can hold. (Minimum is 0.) */ +#ifdef __STDC__ +#define UINT_MAX 4294967295U +#else +#define UINT_MAX 4294967295 +#endif + +/* Minimum and maximum values a `signed long int' can hold. */ +#define LONG_MIN INT_MIN +#define LONG_MAX INT_MAX + +/* Maximum value an `unsigned long int' can hold. (Minimum is 0.) */ +#define ULONG_MAX UINT_MAX + +#endif /* GCC 2. */ + + +#ifndef RAND_MAX +/* The largest number rand will return (same as INT_MAX). */ +#define RAND_MAX INT_MAX +#endif + +#ifdef __SVR4_I386_ABI_L1__ + +#define NL_ARGMAX 9 +#define NL_LANGMAX 14 +#define NL_MSGMAX 32767 +#define NL_NMAX 1 +#define NL_SETMAX 255 +#define NL_TEXTMAX 255 +#define NZERO 20 + +#define WORD_BIT 32 +#define LONG_BIT 32 + +#define FCHR_MAX 1048576 + +#endif /* __SVR4_I386_ABI_L1__ */ + +#endif /* limits.h */ diff --git a/include/malloc.h b/include/malloc.h new file mode 100644 index 000000000..e8fdb0a24 --- /dev/null +++ b/include/malloc.h @@ -0,0 +1,30 @@ + +#ifndef __MALLOC_H +#define __MALLOC_H +#include <features.h> +#include <sys/types.h> + +/* + * Mini malloc allows you to use a less efficient but smaller malloc the + * cost is about 100 bytes of code in free but malloc (700bytes) doesn't + * have to be linked. Unfortunatly memory can only be reused if everything + * above it has been freed + * + */ + +extern void free __P((void *)); +extern void *malloc __P((size_t)); +extern void *realloc __P((void *, size_t)); +extern void *alloca __P((size_t)); + +extern void *(*__alloca_alloc) __P((size_t)); + +#ifdef __LIBC__ +#define __MINI_MALLOC__ +#endif + +#ifdef __MINI_MALLOC__ +#define malloc(x) ((*__alloca_alloc)(x)) +#endif + +#endif diff --git a/include/math.h b/include/math.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/include/math.h diff --git a/include/memory.h b/include/memory.h new file mode 100644 index 000000000..3b2f59002 --- /dev/null +++ b/include/memory.h @@ -0,0 +1 @@ +#include <string.h> diff --git a/include/mntent.h b/include/mntent.h new file mode 100644 index 000000000..b4c6a8f2d --- /dev/null +++ b/include/mntent.h @@ -0,0 +1,110 @@ +#ifndef _MNTENT_H +#define _MNTENT_H + +#include <features.h> + +#define MNTTAB "/etc/fstab" +#define MOUNTED "/etc/mtab" + +#define MNTMAXSTR 512 + +#define MNTTYPE_COHERENT "coherent" /* Coherent file system */ +#define MNTTYPE_EXT "ext" /* Extended file system */ +#define MNTTYPE_EXT2 "ext2" /* Second Extended file system */ +#define MNTTYPE_HPFS "hpfs" /* OS/2's high performance file system */ +#define MNTTYPE_ISO9660 "iso9660" /* ISO CDROM file system */ +#define MNTTYPE_MINIX "minix" /* MINIX file system */ +#define MNTTYPE_MSDOS "msdos" /* MS-DOS file system */ +#define MNTTYPE_VFAT "vfat" /* VFAT (Win95) file system */ +#define MNTTYPE_SYSV "sysv" /* System V file system */ +#define MNTTYPE_UMSDOS "umsdos" /* U MS-DOS file system */ +#define MNTTYPE_XENIX "xenix" /* Xenix file system */ +#define MNTTYPE_XIAFS "xiafs" /* Frank Xia's file system */ +#define MNTTYPE_NFS "nfs" /* Network file system */ +#define MNTTYPE_PROC "proc" /* Linux process file system */ +#define MNTTYPE_IGNORE "ignore" /* Ignore this entry */ +#define MNTTYPE_SWAP "swap" /* Swap device */ + +/* generic mount options */ +#define MNTOPT_DEFAULTS "defaults" /* use all default opts */ +#define MNTOPT_RO "ro" /* read only */ +#define MNTOPT_RW "rw" /* read/write */ +#define MNTOPT_SUID "suid" /* set uid allowed */ +#define MNTOPT_NOSUID "nosuid" /* no set uid allowed */ +#define MNTOPT_NOAUTO "noauto" /* don't auto mount */ + +/* ext2 and msdos options */ +#define MNTOPT_CHECK "check" /* filesystem check level */ + +/* ext2 specific options */ +#define MNTOPT_BSDDF "bsddf" /* disable MINIX compatibility disk free counting */ +#define MNTOPT_BSDGROUPS "bsdgroups" /* set BSD group usage */ +#define MNTOPT_ERRORS "errors" /* set behaviour on error */ +#define MNTOPT_GRPID "grpid" /* set BSD group usage */ +#define MNTOPT_MINIXDF "minixdf" /* enable MINIX compatibility disk free counting */ +#define MNTOPT_NOCHECK "nocheck" /* reset filesystem checks */ +#define MNTOPT_NOGRPID "nogrpid" /* set SYSV group usage */ +#define MNTOPT_RESGID "resgid" /* group to consider like root for reserved blocks */ +#define MNTOPT_RESUID "resuid" /* user to consider like root for reserved blocks */ +#define MNTOPT_SB "sb" /* set used super block */ +#define MNTOPT_SYSVGROUPS "sysvgroups" /* set SYSV group usage */ + +/* options common to hpfs, isofs, and msdos */ +#define MNTOPT_CONV "conv" /* convert specified types of data */ +#define MNTOPT_GID "gid" /* use given gid */ +#define MNTOPT_UID "uid" /* use given uid */ +#define MNTOPT_UMASK "umask" /* use given umask, not isofs */ + +/* hpfs specific options */ +#define MNTOPT_CASE "case" /* case conversation */ + +/* isofs specific options */ +#define MNTOPT_BLOCK "block" /* use given block size */ +#define MNTOPT_CRUFT "cruft" /* ??? */ +#define MNTOPT_MAP "map" /* ??? */ +#define MNTOPT_NOROCK "norock" /* not rockwell format ??? */ + +/* msdos specific options */ +#define MNTOPT_FAT "fat" /* set FAT size */ +#define MNTOPT_QUIET "quiet" /* ??? */ + +/* swap specific options */ + +/* options common to ext, ext2, minix, xiafs, sysv, xenix, coherent */ +#define MNTOPT_NOQUOTA "noquota" /* don't use any quota on this partition */ +#define MNTOPT_USRQUOTA "usrquota" /* use userquota on this partition */ +#define MNTOPT_GRPQUOTA "grpquota" /* use groupquota on this partition */ + +/* none defined yet */ + +__BEGIN_DECLS + +struct mntent{ + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; + int mnt_freq; + int mnt_passno; +}; + +__END_DECLS + +#define __need_file +#include <stdio.h> + +__BEGIN_DECLS + +extern FILE *setmntent __P ((__const char *__filep, + __const char *__type)); +extern struct mntent + *getmntent __P ((FILE *__filep)); +extern int addmntent __P ((FILE *__filep, + __const struct mntent *__mnt)); +extern char *hasmntopt __P ((__const struct mntent *__mnt, + __const char *__opt)); +extern int endmntent __P ((FILE *__filep)); + +__END_DECLS + +#endif /* _MNTENT_H */ diff --git a/include/netdb.h b/include/netdb.h new file mode 100644 index 000000000..f332a7c59 --- /dev/null +++ b/include/netdb.h @@ -0,0 +1,215 @@ +/*- + * Copyright (c) 1980, 1983, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)netdb.h 8.1 (Berkeley) 6/2/93 + * netdb.h,v 1.4 1995/08/14 04:05:04 hjl Exp + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +#ifndef _NETDB_H_ +#define _NETDB_H_ + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) +#include <stdio.h> +#include <netinet/in.h> +#endif + +#include <paths.h> + +#define _PATH_HEQUIV __PATH_ETC_INET"/hosts.equiv" +#define _PATH_HOSTS __PATH_ETC_INET"/hosts" +#define _PATH_NETWORKS __PATH_ETC_INET"/networks" +#define _PATH_PROTOCOLS __PATH_ETC_INET"/protocols" +#define _PATH_SERVICES __PATH_ETC_INET"/services" +#define _PATH_RESCONF __PATH_ETC_INET"/resolv.conf" +#define _PATH_RPC __PATH_ETC_INET"/rpc" + + +/* + * Structures returned by network data base library. All addresses are + * supplied in host order, and returned in network order (suitable for + * use in system calls). + */ +struct hostent { + char *h_name; /* official name of host */ + char **h_aliases; /* alias list */ + int h_addrtype; /* host address type */ + int h_length; /* length of address */ + char **h_addr_list; /* list of addresses from name server */ +#define h_addr h_addr_list[0] /* address, for backward compatiblity */ +}; + +/* + * Assumption here is that a network number + * fits in an unsigned long -- probably a poor one. + */ +struct netent { + char *n_name; /* official name of net */ + char **n_aliases; /* alias list */ + int n_addrtype; /* net address type */ + unsigned long n_net; /* network # */ +}; + +struct servent { + char *s_name; /* official service name */ + char **s_aliases; /* alias list */ + int s_port; /* port # */ + char *s_proto; /* protocol to use */ +}; + +struct protoent { + char *p_name; /* official protocol name */ + char **p_aliases; /* alias list */ + int p_proto; /* protocol # */ +}; + +struct rpcent { + char *r_name; /* name of server for this rpc program */ + char **r_aliases; /* alias list */ + int r_number; /* rpc program number */ +}; + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) + +#define __NETDB_MAXALIASES 35 +#define __NETDB_MAXADDRS 35 + +/* + * Error return codes from gethostbyname() and gethostbyaddr() + * (left in extern int h_errno). + */ +#define h_errno (*__h_errno_location ()) +#else +extern int h_errno; +#endif + +#define NETDB_INTERNAL -1 /* see errno */ +#define NETDB_SUCCESS 0 /* no problem */ +#define HOST_NOT_FOUND 1 /* Authoritative Answer Host not found */ +#define TRY_AGAIN 2 /* Non-Authoritive Host not found, or SERVERFAIL */ +#define NO_RECOVERY 3 /* Non recoverable errors, FORMERR, REFUSED, NOTIMP */ +#define NO_DATA 4 /* Valid name, no data record of requested type */ +#define NO_ADDRESS NO_DATA /* no address, look for MX record */ + +#include <features.h> + +__BEGIN_DECLS + +void endhostent __P((void)); +void endnetent __P((void)); +void endprotoent __P((void)); +void endservent __P((void)); +void endrpcent __P ((void)); +struct hostent *gethostbyaddr __P((__const char *, int, int)); +struct hostent *gethostbyname __P((__const char *)); +struct hostent *gethostent __P((void)); +struct netent *getnetbyaddr __P((long, int)); /* u_long? */ +struct netent *getnetbyname __P((__const char *)); +struct netent *getnetent __P((void)); +struct protoent *getprotobyname __P((__const char *)); +struct protoent *getprotobynumber __P((int)); +struct protoent *getprotoent __P((void)); +struct servent *getservbyname __P((__const char *, __const char *)); +struct servent *getservbyport __P((int, __const char *)); +struct servent *getservent __P((void)); +struct rpcent *getrpcent __P((void)); +struct rpcent *getrpcbyname __P((__const char *)); +struct rpcent *getrpcbynumber __P((int)); +void herror __P((__const char *)); +void sethostent __P((int)); +/* void sethostfile __P((__const char *)); */ +void setnetent __P((int)); +void setprotoent __P((int)); +void setservent __P((int)); +void setrpcent __P((int)); + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) +struct hostent *gethostbyaddr_r __P((const char *__addr, + int __length, int __type, + struct hostent *__result, + char *__buffer, int __buflen, int *__h_errnop)); +struct hostent *gethostbyname_r __P((const char * __name, + struct hostent *__result, char *__buffer, + int __buflen, int *__h_errnop)); +struct hostent *gethostent_r __P((struct hostent *__result, + char *__buffer, int __buflen, int *__h_errnop)); +struct netent *getnetbyaddr_r __P((long __net, int __type, + struct netent *__result, char *__buffer, + int __buflen)); +struct netent *getnetbyname_r __P((const char * __name, + struct netent *__result, char *__buffer, + int __buflen)); +struct netent *getnetent_r __P((struct netent *__result, + char *__buffer, int __buflen)); +struct protoent *getprotobyname_r __P((const char * __name, + struct protoent *__result, char *__buffer, + int __buflen)); +struct protoent *getprotobynumber_r __P((int __proto, + struct protoent *__result, char *__buffer, + int __buflen)); +struct protoent *getprotoent_r __P((struct protoent *__result, + char *__buffer, int __buflen)); +struct servent *getservbyname_r __P((const char * __name, + const char *__proto, struct servent *__result, + char *__buffer, int __buflen)); +struct servent *getservbyport_r __P((int __port, + const char *__proto, struct servent *__result, + char *__buffer, int __buflen)); +struct servent *getservent_r __P((struct servent *__result, + char *__buffer, int __buflen)); + +int *__h_errno_location __P((void)); + +#endif + +__END_DECLS + +#endif /* !_NETDB_H_ */ diff --git a/include/netinet/igmp.h b/include/netinet/igmp.h new file mode 100644 index 000000000..4525630e1 --- /dev/null +++ b/include/netinet/igmp.h @@ -0,0 +1,24 @@ +#ifndef _NETINET_IGMP_H +#define _NETINET_IGMP_H + +#include <linux/igmp.h> + +#ifdef __BSD_SOURCE + +struct igmp +{ + __u8 igmp_type; + __u8 igmp_code; + __u16 igmp_cksum; + struct in_addr igmp_group; +}; + +#define IGMP_MINLEN 8 +#define IGMP_MAX_HOST_REPORT_DELAY 10 +#define IGMP_TIMER_SCALE 10 + +#define IGMP_AGE_THRESHOLD 540 + +#endif + +#endif /* _NETINET_IGMP_H */ diff --git a/include/netinet/in.h b/include/netinet/in.h new file mode 100644 index 000000000..d666c67ac --- /dev/null +++ b/include/netinet/in.h @@ -0,0 +1,88 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 1, or (at your option) +any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with the GNU C Library; see the file COPYING. If not, write to +the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +#ifndef _NETINET_IN_H + +#define _NETINET_IN_H 1 +#include <features.h> + +#include <sys/socket.h> + +__BEGIN_DECLS + +/* Standard well-known ports. */ +enum + { + IPPORT_ECHO = 7, /* Echo service. */ + IPPORT_DISCARD = 9, /* Discard transmissions service. */ + IPPORT_SYSTAT = 11, /* System status service. */ + IPPORT_DAYTIME = 13, /* Time of day service. */ + IPPORT_NETSTAT = 15, /* Network status service. */ + IPPORT_FTP = 21, /* File Transfer Protocol. */ + IPPORT_TELNET = 23, /* Telnet protocol. */ + IPPORT_SMTP = 25, /* Simple Mail Transfer Protocol. */ + IPPORT_TIMESERVER = 37, /* Timeserver service. */ + IPPORT_NAMESERVER = 42, /* Domain Name Service. */ + IPPORT_WHOIS = 43, /* Internet Whois service. */ + IPPORT_MTP = 57, + + IPPORT_TFTP = 69, /* Trivial File Transfer Protocol. */ + IPPORT_RJE = 77, + IPPORT_FINGER = 79, /* Finger service. */ + IPPORT_TTYLINK = 87, + IPPORT_SUPDUP = 95, /* SUPDUP protocol. */ + + + IPPORT_EXECSERVER = 512, /* execd service. */ + IPPORT_LOGINSERVER = 513, /* rlogind service. */ + IPPORT_CMDSERVER = 514, + IPPORT_EFSSERVER = 520, + + /* UDP ports. */ + IPPORT_BIFFUDP = 512, + IPPORT_WHOSERVER = 513, + IPPORT_ROUTESERVER = 520, + + /* Ports less than this value are reserved for privileged processes. */ + IPPORT_RESERVED = 1024, + + /* Ports greater this value are reserved for (non-privileged) servers. */ + IPPORT_USERRESERVED = 5000 + }; + + +/* Link numbers. */ +#define IMPLINK_IP 155 +#define IMPLINK_LOWEXPER 156 +#define IMPLINK_HIGHEXPER 158 + + +/* + * Many other definitions have been moved to <linux/in.h>, + * because several parts of the kernel need them. -FvK + */ +#include <linux/in.h> + +/* + * Bind a socket to a privileged IP port + */ +extern int bindresvport __P ((int __sockfd, + struct sockaddr_in * __sin)); + +__END_DECLS + +#endif /* netinet/in.h */ diff --git a/include/netinet/in_systm.h b/include/netinet/in_systm.h new file mode 100644 index 000000000..f481c5511 --- /dev/null +++ b/include/netinet/in_systm.h @@ -0,0 +1 @@ +#include <linux/in_systm.h> diff --git a/include/netinet/ip.h b/include/netinet/ip.h new file mode 100644 index 000000000..a6c49b6af --- /dev/null +++ b/include/netinet/ip.h @@ -0,0 +1,39 @@ +#ifndef _NETINET_IP_H +#define _NETINET_IP_H + +#include <features.h> +#include <netinet/in.h> +#include <linux/ip.h> + +#ifdef _BSD_SOURCE + +/* + * BSD has the following structure + */ + +struct ip +{ +#if defined(__LITTLE_ENDIAN_BITFIELD) + __u8 ip_hl:4, + ip_v:4; +#else + __u8 ip_v:4, + ip_hl:4; +#endif +#define IPVERSION 4 + __u8 ip_tos; + __u16 ip_len; + __u16 ip_id; + __u16 ip_off; + __u8 ip_ttl; + __u8 ip_p; + __u16 ip_csum; + struct in_addr ip_src,ip_dst; +}; + +#define IP_DF 0x4000 /* dont fragment flag */ +#define IP_MF 0x2000 /* more fragments flag */ + +#endif + +#endif /* _NETINET_IP_H */ diff --git a/include/netinet/ip_fw.h b/include/netinet/ip_fw.h new file mode 100644 index 000000000..278a0393f --- /dev/null +++ b/include/netinet/ip_fw.h @@ -0,0 +1 @@ +#include <linux/ip_fw.h> diff --git a/include/netinet/ip_icmp.h b/include/netinet/ip_icmp.h new file mode 100644 index 000000000..1662e3f7f --- /dev/null +++ b/include/netinet/ip_icmp.h @@ -0,0 +1 @@ +#include <linux/icmp.h> diff --git a/include/netinet/ip_tcp.h b/include/netinet/ip_tcp.h new file mode 100644 index 000000000..39111f275 --- /dev/null +++ b/include/netinet/ip_tcp.h @@ -0,0 +1,72 @@ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + * + * @(#)tcp.h 7.5 (Berkeley) 6/29/88 + */ + +#ifndef _NETINET_IP_TCP_H +#define _NETINET_IP_TCP_H + +#include <endian.h> +#include <linux/socket.h> +#include <sys/types.h> + +typedef u_long tcp_seq; +/* + * TCP header. + * Per RFC 793, September, 1981. + */ +struct tcphdr { + u_short th_sport; /* source port */ + u_short th_dport; /* destination port */ + tcp_seq th_seq; /* sequence number */ + tcp_seq th_ack; /* acknowledgement number */ +#if __BYTE_ORDER == __LITTLE_ENDIAN + u_char th_x2:4, /* (unused) */ + th_off:4; /* data offset */ +#endif +#if __BYTE_ORDER == __BIG_ENDIAN + u_char th_off:4, /* data offset */ + th_x2:4; /* (unused) */ +#endif + u_char th_flags; +#define TH_FIN 0x01 +#define TH_SYN 0x02 +#define TH_RST 0x04 +#define TH_PUSH 0x08 +#define TH_ACK 0x10 +#define TH_URG 0x20 + u_short th_win; /* window */ + u_short th_sum; /* checksum */ + u_short th_urp; /* urgent pointer */ +}; + +#define TCPOPT_EOL 0 +#define TCPOPT_NOP 1 +#define TCPOPT_MAXSEG 2 + +/* + * Default maximum segment size for TCP. + * With an IP MSS of 576, this is 536, + * but 512 is probably more convenient. + */ +#ifdef lint +#define TCP_MSS 536 +#else +#define TCP_MSS MIN(512, IP_MSS - sizeof (struct tcpiphdr)) +#endif + +#endif /* _NETINET_TCP_H */ diff --git a/include/netinet/ip_udp.h b/include/netinet/ip_udp.h new file mode 100644 index 000000000..3f0d8ef7c --- /dev/null +++ b/include/netinet/ip_udp.h @@ -0,0 +1 @@ +#include <linux/udp.h> diff --git a/include/netinet/protocols.h b/include/netinet/protocols.h new file mode 100644 index 000000000..1a619c474 --- /dev/null +++ b/include/netinet/protocols.h @@ -0,0 +1,62 @@ +/* protocols.h */ +#ifndef _NETINET_PROTOCOLS_H +#define _NETINET_PROTOCOLS_H + +#define IP_ICMP 1 +#define IP_IGMP 2 +#define IP_GGP 3 +#define IP_ST 5 +#define IP_TCP 6 +#define IP_UCL 7 +#define IP_EGP 8 +#define IP_IGP 9 +#define IP_BBN_RCC_MON 10 +#define IP_NVP_II 11 +#define IP_PUP 12 +#define IP_ARGUS 13 +#define IP_EMCON 14 +#define IP_XNET 15 +#define IP_CHAOS 16 +#define IP_UDP 17 +#define IP_MUX 18 +#define IP_DCN_MEAS 19 +#define IP_HMP 20 +#define IP_PRM 21 +#define IP_XNS_IDP 22 +#define IP_TRUNK1 23 +#define IP_TRUNK2 24 +#define IP_LEAF1 25 +#define IP_LEAF2 26 +#define IP_RDP 27 +#define IP_IRTP 28 +#define IP_ISO_TP4 29 +#define IP_NETBLT 30 +#define IP_MFE_NSP 31 +#define IP_MERIT_INP 32 +#define IP_SEP 33 +#define IP_3PC 34 +#define IP_CFTP 62 +#define SAT_EXPAK 64 +#define IP_RVD 66 +#define IP_IPPC 67 +#define IP_SAT_MON 69 +#define IP_VISA 70 +#define IP_IPCV 71 +#define IP_BR_SAT_MON 76 +#define IP_SUN_ND 77 +#define IP_WB_MON 78 +#define IP_WB_EXPAK 79 +#define IP_ISO_IP 80 +#define IP_VMTP 81 +#define IP_SECURE_VMTP 82 +#define IP_VINES 83 +#define IP_TTP 84 +#define NSFNET_IGP 85 +#define IP_DGP 86 +#define IP_TCF 87 +#define IP_IGRP 88 +#define IP_OSPFIGP 89 +#define IP_SPRITE_RPG 90 +#define IP_LARP 91 + +#endif /* _NETINET_PROTOCOLS_H*/ diff --git a/include/netinet/tcp.h b/include/netinet/tcp.h new file mode 100644 index 000000000..8636ec7d0 --- /dev/null +++ b/include/netinet/tcp.h @@ -0,0 +1 @@ +#include <netinet/ip_tcp.h> diff --git a/include/netinet/udp.h b/include/netinet/udp.h new file mode 100644 index 000000000..39a57a3c7 --- /dev/null +++ b/include/netinet/udp.h @@ -0,0 +1 @@ +#include <netinet/ip_udp.h> diff --git a/include/paths.h b/include/paths.h new file mode 100644 index 000000000..2af8a5749 --- /dev/null +++ b/include/paths.h @@ -0,0 +1,22 @@ +/* paths.h <ndf@linux.mit.edu> */ + +#ifndef ___PATHS_H +#define ___PATHS_H + + +#define _PATH_CONSOLE "/dev/console" +#define _PATH_TTY "/dev/tty" +#define _PATH_NOLOGIN "/etc/nologin" +#define _PATH_LOGIN "/bin/login" +#define _PATH_BSHELL "/bin/sh" +#define _PATH_UTMP "/var/run/utmp" +#define _PATH_WTMP "/var/log/wtmp" +#define _PATH_DEFPATH "/bin:/usr/bin:/usr/local/bin:." +#define _PATH_DEV "/dev/" +#define _PATH_DEVNULL "/dev/null" +#define _PATH_TMP "/tmp/" +#define _PATH_LASTLOG "/var/log/lastlog" +#define _PATH_LOCALE "/usr/lib/locale" +#define _PATH_VARRUN "/var/log/" + +#endif /* __PATHS_H */ diff --git a/include/pwd.h b/include/pwd.h new file mode 100644 index 000000000..1b48c6a6e --- /dev/null +++ b/include/pwd.h @@ -0,0 +1,40 @@ +#ifndef __PWD_H +#define __PWD_H + +#include <sys/types.h> +#include <features.h> +#include <stdio.h> + +/* The passwd structure. */ +struct passwd +{ + char *pw_name; /* Username. */ + char *pw_passwd; /* Password. */ + uid_t pw_uid; /* User ID. */ + gid_t pw_gid; /* Group ID. */ + char *pw_gecos; /* Real name. */ + char *pw_dir; /* Home directory. */ + char *pw_shell; /* Shell program. */ +}; + + +extern void setpwent __P ((void)); +extern void endpwent __P ((void)); +extern struct passwd * getpwent __P ((void)); + +extern int putpwent __P ((__const struct passwd * __p, FILE * __f)); +extern int getpw __P ((uid_t uid, char *buf)); + +extern struct passwd * fgetpwent __P ((FILE * file)); + +extern struct passwd * getpwuid __P ((__const uid_t)); +extern struct passwd * getpwnam __P ((__const char *)); + +#ifdef __LIBC__ +extern struct passwd * __getpwent __P ((__const int passwd_fd)); +#endif + +#endif /* pwd.h */ + + + diff --git a/include/regexp.h b/include/regexp.h new file mode 100644 index 000000000..73d6bf412 --- /dev/null +++ b/include/regexp.h @@ -0,0 +1,21 @@ +/* + * Definitions etc. for regexp(3) routines. + * + * Caveat: this is V8 regexp(3) [actually, a reimplementation thereof], + * not the System V one. + */ +#define NSUBEXP 10 +typedef struct regexp { + char *startp[NSUBEXP]; + char *endp[NSUBEXP]; + char regstart; /* Internal use only. */ + char reganch; /* Internal use only. */ + char *regmust; /* Internal use only. */ + int regmlen; /* Internal use only. */ + char program[1]; /* Unwarranted chumminess with compiler. */ +} regexp; + +extern regexp *regcomp(); +extern int regexec(); +extern void regsub(); +extern void regerror(); diff --git a/include/resolv.h b/include/resolv.h new file mode 100644 index 000000000..53ee2f235 --- /dev/null +++ b/include/resolv.h @@ -0,0 +1,85 @@ +/* resolv.h: DNS Resolver + * + * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>, + * The Silver Hammer Group, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + */ + +#ifndef _RESOLV_H_ +#define _RESOLV_H_ + +#include <netdb.h> +#include <netinet/in.h> + +struct resolv_header { + int id; + int qr,opcode,aa,tc,rd,ra,rcode; + int qdcount; + int ancount; + int nscount; + int arcount; +}; + +struct resolv_question { + char * dotted; + int qtype; + int qclass; +}; + +struct resolv_answer { + char * dotted; + int atype; + int aclass; + int ttl; + int rdlength; + unsigned char * rdata; + int rdoffset; +}; + +int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen); +int decode_header(unsigned char * data, struct resolv_header * h); +int encode_dotted(const char * dotted, unsigned char * dest, int maxlen); +int decode_dotted(const unsigned char * message, int offset, + char * dest, int maxlen); +int length_dotted(const unsigned char * message, int offset); +int encode_question(struct resolv_question * q, + unsigned char * dest, int maxlen); +int decode_question(unsigned char * message, int offset, + struct resolv_question * q); +int length_question(unsigned char * message, int offset); +int encode_answer(struct resolv_answer * a, + unsigned char * dest, int maxlen); +int decode_answer(unsigned char * message, int offset, + struct resolv_answer * a); +char * resolve_name(const char * name, int mailbox); + +int encode_packet(struct resolv_header * h, + struct resolv_question ** q, + struct resolv_question ** an, + struct resolv_question ** ns, + struct resolv_question ** ar, + unsigned char * dest, int maxlen); +int decode_packet(unsigned char * data, struct resolv_header * h); + +int dns_lookup(const char * name, int type, int nscount, const char ** nsip, + unsigned char ** outpacket, struct resolv_answer * a); + +int resolve_address(const char * address, + int nscount, const char ** nsip, + struct in_addr * in); + +int resolve_mailbox(const char * address, + int nscount, const char ** nsip, + struct in_addr * in); + +extern int open_nameservers(void); +extern void close_nameservers(void); + +extern struct hostent * gethostbyname(const char * name); +extern struct hostent * gethostbyaddr(const char * addr, int len, int type); + +#endif /*_RESOLV_H_*/ diff --git a/include/rpc/auth.h b/include/rpc/auth.h new file mode 100644 index 000000000..33cb42951 --- /dev/null +++ b/include/rpc/auth.h @@ -0,0 +1,166 @@ +/* @(#)auth.h 2.3 88/08/07 4.0 RPCSRC; from 1.17 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * auth.h, Authentication interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The data structures are completely opaque to the client. The client + * is required to pass a AUTH * to routines that create rpc + * "sessions". + */ + + +#define MAX_AUTH_BYTES 400 +#define MAXNETNAMELEN 255 /* maximum length of network user's name */ + +/* + * Status returned from authentication check + */ +enum auth_stat { + AUTH_OK=0, + /* + * failed at remote end + */ + AUTH_BADCRED=1, /* bogus credentials (seal broken) */ + AUTH_REJECTEDCRED=2, /* client should begin new session */ + AUTH_BADVERF=3, /* bogus verifier (seal broken) */ + AUTH_REJECTEDVERF=4, /* verifier expired or was replayed */ + AUTH_TOOWEAK=5, /* rejected due to security reasons */ + /* + * failed locally + */ + AUTH_INVALIDRESP=6, /* bogus response verifier */ + AUTH_FAILED=7 /* some unknown reason */ +}; + +#if (mc68000 || sparc || vax || i386) +typedef u_long u_int32; /* 32-bit unsigned integers */ +#endif + +union des_block { + struct { + u_int32 high; + u_int32 low; + } key; + char c[8]; +}; +typedef union des_block des_block; +extern bool_t xdr_des_block(); + +/* + * Authentication info. Opaque to client. + */ +struct opaque_auth { + enum_t oa_flavor; /* flavor of auth */ + caddr_t oa_base; /* address of more auth stuff */ + u_int oa_length; /* not to exceed MAX_AUTH_BYTES */ +}; + + +/* + * Auth handle, interface to client side authenticators. + */ +typedef struct { + struct opaque_auth ah_cred; + struct opaque_auth ah_verf; + union des_block ah_key; + struct auth_ops { + void (*ah_nextverf)(); + int (*ah_marshal)(); /* nextverf & serialize */ + int (*ah_validate)(); /* validate varifier */ + int (*ah_refresh)(); /* refresh credentials */ + void (*ah_destroy)(); /* destroy this structure */ + } *ah_ops; + caddr_t ah_private; +} AUTH; + + +/* + * Authentication ops. + * The ops and the auth handle provide the interface to the authenticators. + * + * AUTH *auth; + * XDR *xdrs; + * struct opaque_auth verf; + */ +#define AUTH_NEXTVERF(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) +#define auth_nextverf(auth) \ + ((*((auth)->ah_ops->ah_nextverf))(auth)) + +#define AUTH_MARSHALL(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) +#define auth_marshall(auth, xdrs) \ + ((*((auth)->ah_ops->ah_marshal))(auth, xdrs)) + +#define AUTH_VALIDATE(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) +#define auth_validate(auth, verfp) \ + ((*((auth)->ah_ops->ah_validate))((auth), verfp)) + +#define AUTH_REFRESH(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) +#define auth_refresh(auth) \ + ((*((auth)->ah_ops->ah_refresh))(auth)) + +#define AUTH_DESTROY(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) +#define auth_destroy(auth) \ + ((*((auth)->ah_ops->ah_destroy))(auth)) + + +extern struct opaque_auth _null_auth; + + +/* + * These are the various implementations of client side authenticators. + */ + +/* + * Unix style authentication + * AUTH *authunix_create(machname, uid, gid, len, aup_gids) + * char *machname; + * int uid; + * int gid; + * int len; + * int *aup_gids; + */ +extern AUTH *authunix_create(); +extern AUTH *authunix_create_default(); /* takes no parameters */ +extern AUTH *authnone_create(); /* takes no parameters */ +extern AUTH *authdes_create(); + +#define AUTH_NONE 0 /* no authentication */ +#define AUTH_NULL 0 /* backward compatibility */ +#define AUTH_UNIX 1 /* unix style (uid, gids) */ +#define AUTH_SHORT 2 /* short hand unix style */ +#define AUTH_DES 3 /* des style (encrypted timestamps) */ diff --git a/include/rpc/auth_des.h b/include/rpc/auth_des.h new file mode 100644 index 000000000..8c2f79469 --- /dev/null +++ b/include/rpc/auth_des.h @@ -0,0 +1,46 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _RPC_AUTH_DES_H + +#define _RPC_AUTH_DES_H 1 +#include <sys/cdefs.h> + +__BEGIN_DECLS + +/* This is no complete version of this header. More definitions with + the real authentication stuff will come in 1997. For now we only + need to define the function for handling public keys. */ + + +/* Get the public key for NAME and place it in KEY. NAME can only be + up to MAXNETNAMELEN bytes long and the destination buffer KEY should + have HEXKEYBATES + 1 bytes long to fit all characters from the key. */ +extern int getpublickey __P ((__const char *__name, char *__key)); + +/* Get the secret key for NAME and place it in KEY. PASSWD is used to + decrypt the encrypted key stored in the database. NAME can only be + up to MAXNETNAMELEN bytes long and the destination buffer KEY + should have HEXKEYBATES + 1 bytes long to fit all characters from + the key. */ +extern int getsecretkey __P ((__const char *__name, char *__key, + __const char *__passwd)); + +__END_DECLS + +#endif /* rpc/auth_des.h */ diff --git a/include/rpc/auth_unix.h b/include/rpc/auth_unix.h new file mode 100644 index 000000000..705741e13 --- /dev/null +++ b/include/rpc/auth_unix.h @@ -0,0 +1,72 @@ +/* @(#)auth_unix.h 2.2 88/07/29 4.0 RPCSRC; from 1.8 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)auth_unix.h 1.5 86/07/16 SMI */ + +/* + * auth_unix.h, Protocol for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * The system is very weak. The client uses no encryption for it + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + */ + +/* The machine name is part of a credential; it may not exceed 255 bytes */ +#define MAX_MACHINE_NAME 255 + +/* gids compose part of a credential; there may not be more than 16 of them */ +#define NGRPS 16 + +/* + * Unix style credentials. + */ +struct authunix_parms { + u_long aup_time; + char *aup_machname; + int aup_uid; + int aup_gid; + u_int aup_len; + int *aup_gids; +}; + +extern bool_t xdr_authunix_parms(); + +/* + * If a response verifier has flavor AUTH_SHORT, + * then the body of the response verifier encapsulates the following structure; + * again it is serialized in the obvious fashion. + */ +struct short_hand_verf { + struct opaque_auth new_cred; +}; diff --git a/include/rpc/clnt.h b/include/rpc/clnt.h new file mode 100644 index 000000000..8c002a19f --- /dev/null +++ b/include/rpc/clnt.h @@ -0,0 +1,331 @@ +/* @(#)clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.31 88/02/08 SMI*/ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * clnt.h - Client side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef _CLNT_ +#define _CLNT_ + +/* + * Rpc calls return an enum clnt_stat. This should be looked at more, + * since each implementation is required to live with this (implementation + * independent) list of errors. + */ +enum clnt_stat { + RPC_SUCCESS=0, /* call succeeded */ + /* + * local errors + */ + RPC_CANTENCODEARGS=1, /* can't encode arguments */ + RPC_CANTDECODERES=2, /* can't decode results */ + RPC_CANTSEND=3, /* failure in sending call */ + RPC_CANTRECV=4, /* failure in receiving result */ + RPC_TIMEDOUT=5, /* call timed out */ + /* + * remote errors + */ + RPC_VERSMISMATCH=6, /* rpc versions not compatible */ + RPC_AUTHERROR=7, /* authentication error */ + RPC_PROGUNAVAIL=8, /* program not available */ + RPC_PROGVERSMISMATCH=9, /* program version mismatched */ + RPC_PROCUNAVAIL=10, /* procedure unavailable */ + RPC_CANTDECODEARGS=11, /* decode arguments error */ + RPC_SYSTEMERROR=12, /* generic "other problem" */ + + /* + * callrpc & clnt_create errors + */ + RPC_UNKNOWNHOST=13, /* unknown host name */ + RPC_UNKNOWNPROTO=17, /* unkown protocol */ + + /* + * _ create errors + */ + RPC_PMAPFAILURE=14, /* the pmapper failed in its call */ + RPC_PROGNOTREGISTERED=15, /* remote program is not registered */ + /* + * unspecified error + */ + RPC_FAILED=16 +}; + + +/* + * Error info. + */ +struct rpc_err { + enum clnt_stat re_status; + union { + int RE_errno; /* realated system error */ + enum auth_stat RE_why; /* why the auth error occurred */ + struct { + u_long low; /* lowest verion supported */ + u_long high; /* highest verion supported */ + } RE_vers; + struct { /* maybe meaningful if RPC_FAILED */ + long s1; + long s2; + } RE_lb; /* life boot & debugging only */ + } ru; +#define re_errno ru.RE_errno +#define re_why ru.RE_why +#define re_vers ru.RE_vers +#define re_lb ru.RE_lb +}; + + +/* + * Client rpc handle. + * Created by individual implementations, see e.g. rpc_udp.c. + * Client is responsible for initializing auth, see e.g. auth_none.c. + */ +typedef struct { + AUTH *cl_auth; /* authenticator */ + struct clnt_ops { + enum clnt_stat (*cl_call)(); /* call remote procedure */ + void (*cl_abort)(); /* abort a call */ + void (*cl_geterr)(); /* get specific error code */ + bool_t (*cl_freeres)(); /* frees results */ + void (*cl_destroy)();/* destroy this structure */ + bool_t (*cl_control)();/* the ioctl() of rpc */ + } *cl_ops; + caddr_t cl_private; /* private stuff */ +} CLIENT; + + +/* + * client side rpc interface ops + * + * Parameter types are: + * + */ + +/* + * enum clnt_stat + * CLNT_CALL(rh, proc, xargs, argsp, xres, resp, timeout) + * CLIENT *rh; + * u_long proc; + * xdrproc_t xargs; + * caddr_t argsp; + * xdrproc_t xres; + * caddr_t resp; + * struct timeval timeout; + */ +#define CLNT_CALL(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) +#define clnt_call(rh, proc, xargs, argsp, xres, resp, secs) \ + ((*(rh)->cl_ops->cl_call)(rh, proc, xargs, argsp, xres, resp, secs)) + +/* + * void + * CLNT_ABORT(rh); + * CLIENT *rh; + */ +#define CLNT_ABORT(rh) ((*(rh)->cl_ops->cl_abort)(rh)) +#define clnt_abort(rh) ((*(rh)->cl_ops->cl_abort)(rh)) + +/* + * struct rpc_err + * CLNT_GETERR(rh); + * CLIENT *rh; + */ +#define CLNT_GETERR(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) +#define clnt_geterr(rh,errp) ((*(rh)->cl_ops->cl_geterr)(rh, errp)) + + +/* + * bool_t + * CLNT_FREERES(rh, xres, resp); + * CLIENT *rh; + * xdrproc_t xres; + * caddr_t resp; + */ +#define CLNT_FREERES(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) +#define clnt_freeres(rh,xres,resp) ((*(rh)->cl_ops->cl_freeres)(rh,xres,resp)) + +/* + * bool_t + * CLNT_CONTROL(cl, request, info) + * CLIENT *cl; + * u_int request; + * char *info; + */ +#define CLNT_CONTROL(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) +#define clnt_control(cl,rq,in) ((*(cl)->cl_ops->cl_control)(cl,rq,in)) + +/* + * control operations that apply to both udp and tcp transports + */ +#define CLSET_TIMEOUT 1 /* set timeout (timeval) */ +#define CLGET_TIMEOUT 2 /* get timeout (timeval) */ +#define CLGET_SERVER_ADDR 3 /* get server's address (sockaddr) */ +/* + * udp only control operations + */ +#define CLSET_RETRY_TIMEOUT 4 /* set retry timeout (timeval) */ +#define CLGET_RETRY_TIMEOUT 5 /* get retry timeout (timeval) */ + +/* + * void + * CLNT_DESTROY(rh); + * CLIENT *rh; + */ +#define CLNT_DESTROY(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) +#define clnt_destroy(rh) ((*(rh)->cl_ops->cl_destroy)(rh)) + + +/* + * RPCTEST is a test program which is accessable on every rpc + * transport/port. It is used for testing, performance evaluation, + * and network administration. + */ + +#define RPCTEST_PROGRAM ((u_long)1) +#define RPCTEST_VERSION ((u_long)1) +#define RPCTEST_NULL_PROC ((u_long)2) +#define RPCTEST_NULL_BATCH_PROC ((u_long)3) + +/* + * By convention, procedure 0 takes null arguments and returns them + */ + +#define NULLPROC ((u_long)0) + +/* + * Below are the client handle creation routines for the various + * implementations of client side rpc. They can return NULL if a + * creation failure occurs. + */ + +/* + * Memory based rpc (for speed check and testing) + * CLIENT * + * clntraw_create(prog, vers) + * u_long prog; + * u_long vers; + */ +extern CLIENT *clntraw_create(); + + +/* + * Generic client creation routine. Supported protocols are "udp" and "tcp" + */ +extern CLIENT * +clnt_create(/*host, prog, vers, prot*/); /* + char *host; -- hostname + u_long prog; -- program number + u_long vers; -- version number + char *prot; -- protocol +*/ + + + + +/* + * TCP based rpc + * CLIENT * + * clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long prog; + * u_long version; + * register int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +extern CLIENT *clnttcp_create(); + +/* + * UDP based rpc. + * CLIENT * + * clntudp_create(raddr, program, version, wait, sockp) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * + * Same as above, but you specify max packet sizes. + * CLIENT * + * clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + * struct sockaddr_in *raddr; + * u_long program; + * u_long version; + * struct timeval wait; + * int *sockp; + * u_int sendsz; + * u_int recvsz; + */ +extern CLIENT *clntudp_create(); +extern CLIENT *clntudp_bufcreate(); + +/* + * Print why creation failed + */ +void clnt_pcreateerror(/* char *msg */); /* stderr */ +char *clnt_spcreateerror(/* char *msg */); /* string */ + +/* + * Like clnt_perror(), but is more verbose in its output + */ +void clnt_perrno(/* enum clnt_stat num */); /* stderr */ + +/* + * Print an English error message, given the client error code + */ +void clnt_perror(/* CLIENT *clnt, char *msg */); /* stderr */ +char *clnt_sperror(/* CLIENT *clnt, char *msg */); /* string */ + +/* + * If a creation fails, the following allows the user to figure out why. + */ +struct rpc_createerr { + enum clnt_stat cf_stat; + struct rpc_err cf_error; /* useful when cf_stat == RPC_PMAPFAILURE */ +}; + +extern struct rpc_createerr rpc_createerr; + + + +/* + * Copy error message to buffer. + */ +char *clnt_sperrno(/* enum clnt_stat num */); /* string */ + + + +#define UDPMSGSIZE 8800 /* rpc imposed limit on udp msg size */ +#define RPCSMALLMSGSIZE 400 /* a more reasonable packet size */ + +#endif /*!_CLNT_*/ diff --git a/include/rpc/pmap_clnt.h b/include/rpc/pmap_clnt.h new file mode 100644 index 000000000..d2ea2a88e --- /dev/null +++ b/include/rpc/pmap_clnt.h @@ -0,0 +1,65 @@ +/* @(#)pmap_clnt.h 2.1 88/07/29 4.0 RPCSRC; from 1.11 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * pmap_clnt.h + * Supplies C routines to get to portmap services. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +/* + * Usage: + * success = pmap_set(program, version, protocol, port); + * success = pmap_unset(program, version); + * port = pmap_getport(address, program, version, protocol); + * head = pmap_getmaps(address); + * clnt_stat = pmap_rmtcall(address, program, version, procedure, + * xdrargs, argsp, xdrres, resp, tout, port_ptr) + * (works for udp only.) + * clnt_stat = clnt_broadcast(program, version, procedure, + * xdrargs, argsp, xdrres, resp, eachresult) + * (like pmap_rmtcall, except the call is broadcasted to all + * locally connected nets. For each valid response received, + * the procedure eachresult is called. Its form is: + * done = eachresult(resp, raddr) + * bool_t done; + * caddr_t resp; + * struct sockaddr_in raddr; + * where resp points to the results of the call and raddr is the + * address if the responder to the broadcast. + */ + +extern bool_t pmap_set(); +extern bool_t pmap_unset(); +extern struct pmaplist *pmap_getmaps(); +enum clnt_stat pmap_rmtcall(); +enum clnt_stat clnt_broadcast(); +extern u_short pmap_getport(); diff --git a/include/rpc/pmap_prot.h b/include/rpc/pmap_prot.h new file mode 100644 index 000000000..ccf7a77b4 --- /dev/null +++ b/include/rpc/pmap_prot.h @@ -0,0 +1,94 @@ +/* @(#)pmap_prot.h 2.1 88/07/29 4.0 RPCSRC; from 1.14 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * pmap_prot.h + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The following procedures are supported by the protocol: + * + * PMAPPROC_NULL() returns () + * takes nothing, returns nothing + * + * PMAPPROC_SET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Registers the tuple + * [prog, vers, prot, port]. + * + * PMAPPROC_UNSET(struct pmap) returns (bool_t) + * TRUE is success, FALSE is failure. Un-registers pair + * [prog, vers]. prot and port are ignored. + * + * PMAPPROC_GETPORT(struct pmap) returns (long unsigned). + * 0 is failure. Otherwise returns the port number where the pair + * [prog, vers] is registered. It may lie! + * + * PMAPPROC_DUMP() RETURNS (struct pmaplist *) + * + * PMAPPROC_CALLIT(unsigned, unsigned, unsigned, string<>) + * RETURNS (port, string<>); + * usage: encapsulatedresults = PMAPPROC_CALLIT(prog, vers, proc, encapsulatedargs); + * Calls the procedure on the local machine. If it is not registered, + * this procedure is quite; ie it does not return error information!!! + * This procedure only is supported on rpc/udp and calls via + * rpc/udp. This routine only passes null authentication parameters. + * This file has no interface to xdr routines for PMAPPROC_CALLIT. + * + * The service supports remote procedure calls on udp/ip or tcp/ip socket 111. + */ + +#define PMAPPORT ((u_short)111) +#define PMAPPROG ((u_long)100000) +#define PMAPVERS ((u_long)2) +#define PMAPVERS_PROTO ((u_long)2) +#define PMAPVERS_ORIG ((u_long)1) +#define PMAPPROC_NULL ((u_long)0) +#define PMAPPROC_SET ((u_long)1) +#define PMAPPROC_UNSET ((u_long)2) +#define PMAPPROC_GETPORT ((u_long)3) +#define PMAPPROC_DUMP ((u_long)4) +#define PMAPPROC_CALLIT ((u_long)5) + +struct pmap { + long unsigned pm_prog; + long unsigned pm_vers; + long unsigned pm_prot; + long unsigned pm_port; +}; + +extern bool_t xdr_pmap(); + +struct pmaplist { + struct pmap pml_map; + struct pmaplist *pml_next; +}; + +extern bool_t xdr_pmaplist(); diff --git a/include/rpc/pmap_rmt.h b/include/rpc/pmap_rmt.h new file mode 100644 index 000000000..ee68cebec --- /dev/null +++ b/include/rpc/pmap_rmt.h @@ -0,0 +1,53 @@ +/* @(#)pmap_rmt.h 2.1 88/07/29 4.0 RPCSRC; from 1.2 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Structures and XDR routines for parameters to and replies from + * the portmapper remote-call-service. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + */ + +struct rmtcallargs { + u_long prog, vers, proc, arglen; + caddr_t args_ptr; + xdrproc_t xdr_args; +}; + +bool_t xdr_rmtcall_args(); + +struct rmtcallres { + u_long *port_ptr; + u_long resultslen; + caddr_t results_ptr; + xdrproc_t xdr_results; +}; + +bool_t xdr_rmtcallres(); diff --git a/include/rpc/rpc.h b/include/rpc/rpc.h new file mode 100644 index 000000000..b7d50d2dc --- /dev/null +++ b/include/rpc/rpc.h @@ -0,0 +1,79 @@ +/* @(#)rpc.h 2.3 88/08/10 4.0 RPCSRC; from 1.9 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * rpc.h, Just includes the billions of rpc header files necessary to + * do remote procedure calling. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ +#ifndef __RPC_HEADER__ +#define __RPC_HEADER__ + +#ifdef linux +#include <sys/time.h> +#endif + +#include <rpc/types.h> /* some typedefs */ +#include <netinet/in.h> + +/* external data representation interfaces */ +#include <rpc/xdr.h> /* generic (de)serializer */ + +/* Client side only authentication */ +#include <rpc/auth.h> /* generic authenticator (client side) */ + +/* Client side (mostly) remote procedure call */ +#include <rpc/clnt.h> /* generic rpc stuff */ + +/* semi-private protocol headers */ +#include <rpc/rpc_msg.h> /* protocol for rpc messages */ +#include <rpc/auth_unix.h> /* protocol for unix style cred */ +/* + * Uncomment-out the next line if you are building the rpc library with + * DES Authentication (see the README file in the secure_rpc/ directory). + */ +/*#include <rpc/auth_des.h> /* protocol for des style cred */ + +/* Server side only remote procedure callee */ +#include <rpc/svc.h> /* service manager and multiplexer */ +#include <rpc/svc_auth.h> /* service side authenticator */ + +/* + * COMMENT OUT THE NEXT INCLUDE IF RUNNING ON SUN OS OR ON A VERSION + * OF UNIX BASED ON NFSSRC. These systems will already have the structures + * defined by <rpc/netdb.h> included in <netdb.h>. + */ +/* routines for parsing /etc/rpc */ +#if 0 +#include <rpc/netdb.h> /* structures and routines to parse /etc/rpc */ +#endif + +#endif /* ndef __RPC_HEADER__ */ diff --git a/include/rpc/rpc_msg.h b/include/rpc/rpc_msg.h new file mode 100644 index 000000000..b78872b6a --- /dev/null +++ b/include/rpc/rpc_msg.h @@ -0,0 +1,187 @@ +/* @(#)rpc_msg.h 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)rpc_msg.h 1.7 86/07/16 SMI */ + +/* + * rpc_msg.h + * rpc message definition + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#define RPC_MSG_VERSION ((u_long) 2) +#define RPC_SERVICE_PORT ((u_short) 2048) + +/* + * Bottom up definition of an rpc message. + * NOTE: call and reply use the same overall stuct but + * different parts of unions within it. + */ + +enum msg_type { + CALL=0, + REPLY=1 +}; + +enum reply_stat { + MSG_ACCEPTED=0, + MSG_DENIED=1 +}; + +enum accept_stat { + SUCCESS=0, + PROG_UNAVAIL=1, + PROG_MISMATCH=2, + PROC_UNAVAIL=3, + GARBAGE_ARGS=4, + SYSTEM_ERR=5 +}; + +enum reject_stat { + RPC_MISMATCH=0, + AUTH_ERROR=1 +}; + +/* + * Reply part of an rpc exchange + */ + +/* + * Reply to an rpc request that was accepted by the server. + * Note: there could be an error even though the request was + * accepted. + */ +struct accepted_reply { + struct opaque_auth ar_verf; + enum accept_stat ar_stat; + union { + struct { + u_long low; + u_long high; + } AR_versions; + struct { + caddr_t where; + xdrproc_t proc; + } AR_results; + /* and many other null cases */ + } ru; +#define ar_results ru.AR_results +#define ar_vers ru.AR_versions +}; + +/* + * Reply to an rpc request that was rejected by the server. + */ +struct rejected_reply { + enum reject_stat rj_stat; + union { + struct { + u_long low; + u_long high; + } RJ_versions; + enum auth_stat RJ_why; /* why authentication did not work */ + } ru; +#define rj_vers ru.RJ_versions +#define rj_why ru.RJ_why +}; + +/* + * Body of a reply to an rpc request. + */ +struct reply_body { + enum reply_stat rp_stat; + union { + struct accepted_reply RP_ar; + struct rejected_reply RP_dr; + } ru; +#define rp_acpt ru.RP_ar +#define rp_rjct ru.RP_dr +}; + +/* + * Body of an rpc request call. + */ +struct call_body { + u_long cb_rpcvers; /* must be equal to two */ + u_long cb_prog; + u_long cb_vers; + u_long cb_proc; + struct opaque_auth cb_cred; + struct opaque_auth cb_verf; /* protocol specific - provided by client */ +}; + +/* + * The rpc message + */ +struct rpc_msg { + u_long rm_xid; + enum msg_type rm_direction; + union { + struct call_body RM_cmb; + struct reply_body RM_rmb; + } ru; +#define rm_call ru.RM_cmb +#define rm_reply ru.RM_rmb +}; +#define acpted_rply ru.RM_rmb.ru.RP_ar +#define rjcted_rply ru.RM_rmb.ru.RP_dr + + +/* + * XDR routine to handle a rpc message. + * xdr_callmsg(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callmsg(); + +/* + * XDR routine to pre-serialize the static part of a rpc message. + * xdr_callhdr(xdrs, cmsg) + * XDR *xdrs; + * struct rpc_msg *cmsg; + */ +extern bool_t xdr_callhdr(); + +/* + * XDR routine to handle a rpc reply. + * xdr_replymsg(xdrs, rmsg) + * XDR *xdrs; + * struct rpc_msg *rmsg; + */ +extern bool_t xdr_replymsg(); + +/* + * Fills in the error part of a reply message. + * _seterr_reply(msg, error) + * struct rpc_msg *msg; + * struct rpc_err *error; + */ +extern void _seterr_reply(); diff --git a/include/rpc/svc.h b/include/rpc/svc.h new file mode 100644 index 000000000..3cb07ef3f --- /dev/null +++ b/include/rpc/svc.h @@ -0,0 +1,280 @@ +/* @(#)svc.h 2.2 88/07/29 4.0 RPCSRC; from 1.20 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * svc.h, Server-side remote procedure call interface. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef __SVC_HEADER__ +#define __SVC_HEADER__ + +/* + * This interface must manage two items concerning remote procedure calling: + * + * 1) An arbitrary number of transport connections upon which rpc requests + * are received. The two most notable transports are TCP and UDP; they are + * created and registered by routines in svc_tcp.c and svc_udp.c, respectively; + * they in turn call xprt_register and xprt_unregister. + * + * 2) An arbitrary number of locally registered services. Services are + * described by the following four data: program number, version number, + * "service dispatch" function, a transport handle, and a boolean that + * indicates whether or not the exported program should be registered with a + * local binder service; if true the program's number and version and the + * port number from the transport handle are registered with the binder. + * These data are registered with the rpc svc system via svc_register. + * + * A service's dispatch function is called whenever an rpc request comes in + * on a transport. The request's program and version numbers must match + * those of the registered service. The dispatch function is passed two + * parameters, struct svc_req * and SVCXPRT *, defined below. + */ + +enum xprt_stat { + XPRT_DIED, + XPRT_MOREREQS, + XPRT_IDLE +}; + +/* + * Server side transport handle + */ +typedef struct { + int xp_sock; + u_short xp_port; /* associated port number */ + struct xp_ops { + bool_t (*xp_recv)(); /* receive incomming requests */ + enum xprt_stat (*xp_stat)(); /* get transport status */ + bool_t (*xp_getargs)(); /* get arguments */ + bool_t (*xp_reply)(); /* send reply */ + bool_t (*xp_freeargs)();/* free mem allocated for args */ + void (*xp_destroy)(); /* destroy this struct */ + } *xp_ops; + int xp_addrlen; /* length of remote address */ + struct sockaddr_in xp_raddr; /* remote address */ + struct opaque_auth xp_verf; /* raw response verifier */ + caddr_t xp_p1; /* private */ + caddr_t xp_p2; /* private */ +} SVCXPRT; + +/* + * Approved way of getting address of caller + */ +#define svc_getcaller(x) (&(x)->xp_raddr) + +/* + * Operations defined on an SVCXPRT handle + * + * SVCXPRT *xprt; + * struct rpc_msg *msg; + * xdrproc_t xargs; + * caddr_t argsp; + */ +#define SVC_RECV(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) +#define svc_recv(xprt, msg) \ + (*(xprt)->xp_ops->xp_recv)((xprt), (msg)) + +#define SVC_STAT(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) +#define svc_stat(xprt) \ + (*(xprt)->xp_ops->xp_stat)(xprt) + +#define SVC_GETARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) +#define svc_getargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_getargs)((xprt), (xargs), (argsp)) + +#define SVC_REPLY(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) +#define svc_reply(xprt, msg) \ + (*(xprt)->xp_ops->xp_reply) ((xprt), (msg)) + +#define SVC_FREEARGS(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) +#define svc_freeargs(xprt, xargs, argsp) \ + (*(xprt)->xp_ops->xp_freeargs)((xprt), (xargs), (argsp)) + +#define SVC_DESTROY(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) +#define svc_destroy(xprt) \ + (*(xprt)->xp_ops->xp_destroy)(xprt) + + +/* + * Service request + */ +struct svc_req { + u_long rq_prog; /* service program number */ + u_long rq_vers; /* service protocol version */ + u_long rq_proc; /* the desired procedure */ + struct opaque_auth rq_cred; /* raw creds from the wire */ + caddr_t rq_clntcred; /* read only cooked cred */ + SVCXPRT *rq_xprt; /* associated transport */ +}; + + +/* + * Service registration + * + * svc_register(xprt, prog, vers, dispatch, protocol) + * SVCXPRT *xprt; + * u_long prog; + * u_long vers; + * void (*dispatch)(); + * int protocol; /* like TCP or UDP, zero means do not register + */ +extern bool_t svc_register(); + +/* + * Service un-registration + * + * svc_unregister(prog, vers) + * u_long prog; + * u_long vers; + */ +extern void svc_unregister(); + +/* + * Transport registration. + * + * xprt_register(xprt) + * SVCXPRT *xprt; + */ +extern void xprt_register(); + +/* + * Transport un-register + * + * xprt_unregister(xprt) + * SVCXPRT *xprt; + */ +extern void xprt_unregister(); + + + + +/* + * When the service routine is called, it must first check to see if it + * knows about the procedure; if not, it should call svcerr_noproc + * and return. If so, it should deserialize its arguments via + * SVC_GETARGS (defined above). If the deserialization does not work, + * svcerr_decode should be called followed by a return. Successful + * decoding of the arguments should be followed the execution of the + * procedure's code and a call to svc_sendreply. + * + * Also, if the service refuses to execute the procedure due to too- + * weak authentication parameters, svcerr_weakauth should be called. + * Note: do not confuse access-control failure with weak authentication! + * + * NB: In pure implementations of rpc, the caller always waits for a reply + * msg. This message is sent when svc_sendreply is called. + * Therefore pure service implementations should always call + * svc_sendreply even if the function logically returns void; use + * xdr.h - xdr_void for the xdr routine. HOWEVER, tcp based rpc allows + * for the abuse of pure rpc via batched calling or pipelining. In the + * case of a batched call, svc_sendreply should NOT be called since + * this would send a return message, which is what batching tries to avoid. + * It is the service/protocol writer's responsibility to know which calls are + * batched and which are not. Warning: responding to batch calls may + * deadlock the caller and server processes! + */ + +extern bool_t svc_sendreply(); +extern void svcerr_decode(); +extern void svcerr_weakauth(); +extern void svcerr_noproc(); +extern void svcerr_progvers(); +extern void svcerr_auth(); +extern void svcerr_noprog(); +extern void svcerr_systemerr(); + +/* + * Lowest level dispatching -OR- who owns this process anyway. + * Somebody has to wait for incoming requests and then call the correct + * service routine. The routine svc_run does infinite waiting; i.e., + * svc_run never returns. + * Since another (co-existant) package may wish to selectively wait for + * incoming calls or other events outside of the rpc architecture, the + * routine svc_getreq is provided. It must be passed readfds, the + * "in-place" results of a select system call (see select, section 2). + */ + +/* + * Global keeper of rpc service descriptors in use + * dynamic; must be inspected before each call to select + */ +#ifdef FD_SETSIZE +extern fd_set svc_fdset; +#define svc_fds svc_fdset.fds_bits[0] /* compatibility */ +#else +extern int svc_fds; +#endif /* def FD_SETSIZE */ + +/* + * a small program implemented by the svc_rpc implementation itself; + * also see clnt.h for protocol numbers. + */ +extern void rpctest_service(); + +extern void svc_getreq(); +extern void svc_getreqset(); /* takes fdset instead of int */ +extern void svc_run(); /* never returns */ + +/* + * Socket to use on svcxxx_create call to get default socket + */ +#define RPC_ANYSOCK -1 + +/* + * These are the existing service side transport implementations + */ + +/* + * Memory based rpc for testing and timing. + */ +extern SVCXPRT *svcraw_create(); + +/* + * Udp based rpc. + */ +extern SVCXPRT *svcudp_create(); +extern SVCXPRT *svcudp_bufcreate(); + +/* + * Tcp based rpc. + */ +extern SVCXPRT *svctcp_create(); + + + +#endif !__SVC_HEADER__ diff --git a/include/rpc/svc_auth.h b/include/rpc/svc_auth.h new file mode 100644 index 000000000..a36a01aba --- /dev/null +++ b/include/rpc/svc_auth.h @@ -0,0 +1,42 @@ +/* @(#)svc_auth.h 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)svc_auth.h 1.6 86/07/16 SMI */ + +/* + * svc_auth.h, Service side of rpc authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + + +/* + * Server side authenticator + */ +extern enum auth_stat _authenticate(); diff --git a/include/rpc/types.h b/include/rpc/types.h new file mode 100644 index 000000000..96d92428c --- /dev/null +++ b/include/rpc/types.h @@ -0,0 +1,65 @@ +/* @(#)types.h 2.3 88/08/15 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)types.h 1.18 87/07/24 SMI */ + +/* + * Rpc additions to <sys/types.h> + */ +#ifndef __TYPES_RPC_HEADER__ +#define __TYPES_RPC_HEADER__ + +#define bool_t int +#define enum_t int +#define FALSE (0) +#define TRUE (1) +#define __dontcare__ -1 +#ifndef NULL +# define NULL 0 +#endif + +#include <stdlib.h> +#define mem_alloc(bsize) malloc(bsize) +#define mem_free(ptr, bsize) free(ptr) + +#ifndef makedev /* ie, we haven't already included it */ +#include <sys/types.h> +#endif +#include <sys/time.h> + +#ifndef linux +#ifndef INADDR_LOOPBACK +#define INADDR_LOOPBACK (u_long)0x7F000001 +#endif +#endif +#ifndef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 64 +#endif + +#endif /* ndef __TYPES_RPC_HEADER__ */ diff --git a/include/rpc/xdr.h b/include/rpc/xdr.h new file mode 100644 index 000000000..6cd3e6fe0 --- /dev/null +++ b/include/rpc/xdr.h @@ -0,0 +1,270 @@ +/* @(#)xdr.h 2.2 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +/* @(#)xdr.h 1.19 87/04/22 SMI */ + +/* + * xdr.h, External Data Representation Serialization Routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#ifndef __XDR_HEADER__ +#define __XDR_HEADER__ + +/* + * XDR provides a conventional way for converting between C data + * types and an external bit-string representation. Library supplied + * routines provide for the conversion on built-in C data types. These + * routines and utility routines defined here are used to help implement + * a type encode/decode routine for each user-defined type. + * + * Each data type provides a single procedure which takes two arguments: + * + * bool_t + * xdrproc(xdrs, argresp) + * XDR *xdrs; + * <type> *argresp; + * + * xdrs is an instance of a XDR handle, to which or from which the data + * type is to be converted. argresp is a pointer to the structure to be + * converted. The XDR handle contains an operation field which indicates + * which of the operations (ENCODE, DECODE * or FREE) is to be performed. + * + * XDR_DECODE may allocate space if the pointer argresp is null. This + * data can be freed with the XDR_FREE operation. + * + * We write only one procedure per data type to make it easy + * to keep the encode and decode procedures for a data type consistent. + * In many cases the same code performs all operations on a user defined type, + * because all the hard work is done in the component type routines. + * decode as a series of calls on the nested data types. + */ + +/* + * Xdr operations. XDR_ENCODE causes the type to be encoded into the + * stream. XDR_DECODE causes the type to be extracted from the stream. + * XDR_FREE can be used to release the space allocated by an XDR_DECODE + * request. + */ +enum xdr_op { + XDR_ENCODE=0, + XDR_DECODE=1, + XDR_FREE=2 +}; + +/* + * This is the number of bytes per unit of external data. + */ +#define BYTES_PER_XDR_UNIT (4) +#define RNDUP(x) ((((x) + BYTES_PER_XDR_UNIT - 1) / BYTES_PER_XDR_UNIT) \ + * BYTES_PER_XDR_UNIT) + +/* + * A xdrproc_t exists for each data type which is to be encoded or decoded. + * + * The second argument to the xdrproc_t is a pointer to an opaque pointer. + * The opaque pointer generally points to a structure of the data type + * to be decoded. If this pointer is 0, then the type routines should + * allocate dynamic storage of the appropriate size and return it. + * bool_t (*xdrproc_t)(XDR *, caddr_t *); + */ +typedef bool_t (*xdrproc_t)(); + +/* + * The XDR handle. + * Contains operation which is being applied to the stream, + * an operations vector for the paticular implementation (e.g. see xdr_mem.c), + * and two private fields for the use of the particular impelementation. + */ +typedef struct { + enum xdr_op x_op; /* operation; fast additional param */ + struct xdr_ops { + bool_t (*x_getlong)(); /* get a long from underlying stream */ + bool_t (*x_putlong)(); /* put a long to " */ + bool_t (*x_getbytes)();/* get some bytes from " */ + bool_t (*x_putbytes)();/* put some bytes to " */ + u_int (*x_getpostn)();/* returns bytes off from beginning */ + bool_t (*x_setpostn)();/* lets you reposition the stream */ + long * (*x_inline)(); /* buf quick ptr to buffered data */ + void (*x_destroy)(); /* free privates of this xdr_stream */ + } *x_ops; + caddr_t x_public; /* users' data */ + caddr_t x_private; /* pointer to private data */ + caddr_t x_base; /* private used for position info */ + int x_handy; /* extra private word */ +} XDR; + +/* + * Operations defined on a XDR handle + * + * XDR *xdrs; + * long *longp; + * caddr_t addr; + * u_int len; + * u_int pos; + */ +#define XDR_GETLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) +#define xdr_getlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_getlong)(xdrs, longp) + +#define XDR_PUTLONG(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) +#define xdr_putlong(xdrs, longp) \ + (*(xdrs)->x_ops->x_putlong)(xdrs, longp) + +#define XDR_GETBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) +#define xdr_getbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len) + +#define XDR_PUTBYTES(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) +#define xdr_putbytes(xdrs, addr, len) \ + (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len) + +#define XDR_GETPOS(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) +#define xdr_getpos(xdrs) \ + (*(xdrs)->x_ops->x_getpostn)(xdrs) + +#define XDR_SETPOS(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) +#define xdr_setpos(xdrs, pos) \ + (*(xdrs)->x_ops->x_setpostn)(xdrs, pos) + +#define XDR_INLINE(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) +#define xdr_inline(xdrs, len) \ + (*(xdrs)->x_ops->x_inline)(xdrs, len) + +#define XDR_DESTROY(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) +#define xdr_destroy(xdrs) \ + if ((xdrs)->x_ops->x_destroy) \ + (*(xdrs)->x_ops->x_destroy)(xdrs) + +/* + * Support struct for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * a entry with a null procedure pointer. The xdr_union routine gets + * the discriminant value and then searches the array of structures + * for a matching value. If a match is found the associated xdr routine + * is called to handle that part of the union. If there is + * no match, then a default routine may be called. + * If there is no match and no default routine it is an error. + */ +#define NULL_xdrproc_t ((xdrproc_t)0) +struct xdr_discrim { + int value; + xdrproc_t proc; +}; + +/* + * In-line routines for fast encode/decode of primitve data types. + * Caveat emptor: these use single memory cycles to get the + * data from the underlying buffer, and will fail to operate + * properly if the data is not aligned. The standard way to use these + * is to say: + * if ((buf = XDR_INLINE(xdrs, count)) == NULL) + * return (FALSE); + * <<< macro calls >>> + * where ``count'' is the number of bytes of data occupied + * by the primitive data types. + * + * N.B. and frozen for all time: each data type here uses 4 bytes + * of external representation. + */ +#define IXDR_GET_LONG(buf) ((long)ntohl((u_long)*(buf)++)) +#define IXDR_PUT_LONG(buf, v) (*(buf)++ = (long)htonl((u_long)v)) + +#define IXDR_GET_BOOL(buf) ((bool_t)IXDR_GET_LONG(buf)) +#define IXDR_GET_ENUM(buf, t) ((t)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_LONG(buf) ((u_long)IXDR_GET_LONG(buf)) +#define IXDR_GET_SHORT(buf) ((short)IXDR_GET_LONG(buf)) +#define IXDR_GET_U_SHORT(buf) ((u_short)IXDR_GET_LONG(buf)) + +#define IXDR_PUT_BOOL(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_ENUM(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_LONG(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) +#define IXDR_PUT_U_SHORT(buf, v) IXDR_PUT_LONG((buf), ((long)(v))) + +/* + * These are the "generic" xdr routines. + */ +extern bool_t xdr_void(); +extern bool_t xdr_int(); +extern bool_t xdr_u_int(); +extern bool_t xdr_long(); +extern bool_t xdr_u_long(); +extern bool_t xdr_short(); +extern bool_t xdr_u_short(); +extern bool_t xdr_bool(); +extern bool_t xdr_enum(); +extern bool_t xdr_array(); +extern bool_t xdr_bytes(); +extern bool_t xdr_opaque(); +extern bool_t xdr_string(); +extern bool_t xdr_union(); +extern bool_t xdr_char(); +extern bool_t xdr_u_char(); +extern bool_t xdr_vector(); +extern bool_t xdr_float(); +extern bool_t xdr_double(); +extern bool_t xdr_reference(); +extern bool_t xdr_pointer(); +extern bool_t xdr_wrapstring(); + +/* + * Common opaque bytes objects used by many rpc protocols; + * declared here due to commonality. + */ +#define MAX_NETOBJ_SZ 1024 +struct netobj { + u_int n_len; + char *n_bytes; +}; +typedef struct netobj netobj; +extern bool_t xdr_netobj(); + +/* + * These are the public routines for the various implementations of + * xdr streams. + */ +extern void xdrmem_create(); /* XDR using memory buffers */ +extern void xdrstdio_create(); /* XDR using stdio library */ +extern void xdrrec_create(); /* XDR pseudo records for tcp */ +extern bool_t xdrrec_endofrecord(); /* make end of xdr record */ +extern bool_t xdrrec_skiprecord(); /* move to beginning of next record */ +extern bool_t xdrrec_eof(); /* true if no more input */ + +#endif !__XDR_HEADER__ diff --git a/include/search.h b/include/search.h new file mode 100644 index 000000000..b9c8a1785 --- /dev/null +++ b/include/search.h @@ -0,0 +1,94 @@ +/* Copyright (C) 1993 Ulrich Drepper + +This file is intended to be included in the GNU C Library and the +Linux C Library. So the copyright notice will be: + + +Copyright (C) 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. + + +For now the file can be distributed under the LGPL. */ + +#ifndef _SEARCH_H +#define _SEARCH_H + +#include <features.h> + +#define __need_size_t +#define __need_NULL +#include <stddef.h> + +__BEGIN_DECLS + +#ifndef __COMPAR_FN_T +#define __COMPAR_FN_T +typedef int (*__compar_fn_t) __P ((__const __ptr_t, __const __ptr_t)); +#endif + +/* for use with hsearch(3) */ + +typedef struct entry { char *key; char *data; } ENTRY; +typedef enum { FIND, ENTER } ACTION; + +extern ENTRY * hsearch __P((ENTRY __item, ACTION __action)); +extern int hcreate __P((unsigned __nel)); +extern void hdestroy __P((void)); + + +/* The tsearch routines are very interesting. They make many + * assumptions about the compiler. It assumpts that the first field + * in node must be the "key" field, which points to the datum. + * Everything depends on that. It is a very tricky stuff. H.J. + */ +/* For tsearch */ +typedef enum { preorder, postorder, endorder, leaf } VISIT; + +extern void *tsearch __P((__const void * __key, void **__rootp, + __compar_fn_t compar)); + +extern void *tfind __P((__const void * __key, __const void ** __rootp, + __compar_fn_t compar)); + +extern void *tdelete __P((__const void * __key, void ** __rootp, + __compar_fn_t compar)); + +#ifndef __ACTION_FN_T +#define __ACTION_FN_T +/* FYI, the first argument should be a pointer to "key". + * Please read the man page for details. + */ +typedef void (*__action_fn_t) __P((__const void *__nodep, + __const VISIT __value, + __const int __level)); +#endif + +extern void twalk __P((__const void * __root, __action_fn_t action)); + + +extern void * lfind __P((__const void * __key, __const void * __base, + size_t * __nmemb, size_t __size, + __compar_fn_t __compar)); + +extern void * lsearch __P((__const void * __key, __const void * __base, + size_t * __nmemb, size_t __size, + __compar_fn_t __compar)); + +__END_DECLS + +#endif /* search.h */ diff --git a/include/setjmp.h b/include/setjmp.h new file mode 100644 index 000000000..53d0223fd --- /dev/null +++ b/include/setjmp.h @@ -0,0 +1,22 @@ +/* + setjmp.h + stubs for future use. +*/ + +#ifndef _SETJMP_H_ +#ifdef __cplusplus +extern "C" { +#endif +#define _SETJMP_H_ + +#include "_ansi.h" +#include <machine/setjmp.h> + +void _EXFUN(longjmp,(jmp_buf __jmpb, int __retval)); +int _EXFUN(setjmp,(jmp_buf __jmpb)); + +#ifdef __cplusplus +} +#endif +#endif /* _SETJMP_H_ */ + diff --git a/include/signal.h b/include/signal.h new file mode 100644 index 000000000..9daf0c07c --- /dev/null +++ b/include/signal.h @@ -0,0 +1,166 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.7 SIGNAL HANDLING <signal.h> + */ + +#ifndef _SIGNAL_H +#define _SIGNAL_H + +#include <features.h> +#include <sys/types.h> +#include <linux/signal.h> + +#ifndef SIGCLD +#define SIGCLD SIGCHLD +#endif + +/* SVR4 */ +#ifndef SA_RESETHAND +#define SA_RESETHAND SA_ONESHOT +#endif + +/* SVR4 */ +#ifndef SA_NODEFER +#define SA_NODEFER SA_NOMASK +#endif + +typedef int sig_atomic_t; + +typedef __sighandler_t SignalHandler; + +#ifndef BADSIG +#define BADSIG SIG_ERR +#endif + +/* The Interviews version also has these ... */ + +#define SignalBad ((SignalHandler)-1) +#define SignalDefault ((SignalHandler)0) +#define SignalIgnore ((SignalHandler)1) + +__BEGIN_DECLS + +extern __const char * __const sys_siglist[]; +extern __const char * __const _sys_siglist[]; + +extern __sighandler_t + signal __P ((int __sig, __sighandler_t)); +extern __sighandler_t + __signal __P ((int __sig, __sighandler_t, int flags)); +extern int raise __P ((int __sig)); +extern int __kill __P ((pid_t __pid, int __sig)); +extern int kill __P ((pid_t __pid, int __sig)); +extern int killpg __P ((int __pgrp, int __sig)); +extern int sigaddset __P ((sigset_t *__mask, int __sig)); +extern int sigdelset __P ((sigset_t *__mask, int __sig)); +extern int sigemptyset __P ((sigset_t *__mask)); +extern int sigfillset __P ((sigset_t *__mask)); +extern int sigismember __P ((__const sigset_t *__mask, int __sig)); +extern int sigpending __P ((sigset_t *__set)); + +extern int __sigprocmask __P ((int __how, __const sigset_t *__set, + sigset_t *__oldset)); +extern int sigprocmask __P ((int __how, __const sigset_t *__set, + sigset_t *__oldset)); + +extern int sigsuspend __P ((__const sigset_t *sigmask)); + +extern int __sigaction __P ((int __sig, struct sigaction *__act, + struct sigaction *__oldact)); +extern int sigaction __P ((int __sig, struct sigaction *__act, + struct sigaction *__oldact)); + +#define __sigemptyset(set) ((*(set) = 0L), 0) +#define __sigfillset(set) ((*(set) = -1L), 0) +#define __sigaddset(set, sig) ((*(set) |= __sigmask (sig)), 0) +#define __sigdelset(set, sig) ((*(set) &= ~__sigmask (sig)), 0) +#define __sigismember(set, sig) ((*(set) & __sigmask (sig)) ? 1 : 0) + + +#if 1 +#define sigemptyset __sigemptyset +#define sigfillset __sigfillset + +/* We don't do that any more since it causes problems due to + * "sig" > _NSIG and "sig" < 1. It isn't worth the touble to make + * them inline and static. Use __sigxxxxx if you want speed with + * correct "sig". + */ +#if 1 +#define sigaddset __sigaddset +#define sigdelset __sigdelset +#define sigismember __sigismember +#endif + +#endif + + +/* Return a mask that includes SIG only. */ +#define __sigmask(sig) (1 << ((sig) - 1)) + +extern int __sigsetmask __P ((int __mask)); +extern int __siggetmask __P ((void)); +extern int __sigblock __P ((int __mask)); +extern int __sigpause __P ((int __mask)); + +#ifdef __USE_SVID +/* SVID names for the same things. */ +extern __sighandler_t ssignal __P ((int __sig, __sighandler_t __handler)); +extern int gsignal __P ((int __sig)); + +#endif /* Use SVID. */ + +/* BSD */ +#ifdef __USE_BSD +#define sigmask __sigmask + +extern int sigblock __P ((int __mask)); +extern int sigpause __P ((int __mask)); +extern int sigsetmask __P ((int __mask)); +extern int siggetmask __P ((void)); +extern void psignal __P ((int __sig, __const char *__str)); + +extern int siginterrupt __P ((int __sig, int __flag)); + +/* The `sig' bit is set if the interrupt on it + * is enabled via siginterrupt (). */ +extern sigset_t _sigintr; + +#endif /* Use BSD. */ + +#ifdef __USE_BSD_SIGNAL + +extern __sighandler_t + __bsd_signal __P ((int __sig, __sighandler_t)); +#define signal __bsd_signal + +#endif /* __USE_BSD_SIGNAL */ + +__END_DECLS + +#if _MIT_POSIX_THREADS +#define __SIGFILLSET 0xffffffff +#define __SIGEMPTYSET 0 +#define __SIGADDSET(s,n) ((*s) |= (1 << ((n) - 1))) +#define __SIGDELSET(s,n) ((*s) &= ~(1 << ((n) - 1))) +#define __SIGISMEMBER(s,n) ((*s) & (1 << ((n) - 1))) +#endif + +#endif /* _SIGNAL_H */ diff --git a/include/stdarg.h b/include/stdarg.h new file mode 100644 index 000000000..321e6646e --- /dev/null +++ b/include/stdarg.h @@ -0,0 +1,47 @@ + /* + * @(#) stdarg.h 1.2 91/11/30 21:10:39 + * + * Sample stdarg.h file for use with the unproto filter. + * + * This file serves two purposes. + * + * 1 - As an include file for use with ANSI-style C source that implements + * variadic functions. + * + * 2 - To configure the unproto filter itself. If the _VA_ALIST_ macro is + * defined, its value will appear in the place of the "..." in argument + * lists of variadic function *definitions* (not declarations). + * + * Compilers that pass arguments via the stack can use the default code at the + * end of this file (this usually applies for the VAX, MC68k and 80*86 + * architectures). + * + * RISC-based systems often need special tricks. An example of the latter is + * given for the SPARC architecture. Read your /usr/include/varargs.h for + * more information. + * + * You can use the varargs.c program provided with the unproto package to + * verify that the stdarg.h file has been set up correctly. + */ + +#ifndef __STDARG_H +#define __STDARG_H + +#ifdef sparc +# define _VA_ALIST_ "__builtin_va_alist" + typedef char *va_list; +# define va_start(ap, p) (ap = (char *) &__builtin_va_alist) +# define va_arg(ap, type) ((type *) __builtin_va_arg_incr((type *) ap))[0] +# define va_end(ap) +#else /* vax, mc68k, 80*86 */ + typedef char *va_list; +# define va_start(ap, p) (ap = (char *) (&(p)+1)) +# define va_arg(ap, type) ((type *) (ap += sizeof(type)))[-1] +# define va_end(ap) +#endif + +#endif /* __STDARG_H */ + +#if __FIRST_ARG_IN_AX__ +#error First arg is in a register, stdarg.h cannot take its address +#endif diff --git a/include/stdio.h b/include/stdio.h new file mode 100644 index 000000000..1f63f6002 --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,118 @@ + +#ifndef __STDIO_H +#define __STDIO_H + +#include <features.h> +#include <sys/types.h> + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#define _IOFBF 0x00 /* full buffering */ +#define _IOLBF 0x01 /* line buffering */ +#define _IONBF 0x02 /* no buffering */ +#define __MODE_BUF 0x03 /* Modal buffering dependent on isatty */ + +#define __MODE_FREEBUF 0x04 /* Buffer allocated with malloc, can free */ +#define __MODE_FREEFIL 0x08 /* FILE allocated with malloc, can free */ + +#define __MODE_READ 0x10 /* Opened in read only */ +#define __MODE_WRITE 0x20 /* Opened in write only */ +#define __MODE_RDWR 0x30 /* Opened in read/write */ + +#define __MODE_READING 0x40 /* Buffer has pending read data */ +#define __MODE_WRITING 0x80 /* Buffer has pending write data */ + +#define __MODE_EOF 0x100 /* EOF status */ +#define __MODE_ERR 0x200 /* Error status */ +#define __MODE_UNGOT 0x400 /* Buffer has been polluted by ungetc */ + +#define __MODE_IOTRAN 0 + +/* when you add or change fields here, be sure to change the initialization + * in stdio_init and fopen */ +struct __stdio_file { + unsigned char *bufpos; /* the next byte to write to or read from */ + unsigned char *bufread; /* the end of data returned by last read() */ + unsigned char *bufwrite; /* highest address writable by macro */ + unsigned char *bufstart; /* the start of the buffer */ + unsigned char *bufend; /* the end of the buffer; ie the byte after the last + malloc()ed byte */ + + int fd; /* the file descriptor associated with the stream */ + int mode; + + char unbuf[8]; /* The buffer for 'unbuffered' streams */ + + struct __stdio_file * next; +}; + +#define EOF (-1) +#ifndef NULL +#define NULL (0) +#endif + +typedef struct __stdio_file FILE; + +#define BUFSIZ (500) /*(508) should get us a fully used kmalloc bucket */ + +extern FILE stdin[1]; +extern FILE stdout[1]; +extern FILE stderr[1]; + + +#define putc(c, stream) \ + (((stream)->bufpos >= (stream)->bufwrite) ? fputc((c), (stream)) \ + : (unsigned char) (*(stream)->bufpos++ = (c)) ) + +#define getc(stream) \ + (((stream)->bufpos >= (stream)->bufread) ? fgetc(stream): \ + (*(stream)->bufpos++)) + +#define putchar(c) putc((c), stdout) +#define getchar() getc(stdin) + +#define ferror(fp) (((fp)->mode&__MODE_ERR) != 0) +#define feof(fp) (((fp)->mode&__MODE_EOF) != 0) +#define clearerr(fp) ((fp)->mode &= ~(__MODE_EOF|__MODE_ERR),0) +#define fileno(fp) ((fp)->fd) + +/* These two call malloc */ +#define setlinebuf(__fp) setvbuf((__fp), (char*)0, _IOLBF, 0) +extern int setvbuf __P((FILE*, char*, int, size_t)); + +/* These don't */ +#define setbuf(__fp, __buf) setbuffer((__fp), (__buf), BUFSIZ) +extern void setbuffer __P((FILE*, char*, int)); + +extern int fgetc __P((FILE*)); +extern int fputc __P((int, FILE*)); + +extern int fclose __P((FILE*)); +extern int fflush __P((FILE*)); +extern char *fgets __P((char*, size_t, FILE*)); +extern FILE *__fopen __P((char*, int, FILE*, char*)); + +#define fopen(__file, __mode) __fopen((__file), -1, (FILE*)0, (__mode)) +#define freopen(__file, __mode, __fp) __fopen((__file), -1, (__fp), (__mode)) +#define fdopen(__file, __mode) __fopen((char*)0, (__file), (FILE*)0, (__mode)) + +extern int fseek __P((FILE*, long, int)); +extern long ftell __P((FILE*)); +extern void rewind __P((FILE*)); + +extern int fputs __P((char*, FILE*)); +extern int puts __P((char*)); + +extern int printf __P ((__const char*, ...)); +extern int fprintf __P ((FILE*, __const char*, ...)); +extern int sprintf __P ((char*, __const char*, ...)); + +extern int ungetc __P ((int c, FILE * stream)); + +#define stdio_pending(fp) ((fp)->bufread>(fp)->bufpos) + +#endif /* __STDIO_H */ diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100644 index 000000000..27c0a5885 --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,75 @@ +/* stdlib.h <ndf@linux.mit.edu> */ +#include <features.h> +#include <sys/types.h> + +#ifndef __STDLIB_H +#define __STDLIB_H + +/* Don't overwrite user definitions of NULL */ +#ifndef NULL +#define NULL ((void *) 0) +#endif + +/* For program termination */ +#define EXIT_FAILURE 1 +#define EXIT_SUCCESS 0 + +extern void * malloc __P ((size_t)); +extern void * calloc __P ((size_t, size_t)); +extern void free __P ((void *)); +extern void * realloc __P ((void *, size_t)); + +#ifdef DEBUG_MALLOC + +extern void * malloc_dbg __P ((size_t, char* func, char* file, int line)); +extern void * calloc_dbg __P ((size_t, size_t, char* func, char* file, int line)); +extern void free_dbg __P ((void *, char* func, char* file, int line)); +extern void * realloc_dbg __P ((void *, size_t, char* func, char* file, int line)); + +#define malloc(x) malloc_dbg((x),__FUNCTION__,__FILE__,__LINE__) +#define calloc(x,y) calloc_dbg((x),(y),__FUNCTION__,__FILE__,__LINE__) +#define free(x) free_dbg((x),__FUNCTION__,__FILE__,__LINE__) +#define realloc(x) realloc((x),__FUNCTION__,__FILE__,__LINE__) + +#endif + +extern int rand __P ((void)); +extern void srand __P ((unsigned int seed)); + +extern long strtol __P ((const char * nptr, char ** endptr, int base)); +extern unsigned long strtoul __P ((const char * nptr, + char ** endptr, int base)); +#ifndef __HAS_NO_FLOATS__ +extern float strtod __P ((const char * nptr, char ** endptr)); +#endif + +extern char *getenv __P ((__const char *__name)); + +extern int putenv __P ((__const char *__string)); + +extern int setenv __P ((__const char *__name, __const char *__value, + int __replace)); + +extern int system __P ((__const char *__command)); + +extern int qsort __P ((char *base, int num, int size, int (*cmp)())); + +extern char * gcvt __P ((float number, size_t ndigit, char * buf)); + +#define atof(x) strtod((x),(char**)0) + +/* Returned by `div'. */ +typedef struct + { + int quot; /* Quotient. */ + int rem; /* Remainder. */ + } div_t; + +/* Returned by `ldiv'. */ +typedef struct + { + long int quot; /* Quotient. */ + long int rem; /* Remainder. */ + } ldiv_t; + +#endif /* __STDLIB_H */ diff --git a/include/string.h b/include/string.h new file mode 100644 index 000000000..eb448492e --- /dev/null +++ b/include/string.h @@ -0,0 +1,56 @@ + +#ifndef __STRING_H +#define __STRING_H +#include <features.h> +#include <sys/types.h> +#include <stddef.h> + +/* Basic string functions */ +extern size_t strlen __P ((__const char* __str)); + +extern char * strcat __P ((char*, __const char*)); +extern char * strcpy __P ((char*, __const char*)); +extern int strcmp __P ((__const char*, __const char*)); + +extern char * strncat __P ((char*, __const char*, size_t)); +extern char * strncpy __P ((char*, __const char*, size_t)); +extern int strncmp __P ((__const char*, __const char*, size_t)); + +extern char * strchr __P ((char*, int)); +extern char * strrchr __P ((char*, int)); +extern char * strdup __P ((__const char*)); + +/* Basic mem functions */ +extern void * memcpy __P ((void*, __const void*, size_t)); +extern void * memccpy __P ((void*, void*, int, size_t)); +extern void * memchr __P ((__const void*, __const int, size_t)); +extern void * memset __P ((void*, int, size_t)); +extern int memcmp __P ((__const void*, __const void*, size_t)); + +extern void * memmove __P ((void*, void*, size_t)); + +/* Minimal (very!) locale support */ +#define strcoll strcmp +#define strxfrm strncpy + +/* BSDisms */ +#define index strchr +#define rindex strrchr + +/* Other common BSD functions */ +extern int strcasecmp __P ((char*, char*)); +extern int strncasecmp __P ((char*, char*, size_t)); +char *strpbrk __P ((char *, char *)); +char *strsep __P ((char **, char *)); +char *strstr __P ((char *, char *)); +char *strtok __P ((char *, char *)); +size_t strcspn __P ((char *, char *)); +size_t strspn __P ((char *, char *)); + +/* More BSD compatabilty */ +#define bcmp memcmp + +/* Linux silly hour */ +char *strfry __P ((char *)); + +#endif diff --git a/include/strings.h b/include/strings.h new file mode 100644 index 000000000..3b2f59002 --- /dev/null +++ b/include/strings.h @@ -0,0 +1 @@ +#include <string.h> diff --git a/include/sys/bitypes.h b/include/sys/bitypes.h new file mode 100644 index 000000000..e2ac0ab45 --- /dev/null +++ b/include/sys/bitypes.h @@ -0,0 +1,94 @@ +/* + * bitypes.h,v 1.4 1995/08/24 01:58:54 hjl Exp + */ + +/* + * ++Copyright++ 1993 + * - + * Copyright (c) 1993 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * - + * Portions Copyright (c) 1993 by Digital Equipment Corporation. + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies, and that + * the name of Digital Equipment Corporation not be used in advertising or + * publicity pertaining to distribution of the document or software without + * specific, written prior permission. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL + * WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT + * CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. + * - + * --Copyright-- + */ + +/* +#ifdef __USE_BSD +*/ + +/* +#ifndef __BIT_TYPES_DEFINED__ +# if (defined(BSD) && (BSD >= 199306)) || \ + (defined(_BSDI_VERSION) && (_BSDI_VERSION >= 199312)) +# define __BIT_TYPES_DEFINED__ +# endif +#endif +*/ + +#ifndef __BIT_TYPES_DEFINED__ +#define __BIT_TYPES_DEFINED__ + + /* + * Basic integral types. Omit the typedef if + * not possible for a machine/compiler combination. + */ + typedef /*signed*/ char int8_t; + typedef unsigned char u_int8_t; + typedef short int16_t; + typedef unsigned short u_int16_t; + typedef int int32_t; + typedef unsigned int u_int32_t; + +# if __GNUC__ >= 2 && !defined(__STRICT_ANSI__) + typedef long long int64_t; + typedef unsigned long long u_int64_t; +# endif + +#endif /* __BIT_TYPES_DEFINED__ */ + +/* #endif __USE_BSD */ diff --git a/include/sys/cdefs.h b/include/sys/cdefs.h new file mode 100644 index 000000000..0afc8830f --- /dev/null +++ b/include/sys/cdefs.h @@ -0,0 +1,36 @@ + +#ifndef __SYS_CDEFS_H +#define __SYS_CDEFS_H +#include <features.h> + +#if defined (__STDC__) && __STDC__ + +#define __CONCAT(x,y) x ## y +#define __STRING(x) #x + +/* This is not a typedef so `const __ptr_t' does the right thing. */ +#define __ptr_t void * +typedef long double __long_double_t; + +#else + +#define __CONCAT(x,y) x/**/y +#define __STRING(x) "x" + +#define __ptr_t char * + +#ifndef __HAS_NO_FLOATS__ +typedef double __long_double_t; +#endif + +#endif + +/* No C++ */ +#define __BEGIN_DECLS +#define __END_DECLS + +/* GNUish things */ +#define __CONSTVALUE +#define __CONSTVALUE2 + +#endif diff --git a/include/sys/dir.h b/include/sys/dir.h new file mode 100644 index 000000000..1c2cea7df --- /dev/null +++ b/include/sys/dir.h @@ -0,0 +1,17 @@ +#ifdef _SYS_DIRENT_H +#error "Can't include both sys/dir.h and sys/dirent.h" +#define _SYS_DIR_H +#endif + +#ifndef _SYS_DIR_H +#define _SYS_DIR_H + +#include <dirent.h> + +#define direct dirent + +#undef DIRSIZ +#define DIRSIZ(dp) ((sizeof (struct direct) - (MAXNAMLEN+1)) + \ + (((dp)->d_namlen+1 + 3) &~ 3)) + +#endif diff --git a/include/sys/errno.h b/include/sys/errno.h new file mode 100644 index 000000000..339f4fc10 --- /dev/null +++ b/include/sys/errno.h @@ -0,0 +1 @@ +#include <errno.h> diff --git a/include/sys/fcntl.h b/include/sys/fcntl.h new file mode 100644 index 000000000..cd304557e --- /dev/null +++ b/include/sys/fcntl.h @@ -0,0 +1 @@ +#include <fcntl.h> diff --git a/include/sys/file.h b/include/sys/file.h new file mode 100644 index 000000000..2401b155a --- /dev/null +++ b/include/sys/file.h @@ -0,0 +1,35 @@ +#ifndef _SYS_FILE_H +#define _SYS_FILE_H + +#include <features.h> +#include <fcntl.h> + +#ifndef L_SET + +#define L_SET 0 /* absolute offset */ +#define L_INCR 1 /* relative to current offset */ +#define L_XTND 2 /* relative to end of file */ + +#endif + +#ifndef LOCK_SH + +/* Operations for the `flock' call. */ +#define LOCK_SH 1 /* Shared lock. */ +#define LOCK_EX 2 /* Exclusive lock. */ +#define LOCK_UN 8 /* Unlock. */ + +/* Can be OR'd in to one of the above. */ +#define LOCK_NB 4 /* Don't block when locking. */ + +#endif + +__BEGIN_DECLS + +/* Apply or remove an advisory lock, according to OPERATION, + on the file FD refers to. */ +extern int flock __P ((int __fd, int __operation)); + +__END_DECLS + +#endif diff --git a/include/sys/ioctl.h b/include/sys/ioctl.h new file mode 100644 index 000000000..11dd06edb --- /dev/null +++ b/include/sys/ioctl.h @@ -0,0 +1,17 @@ +#ifndef _SYS_IOCTL_H +#define _SYS_IOCTL_H + +#include <linux/ioctl.h> +#include <features.h> +#include <termios.h> +#include <sys/socketio.h> + +__BEGIN_DECLS + +extern int ioctl __P ((int __fildes, int __cmd, ...)); +extern int __ioctl __P ((int __fildes, int __cmd, ...)); + +__END_DECLS + + +#endif diff --git a/include/sys/mman.h b/include/sys/mman.h new file mode 100644 index 000000000..8dc79d909 --- /dev/null +++ b/include/sys/mman.h @@ -0,0 +1,35 @@ +#ifndef _SYS_MMAN_H +#define _SYS_MMAN_H + +#include <features.h> +#include <sys/types.h> +#include <linux/mman.h> + +#ifndef MAP_ANON +#define MAP_ANON MAP_ANONYMOUS /* idem */ +#endif +#ifndef MAP_FILE +#define MAP_FILE 0x00 /* The 'normal' way: mapped from file */ +#endif + +__BEGIN_DECLS + +extern __ptr_t mmap __P((__ptr_t __addr, size_t __len, + int __prot, int __flags, int __fd, off_t __off)); +extern int munmap __P((__ptr_t __addr, size_t __len)); +extern int mprotect __P ((__const __ptr_t __addr, size_t __len, int __prot)); + +extern int msync __P((__ptr_t __addr, size_t __len, int __flags)); + +extern int mlock __P((__const __ptr_t __addr, size_t __len)); +extern int munlock __P((__const __ptr_t __addr, size_t __len)); + +extern int mlockall __P((int __flags)); +extern int munlockall __P((void)); + +extern __ptr_t mremap __P((__ptr_t __addr, size_t __old_len, + size_t __new_len, int __may_move)); + +__END_DECLS + +#endif /* _SYS_MMAN_H */ diff --git a/include/sys/mount.h b/include/sys/mount.h new file mode 100644 index 000000000..a0765e2ee --- /dev/null +++ b/include/sys/mount.h @@ -0,0 +1,17 @@ +#ifndef _SYS_MOUNT_H +#define _SYS_MOUNT_H + +#include <features.h> + +__BEGIN_DECLS + +extern int mount __P ((__const char* __specialfile, + __const char* __dir,__const char* __filesystemype, + unsigned long __rwflag,__const void *__data)); + +extern int umount __P ((__const char* __specialfile)); + + +__END_DECLS + +#endif diff --git a/include/sys/param.h b/include/sys/param.h new file mode 100644 index 000000000..906a0a230 --- /dev/null +++ b/include/sys/param.h @@ -0,0 +1,46 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#ifndef _PARAM_H +#define _PARAM_H + +#include <features.h> +#include <limits.h> +#include <linux/limits.h> +#include <linux/param.h> + +#include <sys/types.h> + +#define MAXPATHLEN PATH_MAX + +#ifndef NR_OPEN +#define NR_OPEN 32 +#endif +#ifndef NR_FILE +#define NR_FILE 32 +#endif + +/* Bit map related macros. */ +#define setbit(a,i) ((a)[(i)/NBBY] |= 1<<((i)%NBBY)) +#define clrbit(a,i) ((a)[(i)/NBBY] &= ~(1<<((i)%NBBY))) +#define isset(a,i) ((a)[(i)/NBBY] & (1<<((i)%NBBY))) +#define isclr(a,i) (((a)[(i)/NBBY] & (1<<((i)%NBBY))) == 0) + +/* Macros for counting and rounding. */ +#ifndef howmany +#define howmany(x, y) (((x)+((y)-1))/(y)) +#endif +#define roundup(x, y) ((((x)+((y)-1))/(y))*(y)) +#define powerof2(x) ((((x)-1)&(x))==0) + +/* Macros for min/max. */ +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + + +/* Unit of `st_blocks'. */ +#define DEV_BSIZE 512 + +#endif /* _PARAM_H */ diff --git a/include/sys/resource.h b/include/sys/resource.h new file mode 100644 index 000000000..19ed06f50 --- /dev/null +++ b/include/sys/resource.h @@ -0,0 +1,73 @@ +/* + * Resource control/accounting header file for linux-86 + */ + +#ifndef _SYS_RESOURCE_H +#define _SYS_RESOURCE_H + +#include <features.h> +#include <sys/time.h> +#include <limits.h> + +#define RUSAGE_SELF 0 +#define RUSAGE_CHILDREN (-1) +#define RUSAGE_BOTH (-2) /* sys_wait4() uses this */ + +struct rusage { + struct timeval ru_utime; /* user time used */ + struct timeval ru_stime; /* system time used */ + long ru_maxrss; /* maximum resident set size */ + long ru_ixrss; /* integral shared memory size */ + long ru_idrss; /* integral unshared data size */ + long ru_isrss; /* integral unshared stack size */ + long ru_minflt; /* page reclaims */ + long ru_majflt; /* page faults */ + long ru_nswap; /* swaps */ + long ru_inblock; /* block input operations */ + long ru_oublock; /* block output operations */ + long ru_msgsnd; /* messages sent */ + long ru_msgrcv; /* messages received */ + long ru_nsignals; /* signals received */ + long ru_nvcsw; /* voluntary context switches */ + long ru_nivcsw; /* involuntary " */ +}; + +#define RLIM_INFINITY ((long)(~0UL>>1)) + +struct rlimit { + long rlim_cur; + long rlim_max; +}; + +#define PRIO_MIN (-20) +#define PRIO_MAX 20 + +#define PRIO_PROCESS 0 +#define PRIO_PGRP 1 +#define PRIO_USER 2 + +#define RLIMIT_CPU 0 /* CPU time in ms */ +#define RLIMIT_FSIZE 1 /* Maximum filesize */ +#define RLIMIT_DATA 2 /* max data size */ +#define RLIMIT_STACK 3 /* max stack size */ +#define RLIMIT_CORE 4 /* max core file size */ +#define RLIMIT_RSS 5 /* max resident set size */ +#define RLIMIT_NPROC 6 /* max number of processes */ +#define RLIMIT_NOFILE 7 /* max number of open files */ +#define RLIMIT_MEMLOCK 8 /* max locked-in-memory address space */ + +#define RLIM_NLIMITS 9 + +extern int getrlimit __P ((int __resource, + struct rlimit *__rlp)); +extern int setrlimit __P ((int __resource, + __const struct rlimit *__rlp)); + +extern int getpriority __P((int __which, int __who)); +extern int setpriority __P((int __which, int __who, + int __prio)); + +extern int __getrusage __P ((int __who, struct rusage *__rusage)); +extern int getrusage __P ((int __who, struct rusage *__rusage)); + +#endif /* _SYS_RESOURCE_H */ diff --git a/include/sys/signal.h b/include/sys/signal.h new file mode 100644 index 000000000..2e602dad8 --- /dev/null +++ b/include/sys/signal.h @@ -0,0 +1 @@ +#include <signal.h> diff --git a/include/sys/socket.h b/include/sys/socket.h new file mode 100644 index 000000000..5dcef2d1b --- /dev/null +++ b/include/sys/socket.h @@ -0,0 +1,135 @@ +#ifndef _SYS_SOCKET_H +#define _SYS_SOCKET_H + +#include <features.h> +#include <sys/types.h> +#include <linux/socket.h> + +#ifdef _MIT_POSIX_THREADS +#include <pthread/mit/posix.h> +#endif + +__BEGIN_DECLS + +/* struct msghdr is not defined in linux 1.2. This will allow sendmsg + and recvmsg in libc 5.2.9 to compile under 1.2.x and shouldn't cause + any problem for 1.3.x */ +struct msghdr; + +/* Create a new socket of type TYPE in domain DOMAIN, using + protocol PROTOCOL. If PROTOCOL is zero, one is chosen + automatically. Returns a file descriptor for the new socket, + or -1 for errors. */ +int socket __P ((int __family, int __type, int __protocol)); + +/* Create two new sockets, of type TYPE in domain DOMAIN and using + protocol PROTOCOL, which are connected to each other, and put file + descriptors for them in FDS[0] and FDS[1]. If PROTOCOL is zero, + one will be chosen automatically. Returns 0 on success, -1 + for errors. */ +int socketpair __P ((int __family, int __type, int __protocol, + int __sockvec[2])); + +/* Give the socket FD the local address ADDR (which is LEN bytes + long). */ +int bind __P ((int __sockfd, __const struct sockaddr *__my_addr, + int __addrlen)); + +/* Open a connection on socket FD to peer at ADDR (which LEN bytes + long). For connectionless socket types, just set the default + address to send to and the only address from which to accept + transmissions. Return 0 on success, -1 for errors. */ +int connect __P ((int __sockfd, __const struct sockaddr *__serv_addr, + int __addrlen)); + +/* Prepare to accept connections on socket FD. + N connection requests will be queued before further requests are + refused. Returns 0 on success, -1 for errors. */ +int listen __P ((int __sockfd, int __n)); + +/* Await a connection on socket FD. + When a connection arrives, open a new socket to communicate with it, + set *ADDR (which is *ADDR_LEN bytes long) to the address of the + connecting peer and *ADDR_LEN to the address's actual length, and + return the new socket's descriptor, or -1 for errors. */ +int accept __P ((int __sockfd, __const struct sockaddr *__peer, + int *__paddrlen)); + +/* Put the current value for socket FD's option OPTNAME at protocol + level LEVEL into OPTVAL (which is *OPTLEN bytes long), and set + *OPTLEN to the value's actual length. Returns 0 on success, -1 for + errors. */ +int getsockopt __P ((int __s, int __level, int __optname, + void *__optval, int *__optlen)); + +/* Set socket FD's option OPTNAME at protocol level LEVEL + to *OPTVAL (which is OPTLEN bytes long). + Returns 0 on success, -1 for errors. */ +int setsockopt __P ((int __s, int __level, int __optname, + __const void *__optval, int optlen)); + +/* Put the local address of FD into *ADDR and its length in *LEN. */ +int getsockname __P ((int __sockfd, struct sockaddr *__addr, + int *__paddrlen)); + +/* Put the address of the peer connected to socket FD into *ADDR + (which is *LEN bytes long), and its actual length into *LEN. */ +int getpeername __P ((int __sockfd, struct sockaddr *__peer, + int *__paddrlen)); + +/* Send N bytes of BUF to socket FD. Returns the number sent or -1. */ +int send __P ((int __sockfd, __const void *__buff, size_t __len, + unsigned int __flags)); + +/* Read N bytes into BUF from socket FD. + Returns the number read or -1 for errors. */ +int recv __P ((int __sockfd, void *__buff, size_t __len, + unsigned int __flags)); + +/* Send N bytes of BUF on socket FD to peer at address ADDR (which is + ADDR_LEN bytes long). Returns the number sent, or -1 for errors. */ +int sendto __P ((int __sockfd, __const void *__buff, size_t __len, + unsigned int __flags, __const struct sockaddr *__to, + int __tolen)); + +/* Read N bytes into BUF through socket FD. + If ADDR is not NULL, fill in *ADDR_LEN bytes of it with tha address + of the sender, and store the actual size of the address in + *ADDR_LEN. Returns the number of bytes read or -1 for errors. */ +int recvfrom __P ((int __sockfd, void *__buff, size_t __len, + unsigned int __flags, struct sockaddr *__from, + int *__fromlen)); + +/* Send a message described MESSAGE on socket FD. + Returns the number of bytes sent, or -1 for errors. */ +extern int sendmsg __P ((int __fd, __const struct msghdr *__message, + unsigned int __flags)); + +/* Receive a message as described by MESSAGE from socket FD. + Returns the number of bytes read or -1 for errors. */ +extern int recvmsg __P ((int __fd, struct msghdr *__message, + unsigned int __flags)); + +/* Shut down all or part of the connection open on socket FD. + HOW determines what to shut down: + 0 = No more receptions; + 1 = No more transmissions; + 2 = No more receptions or transmissions. + Returns 0 on success, -1 for errors. */ +int shutdown __P ((int __sockfd, int __how)); + + +/* belongs here or elsewhere? */ +int rcmd __P ((char **__ahost, unsigned short __inport, + __const char *__locuser, __const char *__remuser, + __const char *__cmd, int *__fd2p)); +int rresvport __P ((int *__port)); +int ruserok __P ((__const char *__rhost, int __superuser, + __const char *__ruser, __const char *__luser)); +int rexec __P ((char **__ahost, int __inport, __const char *__user, + __const char *__passwd, __const char *__cmd, + int *__fd2p)); + +__END_DECLS + +#endif /* _SYS_SOCKET_H */ diff --git a/include/sys/socketcall.h b/include/sys/socketcall.h new file mode 100644 index 000000000..52e958395 --- /dev/null +++ b/include/sys/socketcall.h @@ -0,0 +1,22 @@ +#ifndef _SYS_SOCKETCALL_H +#define _SYS_SOCKETCALL_H + +#define SYS_SOCKET 1 +#define SYS_BIND 2 +#define SYS_CONNECT 3 +#define SYS_LISTEN 4 +#define SYS_ACCEPT 5 +#define SYS_GETSOCKNAME 6 +#define SYS_GETPEERNAME 7 +#define SYS_SOCKETPAIR 8 +#define SYS_SEND 9 +#define SYS_RECV 10 +#define SYS_SENDTO 11 +#define SYS_RECVFROM 12 +#define SYS_SHUTDOWN 13 +#define SYS_SETSOCKOPT 14 +#define SYS_GETSOCKOPT 15 +#define SYS_SENDMSG 16 +#define SYS_RECVMSG 17 + +#endif _SYS_SOCKETCALL_H diff --git a/include/sys/socketio.h b/include/sys/socketio.h new file mode 100644 index 000000000..332bcf0dc --- /dev/null +++ b/include/sys/socketio.h @@ -0,0 +1 @@ +#include <linux/sockios.h> diff --git a/include/sys/socketvar.h b/include/sys/socketvar.h new file mode 100644 index 000000000..283356534 --- /dev/null +++ b/include/sys/socketvar.h @@ -0,0 +1,8 @@ +/* + * This seems the best way to handle this. sys/socket.h already has + * all the right bits in it. In fact there isn't a single useful thing + * in the BSD net-2 sys/socketvar.h anyway but people persist in including + * it... + * Alan + */ +#include <sys/socket.h> diff --git a/include/sys/stat.h b/include/sys/stat.h new file mode 100644 index 000000000..e486d755c --- /dev/null +++ b/include/sys/stat.h @@ -0,0 +1,192 @@ +#ifndef _SYS_STAT_H +#define _SYS_STAT_H + +#include <features.h> +#include <sys/types.h> +#undef __NOT_KERNEL +#define __NOT_KERNEL +#include <linux/stat.h> +#undef __NOT_KERNEL + +#ifdef __SVR4_I386_ABI_L1__ +#include <sys/time.h> /* For timestruc_t */ +#endif /* __SVR4_I386_ABI_L1__ */ + +__BEGIN_DECLS + +struct stat { + dev_t st_dev; + +#ifdef __SVR4_I386_ABI_L1__ + long st_pad1[3]; +#else + unsigned short __pad1; +#endif + + ino_t st_ino; + umode_t st_mode; + nlink_t st_nlink; + uid_t st_uid; + gid_t st_gid; + dev_t st_rdev; + +#ifdef __SVR4_I386_ABI_L1__ + long st_pad2[2]; +#else + unsigned short __pad2; +#endif + + off_t st_size; + +#ifdef __SVR4_I386_ABI_L1__ + timestruc_t st_atim; + timestruc_t st_mtim; + timestruc_t st_ctim; + long st_blksize; + long st_blocks; + +#define FSTYPSZ 16 + + char st_fstype[FSTYPSZ]; + long st_pad4[8]; + +#define st_atime st_atim.tv_sec +#define st_mtime st_mtim.tv_sec +#define st_ctime st_ctim.tv_sec + +#else /*! __SVR4_I386_ABI_L1__*/ + unsigned long st_blksize; + unsigned long st_blocks; + time_t st_atime; + unsigned long __unused1; + time_t st_mtime; + unsigned long __unused2; + time_t st_ctime; + unsigned long __unused3; + unsigned long __unused4; + unsigned long __unused5; +#endif /*! __SVR4_I386_ABI_L1__*/ +}; + + +#define LINUX_MKNOD_VERSION 1 /* SVr4 */ +#define LINUX_STAT_VERSION 1 /* SVr4 */ + +extern int _fxstat __P ((int __ver, int __fildes, + struct stat *__stat_buf)); + +extern int _xstat __P ((int __ver, __const char *__filename, + struct stat *__stat_buf)); + +extern int _lxstat __P ((int __ver, __const char *__filename, + struct stat *__stat_buf)); + +#ifdef _MIT_POSIX_THREADS +extern int __machdep_sys__fxstat __P ((int __ver, int __fd, + struct stat *__stat_buf)); +#endif + +extern int _xmknod __P ((int __ver, __const char *__path, + mode_t __mode, dev_t *__dev)); + +/* Some synonyms used historically in the kernel and elsewhere */ +#define S_IREAD S_IRUSR /* read permission, owner */ +#define S_IWRITE S_IWUSR /* write permission, owner */ +#define S_IEXEC S_IXUSR /* execute/search permission, owner */ + +extern int __chmod __P ((__const char *__path, mode_t __mode)); +extern int chmod __P ((__const char *__path, mode_t __mode)); + +extern int __fchmod __P ((int __fildes, mode_t __mode)); +extern int fchmod __P ((int __fildes, mode_t __mode)); + +extern int __mkdir __P ((__const char *__path, mode_t __mode)); +extern int mkdir __P ((__const char *__path, mode_t __mode)); + +extern int mkfifo __P ((__const char *__path, mode_t __mode)); + +#if 1 + +extern int __fstat __P ((int __fildes, struct stat *__stat_buf)); +extern int fstat __P ((int __fildes, struct stat *__stat_buf)); + +extern int __stat __P ((__const char *__filename, + struct stat *__stat_buf)); +extern int stat __P ((__const char *__filename, + struct stat *__stat_buf)); + +extern int __lstat __P ((__const char *__filename, + struct stat *__stat_buf)); +extern int lstat __P ((__const char *__filename, + struct stat *__stat_buf)); + +extern int __mknod __P ((__const char *__path, mode_t __mode, + dev_t __dev)); +extern int mknod __P ((__const char *__path, mode_t __mode, + dev_t __dev)); +#endif /* #if 0 */ + +extern mode_t __umask __P ((mode_t __mask)); +extern mode_t umask __P ((mode_t __mask)); + +__END_DECLS + +#if 0 + +static __inline__ int __stat(__const char * __path, struct stat * __statbuf) +{ + return _xstat(LINUX_STAT_VERSION, __path, __statbuf); +} + +static __inline__ int stat(__const char * __path, struct stat * __statbuf) +{ + return _xstat(LINUX_STAT_VERSION, __path, __statbuf); +} + +static __inline__ int __lstat(__const char * __path, struct stat * __statbuf) +{ + return _lxstat(LINUX_STAT_VERSION, __path, __statbuf); +} + +static __inline__ int lstat(__const char * __path, struct stat * __statbuf) +{ + return _lxstat(LINUX_STAT_VERSION, __path, __statbuf); +} + +static __inline__ int __fstat(int __fd, struct stat * __statbuf) +{ + return _fxstat(LINUX_STAT_VERSION, __fd, __statbuf); +} + +static __inline__ int fstat(int __fd, struct stat * __statbuf) +{ + return _fxstat(LINUX_STAT_VERSION, __fd, __statbuf); +} + +static __inline__ int __mknod(__const char * __path, mode_t __mode, dev_t __dev) +{ + return _xmknod(LINUX_MKNOD_VERSION, __path, __mode, &__dev); +} + +static __inline__ int mknod(__const char * __path, mode_t __mode, dev_t __dev) +{ + return _xmknod(LINUX_MKNOD_VERSION, __path, __mode, &__dev); +} + +#ifdef _MIT_POSIX_THREADS + +static __inline__ int __machdep_sys_fstat(int __fd, struct stat * __statbuf) +{ + return __machdep_sys__fxstat(LINUX_STAT_VERSION, __fd, __statbuf); +} + +static __inline__ int machdep_sys_fstat(int __fd, struct stat * __statbuf) +{ + return __machdep_sys__fxstat(LINUX_STAT_VERSION, __fd, __statbuf); +} + +#endif + +#endif + +#endif diff --git a/include/sys/syscall.h b/include/sys/syscall.h new file mode 100644 index 000000000..f4ca99f18 --- /dev/null +++ b/include/sys/syscall.h @@ -0,0 +1,182 @@ +#ifndef _SYS_SYSCALL_H +#define _SYS_SYSCALL_H + +#define SYS_setup 0 /* Used only by init, to get system going. */ +#define SYS_exit 1 +#define SYS_fork 2 +#define SYS_read 3 +#define SYS_write 4 +#define SYS_open 5 +#define SYS_close 6 +#define SYS_waitpid 7 +#define SYS_creat 8 +#define SYS_link 9 +#define SYS_unlink 10 +#define SYS_execve 11 +#define SYS_chdir 12 +#define SYS_time 13 +#define SYS_mknod 14 +#define SYS_prev_mknod 14 +#define SYS_chmod 15 +#define SYS_chown 16 +#define SYS_break 17 +#define SYS_oldstat 18 +#define SYS_lseek 19 +#define SYS_getpid 20 +#define SYS_mount 21 +#define SYS_umount 22 +#define SYS_setuid 23 +#define SYS_getuid 24 +#define SYS_stime 25 +#define SYS_ptrace 26 +#define SYS_alarm 27 +#define SYS_oldfstat 28 +#define SYS_pause 29 +#define SYS_utime 30 +#define SYS_stty 31 +#define SYS_gtty 32 +#define SYS_access 33 +#define SYS_nice 34 +#define SYS_ftime 35 +#define SYS_sync 36 +#define SYS_kill 37 +#define SYS_rename 38 +#define SYS_mkdir 39 +#define SYS_rmdir 40 +#define SYS_dup 41 +#define SYS_pipe 42 +#define SYS_times 43 +#define SYS_prof 44 +#define SYS_brk 45 +#define SYS_setgid 46 +#define SYS_getgid 47 +#define SYS_signal 48 +#define SYS_geteuid 49 +#define SYS_getegid 50 +#define SYS_acct 51 +#define SYS_phys 52 +#define SYS_lock 53 +#define SYS_ioctl 54 +#define SYS_fcntl 55 +#define SYS_mpx 56 +#define SYS_setpgid 57 +#define SYS_ulimit 58 +#define SYS_oldolduname 59 +#define SYS_umask 60 +#define SYS_chroot 61 +#define SYS_prev_ustat 62 +#define SYS_dup2 63 +#define SYS_getppid 64 +#define SYS_getpgrp 65 +#define SYS_setsid 66 +#define SYS_sigaction 67 +#define SYS_siggetmask 68 +#define SYS_sigsetmask 69 +#define SYS_setreuid 70 +#define SYS_setregid 71 +#define SYS_sigsuspend 72 +#define SYS_sigpending 73 +#define SYS_sethostname 74 +#define SYS_setrlimit 75 +#define SYS_getrlimit 76 +#define SYS_getrusage 77 +#define SYS_gettimeofday 78 +#define SYS_settimeofday 79 +#define SYS_getgroups 80 +#define SYS_setgroups 81 +#define SYS_select 82 +#define SYS_symlink 83 +#define SYS_oldlstat 84 +#define SYS_readlink 85 +#define SYS_uselib 86 +#define SYS_swapon 87 +#define SYS_reboot 88 +#define SYS_readdir 89 +#define SYS_mmap 90 +#define SYS_munmap 91 +#define SYS_truncate 92 +#define SYS_ftruncate 93 +#define SYS_fchmod 94 +#define SYS_fchown 95 +#define SYS_getpriority 96 +#define SYS_setpriority 97 +#define SYS_profil 98 +#define SYS_statfs 99 +#define SYS_fstatfs 100 +#define SYS_ioperm 101 +#define SYS_socketcall 102 +#define SYS_klog 103 +#define SYS_setitimer 104 +#define SYS_getitimer 105 +#define SYS_prev_stat 106 +#define SYS_prev_lstat 107 +#define SYS_prev_fstat 108 +#define SYS_stat 106 +#define SYS_lstat 107 +#define SYS_fstat 108 +#define SYS_olduname 109 +#define SYS_iopl 110 +#define SYS_vhangup 111 +#define SYS_idle 112 +#define SYS_vm86old 113 +#define SYS_wait4 114 +#define SYS_swapoff 115 +#define SYS_sysinfo 116 +#define SYS_ipc 117 +#define SYS_fsync 118 +#define SYS_sigreturn 119 +#define SYS_clone 120 +#define SYS_setdomainname 121 +#define SYS_uname 122 +#define SYS_modify_ldt 123 +#define SYS_adjtimex 124 +#define SYS_mprotect 125 +#define SYS_sigprocmask 126 +#define SYS_create_module 127 +#define SYS_init_module 128 +#define SYS_delete_module 129 +#define SYS_get_kernel_syms 130 +#define SYS_quotactl 131 +#define SYS_getpgid 132 +#define SYS_fchdir 133 +#define SYS_bdflush 134 +#define SYS_sysfs 135 +#define SYS_personality 136 +#define SYS_afs_syscall 137 /* Syscall for Andrew File System */ +#define SYS_setfsuid 138 +#define SYS_setfsgid 139 +#define SYS__llseek 140 +#define SYS_getdents 141 +#define SYS__newselect 142 +#define SYS_flock 143 +#define SYS_syscall_flock SYS_flock +#define SYS_msync 144 +#define SYS_readv 145 +#define SYS_syscall_readv SYS_readv +#define SYS_writev 146 +#define SYS_syscall_writev SYS_writev +#define SYS_getsid 147 +#define SYS_fdatasync 148 +#define SYS__sysctl 149 +#define SYS_mlock 150 +#define SYS_munlock 151 +#define SYS_mlockall 152 +#define SYS_munlockall 153 +#define SYS_sched_setparam 154 +#define SYS_sched_getparam 155 +#define SYS_sched_setscheduler 156 +#define SYS_sched_getscheduler 157 +#define SYS_sched_yield 158 +#define SYS_sched_get_priority_max 159 +#define SYS_sched_get_priority_min 160 +#define SYS_sched_rr_get_interval 161 +#define SYS_nanosleep 162 +#define SYS_mremap 163 +#define SYS_setresuid 164 +#define SYS_getresuid 165 +#define SYS_vm86 166 +#define SYS_query_module 167 +#define SYS_poll 168 +#define SYS_syscall_poll SYS_poll + +#endif /* <sys/syscall.h> */ diff --git a/include/sys/syslog.h b/include/sys/syslog.h new file mode 100644 index 000000000..38d74a03b --- /dev/null +++ b/include/sys/syslog.h @@ -0,0 +1,200 @@ +/* + * Copyright (c) 1982, 1986, 1988 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)syslog.h 7.20 (Berkeley) 2/23/91 + */ + +#ifndef _SYS_LOG_H +#define _SYS_LOG_H + +#include <features.h> + +#define _PATH_LOG "/dev/log" + +/* + * priorities/facilities are encoded into a single 32-bit quantity, where the + * bottom 3 bits are the priority (0-7) and the top 28 bits are the facility + * (0-big number). Both the priorities and the facilities map roughly + * one-to-one to strings in the syslogd(8) source code. This mapping is + * included in this file. + * + * priorities (these are ordered) + */ +#define LOG_EMERG 0 /* system is unusable */ +#define LOG_ALERT 1 /* action must be taken immediately */ +#define LOG_CRIT 2 /* critical conditions */ +#define LOG_ERR 3 /* error conditions */ +#define LOG_WARNING 4 /* warning conditions */ +#define LOG_NOTICE 5 /* normal but significant condition */ +#define LOG_INFO 6 /* informational */ +#define LOG_DEBUG 7 /* debug-level messages */ + +#define LOG_PRIMASK 0x07 /* mask to extract priority part (internal) */ + /* extract priority */ +#define LOG_PRI(p) ((p) & LOG_PRIMASK) +#define LOG_MAKEPRI(fac, pri) (((fac) << 3) | (pri)) + +#ifdef SYSLOG_NAMES +#define INTERNAL_NOPRI 0x10 /* the "no priority" priority */ + /* mark "facility" */ +#define INTERNAL_MARK LOG_MAKEPRI(LOG_NFACILITIES, 0) +typedef struct _code { + char *c_name; + int c_val; +} CODE; + +CODE prioritynames[] = { + { "alert", LOG_ALERT }, + { "crit", LOG_CRIT }, + { "debug", LOG_DEBUG }, + { "emerg", LOG_EMERG }, + { "err", LOG_ERR }, + { "error", LOG_ERR }, /* DEPRECATED */ + { "info", LOG_INFO }, + { "none", INTERNAL_NOPRI }, /* INTERNAL */ + { "notice", LOG_NOTICE }, + { "panic", LOG_EMERG }, /* DEPRECATED */ + { "warn", LOG_WARNING }, /* DEPRECATED */ + { "warning", LOG_WARNING }, + { NULL, -1 } +}; +#endif + +/* facility codes */ +#define LOG_KERN (0<<3) /* kernel messages */ +#define LOG_USER (1<<3) /* random user-level messages */ +#define LOG_MAIL (2<<3) /* mail system */ +#define LOG_DAEMON (3<<3) /* system daemons */ +#define LOG_AUTH (4<<3) /* security/authorization messages */ +#define LOG_SYSLOG (5<<3) /* messages generated internally by syslogd */ +#define LOG_LPR (6<<3) /* line printer subsystem */ +#define LOG_NEWS (7<<3) /* network news subsystem */ +#define LOG_UUCP (8<<3) /* UUCP subsystem */ +#define LOG_CRON (9<<3) /* clock daemon */ +#define LOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */ + + /* other codes through 15 reserved for system use */ +#define LOG_LOCAL0 (16<<3) /* reserved for local use */ +#define LOG_LOCAL1 (17<<3) /* reserved for local use */ +#define LOG_LOCAL2 (18<<3) /* reserved for local use */ +#define LOG_LOCAL3 (19<<3) /* reserved for local use */ +#define LOG_LOCAL4 (20<<3) /* reserved for local use */ +#define LOG_LOCAL5 (21<<3) /* reserved for local use */ +#define LOG_LOCAL6 (22<<3) /* reserved for local use */ +#define LOG_LOCAL7 (23<<3) /* reserved for local use */ + +#define LOG_NFACILITIES 24 /* current number of facilities */ +#define LOG_FACMASK 0x03f8 /* mask to extract facility part */ + /* facility of pri */ +#define LOG_FAC(p) (((p) & LOG_FACMASK) >> 3) + +#ifdef SYSLOG_NAMES +CODE facilitynames[] = { + { "auth", LOG_AUTH }, + { "authpriv", LOG_AUTHPRIV }, + { "cron", LOG_CRON }, + { "daemon", LOG_DAEMON }, + { "kern", LOG_KERN }, + { "lpr", LOG_LPR }, + { "mail", LOG_MAIL }, + { "mark", INTERNAL_MARK }, /* INTERNAL */ + { "news", LOG_NEWS }, + { "security", LOG_AUTH }, /* DEPRECATED */ + { "syslog", LOG_SYSLOG }, + { "user", LOG_USER }, + { "uucp", LOG_UUCP }, + { "local0", LOG_LOCAL0 }, + { "local1", LOG_LOCAL1 }, + { "local2", LOG_LOCAL2 }, + { "local3", LOG_LOCAL3 }, + { "local4", LOG_LOCAL4 }, + { "local5", LOG_LOCAL5 }, + { "local6", LOG_LOCAL6 }, + { "local7", LOG_LOCAL7 }, + { NULL, -1 } +}; +#endif + +#ifdef KERNEL +#define LOG_PRINTF -1 /* pseudo-priority to indicate use of printf */ +#endif + +/* + * arguments to setlogmask. + */ +#define LOG_MASK(pri) (1 << (pri)) /* mask for one priority */ +#define LOG_UPTO(pri) ((1 << ((pri)+1)) - 1) /* all priorities through pri */ + +/* + * Option flags for openlog. + * + * LOG_ODELAY no longer does anything. + * LOG_NDELAY is the inverse of what it used to be. + */ +#define LOG_PID 0x01 /* log the pid with each message */ +#define LOG_CONS 0x02 /* log on the console if errors in sending */ +#define LOG_ODELAY 0x04 /* delay open until first syslog() (default) */ +#define LOG_NDELAY 0x08 /* don't delay open */ +#define LOG_NOWAIT 0x10 /* don't wait for console forks: DEPRECATED */ +#define LOG_PERROR 0x20 /* log to stderr as well */ + +#ifndef KERNEL + +#include <sys/cdefs.h> + +__BEGIN_DECLS + +#ifdef __GNUC__ +/* This define avoids name pollution if we're using GNU stdarg.h */ +#define __need___va_list +#include <stdarg.h> +#endif + +void closelog __P((void)); +void openlog __P((__const char *, int, int)); +int setlogmask __P((int)); +void syslog __P((int, __const char *, ...)) +#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 5) + __attribute__ ((format (printf, 2, 0))) +#endif + ; +#ifdef __GNUC_VA_LIST +void vsyslog __P((int, __const char *, __gnuc_va_list)); +#else +void vsyslog __P(()); +#endif + +__END_DECLS + +#endif /* !KERNEL */ + +#endif /* _SYS_LOG_H */ diff --git a/include/sys/termios.h b/include/sys/termios.h new file mode 100644 index 000000000..3e18805ab --- /dev/null +++ b/include/sys/termios.h @@ -0,0 +1,4 @@ +#ifndef _SYS_TERMIOS_H +#define _SYS_TERMIOS_H +#include <termios.h> +#endif diff --git a/include/sys/time.h b/include/sys/time.h new file mode 100644 index 000000000..98e51c07c --- /dev/null +++ b/include/sys/time.h @@ -0,0 +1,81 @@ +#ifndef _SYS_TIME_H +#define _SYS_TIME_H + +#include <features.h> +#include <linux/types.h> +#include <linux/time.h> + +#define DST_NONE 0 /* not on dst */ +#define DST_USA 1 /* USA style dst */ +#define DST_AUST 2 /* Australian style dst */ +#define DST_WET 3 /* Western European dst */ +#define DST_MET 4 /* Middle European dst */ +#define DST_EET 5 /* Eastern European dst */ +#define DST_CAN 6 /* Canada */ +#define DST_GB 7 /* Great Britain and Eire */ +#define DST_RUM 8 /* Rumania */ +#define DST_TUR 9 /* Turkey */ +#define DST_AUSTALT 10 /* Australian style with shift in 1986 */ + +#ifdef __SVR4_I386_ABI_L1__ +typedef struct timestruc { + time_t tv_sec; + long tv_nsec; +} timestruc_t; +#endif /* __SVR4_I386_ABI_L1__ */ + +/* + * Operations on timevals. + * + * NB: timercmp does not work for >= or <=. + * + */ +#define timerisset(tvp) ((tvp)->tv_sec || (tvp)->tv_usec) +#define timercmp(tvp, uvp, cmp) \ + (((tvp)->tv_sec == (uvp)->tv_sec && (tvp)->tv_usec cmp (uvp)->tv_usec) \ + || (tvp)->tv_sec cmp (uvp)->tv_sec) +#define timerclear(tvp) ((tvp)->tv_sec = (tvp)->tv_usec = 0) + +#include <time.h> +#include <sys/types.h> + +__BEGIN_DECLS + +extern int __gettimeofday __P ((struct timeval * __tp, + struct timezone * __tz)); +extern int gettimeofday __P ((struct timeval * __tp, + struct timezone * __tz)); +extern int __settimeofday __P ((__const struct timeval *__tv, + __const struct timezone *__tz)); +extern int settimeofday __P ((__const struct timeval *__tv, + __const struct timezone *__tz)); + +extern int __select __P ((int __width, fd_set * __readfds, + fd_set * __writefds, fd_set * __exceptfds, + struct timeval * __timeout)); +extern int select __P ((int __width, fd_set * __readfds, + fd_set * __writefds, fd_set * __exceptfds, + struct timeval * __timeout)); + +extern int __getitimer __P ((int __which, + struct itimerval *__value)); +extern int getitimer __P ((int __which, + struct itimerval *__value)); +extern int __setitimer __P ((int __which, + __const struct itimerval *__value, + struct itimerval *__ovalue)); +extern int setitimer __P ((int __which, + __const struct itimerval *__value, + struct itimerval *__ovalue)); + +extern int __adjtime __P ((struct timeval * __itv, + struct timeval * __otv)); +extern int adjtime __P ((struct timeval * __itv, + struct timeval * __otv)); + +extern int __utimes __P((char *__path, struct timeval *tvp)); +extern int utimes __P((char *__path, struct timeval *tvp)); + +__END_DECLS + +#endif /*_SYS_TIME_H*/ diff --git a/include/sys/times.h b/include/sys/times.h new file mode 100644 index 000000000..b6defa877 --- /dev/null +++ b/include/sys/times.h @@ -0,0 +1,21 @@ +#ifndef _SYS_TIMES_H +#define _SYS_TIMES_H + +#include <features.h> +#include <sys/types.h> +#include <time.h> + +struct tms { + clock_t tms_utime; + clock_t tms_stime; + clock_t tms_cutime; + clock_t tms_cstime; +}; + +__BEGIN_DECLS + +extern clock_t times __P ((struct tms * __tp)); + +__END_DECLS + +#endif diff --git a/include/sys/types.h b/include/sys/types.h new file mode 100644 index 000000000..4a5cdfab6 --- /dev/null +++ b/include/sys/types.h @@ -0,0 +1,4 @@ +#include <stddef.h> +#include <sys/bitypes.h> +#include <linux/types.h> +#include <gnu/types.h> diff --git a/include/sys/uio.h b/include/sys/uio.h new file mode 100644 index 000000000..87120e6ff --- /dev/null +++ b/include/sys/uio.h @@ -0,0 +1,65 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#ifndef _SYS_UIO_H + +#define _SYS_UIO_H 1 +#include <features.h> + +__BEGIN_DECLS + +#define __need_size_t +#include <stddef.h> + +/* That is a klude for Linux. */ +#ifdef __linux__ +#include <linux/socket.h> +#endif + +#ifndef __LINUX_UIO_H + +/* Structure describing a section of memory. */ + +struct iovec +{ + /* Starting address. */ + __ptr_t iov_base; + /* Length in bytes. */ + size_t iov_len; +}; + +#endif + +/* Read data from file descriptor FD, and put the result in the + buffers described by VECTOR, which is a vector of COUNT `struct iovec's. + The buffers are filled in the order specified. + Operates just like `read' (see <unistd.h>) except that data are + put in VECTOR instead of a contiguous buffer. */ +int readv __P ((int __fd, __const struct iovec * __vector, size_t __count)); + +/* Write data pointed by the buffers described by VECTOR, which + is a vector of COUNT `struct iovec's, to file descriptor FD. + The data is written in the order specified. + Operates just like `write' (see <unistd.h>) except that the data + are taken from VECTOR instead of a contiguous buffer. */ +int writev __P ((int __fd, __const struct iovec * __vector, size_t __count)); + + +__END_DECLS + +#endif /* sys/uio.h */ diff --git a/include/sys/un.h b/include/sys/un.h new file mode 100644 index 000000000..efb674cc3 --- /dev/null +++ b/include/sys/un.h @@ -0,0 +1 @@ +#include <linux/un.h> diff --git a/include/sys/utsname.h b/include/sys/utsname.h new file mode 100644 index 000000000..0cbc37f2a --- /dev/null +++ b/include/sys/utsname.h @@ -0,0 +1,18 @@ +#ifndef __SYS_UTSNAME_H +#define __SYS_UTSNAME_H + +#include <features.h> +#include <sys/param.h> + +struct utsname { + char sysname[65]; + char nodename[65]; + char release[65]; + char version[65]; + char machine[65]; + char domainname[65]; +}; + +extern int uname __P ((struct utsname * __utsbuf)); + +#endif diff --git a/include/sys/vfs.h b/include/sys/vfs.h new file mode 100644 index 000000000..1018591b9 --- /dev/null +++ b/include/sys/vfs.h @@ -0,0 +1,17 @@ +#ifndef _SYS_VFS_H +#define _SYS_VFS_H + +#include <features.h> +#include <linux/vfs.h> + +__BEGIN_DECLS + +extern int __statfs __P ((__const char *__path, struct statfs *__buf)); +extern int statfs __P ((__const char *__path, struct statfs *__buf)); + +extern int __fstatfs __P ((int __fildes, struct statfs *__buf)); +extern int fstatfs __P ((int __fildes, struct statfs *__buf)); + +__END_DECLS + +#endif /*_SYS_VFS_H */ diff --git a/include/sys/vm86.h b/include/sys/vm86.h new file mode 100644 index 000000000..851814e13 --- /dev/null +++ b/include/sys/vm86.h @@ -0,0 +1,125 @@ +#if !__AS386_16__ + +#ifndef _SYS_VM86_H +#define _SYS_VM86_H + +#include <features.h> +#ifndef _LINUX_VM86_H +#define _LINUX_VM86_H + +/* + * I'm guessing at the VIF/VIP flag usage, but hope that this is how + * the Pentium uses them. Linux will return from vm86 mode when both + * VIF and VIP is set. + * + * On a Pentium, we could probably optimize the virtual flags directly + * in the eflags register instead of doing it "by hand" in vflags... + * + * Linus + */ + +#define TF_MASK 0x00000100 +#define IF_MASK 0x00000200 +#define IOPL_MASK 0x00003000 +#define NT_MASK 0x00004000 +#define VM_MASK 0x00020000 +#define AC_MASK 0x00040000 +#define VIF_MASK 0x00080000 /* virtual interrupt flag */ +#define VIP_MASK 0x00100000 /* virtual interrupt pending */ +#define ID_MASK 0x00200000 + +#define BIOSSEG 0x0f000 + +#define CPU_086 0 +#define CPU_186 1 +#define CPU_286 2 +#define CPU_386 3 +#define CPU_486 4 +#define CPU_586 5 + +/* + * Return values for the 'vm86()' system call + */ +#define VM86_TYPE(retval) ((retval) & 0xff) +#define VM86_ARG(retval) ((retval) >> 8) + +#define VM86_SIGNAL 0 /* return due to signal */ +#define VM86_UNKNOWN 1 /* unhandled GP fault - IO-instruction or similar */ +#define VM86_INTx 2 /* int3/int x instruction (ARG = x) */ +#define VM86_STI 3 /* sti/popf/iret instruction enabled virtual interrupts */ + +/* + * This is the stack-layout when we have done a "SAVE_ALL" from vm86 + * mode - the main change is that the old segment descriptors aren't + * useful any more and are forced to be zero by the kernel (and the + * hardware when a trap occurs), and the real segment descriptors are + * at the end of the structure. Look at ptrace.h to see the "normal" + * setup. + */ + +struct vm86_regs { +/* + * normal regs, with special meaning for the segment descriptors.. + */ + long ebx; + long ecx; + long edx; + long esi; + long edi; + long ebp; + long eax; + long __null_ds; + long __null_es; + long __null_fs; + long __null_gs; + long orig_eax; + long eip; + unsigned short cs, __csh; + long eflags; + long esp; + unsigned short ss, __ssh; +/* + * these are specific to v86 mode: + */ + unsigned short es, __esh; + unsigned short ds, __dsh; + unsigned short fs, __fsh; + unsigned short gs, __gsh; +}; + +struct revectored_struct { + unsigned long __map[8]; /* 256 bits */ +}; + +struct vm86_struct { + struct vm86_regs regs; + unsigned long flags; + unsigned long screen_bitmap; + unsigned long cpu_type; + struct revectored_struct int_revectored; + struct revectored_struct int21_revectored; +}; + +/* + * flags masks + */ +#define VM86_SCREEN_BITMAP 0x0001 + +#ifdef __KERNEL__ + +void handle_vm86_fault(struct vm86_regs *, long); +void handle_vm86_debug(struct vm86_regs *, long); + +#endif + +#endif + +__BEGIN_DECLS + +extern vm86(struct vm86_struct * __info); + +__END_DECLS + +#endif /*_SYS_VM86_H */ + +#endif diff --git a/include/sys/wait.h b/include/sys/wait.h new file mode 100644 index 000000000..95f1b2eab --- /dev/null +++ b/include/sys/wait.h @@ -0,0 +1,146 @@ +/* Copyright (C) 1991, 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * POSIX Standard: 3.2.1 Wait for Process Termination <sys/wait.h> + */ + +#ifndef _SYS_WAIT_H + +#define _SYS_WAIT_H 1 +#include <features.h> + +__BEGIN_DECLS + +#include <gnu/types.h> + +/* This will define the `W*' macros for the flag + bits to `waitpid', `wait3', and `wait4'. */ +#include <waitflags.h> + +#ifdef __USE_BSD + +/* Lots of hair to allow traditional BSD use of `union wait' + as well as POSIX.1 use of `int' for the status word. */ + +#ifdef __GNUC__ +#define __WAIT_INT(status) \ + (__extension__ ({ union { __typeof(status) __in; int __i; } __u; \ + __u.__in = (status); __u.__i; })) +#else +#define __WAIT_INT(status) (*(int *) &(status)) +#endif + +/* This is the type of the argument to `wait'. With GCC 2.6.1 and later, + the funky union causes redeclarations with either `int *' or `union wait + *' to be allowed without complaint. __WAIT_STATUS_DEFN is the type used + in the actual function definitions. */ + +/* g++ in gcc 2.6.1 doesn't work. Maybe 2.7.x. H.J. */ +#if !defined (__GNUC__) || defined (__cplusplus) || \ + __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || \ + (defined(_MIT_POSIX_THREADS) && _MIT_POSIX_THREADS > 0) +#define __WAIT_STATUS __ptr_t +#define __WAIT_STATUS_DEFN __ptr_t +#else +/* This works in GCC 2.6.1 and later. */ +typedef union + { + union wait *__uptr; + int *__iptr; + } __WAIT_STATUS __attribute__ ((transparent_union)); +#define __WAIT_STATUS_DEFN int * +#endif + +#else /* Don't use BSD. */ + +#define __WAIT_INT(status) (status) +#define __WAIT_STATUS int * + +#endif /* Use BSD. */ + +/* This will define all the `__W*' macros. */ +#include <waitstatus.h> + +#define WEXITSTATUS(status) __WEXITSTATUS(__WAIT_INT(status)) +#define WTERMSIG(status) __WTERMSIG(__WAIT_INT(status)) +#define WSTOPSIG(status) __WSTOPSIG(__WAIT_INT(status)) +#define WIFEXITED(status) __WIFEXITED(__WAIT_INT(status)) +#define WIFSIGNALED(status) __WIFSIGNALED(__WAIT_INT(status)) +#define WIFSTOPPED(status) __WIFSTOPPED(__WAIT_INT(status)) + +#ifdef __USE_BSD +#define WCOREDUMP(status) __WCOREDUMP(__WAIT_INT(status)) +#define W_EXITCODE(ret, sig) __W_EXITCODE(ret, sig) +#define W_STOPCODE(sig) __W_STOPCODE(sig) +#endif + + +/* Wait for a child to die. When one does, put its status in *STAT_LOC + and return its process ID. For errors, return (pid_t) -1. */ +extern __pid_t __wait __P ((__WAIT_STATUS __stat_loc)); +extern __pid_t wait __P ((__WAIT_STATUS __stat_loc)); + +#ifdef __USE_BSD +/* Special values for the PID argument to `waitpid' and `wait4'. */ +#define WAIT_ANY (-1) /* Any process. */ +#define WAIT_MYPGRP 0 /* Any process in my process group. */ +#endif + +/* Wait for a child matching PID to die. + If PID is greater than 0, match any process whose process ID is PID. + If PID is (pid_t) -1, match any process. + If PID is (pid_t) 0, match any process with the + same process group as the current process. + If PID is less than -1, match any process whose + process group is the absolute value of PID. + If the WNOHANG bit is set in OPTIONS, and that child + is not already dead, return (pid_t) 0. If successful, + return PID and store the dead child's status in STAT_LOC. + Return (pid_t) -1 for errors. If the WUNTRACED bit is + set in OPTIONS, return status for stopped children; otherwise don't. */ +extern __pid_t __waitpid __P ((__pid_t __pid, int *__stat_loc, + int __options)); +extern __pid_t waitpid __P ((__pid_t __pid, int *__stat_loc, + int __options)); +#ifdef __USE_BSD +/* This being here makes the prototypes valid whether or not + we have already included <sys/resource.h> to define `struct rusage'. */ +struct rusage; + +/* Wait for a child to exit. When one does, put its status in *STAT_LOC and + return its process ID. For errors return (pid_t) -1. If USAGE is not + nil, store information about the child's resource usage there. If the + WUNTRACED bit is set in OPTIONS, return status for stopped children; + otherwise don't. */ +extern __pid_t __wait3 __P ((__WAIT_STATUS __stat_loc, + int __options, struct rusage * __usage)); +extern __pid_t wait3 __P ((__WAIT_STATUS __stat_loc, + int __options, struct rusage * __usage)); + +/* PID is like waitpid. Other args are like wait3. */ +extern __pid_t __wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc, + int __options, struct rusage *__usage)); +extern __pid_t wait4 __P ((__pid_t __pid, __WAIT_STATUS __stat_loc, + int __options, struct rusage *__usage)); +#endif /* Use BSD. */ + + +__END_DECLS + +#endif /* sys/wait.h */ diff --git a/include/syscall.h b/include/syscall.h new file mode 100644 index 000000000..fa08654a3 --- /dev/null +++ b/include/syscall.h @@ -0,0 +1,6 @@ +#include <errno.h> + +#define __check_errno(__res) ((__res) >= 0) + +#include <m68k/syscall.h> +#include <sys/syscall.h> diff --git a/include/syslog.h b/include/syslog.h new file mode 100644 index 000000000..830b4928a --- /dev/null +++ b/include/syslog.h @@ -0,0 +1 @@ +#include <sys/syslog.h> diff --git a/include/termcap.h b/include/termcap.h new file mode 100644 index 000000000..a7ae37b72 --- /dev/null +++ b/include/termcap.h @@ -0,0 +1,21 @@ + +#ifndef _TERMCAP_H +#define _TERMCAP_H + +#include <features.h> +#include <sys/types.h> + +extern char PC; +extern char *UP; +extern char *BC; +extern int ospeed; + +extern int tgetent __P((char *, const char *)); +extern int tgetflag __P((const char *)); +extern int tgetnum __P((const char *)); +extern char *tgetstr __P((const char *, char **)); + +extern int tputs __P((const char *, int, int (*)(int))); +extern char *tgoto __P((const char *, int, int)); + +#endif /* _TERMCAP_H */ diff --git a/include/termio.h b/include/termio.h new file mode 100644 index 000000000..9e2695652 --- /dev/null +++ b/include/termio.h @@ -0,0 +1 @@ +#include <termios.h> diff --git a/include/termios.h b/include/termios.h new file mode 100644 index 000000000..8dcb5bc5e --- /dev/null +++ b/include/termios.h @@ -0,0 +1,32 @@ +#ifndef __TERMIOS_H +#define __TERMIOS_H + +#include <features.h> +#include <sys/types.h> +#include <linux/termios.h> + +extern speed_t cfgetispeed __P ((struct termios *__termios_p)); +extern speed_t cfgetospeed __P ((struct termios *__termios_p)); +extern int cfsetispeed __P ((struct termios *__termios_p, speed_t __speed)); +extern int cfsetospeed __P ((struct termios *__termios_p, speed_t __speed)); + +extern int tcspeed_to_number __P ((speed_t __speed)); +extern speed_t tcspeed_from_number __P ((int number)); + +extern int cfgetispeedn __P ((struct termios *__termios_p)); +extern int cfgetospeedn __P ((struct termios *__termios_p)); +extern int cfsetispeedn __P ((struct termios *__termios_p, int __speed)); +extern int cfsetospeedn __P ((struct termios *__termios_p, int __speed)); + +extern void cfmakeraw __P ((struct termios *__t)); + +extern int tcsetattr __P ((int __fd, int __opt, struct termios *__termios_p)); +extern int tcgetattr __P ((int __fildes, struct termios *__termios_p)); +extern int tcdrain __P ((int __fildes)); +extern int tcflow __P ((int __fildes, int __action)); +extern int tcflush __P ((int __fildes, int __queue_selector)); +extern int tcsendbreak __P ((int __fildes, int __duration)); +extern pid_t tcgetpgrp __P ((int __fildes)); +extern int tcsetpgrp __P ((int __fildes, pid_t __pgrp_id)); + +#endif diff --git a/include/time.h b/include/time.h new file mode 100644 index 000000000..9bbcd8be0 --- /dev/null +++ b/include/time.h @@ -0,0 +1,128 @@ +/* Copyright (C) 1991, 1992, 1993, 1994 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the, 1992 Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +/* + * ANSI Standard: 4.12 DATE and TIME <time.h> + */ + +#ifndef _TIME_H +#define _TIME_H + +#include <features.h> +#include <sys/time.h> + +#ifndef _TIME_T +#define _TIME_T +typedef long time_t; +#endif + +#ifndef _CLOCK_T +#define _CLOCK_T +typedef long clock_t; +#endif + +#ifndef _SIZE_T +#define _SIZE_T +typedef unsigned int size_t; +#endif + +#ifndef NULL +#ifdef __cplusplus +#define NULL 0 +#else +#define NULL ((void *) 0) +#endif +#endif + +#define CLOCKS_PER_SEC 100 +#define CLK_TCK 100 /* That must be the same as HZ ???? */ + +struct tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + /* Those are for future use. */ + long int __tm_gmtoff__; + __const char *__tm_zone__; +}; + +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) + +extern char *tzname[2]; +extern int daylight; +extern long int timezone; + +__BEGIN_DECLS + +extern int stime __P ((time_t* __tptr)); + +extern clock_t clock __P ((void)); +extern time_t time __P ((time_t * __tp)); +extern __CONSTVALUE double difftime __P ((time_t __time2, + time_t __time1)) __CONSTVALUE2; +extern time_t mktime __P ((struct tm * __tp)); + +extern char * asctime __P ((__const struct tm * __tp)); +extern char * ctime __P ((__const time_t * __tp)); +extern size_t strftime __P ((char * __s, size_t __smax, + __const char * __fmt, __const struct tm * __tp)); +extern char * strptime __P ((__const char * __s, __const char * __fmt, + struct tm * __tm)); + +extern void tzset __P ((void)); + +extern struct tm* gmtime __P ((__const time_t *__tp)); +extern struct tm* localtime __P ((__const time_t * __tp)); + +#ifdef __USE_MISC +/* Miscellaneous functions many Unices inherited from the public domain + localtime package. These are included only for compatibility. */ + +/* Like `mktime', but for TP represents Universal Time, not local time. */ +extern time_t timegm __P ((struct tm *__tp)); + +/* Another name for `mktime'. */ +extern time_t timelocal __P ((struct tm *__tp)); + +#endif + +#if defined(_POSIX_THREAD_SAFE_FUNCTIONS) || defined(_REENTRANT) + +extern char * asctime_r __P((__const struct tm *, char *)); +extern char * ctime_r __P((__const time_t *, char *)); +extern struct tm* gmtime_r __P((__const time_t *, struct tm *)); +extern struct tm* localtime_r __P((__const time_t *, struct tm *)); + +#endif + +struct timespec; + +/* IEEE Std 1003.1b-1993. */ +extern int nanosleep __P((__const struct timespec *__rqtp, + struct timespec *__rmtp)); + +__END_DECLS + +#endif diff --git a/include/unistd.h b/include/unistd.h new file mode 100644 index 000000000..6c39b42c5 --- /dev/null +++ b/include/unistd.h @@ -0,0 +1,108 @@ +/* unistd.h <ndf@linux.mit.edu> */ +#include <features.h> +#include <sys/types.h> + +#ifndef __UNISTD_H +#define __UNISTD_H + +#include <errno.h> +#include <asm/unistd.h> + +#define STDIN_FILENO 0 +#define STDOUT_FILENO 1 +#define STDERR_FILENO 2 + + + +extern int close __P ((int)); +extern size_t read __P ((int __fd, char * __buf, size_t __nbytes)); +extern size_t write __P ((int __fd, __const char * __buf, size_t __n)); +extern off_t lseek __P ((int __fd, off_t __n, int __whence)); +extern int pipe __P ((int __pipedes[2])); +extern unsigned int alarm __P ((unsigned int __seconds)); +extern int sleep __P ((unsigned int __seconds)); +extern void usleep __P ((unsigned long __microseconds)); +extern int pause __P ((void)); +extern char* crypt __P((__const char *__key, __const char *__salt)); +extern int isatty __P ((int __fd)); +extern int readlink __P ((__const char *__path, char *__buf, size_t __len)); +extern int link __P ((__const char *__from, __const char *__to)); +extern int symlink __P ((__const char *__from, __const char *__to)); +extern int readlink __P ((__const char *__path, char *__buf, size_t __len)); +extern int unlink __P ((__const char *__name)); +extern char *getcwd __P ((char *__buf, size_t __size)); +extern int fchdir __P ((int __fd)); +extern int chdir __P ((__const char *__path)); +extern int chown __P ((__const char *__file, + uid_t __owner, gid_t __group)); + +extern int fchown __P ((int __fd, + uid_t __owner, gid_t __group)); + +extern int fsync __P ((int __fd)); + +extern int sync __P ((void)); + +extern int rmdir __P ((__const char *__path)); + +extern int rename __P((__const char* _old, __const char* _new)); + +extern int access __P ((__const char *__name, int __type)); + +extern int reboot __P ((int __magic, int __magic_too, int __flag)); + +extern int mkstemp __P ((char * __template)); +extern char * mktemp __P ((char * __template)); + +extern int _clone __P ((int (*fn)(void *arg), void *child_stack, int flags, void *arg)); + + +#if 0 +#ifndef SYS_fork +#define SYS_fork 2 +#endif + +#define vfork() ({ \ +register long __res __asm__ ("%d0"); \ +__asm__ __volatile__ ("trap #0" \ + : "=g" (__res) \ + : "0" (SYS_fork) \ + : "%d0"); \ +__res; \ +}) +#endif + +#define vfork() ({ \ +register unsigned long __res __asm__ ("%d0") = __NR_fork; \ +__asm__ __volatile__ ("trap #0" \ + : "=g" (__res) \ + : "0" (__res) \ + : "%d0"); \ +if (__res >= (unsigned long)-4096) { \ + errno = -__res; \ + __res = (pid_t)-1; \ +} \ +(pid_t)__res; \ +}) + + +#define fork fork_not_available_use_vfork +#define clone clone_not_available_use__clone + + +#ifndef SEEK_SET +#define SEEK_SET 0 +#define SEEK_CUR 1 +#define SEEK_END 2 +#endif + +#ifndef R_OK +#define R_OK 4 /* Test for read permission. */ +#define W_OK 2 /* Test for write permission. */ +#define X_OK 1 /* Test for execute permission. */ +#define F_OK 0 /* Test for existence. */ +#endif + +#endif /* __UNISTD_H */ + + diff --git a/include/utime.h b/include/utime.h new file mode 100644 index 000000000..7f82b9fa6 --- /dev/null +++ b/include/utime.h @@ -0,0 +1,15 @@ +#ifndef __UTIME_H +#define __UTIME_H + +#include <features.h> +#include <sys/types.h> + +struct utimbuf { + time_t actime; + time_t modtime; +}; + +extern int utime __P ((char *__filename, struct utimbuf *__utimebuf)); + +#endif + diff --git a/include/utmp.h b/include/utmp.h new file mode 100644 index 000000000..9fe0e873b --- /dev/null +++ b/include/utmp.h @@ -0,0 +1,52 @@ +/* utmp.h */ + +#ifndef __UTMP_H +#define __UTMP_H + +#include <features.h> +#include <sys/types.h> +#include <paths.h> +#include <time.h> + +#define UT_UNKNOWN 0 +#define UT_LINESIZE 12 +#define UT_NAMESIZE 8 +#define UT_HOSTSIZE 16 + +#define RUN_LVL 1 +#define BOOT_TIME 2 +#define NEW_TIME 3 +#define OLD_TIME 4 + +#define INIT_PROCESS 5 +#define LOGIN_PROCESS 6 +#define USER_PROCESS 7 +#define DEAD_PROCESS 8 + +struct utmp +{ + short ut_type; /* type of login */ + pid_t ut_pid; /* pid of login-process */ + char ut_line[UT_LINESIZE]; /* devicename of tty -"/dev/", null-term */ + char ut_id[2]; /* abbrev. ttyname, as 01, s1 etc. */ + time_t ut_time; /* login time */ + char ut_user[UT_NAMESIZE]; /* username, not null-term */ + char ut_host[UT_HOSTSIZE]; /* hostname for remote login... */ + long ut_addr; /* IP addr of remote host */ + +}; + +extern void setutent __P ((void)); +extern void utmpname __P ((__const char *)); +extern struct utmp * getutent __P ((void)); +extern struct utmp * getutid __P ((struct utmp *)); +extern struct utmp * getutline __P ((struct utmp *)); +extern struct utmp * pututline __P ((struct utmp *)); +extern void endutent __P ((void)); + +#ifdef __LIBC__ +struct utmp * __getutent __P ((int)); +#endif + +#endif /* __UTMP_H */ + diff --git a/include/wait.h b/include/wait.h new file mode 100644 index 000000000..cdb77149f --- /dev/null +++ b/include/wait.h @@ -0,0 +1,3 @@ +/* SVR4 ABI requires <wait.h> rather than <sys/wait.h> */ + +#include <sys/wait.h> diff --git a/libc/inet/Makefile b/libc/inet/Makefile new file mode 100644 index 000000000..28565cecd --- /dev/null +++ b/libc/inet/Makefile @@ -0,0 +1,43 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# Copyright (C) 1998-1999 D. Jeff Dionne <jeff@rt-control.com> +# Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com> +# Copyright (C) 1999 D. Jeff Dionne <jeff@rt-control.com> +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -fno-builtin -I../include + +ASRC=addr.c +AOBJ=inet_aton.o inet_addr.o inet_ntoa.o + +RSRC=resolv.c +ROBJ= encodeh.o decodeh.o encoded.o decoded.o lengthd.o encodeq.o \ +decodeq.o lengthq.o encodea.o decodea.o encodep.o decodep.o \ +formquery.o dnslookup.o resolveaddress.o resolvemailbox.o \ +opennameservers.o closenameservers.o resolvename.o gethostbyname.o\ +gethostbyaddr.o + +OBJ=$(AOBJ) $(ROBJ) + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(AOBJ)): $(ASRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)($(ROBJ)): $(RSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +clean: + rm -f *.o libc.a diff --git a/libc/inet/addr.c b/libc/inet/addr.c new file mode 100644 index 000000000..bb27753bf --- /dev/null +++ b/libc/inet/addr.c @@ -0,0 +1,85 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> +#include <ctype.h> +#include <netinet/in.h> + + +#ifdef L_inet_aton +int +inet_aton(cp, inp) +const char *cp; +struct in_addr *inp; +{ + unsigned long addr; + int value; + int part; + + if (!inp) + return 0; + + addr = 0; + for (part=1;part<=4;part++) { + + if (!isdigit(*cp)) + return 0; + + value = 0; + while (isdigit(*cp)) { + value *= 10; + value += *cp++ - '0'; + if (value > 255) + return 0; + } + + if (*cp++ != ((part == 4) ? '\0' : '.')) + return 0; + + addr <<= 8; + addr |= value; + } + + inp->s_addr = htonl(addr); + + return 1; +} +#endif + +#ifdef L_inet_addr +unsigned long +inet_addr(cp) +const char *cp; +{ + struct in_addr a; + if (!inet_aton(cp, &a)) + return -1; + else + return a.s_addr; +} +#endif + +#ifdef L_inet_ntoa + +extern char * itoa(int); + +char * +inet_ntoa(in) +struct in_addr in; +{ + static char buf[18]; + unsigned long addr = ntohl(in.s_addr); + + strcpy(buf, itoa((addr >> 24) & 0xff)); + strcat(buf, "."); + strcat(buf, itoa((addr >> 16) & 0xff)); + strcat(buf, "."); + strcat(buf, itoa((addr >> 8) & 0xff)); + strcat(buf, "."); + strcat(buf, itoa(addr & 0xff)); + + return buf; +} +#endif diff --git a/libc/inet/resolv.c b/libc/inet/resolv.c new file mode 100644 index 000000000..b4cfab104 --- /dev/null +++ b/libc/inet/resolv.c @@ -0,0 +1,892 @@ +/* resolv.c: DNS Resolver + * + * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>, + * The Silver Hammer Group, Ltd. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + */ + +#include <string.h> +#include <stdio.h> +#include <signal.h> +#include <sys/socket.h> +#include <sys/types.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include <stdlib.h> +#include <unistd.h> +#include <cfgfile.h> +#include <resolv.h> + +#define DNS_SERVICE 53 +#define MAX_RECURSE 5 +#define REPLY_TIMEOUT 10 +#define MAX_RETRIES 15 + +#undef DEBUG +#ifdef DEBUG +#define DPRINTF(X,args...) printf(X,args...) +#else +#define DPRINTF(X,args...) +#endif /* DEBUG */ + +#ifdef L_encodeh +int encode_header(struct resolv_header * h, unsigned char * dest, int maxlen) +{ + if (maxlen < 12) + return -1; + + dest[0] = (h->id & 0xff00) >> 8; + dest[1] = (h->id & 0x00ff) >> 0; + dest[2] = (h->qr ? 0x80 : 0) | + ((h->opcode & 0x0f) << 3) | + (h->aa ? 0x04 : 0) | + (h->tc ? 0x02 : 0) | + (h->rd ? 0x01 : 0); + dest[3] = (h->ra ? 0x80 : 0) | + (h->rcode & 0x0f); + dest[4] = (h->qdcount & 0xff00) >> 8; + dest[5] = (h->qdcount & 0x00ff) >> 0; + dest[6] = (h->ancount & 0xff00) >> 8; + dest[7] = (h->ancount & 0x00ff) >> 0; + dest[8] = (h->nscount & 0xff00) >> 8; + dest[9] = (h->nscount & 0x00ff) >> 0; + dest[10] = (h->arcount & 0xff00) >> 8; + dest[11] = (h->arcount & 0x00ff) >> 0; + + return 12; +} +#endif + +#ifdef L_decodeh +int decode_header(unsigned char * data, struct resolv_header * h) +{ + h->id = (data[0] << 8) | data[1]; + h->qr = (data[2] & 0x80) ? 1 : 0; + h->opcode = (data[2] >> 3) & 0x0f; + h->aa = (data[2] & 0x04) ? 1 : 0; + h->tc = (data[2] & 0x02) ? 1 : 0; + h->rd = (data[2] & 0x01) ? 1 : 0; + h->ra = (data[3] & 0x80) ? 1 : 0; + h->rcode = data[3] & 0x0f; + h->qdcount = (data[4] << 8) | data[5]; + h->ancount = (data[6] << 8) | data[7]; + h->nscount = (data[8] << 8) | data[9]; + h->arcount = (data[10] << 8) | data[11]; + + return 12; +} +#endif + +#ifdef L_encoded +/* Encode a dotted string into nameserver transport-level encoding. + This routine is fairly dumb, and doesn't attempt to compress + the data */ + +int encode_dotted(const char * dotted, unsigned char * dest, int maxlen) +{ + int used=0; + + while(dotted && *dotted) { + char * c = strchr(dotted, '.'); + int l = c ? c - dotted : strlen(dotted); + + if (l >= (maxlen-used-1)) + return -1; + + dest[used++] = l; + memcpy(dest+used, dotted, l); + used += l; + + if (c) + dotted = c+1; + else + break; + } + + if (maxlen < 1) + return -1; + + dest[used++] = 0; + + return used; +} +#endif + +#ifdef L_decoded +/* Decode a dotted string from nameserver transport-level encoding. + This routine understands compressed data. */ + +int decode_dotted(const unsigned char * data, int offset, + char * dest, int maxlen) +{ + int l; + int measure=1; + int total = 0; + int used=0; + + if (!data) + return -1; + + while ((measure && total++), (l=data[offset++])) { + + if ((l & 0xc0) == (0xc0)) { + if (measure) + total++; + /* compressed item, redirect */ + offset = ((l & 0x3f) << 8) | data[offset]; + measure = 0; + continue; + } + + if ((used+l+1) >= maxlen) + return -1; + + memcpy(dest+used, data+offset, l); + offset += l; + used += l; + if (measure) + total += l; + + if (data[offset] != 0) + dest[used++] = '.'; + else + dest[used++] = '\0'; + } + + DPRINTF("Total decode len = %d\n", total); + + return total; +} +#endif + +#ifdef L_lengthd + +int length_dotted(const unsigned char * data, int offset) +{ + int orig_offset = offset; + int l; + + if (!data) + return -1; + + while ((l=data[offset++])) { + + if ((l & 0xc0) == (0xc0)) { + offset++; + break; + } + + offset += l; + } + + return offset-orig_offset; +} +#endif + +#ifdef L_encodeq +int encode_question(struct resolv_question * q, + unsigned char * dest, int maxlen) +{ + int i; + + i = encode_dotted(q->dotted, dest, maxlen); + if (i < 0) + return i; + + dest += i; + maxlen -= i; + + if (maxlen < 4) + return -1; + + dest[0] = (q->qtype & 0xff00) >> 8; + dest[1] = (q->qtype & 0x00ff) >> 0; + dest[2] = (q->qclass & 0xff00) >> 8; + dest[3] = (q->qclass & 0x00ff) >> 0; + + return i+4; +} +#endif + +#ifdef L_decodeq +int decode_question(unsigned char * message, int offset, + struct resolv_question * q) +{ + char temp[256]; + int i; + + i = decode_dotted(message, offset, temp, 256); + if (i < 0) + return i; + + offset += i; + + q->dotted = strdup(temp); + q->qtype = (message[offset+0] << 8) | message[offset+1]; + q->qclass = (message[offset+2] << 8) | message[offset+3]; + + return i+4; +} +#endif + +#ifdef L_lengthq +int length_question(unsigned char * message, int offset) +{ + int i; + + i = length_dotted(message, offset); + if (i < 0) + return i; + + return i+4; +} +#endif + +#ifdef L_encodea +int encode_answer(struct resolv_answer * a, + unsigned char * dest, int maxlen) +{ + int i; + + i = encode_dotted(a->dotted, dest, maxlen); + if (i < 0) + return i; + + dest += i; + maxlen -= i; + + if (maxlen < (10+a->rdlength)) + return -1; + + *dest++ = (a->atype & 0xff00) >> 8; + *dest++ = (a->atype & 0x00ff) >> 0; + *dest++ = (a->aclass & 0xff00) >> 8; + *dest++ = (a->aclass & 0x00ff) >> 0; + *dest++ = (a->ttl & 0xff000000) >> 24; + *dest++ = (a->ttl & 0x00ff0000) >> 16; + *dest++ = (a->ttl & 0x0000ff00) >> 8; + *dest++ = (a->ttl & 0x000000ff) >> 0; + *dest++ = (a->rdlength & 0xff00) >> 8; + *dest++ = (a->rdlength & 0x00ff) >> 0; + memcpy(dest, a->rdata, a->rdlength); + + return i+10+a->rdlength; +} +#endif + +#ifdef L_decodea +int decode_answer(unsigned char * message, int offset, + struct resolv_answer * a) +{ + char temp[256]; + int i; + + i = decode_dotted(message, offset, temp, 256); + if (i < 0) + return i; + + message += offset+i; + + a->dotted = strdup(temp); + a->atype = (message[0] << 8) | message[1]; message += 2; + a->aclass = (message[0] << 8) | message[1]; message += 2; + a->ttl = (message[0] << 24) | + (message[1] << 16) | + (message[2] << 8) | + (message[3] << 0); + message += 4; + a->rdlength = (message[0] << 8) | message[1]; message += 2; + a->rdata = message; + a->rdoffset = offset+i+10; + + DPRINTF("i=%d,rdlength=%d\n", i, a->rdlength); + + return i+10+a->rdlength; +} +#endif + +#ifdef L_encodep +int encode_packet(struct resolv_header * h, + struct resolv_question ** q, + struct resolv_question ** an, + struct resolv_question ** ns, + struct resolv_question ** ar, + unsigned char * dest, int maxlen) +{ + int i, total=0; + int j; + + i = encode_header(h, dest, maxlen); + if (i < 0) + return i; + + dest += i; + maxlen -= i; + total += i; + + for(j=0;j<h->qdcount;j++) { + i = encode_question(q[j], dest, maxlen); + if (i < 0) + return i; + dest += i; + maxlen -= i; + total += i; + } + + for(j=0;j<h->ancount;j++) { + i = encode_answer(an[j], dest, maxlen); + if (i < 0) + return i; + dest += i; + maxlen -= i; + total += i; + } + for(j=0;j<h->nscount;j++) { + i = encode_answer(ns[j], dest, maxlen); + if (i < 0) + return i; + dest += i; + maxlen -= i; + total += i; + } + for(j=0;j<h->arcount;j++) { + i = encode_answer(ar[j], dest, maxlen); + if (i < 0) + return i; + dest += i; + maxlen -= i; + total += i; + } + + return total; +} +#endif + +#ifdef L_decodep +int decode_packet(unsigned char * data, struct resolv_header * h) +{ + return decode_header(data, h); +} +#endif + +#ifdef L_formquery +int form_query(int id, const char * name, int type, unsigned char * packet, int maxlen) +{ + struct resolv_header h; + struct resolv_question q; + int i,j; + + memset(&h, 0, sizeof(h)); + h.id = id; + h.qdcount = 1; + + q.dotted = (char*)name; + q.qtype = type; + q.qclass = 1 /*CLASS_IN*/; + + i = encode_header(&h, packet, maxlen); + if (i < 0) + return i; + + j = encode_question(&q, packet+i, maxlen-i); + if (j < 0) + return j; + + return i+j; +} +#endif + +#ifdef L_dnslookup + +int dns_caught_signal = 0; +void dns_catch_signal(int signo) { + dns_caught_signal = 1; +} + +int dns_lookup(const char * name, int type, int nscount, const char ** nsip, + unsigned char ** outpacket, struct resolv_answer * a) +{ + static int id=1; + int i,j,len; + int fd; + int pos; + static int ns = 0; + struct sockaddr_in sa; + int oldalarm; + __sighandler_t oldhandler; + struct resolv_header h; + struct resolv_question q; + int retries = 0; + unsigned char * packet = malloc(512); + + if (!packet) + goto fail1; + + DPRINTF("Looking up type %d answer for '%s'\n", type, name); + + + if (!nscount) + goto fail1; + + ns %= nscount; + + fd = -1; + + while (retries++ < MAX_RETRIES) { + + if (fd != -1) + close(fd); + + fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + + if (fd==-1) + goto fail2; + + + memset(packet, 0, 512); + + memset(&h, 0, sizeof(h)); + h.id = ++id; + h.qdcount = 1; + h.rd = 1; + + DPRINTF("encoding header\n"); + + i = encode_header(&h, packet, 512); + if (i < 0) + goto fail3; + + q.dotted = (char*)name; + q.qtype = type; + q.qclass = 1 /*CLASS_IN*/; + + j = encode_question(&q, packet+i, 512-i); + if (j < 0) + goto fail3; + + len = i+j; + + DPRINTF("On try %d, sending query to port %d of machine %s\n", + retries, DNS_SERVICE, nsip[ns]); + + sa.sin_family = AF_INET; + sa.sin_port = htons(DNS_SERVICE); + sa.sin_addr.s_addr = inet_addr(nsip[ns]); + + if (connect(fd, (struct sockaddr*)&sa, sizeof(sa))==-1) { + if (errno == ENETUNREACH) { + /* routing error, presume not transient */ + goto tryall; + } else + /* retry */ + break; + } + + DPRINTF("Transmitting packet of length %d, id=%d, qr=%d\n", + len, h.id, h.qr); + + send(fd, packet, len, 0); + + dns_caught_signal = 0; + oldalarm = alarm(REPLY_TIMEOUT); + oldhandler = signal(SIGALRM, dns_catch_signal); + + i = recv(fd, packet, 512, 0); + + alarm(0); + signal(SIGALRM, oldhandler); + alarm(oldalarm); + + DPRINTF("Timeout=%d, len=%d\n", + dns_caught_signal, i); + + if (dns_caught_signal) + /* timed out, so retry send and receive, + to next nameserver on queue */ + goto again; + + if (i < 12) + /* too short ! */ + goto again; + + decode_header(packet, &h); + + DPRINTF("id = %d, qr = %d\n", + h.id, h.qr); + + if ((h.id != id) || (!h.qr)) + /* unsolicited */ + goto again; + + DPRINTF("Got response (i think)!\n"); + DPRINTF("qrcount=%d,ancount=%d,nscount=%d,arcount=%d\n", + h.qdcount, h.ancount, h.nscount, h.arcount); + DPRINTF("opcode=%d,aa=%d,tc=%d,rd=%d,ra=%d,rcode=%d\n", + h.opcode,h.aa,h.tc,h.rd,h.ra,h.rcode); + + if ((h.rcode) || (h.ancount < 1)) { + /* negative result, not present */ + goto tryall; + } + + pos = 12; + + for(j=0;j<h.qdcount;j++) { + DPRINTF("Skipping question %d at %d\n", j, pos); + i = length_question(packet, pos); + DPRINTF("Length of question %d is %d\n", j, i); + if (i < 0) + goto again; + pos += i; + } + DPRINTF("Decoding answer at pos %d\n", pos); + + i = decode_answer(packet, pos, a); + + if (i<0) { + DPRINTF("failed decode %d\n", i); + goto again; + } + + DPRINTF("Answer name = |%s|\n", a->dotted); + DPRINTF("Answer type = |%d|\n", a->atype); + + close(fd); + + if (outpacket) + *outpacket = packet; + else + free(packet); + return (0); /* success! */ + + tryall: + /* if there are other nameservers, give them a go, + otherwise return with error */ + if (retries >= nscount) + break; + again: + ns = (ns + 1) % nscount; + continue; + } + + + +fail3: + close(fd); +fail2: + free(packet); +fail1: + return -1; +} +#endif + +#ifdef L_resolveaddress + +int resolve_address(const char * address, + int nscount, const char ** nsip, + struct in_addr * in) +{ + unsigned char * packet; + struct resolv_answer a; + char temp[256]; + int i; + int nest=0; + + if (!address || !in) + return -1; + + strcpy(temp, address); + + for(;;) { + + i = dns_lookup(temp, 1, nscount, nsip, &packet, &a); + + if (i<0) + return -1; + + free(a.dotted); + + if (a.atype == 5) { /* CNAME*/ + i = decode_dotted(packet, a.rdoffset, temp, 256); + free(packet); + + if (i <0) + return -1; + if (++nest > MAX_RECURSE) + return -1; + continue; + } else if (a.atype == 1) { /* ADDRESS */ + free(packet); + break; + } else { + free(packet); + return -1; + } + } + + if (in) + memcpy(in, a.rdata, 4); + + return 0; +} +#endif + +#ifdef L_resolvemailbox + +int resolve_mailbox(const char * address, + int nscount, const char ** nsip, + struct in_addr * in) +{ + struct resolv_answer a; + unsigned char * packet; + char temp[256]; + int nest=0; + int i; + + if (!address || !in) + return -1; + + /* look up mail exchange */ + i = dns_lookup(address, 15, nscount, nsip, &packet, &a); + + strcpy(temp, address); + + if (i>=0) { + i = decode_dotted(packet, a.rdoffset+2, temp, 256); + free(packet); + } + + for(;;) { + + i = dns_lookup(temp, 1, nscount, nsip, &packet, &a); + + if (i<0) + return -1; + + free(a.dotted); + + if (a.atype == 5) { /* CNAME*/ + i = decode_dotted(packet, a.rdoffset, temp, 256); + free(packet); + if (i<0) + return i; + if (++nest > MAX_RECURSE) + return -1; + continue; + } else if (a.atype == 1) { /* ADDRESS */ + free(packet); + break; + } else { + free(packet); + return -1; + } + } + + if (in) + memcpy(in, a.rdata, 4); + + return 0; +} +#endif + +extern int nameservers; +extern const char * nameserver[3]; + +#ifdef L_opennameservers + +int nameservers; +const char * nameserver[3]; + +int open_nameservers() +{ + FILE *fp; + char **arg; + int i; + + if (fp = fopen("/etc/resolv.conf", "r")) { + if (arg = cfgfind(fp, "nameserver")) { + for (i=1; arg[i]; i++) { + nameserver[nameservers++] = strdup(arg[i]); + } + } + fclose(fp); + } + return 0; +} +#endif + +#ifdef L_closenameservers +void close_nameservers(void) { + + while(nameservers>0) + free(nameserver[--nameservers]); +} +#endif + + +#ifdef L_resolvename + +char * resolve_name(const char * name, int mailbox) +{ + struct in_addr in; + int i; + + /* shortcut: is it a valid IP address to begin with? */ + if (inet_aton(name, &in)) + return name; + + open_nameservers(); + + DPRINTF("looking up '%s', mailbox=%d, nameservers=%d\n", + name, mailbox, nameservers); + + if (mailbox) + i = resolve_mailbox(name, nameservers, nameserver, &in); + else + i = resolve_address(name, nameservers, nameserver, &in); + + if (i<0) + return 0; + + DPRINTF("success = '%s'\n", inet_ntoa(in)); + + return inet_ntoa(in); +} +#endif + +#ifdef L_gethostbyname + +struct hostent * gethostbyname(const char * name) +{ + static struct hostent h; + static char namebuf[256]; + static struct in_addr in; + static struct in_addr *addr_list[2]; + unsigned char * packet; + struct resolv_answer a; + int i; + int nest=0; + + open_nameservers(); + + if (!name) + return 0; + + memset(&h, 0, sizeof(h)); + + addr_list[0] = ∈ + addr_list[1] = 0; + + strcpy(namebuf, name); + + for(;;) { + + i = dns_lookup(namebuf, 1, nameservers, nameserver, &packet, &a); + + if (i<0) + return 0; + + strcpy(namebuf, a.dotted); + free(a.dotted); + + + if (a.atype == 5) { /* CNAME*/ + i = decode_dotted(packet, a.rdoffset, namebuf, 256); + free(packet); + + if (i <0) + return 0; + if (++nest > MAX_RECURSE) + return 0; + continue; + } else if (a.atype == 1) { /* ADDRESS */ + memcpy(&in, a.rdata, sizeof(in)); + h.h_name = namebuf; + h.h_addrtype = AF_INET; + h.h_length = sizeof(in); + h.h_addr_list = (char**)addr_list; + free(packet); + break; + } else { + free(packet); + return 0; + } + } + + return &h; +} +#endif + +#ifdef L_gethostbyaddr + +struct hostent * gethostbyaddr(const char * addr, int len, int type) +{ + static struct hostent h; + static char namebuf[256]; + static struct in_addr in; + static struct in_addr *addr_list[2]; + unsigned char * packet; + struct resolv_answer a; + int i; + int nest=0; + + if (!addr || (len != sizeof(in)) || (type != AF_INET)) + return 0; + + memcpy(&in.s_addr, addr, len); + + open_nameservers(); + + memset(&h, 0, sizeof(h)); + + addr_list[0] = ∈ + addr_list[1] = 0; + + sprintf(namebuf, "%d.%d.%d.%d.in-addr.arpa", + (in.s_addr >> 24) & 0xff, + (in.s_addr >> 16) & 0xff, + (in.s_addr >> 8) & 0xff, + (in.s_addr >> 0) & 0xff + ); + + for(;;) { + + i = dns_lookup(namebuf, 12, nameservers, nameserver, &packet, &a); + + if (i<0) + return 0; + + strcpy(namebuf, a.dotted); + free(a.dotted); + + if (a.atype == 5) { /* CNAME*/ + i = decode_dotted(packet, a.rdoffset, namebuf, 256); + free(packet); + + if (i <0) + return 0; + if (++nest > MAX_RECURSE) + return 0; + continue; + } else if (a.atype == 12) { /* ADDRESS */ + i = decode_dotted(packet, a.rdoffset, namebuf, 256); + free(packet); + + h.h_name = namebuf; + h.h_addrtype = AF_INET; + h.h_length = sizeof(in); + h.h_addr_list = (char**)addr_list; + break; + } else { + free(packet); + return 0; + } + } + + return &h; +} +#endif diff --git a/libc/inet/rpc/Makefile b/libc/inet/rpc/Makefile new file mode 100644 index 000000000..388434165 --- /dev/null +++ b/libc/inet/rpc/Makefile @@ -0,0 +1,27 @@ +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CFLAGS= -O2 -fomit-frame-pointer -Dlinux -I../include + +OBJS = auth_none.o auth_unix.o authunix_prot.o \ + bindresvport.o clnt_generic.o clnt_perror.o \ + clnt_raw.o clnt_simple.o clnt_tcp.o clnt_udp.o \ + get_myaddress.o getrpcent.o getrpcport.o pmap_clnt.o \ + pmap_getmaps.o pmap_getport.o pmap_prot.o pmap_prot2.o \ + pmap_rmt.o rpc_callmsg.o rpc_commondata.o \ + rpc_dtablesize.o rpc_prot.o svc.o svc_auth.o \ + svc_auth_unix.o svc_raw.o svc_run.o svc_simple.o \ + svc_tcp.o svc_udp.o xdr.o xdr_array.o xdr_float.o \ + xdr_mem.o xdr_rec.o xdr_reference.o xdr_stdio.o + +LIBC = ../libc.a + +all: $(LIBC) + +$(LIBC): $(LIBC)($(OBJS)) + +clean: + rm -f *.[oa] *~ core + + diff --git a/libc/inet/rpc/auth_none.c b/libc/inet/rpc/auth_none.c new file mode 100644 index 000000000..630037fb4 --- /dev/null +++ b/libc/inet/rpc/auth_none.c @@ -0,0 +1,133 @@ +/* @(#)auth_none.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)auth_none.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * auth_none.c + * Creates a client authentication handle for passing "null" + * credentials and verifiers to remote systems. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#define MAX_MARSHEL_SIZE 20 + +/* + * Authenticator operations routines + */ +static void authnone_verf(); +static void authnone_destroy(); +static bool_t authnone_marshal(); +static bool_t authnone_validate(); +static bool_t authnone_refresh(); + +static struct auth_ops ops = { + authnone_verf, + authnone_marshal, + authnone_validate, + authnone_refresh, + authnone_destroy +}; + +static struct authnone_private { + AUTH no_client; + char marshalled_client[MAX_MARSHEL_SIZE]; + u_int mcnt; +} *authnone_private; + +AUTH * +authnone_create() +{ + register struct authnone_private *ap = authnone_private; + XDR xdr_stream; + register XDR *xdrs; + + if (ap == 0) { + ap = (struct authnone_private *)calloc(1, sizeof (*ap)); + if (ap == 0) + return (0); + authnone_private = ap; + } + if (!ap->mcnt) { + ap->no_client.ah_cred = ap->no_client.ah_verf = _null_auth; + ap->no_client.ah_ops = &ops; + xdrs = &xdr_stream; + xdrmem_create(xdrs, ap->marshalled_client, (u_int)MAX_MARSHEL_SIZE, + XDR_ENCODE); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_cred); + (void)xdr_opaque_auth(xdrs, &ap->no_client.ah_verf); + ap->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + } + return (&ap->no_client); +} + +/*ARGSUSED*/ +static bool_t +authnone_marshal(client, xdrs) + AUTH *client; + XDR *xdrs; +{ + register struct authnone_private *ap = authnone_private; + + if (ap == 0) + return (0); + return ((*xdrs->x_ops->x_putbytes)(xdrs, + ap->marshalled_client, ap->mcnt)); +} + +static void +authnone_verf() +{ +} + +static bool_t +authnone_validate() +{ + + return (TRUE); +} + +static bool_t +authnone_refresh() +{ + + return (FALSE); +} + +static void +authnone_destroy() +{ +} diff --git a/libc/inet/rpc/auth_unix.c b/libc/inet/rpc/auth_unix.c new file mode 100644 index 000000000..87ff2b648 --- /dev/null +++ b/libc/inet/rpc/auth_unix.c @@ -0,0 +1,319 @@ +/* @(#)auth_unix.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)auth_unix.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * auth_unix.c, Implements UNIX style authentication parameters. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * The system is very weak. The client uses no encryption for it's + * credentials and only sends null verifiers. The server sends backs + * null verifiers or optionally a verifier that suggests a new short hand + * for the credentials. + * + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> + +/* + * Unix authenticator operations vector + */ +static void authunix_nextverf(); +static bool_t authunix_marshal(); +static bool_t authunix_validate(); +static bool_t authunix_refresh(); +static void authunix_destroy(); + +static struct auth_ops auth_unix_ops = { + authunix_nextverf, + authunix_marshal, + authunix_validate, + authunix_refresh, + authunix_destroy +}; + +/* + * This struct is pointed to by the ah_private field of an auth_handle. + */ +struct audata { + struct opaque_auth au_origcred; /* original credentials */ + struct opaque_auth au_shcred; /* short hand cred */ + u_long au_shfaults; /* short hand cache faults */ + char au_marshed[MAX_AUTH_BYTES]; + u_int au_mpos; /* xdr pos at end of marshed */ +}; +#define AUTH_PRIVATE(auth) ((struct audata *)auth->ah_private) + +static bool_t marshal_new_auth(); + + +/* + * Create a unix style authenticator. + * Returns an auth handle with the given stuff in it. + */ +AUTH * +authunix_create(machname, uid, gid, len, aup_gids) + char *machname; + int uid; + int gid; + register int len; + int *aup_gids; +{ + struct authunix_parms aup; + char mymem[MAX_AUTH_BYTES]; + struct timeval now; + XDR xdrs; + register AUTH *auth; + register struct audata *au; + + /* + * Allocate and set up auth handle + */ + auth = (AUTH *)mem_alloc(sizeof(*auth)); +#ifndef KERNEL + if (auth == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + au = (struct audata *)mem_alloc(sizeof(*au)); +#ifndef KERNEL + if (au == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + auth->ah_ops = &auth_unix_ops; + auth->ah_private = (caddr_t)au; + auth->ah_verf = au->au_shcred = _null_auth; + au->au_shfaults = 0; + + /* + * fill in param struct from the given params + */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + aup.aup_machname = machname; + aup.aup_uid = uid; + aup.aup_gid = gid; + aup.aup_len = (u_int)len; + aup.aup_gids = aup_gids; + + /* + * Serialize the parameters into origcred + */ + xdrmem_create(&xdrs, mymem, MAX_AUTH_BYTES, XDR_ENCODE); + if (! xdr_authunix_parms(&xdrs, &aup)) + abort(); + au->au_origcred.oa_length = len = XDR_GETPOS(&xdrs); + au->au_origcred.oa_flavor = AUTH_UNIX; +#ifdef KERNEL + au->au_origcred.oa_base = mem_alloc((u_int) len); +#else + if ((au->au_origcred.oa_base = mem_alloc((u_int) len)) == NULL) { + (void)fprintf(stderr, "authunix_create: out of memory\n"); + return (NULL); + } +#endif + bcopy(mymem, au->au_origcred.oa_base, (u_int)len); + + /* + * set auth handle to reflect new cred. + */ + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); + return (auth); +} + +/* + * Returns an auth handle with parameters determined by doing lots of + * syscalls. + */ +AUTH * +authunix_create_default() +{ + register int len; + char machname[MAX_MACHINE_NAME + 1]; + register int uid; + register int gid; + int gids[NGRPS]; + + if (gethostname(machname, MAX_MACHINE_NAME) == -1) + abort(); + machname[MAX_MACHINE_NAME] = 0; + uid = geteuid(); + gid = getegid(); + if ((len = getgroups(NGRPS, gids)) < 0) + abort(); + return (authunix_create(machname, uid, gid, len, gids)); +} + +/* + * authunix operations + */ + +static void +authunix_nextverf(auth) + AUTH *auth; +{ + /* no action necessary */ +} + +static bool_t +authunix_marshal(auth, xdrs) + AUTH *auth; + XDR *xdrs; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + return (XDR_PUTBYTES(xdrs, au->au_marshed, au->au_mpos)); +} + +static bool_t +authunix_validate(auth, verf) + register AUTH *auth; + struct opaque_auth verf; +{ + register struct audata *au; + XDR xdrs; + + if (verf.oa_flavor == AUTH_SHORT) { + au = AUTH_PRIVATE(auth); + xdrmem_create(&xdrs, verf.oa_base, verf.oa_length, XDR_DECODE); + + if (au->au_shcred.oa_base != NULL) { + mem_free(au->au_shcred.oa_base, + au->au_shcred.oa_length); + au->au_shcred.oa_base = NULL; + } + if (xdr_opaque_auth(&xdrs, &au->au_shcred)) { + auth->ah_cred = au->au_shcred; + } else { + xdrs.x_op = XDR_FREE; + (void)xdr_opaque_auth(&xdrs, &au->au_shcred); + au->au_shcred.oa_base = NULL; + auth->ah_cred = au->au_origcred; + } + marshal_new_auth(auth); + } + return (TRUE); +} + +static bool_t +authunix_refresh(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + struct authunix_parms aup; + struct timeval now; + XDR xdrs; + register int stat; + + if (auth->ah_cred.oa_base == au->au_origcred.oa_base) { + /* there is no hope. Punt */ + return (FALSE); + } + au->au_shfaults ++; + + /* first deserialize the creds back into a struct authunix_parms */ + aup.aup_machname = NULL; + aup.aup_gids = (int *)NULL; + xdrmem_create(&xdrs, au->au_origcred.oa_base, + au->au_origcred.oa_length, XDR_DECODE); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + + /* update the time and serialize in place */ + (void)gettimeofday(&now, (struct timezone *)0); + aup.aup_time = now.tv_sec; + xdrs.x_op = XDR_ENCODE; + XDR_SETPOS(&xdrs, 0); + stat = xdr_authunix_parms(&xdrs, &aup); + if (! stat) + goto done; + auth->ah_cred = au->au_origcred; + marshal_new_auth(auth); +done: + /* free the struct authunix_parms created by deserializing */ + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, &aup); + XDR_DESTROY(&xdrs); + return (stat); +} + +static void +authunix_destroy(auth) + register AUTH *auth; +{ + register struct audata *au = AUTH_PRIVATE(auth); + + mem_free(au->au_origcred.oa_base, au->au_origcred.oa_length); + + if (au->au_shcred.oa_base != NULL) + mem_free(au->au_shcred.oa_base, au->au_shcred.oa_length); + + mem_free(auth->ah_private, sizeof(struct audata)); + + if (auth->ah_verf.oa_base != NULL) + mem_free(auth->ah_verf.oa_base, auth->ah_verf.oa_length); + + mem_free((caddr_t)auth, sizeof(*auth)); +} + +/* + * Marshals (pre-serializes) an auth struct. + * sets private data, au_marshed and au_mpos + */ +static bool_t +marshal_new_auth(auth) + register AUTH *auth; +{ + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + register struct audata *au = AUTH_PRIVATE(auth); + + xdrmem_create(xdrs, au->au_marshed, MAX_AUTH_BYTES, XDR_ENCODE); + if ((! xdr_opaque_auth(xdrs, &(auth->ah_cred))) || + (! xdr_opaque_auth(xdrs, &(auth->ah_verf)))) { + perror("auth_none.c - Fatal marshalling problem"); + } else { + au->au_mpos = XDR_GETPOS(xdrs); + } + XDR_DESTROY(xdrs); +} diff --git a/libc/inet/rpc/authunix_prot.c b/libc/inet/rpc/authunix_prot.c new file mode 100644 index 000000000..a60d99a57 --- /dev/null +++ b/libc/inet/rpc/authunix_prot.c @@ -0,0 +1,66 @@ +/* @(#)authunix_prot.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)authunix_prot.c 1.15 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * authunix_prot.c + * XDR for UNIX style authentication parameters for RPC + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/auth.h> +#include <rpc/auth_unix.h> + +/* + * XDR for unix authentication parameters. + */ +bool_t +xdr_authunix_parms(xdrs, p) + register XDR *xdrs; + register struct authunix_parms *p; +{ + + if (xdr_u_long(xdrs, &(p->aup_time)) + && xdr_string(xdrs, &(p->aup_machname), MAX_MACHINE_NAME) + && xdr_int(xdrs, &(p->aup_uid)) + && xdr_int(xdrs, &(p->aup_gid)) + && xdr_array(xdrs, (caddr_t *)&(p->aup_gids), + &(p->aup_len), NGRPS, sizeof(int), xdr_int) ) { + return (TRUE); + } + return (FALSE); +} + diff --git a/libc/inet/rpc/bindresvport.c b/libc/inet/rpc/bindresvport.c new file mode 100644 index 000000000..71803dd41 --- /dev/null +++ b/libc/inet/rpc/bindresvport.c @@ -0,0 +1,78 @@ +static char sccsid[] = "@(#)bindresvport.c 2.2 88/07/29 4.0 RPCSRC 1.8 88/02/08 SMI"; +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1987 by Sun Microsystems, Inc. + */ + +#include <sys/types.h> +#include <sys/errno.h> +#include <sys/socket.h> +#include <netinet/in.h> + +/* + * Bind a socket to a privileged IP port + */ +bindresvport(sd, sin) + int sd; + struct sockaddr_in *sin; +{ + int res; + static short port; + struct sockaddr_in myaddr; + extern int errno; + int i; + +#define STARTPORT 600 +#define ENDPORT (IPPORT_RESERVED - 1) +#define NPORTS (ENDPORT - STARTPORT + 1) + + if (sin == (struct sockaddr_in *)0) { + sin = &myaddr; + bzero(sin, sizeof (*sin)); + sin->sin_family = AF_INET; + } else if (sin->sin_family != AF_INET) { + errno = EPFNOSUPPORT; + return (-1); + } + if (port == 0) { + port = (getpid() % NPORTS) + STARTPORT; + } + res = -1; + errno = EADDRINUSE; + for (i = 0; i < NPORTS && res < 0 && errno == EADDRINUSE; i++) { + sin->sin_port = htons(port++); + if (port > ENDPORT) { + port = STARTPORT; + } + res = bind(sd, sin, sizeof(struct sockaddr_in)); + } + return (res); +} diff --git a/libc/inet/rpc/clnt_generic.c b/libc/inet/rpc/clnt_generic.c new file mode 100644 index 000000000..9124ccf16 --- /dev/null +++ b/libc/inet/rpc/clnt_generic.c @@ -0,0 +1,115 @@ +/* @(#)clnt_generic.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_generic.c 1.4 87/08/11 (C) 1987 SMI"; +#endif +/* + * Copyright (C) 1987, Sun Microsystems, Inc. + */ +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/errno.h> +#include <netdb.h> + +/* + * Generic client creation: takes (hostname, program-number, protocol) and + * returns client handle. Default options are set, which the user can + * change using the rpc equivalent of ioctl()'s. + */ +CLIENT * +clnt_create(hostname, prog, vers, proto) + char *hostname; + unsigned prog; + unsigned vers; + char *proto; +{ + struct hostent *h; + struct protoent *p; + struct sockaddr_in sin; + int sock; + struct timeval tv; + CLIENT *client; + + h = gethostbyname(hostname); + if (h == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNHOST; + return (NULL); + } + if (h->h_addrtype != AF_INET) { + /* + * Only support INET for now + */ + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EAFNOSUPPORT; + return (NULL); + } +#ifdef linux + bzero((char *) &sin, sizeof(sin)); +#endif + sin.sin_family = h->h_addrtype; + sin.sin_port = 0; +#ifndef linux + bzero(sin.sin_zero, sizeof(sin.sin_zero)); +#endif + bcopy(h->h_addr, (char*)&sin.sin_addr, h->h_length); + p = getprotobyname(proto); + if (p == NULL) { + rpc_createerr.cf_stat = RPC_UNKNOWNPROTO; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + sock = RPC_ANYSOCK; + switch (p->p_proto) { + case IPPROTO_UDP: + tv.tv_sec = 5; + tv.tv_usec = 0; + client = clntudp_create(&sin, prog, vers, tv, &sock); + if (client == NULL) { + return (NULL); + } + tv.tv_sec = 25; + clnt_control(client, CLSET_TIMEOUT, &tv); + break; + case IPPROTO_TCP: + client = clnttcp_create(&sin, prog, vers, &sock, 0, 0); + if (client == NULL) { + return (NULL); + } + tv.tv_sec = 25; + tv.tv_usec = 0; + clnt_control(client, CLSET_TIMEOUT, &tv); + break; + default: + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = EPFNOSUPPORT; + return (NULL); + } + return (client); +} diff --git a/libc/inet/rpc/clnt_perror.c b/libc/inet/rpc/clnt_perror.c new file mode 100644 index 000000000..80f51aa79 --- /dev/null +++ b/libc/inet/rpc/clnt_perror.c @@ -0,0 +1,310 @@ +/* @(#)clnt_perror.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_perror.c 1.15 87/10/07 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_perror.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/auth.h> +#include <rpc/clnt.h> + +extern char *sys_errlist[]; +static char *auth_errmsg(); + +extern char *strcpy(); + +static char *buf; + +static char * +_buf() +{ + + if (buf == 0) + buf = (char *)malloc(256); + return (buf); +} + +/* + * Print reply error info + */ +char * +clnt_sperror(rpch, s) + CLIENT *rpch; + char *s; +{ +#if 0 + struct rpc_err e; + void clnt_perrno(); + char *err; + char *str = _buf(); + char *strstart = str; + + if (str == 0) + return (0); + CLNT_GETERR(rpch, &e); + + (void) sprintf(str, "%s: ", s); + str += strlen(str); + + (void) strcpy(str, clnt_sperrno(e.re_status)); + str += strlen(str); + + switch (e.re_status) { + case RPC_SUCCESS: + case RPC_CANTENCODEARGS: + case RPC_CANTDECODERES: + case RPC_TIMEDOUT: + case RPC_PROGUNAVAIL: + case RPC_PROCUNAVAIL: + case RPC_CANTDECODEARGS: + case RPC_SYSTEMERROR: + case RPC_UNKNOWNHOST: + case RPC_UNKNOWNPROTO: + case RPC_PMAPFAILURE: + case RPC_PROGNOTREGISTERED: + case RPC_FAILED: + break; + + case RPC_CANTSEND: + case RPC_CANTRECV: + (void) sprintf(str, "; errno = %s", + sys_errlist[e.re_errno]); + str += strlen(str); + break; + + case RPC_VERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + case RPC_AUTHERROR: + err = auth_errmsg(e.re_why); + (void) sprintf(str,"; why = "); + str += strlen(str); + if (err != NULL) { + (void) sprintf(str, "%s",err); + } else { + (void) sprintf(str, + "(unknown authentication error - %d)", + (int) e.re_why); + } + str += strlen(str); + break; + + case RPC_PROGVERSMISMATCH: + (void) sprintf(str, + "; low version = %lu, high version = %lu", + e.re_vers.low, e.re_vers.high); + str += strlen(str); + break; + + default: /* unknown */ + (void) sprintf(str, + "; s1 = %lu, s2 = %lu", + e.re_lb.s1, e.re_lb.s2); + str += strlen(str); + break; + } + (void) sprintf(str, "\n"); + return(strstart) ; +#endif +} + +void +clnt_perror(rpch, s) + CLIENT *rpch; + char *s; +{ + (void) fprintf(stderr,"%s",clnt_sperror(rpch,s)); +} + + +struct rpc_errtab { + enum clnt_stat status; + char *message; +}; +#if 0 +static struct rpc_errtab rpc_errlist[] = { + { RPC_SUCCESS, + "RPC: Success" }, + { RPC_CANTENCODEARGS, + "RPC: Can't encode arguments" }, + { RPC_CANTDECODERES, + "RPC: Can't decode result" }, + { RPC_CANTSEND, + "RPC: Unable to send" }, + { RPC_CANTRECV, + "RPC: Unable to receive" }, + { RPC_TIMEDOUT, + "RPC: Timed out" }, + { RPC_VERSMISMATCH, + "RPC: Incompatible versions of RPC" }, + { RPC_AUTHERROR, + "RPC: Authentication error" }, + { RPC_PROGUNAVAIL, + "RPC: Program unavailable" }, + { RPC_PROGVERSMISMATCH, + "RPC: Program/version mismatch" }, + { RPC_PROCUNAVAIL, + "RPC: Procedure unavailable" }, + { RPC_CANTDECODEARGS, + "RPC: Server can't decode arguments" }, + { RPC_SYSTEMERROR, + "RPC: Remote system error" }, + { RPC_UNKNOWNHOST, + "RPC: Unknown host" }, + { RPC_UNKNOWNPROTO, + "RPC: Unknown protocol" }, + { RPC_PMAPFAILURE, + "RPC: Port mapper failure" }, + { RPC_PROGNOTREGISTERED, + "RPC: Program not registered"}, + { RPC_FAILED, + "RPC: Failed (unspecified error)"} +}; +#endif + +/* + * This interface for use by clntrpc + */ +char * +clnt_sperrno(stat) + enum clnt_stat stat; +{ +#if 0 + int i; + + for (i = 0; i < sizeof(rpc_errlist)/sizeof(struct rpc_errtab); i++) { + if (rpc_errlist[i].status == stat) { + return (rpc_errlist[i].message); + } + } +#endif + return ("RPC: (unknown error code)"); +} + +void +clnt_perrno(num) + enum clnt_stat num; +{ + (void) fprintf(stderr,"%s",clnt_sperrno(num)); +} + + +char * +clnt_spcreateerror(s) + char *s; +{ +#if 0 + extern int sys_nerr; + extern char *sys_errlist[]; + char *str = _buf(); + + if (str == 0) + return(0); + (void) sprintf(str, "%s: ", s); + (void) strcat(str, clnt_sperrno(rpc_createerr.cf_stat)); + switch (rpc_createerr.cf_stat) { + case RPC_PMAPFAILURE: + (void) strcat(str, " - "); + (void) strcat(str, + clnt_sperrno(rpc_createerr.cf_error.re_status)); + break; + + case RPC_SYSTEMERROR: + (void) strcat(str, " - "); + if (rpc_createerr.cf_error.re_errno > 0 + && rpc_createerr.cf_error.re_errno < sys_nerr) + (void) strcat(str, + sys_errlist[rpc_createerr.cf_error.re_errno]); + else + (void) sprintf(&str[strlen(str)], "Error %d", + rpc_createerr.cf_error.re_errno); + break; + } + (void) strcat(str, "\n"); + return (str); +#endif +} + +void +clnt_pcreateerror(s) + char *s; +{ + (void) fprintf(stderr,"%s",clnt_spcreateerror(s)); +} + +struct auth_errtab { + enum auth_stat status; + char *message; +}; + +static struct auth_errtab auth_errlist[] = { + { AUTH_OK, + "Authentication OK" }, + { AUTH_BADCRED, + "Invalid client credential" }, + { AUTH_REJECTEDCRED, + "Server rejected credential" }, + { AUTH_BADVERF, + "Invalid client verifier" }, + { AUTH_REJECTEDVERF, + "Server rejected verifier" }, + { AUTH_TOOWEAK, + "Client credential too weak" }, + { AUTH_INVALIDRESP, + "Invalid server verifier" }, + { AUTH_FAILED, + "Failed (unspecified error)" }, +}; + +static char * +auth_errmsg(stat) + enum auth_stat stat; +{ + int i; + + for (i = 0; i < sizeof(auth_errlist)/sizeof(struct auth_errtab); i++) { + if (auth_errlist[i].status == stat) { + return(auth_errlist[i].message); + } + } + return(NULL); +} diff --git a/libc/inet/rpc/clnt_raw.c b/libc/inet/rpc/clnt_raw.c new file mode 100644 index 000000000..89059ae2d --- /dev/null +++ b/libc/inet/rpc/clnt_raw.c @@ -0,0 +1,238 @@ +/* @(#)clnt_raw.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_raw.c 1.22 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_raw.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Memory based rpc for simple testing and timing. + * Interface to create an rpc client and server in the same process. + * This lets us similate rpc and get round trip overhead, without + * any interference from the kernal. + */ + +#include <rpc/rpc.h> + +#define MCALL_MSG_SIZE 24 + +/* + * This is the "network" we will be moving stuff over. + */ +static struct clntraw_private { + CLIENT client_object; + XDR xdr_stream; + char _raw_buf[UDPMSGSIZE]; + char mashl_callmsg[MCALL_MSG_SIZE]; + u_int mcnt; +} *clntraw_private; + +static enum clnt_stat clntraw_call(); +static void clntraw_abort(); +static void clntraw_geterr(); +static bool_t clntraw_freeres(); +static bool_t clntraw_control(); +static void clntraw_destroy(); + +static struct clnt_ops client_ops = { + clntraw_call, + clntraw_abort, + clntraw_geterr, + clntraw_freeres, + clntraw_destroy, + clntraw_control +}; + +void svc_getreq(); + +/* + * Create a client handle for memory based rpc. + */ +CLIENT * +clntraw_create(prog, vers) + u_long prog; + u_long vers; +{ + register struct clntraw_private *clp = clntraw_private; + struct rpc_msg call_msg; + XDR *xdrs = &clp->xdr_stream; + CLIENT *client = &clp->client_object; + + if (clp == 0) { + clp = (struct clntraw_private *)calloc(1, sizeof (*clp)); + if (clp == 0) + return (0); + clntraw_private = clp; + } + /* + * pre-serialize the staic part of the call msg and stash it away + */ + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + xdrmem_create(xdrs, clp->mashl_callmsg, MCALL_MSG_SIZE, XDR_ENCODE); + if (! xdr_callhdr(xdrs, &call_msg)) { + perror("clnt_raw.c - Fatal header serialization error."); + } + clp->mcnt = XDR_GETPOS(xdrs); + XDR_DESTROY(xdrs); + + /* + * Set xdrmem for client/server shared buffer + */ + xdrmem_create(xdrs, clp->_raw_buf, UDPMSGSIZE, XDR_FREE); + + /* + * create client handle + */ + client->cl_ops = &client_ops; + client->cl_auth = authnone_create(); + return (client); +} + +static enum clnt_stat +clntraw_call(h, proc, xargs, argsp, xresults, resultsp, timeout) + CLIENT *h; + u_long proc; + xdrproc_t xargs; + caddr_t argsp; + xdrproc_t xresults; + caddr_t resultsp; + struct timeval timeout; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + struct rpc_msg msg; + enum clnt_stat status; + struct rpc_err error; + + if (clp == 0) + return (RPC_FAILED); +call_again: + /* + * send request + */ + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + ((struct rpc_msg *)clp->mashl_callmsg)->rm_xid ++ ; + if ((! XDR_PUTBYTES(xdrs, clp->mashl_callmsg, clp->mcnt)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) { + return (RPC_CANTENCODEARGS); + } + (void)XDR_GETPOS(xdrs); /* called just to cause overhead */ + + /* + * We have to call server input routine here because this is + * all going on in one process. Yuk. + */ + svc_getreq(1); + + /* + * get results + */ + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = resultsp; + msg.acpted_rply.ar_results.proc = xresults; + if (! xdr_replymsg(xdrs, &msg)) + return (RPC_CANTDECODERES); + _seterr_reply(&msg, &error); + status = error.re_status; + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + } /* end successful completion */ + else { + if (AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + + if (status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &msg.acpted_rply.ar_verf)) { + status = RPC_AUTHERROR; + } + if (msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(msg.acpted_rply.ar_verf)); + } + } + + return (status); +} + +static void +clntraw_geterr() +{ +} + + +static bool_t +clntraw_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct clntraw_private *clp = clntraw_private; + register XDR *xdrs = &clp->xdr_stream; + bool_t rval; + + if (clp == 0) + { + rval = (bool_t) RPC_FAILED; + return (rval); + } + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntraw_abort() +{ +} + +static bool_t +clntraw_control() +{ + return (FALSE); +} + +static void +clntraw_destroy() +{ +} diff --git a/libc/inet/rpc/clnt_simple.c b/libc/inet/rpc/clnt_simple.c new file mode 100644 index 000000000..043ce0a3e --- /dev/null +++ b/libc/inet/rpc/clnt_simple.c @@ -0,0 +1,112 @@ +/* @(#)clnt_simple.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_simple.c 1.35 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> +#include <strings.h> + +static struct callrpc_private { + CLIENT *client; + int socket; + int oldprognum, oldversnum, valid; + char *oldhost; +} *callrpc_private; + +callrpc(host, prognum, versnum, procnum, inproc, in, outproc, out) + char *host; + xdrproc_t inproc, outproc; + char *in, *out; +{ + register struct callrpc_private *crp = callrpc_private; + struct sockaddr_in server_addr; + enum clnt_stat clnt_stat; + struct hostent *hp; + struct timeval timeout, tottimeout; + + if (crp == 0) { + crp = (struct callrpc_private *)calloc(1, sizeof (*crp)); + if (crp == 0) + return (0); + callrpc_private = crp; + } + if (crp->oldhost == NULL) { + crp->oldhost = malloc(256); + crp->oldhost[0] = 0; + crp->socket = RPC_ANYSOCK; + } + if (crp->valid && crp->oldprognum == prognum && crp->oldversnum == versnum + && strcmp(crp->oldhost, host) == 0) { + /* reuse old client */ + } else { + crp->valid = 0; + (void)close(crp->socket); + crp->socket = RPC_ANYSOCK; + if (crp->client) { + clnt_destroy(crp->client); + crp->client = NULL; + } + if ((hp = gethostbyname(host)) == NULL) + return ((int) RPC_UNKNOWNHOST); + timeout.tv_usec = 0; + timeout.tv_sec = 5; + bcopy(hp->h_addr, (char *)&server_addr.sin_addr, hp->h_length); + server_addr.sin_family = AF_INET; + server_addr.sin_port = 0; + if ((crp->client = clntudp_create(&server_addr, (u_long)prognum, + (u_long)versnum, timeout, &crp->socket)) == NULL) + return ((int) rpc_createerr.cf_stat); + crp->valid = 1; + crp->oldprognum = prognum; + crp->oldversnum = versnum; + (void) strcpy(crp->oldhost, host); + } + tottimeout.tv_sec = 25; + tottimeout.tv_usec = 0; + clnt_stat = clnt_call(crp->client, procnum, inproc, in, + outproc, out, tottimeout); + /* + * if call failed, empty cache + */ + if (clnt_stat != RPC_SUCCESS) + crp->valid = 0; + return ((int) clnt_stat); +} diff --git a/libc/inet/rpc/clnt_tcp.c b/libc/inet/rpc/clnt_tcp.c new file mode 100644 index 000000000..2222bc657 --- /dev/null +++ b/libc/inet/rpc/clnt_tcp.c @@ -0,0 +1,466 @@ +/* @(#)clnt_tcp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_tcp.c 1.37 87/10/05 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_tcp.c, Implements a TCP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * TCP based RPC supports 'batched calls'. + * A sequence of calls may be batched-up in a send buffer. The rpc call + * return immediately to the client even though the call was not necessarily + * sent. The batching occurs if the results' xdr routine is NULL (0) AND + * the rpc timeout value is zero (see clnt.h, rpc). + * + * Clients should NOT casually batch calls that in fact return results; that is, + * the server side should be aware that a call is batched and not produce any + * return message. Batched calls that produce many result messages can + * deadlock (netlock) the client and the server.... + * + * Now go hang yourself. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> +#include <errno.h> +#include <rpc/pmap_clnt.h> + +#define MCALL_MSG_SIZE 24 + +extern int errno; + +static int readtcp(); +static int writetcp(); + +static enum clnt_stat clnttcp_call(); +static void clnttcp_abort(); +static void clnttcp_geterr(); +static bool_t clnttcp_freeres(); +static bool_t clnttcp_control(); +static void clnttcp_destroy(); + +static struct clnt_ops tcp_ops = { + clnttcp_call, + clnttcp_abort, + clnttcp_geterr, + clnttcp_freeres, + clnttcp_destroy, + clnttcp_control +}; + +struct ct_data { + int ct_sock; + bool_t ct_closeit; + struct timeval ct_wait; + bool_t ct_waitset; /* wait set by clnt_control? */ + struct sockaddr_in ct_addr; + struct rpc_err ct_error; + char ct_mcall[MCALL_MSG_SIZE]; /* marshalled callmsg */ + u_int ct_mpos; /* pos after marshal */ + XDR ct_xdrs; +}; + +/* + * Create a client handle for a tcp/ip connection. + * If *sockp<0, *sockp is set to a newly created TCP socket and it is + * connected to raddr. If *sockp non-negative then + * raddr is ignored. The rpc/tcp package does buffering + * similar to stdio, so the client must pick send and receive buffer sizes,]; + * 0 => use the default. + * If raddr->sin_port is 0, then a binder on the remote machine is + * consulted for the right port number. + * NB: *sockp is copied into a private area. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is set null authentication. Caller may wish to set this + * something more useful. + */ +CLIENT * +clnttcp_create(raddr, prog, vers, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long prog; + u_long vers; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *h; + register struct ct_data *ct; + struct timeval now; + struct rpc_msg call_msg; + + h = (CLIENT *)mem_alloc(sizeof(*h)); + if (h == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + ct = (struct ct_data *)mem_alloc(sizeof(*ct)); + if (ct == NULL) { + (void)fprintf(stderr, "clnttcp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + + /* + * If no port number given ask the pmap for one + */ + if (raddr->sin_port == 0) { + u_short port; + if ((port = pmap_getport(raddr, prog, vers, IPPROTO_TCP)) == 0) { + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); + } + raddr->sin_port = htons(port); + } + + /* + * If no socket given, open one + */ + if (*sockp < 0) { + *sockp = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + if ((*sockp < 0) + || (connect(*sockp, (struct sockaddr *)raddr, + sizeof(*raddr)) < 0)) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + (void)close(*sockp); + goto fooy; + } + ct->ct_closeit = TRUE; + } else { + ct->ct_closeit = FALSE; + } + + /* + * Set up private data struct + */ + ct->ct_sock = *sockp; + ct->ct_wait.tv_usec = 0; + ct->ct_waitset = FALSE; + ct->ct_addr = *raddr; + + /* + * Initialize call message + */ + (void)gettimeofday(&now, (struct timezone *)0); + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = prog; + call_msg.rm_call.cb_vers = vers; + + /* + * pre-serialize the staic part of the call msg and stash it away + */ + xdrmem_create(&(ct->ct_xdrs), ct->ct_mcall, MCALL_MSG_SIZE, + XDR_ENCODE); + if (! xdr_callhdr(&(ct->ct_xdrs), &call_msg)) { + if (ct->ct_closeit) { + (void)close(*sockp); + } + goto fooy; + } + ct->ct_mpos = XDR_GETPOS(&(ct->ct_xdrs)); + XDR_DESTROY(&(ct->ct_xdrs)); + + /* + * Create a client handle which uses xdrrec for serialization + * and authnone for authentication. + */ + xdrrec_create(&(ct->ct_xdrs), sendsz, recvsz, + (caddr_t)ct, readtcp, writetcp); + h->cl_ops = &tcp_ops; + h->cl_private = (caddr_t) ct; + h->cl_auth = authnone_create(); + return (h); + +fooy: + /* + * Something goofed, free stuff and barf + */ + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +static enum clnt_stat +clnttcp_call(h, proc, xdr_args, args_ptr, xdr_results, results_ptr, timeout) + register CLIENT *h; + u_long proc; + xdrproc_t xdr_args; + caddr_t args_ptr; + xdrproc_t xdr_results; + caddr_t results_ptr; + struct timeval timeout; +{ + register struct ct_data *ct = (struct ct_data *) h->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + struct rpc_msg reply_msg; + u_long x_id; + u_long *msg_x_id = (u_long *)(ct->ct_mcall); /* yuk */ + register bool_t shipnow; + int refreshes = 2; + + if (!ct->ct_waitset) { + ct->ct_wait = timeout; + } + + shipnow = + (xdr_results == (xdrproc_t)0 && timeout.tv_sec == 0 + && timeout.tv_usec == 0) ? FALSE : TRUE; + +call_again: + xdrs->x_op = XDR_ENCODE; + ct->ct_error.re_status = RPC_SUCCESS; + x_id = ntohl(--(*msg_x_id)); + if ((! XDR_PUTBYTES(xdrs, ct->ct_mcall, ct->ct_mpos)) || + (! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(h->cl_auth, xdrs)) || + (! (*xdr_args)(xdrs, args_ptr))) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTENCODEARGS; + (void)xdrrec_endofrecord(xdrs, TRUE); + return (ct->ct_error.re_status); + } + if (! xdrrec_endofrecord(xdrs, shipnow)) + return (ct->ct_error.re_status = RPC_CANTSEND); + if (! shipnow) + return (RPC_SUCCESS); + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return(ct->ct_error.re_status = RPC_TIMEDOUT); + } + + + /* + * Keep receiving until we get a valid transaction id + */ + xdrs->x_op = XDR_DECODE; + while (TRUE) { + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = NULL; + reply_msg.acpted_rply.ar_results.proc = xdr_void; + if (! xdrrec_skiprecord(xdrs)) + return (ct->ct_error.re_status); + /* now decode and validate the response header */ + if (! xdr_replymsg(xdrs, &reply_msg)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + continue; + return (ct->ct_error.re_status); + } + if (reply_msg.rm_xid == x_id) + break; + } + + /* + * process header + */ + _seterr_reply(&reply_msg, &(ct->ct_error)); + if (ct->ct_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(h->cl_auth, &reply_msg.acpted_rply.ar_verf)) { + ct->ct_error.re_status = RPC_AUTHERROR; + ct->ct_error.re_why = AUTH_INVALIDRESP; + } else if (! (*xdr_results)(xdrs, results_ptr)) { + if (ct->ct_error.re_status == RPC_SUCCESS) + ct->ct_error.re_status = RPC_CANTDECODERES; + } + /* free verifier ... */ + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (refreshes-- && AUTH_REFRESH(h->cl_auth)) + goto call_again; + } /* end of unsuccessful completion */ + return (ct->ct_error.re_status); +} + +static void +clnttcp_geterr(h, errp) + CLIENT *h; + struct rpc_err *errp; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + *errp = ct->ct_error; +} + +static bool_t +clnttcp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + register XDR *xdrs = &(ct->ct_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clnttcp_abort() +{ +} + +static bool_t +clnttcp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct ct_data *ct = (struct ct_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + ct->ct_wait = *(struct timeval *)info; + ct->ct_waitset = TRUE; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = ct->ct_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = ct->ct_addr; + break; + default: + return (FALSE); + } + return (TRUE); +} + + +static void +clnttcp_destroy(h) + CLIENT *h; +{ + register struct ct_data *ct = + (struct ct_data *) h->cl_private; + + if (ct->ct_closeit) { + (void)close(ct->ct_sock); + } + XDR_DESTROY(&(ct->ct_xdrs)); + mem_free((caddr_t)ct, sizeof(struct ct_data)); + mem_free((caddr_t)h, sizeof(CLIENT)); +} + +/* + * Interface between xdr serializer and tcp connection. + * Behaves like the system calls, read & write, but keeps some error state + * around for the rpc level. + */ +static int +readtcp(ct, buf, len) + register struct ct_data *ct; + caddr_t buf; + register int len; +{ +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; + + if (len == 0) + return (0); + FD_ZERO(&mask); + FD_SET(ct->ct_sock, &mask); +#else + register int mask = 1 << (ct->ct_sock); + int readfds; + + if (len == 0) + return (0); + +#endif /* def FD_SETSIZE */ + while (TRUE) { + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, + &(ct->ct_wait))) { + case 0: + ct->ct_error.re_status = RPC_TIMEDOUT; + return (-1); + + case -1: + if (errno == EINTR) + continue; + ct->ct_error.re_status = RPC_CANTRECV; + ct->ct_error.re_errno = errno; + return (-1); + } + break; + } + switch (len = read(ct->ct_sock, buf, len)) { + + case 0: + /* premature eof */ + ct->ct_error.re_errno = ECONNRESET; + ct->ct_error.re_status = RPC_CANTRECV; + len = -1; /* it's really an error */ + break; + + case -1: + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTRECV; + break; + } + return (len); +} + +static int +writetcp(ct, buf, len) + struct ct_data *ct; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(ct->ct_sock, buf, cnt)) == -1) { + ct->ct_error.re_errno = errno; + ct->ct_error.re_status = RPC_CANTSEND; + return (-1); + } + } + return (len); +} diff --git a/libc/inet/rpc/clnt_udp.c b/libc/inet/rpc/clnt_udp.c new file mode 100644 index 000000000..815cbb4ed --- /dev/null +++ b/libc/inet/rpc/clnt_udp.c @@ -0,0 +1,442 @@ +/* @(#)clnt_udp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)clnt_udp.c 1.39 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * clnt_udp.c, Implements a UDP/IP based, client side RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <sys/ioctl.h> +#include <netdb.h> +#include <errno.h> +#include <rpc/pmap_clnt.h> + +extern int errno; + +/* + * UDP bases client side rpc operations + */ +static enum clnt_stat clntudp_call(); +static void clntudp_abort(); +static void clntudp_geterr(); +static bool_t clntudp_freeres(); +static bool_t clntudp_control(); +static void clntudp_destroy(); + +static struct clnt_ops udp_ops = { + clntudp_call, + clntudp_abort, + clntudp_geterr, + clntudp_freeres, + clntudp_destroy, + clntudp_control +}; + +/* + * Private data kept per client handle + */ +struct cu_data { + int cu_sock; + bool_t cu_closeit; + struct sockaddr_in cu_raddr; + int cu_rlen; + struct timeval cu_wait; + struct timeval cu_total; + struct rpc_err cu_error; + XDR cu_outxdrs; + u_int cu_xdrpos; + u_int cu_sendsz; + char *cu_outbuf; + u_int cu_recvsz; + char cu_inbuf[1]; +}; + +/* + * Create a UDP based client handle. + * If *sockp<0, *sockp is set to a newly created UPD socket. + * If raddr->sin_port is 0 a binder on the remote machine + * is consulted for the correct port number. + * NB: It is the clients responsibility to close *sockp. + * NB: The rpch->cl_auth is initialized to null authentication. + * Caller may wish to set this something more useful. + * + * wait is the amount of time used between retransmitting a call if + * no response has been heard; retransmition occurs until the actual + * rpc call times out. + * + * sendsz and recvsz are the maximum allowable packet sizes that can be + * sent and received. + */ +CLIENT * +clntudp_bufcreate(raddr, program, version, wait, sockp, sendsz, recvsz) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; + u_int sendsz; + u_int recvsz; +{ + CLIENT *cl; + register struct cu_data *cu; + struct timeval now; + struct rpc_msg call_msg; + + cl = (CLIENT *)mem_alloc(sizeof(CLIENT)); + if (cl == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + sendsz = ((sendsz + 3) / 4) * 4; + recvsz = ((recvsz + 3) / 4) * 4; + cu = (struct cu_data *)mem_alloc(sizeof(*cu) + sendsz + recvsz); + if (cu == NULL) { + (void) fprintf(stderr, "clntudp_create: out of memory\n"); + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + cu->cu_outbuf = &cu->cu_inbuf[recvsz]; + + (void)gettimeofday(&now, (struct timezone *)0); + if (raddr->sin_port == 0) { + u_short port; + if ((port = + pmap_getport(raddr, program, version, IPPROTO_UDP)) == 0) { + goto fooy; + } + raddr->sin_port = htons(port); + } + cl->cl_ops = &udp_ops; + cl->cl_private = (caddr_t)cu; + cu->cu_raddr = *raddr; + cu->cu_rlen = sizeof (cu->cu_raddr); + cu->cu_wait = wait; + cu->cu_total.tv_sec = -1; + cu->cu_total.tv_usec = -1; + cu->cu_sendsz = sendsz; + cu->cu_recvsz = recvsz; + call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec; + call_msg.rm_direction = CALL; + call_msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + call_msg.rm_call.cb_prog = program; + call_msg.rm_call.cb_vers = version; + xdrmem_create(&(cu->cu_outxdrs), cu->cu_outbuf, + sendsz, XDR_ENCODE); + if (! xdr_callhdr(&(cu->cu_outxdrs), &call_msg)) { + goto fooy; + } + cu->cu_xdrpos = XDR_GETPOS(&(cu->cu_outxdrs)); + if (*sockp < 0) { + int dontblock = 1; + + *sockp = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (*sockp < 0) { + rpc_createerr.cf_stat = RPC_SYSTEMERROR; + rpc_createerr.cf_error.re_errno = errno; + goto fooy; + } + /* attempt to bind to prov port */ + (void)bindresvport(*sockp, (struct sockaddr_in *)0); + /* the sockets rpc controls are non-blocking */ + (void)ioctl(*sockp, FIONBIO, (char *) &dontblock); + cu->cu_closeit = TRUE; + } else { + cu->cu_closeit = FALSE; + } + cu->cu_sock = *sockp; + cl->cl_auth = authnone_create(); + return (cl); +fooy: + if (cu) + mem_free((caddr_t)cu, sizeof(*cu) + sendsz + recvsz); + if (cl) + mem_free((caddr_t)cl, sizeof(CLIENT)); + return ((CLIENT *)NULL); +} + +CLIENT * +clntudp_create(raddr, program, version, wait, sockp) + struct sockaddr_in *raddr; + u_long program; + u_long version; + struct timeval wait; + register int *sockp; +{ + + return(clntudp_bufcreate(raddr, program, version, wait, sockp, + UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum clnt_stat +clntudp_call(cl, proc, xargs, argsp, xresults, resultsp, utimeout) + register CLIENT *cl; /* client handle */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + struct timeval utimeout; /* seconds to wait before giving up */ +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs; + register int outlen; + register int inlen; + int fromlen; +#ifdef FD_SETSIZE + fd_set readfds; + fd_set mask; +#else + int readfds; + register int mask; +#endif /* def FD_SETSIZE */ + struct sockaddr_in from; + struct rpc_msg reply_msg; + XDR reply_xdrs; + struct timeval time_waited; + bool_t ok; + int nrefreshes = 2; /* number of times to refresh cred */ + struct timeval timeout; + + if (cu->cu_total.tv_usec == -1) { + timeout = utimeout; /* use supplied timeout */ + } else { + timeout = cu->cu_total; /* use default timeout */ + } + + time_waited.tv_sec = 0; + time_waited.tv_usec = 0; +call_again: + xdrs = &(cu->cu_outxdrs); + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, cu->cu_xdrpos); + /* + * the transaction is the first thing in the out buffer + */ + (*(u_short *)(cu->cu_outbuf))++; + if ((! XDR_PUTLONG(xdrs, (long *)&proc)) || + (! AUTH_MARSHALL(cl->cl_auth, xdrs)) || + (! (*xargs)(xdrs, argsp))) + return (cu->cu_error.re_status = RPC_CANTENCODEARGS); + outlen = (int)XDR_GETPOS(xdrs); + +send_again: + if (sendto(cu->cu_sock, cu->cu_outbuf, outlen, 0, + (struct sockaddr *)&(cu->cu_raddr), cu->cu_rlen) + != outlen) { + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTSEND); + } + + /* + * Hack to provide rpc-based message passing + */ + if (timeout.tv_sec == 0 && timeout.tv_usec == 0) { + return (cu->cu_error.re_status = RPC_TIMEDOUT); + } + /* + * sub-optimal code appears here because we have + * some clock time to spare while the packets are in flight. + * (We assume that this is actually only executed once.) + */ + reply_msg.acpted_rply.ar_verf = _null_auth; + reply_msg.acpted_rply.ar_results.where = resultsp; + reply_msg.acpted_rply.ar_results.proc = xresults; +#ifdef FD_SETSIZE + FD_ZERO(&mask); + FD_SET(cu->cu_sock, &mask); +#else + mask = 1 << cu->cu_sock; +#endif /* def FD_SETSIZE */ + for (;;) { + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, + (int *)NULL, &(cu->cu_wait))) { + + case 0: + time_waited.tv_sec += cu->cu_wait.tv_sec; + time_waited.tv_usec += cu->cu_wait.tv_usec; + while (time_waited.tv_usec >= 1000000) { + time_waited.tv_sec++; + time_waited.tv_usec -= 1000000; + } + if ((time_waited.tv_sec < timeout.tv_sec) || + ((time_waited.tv_sec == timeout.tv_sec) && + (time_waited.tv_usec < timeout.tv_usec))) + goto send_again; + return (cu->cu_error.re_status = RPC_TIMEDOUT); + + /* + * buggy in other cases because time_waited is not being + * updated. + */ + case -1: + if (errno == EINTR) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + do { + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(cu->cu_sock, cu->cu_inbuf, + (int) cu->cu_recvsz, 0, + (struct sockaddr *)&from, &fromlen); + } while (inlen < 0 && errno == EINTR); + if (inlen < 0) { + if (errno == EWOULDBLOCK) + continue; + cu->cu_error.re_errno = errno; + return (cu->cu_error.re_status = RPC_CANTRECV); + } + if (inlen < sizeof(u_long)) + continue; + /* see if reply transaction id matches sent id */ + if (*((u_long *)(cu->cu_inbuf)) != *((u_long *)(cu->cu_outbuf))) + continue; + /* we now assume we have the proper reply */ + break; + } + + /* + * now decode and validate the response + */ + xdrmem_create(&reply_xdrs, cu->cu_inbuf, (u_int)inlen, XDR_DECODE); + ok = xdr_replymsg(&reply_xdrs, &reply_msg); + /* XDR_DESTROY(&reply_xdrs); save a few cycles on noop destroy */ + if (ok) { + _seterr_reply(&reply_msg, &(cu->cu_error)); + if (cu->cu_error.re_status == RPC_SUCCESS) { + if (! AUTH_VALIDATE(cl->cl_auth, + &reply_msg.acpted_rply.ar_verf)) { + cu->cu_error.re_status = RPC_AUTHERROR; + cu->cu_error.re_why = AUTH_INVALIDRESP; + } + if (reply_msg.acpted_rply.ar_verf.oa_base != NULL) { + xdrs->x_op = XDR_FREE; + (void)xdr_opaque_auth(xdrs, + &(reply_msg.acpted_rply.ar_verf)); + } + } /* end successful completion */ + else { + /* maybe our credentials need to be refreshed ... */ + if (nrefreshes > 0 && AUTH_REFRESH(cl->cl_auth)) { + nrefreshes--; + goto call_again; + } + } /* end of unsuccessful completion */ + } /* end of valid reply message */ + else { + cu->cu_error.re_status = RPC_CANTDECODERES; + } + return (cu->cu_error.re_status); +} + +static void +clntudp_geterr(cl, errp) + CLIENT *cl; + struct rpc_err *errp; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + *errp = cu->cu_error; +} + + +static bool_t +clntudp_freeres(cl, xdr_res, res_ptr) + CLIENT *cl; + xdrproc_t xdr_res; + caddr_t res_ptr; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + register XDR *xdrs = &(cu->cu_outxdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_res)(xdrs, res_ptr)); +} + +static void +clntudp_abort(/*h*/) + /*CLIENT *h;*/ +{ +} + +static bool_t +clntudp_control(cl, request, info) + CLIENT *cl; + int request; + char *info; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + switch (request) { + case CLSET_TIMEOUT: + cu->cu_total = *(struct timeval *)info; + break; + case CLGET_TIMEOUT: + *(struct timeval *)info = cu->cu_total; + break; + case CLSET_RETRY_TIMEOUT: + cu->cu_wait = *(struct timeval *)info; + break; + case CLGET_RETRY_TIMEOUT: + *(struct timeval *)info = cu->cu_wait; + break; + case CLGET_SERVER_ADDR: + *(struct sockaddr_in *)info = cu->cu_raddr; + break; + default: + return (FALSE); + } + return (TRUE); +} + +static void +clntudp_destroy(cl) + CLIENT *cl; +{ + register struct cu_data *cu = (struct cu_data *)cl->cl_private; + + if (cu->cu_closeit) { + (void)close(cu->cu_sock); + } + XDR_DESTROY(&(cu->cu_outxdrs)); + mem_free((caddr_t)cu, (sizeof(*cu) + cu->cu_sendsz + cu->cu_recvsz)); + mem_free((caddr_t)cl, sizeof(CLIENT)); +} diff --git a/libc/inet/rpc/get_myaddress.c b/libc/inet/rpc/get_myaddress.c new file mode 100644 index 000000000..44a6eb38c --- /dev/null +++ b/libc/inet/rpc/get_myaddress.c @@ -0,0 +1,108 @@ +/* @(#)get_myaddress.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)get_myaddress.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * get_myaddress.c + * + * Get client's IP address via ioctl. This avoids using the yellowpages. + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/pmap_prot.h> +#include <sys/socket.h> +#include <stdio.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#include <netinet/in.h> + +#ifdef linux +/* DO use gethostbyname because it's portable */ +#include <netdb.h> +get_myaddress(addr) + struct sockaddr_in *addr; +{ + char localhost[256 + 1]; + struct hostent *hp; + + gethostname(localhost, 256); + if ((hp = gethostbyname(localhost)) == NULL) { + perror("get_myaddress: gethostbyname"); + exit(1); + } + addr->sin_family = AF_INET; + bcopy((char *) hp->h_addr, (char *) &addr->sin_addr, hp->h_length); + addr->sin_port = htons(PMAPPORT); +} +#else +/* + * don't use gethostbyname, which would invoke yellow pages + */ +get_myaddress(addr) + struct sockaddr_in *addr; +{ + int s; + char buf[BUFSIZ]; + struct ifconf ifc; + struct ifreq ifreq, *ifr; + int len; + + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + perror("get_myaddress: socket"); + exit(1); + } + ifc.ifc_len = sizeof (buf); + ifc.ifc_buf = buf; + if (ioctl(s, SIOCGIFCONF, (char *)&ifc) < 0) { + perror("get_myaddress: ioctl (get interface configuration)"); + exit(1); + } + ifr = ifc.ifc_req; + for (len = ifc.ifc_len; len; len -= sizeof ifreq) { + ifreq = *ifr; + if (ioctl(s, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + perror("get_myaddress: ioctl"); + exit(1); + } + if ((ifreq.ifr_flags & IFF_UP) && + ifr->ifr_addr.sa_family == AF_INET) { + *addr = *((struct sockaddr_in *)&ifr->ifr_addr); + addr->sin_port = htons(PMAPPORT); + break; + } + ifr++; + } + (void) close(s); +} +#endif diff --git a/libc/inet/rpc/getrpcent.c b/libc/inet/rpc/getrpcent.c new file mode 100644 index 000000000..e0b7342cc --- /dev/null +++ b/libc/inet/rpc/getrpcent.c @@ -0,0 +1,286 @@ +/* @(#)getrpcent.c 2.2 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)getrpcent.c 1.9 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <rpc/rpc.h> +#include <netdb.h> +#include <sys/socket.h> + +/* + * Internet version. + */ +struct rpcdata { + FILE *rpcf; + char *current; + int currentlen; + int stayopen; +#define MAXALIASES 35 + char *rpc_aliases[MAXALIASES]; + struct rpcent rpc; + char line[BUFSIZ+1]; + char *domain; +} *rpcdata, *_rpcdata(); + +static struct rpcent *interpret(); +struct hostent *gethostent(); +char *inet_ntoa(); +#ifndef linux +static char *index(); +#else +char *index(); +#endif + +static char RPCDB[] = "/etc/rpc"; + +static struct rpcdata * +_rpcdata() +{ + register struct rpcdata *d = rpcdata; + + if (d == 0) { + d = (struct rpcdata *)calloc(1, sizeof (struct rpcdata)); + rpcdata = d; + } + return (d); +} + +struct rpcent * +getrpcbynumber(number) + register int number; +{ + register struct rpcdata *d = _rpcdata(); + register struct rpcent *p; + int reason; + char adrstr[16], *val = NULL; + int vallen; + + if (d == 0) + return (0); + setrpcent(0); + while (p = getrpcent()) { + if (p->r_number == number) + break; + } + endrpcent(); + return (p); +} + +struct rpcent * +#ifdef linux +getrpcbyname(const char *name) +#else +getrpcbyname(name) + char *name; +#endif +{ + struct rpcent *rpc; + char **rp; + + setrpcent(0); + while(rpc = getrpcent()) { + if (strcmp(rpc->r_name, name) == 0) + return (rpc); + for (rp = rpc->r_aliases; *rp != NULL; rp++) { + if (strcmp(*rp, name) == 0) + return (rpc); + } + } + endrpcent(); + return (NULL); +} + +#ifdef linux +void +#endif +setrpcent(f) + int f; +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->rpcf == NULL) + d->rpcf = fopen(RPCDB, "r"); + else + rewind(d->rpcf); + if (d->current) + free(d->current); + d->current = NULL; + d->stayopen |= f; +} + +#ifdef linux +void +#endif +endrpcent() +{ + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return; + if (d->current && !d->stayopen) { + free(d->current); + d->current = NULL; + } + if (d->rpcf && !d->stayopen) { + fclose(d->rpcf); + d->rpcf = NULL; + } +} + +struct rpcent * +getrpcent() +{ + struct rpcent *hp; + int reason; + char *key = NULL, *val = NULL; + int keylen, vallen; + register struct rpcdata *d = _rpcdata(); + + if (d == 0) + return(NULL); + if (d->rpcf == NULL && (d->rpcf = fopen(RPCDB, "r")) == NULL) + return (NULL); + if (fgets(d->line, BUFSIZ, d->rpcf) == NULL) + return (NULL); + return interpret(d->line, strlen(d->line)); +} + +#ifdef linux +static char * +firstwhite(s) +char *s; +{ + char *s1, *s2; + + s1 = index(s, ' '); + s2 = index(s, '\t'); + if (s1) { + if (s2) + return (s1 < s2) ? s1 : s2; + else + return s1; + } + else + return s2; +} +#endif + +static struct rpcent * +interpret(val, len) +{ + register struct rpcdata *d = _rpcdata(); + char *p; + register char *cp, **q; + + if (d == 0) + return; + strncpy(d->line, val, len); + p = d->line; + d->line[len] = '\n'; + if (*p == '#') + return (getrpcent()); + cp = index(p, '#'); + if (cp == NULL) + { + cp = index(p, '\n'); + if (cp == NULL) + return (getrpcent()); + } + *cp = '\0'; +#ifdef linux + if ((cp = firstwhite(p))) + *cp++ = 0; + else + return (getrpcent()); +#else + cp = index(p, ' '); + if (cp == NULL) + { + cp = index(p, '\t'); + if (cp == NULL) + return (getrpcent()); + } + *cp++ = '\0'; +#endif + /* THIS STUFF IS INTERNET SPECIFIC */ + d->rpc.r_name = d->line; + while (*cp == ' ' || *cp == '\t') + cp++; + d->rpc.r_number = atoi(cp); + q = d->rpc.r_aliases = d->rpc_aliases; +#ifdef linux + if ((cp = firstwhite(cp))) + *cp++ = '\0'; +#else + cp = index(p, ' '); + if (cp != NULL) + *cp++ = '\0'; + else + { + cp = index(p, '\t'); + if (cp != NULL) + *cp++ = '\0'; + } +#endif + while (cp && *cp) { + if (*cp == ' ' || *cp == '\t') { + cp++; + continue; + } + if (q < &(d->rpc_aliases[MAXALIASES - 1])) + *q++ = cp; +#ifdef linux + if ((cp = firstwhite(cp))) + *cp++ = '\0'; +#else + cp = index(p, ' '); + if (cp != NULL) + *cp++ = '\0'; + else + { + cp = index(p, '\t'); + if (cp != NULL) + *cp++ = '\0'; + } +#endif + } + *q = NULL; + return (&d->rpc); +} diff --git a/libc/inet/rpc/getrpcport.c b/libc/inet/rpc/getrpcport.c new file mode 100644 index 000000000..9b13bac6b --- /dev/null +++ b/libc/inet/rpc/getrpcport.c @@ -0,0 +1,55 @@ +/* @(#)getrpcport.c 2.1 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)getrpcport.c 1.3 87/08/11 SMI"; +#endif +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * Copyright (c) 1985 by Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <netdb.h> +#include <sys/socket.h> + +getrpcport(host, prognum, versnum, proto) + char *host; +{ + struct sockaddr_in addr; + struct hostent *hp; + + if ((hp = gethostbyname(host)) == NULL) + return (0); + bcopy(hp->h_addr, (char *) &addr.sin_addr, hp->h_length); + addr.sin_family = AF_INET; + addr.sin_port = 0; + return (pmap_getport(&addr, prognum, versnum, proto)); +} diff --git a/libc/inet/rpc/pmap_clnt.c b/libc/inet/rpc/pmap_clnt.c new file mode 100644 index 000000000..09220e77b --- /dev/null +++ b/libc/inet/rpc/pmap_clnt.c @@ -0,0 +1,115 @@ +/* @(#)pmap_clnt.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_clnt.c 1.37 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_clnt.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +void clnt_perror(); + + +/* + * Set a mapping between program,version and port. + * Calls the pmap service remotely to do the mapping. + */ +bool_t +pmap_set(program, version, protocol, port) + u_long program; + u_long version; + int protocol; + u_short port; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + get_myaddress(&myaddress); + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = port; + if (CLNT_CALL(client, PMAPPROC_SET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout) != RPC_SUCCESS) { + clnt_perror(client, "Cannot register service"); + return (FALSE); + } + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} + +/* + * Remove the mapping between program,version and port. + * Calls the pmap service remotely to do the un-mapping. + */ +bool_t +pmap_unset(program, version) + u_long program; + u_long version; +{ + struct sockaddr_in myaddress; + int socket = -1; + register CLIENT *client; + struct pmap parms; + bool_t rslt; + + get_myaddress(&myaddress); + client = clntudp_bufcreate(&myaddress, PMAPPROG, PMAPVERS, + timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client == (CLIENT *)NULL) + return (FALSE); + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_port = parms.pm_prot = 0; + CLNT_CALL(client, PMAPPROC_UNSET, xdr_pmap, &parms, xdr_bool, &rslt, + tottimeout); + CLNT_DESTROY(client); + (void)close(socket); + return (rslt); +} diff --git a/libc/inet/rpc/pmap_getmaps.c b/libc/inet/rpc/pmap_getmaps.c new file mode 100644 index 000000000..e4a9c4936 --- /dev/null +++ b/libc/inet/rpc/pmap_getmaps.c @@ -0,0 +1,84 @@ +/* @(#)pmap_getmaps.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getmaps.c 1.10 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_getmap.c + * Client interface to pmap rpc service. + * contains pmap_getmaps, which is only tcp service involved + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <sys/socket.h> +#include <netdb.h> +#include <stdio.h> +#include <errno.h> +#include <net/if.h> +#include <sys/ioctl.h> +#define NAMELEN 255 +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; + +/* + * Get a copy of the current port maps. + * Calls the pmap service remotely to do get the maps. + */ +struct pmaplist * +pmap_getmaps(address) + struct sockaddr_in *address; +{ + struct pmaplist *head = (struct pmaplist *)NULL; + int socket = -1; + struct timeval minutetimeout; + register CLIENT *client; + + minutetimeout.tv_sec = 60; + minutetimeout.tv_usec = 0; + address->sin_port = htons(PMAPPORT); + client = clnttcp_create(address, PMAPPROG, + PMAPVERS, &socket, 50, 500); + if (client != (CLIENT *)NULL) { + if (CLNT_CALL(client, PMAPPROC_DUMP, xdr_void, NULL, xdr_pmaplist, + &head, minutetimeout) != RPC_SUCCESS) { + clnt_perror(client, "pmap_getmaps rpc problem"); + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (head); +} diff --git a/libc/inet/rpc/pmap_getport.c b/libc/inet/rpc/pmap_getport.c new file mode 100644 index 000000000..77b9cf743 --- /dev/null +++ b/libc/inet/rpc/pmap_getport.c @@ -0,0 +1,87 @@ +/* @(#)pmap_getport.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_getport.c 1.9 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_getport.c + * Client interface to pmap rpc service. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <sys/socket.h> +#include <net/if.h> + +static struct timeval timeout = { 5, 0 }; +static struct timeval tottimeout = { 60, 0 }; + +/* + * Find the mapped port for program,version. + * Calls the pmap service remotely to do the lookup. + * Returns 0 if no map exists. + */ +u_short +pmap_getport(address, program, version, protocol) + struct sockaddr_in *address; + u_long program; + u_long version; + u_int protocol; +{ + u_short port = 0; + int socket = -1; + register CLIENT *client; + struct pmap parms; + + address->sin_port = htons(PMAPPORT); + client = clntudp_bufcreate(address, PMAPPROG, + PMAPVERS, timeout, &socket, RPCSMALLMSGSIZE, RPCSMALLMSGSIZE); + if (client != (CLIENT *)NULL) { + parms.pm_prog = program; + parms.pm_vers = version; + parms.pm_prot = protocol; + parms.pm_port = 0; /* not needed or used */ + if (CLNT_CALL(client, PMAPPROC_GETPORT, xdr_pmap, &parms, + xdr_u_short, &port, tottimeout) != RPC_SUCCESS){ + rpc_createerr.cf_stat = RPC_PMAPFAILURE; + clnt_geterr(client, &rpc_createerr.cf_error); + } else if (port == 0) { + rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED; + } + CLNT_DESTROY(client); + } + (void)close(socket); + address->sin_port = 0; + return (port); +} diff --git a/libc/inet/rpc/pmap_prot.c b/libc/inet/rpc/pmap_prot.c new file mode 100644 index 000000000..643c2ff6a --- /dev/null +++ b/libc/inet/rpc/pmap_prot.c @@ -0,0 +1,57 @@ +/* @(#)pmap_prot.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot.c 1.17 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_prot.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/pmap_prot.h> + + +bool_t +xdr_pmap(xdrs, regs) + XDR *xdrs; + struct pmap *regs; +{ + + if (xdr_u_long(xdrs, ®s->pm_prog) && + xdr_u_long(xdrs, ®s->pm_vers) && + xdr_u_long(xdrs, ®s->pm_prot)) + return (xdr_u_long(xdrs, ®s->pm_port)); + return (FALSE); +} diff --git a/libc/inet/rpc/pmap_prot2.c b/libc/inet/rpc/pmap_prot2.c new file mode 100644 index 000000000..e2a8214d4 --- /dev/null +++ b/libc/inet/rpc/pmap_prot2.c @@ -0,0 +1,116 @@ +/* @(#)pmap_prot2.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_prot2.c 1.3 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_prot2.c + * Protocol for the local binder service, or pmap. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <rpc/pmap_prot.h> + + +/* + * What is going on with linked lists? (!) + * First recall the link list declaration from pmap_prot.h: + * + * struct pmaplist { + * struct pmap pml_map; + * struct pmaplist *pml_map; + * }; + * + * Compare that declaration with a corresponding xdr declaration that + * is (a) pointer-less, and (b) recursive: + * + * typedef union switch (bool_t) { + * + * case TRUE: struct { + * struct pmap; + * pmaplist_t foo; + * }; + * + * case FALSE: struct {}; + * } pmaplist_t; + * + * Notice that the xdr declaration has no nxt pointer while + * the C declaration has no bool_t variable. The bool_t can be + * interpreted as ``more data follows me''; if FALSE then nothing + * follows this bool_t; if TRUE then the bool_t is followed by + * an actual struct pmap, and then (recursively) by the + * xdr union, pamplist_t. + * + * This could be implemented via the xdr_union primitive, though this + * would cause a one recursive call per element in the list. Rather than do + * that we can ``unwind'' the recursion + * into a while loop and do the union arms in-place. + * + * The head of the list is what the C programmer wishes to past around + * the net, yet is the data that the pointer points to which is interesting; + * this sounds like a job for xdr_reference! + */ +bool_t +xdr_pmaplist(xdrs, rp) + register XDR *xdrs; + register struct pmaplist **rp; +{ + /* + * more_elements is pre-computed in case the direction is + * XDR_ENCODE or XDR_FREE. more_elements is overwritten by + * xdr_bool when the direction is XDR_DECODE. + */ + bool_t more_elements; + register int freeing = (xdrs->x_op == XDR_FREE); + register struct pmaplist **next; + + while (TRUE) { + more_elements = (bool_t)(*rp != NULL); + if (! xdr_bool(xdrs, &more_elements)) + return (FALSE); + if (! more_elements) + return (TRUE); /* we are done */ + /* + * the unfortunate side effect of non-recursion is that in + * the case of freeing we must remember the next object + * before we free the current object ... + */ + if (freeing) + next = &((*rp)->pml_next); + if (! xdr_reference(xdrs, (caddr_t *)rp, + (u_int)sizeof(struct pmaplist), xdr_pmap)) + return (FALSE); + rp = (freeing) ? next : &((*rp)->pml_next); + } +} diff --git a/libc/inet/rpc/pmap_rmt.c b/libc/inet/rpc/pmap_rmt.c new file mode 100644 index 000000000..08b6bebd3 --- /dev/null +++ b/libc/inet/rpc/pmap_rmt.c @@ -0,0 +1,408 @@ +/* @(#)pmap_rmt.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)pmap_rmt.c 1.21 87/08/27 Copyr 1984 Sun Micro"; +#endif + +/* + * pmap_rmt.c + * Client interface to pmap rpc service. + * remote call and broadcast service + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> +#include <rpc/pmap_prot.h> +#include <rpc/pmap_clnt.h> +#include <rpc/pmap_rmt.h> +#include <sys/socket.h> +#include <stdio.h> +#include <errno.h> +#include <net/if.h> +#include <sys/ioctl.h> +#include <arpa/inet.h> +#define MAX_BROADCAST_SIZE 1400 + +extern int errno; +static struct timeval timeout = { 3, 0 }; + + +/* + * pmapper remote-call-service interface. + * This routine is used to call the pmapper remote call service + * which will look up a service program in the port maps, and then + * remotely call that routine with the given parameters. This allows + * programs to do a lookup and call in one step. +*/ +enum clnt_stat +pmap_rmtcall(addr, prog, vers, proc, xdrargs, argsp, xdrres, resp, tout, port_ptr) + struct sockaddr_in *addr; + u_long prog, vers, proc; + xdrproc_t xdrargs, xdrres; + caddr_t argsp, resp; + struct timeval tout; + u_long *port_ptr; +{ + int socket = -1; + register CLIENT *client; + struct rmtcallargs a; + struct rmtcallres r; + enum clnt_stat stat; + + addr->sin_port = htons(PMAPPORT); + client = clntudp_create(addr, PMAPPROG, PMAPVERS, timeout, &socket); + if (client != (CLIENT *)NULL) { + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.args_ptr = argsp; + a.xdr_args = xdrargs; + r.port_ptr = port_ptr; + r.results_ptr = resp; + r.xdr_results = xdrres; + stat = CLNT_CALL(client, PMAPPROC_CALLIT, xdr_rmtcall_args, &a, + xdr_rmtcallres, &r, tout); + CLNT_DESTROY(client); + } else { + stat = RPC_FAILED; + } + (void)close(socket); + addr->sin_port = 0; + return (stat); +} + + +/* + * XDR remote call arguments + * written for XDR_ENCODE direction only + */ +bool_t +xdr_rmtcall_args(xdrs, cap) + register XDR *xdrs; + register struct rmtcallargs *cap; +{ + u_int lenposition, argposition, position; + + if (xdr_u_long(xdrs, &(cap->prog)) && + xdr_u_long(xdrs, &(cap->vers)) && + xdr_u_long(xdrs, &(cap->proc))) { + lenposition = XDR_GETPOS(xdrs); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + argposition = XDR_GETPOS(xdrs); + if (! (*(cap->xdr_args))(xdrs, cap->args_ptr)) + return (FALSE); + position = XDR_GETPOS(xdrs); + cap->arglen = (u_long)position - (u_long)argposition; + XDR_SETPOS(xdrs, lenposition); + if (! xdr_u_long(xdrs, &(cap->arglen))) + return (FALSE); + XDR_SETPOS(xdrs, position); + return (TRUE); + } + return (FALSE); +} + +/* + * XDR remote call results + * written for XDR_DECODE direction only + */ +bool_t +xdr_rmtcallres(xdrs, crp) + register XDR *xdrs; + register struct rmtcallres *crp; +{ + caddr_t port_ptr; + + port_ptr = (caddr_t)crp->port_ptr; + if (xdr_reference(xdrs, &port_ptr, sizeof (u_long), + xdr_u_long) && xdr_u_long(xdrs, &crp->resultslen)) { + crp->port_ptr = (u_long *)port_ptr; + return ((*(crp->xdr_results))(xdrs, crp->results_ptr)); + } + return (FALSE); +} + + +/* + * The following is kludged-up support for simple rpc broadcasts. + * Someday a large, complicated system will replace these trivial + * routines which only support udp/ip . + */ + +static int +getbroadcastnets(addrs, sock, buf) + struct in_addr *addrs; + int sock; /* any valid socket will do */ + char *buf; /* why allocxate more when we can use existing... */ +{ +#ifdef linux + struct sockaddr_in addr; + + get_myaddress(&addr); +#if 1 + printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); +#else + addrs[0] = inet_makeaddr(inet_netof(addr.sin_addr), INADDR_ANY); +#endif + return 1; +#else + struct ifconf ifc; + struct ifreq ifreq, *ifr; + struct sockaddr_in *sin; + int n, i; + + ifc.ifc_len = UDPMSGSIZE; + ifc.ifc_buf = buf; + if (ioctl(sock, SIOCGIFCONF, (char *)&ifc) < 0) { + perror("broadcast: ioctl (get interface configuration)"); + return (0); + } + ifr = ifc.ifc_req; + for (i = 0, n = ifc.ifc_len/sizeof (struct ifreq); n > 0; n--, ifr++) { + ifreq = *ifr; + if (ioctl(sock, SIOCGIFFLAGS, (char *)&ifreq) < 0) { + perror("broadcast: ioctl (get interface flags)"); + continue; + } + if ((ifreq.ifr_flags & IFF_BROADCAST) && + (ifreq.ifr_flags & IFF_UP) && + ifr->ifr_addr.sa_family == AF_INET) { + sin = (struct sockaddr_in *)&ifr->ifr_addr; +#ifdef SIOCGIFBRDADDR /* 4.3BSD */ + if (ioctl(sock, SIOCGIFBRDADDR, (char *)&ifreq) < 0) { +#if 1 +printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); +#else + addrs[i++] = inet_makeaddr(inet_netof + (sin->sin_addr.s_addr), INADDR_ANY); +#endif + } else { + addrs[i++] = ((struct sockaddr_in*) + &ifreq.ifr_addr)->sin_addr; + } +#else /* 4.2 BSD */ +#if 1 +printf("%s(%d): no inet_makeaddr()\n", __FILE__, __LINE__); +#else + addrs[i++] = inet_makeaddr(inet_netof + (sin->sin_addr.s_addr), INADDR_ANY); +#endif +#endif + } + } + return (i); +#endif +} + +typedef bool_t (*resultproc_t)(); + +enum clnt_stat +clnt_broadcast(prog, vers, proc, xargs, argsp, xresults, resultsp, eachresult) + u_long prog; /* program number */ + u_long vers; /* version number */ + u_long proc; /* procedure number */ + xdrproc_t xargs; /* xdr routine for args */ + caddr_t argsp; /* pointer to args */ + xdrproc_t xresults; /* xdr routine for results */ + caddr_t resultsp; /* pointer to results */ + resultproc_t eachresult; /* call with each result obtained */ +{ + enum clnt_stat stat; + AUTH *unix_auth = authunix_create_default(); + XDR xdr_stream; + register XDR *xdrs = &xdr_stream; + int outlen, inlen, fromlen, nets; + register int sock; + int on = 1; +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; +#else + int readfds; + register int mask; +#endif /* def FD_SETSIZE */ + register int i; + bool_t done = FALSE; + register u_long xid; + u_long port; + struct in_addr addrs[20]; + struct sockaddr_in baddr, raddr; /* broadcast and response addresses */ + struct rmtcallargs a; + struct rmtcallres r; + struct rpc_msg msg; + struct timeval t; + char outbuf[MAX_BROADCAST_SIZE], inbuf[UDPMSGSIZE]; + + /* + * initialization: create a socket, a broadcast address, and + * preserialize the arguments into a send buffer. + */ + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("Cannot create socket for broadcast rpc"); + stat = RPC_CANTSEND; + goto done_broad; + } +#ifdef SO_BROADCAST + if (setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &on, sizeof (on)) < 0) { + perror("Cannot set socket option SO_BROADCAST"); + stat = RPC_CANTSEND; + goto done_broad; + } +#endif /* def SO_BROADCAST */ +#ifdef FD_SETSIZE + FD_ZERO(&mask); + FD_SET(sock, &mask); +#else + mask = (1 << sock); +#endif /* def FD_SETSIZE */ + nets = getbroadcastnets(addrs, sock, inbuf); + bzero((char *)&baddr, sizeof (baddr)); + baddr.sin_family = AF_INET; + baddr.sin_port = htons(PMAPPORT); + baddr.sin_addr.s_addr = htonl(INADDR_ANY); +/* baddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY); */ + (void)gettimeofday(&t, (struct timezone *)0); + msg.rm_xid = xid = getpid() ^ t.tv_sec ^ t.tv_usec; + t.tv_usec = 0; + msg.rm_direction = CALL; + msg.rm_call.cb_rpcvers = RPC_MSG_VERSION; + msg.rm_call.cb_prog = PMAPPROG; + msg.rm_call.cb_vers = PMAPVERS; + msg.rm_call.cb_proc = PMAPPROC_CALLIT; + msg.rm_call.cb_cred = unix_auth->ah_cred; + msg.rm_call.cb_verf = unix_auth->ah_verf; + a.prog = prog; + a.vers = vers; + a.proc = proc; + a.xdr_args = xargs; + a.args_ptr = argsp; + r.port_ptr = &port; + r.xdr_results = xresults; + r.results_ptr = resultsp; + xdrmem_create(xdrs, outbuf, MAX_BROADCAST_SIZE, XDR_ENCODE); + if ((! xdr_callmsg(xdrs, &msg)) || (! xdr_rmtcall_args(xdrs, &a))) { + stat = RPC_CANTENCODEARGS; + goto done_broad; + } + outlen = (int)xdr_getpos(xdrs); + xdr_destroy(xdrs); + /* + * Basic loop: broadcast a packet and wait a while for response(s). + * The response timeout grows larger per iteration. + */ + for (t.tv_sec = 4; t.tv_sec <= 14; t.tv_sec += 2) { + for (i = 0; i < nets; i++) { + baddr.sin_addr = addrs[i]; + if (sendto(sock, outbuf, outlen, 0, + (struct sockaddr *)&baddr, + sizeof (struct sockaddr)) != outlen) { + perror("Cannot send broadcast packet"); + stat = RPC_CANTSEND; + goto done_broad; + } + } + if (eachresult == NULL) { + stat = RPC_SUCCESS; + goto done_broad; + } + recv_again: + msg.acpted_rply.ar_verf = _null_auth; + msg.acpted_rply.ar_results.where = (caddr_t)&r; + msg.acpted_rply.ar_results.proc = xdr_rmtcallres; + readfds = mask; + switch (select(_rpc_dtablesize(), &readfds, (int *)NULL, + (int *)NULL, &t)) { + + case 0: /* timed out */ + stat = RPC_TIMEDOUT; + continue; + + case -1: /* some kind of error */ + if (errno == EINTR) + goto recv_again; + perror("Broadcast select problem"); + stat = RPC_CANTRECV; + goto done_broad; + + } /* end of select results switch */ + try_again: + fromlen = sizeof(struct sockaddr); + inlen = recvfrom(sock, inbuf, UDPMSGSIZE, 0, + (struct sockaddr *)&raddr, &fromlen); + if (inlen < 0) { + if (errno == EINTR) + goto try_again; + perror("Cannot receive reply to broadcast"); + stat = RPC_CANTRECV; + goto done_broad; + } + if (inlen < sizeof(u_long)) + goto recv_again; + /* + * see if reply transaction id matches sent id. + * If so, decode the results. + */ + xdrmem_create(xdrs, inbuf, (u_int)inlen, XDR_DECODE); + if (xdr_replymsg(xdrs, &msg)) { + if ((msg.rm_xid == xid) && + (msg.rm_reply.rp_stat == MSG_ACCEPTED) && + (msg.acpted_rply.ar_stat == SUCCESS)) { + raddr.sin_port = htons((u_short)port); + done = (*eachresult)(resultsp, &raddr); + } + /* otherwise, we just ignore the errors ... */ + } else { +#ifdef notdef + /* some kind of deserialization problem ... */ + if (msg.rm_xid == xid) + fprintf(stderr, "Broadcast deserialization problem"); + /* otherwise, just random garbage */ +#endif + } + xdrs->x_op = XDR_FREE; + msg.acpted_rply.ar_results.proc = xdr_void; + (void)xdr_replymsg(xdrs, &msg); + (void)(*xresults)(xdrs, resultsp); + xdr_destroy(xdrs); + if (done) { + stat = RPC_SUCCESS; + goto done_broad; + } else { + goto recv_again; + } + } +done_broad: + (void)close(sock); + AUTH_DESTROY(unix_auth); + return (stat); +} + diff --git a/libc/inet/rpc/rpc_callmsg.c b/libc/inet/rpc/rpc_callmsg.c new file mode 100644 index 000000000..d9d815a6f --- /dev/null +++ b/libc/inet/rpc/rpc_callmsg.c @@ -0,0 +1,190 @@ +/* @(#)rpc_callmsg.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_callmsg.c 1.4 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * rpc_callmsg.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + */ + +#include <sys/param.h> + +#include <rpc/rpc.h> + +/* + * XDR a call message + */ +bool_t +xdr_callmsg(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + register long *buf; + register struct opaque_auth *oa; + + if (xdrs->x_op == XDR_ENCODE) { + if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_cred.oa_length) + + 2 * BYTES_PER_XDR_UNIT + + RNDUP(cmsg->rm_call.cb_verf.oa_length)); + if (buf != NULL) { + IXDR_PUT_LONG(buf, cmsg->rm_xid); + IXDR_PUT_ENUM(buf, cmsg->rm_direction); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_rpcvers); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_prog); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_vers); + IXDR_PUT_LONG(buf, cmsg->rm_call.cb_proc); + oa = &cmsg->rm_call.cb_cred; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + buf += RNDUP(oa->oa_length) / sizeof (long); + } + oa = &cmsg->rm_call.cb_verf; + IXDR_PUT_ENUM(buf, oa->oa_flavor); + IXDR_PUT_LONG(buf, oa->oa_length); + if (oa->oa_length) { + bcopy(oa->oa_base, (caddr_t)buf, oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / sizeof (long); + */ + } + return (TRUE); + } + } + if (xdrs->x_op == XDR_DECODE) { + buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT); + if (buf != NULL) { + cmsg->rm_xid = IXDR_GET_LONG(buf); + cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type); + if (cmsg->rm_direction != CALL) { + return (FALSE); + } + cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf); + if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) { + return (FALSE); + } + cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf); + cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf); + oa = &cmsg->rm_call.cb_cred; + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need.... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + oa = &cmsg->rm_call.cb_verf; + buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT); + if (buf == NULL) { + if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE || + xdr_u_int(xdrs, &oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t); + oa->oa_length = IXDR_GET_LONG(buf); + } + if (oa->oa_length) { + if (oa->oa_length > MAX_AUTH_BYTES) { + return (FALSE); + } + if (oa->oa_base == NULL) { + oa->oa_base = (caddr_t) + mem_alloc(oa->oa_length); + } + buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length)); + if (buf == NULL) { + if (xdr_opaque(xdrs, oa->oa_base, + oa->oa_length) == FALSE) { + return (FALSE); + } + } else { + bcopy((caddr_t)buf, oa->oa_base, + oa->oa_length); + /* no real need... + buf += RNDUP(oa->oa_length) / + sizeof (long); + */ + } + } + return (TRUE); + } + } + if ( + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + (cmsg->rm_direction == CALL) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + (cmsg->rm_call.cb_rpcvers == RPC_MSG_VERSION) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_proc)) && + xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_cred)) ) + return (xdr_opaque_auth(xdrs, &(cmsg->rm_call.cb_verf))); + return (FALSE); +} + diff --git a/libc/inet/rpc/rpc_commondata.c b/libc/inet/rpc/rpc_commondata.c new file mode 100644 index 000000000..75cead087 --- /dev/null +++ b/libc/inet/rpc/rpc_commondata.c @@ -0,0 +1,41 @@ +/* @(#)rpc_commondata.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#include <rpc/rpc.h> +/* + * This file should only contain common data (global data) that is exported + * by public interfaces + */ +struct opaque_auth _null_auth; +#ifdef FD_SETSIZE +fd_set svc_fdset; +#else +int svc_fds; +#endif /* def FD_SETSIZE */ +struct rpc_createerr rpc_createerr; diff --git a/libc/inet/rpc/rpc_dtablesize.c b/libc/inet/rpc/rpc_dtablesize.c new file mode 100644 index 000000000..a8488172e --- /dev/null +++ b/libc/inet/rpc/rpc_dtablesize.c @@ -0,0 +1,46 @@ +/* @(#)rpc_dtablesize.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_dtablesize.c 1.2 87/08/11 Copyr 1987 Sun Micro"; +#endif + +/* + * Cache the result of getdtablesize(), so we don't have to do an + * expensive system call every time. + */ +_rpc_dtablesize() +{ + static int size; + + if (size == 0) { + size = getdtablesize(); + } + return (size); +} diff --git a/libc/inet/rpc/rpc_prot.c b/libc/inet/rpc/rpc_prot.c new file mode 100644 index 000000000..4b1319ad5 --- /dev/null +++ b/libc/inet/rpc/rpc_prot.c @@ -0,0 +1,289 @@ +/* @(#)rpc_prot.c 2.3 88/08/07 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)rpc_prot.c 1.36 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * rpc_prot.c + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements the rpc message definition, + * its serializer and some common rpc utility routines. + * The routines are meant for various implementations of rpc - + * they are NOT for the rpc client or rpc service implementations! + * Because authentication stuff is easy and is part of rpc, the opaque + * routines are also in this program. + */ + +#include <sys/param.h> + +#include <rpc/rpc.h> + +/* * * * * * * * * * * * * * XDR Authentication * * * * * * * * * * * */ + +struct opaque_auth _null_auth; + +/* + * XDR an opaque authentication struct + * (see auth.h) + */ +bool_t +xdr_opaque_auth(xdrs, ap) + register XDR *xdrs; + register struct opaque_auth *ap; +{ + + if (xdr_enum(xdrs, &(ap->oa_flavor))) + return (xdr_bytes(xdrs, &ap->oa_base, + &ap->oa_length, MAX_AUTH_BYTES)); + return (FALSE); +} + +/* + * XDR a DES block + */ +bool_t +xdr_des_block(xdrs, blkp) + register XDR *xdrs; + register des_block *blkp; +{ + return (xdr_opaque(xdrs, (caddr_t)blkp, sizeof(des_block))); +} + +/* * * * * * * * * * * * * * XDR RPC MESSAGE * * * * * * * * * * * * * * * */ + +/* + * XDR the MSG_ACCEPTED part of a reply message union + */ +bool_t +xdr_accepted_reply(xdrs, ar) + register XDR *xdrs; + register struct accepted_reply *ar; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_opaque_auth(xdrs, &(ar->ar_verf))) + return (FALSE); + if (! xdr_enum(xdrs, (enum_t *)&(ar->ar_stat))) + return (FALSE); + switch (ar->ar_stat) { + + case SUCCESS: + return ((*(ar->ar_results.proc))(xdrs, ar->ar_results.where)); + + case PROG_MISMATCH: + if (! xdr_u_long(xdrs, &(ar->ar_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(ar->ar_vers.high))); + } + return (TRUE); /* TRUE => open ended set of problems */ +} + +/* + * XDR the MSG_DENIED part of a reply message union + */ +bool_t +xdr_rejected_reply(xdrs, rr) + register XDR *xdrs; + register struct rejected_reply *rr; +{ + + /* personalized union, rather than calling xdr_union */ + if (! xdr_enum(xdrs, (enum_t *)&(rr->rj_stat))) + return (FALSE); + switch (rr->rj_stat) { + + case RPC_MISMATCH: + if (! xdr_u_long(xdrs, &(rr->rj_vers.low))) + return (FALSE); + return (xdr_u_long(xdrs, &(rr->rj_vers.high))); + + case AUTH_ERROR: + return (xdr_enum(xdrs, (enum_t *)&(rr->rj_why))); + } + return (FALSE); +} + +static struct xdr_discrim reply_dscrm[3] = { + { (int)MSG_ACCEPTED, xdr_accepted_reply }, + { (int)MSG_DENIED, xdr_rejected_reply }, + { __dontcare__, NULL_xdrproc_t } }; + +/* + * XDR a reply message + */ +bool_t +xdr_replymsg(xdrs, rmsg) + register XDR *xdrs; + register struct rpc_msg *rmsg; +{ + if ( + xdr_u_long(xdrs, &(rmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(rmsg->rm_direction)) && + (rmsg->rm_direction == REPLY) ) + return (xdr_union(xdrs, (enum_t *)&(rmsg->rm_reply.rp_stat), + (caddr_t)&(rmsg->rm_reply.ru), reply_dscrm, NULL_xdrproc_t)); + return (FALSE); +} + + +/* + * Serializes the "static part" of a call message header. + * The fields include: rm_xid, rm_direction, rpcvers, prog, and vers. + * The rm_xid is not really static, but the user can easily munge on the fly. + */ +bool_t +xdr_callhdr(xdrs, cmsg) + register XDR *xdrs; + register struct rpc_msg *cmsg; +{ + + cmsg->rm_direction = CALL; + cmsg->rm_call.cb_rpcvers = RPC_MSG_VERSION; + if ( + (xdrs->x_op == XDR_ENCODE) && + xdr_u_long(xdrs, &(cmsg->rm_xid)) && + xdr_enum(xdrs, (enum_t *)&(cmsg->rm_direction)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_rpcvers)) && + xdr_u_long(xdrs, &(cmsg->rm_call.cb_prog)) ) + return (xdr_u_long(xdrs, &(cmsg->rm_call.cb_vers))); + return (FALSE); +} + +/* ************************** Client utility routine ************* */ + +static void +accepted(acpt_stat, error) + register enum accept_stat acpt_stat; + register struct rpc_err *error; +{ + + switch (acpt_stat) { + + case PROG_UNAVAIL: + error->re_status = RPC_PROGUNAVAIL; + return; + + case PROG_MISMATCH: + error->re_status = RPC_PROGVERSMISMATCH; + return; + + case PROC_UNAVAIL: + error->re_status = RPC_PROCUNAVAIL; + return; + + case GARBAGE_ARGS: + error->re_status = RPC_CANTDECODEARGS; + return; + + case SYSTEM_ERR: + error->re_status = RPC_SYSTEMERROR; + return; + + case SUCCESS: + error->re_status = RPC_SUCCESS; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_ACCEPTED; + error->re_lb.s2 = (long)acpt_stat; +} + +static void +rejected(rjct_stat, error) + register enum reject_stat rjct_stat; + register struct rpc_err *error; +{ + + switch (rjct_stat) { + + case RPC_VERSMISMATCH: + error->re_status = RPC_VERSMISMATCH; + return; + + case AUTH_ERROR: + error->re_status = RPC_AUTHERROR; + return; + } + /* something's wrong, but we don't know what ... */ + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)MSG_DENIED; + error->re_lb.s2 = (long)rjct_stat; +} + +/* + * given a reply message, fills in the error + */ +void +_seterr_reply(msg, error) + register struct rpc_msg *msg; + register struct rpc_err *error; +{ + + /* optimized for normal, SUCCESSful case */ + switch (msg->rm_reply.rp_stat) { + + case MSG_ACCEPTED: + if (msg->acpted_rply.ar_stat == SUCCESS) { + error->re_status = RPC_SUCCESS; + return; + }; + accepted(msg->acpted_rply.ar_stat, error); + break; + + case MSG_DENIED: + rejected(msg->rjcted_rply.rj_stat, error); + break; + + default: + error->re_status = RPC_FAILED; + error->re_lb.s1 = (long)(msg->rm_reply.rp_stat); + break; + } + switch (error->re_status) { + + case RPC_VERSMISMATCH: + error->re_vers.low = msg->rjcted_rply.rj_vers.low; + error->re_vers.high = msg->rjcted_rply.rj_vers.high; + break; + + case RPC_AUTHERROR: + error->re_why = msg->rjcted_rply.rj_why; + break; + + case RPC_PROGVERSMISMATCH: + error->re_vers.low = msg->acpted_rply.ar_vers.low; + error->re_vers.high = msg->acpted_rply.ar_vers.high; + break; + } +} diff --git a/libc/inet/rpc/svc.c b/libc/inet/rpc/svc.c new file mode 100644 index 000000000..feac64628 --- /dev/null +++ b/libc/inet/rpc/svc.c @@ -0,0 +1,492 @@ +/* @(#)svc.c 2.4 88/08/11 4.0 RPCSRC; from 1.44 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc.c 1.41 87/10/13 Copyr 1984 Sun Micro"; +#endif + +/* + * svc.c, Server-side remote procedure call interface. + * + * There are two sets of procedures here. The xprt routines are + * for handling transport handles. The svc routines handle the + * list of service routines. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <sys/errno.h> +#include <rpc/rpc.h> +#include <rpc/pmap_clnt.h> +#ifdef linux +#include <sys/types.h> +#endif + +extern int errno; + +#ifdef FD_SETSIZE +static SVCXPRT **xports; +#else +#define NOFILE 32 + +static SVCXPRT *xports[NOFILE]; +#endif /* def FD_SETSIZE */ + +#define NULL_SVC ((struct svc_callout *)0) +#define RQCRED_SIZE 400 /* this size is excessive */ + +/* + * The services list + * Each entry represents a set of procedures (an rpc program). + * The dispatch routine takes request structs and runs the + * apropriate procedure. + */ +static struct svc_callout { + struct svc_callout *sc_next; + u_long sc_prog; + u_long sc_vers; + void (*sc_dispatch)(); +} *svc_head; + +static struct svc_callout *svc_find(); + +/* *************** SVCXPRT related stuff **************** */ + +/* + * Activate a transport handle. + */ +void +xprt_register(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + +#ifdef FD_SETSIZE + if (xports == NULL) { + xports = (SVCXPRT **) + mem_alloc(FD_SETSIZE * sizeof(SVCXPRT *)); + } + if (sock < _rpc_dtablesize()) { + xports[sock] = xprt; + FD_SET(sock, &svc_fdset); + } +#else + if (sock < NOFILE) { + xports[sock] = xprt; + svc_fds |= (1 << sock); + } +#endif /* def FD_SETSIZE */ + +} + +/* + * De-activate a transport handle. + */ +void +xprt_unregister(xprt) + SVCXPRT *xprt; +{ + register int sock = xprt->xp_sock; + +#ifdef FD_SETSIZE + if ((sock < _rpc_dtablesize()) && (xports[sock] == xprt)) { + xports[sock] = (SVCXPRT *)0; + FD_CLR(sock, &svc_fdset); + } +#else + if ((sock < NOFILE) && (xports[sock] == xprt)) { + xports[sock] = (SVCXPRT *)0; + svc_fds &= ~(1 << sock); + } +#endif /* def FD_SETSIZE */ +} + + +/* ********************** CALLOUT list related stuff ************* */ + +/* + * Add a service program to the callout list. + * The dispatch routine will be called when a rpc request for this + * program number comes in. + */ +bool_t +svc_register(xprt, prog, vers, dispatch, protocol) + SVCXPRT *xprt; + u_long prog; + u_long vers; + void (*dispatch)(); + int protocol; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) != NULL_SVC) { + if (s->sc_dispatch == dispatch) + goto pmap_it; /* he is registering another xptr */ + return (FALSE); + } + s = (struct svc_callout *)mem_alloc(sizeof(struct svc_callout)); + if (s == (struct svc_callout *)0) { + return (FALSE); + } + s->sc_prog = prog; + s->sc_vers = vers; + s->sc_dispatch = dispatch; + s->sc_next = svc_head; + svc_head = s; +pmap_it: + /* now register the information with the local binder service */ + if (protocol) { + return (pmap_set(prog, vers, protocol, xprt->xp_port)); + } + return (TRUE); +} + +/* + * Remove a service program from the callout list. + */ +void +svc_unregister(prog, vers) + u_long prog; + u_long vers; +{ + struct svc_callout *prev; + register struct svc_callout *s; + + if ((s = svc_find(prog, vers, &prev)) == NULL_SVC) + return; + if (prev == NULL_SVC) { + svc_head = s->sc_next; + } else { + prev->sc_next = s->sc_next; + } + s->sc_next = NULL_SVC; + mem_free((char *) s, (u_int) sizeof(struct svc_callout)); + /* now unregister the information with the local binder service */ + (void)pmap_unset(prog, vers); +} + +/* + * Search the callout list for a program number, return the callout + * struct. + */ +static struct svc_callout * +svc_find(prog, vers, prev) + u_long prog; + u_long vers; + struct svc_callout **prev; +{ + register struct svc_callout *s, *p; + + p = NULL_SVC; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if ((s->sc_prog == prog) && (s->sc_vers == vers)) + goto done; + p = s; + } +done: + *prev = p; + return (s); +} + +/* ******************* REPLY GENERATION ROUTINES ************ */ + +/* + * Send a reply to an rpc request + */ +bool_t +svc_sendreply(xprt, xdr_results, xdr_location) + register SVCXPRT *xprt; + xdrproc_t xdr_results; + caddr_t xdr_location; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SUCCESS; + rply.acpted_rply.ar_results.where = xdr_location; + rply.acpted_rply.ar_results.proc = xdr_results; + return (SVC_REPLY(xprt, &rply)); +} + +/* + * No procedure error reply + */ +void +svcerr_noproc(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROC_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Can't decode args error reply + */ +void +svcerr_decode(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = GARBAGE_ARGS; + SVC_REPLY(xprt, &rply); +} + +/* + * Some system error + */ +void +svcerr_systemerr(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = SYSTEM_ERR; + SVC_REPLY(xprt, &rply); +} + +/* + * Authentication error reply + */ +void +svcerr_auth(xprt, why) + SVCXPRT *xprt; + enum auth_stat why; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_DENIED; + rply.rjcted_rply.rj_stat = AUTH_ERROR; + rply.rjcted_rply.rj_why = why; + SVC_REPLY(xprt, &rply); +} + +/* + * Auth too weak error reply + */ +void +svcerr_weakauth(xprt) + SVCXPRT *xprt; +{ + + svcerr_auth(xprt, AUTH_TOOWEAK); +} + +/* + * Program unavailable error reply + */ +void +svcerr_noprog(xprt) + register SVCXPRT *xprt; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_UNAVAIL; + SVC_REPLY(xprt, &rply); +} + +/* + * Program version mismatch error reply + */ +void +svcerr_progvers(xprt, low_vers, high_vers) + register SVCXPRT *xprt; + u_long low_vers; + u_long high_vers; +{ + struct rpc_msg rply; + + rply.rm_direction = REPLY; + rply.rm_reply.rp_stat = MSG_ACCEPTED; + rply.acpted_rply.ar_verf = xprt->xp_verf; + rply.acpted_rply.ar_stat = PROG_MISMATCH; + rply.acpted_rply.ar_vers.low = low_vers; + rply.acpted_rply.ar_vers.high = high_vers; + SVC_REPLY(xprt, &rply); +} + +/* ******************* SERVER INPUT STUFF ******************* */ + +/* + * Get server side input from some transport. + * + * Statement of authentication parameters management: + * This function owns and manages all authentication parameters, specifically + * the "raw" parameters (msg.rm_call.cb_cred and msg.rm_call.cb_verf) and + * the "cooked" credentials (rqst->rq_clntcred). + * However, this function does not know the structure of the cooked + * credentials, so it make the following assumptions: + * a) the structure is contiguous (no pointers), and + * b) the cred structure size does not exceed RQCRED_SIZE bytes. + * In all events, all three parameters are freed upon exit from this routine. + * The storage is trivially management on the call stack in user land, but + * is mallocated in kernel land. + */ + +void +svc_getreq(rdfds) + int rdfds; +{ +#ifdef FD_SETSIZE + fd_set readfds; + + FD_ZERO(&readfds); +/*#ifdef linux*/ +#if 0 + readfds = rdfds; +#else + readfds.fds_bits[0] = rdfds; +#endif + svc_getreqset(&readfds); +#else + int readfds = rdfds & svc_fds; + + svc_getreqset(&readfds); +#endif /* def FD_SETSIZE */ +} + +void +svc_getreqset(readfds) +#ifdef FD_SETSIZE + fd_set *readfds; +{ +#else + int *readfds; +{ + int readfds_local = *readfds; +#endif /* def FD_SETSIZE */ + enum xprt_stat stat; + struct rpc_msg msg; + int prog_found; + u_long low_vers; + u_long high_vers; + struct svc_req r; + register SVCXPRT *xprt; + register u_long mask; + register int bit; + register u_long *maskp; + register int setsize; + register int sock; + char cred_area[2*MAX_AUTH_BYTES + RQCRED_SIZE]; + msg.rm_call.cb_cred.oa_base = cred_area; + msg.rm_call.cb_verf.oa_base = &(cred_area[MAX_AUTH_BYTES]); + r.rq_clntcred = &(cred_area[2*MAX_AUTH_BYTES]); + + +#ifdef FD_SETSIZE + setsize = _rpc_dtablesize(); +#ifdef linux +/*#define NFDBITS 32*/ + maskp = (u_long *)readfds; +#else + maskp = (u_long *)readfds->fds_bits; +#endif + for (sock = 0; sock < setsize; sock += NFDBITS) { + for (mask = *maskp++; bit = ffs(mask); mask ^= (1 << (bit - 1))) { + /* sock has input waiting */ + xprt = xports[sock + bit - 1]; +#else + for (sock = 0; readfds_local != 0; sock++, readfds_local >>= 1) { + if ((readfds_local & 1) != 0) { + /* sock has input waiting */ + xprt = xports[sock]; +#endif /* def FD_SETSIZE */ + /* now receive msgs from xprtprt (support batch calls) */ + do { + if (SVC_RECV(xprt, &msg)) { + + /* now find the exported program and call it */ + register struct svc_callout *s; + enum auth_stat why; + + r.rq_xprt = xprt; + r.rq_prog = msg.rm_call.cb_prog; + r.rq_vers = msg.rm_call.cb_vers; + r.rq_proc = msg.rm_call.cb_proc; + r.rq_cred = msg.rm_call.cb_cred; + /* first authenticate the message */ + if ((why= _authenticate(&r, &msg)) != AUTH_OK) { + svcerr_auth(xprt, why); + goto call_done; + } + /* now match message with a registered service*/ + prog_found = FALSE; + low_vers = 0 - 1; + high_vers = 0; + for (s = svc_head; s != NULL_SVC; s = s->sc_next) { + if (s->sc_prog == r.rq_prog) { + if (s->sc_vers == r.rq_vers) { + (*s->sc_dispatch)(&r, xprt); + goto call_done; + } /* found correct version */ + prog_found = TRUE; + if (s->sc_vers < low_vers) + low_vers = s->sc_vers; + if (s->sc_vers > high_vers) + high_vers = s->sc_vers; + } /* found correct program */ + } + /* + * if we got here, the program or version + * is not served ... + */ + if (prog_found) + svcerr_progvers(xprt, + low_vers, high_vers); + else + svcerr_noprog(xprt); + /* Fall through to ... */ + } + call_done: + if ((stat = SVC_STAT(xprt)) == XPRT_DIED){ + SVC_DESTROY(xprt); + break; + } + } while (stat == XPRT_MOREREQS); + } + } +} diff --git a/libc/inet/rpc/svc_auth.c b/libc/inet/rpc/svc_auth.c new file mode 100644 index 000000000..ab7ab6942 --- /dev/null +++ b/libc/inet/rpc/svc_auth.c @@ -0,0 +1,114 @@ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_auth.c 2.1 88/08/07 4.0 RPCSRC; from 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * svc_auth_nodes.c, Server-side rpc authenticator interface, + * *WITHOUT* DES authentication. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> + +/* + * svcauthsw is the bdevsw of server side authentication. + * + * Server side authenticators are called from authenticate by + * using the client auth struct flavor field to index into svcauthsw. + * The server auth flavors must implement a routine that looks + * like: + * + * enum auth_stat + * flavorx_auth(rqst, msg) + * register struct svc_req *rqst; + * register struct rpc_msg *msg; + * + */ + +enum auth_stat _svcauth_null(); /* no authentication */ +enum auth_stat _svcauth_unix(); /* unix style (uid, gids) */ +enum auth_stat _svcauth_short(); /* short hand unix style */ + +static struct { + enum auth_stat (*authenticator)(); +} svcauthsw[] = { + _svcauth_null, /* AUTH_NULL */ + _svcauth_unix, /* AUTH_UNIX */ + _svcauth_short, /* AUTH_SHORT */ +}; +#define AUTH_MAX 2 /* HIGHEST AUTH NUMBER */ + + +/* + * The call rpc message, msg has been obtained from the wire. The msg contains + * the raw form of credentials and verifiers. authenticate returns AUTH_OK + * if the msg is successfully authenticated. If AUTH_OK then the routine also + * does the following things: + * set rqst->rq_xprt->verf to the appropriate response verifier; + * sets rqst->rq_client_cred to the "cooked" form of the credentials. + * + * NB: rqst->rq_cxprt->verf must be pre-alloctaed; + * its length is set appropriately. + * + * The caller still owns and is responsible for msg->u.cmb.cred and + * msg->u.cmb.verf. The authentication system retains ownership of + * rqst->rq_client_cred, the cooked credentials. + * + * There is an assumption that any flavour less than AUTH_NULL is + * invalid. + */ +enum auth_stat +_authenticate(rqst, msg) + register struct svc_req *rqst; + struct rpc_msg *msg; +{ + register int cred_flavor; + + rqst->rq_cred = msg->rm_call.cb_cred; + rqst->rq_xprt->xp_verf.oa_flavor = _null_auth.oa_flavor; + rqst->rq_xprt->xp_verf.oa_length = 0; + cred_flavor = rqst->rq_cred.oa_flavor; + if ((cred_flavor <= AUTH_MAX) && (cred_flavor >= AUTH_NULL)) { + return ((*(svcauthsw[cred_flavor].authenticator))(rqst, msg)); + } + + return (AUTH_REJECTEDCRED); +} + +enum auth_stat +_svcauth_null(/*rqst, msg*/) + /*struct svc_req *rqst; + struct rpc_msg *msg;*/ +{ + + return (AUTH_OK); +} diff --git a/libc/inet/rpc/svc_auth_unix.c b/libc/inet/rpc/svc_auth_unix.c new file mode 100644 index 000000000..ea00b7895 --- /dev/null +++ b/libc/inet/rpc/svc_auth_unix.c @@ -0,0 +1,134 @@ +/* @(#)svc_auth_unix.c 2.3 88/08/01 4.0 RPCSRC; from 1.28 88/02/08 SMI */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_auth_unix.c 1.28 88/02/08 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_auth_unix.c + * Handles UNIX flavor authentication parameters on the service side of rpc. + * There are two svc auth implementations here: AUTH_UNIX and AUTH_SHORT. + * _svcauth_unix does full blown unix style uid,gid+gids auth, + * _svcauth_short uses a shorthand auth to index into a cache of longhand auths. + * Note: the shorthand has been gutted for efficiency. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> + +/* + * Unix longhand authenticator + */ +enum auth_stat +_svcauth_unix(rqst, msg) + register struct svc_req *rqst; + register struct rpc_msg *msg; +{ + register enum auth_stat stat; + XDR xdrs; + register struct authunix_parms *aup; + register long *buf; + struct area { + struct authunix_parms area_aup; + char area_machname[MAX_MACHINE_NAME+1]; + int area_gids[NGRPS]; + } *area; + u_int auth_len; + int str_len, gid_len; + register int i; + + area = (struct area *) rqst->rq_clntcred; + aup = &area->area_aup; + aup->aup_machname = area->area_machname; + aup->aup_gids = area->area_gids; + auth_len = (u_int)msg->rm_call.cb_cred.oa_length; + xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE); + buf = XDR_INLINE(&xdrs, auth_len); + if (buf != NULL) { + aup->aup_time = IXDR_GET_LONG(buf); + str_len = IXDR_GET_U_LONG(buf); + if (str_len > MAX_MACHINE_NAME) { + stat = AUTH_BADCRED; + goto done; + } + bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len); + aup->aup_machname[str_len] = 0; + str_len = RNDUP(str_len); + buf += str_len / sizeof (long); + aup->aup_uid = IXDR_GET_LONG(buf); + aup->aup_gid = IXDR_GET_LONG(buf); + gid_len = IXDR_GET_U_LONG(buf); + if (gid_len > NGRPS) { + stat = AUTH_BADCRED; + goto done; + } + aup->aup_len = gid_len; + for (i = 0; i < gid_len; i++) { + aup->aup_gids[i] = IXDR_GET_LONG(buf); + } + /* + * five is the smallest unix credentials structure - + * timestamp, hostname len (0), uid, gid, and gids len (0). + */ + if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) { + (void) printf("bad auth_len gid %d str %d auth %d\n", + gid_len, str_len, auth_len); + stat = AUTH_BADCRED; + goto done; + } + } else if (! xdr_authunix_parms(&xdrs, aup)) { + xdrs.x_op = XDR_FREE; + (void)xdr_authunix_parms(&xdrs, aup); + stat = AUTH_BADCRED; + goto done; + } + rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL; + rqst->rq_xprt->xp_verf.oa_length = 0; + stat = AUTH_OK; +done: + XDR_DESTROY(&xdrs); + return (stat); +} + + +/* + * Shorthand unix authenticator + * Looks up longhand in a cache. + */ +/*ARGSUSED*/ +enum auth_stat +_svcauth_short(rqst, msg) + struct svc_req *rqst; + struct rpc_msg *msg; +{ + return (AUTH_REJECTEDCRED); +} diff --git a/libc/inet/rpc/svc_raw.c b/libc/inet/rpc/svc_raw.c new file mode 100644 index 000000000..1170ecec8 --- /dev/null +++ b/libc/inet/rpc/svc_raw.c @@ -0,0 +1,166 @@ +/* @(#)svc_raw.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_raw.c 1.15 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_raw.c, This a toy for simple testing and timing. + * Interface to create an rpc client and server in the same UNIX process. + * This lets us similate rpc and get rpc (round trip) overhead, without + * any interference from the kernal. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <rpc/rpc.h> + + +/* + * This is the "network" that we will be moving data over + */ +static struct svcraw_private { + char _raw_buf[UDPMSGSIZE]; + SVCXPRT server; + XDR xdr_stream; + char verf_body[MAX_AUTH_BYTES]; +} *svcraw_private; + +static bool_t svcraw_recv(); +static enum xprt_stat svcraw_stat(); +static bool_t svcraw_getargs(); +static bool_t svcraw_reply(); +static bool_t svcraw_freeargs(); +static void svcraw_destroy(); + +static struct xp_ops server_ops = { + svcraw_recv, + svcraw_stat, + svcraw_getargs, + svcraw_reply, + svcraw_freeargs, + svcraw_destroy +}; + +SVCXPRT * +svcraw_create() +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) { + srp = (struct svcraw_private *)calloc(1, sizeof (*srp)); + if (srp == 0) + return (0); + } + srp->server.xp_sock = 0; + srp->server.xp_port = 0; + srp->server.xp_ops = &server_ops; + srp->server.xp_verf.oa_base = srp->verf_body; + xdrmem_create(&srp->xdr_stream, srp->_raw_buf, UDPMSGSIZE, XDR_FREE); + return (&srp->server); +} + +static enum xprt_stat +svcraw_stat() +{ + + return (XPRT_IDLE); +} + +static bool_t +svcraw_recv(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (0); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + return (TRUE); +} + +static bool_t +svcraw_reply(xprt, msg) + SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_replymsg(xdrs, msg)) + return (FALSE); + (void)XDR_GETPOS(xdrs); /* called just for overhead */ + return (TRUE); +} + +static bool_t +svcraw_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + + if (srp == 0) + return (FALSE); + return ((*xdr_args)(&srp->xdr_stream, args_ptr)); +} + +static bool_t +svcraw_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register struct svcraw_private *srp = svcraw_private; + register XDR *xdrs; + + if (srp == 0) + return (FALSE); + xdrs = &srp->xdr_stream; + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcraw_destroy() +{ +} diff --git a/libc/inet/rpc/svc_run.c b/libc/inet/rpc/svc_run.c new file mode 100644 index 000000000..c1c3e0478 --- /dev/null +++ b/libc/inet/rpc/svc_run.c @@ -0,0 +1,72 @@ +/* @(#)svc_run.c 2.1 88/07/29 4.0 RPCSRC */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_run.c 1.1 87/10/13 Copyr 1984 Sun Micro"; +#endif + +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ + +/* + * This is the rpc server side idle loop + * Wait for input, call server program. + */ +#include <rpc/rpc.h> +#include <sys/errno.h> + +void +svc_run() +{ +#ifdef FD_SETSIZE + fd_set readfds; +#else + int readfds; +#endif /* def FD_SETSIZE */ + extern int errno; + + for (;;) { +#ifdef FD_SETSIZE + readfds = svc_fdset; +#else + readfds = svc_fds; +#endif /* def FD_SETSIZE */ + switch (select(_rpc_dtablesize(), &readfds, (int *)0, (int *)0, + (struct timeval *)0)) { + case -1: + if (errno == EINTR) { + continue; + } + perror("svc_run: - select failed"); + return; + case 0: + continue; + default: + svc_getreqset(&readfds); + } + } +} diff --git a/libc/inet/rpc/svc_simple.c b/libc/inet/rpc/svc_simple.c new file mode 100644 index 000000000..d6bcbd3c0 --- /dev/null +++ b/libc/inet/rpc/svc_simple.c @@ -0,0 +1,143 @@ +/* @(#)svc_simple.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_simple.c 1.18 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_simple.c + * Simplified front end to rpc. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <netdb.h> + +static struct proglst { + char *(*p_progname)(); + int p_prognum; + int p_procnum; + xdrproc_t p_inproc, p_outproc; + struct proglst *p_nxt; +} *proglst; +static void universal(); +static SVCXPRT *transp; +struct proglst *pl; + +registerrpc(prognum, versnum, procnum, progname, inproc, outproc) + char *(*progname)(); + xdrproc_t inproc, outproc; +{ + + if (procnum == NULLPROC) { + (void) fprintf(stderr, + "can't reassign procedure number %d\n", NULLPROC); + return (-1); + } + if (transp == 0) { + transp = svcudp_create(RPC_ANYSOCK); + if (transp == NULL) { + (void) fprintf(stderr, "couldn't create an rpc server\n"); + return (-1); + } + } + (void) pmap_unset((u_long)prognum, (u_long)versnum); + if (!svc_register(transp, (u_long)prognum, (u_long)versnum, + universal, IPPROTO_UDP)) { + (void) fprintf(stderr, "couldn't register prog %d vers %d\n", + prognum, versnum); + return (-1); + } + pl = (struct proglst *)malloc(sizeof(struct proglst)); + if (pl == NULL) { + (void) fprintf(stderr, "registerrpc: out of memory\n"); + return (-1); + } + pl->p_progname = progname; + pl->p_prognum = prognum; + pl->p_procnum = procnum; + pl->p_inproc = inproc; + pl->p_outproc = outproc; + pl->p_nxt = proglst; + proglst = pl; + return (0); +} + +static void +universal(rqstp, transp) + struct svc_req *rqstp; + SVCXPRT *transp; +{ + int prog, proc; + char *outdata; + char xdrbuf[UDPMSGSIZE]; + struct proglst *pl; + + /* + * enforce "procnum 0 is echo" convention + */ + if (rqstp->rq_proc == NULLPROC) { + if (svc_sendreply(transp, xdr_void, (char *)NULL) == FALSE) { + (void) fprintf(stderr, "xxx\n"); + exit(1); + } + return; + } + prog = rqstp->rq_prog; + proc = rqstp->rq_proc; + for (pl = proglst; pl != NULL; pl = pl->p_nxt) + if (pl->p_prognum == prog && pl->p_procnum == proc) { + /* decode arguments into a CLEAN buffer */ + bzero(xdrbuf, sizeof(xdrbuf)); /* required ! */ + if (!svc_getargs(transp, pl->p_inproc, xdrbuf)) { + svcerr_decode(transp); + return; + } + outdata = (*(pl->p_progname))(xdrbuf); + if (outdata == NULL && pl->p_outproc != xdr_void) + /* there was an error */ + return; + if (!svc_sendreply(transp, pl->p_outproc, outdata)) { + (void) fprintf(stderr, + "trouble replying to prog %d\n", + pl->p_prognum); + exit(1); + } + /* free the decoded arguments */ + (void)svc_freeargs(transp, pl->p_inproc, xdrbuf); + return; + } + (void) fprintf(stderr, "never registered prog %d\n", prog); + exit(1); +} + diff --git a/libc/inet/rpc/svc_tcp.c b/libc/inet/rpc/svc_tcp.c new file mode 100644 index 000000000..2f859476b --- /dev/null +++ b/libc/inet/rpc/svc_tcp.c @@ -0,0 +1,421 @@ +/* @(#)svc_tcp.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_tcp.c 1.21 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_tcp.c, Server side for TCP/IP based RPC. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * Actually implements two flavors of transporter - + * a tcp rendezvouser (a listner and connection establisher) + * and a record/tcp stream. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <errno.h> +/*#ifndef linux*/ +extern bool_t abort(); +/*#endif*/ +extern errno; + +/* + * Ops vector for TCP/IP based rpc service handle + */ +static bool_t svctcp_recv(); +static enum xprt_stat svctcp_stat(); +static bool_t svctcp_getargs(); +static bool_t svctcp_reply(); +static bool_t svctcp_freeargs(); +static void svctcp_destroy(); + +static struct xp_ops svctcp_op = { + svctcp_recv, + svctcp_stat, + svctcp_getargs, + svctcp_reply, + svctcp_freeargs, + svctcp_destroy +}; + +/* + * Ops vector for TCP/IP rendezvous handler + */ +static bool_t rendezvous_request(); +static enum xprt_stat rendezvous_stat(); + +static struct xp_ops svctcp_rendezvous_op = { + rendezvous_request, + rendezvous_stat, + abort, + abort, + abort, + svctcp_destroy +}; + +static int readtcp(), writetcp(); +static SVCXPRT *makefd_xprt(); + +struct tcp_rendezvous { /* kept in xprt->xp_p1 */ + u_int sendsize; + u_int recvsize; +}; + +struct tcp_conn { /* kept in xprt->xp_p1 */ + enum xprt_stat strm_stat; + u_long x_id; + XDR xdrs; + char verf_body[MAX_AUTH_BYTES]; +}; + +/* + * Usage: + * xprt = svctcp_create(sock, send_buf_size, recv_buf_size); + * + * Creates, registers, and returns a (rpc) tcp based transporter. + * Once *xprt is initialized, it is registered as a transporter + * see (svc.h, xprt_register). This routine returns + * a NULL if a problem occurred. + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svctcp_create + * binds it to an arbitrary port. The routine then starts a tcp + * listener on the socket's associated port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * + * Since tcp streams do buffered io similar to stdio, the caller can specify + * how big the send and receive buffers are via the second and third parms; + * 0 => use the system default. + */ +SVCXPRT * +svctcp_create(sock, sendsize, recvsize) + register int sock; + u_int sendsize; + u_int recvsize; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) { + perror("svc_tcp.c - tcp socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if ((getsockname(sock, (struct sockaddr *)&addr, &len) != 0) || + (listen(sock, 2) != 0)) { + perror("svctcp_.c - cannot getsockname or listen"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + r = (struct tcp_rendezvous *)mem_alloc(sizeof(*r)); + if (r == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + r->sendsize = sendsize; + r->recvsize = recvsize; + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void) fprintf(stderr, "svctcp_create: out of memory\n"); + return (NULL); + } + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)r; + xprt->xp_verf = _null_auth; + xprt->xp_ops = &svctcp_rendezvous_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +/* + * Like svtcp_create(), except the routine takes any *open* UNIX file + * descriptor as its first input. + */ +SVCXPRT * +svcfd_create(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + + return (makefd_xprt(fd, sendsize, recvsize)); +} + +static SVCXPRT * +makefd_xprt(fd, sendsize, recvsize) + int fd; + u_int sendsize; + u_int recvsize; +{ + register SVCXPRT *xprt; + register struct tcp_conn *cd; + + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == (SVCXPRT *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + goto done; + } + cd = (struct tcp_conn *)mem_alloc(sizeof(struct tcp_conn)); + if (cd == (struct tcp_conn *)NULL) { + (void) fprintf(stderr, "svc_tcp: makefd_xprt: out of memory\n"); + mem_free((char *) xprt, sizeof(SVCXPRT)); + xprt = (SVCXPRT *)NULL; + goto done; + } + cd->strm_stat = XPRT_IDLE; + xdrrec_create(&(cd->xdrs), sendsize, recvsize, + (caddr_t)xprt, readtcp, writetcp); + xprt->xp_p2 = NULL; + xprt->xp_p1 = (caddr_t)cd; + xprt->xp_verf.oa_base = cd->verf_body; + xprt->xp_addrlen = 0; + xprt->xp_ops = &svctcp_op; /* truely deals with calls */ + xprt->xp_port = 0; /* this is a connection, not a rendezvouser */ + xprt->xp_sock = fd; + xprt_register(xprt); + done: + return (xprt); +} + +static bool_t +rendezvous_request(xprt) + register SVCXPRT *xprt; +{ + int sock; + struct tcp_rendezvous *r; + struct sockaddr_in addr; + int len; + + r = (struct tcp_rendezvous *)xprt->xp_p1; + again: + len = sizeof(struct sockaddr_in); + if ((sock = accept(xprt->xp_sock, (struct sockaddr *)&addr, + &len)) < 0) { + if (errno == EINTR) + goto again; + return (FALSE); + } + /* + * make a new transporter (re-uses xprt) + */ + xprt = makefd_xprt(sock, r->sendsize, r->recvsize); + xprt->xp_raddr = addr; + xprt->xp_addrlen = len; + return (FALSE); /* there is never an rpc msg to be processed */ +} + +static enum xprt_stat +rendezvous_stat() +{ + + return (XPRT_IDLE); +} + +static void +svctcp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct tcp_conn *cd = (struct tcp_conn *)xprt->xp_p1; + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + if (xprt->xp_port != 0) { + /* a rendezvouser socket */ + xprt->xp_port = 0; + } else { + /* an actual connection socket */ + XDR_DESTROY(&(cd->xdrs)); + } + mem_free((caddr_t)cd, sizeof(struct tcp_conn)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + +/* + * All read operations timeout after 35 seconds. + * A timeout is fatal for the connection. + */ +static struct timeval wait_per_try = { 35, 0 }; + +/* + * reads data from the tcp conection. + * any error is fatal and the connection is closed. + * (And a read of zero bytes is a half closed stream => error.) + */ +static int +readtcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + register int len; +{ + register int sock = xprt->xp_sock; +#ifdef FD_SETSIZE + fd_set mask; + fd_set readfds; + + FD_ZERO(&mask); + FD_SET(sock, &mask); +#else + register int mask = 1 << sock; + int readfds; +#endif /* def FD_SETSIZE */ + do { + readfds = mask; + if (select(_rpc_dtablesize(), &readfds, (int*)NULL, (int*)NULL, + &wait_per_try) <= 0) { + if (errno == EINTR) { + continue; + } + goto fatal_err; + } +#ifdef FD_SETSIZE + } while (!FD_ISSET(sock, &readfds)); +#else + } while (readfds != mask); +#endif /* def FD_SETSIZE */ + if ((len = read(sock, buf, len)) > 0) { + return (len); + } +fatal_err: + ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = XPRT_DIED; + return (-1); +} + +/* + * writes data to the tcp connection. + * Any error is fatal and the connection is closed. + */ +static int +writetcp(xprt, buf, len) + register SVCXPRT *xprt; + caddr_t buf; + int len; +{ + register int i, cnt; + + for (cnt = len; cnt > 0; cnt -= i, buf += i) { + if ((i = write(xprt->xp_sock, buf, cnt)) < 0) { + ((struct tcp_conn *)(xprt->xp_p1))->strm_stat = + XPRT_DIED; + return (-1); + } + } + return (len); +} + +static enum xprt_stat +svctcp_stat(xprt) + SVCXPRT *xprt; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + + if (cd->strm_stat == XPRT_DIED) + return (XPRT_DIED); + if (! xdrrec_eof(&(cd->xdrs))) + return (XPRT_MOREREQS); + return (XPRT_IDLE); +} + +static bool_t +svctcp_recv(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + + xdrs->x_op = XDR_DECODE; + (void)xdrrec_skiprecord(xdrs); + if (xdr_callmsg(xdrs, msg)) { + cd->x_id = msg->rm_xid; + return (TRUE); + } + return (FALSE); +} + +static bool_t +svctcp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(((struct tcp_conn *)(xprt->xp_p1))->xdrs), args_ptr)); +} + +static bool_t +svctcp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = + &(((struct tcp_conn *)(xprt->xp_p1))->xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static bool_t +svctcp_reply(xprt, msg) + SVCXPRT *xprt; + register struct rpc_msg *msg; +{ + register struct tcp_conn *cd = + (struct tcp_conn *)(xprt->xp_p1); + register XDR *xdrs = &(cd->xdrs); + register bool_t stat; + + xdrs->x_op = XDR_ENCODE; + msg->rm_xid = cd->x_id; + stat = xdr_replymsg(xdrs, msg); + (void)xdrrec_endofrecord(xdrs, TRUE); + return (stat); +} diff --git a/libc/inet/rpc/svc_udp.c b/libc/inet/rpc/svc_udp.c new file mode 100644 index 000000000..69ef7a1ce --- /dev/null +++ b/libc/inet/rpc/svc_udp.c @@ -0,0 +1,475 @@ +/* @(#)svc_udp.c 2.2 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)svc_udp.c 1.24 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * svc_udp.c, + * Server side for UDP/IP based RPC. (Does some caching in the hopes of + * achieving execute-at-most-once semantics.) + * + * Copyright (C) 1984, Sun Microsystems, Inc. + */ + +#include <stdio.h> +#include <rpc/rpc.h> +#include <sys/socket.h> +#include <errno.h> + + +#define rpc_buffer(xprt) ((xprt)->xp_p1) +#define MAX(a, b) ((a > b) ? a : b) + +static bool_t svcudp_recv(); +static bool_t svcudp_reply(); +static enum xprt_stat svcudp_stat(); +static bool_t svcudp_getargs(); +static bool_t svcudp_freeargs(); +static void svcudp_destroy(); + +static struct xp_ops svcudp_op = { + svcudp_recv, + svcudp_stat, + svcudp_getargs, + svcudp_reply, + svcudp_freeargs, + svcudp_destroy +}; + +extern int errno; + +/* + * kept in xprt->xp_p2 + */ +struct svcudp_data { + u_int su_iosz; /* byte size of send.recv buffer */ + u_long su_xid; /* transaction id */ + XDR su_xdrs; /* XDR handle */ + char su_verfbody[MAX_AUTH_BYTES]; /* verifier body */ + char * su_cache; /* cached data, NULL if no cache */ +}; +#define su_data(xprt) ((struct svcudp_data *)(xprt->xp_p2)) + +/* + * Usage: + * xprt = svcudp_create(sock); + * + * If sock<0 then a socket is created, else sock is used. + * If the socket, sock is not bound to a port then svcudp_create + * binds it to an arbitrary port. In any (successful) case, + * xprt->xp_sock is the registered socket number and xprt->xp_port is the + * associated port number. + * Once *xprt is initialized, it is registered as a transporter; + * see (svc.h, xprt_register). + * The routines returns NULL if a problem occurred. + */ +SVCXPRT * +svcudp_bufcreate(sock, sendsz, recvsz) + register int sock; + u_int sendsz, recvsz; +{ + bool_t madesock = FALSE; + register SVCXPRT *xprt; + register struct svcudp_data *su; + struct sockaddr_in addr; + int len = sizeof(struct sockaddr_in); + + if (sock == RPC_ANYSOCK) { + if ((sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) { + perror("svcudp_create: socket creation problem"); + return ((SVCXPRT *)NULL); + } + madesock = TRUE; + } + bzero((char *)&addr, sizeof (addr)); + addr.sin_family = AF_INET; + if (bindresvport(sock, &addr)) { + addr.sin_port = 0; + (void)bind(sock, (struct sockaddr *)&addr, len); + } + if (getsockname(sock, (struct sockaddr *)&addr, &len) != 0) { + perror("svcudp_create - cannot getsockname"); + if (madesock) + (void)close(sock); + return ((SVCXPRT *)NULL); + } + xprt = (SVCXPRT *)mem_alloc(sizeof(SVCXPRT)); + if (xprt == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su = (struct svcudp_data *)mem_alloc(sizeof(*su)); + if (su == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + su->su_iosz = ((MAX(sendsz, recvsz) + 3) / 4) * 4; + if ((rpc_buffer(xprt) = mem_alloc(su->su_iosz)) == NULL) { + (void)fprintf(stderr, "svcudp_create: out of memory\n"); + return (NULL); + } + xdrmem_create( + &(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_DECODE); + su->su_cache = NULL; + xprt->xp_p2 = (caddr_t)su; + xprt->xp_verf.oa_base = su->su_verfbody; + xprt->xp_ops = &svcudp_op; + xprt->xp_port = ntohs(addr.sin_port); + xprt->xp_sock = sock; + xprt_register(xprt); + return (xprt); +} + +SVCXPRT * +svcudp_create(sock) + int sock; +{ + + return(svcudp_bufcreate(sock, UDPMSGSIZE, UDPMSGSIZE)); +} + +static enum xprt_stat +svcudp_stat(xprt) + SVCXPRT *xprt; +{ + + return (XPRT_IDLE); +} + +static bool_t +svcudp_recv(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int rlen; + char *reply; + u_long replylen; + + again: + xprt->xp_addrlen = sizeof(struct sockaddr_in); + rlen = recvfrom(xprt->xp_sock, rpc_buffer(xprt), (int) su->su_iosz, + 0, (struct sockaddr *)&(xprt->xp_raddr), &(xprt->xp_addrlen)); + if (rlen == -1 && errno == EINTR) + goto again; + if (rlen < 4*sizeof(u_long)) + return (FALSE); + xdrs->x_op = XDR_DECODE; + XDR_SETPOS(xdrs, 0); + if (! xdr_callmsg(xdrs, msg)) + return (FALSE); + su->su_xid = msg->rm_xid; + if (su->su_cache != NULL) { + if (cache_get(xprt, msg, &reply, &replylen)) { + (void) sendto(xprt->xp_sock, reply, (int) replylen, 0, + (struct sockaddr *) &xprt->xp_raddr, xprt->xp_addrlen); + return (TRUE); + } + } + return (TRUE); +} + +static bool_t +svcudp_reply(xprt, msg) + register SVCXPRT *xprt; + struct rpc_msg *msg; +{ + register struct svcudp_data *su = su_data(xprt); + register XDR *xdrs = &(su->su_xdrs); + register int slen; + register bool_t stat = FALSE; + + xdrs->x_op = XDR_ENCODE; + XDR_SETPOS(xdrs, 0); + msg->rm_xid = su->su_xid; + if (xdr_replymsg(xdrs, msg)) { + slen = (int)XDR_GETPOS(xdrs); + if (sendto(xprt->xp_sock, rpc_buffer(xprt), slen, 0, + (struct sockaddr *)&(xprt->xp_raddr), xprt->xp_addrlen) + == slen) { + stat = TRUE; + if (su->su_cache && slen >= 0) { + cache_set(xprt, (u_long) slen); + } + } + } + return (stat); +} + +static bool_t +svcudp_getargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + + return ((*xdr_args)(&(su_data(xprt)->su_xdrs), args_ptr)); +} + +static bool_t +svcudp_freeargs(xprt, xdr_args, args_ptr) + SVCXPRT *xprt; + xdrproc_t xdr_args; + caddr_t args_ptr; +{ + register XDR *xdrs = &(su_data(xprt)->su_xdrs); + + xdrs->x_op = XDR_FREE; + return ((*xdr_args)(xdrs, args_ptr)); +} + +static void +svcudp_destroy(xprt) + register SVCXPRT *xprt; +{ + register struct svcudp_data *su = su_data(xprt); + + xprt_unregister(xprt); + (void)close(xprt->xp_sock); + XDR_DESTROY(&(su->su_xdrs)); + mem_free(rpc_buffer(xprt), su->su_iosz); + mem_free((caddr_t)su, sizeof(struct svcudp_data)); + mem_free((caddr_t)xprt, sizeof(SVCXPRT)); +} + + +/***********this could be a separate file*********************/ + +/* + * Fifo cache for udp server + * Copies pointers to reply buffers into fifo cache + * Buffers are sent again if retransmissions are detected. + */ + +#define SPARSENESS 4 /* 75% sparse */ + +#define CACHE_PERROR(msg) \ + (void) fprintf(stderr,"%s\n", msg) + +#define ALLOC(type, size) \ + (type *) mem_alloc((unsigned) (sizeof(type) * (size))) + +#define BZERO(addr, type, size) \ + bzero((char *) addr, sizeof(type) * (int) (size)) + +/* + * An entry in the cache + */ +typedef struct cache_node *cache_ptr; +struct cache_node { + /* + * Index into cache is xid, proc, vers, prog and address + */ + u_long cache_xid; + u_long cache_proc; + u_long cache_vers; + u_long cache_prog; + struct sockaddr_in cache_addr; + /* + * The cached reply and length + */ + char * cache_reply; + u_long cache_replylen; + /* + * Next node on the list, if there is a collision + */ + cache_ptr cache_next; +}; + + + +/* + * The entire cache + */ +struct udp_cache { + u_long uc_size; /* size of cache */ + cache_ptr *uc_entries; /* hash table of entries in cache */ + cache_ptr *uc_fifo; /* fifo list of entries in cache */ + u_long uc_nextvictim; /* points to next victim in fifo list */ + u_long uc_prog; /* saved program number */ + u_long uc_vers; /* saved version number */ + u_long uc_proc; /* saved procedure number */ + struct sockaddr_in uc_addr; /* saved caller's address */ +}; + + +/* + * the hashing function + */ +#define CACHE_LOC(transp, xid) \ + (xid % (SPARSENESS*((struct udp_cache *) su_data(transp)->su_cache)->uc_size)) + + +/* + * Enable use of the cache. + * Note: there is no disable. + */ +svcudp_enablecache(transp, size) + SVCXPRT *transp; + u_long size; +{ + struct svcudp_data *su = su_data(transp); + struct udp_cache *uc; + + if (su->su_cache != NULL) { + CACHE_PERROR("enablecache: cache already enabled"); + return(0); + } + uc = ALLOC(struct udp_cache, 1); + if (uc == NULL) { + CACHE_PERROR("enablecache: could not allocate cache"); + return(0); + } + uc->uc_size = size; + uc->uc_nextvictim = 0; + uc->uc_entries = ALLOC(cache_ptr, size * SPARSENESS); + if (uc->uc_entries == NULL) { + CACHE_PERROR("enablecache: could not allocate cache data"); + return(0); + } + BZERO(uc->uc_entries, cache_ptr, size * SPARSENESS); + uc->uc_fifo = ALLOC(cache_ptr, size); + if (uc->uc_fifo == NULL) { + CACHE_PERROR("enablecache: could not allocate cache fifo"); + return(0); + } + BZERO(uc->uc_fifo, cache_ptr, size); + su->su_cache = (char *) uc; + return(1); +} + + +/* + * Set an entry in the cache + */ +static +cache_set(xprt, replylen) + SVCXPRT *xprt; + u_long replylen; +{ + register cache_ptr victim; + register cache_ptr *vicp; + register struct svcudp_data *su = su_data(xprt); + struct udp_cache *uc = (struct udp_cache *) su->su_cache; + u_int loc; + char *newbuf; + + /* + * Find space for the new entry, either by + * reusing an old entry, or by mallocing a new one + */ + victim = uc->uc_fifo[uc->uc_nextvictim]; + if (victim != NULL) { + loc = CACHE_LOC(xprt, victim->cache_xid); + for (vicp = &uc->uc_entries[loc]; + *vicp != NULL && *vicp != victim; + vicp = &(*vicp)->cache_next) + ; + if (*vicp == NULL) { + CACHE_PERROR("cache_set: victim not found"); + return; + } + *vicp = victim->cache_next; /* remote from cache */ + newbuf = victim->cache_reply; + } else { + victim = ALLOC(struct cache_node, 1); + if (victim == NULL) { + CACHE_PERROR("cache_set: victim alloc failed"); + return; + } + newbuf = mem_alloc(su->su_iosz); + if (newbuf == NULL) { + CACHE_PERROR("cache_set: could not allocate new rpc_buffer"); + return; + } + } + + /* + * Store it away + */ + victim->cache_replylen = replylen; + victim->cache_reply = rpc_buffer(xprt); + rpc_buffer(xprt) = newbuf; + xdrmem_create(&(su->su_xdrs), rpc_buffer(xprt), su->su_iosz, XDR_ENCODE); + victim->cache_xid = su->su_xid; + victim->cache_proc = uc->uc_proc; + victim->cache_vers = uc->uc_vers; + victim->cache_prog = uc->uc_prog; + victim->cache_addr = uc->uc_addr; + loc = CACHE_LOC(xprt, victim->cache_xid); + victim->cache_next = uc->uc_entries[loc]; + uc->uc_entries[loc] = victim; + uc->uc_fifo[uc->uc_nextvictim++] = victim; + uc->uc_nextvictim %= uc->uc_size; +} + +/* + * Try to get an entry from the cache + * return 1 if found, 0 if not found + */ +static +cache_get(xprt, msg, replyp, replylenp) + SVCXPRT *xprt; + struct rpc_msg *msg; + char **replyp; + u_long *replylenp; +{ + u_int loc; + register cache_ptr ent; + register struct svcudp_data *su = su_data(xprt); + register struct udp_cache *uc = (struct udp_cache *) su->su_cache; + +# define EQADDR(a1, a2) (bcmp((char*)&a1, (char*)&a2, sizeof(a1)) == 0) + + loc = CACHE_LOC(xprt, su->su_xid); + for (ent = uc->uc_entries[loc]; ent != NULL; ent = ent->cache_next) { + if (ent->cache_xid == su->su_xid && + ent->cache_proc == uc->uc_proc && + ent->cache_vers == uc->uc_vers && + ent->cache_prog == uc->uc_prog && + EQADDR(ent->cache_addr, uc->uc_addr)) { + *replyp = ent->cache_reply; + *replylenp = ent->cache_replylen; + return(1); + } + } + /* + * Failed to find entry + * Remember a few things so we can do a set later + */ + uc->uc_proc = msg->rm_call.cb_proc; + uc->uc_vers = msg->rm_call.cb_vers; + uc->uc_prog = msg->rm_call.cb_prog; + uc->uc_addr = xprt->xp_raddr; + return(0); +} + diff --git a/libc/inet/rpc/xdr.c b/libc/inet/rpc/xdr.c new file mode 100644 index 000000000..cc2783813 --- /dev/null +++ b/libc/inet/rpc/xdr.c @@ -0,0 +1,576 @@ +/* @(#)xdr.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr.c 1.35 87/08/12"; +#endif + +/* + * xdr.c, Generic XDR routines implementation. + * + * Copyright (C) 1986, Sun Microsystems, Inc. + * + * These are the "generic" xdr routines used to serialize and de-serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * constants specific to the xdr "protocol" + */ +#define XDR_FALSE ((long) 0) +#define XDR_TRUE ((long) 1) +#define LASTUNSIGNED ((u_int) 0-1) + +/* + * for unit alignment + */ +static char xdr_zero[BYTES_PER_XDR_UNIT] = { 0, 0, 0, 0 }; + +/* + * Free a data structure using XDR + * Not a filter, but a convenient utility nonetheless + */ +void +xdr_free(proc, objp) + xdrproc_t proc; + char *objp; +{ + XDR x; + + x.x_op = XDR_FREE; + (*proc)(&x, objp); +} + +/* + * XDR nothing + */ +bool_t +xdr_void(/* xdrs, addr */) + /* XDR *xdrs; */ + /* caddr_t addr; */ +{ + + return (TRUE); +} + +/* + * XDR integers + */ +bool_t +xdr_int(xdrs, ip) + XDR *xdrs; + int *ip; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)ip)); + return (xdr_long(xdrs, (long *)ip)); +#else + if (sizeof (int) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ip)); + } else { + return (xdr_short(xdrs, (short *)ip)); + } +#endif +} + +/* + * XDR unsigned integers + */ +bool_t +xdr_u_int(xdrs, up) + XDR *xdrs; + u_int *up; +{ + +#ifdef lint + (void) (xdr_short(xdrs, (short *)up)); + return (xdr_u_long(xdrs, (u_long *)up)); +#else + if (sizeof (u_int) == sizeof (u_long)) { + return (xdr_u_long(xdrs, (u_long *)up)); + } else { + return (xdr_short(xdrs, (short *)up)); + } +#endif +} + +/* + * XDR long integers + * same as xdr_u_long - open coded to save a proc call! + */ +bool_t +xdr_long(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, lp)); + + if (xdrs->x_op == XDR_FREE) + return (TRUE); + + return (FALSE); +} + +/* + * XDR unsigned long integers + * same as xdr_long - open coded to save a proc call! + */ +bool_t +xdr_u_long(xdrs, ulp) + register XDR *xdrs; + u_long *ulp; +{ + + if (xdrs->x_op == XDR_DECODE) + return (XDR_GETLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_ENCODE) + return (XDR_PUTLONG(xdrs, (long *)ulp)); + if (xdrs->x_op == XDR_FREE) + return (TRUE); + return (FALSE); +} + +/* + * XDR short integers + */ +bool_t +xdr_short(xdrs, sp) + register XDR *xdrs; + short *sp; +{ + long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (long) *sp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *sp = (short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR unsigned short integers + */ +bool_t +xdr_u_short(xdrs, usp) + register XDR *xdrs; + u_short *usp; +{ + u_long l; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + l = (u_long) *usp; + return (XDR_PUTLONG(xdrs, &l)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &l)) { + return (FALSE); + } + *usp = (u_short) l; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + + +/* + * XDR a char + */ +bool_t +xdr_char(xdrs, cp) + XDR *xdrs; + char *cp; +{ + int i; + + i = (*cp); + if (!xdr_int(xdrs, &i)) { + return (FALSE); + } + *cp = i; + return (TRUE); +} + +/* + * XDR an unsigned char + */ +bool_t +xdr_u_char(xdrs, cp) + XDR *xdrs; + char *cp; +{ + u_int u; + + u = (*cp); + if (!xdr_u_int(xdrs, &u)) { + return (FALSE); + } + *cp = u; + return (TRUE); +} + +/* + * XDR booleans + */ +bool_t +xdr_bool(xdrs, bp) + register XDR *xdrs; + bool_t *bp; +{ + long lb; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + lb = *bp ? XDR_TRUE : XDR_FALSE; + return (XDR_PUTLONG(xdrs, &lb)); + + case XDR_DECODE: + if (!XDR_GETLONG(xdrs, &lb)) { + return (FALSE); + } + *bp = (lb == XDR_FALSE) ? FALSE : TRUE; + return (TRUE); + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * XDR enumerations + */ +bool_t +xdr_enum(xdrs, ep) + XDR *xdrs; + enum_t *ep; +{ +#ifndef lint + enum sizecheck { SIZEVAL }; /* used to find the size of an enum */ + + /* + * enums are treated as ints + */ + if (sizeof (enum sizecheck) == sizeof (long)) { + return (xdr_long(xdrs, (long *)ep)); + } else if (sizeof (enum sizecheck) == sizeof (short)) { + return (xdr_short(xdrs, (short *)ep)); + } else { + return (FALSE); + } +#else + (void) (xdr_short(xdrs, (short *)ep)); + return (xdr_long(xdrs, (long *)ep)); +#endif +} + +/* + * XDR opaque data + * Allows the specification of a fixed size sequence of opaque bytes. + * cp points to the opaque object and cnt gives the byte length. + */ +bool_t +xdr_opaque(xdrs, cp, cnt) + register XDR *xdrs; + caddr_t cp; + register u_int cnt; +{ + register u_int rndup; + static crud[BYTES_PER_XDR_UNIT]; + + /* + * if no data we are done + */ + if (cnt == 0) + return (TRUE); + + /* + * round byte count to full xdr units + */ + rndup = cnt % BYTES_PER_XDR_UNIT; + if (rndup > 0) + rndup = BYTES_PER_XDR_UNIT - rndup; + + if (xdrs->x_op == XDR_DECODE) { + if (!XDR_GETBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_GETBYTES(xdrs, crud, rndup)); + } + + if (xdrs->x_op == XDR_ENCODE) { + if (!XDR_PUTBYTES(xdrs, cp, cnt)) { + return (FALSE); + } + if (rndup == 0) + return (TRUE); + return (XDR_PUTBYTES(xdrs, xdr_zero, rndup)); + } + + if (xdrs->x_op == XDR_FREE) { + return (TRUE); + } + + return (FALSE); +} + +/* + * XDR counted bytes + * *cpp is a pointer to the bytes, *sizep is the count. + * If *cpp is NULL maxsize bytes are allocated + */ +bool_t +xdr_bytes(xdrs, cpp, sizep, maxsize) + register XDR *xdrs; + char **cpp; + register u_int *sizep; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + register u_int nodesize; + + /* + * first deal with the length since xdr bytes are counted + */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + nodesize = *sizep; + if ((nodesize > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) { + *cpp = sp = (char *)mem_alloc(nodesize); + } + if (sp == NULL) { + (void) fprintf(stderr, "xdr_bytes: out of memory\n"); + return (FALSE); + } + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, nodesize)); + + case XDR_FREE: + if (sp != NULL) { + mem_free(sp, nodesize); + *cpp = NULL; + } + return (TRUE); + } + return (FALSE); +} + +/* + * Implemented here due to commonality of the object. + */ +bool_t +xdr_netobj(xdrs, np) + XDR *xdrs; + struct netobj *np; +{ + + return (xdr_bytes(xdrs, &np->n_bytes, &np->n_len, MAX_NETOBJ_SZ)); +} + +/* + * XDR a descriminated union + * Support routine for discriminated unions. + * You create an array of xdrdiscrim structures, terminated with + * an entry with a null procedure pointer. The routine gets + * the discriminant value and then searches the array of xdrdiscrims + * looking for that value. It calls the procedure given in the xdrdiscrim + * to handle the discriminant. If there is no specific routine a default + * routine may be called. + * If there is no specific or default routine an error is returned. + */ +bool_t +xdr_union(xdrs, dscmp, unp, choices, dfault) + register XDR *xdrs; + enum_t *dscmp; /* enum to decide which arm to work on */ + char *unp; /* the union itself */ + struct xdr_discrim *choices; /* [value, xdr proc] for each arm */ + xdrproc_t dfault; /* default xdr routine */ +{ + register enum_t dscm; + + /* + * we deal with the discriminator; it's an enum + */ + if (! xdr_enum(xdrs, dscmp)) { + return (FALSE); + } + dscm = *dscmp; + + /* + * search choices for a value that matches the discriminator. + * if we find one, execute the xdr routine for that value. + */ + for (; choices->proc != NULL_xdrproc_t; choices++) { + if (choices->value == dscm) + return ((*(choices->proc))(xdrs, unp, LASTUNSIGNED)); + } + + /* + * no match - execute the default xdr routine if there is one + */ + return ((dfault == NULL_xdrproc_t) ? FALSE : + (*dfault)(xdrs, unp, LASTUNSIGNED)); +} + + +/* + * Non-portable xdr primitives. + * Care should be taken when moving these routines to new architectures. + */ + + +/* + * XDR null terminated ASCII strings + * xdr_string deals with "C strings" - arrays of bytes that are + * terminated by a NULL character. The parameter cpp references a + * pointer to storage; If the pointer is null, then the necessary + * storage is allocated. The last parameter is the max allowed length + * of the string as specified by a protocol. + */ +bool_t +xdr_string(xdrs, cpp, maxsize) + register XDR *xdrs; + char **cpp; + u_int maxsize; +{ + register char *sp = *cpp; /* sp is the actual string pointer */ + u_int size; + u_int nodesize; + + /* + * first deal with the length since xdr strings are counted-strings + */ + switch (xdrs->x_op) { + case XDR_FREE: + if (sp == NULL) { + return(TRUE); /* already free */ + } + /* fall through... */ + case XDR_ENCODE: + size = strlen(sp); + break; + } + if (! xdr_u_int(xdrs, &size)) { + return (FALSE); + } + if (size > maxsize) { + return (FALSE); + } + nodesize = size + 1; + + /* + * now deal with the actual bytes + */ + switch (xdrs->x_op) { + + case XDR_DECODE: + if (nodesize == 0) { + return (TRUE); + } + if (sp == NULL) + *cpp = sp = (char *)mem_alloc(nodesize); + if (sp == NULL) { + (void) fprintf(stderr, "xdr_string: out of memory\n"); + return (FALSE); + } + sp[size] = 0; + /* fall into ... */ + + case XDR_ENCODE: + return (xdr_opaque(xdrs, sp, size)); + + case XDR_FREE: + mem_free(sp, nodesize); + *cpp = NULL; + return (TRUE); + } + return (FALSE); +} + +/* + * Wrapper for xdr_string that can be called directly from + * routines like clnt_call + */ +bool_t +xdr_wrapstring(xdrs, cpp) + XDR *xdrs; + char **cpp; +{ + if (xdr_string(xdrs, cpp, LASTUNSIGNED)) { + return (TRUE); + } + return (FALSE); +} diff --git a/libc/inet/rpc/xdr_array.c b/libc/inet/rpc/xdr_array.c new file mode 100644 index 000000000..7c2831ccd --- /dev/null +++ b/libc/inet/rpc/xdr_array.c @@ -0,0 +1,153 @@ +/* @(#)xdr_array.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_array.c 1.10 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_array.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * arrays. See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED ((u_int)0-1) + + +/* + * XDR an array of arbitrary elements + * *addrp is a pointer to the array, *sizep is the number of elements. + * If addrp is NULL (*sizep * elsize) bytes are allocated. + * elsize is the size (in bytes) of each element, and elproc is the + * xdr procedure to call to handle each element of the array. + */ +bool_t +xdr_array(xdrs, addrp, sizep, maxsize, elsize, elproc) + register XDR *xdrs; + caddr_t *addrp; /* array pointer */ + u_int *sizep; /* number of elements */ + u_int maxsize; /* max numberof elements */ + u_int elsize; /* size in bytes of each element */ + xdrproc_t elproc; /* xdr routine to handle each element */ +{ + register u_int i; + register caddr_t target = *addrp; + register u_int c; /* the actual element count */ + register bool_t stat = TRUE; + register u_int nodesize; + + /* like strings, arrays are really counted arrays */ + if (! xdr_u_int(xdrs, sizep)) { + return (FALSE); + } + c = *sizep; + if ((c > maxsize) && (xdrs->x_op != XDR_FREE)) { + return (FALSE); + } + nodesize = c * elsize; + + /* + * if we are deserializing, we may need to allocate an array. + * We also save time by checking for a null array if we are freeing. + */ + if (target == NULL) + switch (xdrs->x_op) { + case XDR_DECODE: + if (c == 0) + return (TRUE); + *addrp = target = mem_alloc(nodesize); + if (target == NULL) { + (void) fprintf(stderr, + "xdr_array: out of memory\n"); + return (FALSE); + } + bzero(target, nodesize); + break; + + case XDR_FREE: + return (TRUE); + } + + /* + * now we xdr each element of array + */ + for (i = 0; (i < c) && stat; i++) { + stat = (*elproc)(xdrs, target, LASTUNSIGNED); + target += elsize; + } + + /* + * the array may need freeing + */ + if (xdrs->x_op == XDR_FREE) { + mem_free(*addrp, nodesize); + *addrp = NULL; + } + return (stat); +} + +/* + * xdr_vector(): + * + * XDR a fixed length array. Unlike variable-length arrays, + * the storage of fixed length arrays is static and unfreeable. + * > basep: base of the array + * > size: size of the array + * > elemsize: size of each element + * > xdr_elem: routine to XDR each element + */ +bool_t +xdr_vector(xdrs, basep, nelem, elemsize, xdr_elem) + register XDR *xdrs; + register char *basep; + register u_int nelem; + register u_int elemsize; + register xdrproc_t xdr_elem; +{ + register u_int i; + register char *elptr; + + elptr = basep; + for (i = 0; i < nelem; i++) { + if (! (*xdr_elem)(xdrs, elptr, LASTUNSIGNED)) { + return(FALSE); + } + elptr += elemsize; + } + return(TRUE); +} + diff --git a/libc/inet/rpc/xdr_float.c b/libc/inet/rpc/xdr_float.c new file mode 100644 index 000000000..ad221a79f --- /dev/null +++ b/libc/inet/rpc/xdr_float.c @@ -0,0 +1,272 @@ +/* @(#)xdr_float.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_float.c 1.12 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_float.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These are the "floating point" xdr routines used to (de)serialize + * most common data items. See xdr.h for more info on the interface to + * xdr. + */ + +#include <stdio.h> + +#include <rpc/types.h> +#include <rpc/xdr.h> + +/* + * NB: Not portable. + * This routine works on Suns (Sky / 68000's) and Vaxen. + */ + +#ifdef linux +/* cheat big time */ +#define sparc +#endif + +#ifdef vax + +/* What IEEE single precision floating point looks like on a Vax */ +struct ieee_single { + unsigned int mantissa: 23; + unsigned int exp : 8; + unsigned int sign : 1; +}; + +/* Vax single precision floating point */ +struct vax_single { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; +}; + +#define VAX_SNG_BIAS 0x81 +#define IEEE_SNG_BIAS 0x7f + +static struct sgl_limits { + struct vax_single s; + struct ieee_single ieee; +} sgl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff }, /* Max Vax */ + { 0x0, 0xff, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0 }, /* Min Vax */ + { 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; +#endif /* vax */ + +bool_t +xdr_float(xdrs, fp) + register XDR *xdrs; + register float *fp; +{ +#if !defined(mc68000) && !defined(sparc) + struct ieee_single is; + struct vax_single vs, *vsp; + struct sgl_limits *lim; + int i; +#endif + switch (xdrs->x_op) { + + case XDR_ENCODE: +#if defined(mc68000) || defined(sparc) + return (XDR_PUTLONG(xdrs, (long *)fp)); +#else + vs = *((struct vax_single *)fp); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((vs.mantissa2 == lim->s.mantissa2) && + (vs.exp == lim->s.exp) && + (vs.mantissa1 == lim->s.mantissa1)) { + is = lim->ieee; + goto shipit; + } + } + is.exp = vs.exp - VAX_SNG_BIAS + IEEE_SNG_BIAS; + is.mantissa = (vs.mantissa1 << 16) | vs.mantissa2; + shipit: + is.sign = vs.sign; + return (XDR_PUTLONG(xdrs, (long *)&is)); +#endif + + case XDR_DECODE: +#if defined(mc68000) || defined(sparc) + return (XDR_GETLONG(xdrs, (long *)fp)); +#else + vsp = (struct vax_single *)fp; + if (!XDR_GETLONG(xdrs, (long *)&is)) + return (FALSE); + for (i = 0, lim = sgl_limits; + i < sizeof(sgl_limits)/sizeof(struct sgl_limits); + i++, lim++) { + if ((is.exp == lim->ieee.exp) && + (is.mantissa == lim->ieee.mantissa)) { + *vsp = lim->s; + goto doneit; + } + } + vsp->exp = is.exp - IEEE_SNG_BIAS + VAX_SNG_BIAS; + vsp->mantissa2 = is.mantissa; + vsp->mantissa1 = (is.mantissa >> 16); + doneit: + vsp->sign = is.sign; + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} + +/* + * This routine works on Suns (Sky / 68000's) and Vaxen. + */ + +#ifdef vax +/* What IEEE double precision floating point looks like on a Vax */ +struct ieee_double { + unsigned int mantissa1 : 20; + unsigned int exp : 11; + unsigned int sign : 1; + unsigned int mantissa2 : 32; +}; + +/* Vax double precision floating point */ +struct vax_double { + unsigned int mantissa1 : 7; + unsigned int exp : 8; + unsigned int sign : 1; + unsigned int mantissa2 : 16; + unsigned int mantissa3 : 16; + unsigned int mantissa4 : 16; +}; + +#define VAX_DBL_BIAS 0x81 +#define IEEE_DBL_BIAS 0x3ff +#define MASK(nbits) ((1 << nbits) - 1) + +static struct dbl_limits { + struct vax_double d; + struct ieee_double ieee; +} dbl_limits[2] = { + {{ 0x7f, 0xff, 0x0, 0xffff, 0xffff, 0xffff }, /* Max Vax */ + { 0x0, 0x7ff, 0x0, 0x0 }}, /* Max IEEE */ + {{ 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, /* Min Vax */ + { 0x0, 0x0, 0x0, 0x0 }} /* Min IEEE */ +}; + +#endif /* vax */ + + +bool_t +xdr_double(xdrs, dp) + register XDR *xdrs; + double *dp; +{ + register long *lp; +#if !defined(mc68000) && !defined(sparc) + struct ieee_double id; + struct vax_double vd; + register struct dbl_limits *lim; + int i; +#endif + + switch (xdrs->x_op) { + + case XDR_ENCODE: +#if defined(mc68000) || defined(sparc) + lp = (long *)dp; +#else + vd = *((struct vax_double *)dp); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((vd.mantissa4 == lim->d.mantissa4) && + (vd.mantissa3 == lim->d.mantissa3) && + (vd.mantissa2 == lim->d.mantissa2) && + (vd.mantissa1 == lim->d.mantissa1) && + (vd.exp == lim->d.exp)) { + id = lim->ieee; + goto shipit; + } + } + id.exp = vd.exp - VAX_DBL_BIAS + IEEE_DBL_BIAS; + id.mantissa1 = (vd.mantissa1 << 13) | (vd.mantissa2 >> 3); + id.mantissa2 = ((vd.mantissa2 & MASK(3)) << 29) | + (vd.mantissa3 << 13) | + ((vd.mantissa4 >> 3) & MASK(13)); + shipit: + id.sign = vd.sign; + lp = (long *)&id; +#endif + return (XDR_PUTLONG(xdrs, lp++) && XDR_PUTLONG(xdrs, lp)); + + case XDR_DECODE: +#if defined(mc68000) || defined(sparc) + lp = (long *)dp; + return (XDR_GETLONG(xdrs, lp++) && XDR_GETLONG(xdrs, lp)); +#else + lp = (long *)&id; + if (!XDR_GETLONG(xdrs, lp++) || !XDR_GETLONG(xdrs, lp)) + return (FALSE); + for (i = 0, lim = dbl_limits; + i < sizeof(dbl_limits)/sizeof(struct dbl_limits); + i++, lim++) { + if ((id.mantissa2 == lim->ieee.mantissa2) && + (id.mantissa1 == lim->ieee.mantissa1) && + (id.exp == lim->ieee.exp)) { + vd = lim->d; + goto doneit; + } + } + vd.exp = id.exp - IEEE_DBL_BIAS + VAX_DBL_BIAS; + vd.mantissa1 = (id.mantissa1 >> 13); + vd.mantissa2 = ((id.mantissa1 & MASK(13)) << 3) | + (id.mantissa2 >> 29); + vd.mantissa3 = (id.mantissa2 >> 13); + vd.mantissa4 = (id.mantissa2 << 3); + doneit: + vd.sign = id.sign; + *dp = *((double *)&vd); + return (TRUE); +#endif + + case XDR_FREE: + return (TRUE); + } + return (FALSE); +} diff --git a/libc/inet/rpc/xdr_mem.c b/libc/inet/rpc/xdr_mem.c new file mode 100644 index 000000000..558d36922 --- /dev/null +++ b/libc/inet/rpc/xdr_mem.c @@ -0,0 +1,184 @@ +/* @(#)xdr_mem.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_mem.c 1.19 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_mem.h, XDR implementation using memory buffers. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * If you have some data to be interpreted as external data representation + * or to be converted to external data representation in a memory buffer, + * then this is the package for you. + * + */ + + +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +static bool_t xdrmem_getlong(); +static bool_t xdrmem_putlong(); +static bool_t xdrmem_getbytes(); +static bool_t xdrmem_putbytes(); +static u_int xdrmem_getpos(); +static bool_t xdrmem_setpos(); +static long * xdrmem_inline(); +static void xdrmem_destroy(); + +static struct xdr_ops xdrmem_ops = { + xdrmem_getlong, + xdrmem_putlong, + xdrmem_getbytes, + xdrmem_putbytes, + xdrmem_getpos, + xdrmem_setpos, + xdrmem_inline, + xdrmem_destroy +}; + +/* + * The procedure xdrmem_create initializes a stream descriptor for a + * memory buffer. + */ +void +xdrmem_create(xdrs, addr, size, op) + register XDR *xdrs; + caddr_t addr; + u_int size; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrmem_ops; + xdrs->x_private = xdrs->x_base = addr; + xdrs->x_handy = size; +} + +static void +xdrmem_destroy(/*xdrs*/) + /*XDR *xdrs;*/ +{ +} + +static bool_t +xdrmem_getlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *lp = (long)ntohl((u_long)(*((long *)(xdrs->x_private)))); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_putlong(xdrs, lp) + register XDR *xdrs; + long *lp; +{ + + if ((xdrs->x_handy -= sizeof(long)) < 0) + return (FALSE); + *(long *)xdrs->x_private = (long)htonl((u_long)(*lp)); + xdrs->x_private += sizeof(long); + return (TRUE); +} + +static bool_t +xdrmem_getbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(xdrs->x_private, addr, len); + xdrs->x_private += len; + return (TRUE); +} + +static bool_t +xdrmem_putbytes(xdrs, addr, len) + register XDR *xdrs; + caddr_t addr; + register u_int len; +{ + + if ((xdrs->x_handy -= len) < 0) + return (FALSE); + bcopy(addr, xdrs->x_private, len); + xdrs->x_private += len; + return (TRUE); +} + +static u_int +xdrmem_getpos(xdrs) + register XDR *xdrs; +{ + + return ((u_int)xdrs->x_private - (u_int)xdrs->x_base); +} + +static bool_t +xdrmem_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register caddr_t newaddr = xdrs->x_base + pos; + register caddr_t lastaddr = xdrs->x_private + xdrs->x_handy; + + if ((long)newaddr > (long)lastaddr) + return (FALSE); + xdrs->x_private = newaddr; + xdrs->x_handy = (int)lastaddr - (int)newaddr; + return (TRUE); +} + +static long * +xdrmem_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + long *buf = 0; + + if (xdrs->x_handy >= len) { + xdrs->x_handy -= len; + buf = (long *) xdrs->x_private; + xdrs->x_private += len; + } + return (buf); +} diff --git a/libc/inet/rpc/xdr_rec.c b/libc/inet/rpc/xdr_rec.c new file mode 100644 index 000000000..4d0d4ecfb --- /dev/null +++ b/libc/inet/rpc/xdr_rec.c @@ -0,0 +1,580 @@ +/* @(#)xdr_rec.c 2.2 88/08/01 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_rec.c 1.21 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_rec.c, Implements TCP/IP based XDR streams with a "record marking" + * layer above tcp (for rpc's use). + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * These routines interface XDRSTREAMS to a tcp/ip connection. + * There is a record marking layer between the xdr stream + * and the tcp transport level. A record is composed on one or more + * record fragments. A record fragment is a thirty-two bit header followed + * by n bytes of data, where n is contained in the header. The header + * is represented as a htonl(u_long). Thegh order bit encodes + * whether or not the fragment is the last fragment of the record + * (1 => fragment is last, 0 => more fragments to follow. + * The other 31 bits encode the byte length of the fragment. + */ + +#include <stdio.h> +#include <rpc/types.h> +#include <rpc/xdr.h> +#include <netinet/in.h> + +extern long lseek(); + +static u_int fix_buf_size(); + +static bool_t xdrrec_getlong(); +static bool_t xdrrec_putlong(); +static bool_t xdrrec_getbytes(); +static bool_t xdrrec_putbytes(); +static u_int xdrrec_getpos(); +static bool_t xdrrec_setpos(); +static long * xdrrec_inline(); +static void xdrrec_destroy(); + +static struct xdr_ops xdrrec_ops = { + xdrrec_getlong, + xdrrec_putlong, + xdrrec_getbytes, + xdrrec_putbytes, + xdrrec_getpos, + xdrrec_setpos, + xdrrec_inline, + xdrrec_destroy +}; + +/* + * A record is composed of one or more record fragments. + * A record fragment is a two-byte header followed by zero to + * 2**32-1 bytes. The header is treated as a long unsigned and is + * encode/decoded to the network via htonl/ntohl. The low order 31 bits + * are a byte count of the fragment. The highest order bit is a boolean: + * 1 => this fragment is the last fragment of the record, + * 0 => this fragment is followed by more fragment(s). + * + * The fragment/record machinery is not general; it is constructed to + * meet the needs of xdr and rpc based on tcp. + */ + +#define LAST_FRAG ((u_long)(1 << 31)) + +typedef struct rec_strm { + caddr_t tcp_handle; + caddr_t the_buffer; + /* + * out-goung bits + */ + int (*writeit)(); + caddr_t out_base; /* output buffer (points to frag header) */ + caddr_t out_finger; /* next output position */ + caddr_t out_boundry; /* data cannot up to this address */ + u_long *frag_header; /* beginning of curren fragment */ + bool_t frag_sent; /* true if buffer sent in middle of record */ + /* + * in-coming bits + */ + int (*readit)(); + u_long in_size; /* fixed size of the input buffer */ + caddr_t in_base; + caddr_t in_finger; /* location of next byte to be had */ + caddr_t in_boundry; /* can read up to this location */ + long fbtbc; /* fragment bytes to be consumed */ + bool_t last_frag; + u_int sendsize; + u_int recvsize; +} RECSTREAM; + + +/* + * Create an xdr handle for xdrrec + * xdrrec_create fills in xdrs. Sendsize and recvsize are + * send and recv buffer sizes (0 => use default). + * tcp_handle is an opaque handle that is passed as the first parameter to + * the procedures readit and writeit. Readit and writeit are read and + * write respectively. They are like the system + * calls expect that they take an opaque handle rather than an fd. + */ +void +xdrrec_create(xdrs, sendsize, recvsize, tcp_handle, readit, writeit) + register XDR *xdrs; + register u_int sendsize; + register u_int recvsize; + caddr_t tcp_handle; + int (*readit)(); /* like read, but pass it a tcp_handle, not sock */ + int (*writeit)(); /* like write, but pass it a tcp_handle, not sock */ +{ + register RECSTREAM *rstrm = + (RECSTREAM *)mem_alloc(sizeof(RECSTREAM)); + + if (rstrm == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + /* + * This is bad. Should rework xdrrec_create to + * return a handle, and in this case return NULL + */ + return; + } + /* + * adjust sizes and allocate buffer quad byte aligned + */ + rstrm->sendsize = sendsize = fix_buf_size(sendsize); + rstrm->recvsize = recvsize = fix_buf_size(recvsize); + rstrm->the_buffer = mem_alloc(sendsize + recvsize + BYTES_PER_XDR_UNIT); + if (rstrm->the_buffer == NULL) { + (void)fprintf(stderr, "xdrrec_create: out of memory\n"); + return; + } + for (rstrm->out_base = rstrm->the_buffer; + (u_int)rstrm->out_base % BYTES_PER_XDR_UNIT != 0; + rstrm->out_base++); + rstrm->in_base = rstrm->out_base + sendsize; + /* + * now the rest ... + */ + xdrs->x_ops = &xdrrec_ops; + xdrs->x_private = (caddr_t)rstrm; + rstrm->tcp_handle = tcp_handle; + rstrm->readit = readit; + rstrm->writeit = writeit; + rstrm->out_finger = rstrm->out_boundry = rstrm->out_base; + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger += sizeof(u_long); + rstrm->out_boundry += sendsize; + rstrm->frag_sent = FALSE; + rstrm->in_size = recvsize; + rstrm->in_boundry = rstrm->in_base; + rstrm->in_finger = (rstrm->in_boundry += recvsize); + rstrm->fbtbc = 0; + rstrm->last_frag = TRUE; +} + + +/* + * The reoutines defined below are the xdr ops which will go into the + * xdr handle filled in by xdrrec_create. + */ + +static bool_t +xdrrec_getlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *buflp = (long *)(rstrm->in_finger); + long mylong; + + /* first try the inline, fast case */ + if ((rstrm->fbtbc >= sizeof(long)) && + (((int)rstrm->in_boundry - (int)buflp) >= sizeof(long))) { + *lp = (long)ntohl((u_long)(*buflp)); + rstrm->fbtbc -= sizeof(long); + rstrm->in_finger += sizeof(long); + } else { + if (! xdrrec_getbytes(xdrs, (caddr_t)&mylong, sizeof(long))) + return (FALSE); + *lp = (long)ntohl((u_long)mylong); + } + return (TRUE); +} + +static bool_t +xdrrec_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register long *dest_lp = ((long *)(rstrm->out_finger)); + + if ((rstrm->out_finger += sizeof(long)) > rstrm->out_boundry) { + /* + * this case should almost never happen so the code is + * inefficient + */ + rstrm->out_finger -= sizeof(long); + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + dest_lp = ((long *)(rstrm->out_finger)); + rstrm->out_finger += sizeof(long); + } + *dest_lp = (long)htonl((u_long)(*lp)); + return (TRUE); +} + +static bool_t /* must manage buffers, fragments, and records */ +xdrrec_getbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = rstrm->fbtbc; + if (current == 0) { + if (rstrm->last_frag) + return (FALSE); + if (! set_input_fragment(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + if (! get_input_bytes(rstrm, addr, current)) + return (FALSE); + addr += current; + rstrm->fbtbc -= current; + len -= current; + } + return (TRUE); +} + +static bool_t +xdrrec_putbytes(xdrs, addr, len) + XDR *xdrs; + register caddr_t addr; + register u_int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register int current; + + while (len > 0) { + current = (u_int)rstrm->out_boundry - (u_int)rstrm->out_finger; + current = (len < current) ? len : current; + bcopy(addr, rstrm->out_finger, current); + rstrm->out_finger += current; + addr += current; + len -= current; + if (rstrm->out_finger == rstrm->out_boundry) { + rstrm->frag_sent = TRUE; + if (! flush_out(rstrm, FALSE)) + return (FALSE); + } + } + return (TRUE); +} + +static u_int +xdrrec_getpos(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + register long pos; + + pos = lseek((int)rstrm->tcp_handle, (long) 0, 1); + if (pos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + pos += rstrm->out_finger - rstrm->out_base; + break; + + case XDR_DECODE: + pos -= rstrm->in_boundry - rstrm->in_finger; + break; + + default: + pos = (u_int) -1; + break; + } + return ((u_int) pos); +} + +static bool_t +xdrrec_setpos(xdrs, pos) + register XDR *xdrs; + u_int pos; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + u_int currpos = xdrrec_getpos(xdrs); + int delta = currpos - pos; + caddr_t newpos; + + if ((int)currpos != -1) + switch (xdrs->x_op) { + + case XDR_ENCODE: + newpos = rstrm->out_finger - delta; + if ((newpos > (caddr_t)(rstrm->frag_header)) && + (newpos < rstrm->out_boundry)) { + rstrm->out_finger = newpos; + return (TRUE); + } + break; + + case XDR_DECODE: + newpos = rstrm->in_finger - delta; + if ((delta < (int)(rstrm->fbtbc)) && + (newpos <= rstrm->in_boundry) && + (newpos >= rstrm->in_base)) { + rstrm->in_finger = newpos; + rstrm->fbtbc -= delta; + return (TRUE); + } + break; + } + return (FALSE); +} + +static long * +xdrrec_inline(xdrs, len) + register XDR *xdrs; + int len; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + long * buf = NULL; + + switch (xdrs->x_op) { + + case XDR_ENCODE: + if ((rstrm->out_finger + len) <= rstrm->out_boundry) { + buf = (long *) rstrm->out_finger; + rstrm->out_finger += len; + } + break; + + case XDR_DECODE: + if ((len <= rstrm->fbtbc) && + ((rstrm->in_finger + len) <= rstrm->in_boundry)) { + buf = (long *) rstrm->in_finger; + rstrm->fbtbc -= len; + rstrm->in_finger += len; + } + break; + } + return (buf); +} + +static void +xdrrec_destroy(xdrs) + register XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)xdrs->x_private; + + mem_free(rstrm->the_buffer, + rstrm->sendsize + rstrm->recvsize + BYTES_PER_XDR_UNIT); + mem_free((caddr_t)rstrm, sizeof(RECSTREAM)); +} + + +/* + * Exported routines to manage xdr records + */ + +/* + * Before reading (deserializing from the stream, one should always call + * this procedure to guarantee proper record alignment. + */ +bool_t +xdrrec_skiprecord(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (FALSE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (FALSE); + } + rstrm->last_frag = FALSE; + return (TRUE); +} + +/* + * Look ahead fuction. + * Returns TRUE iff there is no more input in the buffer + * after consuming the rest of the current record. + */ +bool_t +xdrrec_eof(xdrs) + XDR *xdrs; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + + while (rstrm->fbtbc > 0 || (! rstrm->last_frag)) { + if (! skip_input_bytes(rstrm, rstrm->fbtbc)) + return (TRUE); + rstrm->fbtbc = 0; + if ((! rstrm->last_frag) && (! set_input_fragment(rstrm))) + return (TRUE); + } + if (rstrm->in_finger == rstrm->in_boundry) + return (TRUE); + return (FALSE); +} + +/* + * The client must tell the package when an end-of-record has occurred. + * The second paraemters tells whether the record should be flushed to the + * (output) tcp stream. (This let's the package support batched or + * pipelined procedure calls.) TRUE => immmediate flush to tcp connection. + */ +bool_t +xdrrec_endofrecord(xdrs, sendnow) + XDR *xdrs; + bool_t sendnow; +{ + register RECSTREAM *rstrm = (RECSTREAM *)(xdrs->x_private); + register u_long len; /* fragment length */ + + if (sendnow || rstrm->frag_sent || + ((u_long)rstrm->out_finger + sizeof(u_long) >= + (u_long)rstrm->out_boundry)) { + rstrm->frag_sent = FALSE; + return (flush_out(rstrm, TRUE)); + } + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->frag_header) - + sizeof(u_long); + *(rstrm->frag_header) = htonl((u_long)len | LAST_FRAG); + rstrm->frag_header = (u_long *)rstrm->out_finger; + rstrm->out_finger += sizeof(u_long); + return (TRUE); +} + + +/* + * Internal useful routines + */ +static bool_t +flush_out(rstrm, eor) + register RECSTREAM *rstrm; + bool_t eor; +{ + register u_long eormask = (eor == TRUE) ? LAST_FRAG : 0; + register u_long len = (u_long)(rstrm->out_finger) - + (u_long)(rstrm->frag_header) - sizeof(u_long); + + *(rstrm->frag_header) = htonl(len | eormask); + len = (u_long)(rstrm->out_finger) - (u_long)(rstrm->out_base); + if ((*(rstrm->writeit))(rstrm->tcp_handle, rstrm->out_base, (int)len) + != (int)len) + return (FALSE); + rstrm->frag_header = (u_long *)rstrm->out_base; + rstrm->out_finger = (caddr_t)rstrm->out_base + sizeof(u_long); + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +fill_input_buf(rstrm) + register RECSTREAM *rstrm; +{ + register caddr_t where; + u_int i; + register int len; + + where = rstrm->in_base; + i = (u_int)rstrm->in_boundry % BYTES_PER_XDR_UNIT; + where += i; + len = rstrm->in_size - i; + if ((len = (*(rstrm->readit))(rstrm->tcp_handle, where, len)) == -1) + return (FALSE); + rstrm->in_finger = where; + where += len; + rstrm->in_boundry = where; + return (TRUE); +} + +static bool_t /* knows nothing about records! Only about input buffers */ +get_input_bytes(rstrm, addr, len) + register RECSTREAM *rstrm; + register caddr_t addr; + register int len; +{ + register int current; + + while (len > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (len < current) ? len : current; + bcopy(rstrm->in_finger, addr, current); + rstrm->in_finger += current; + addr += current; + len -= current; + } + return (TRUE); +} + +static bool_t /* next two bytes of the input stream are treated as a header */ +set_input_fragment(rstrm) + register RECSTREAM *rstrm; +{ + u_long header; + + if (! get_input_bytes(rstrm, (caddr_t)&header, sizeof(header))) + return (FALSE); + header = (long)ntohl(header); + rstrm->last_frag = ((header & LAST_FRAG) == 0) ? FALSE : TRUE; + rstrm->fbtbc = header & (~LAST_FRAG); + return (TRUE); +} + +static bool_t /* consumes input bytes; knows nothing about records! */ +skip_input_bytes(rstrm, cnt) + register RECSTREAM *rstrm; + long cnt; +{ + register int current; + + while (cnt > 0) { + current = (int)rstrm->in_boundry - (int)rstrm->in_finger; + if (current == 0) { + if (! fill_input_buf(rstrm)) + return (FALSE); + continue; + } + current = (cnt < current) ? cnt : current; + rstrm->in_finger += current; + cnt -= current; + } + return (TRUE); +} + +static u_int +fix_buf_size(s) + register u_int s; +{ + + if (s < 100) + s = 4000; + return (RNDUP(s)); +} diff --git a/libc/inet/rpc/xdr_reference.c b/libc/inet/rpc/xdr_reference.c new file mode 100644 index 000000000..32d91d999 --- /dev/null +++ b/libc/inet/rpc/xdr_reference.c @@ -0,0 +1,132 @@ +/* @(#)xdr_reference.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_reference.c 1.11 87/08/11 SMI"; +#endif + +/* + * xdr_reference.c, Generic XDR routines impelmentation. + * + * Copyright (C) 1987, Sun Microsystems, Inc. + * + * These are the "non-trivial" xdr primitives used to serialize and de-serialize + * "pointers". See xdr.h for more info on the interface to xdr. + */ + +#include <stdio.h> +#include <rpc/types.h> +#include <rpc/xdr.h> + +#define LASTUNSIGNED ((u_int)0-1) + +/* + * XDR an indirect pointer + * xdr_reference is for recursively translating a structure that is + * referenced by a pointer inside the structure that is currently being + * translated. pp references a pointer to storage. If *pp is null + * the necessary storage is allocated. + * size is the sizeof the referneced structure. + * proc is the routine to handle the referenced structure. + */ +bool_t +xdr_reference(xdrs, pp, size, proc) + register XDR *xdrs; + caddr_t *pp; /* the pointer to work on */ + u_int size; /* size of the object pointed to */ + xdrproc_t proc; /* xdr routine to handle the object */ +{ + register caddr_t loc = *pp; + register bool_t stat; + + if (loc == NULL) + switch (xdrs->x_op) { + case XDR_FREE: + return (TRUE); + + case XDR_DECODE: + *pp = loc = (caddr_t) mem_alloc(size); + if (loc == NULL) { + (void) fprintf(stderr, + "xdr_reference: out of memory\n"); + return (FALSE); + } + bzero(loc, (int)size); + break; + } + + stat = (*proc)(xdrs, loc, LASTUNSIGNED); + + if (xdrs->x_op == XDR_FREE) { + mem_free(loc, size); + *pp = NULL; + } + return (stat); +} + + +/* + * xdr_pointer(): + * + * XDR a pointer to a possibly recursive data structure. This + * differs with xdr_reference in that it can serialize/deserialiaze + * trees correctly. + * + * What's sent is actually a union: + * + * union object_pointer switch (boolean b) { + * case TRUE: object_data data; + * case FALSE: void nothing; + * } + * + * > objpp: Pointer to the pointer to the object. + * > obj_size: size of the object. + * > xdr_obj: routine to XDR an object. + * + */ +bool_t +xdr_pointer(xdrs,objpp,obj_size,xdr_obj) + register XDR *xdrs; + char **objpp; + u_int obj_size; + xdrproc_t xdr_obj; +{ + + bool_t more_data; + + more_data = (*objpp != NULL); + if (! xdr_bool(xdrs,&more_data)) { + return (FALSE); + } + if (! more_data) { + *objpp = NULL; + return (TRUE); + } + return (xdr_reference(xdrs,objpp,obj_size,xdr_obj)); +} diff --git a/libc/inet/rpc/xdr_stdio.c b/libc/inet/rpc/xdr_stdio.c new file mode 100644 index 000000000..694774f6f --- /dev/null +++ b/libc/inet/rpc/xdr_stdio.c @@ -0,0 +1,189 @@ +/* @(#)xdr_stdio.c 2.1 88/07/29 4.0 RPCSRC */ +/* + * Sun RPC is a product of Sun Microsystems, Inc. and is provided for + * unrestricted use provided that this legend is included on all tape + * media and as a part of the software program in whole or part. Users + * may copy or modify Sun RPC without charge, but are not authorized + * to license or distribute it to anyone else except as part of a product or + * program developed by the user. + * + * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE + * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR + * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE. + * + * Sun RPC is provided with no support and without any obligation on the + * part of Sun Microsystems, Inc. to assist in its use, correction, + * modification or enhancement. + * + * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE + * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC + * OR ANY PART THEREOF. + * + * In no event will Sun Microsystems, Inc. be liable for any lost revenue + * or profits or other special, indirect and consequential damages, even if + * Sun has been advised of the possibility of such damages. + * + * Sun Microsystems, Inc. + * 2550 Garcia Avenue + * Mountain View, California 94043 + */ +#if !defined(lint) && defined(SCCSIDS) +static char sccsid[] = "@(#)xdr_stdio.c 1.16 87/08/11 Copyr 1984 Sun Micro"; +#endif + +/* + * xdr_stdio.c, XDR implementation on standard i/o file. + * + * Copyright (C) 1984, Sun Microsystems, Inc. + * + * This set of routines implements a XDR on a stdio stream. + * XDR_ENCODE serializes onto the stream, XDR_DECODE de-serializes + * from the stream. + */ + +#include <rpc/types.h> +#include <stdio.h> +#include <rpc/xdr.h> + +static bool_t xdrstdio_getlong(); +static bool_t xdrstdio_putlong(); +static bool_t xdrstdio_getbytes(); +static bool_t xdrstdio_putbytes(); +static u_int xdrstdio_getpos(); +static bool_t xdrstdio_setpos(); +static long * xdrstdio_inline(); +static void xdrstdio_destroy(); + +/* + * Ops vector for stdio type XDR + */ +static struct xdr_ops xdrstdio_ops = { + xdrstdio_getlong, /* deseraialize a long int */ + xdrstdio_putlong, /* seraialize a long int */ + xdrstdio_getbytes, /* deserialize counted bytes */ + xdrstdio_putbytes, /* serialize counted bytes */ + xdrstdio_getpos, /* get offset in the stream */ + xdrstdio_setpos, /* set offset in the stream */ + xdrstdio_inline, /* prime stream for inline macros */ + xdrstdio_destroy /* destroy stream */ +}; + +/* + * Initialize a stdio xdr stream. + * Sets the xdr stream handle xdrs for use on the stream file. + * Operation flag is set to op. + */ +void +xdrstdio_create(xdrs, file, op) + register XDR *xdrs; + FILE *file; + enum xdr_op op; +{ + + xdrs->x_op = op; + xdrs->x_ops = &xdrstdio_ops; + xdrs->x_private = (caddr_t)file; + xdrs->x_handy = 0; + xdrs->x_base = 0; +} + +/* + * Destroy a stdio xdr stream. + * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create. + */ +static void +xdrstdio_destroy(xdrs) + register XDR *xdrs; +{ + (void)fflush((FILE *)xdrs->x_private); + /* xx should we close the file ?? */ +}; + +static bool_t +xdrstdio_getlong(xdrs, lp) + XDR *xdrs; + register long *lp; +{ + + if (fread((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); +#ifndef mc68000 + *lp = ntohl(*lp); +#endif + return (TRUE); +} + +static bool_t +xdrstdio_putlong(xdrs, lp) + XDR *xdrs; + long *lp; +{ + +#ifndef mc68000 + long mycopy = htonl(*lp); + lp = &mycopy; +#endif + if (fwrite((caddr_t)lp, sizeof(long), 1, (FILE *)xdrs->x_private) != 1) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_getbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fread(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static bool_t +xdrstdio_putbytes(xdrs, addr, len) + XDR *xdrs; + caddr_t addr; + u_int len; +{ + + if ((len != 0) && (fwrite(addr, (int)len, 1, (FILE *)xdrs->x_private) != 1)) + return (FALSE); + return (TRUE); +} + +static u_int +xdrstdio_getpos(xdrs) + XDR *xdrs; +{ + + return ((u_int) ftell((FILE *)xdrs->x_private)); +} + +static bool_t +xdrstdio_setpos(xdrs, pos) + XDR *xdrs; + u_int pos; +{ + + return ((fseek((FILE *)xdrs->x_private, (long)pos, 0) < 0) ? + FALSE : TRUE); +} + +static long * +xdrstdio_inline(xdrs, len) + XDR *xdrs; + u_int len; +{ + + /* + * Must do some work to implement this: must insure + * enough data in the underlying stdio buffer, + * that the buffer is aligned so that we can indirect through a + * long *, and stuff this pointer in xdrs->x_buf. Doing + * a fread or fwrite to a scratch buffer would defeat + * most of the gains to be had here and require storage + * management on this buffer, so we don't do this. + */ + return (NULL); +} diff --git a/libc/misc/time/Makefile b/libc/misc/time/Makefile new file mode 100644 index 000000000..ab47a7e47 --- /dev/null +++ b/libc/misc/time/Makefile @@ -0,0 +1,24 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -I../include + +OBJ=localtime.o gmtime.o asctime.o ctime.o asc_conv.o tm_conv.o mktime.o \ + localtime_r.o gmtime_r.o asctime_r.o ctime_r.o + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +clean: + rm -f *.o libc.a diff --git a/libc/misc/time/README b/libc/misc/time/README new file mode 100644 index 000000000..da4f4e67f --- /dev/null +++ b/libc/misc/time/README @@ -0,0 +1,8 @@ +Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +This file is part of the Linux-8086 C library and is distributed +under the GNU Library General Public License. + +There are two ways of converting the time_t to a struct tm, I'm not +quite sure which is better. + +-Robert diff --git a/libc/misc/time/asc_conv.c b/libc/misc/time/asc_conv.c new file mode 100644 index 000000000..78cbcdd8d --- /dev/null +++ b/libc/misc/time/asc_conv.c @@ -0,0 +1,49 @@ + +#include <time.h> +#include <string.h> +/* + * Internal ascii conversion routine, avoid use of printf, it's a bit big! + */ + + +static void +hit(buf, val) +char * buf; +int val; +{ + *buf = '0' + val%10; +} + +void +__asctime(buffer, ptm) +register char * buffer; +struct tm * ptm; +{ +static char days[] = "SunMonTueWedThuFriSat"; +static char mons[] = "JanFebMarAprMayJunJulAugSepOctNovDec"; + int year; + + /* 012345678901234567890123456 */ + strcpy(buffer, "Err Err .. ..:..:.. ....\n"); + if( (ptm->tm_wday >= 0) && (ptm->tm_wday <= 6) ) + memcpy(buffer, days+3*(ptm->tm_wday), 3); + + if( (ptm->tm_mon >= 0) && (ptm->tm_mon <= 11) ) + memcpy(buffer+4, mons+3*(ptm->tm_mon), 3); + + + hit(buffer+ 8, ptm->tm_mday/10); + hit(buffer+ 9, ptm->tm_mday ); + hit(buffer+11, ptm->tm_hour/10); + hit(buffer+12, ptm->tm_hour ); + hit(buffer+14, ptm->tm_min/10); + hit(buffer+15, ptm->tm_min ); + hit(buffer+17, ptm->tm_sec/10); + hit(buffer+18, ptm->tm_sec ); + + year = ptm->tm_year + 1900; + hit(buffer+20, year/1000); + hit(buffer+21, year/100); + hit(buffer+22, year/10); + hit(buffer+23, year); +} diff --git a/libc/misc/time/asctime.c b/libc/misc/time/asctime.c new file mode 100644 index 000000000..08673cbcc --- /dev/null +++ b/libc/misc/time/asctime.c @@ -0,0 +1,15 @@ + +#include <time.h> + +extern void __asctime(); + +char * +asctime(timeptr) +__const struct tm * timeptr; +{ + static char timebuf[26]; + + if( timeptr == 0 ) return 0; + __asctime(timebuf, timeptr); + return timebuf; +} diff --git a/libc/misc/time/asctime_r.c b/libc/misc/time/asctime_r.c new file mode 100644 index 000000000..ff2b6bfb3 --- /dev/null +++ b/libc/misc/time/asctime_r.c @@ -0,0 +1,15 @@ + +#include <time.h> + +extern void __asctime(); + +char * +asctime_r(timeptr, buf) +__const struct tm * timeptr; +char * buf; +{ + + if( timeptr == 0 ) return 0; + __asctime(buf, timeptr); + return buf; +} diff --git a/libc/misc/time/ctime.c b/libc/misc/time/ctime.c new file mode 100644 index 000000000..2f42cd3f3 --- /dev/null +++ b/libc/misc/time/ctime.c @@ -0,0 +1,26 @@ + +#include <time.h> + +extern void __tm_conv(); +extern void __asctime(); + +char * +ctime(timep) +__const time_t * timep; +{ + static char cbuf[26]; + struct tm tmb; + struct timezone tz; + time_t offt; + + gettimeofday((void*)0, &tz); + + offt = -tz.tz_minuteswest*60L; + + /* tmb.tm_isdst = ? */ + __tm_conv(&tmb, timep, offt); + + __asctime(cbuf, &tmb); + + return cbuf; +} diff --git a/libc/misc/time/ctime_r.c b/libc/misc/time/ctime_r.c new file mode 100644 index 000000000..ac267b04e --- /dev/null +++ b/libc/misc/time/ctime_r.c @@ -0,0 +1,26 @@ + +#include <time.h> + +extern void __tm_conv(); +extern void __asctime(); + +char * +ctime_r(timep, buf) +__const time_t * timep; +char * buf; +{ + struct tm tmb; + struct timezone tz; + time_t offt; + + gettimeofday((void*)0, &tz); + + offt = -tz.tz_minuteswest*60L; + + /* tmb.tm_isdst = ? */ + __tm_conv(&tmb, timep, offt); + + __asctime(buf, &tmb); + + return buf; +} diff --git a/libc/misc/time/gmtime.c b/libc/misc/time/gmtime.c new file mode 100644 index 000000000..69d539392 --- /dev/null +++ b/libc/misc/time/gmtime.c @@ -0,0 +1,16 @@ + +#include <time.h> + +extern void __tm_conv(); + +struct tm * +gmtime(timep) +__const time_t * timep; +{ + static struct tm tmb; + + __tm_conv(&tmb, timep, 0L); + + return &tmb; +} + diff --git a/libc/misc/time/gmtime_r.c b/libc/misc/time/gmtime_r.c new file mode 100644 index 000000000..00c41b349 --- /dev/null +++ b/libc/misc/time/gmtime_r.c @@ -0,0 +1,14 @@ + +#include <time.h> + +extern void __tm_conv(); + +struct tm * +gmtime_r(timep, tp) +__const time_t * timep; +struct tm * tp; +{ + __tm_conv(tp, timep, 0L); + return tp; +} + diff --git a/libc/misc/time/localtime.c b/libc/misc/time/localtime.c new file mode 100644 index 000000000..9d9b46d15 --- /dev/null +++ b/libc/misc/time/localtime.c @@ -0,0 +1,22 @@ + +#include <time.h> + +extern void __tm_conv(); + +struct tm * +localtime(timep) +__const time_t * timep; +{ + static struct tm tmb; + struct timezone tz; + time_t offt; + + gettimeofday((void*)0, &tz); + + offt = -tz.tz_minuteswest*60L; + + /* tmb.tm_isdst = ? */ + __tm_conv(&tmb, timep, offt); + + return &tmb; +} diff --git a/libc/misc/time/localtime_r.c b/libc/misc/time/localtime_r.c new file mode 100644 index 000000000..fe024670c --- /dev/null +++ b/libc/misc/time/localtime_r.c @@ -0,0 +1,22 @@ + +#include <time.h> + +extern void __tm_conv(); + +struct tm * +localtime_r(timep, tp) +__const time_t * timep; +struct tm * tp; +{ + struct timezone tz; + time_t offt; + + gettimeofday((void*)0, &tz); + + offt = -tz.tz_minuteswest*60L; + + /* tmb.tm_isdst = ? */ + __tm_conv(tp, timep, offt); + + return tp; +} diff --git a/libc/misc/time/mktime.c b/libc/misc/time/mktime.c new file mode 100644 index 000000000..7f7aabcd7 --- /dev/null +++ b/libc/misc/time/mktime.c @@ -0,0 +1,259 @@ + +/* This is adapted from glibc */ +/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. */ + + +/* Assume that leap seconds are possible, unless told otherwise. + If the host has a `zic' command with a -L leapsecondfilename' option, + then it supports leap seconds; otherwise it probably doesn't. */ +#ifndef LEAP_SECONDS_POSSIBLE +#define LEAP_SECONDS_POSSIBLE 1 +#endif + +#include <sys/types.h> /* Some systems define `time_t' here. */ +#include <time.h> + +#if __STDC__ || __GNU_LIBRARY__ || STDC_HEADERS +#include <limits.h> +#endif + +#if DEBUG +#include <stdio.h> +#if __STDC__ || __GNU_LIBRARY__ || STDC_HEADERS +#include <stdlib.h> +#endif +/* Make it work even if the system's libc has its own mktime routine. */ +#define mktime my_mktime +#endif /* DEBUG */ + +#ifndef __P +#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +#define __P(args) args +#else +#define __P(args) () +#endif /* GCC. */ +#endif /* Not __P. */ + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#ifndef INT_MIN +#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1)) +#endif +#ifndef INT_MAX +#define INT_MAX (~0 - INT_MIN) +#endif + +#ifndef TIME_T_MIN +#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \ + : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)) +#endif +#ifndef TIME_T_MAX +#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) +#endif + +#define TM_YEAR_BASE 1900 +#define EPOCH_YEAR 1970 + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +/* How many days come before each month (0-12). */ +const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; + +static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *)); +time_t __mktime_internal __P ((struct tm *, + struct tm *(*) (const time_t *, struct tm *), + time_t *)); + +/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP), + measured in seconds, ignoring leap seconds. + YEAR uses the same numbering as TM->tm_year. + All values are in range, except possibly YEAR. + If overflow occurs, yield the low order bits of the correct answer. */ +static time_t +ydhms_tm_diff (year, yday, hour, min, sec, tp) + int year, yday, hour, min, sec; + const struct tm *tp; +{ + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid int overflow. time_t overflow is OK, since + only the low order bits of the correct time_t answer are needed. + Don't convert to time_t until after all divisions are done, since + time_t might be unsigned. */ + int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3); + int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = a100 >> 2; + int b400 = b100 >> 2; + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + time_t years = year - (time_t) tp->tm_year; + time_t days = (365 * years + intervening_leap_days + + (yday - tp->tm_yday)); + return (60 * (60 * (24 * days + (hour - tp->tm_hour)) + + (min - tp->tm_min)) + + (sec - tp->tm_sec)); +} + + +static time_t localtime_offset; + + +/* Convert *TP to a time_t value. */ +time_t +mktime (tp) + struct tm *tp; +{ +#ifdef _LIBC + /* POSIX.1 8.1.1 requires that whenever mktime() is called, the + time zone names contained in the external variable `tzname' shall + be set as if the tzset() function had been called. */ + __tzset (); +#endif + + return __mktime_internal (tp, localtime_r, &localtime_offset); +} + +/* Convert *TP to a time_t value, inverting + the monotonic and mostly-unit-linear conversion function CONVERT. + Use *OFFSET to keep track of a guess at the offset of the result, + compared to what the result would be for UTC without leap seconds. + If *OFFSET's guess is correct, only one CONVERT call is needed. */ +time_t +__mktime_internal (tp, convert, offset) + struct tm *tp; + struct tm *(*convert) __P ((const time_t *, struct tm *)); + time_t *offset; +{ + time_t t, dt, t0; + struct tm tm; + + /* The maximum number of probes (calls to CONVERT) should be enough + to handle any combinations of time zone rule changes, solar time, + and leap seconds. Posix.1 prohibits leap seconds, but some hosts + have them anyway. */ + int remaining_probes = 4; + + /* Time requested. Copy it in case CONVERT modifies *TP; this can + occur if TP is localtime's returned value and CONVERT is localtime. */ + int sec = tp->tm_sec; + int min = tp->tm_min; + int hour = tp->tm_hour; + int mday = tp->tm_mday; + int mon = tp->tm_mon; + int year_requested = tp->tm_year; + int isdst = tp->tm_isdst; + + /* Ensure that mon is in range, and set year accordingly. */ + int mon_remainder = mon % 12; + int negative_mon_remainder = mon_remainder < 0; + int mon_years = mon / 12 - negative_mon_remainder; + int year = year_requested + mon_years; + + /* The other values need not be in range: + the remaining code handles minor overflows correctly, + assuming int and time_t arithmetic wraps around. + Major overflows are caught at the end. */ + + /* Calculate day of year from year, month, and day of month. + The result need not be in range. */ + int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)] + [mon_remainder + 12 * negative_mon_remainder]) + + mday - 1); + +#if LEAP_SECONDS_POSSIBLE + /* Handle out-of-range seconds specially, + since ydhms_tm_diff assumes every minute has 60 seconds. */ + int sec_requested = sec; + if (sec < 0) + sec = 0; + if (59 < sec) + sec = 59; +#endif + + /* Invert CONVERT by probing. First assume the same offset as last time. + Then repeatedly use the error to improve the guess. */ + + tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE; + tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm); + + for (t = t0 + *offset; + (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm))); + t += dt) + if (--remaining_probes == 0) + return -1; + + /* Check whether tm.tm_isdst has the requested value, if any. */ + if (0 <= isdst && 0 <= tm.tm_isdst) + { + int dst_diff = (isdst != 0) - (tm.tm_isdst != 0); + if (dst_diff) + { + /* Move two hours in the direction indicated by the disagreement, + probe some more, and switch to a new time if found. + The largest known fallback due to daylight savings is two hours: + once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */ + time_t ot = t - 2 * 60 * 60 * dst_diff; + while (--remaining_probes != 0) + { + struct tm otm; + if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec, + (*convert) (&ot, &otm)))) + { + t = ot; + tm = otm; + break; + } + if ((ot += dt) == t) + break; /* Avoid a redundant probe. */ + } + } + } + + *offset = t - t0; + +#if LEAP_SECONDS_POSSIBLE + if (sec_requested != tm.tm_sec) + { + /* Adjust time to reflect the tm_sec requested, not the normalized value. + Also, repair any damage from a false match due to a leap second. */ + t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60); + (*convert) (&t, &tm); + } +#endif + +#if 0 + if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3) + { + /* time_t isn't large enough to rule out overflows in ydhms_tm_diff, + so check for major overflows. A gross check suffices, + since if t has overflowed, it is off by a multiple of + TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of + the difference that is bounded by a small value. */ + + double dyear = (double) year_requested + mon_years - tm.tm_year; + double dday = 366 * dyear + mday; + double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested; + + if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec)) + return -1; + } +#endif + + *tp = tm; + return t; +} + diff --git a/libc/misc/time/tm_conv.c b/libc/misc/time/tm_conv.c new file mode 100644 index 000000000..ffd524c4b --- /dev/null +++ b/libc/misc/time/tm_conv.c @@ -0,0 +1,138 @@ + +#if 0 +#include <time.h> + +/* This is a translation from ALGOL in Collected Algorithms of CACM. */ +/* Copied from Algorithm 199, Author: Robert G. Tantzen */ + +void +__tm_conv(tmbuf, timep, offset) +struct tm *tmbuf; +time_t *timep; +time_t offset; +{ +static int moffset[] = + {0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334}; + + long s; + long j, d, m, y; + + offset += *timep; + + tmbuf->tm_isdst = 0; /* Someone else can set this */ + + j = offset / 86400L + 719469; + s = offset % 86400L; + + if( s < 0 ) { s += 86400L; j--; } + + tmbuf->tm_sec = s % 60; + tmbuf->tm_min = (s / 60) % 60; + tmbuf->tm_hour = s / 3600; + + tmbuf->tm_wday = (j+2) % 7; + + /* + * Julian date converter. Takes a julian date (the number of days since + * some distant epoch or other), and fills tmbuf. + */ + + y = (4L * j - 1L) / 146097L; + j = 4L * j - 1L - 146097L * y; + d = j / 4L; + j = (4L * d + 3L) / 1461L; + d = 4L * d + 3L - 1461L * j; + d = (d + 4L) / 4L; + m = (5L * d - 3L) / 153L; + d = 5L * d - 3 - 153L * m; + d = (d + 5L) / 5L; + y = 100L * y + j; + if (m < 10) + m += 2; + else + { + m -= 10; + ++y; + } + + tmbuf->tm_year = y - 1900; + tmbuf->tm_mon = m; + tmbuf->tm_mday = d; + + tmbuf->tm_yday = d + moffset[m]; + if (m > 1 && ((y) % 4 == 0 && ((y) % 100 != 0 || (y) % 400 == 0))) + tmbuf->tm_yday++; +} + +#else + +/* This is adapted from glibc */ +/* Copyright (C) 1991, 1993 Free Software Foundation, Inc */ + +#define SECS_PER_HOUR 3600L +#define SECS_PER_DAY 86400L + +#include <time.h> + +static const unsigned short int __mon_lengths[2][12] = + { + /* Normal years. */ + { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, + /* Leap years. */ + { 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } + }; + + +void +__tm_conv(tmbuf, t, offset) +struct tm *tmbuf; +time_t *t; +time_t offset; +{ + long days, rem; + register int y; + register unsigned short int *ip; + + days = *t / SECS_PER_DAY; + rem = *t % SECS_PER_DAY; + rem += offset; + while (rem < 0) + { + rem += SECS_PER_DAY; + --days; + } + while (rem >= SECS_PER_DAY) + { + rem -= SECS_PER_DAY; + ++days; + } + tmbuf->tm_hour = rem / SECS_PER_HOUR; + rem %= SECS_PER_HOUR; + tmbuf->tm_min = rem / 60; + tmbuf->tm_sec = rem % 60; + /* January 1, 1970 was a Thursday. */ + tmbuf->tm_wday = (4 + days) % 7; + if (tmbuf->tm_wday < 0) + tmbuf->tm_wday += 7; + y = 1970; + while (days >= (rem = __isleap(y) ? 366 : 365)) + { + ++y; + days -= rem; + } + while (days < 0) + { + --y; + days += __isleap(y) ? 366 : 365; + } + tmbuf->tm_year = y - 1900; + tmbuf->tm_yday = days; + ip = __mon_lengths[__isleap(y)]; + for (y = 0; days >= ip[y]; ++y) + days -= ip[y]; + tmbuf->tm_mon = y; + tmbuf->tm_mday = days + 1; + tmbuf->tm_isdst = -1; +} + +#endif diff --git a/libc/pwd_grp/Makefile b/libc/pwd_grp/Makefile new file mode 100644 index 000000000..ce5064852 --- /dev/null +++ b/libc/pwd_grp/Makefile @@ -0,0 +1,33 @@ +# Copyright (C) 1996 Nat Friedman <ndf@aleph1.mit.edu> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -I../include + +CFLAGS=$(ARCH) -ansi $(CCFLAGS) $(DEFS) + +PSRC=__getpwent.c pwent.c getpwnam.c getpwuid.c putpwent.c getpw.c fgetpwent.c +GSRC=__getgrent.c grent.c getgrnam.c getgrgid.c fgetgrent.c initgroups.c \ + config-grp.h +USRC=utent.c + +POBJ=__getpwent.o pwent.o getpwnam.o getpwuid.o putpwent.o getpw.o fgetpwent.o +GOBJ=__getgrent.o grent.o getgrnam.o getgrgid.o fgetgrent.o initgroups.o +UOBJ=utent.o + +OBJ=$(POBJ) $(GOBJ) $(UOBJ) + +all: $(LIBC)($(OBJ)) + @$(RM) $(OBJ) + +$(LIBC)($(GOBJ)): config-grp.h + +clean: + rm -f *.o libc.a + diff --git a/libc/pwd_grp/__getgrent.c b/libc/pwd_grp/__getgrent.c new file mode 100644 index 000000000..612f1124d --- /dev/null +++ b/libc/pwd_grp/__getgrent.c @@ -0,0 +1,168 @@ +/* + * __getgrent.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <stdlib.h> +#include <string.h> +#include <grp.h> +#include "config.h" + +/* + * This is the core group-file read function. It behaves exactly like + * getgrent() except that it is passed a file descriptor. getgrent() + * is just a wrapper for this function. + */ +struct group * +__getgrent(int grp_fd) +{ +#ifndef GR_SCALE_DYNAMIC + static char line_buff[GR_MAX_LINE_LEN]; + static char * members[GR_MAX_MEMBERS]; +#else + static char * line_buff = NULL; + static char ** members = NULL; + short line_index; + short buff_size; +#endif + static struct group group; + register char * ptr; + char * field_begin; + short member_num; + char * endptr; + int line_len; + + + /* We use the restart label to handle malformatted lines */ +restart: +#ifdef GR_SCALE_DYNAMIC + line_index=0; + buff_size=256; +#endif + +#ifndef GR_SCALE_DYNAMIC + /* Read the line into the static buffer */ + if ((line_len=read(grp_fd, line_buff, GR_MAX_LINE_LEN))<=0) + return NULL; + field_begin=strchr(line_buff, '\n'); + if (field_begin!=NULL) + lseek(grp_fd, (long) (1+field_begin-(line_buff+line_len)), SEEK_CUR); + else /* The line is too long - skip it :-\ */ + { + do { if ((line_len=read(grp_fd, line_buff, GR_MAX_LINE_LEN))<=0) + return NULL; + } while (!(field_begin=strchr(line_buff, '\n'))); + lseek(grp_fd, (long) ((field_begin-line_buff)-line_len+1), SEEK_CUR); + goto restart; + } + if (*line_buff=='#' || *line_buff==' ' || *line_buff=='\n' || + *line_buff=='\t') + goto restart; + *field_begin='\0'; + +#else /* !GR_SCALE_DYNAMIC */ + line_buff=realloc(line_buff, buff_size); + while (1) + { + if ((line_len=read(grp_fd, line_buff+line_index, + buff_size-line_index))<=0) + return NULL; + field_begin=strchr(line_buff, '\n'); + if (field_begin!=NULL) + { + lseek(grp_fd, (long) (1+field_begin-(line_len+line_index+line_buff)), + SEEK_CUR); + *field_begin='\0'; + if (*line_buff=='#' || *line_buff==' ' || *line_buff=='\n' || + *line_buff=='\t') + goto restart; + break; + } + else /* Allocate some more space */ + { + line_index=buff_size; + buff_size+=256; + line_buff=realloc(line_buff, buff_size); + } + } +#endif /* GR_SCALE_DYNAMIC */ + + /* Now parse the line */ + group.gr_name=line_buff; + ptr=strchr(line_buff, ':'); + if (ptr==NULL) goto restart; + *ptr++='\0'; + + group.gr_passwd=ptr; + ptr=strchr(ptr, ':'); + if (ptr==NULL) goto restart; + *ptr++='\0'; + + field_begin=ptr; + ptr=strchr(ptr, ':'); + if (ptr==NULL) goto restart; + *ptr++='\0'; + + group.gr_gid=(gid_t) strtoul(field_begin, &endptr, 10); + if (*endptr!='\0') goto restart; + + member_num=0; + field_begin=ptr; + +#ifndef GR_SCALE_DYNAMIC + while ((ptr=strchr(ptr, ','))!=NULL) + { + *ptr='\0'; + ptr++; + members[member_num]=field_begin; + field_begin=ptr; + member_num++; + } + if (*field_begin=='\0') + members[member_num]=NULL; + else + { + members[member_num]=field_begin; + members[member_num+1]=NULL; + } +#else /* !GR_SCALE_DYNAMIC */ + if (members!=NULL) + free (members); + members=(char **) malloc(1*sizeof(char *)); + while ((ptr=strchr(ptr, ','))!=NULL) + { + *ptr='\0'; + ptr++; + members[member_num]=field_begin; + field_begin=ptr; + member_num++; + members=(char **)realloc((void *)members, (member_num+1)*sizeof(char *)); + } + if (*field_begin=='\0') + members[member_num]=NULL; + else + { + members[member_num]=field_begin; + members[member_num+1]=NULL; + } +#endif /* GR_SCALE_DYNAMIC */ + + group.gr_mem=members; + return &group; +} diff --git a/libc/pwd_grp/config.h b/libc/pwd_grp/config.h new file mode 100644 index 000000000..699434b2a --- /dev/null +++ b/libc/pwd_grp/config.h @@ -0,0 +1,65 @@ +/* + * config-grp.h - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + + +#ifndef _CONFIG_GRP_H +#define _CONFIG_GRP_H + +/* + * Define GR_SCALE_DYNAMIC if you want grp to dynamically scale its read buffer + * so that lines of any length can be used. On very very small systems, + * you may want to leave this undefined becasue it will make the grp functions + * somewhat larger (because of the inclusion of malloc and the code necessary). + * On larger systems, you will want to define this, because grp will _not_ + * deal with long lines gracefully (they will be skipped). + */ +#undef GR_SCALE_DYNAMIC + +#ifndef GR_SCALE_DYNAMIC +/* + * If scaling is not dynamic, the buffers will be statically allocated, and + * maximums must be chosen. GR_MAX_LINE_LEN is the maximum number of + * characters per line in the group file. GR_MAX_MEMBERS is the maximum + * number of members of any given group. + */ +#define GR_MAX_LINE_LEN 128 +/* GR_MAX_MEMBERS = (GR_MAX_LINE_LEN-(24+3+6))/9 */ +#define GR_MAX_MEMBERS 11 + +#endif /* !GR_SCALE_DYNAMIC */ + + +/* + * Define GR_DYNAMIC_GROUP_LIST to make initgroups() dynamically allocate + * space for it's GID array before calling setgroups(). This is probably + * unnecessary scalage, so it's undefined by default. + */ +#undef GR_DYNAMIC_GROUP_LIST + +#ifndef GR_DYNAMIC_GROUP_LIST +/* + * GR_MAX_GROUPS is the size of the static array initgroups() uses for + * its static GID array if GR_DYNAMIC_GROUP_LIST isn't defined. + */ +#define GR_MAX_GROUPS 64 + +#endif /* !GR_DYNAMIC_GROUP_LIST */ + +#endif /* !_CONFIG_GRP_H */ diff --git a/libc/pwd_grp/fgetgrent.c b/libc/pwd_grp/fgetgrent.c new file mode 100644 index 000000000..800236fcc --- /dev/null +++ b/libc/pwd_grp/fgetgrent.c @@ -0,0 +1,35 @@ +/* + * fgetgrent.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <errno.h> +#include <grp.h> + +struct group * +fgetgrent(FILE * file) +{ + if (file==NULL) + { + errno=EINTR; + return NULL; + } + + return __getgrent(fileno(file)); +} diff --git a/libc/pwd_grp/fgetpwent.c b/libc/pwd_grp/fgetpwent.c new file mode 100644 index 000000000..e12b89051 --- /dev/null +++ b/libc/pwd_grp/fgetpwent.c @@ -0,0 +1,35 @@ +/* + * fgetpwent.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <errno.h> +#include <stdio.h> +#include <pwd.h> + +struct passwd * +fgetpwent(FILE * file) +{ + if (file==NULL) + { + errno=EINTR; + return NULL; + } + + return __getpwent(fileno(file)); +} diff --git a/libc/pwd_grp/getgrgid.c b/libc/pwd_grp/getgrgid.c new file mode 100644 index 000000000..c1dd20e35 --- /dev/null +++ b/libc/pwd_grp/getgrgid.c @@ -0,0 +1,48 @@ +/* + * getgrgid.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <sys/types.h> +#include <unistd.h> +#include <fcntl.h> +#include <grp.h> + +struct group * +getgrgid(const gid_t gid) +{ + struct group * group; + int grp_fd; + + if ((grp_fd=open("/etc/group", O_RDONLY))<0) + return NULL; + + while ((group=__getgrent(grp_fd))!=NULL) + if (group->gr_gid==gid) + { + close(grp_fd); + return group; + } + + close(grp_fd); + return NULL; +} + + + + diff --git a/libc/pwd_grp/getgrnam.c b/libc/pwd_grp/getgrnam.c new file mode 100644 index 000000000..e6c27fc57 --- /dev/null +++ b/libc/pwd_grp/getgrnam.c @@ -0,0 +1,51 @@ +/* + * getgrnam.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <grp.h> + +struct group * +getgrnam(const char * name) +{ + int grp_fd; + struct group * group; + + if (name==NULL) + { + errno=EINVAL; + return NULL; + } + + if ((grp_fd=open("/etc/group", O_RDONLY))<0) + return NULL; + + while ((group=__getgrent(grp_fd))!=NULL) + if (!strcmp(group->gr_name, name)) + { + close(grp_fd); + return group; + } + + close(grp_fd); + return NULL; +} diff --git a/libc/pwd_grp/getpw.c b/libc/pwd_grp/getpw.c new file mode 100644 index 000000000..4f4e39025 --- /dev/null +++ b/libc/pwd_grp/getpw.c @@ -0,0 +1,51 @@ +/* + * getpw.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <sys/types.h> +#include <errno.h> +#include <stdio.h> +#include <pwd.h> + +int +getpw(uid_t uid, char *buf) +{ + struct passwd * passwd; + + if (buf==NULL) + { + errno=EINVAL; + return -1; + } + if ((passwd=getpwuid(uid))==NULL) + return -1; + + if (sprintf(buf, "%s:%s:%u:%u:%s:%s:%s", passwd->pw_name, passwd->pw_passwd, + passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, + passwd->pw_dir, passwd->pw_shell)<0) + { + errno=ENOBUFS; + return -1; + } + + return 0; +} + + + diff --git a/libc/pwd_grp/getpwnam.c b/libc/pwd_grp/getpwnam.c new file mode 100644 index 000000000..85dbc8ed8 --- /dev/null +++ b/libc/pwd_grp/getpwnam.c @@ -0,0 +1,52 @@ +/* + * getpwnam.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <string.h> +#include <errno.h> +#include <fcntl.h> +#include <pwd.h> + + +struct passwd * +getpwnam(const char * name) +{ + int passwd_fd; + struct passwd * passwd; + + if (name==NULL) + { + errno=EINVAL; + return NULL; + } + + if ((passwd_fd=open("/etc/passwd", O_RDONLY))<0) + return NULL; + + while ((passwd=__getpwent(passwd_fd))!=NULL) + if (!strcmp(passwd->pw_name, name)) + { + close(passwd_fd); + return passwd; + } + + close(passwd_fd); + return NULL; +} diff --git a/libc/pwd_grp/getpwuid.c b/libc/pwd_grp/getpwuid.c new file mode 100644 index 000000000..ffd58c1f0 --- /dev/null +++ b/libc/pwd_grp/getpwuid.c @@ -0,0 +1,44 @@ +/* + * getpwuid.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <pwd.h> + +struct passwd * +getpwuid(uid_t uid) +{ + int passwd_fd; + struct passwd * passwd; + + if ((passwd_fd=open("/etc/passwd", O_RDONLY))<0) + return NULL; + + while ((passwd=__getpwent(passwd_fd))!=NULL) + if (passwd->pw_uid==uid) + { + close(passwd_fd); + return passwd; + } + + close (passwd_fd); + return NULL; +} diff --git a/libc/pwd_grp/grent.c b/libc/pwd_grp/grent.c new file mode 100644 index 000000000..19d618b2b --- /dev/null +++ b/libc/pwd_grp/grent.c @@ -0,0 +1,57 @@ +/* + * grent.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +/* + * setgrent(), endgrent(), and getgrent() are mutually-dependent functions, + * so they are all included in the same object file, and thus all linked + * in together. + */ + +#include <unistd.h> +#include <fcntl.h> +#include <grp.h> + +static int grp_fd=-1; + +void +setgrent(void) +{ + if (grp_fd!=-1) + close(grp_fd); + grp_fd=open("/etc/group", O_RDONLY); +} + +void +endgrent(void) +{ + if (grp_fd!=-1) + close(grp_fd); + grp_fd=-1; +} + +struct group * +getgrent(void) +{ + if (grp_fd==-1) + return NULL; + return __getgrent(grp_fd); +} + + diff --git a/libc/pwd_grp/initgroups.c b/libc/pwd_grp/initgroups.c new file mode 100644 index 000000000..35e1d03ec --- /dev/null +++ b/libc/pwd_grp/initgroups.c @@ -0,0 +1,80 @@ +/* + * initgroups.c - This file is part of the libc-8086/grp package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <string.h> +#include <fcntl.h> +#include <grp.h> +#include "config.h" + +int +initgroups(__const char * user, gid_t gid) +{ + register struct group * group; +#ifndef GR_DYNAMIC_GROUP_LIST + gid_t group_list[GR_MAX_GROUPS]; +#else + gid_t * group_list=NULL; +#endif + register char ** tmp_mem; + int num_groups; + int grp_fd; + + + if ((grp_fd=open("/etc/group", O_RDONLY))<0) + return -1; + + num_groups=0; +#ifdef GR_DYNAMIC_GROUP_LIST + group_list=(gid_t *) realloc(group_list, 1); +#endif + group_list[num_groups]=gid; +#ifndef GR_DYNAMIC_GROUP_LIST + while (num_groups<GR_MAX_GROUPS && + (group=__getgrent(grp_fd))!=NULL) +#else + while ((group=__getgrent(grp_fd))!=NULL) +#endif + { + if (group->gr_gid!=gid); + { + tmp_mem=group->gr_mem; + while(*tmp_mem!=NULL) + { + if (!strcmp(*tmp_mem, user)) + { + num_groups++; +#ifdef GR_DYNAMIC_GROUP_LIST + group_list=(gid_t *)realloc(group_list, + num_groups*sizeof(gid_t *)); +#endif + group_list[num_groups]=group->gr_gid; + } + tmp_mem++; + } + } + } + close(grp_fd); + return setgroups(num_groups, group_list); +} + + + + diff --git a/libc/pwd_grp/putpwent.c b/libc/pwd_grp/putpwent.c new file mode 100644 index 000000000..a0035ea98 --- /dev/null +++ b/libc/pwd_grp/putpwent.c @@ -0,0 +1,39 @@ +/* + * putpwent.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <stdio.h> +#include <errno.h> +#include <pwd.h> + +int +putpwent(const struct passwd * passwd, FILE * f) +{ + if (passwd == NULL || f == NULL) + { + errno=EINVAL; + return -1; + } + if (fprintf(f, "%s:%s:%u:%u:%s:%s:%s\n", passwd->pw_name, passwd->pw_passwd, + passwd->pw_gid, passwd->pw_uid, passwd->pw_gecos, + passwd->pw_dir, passwd->pw_shell)<0) + return -1; + + return 0; +} diff --git a/libc/pwd_grp/pwent.c b/libc/pwd_grp/pwent.c new file mode 100644 index 000000000..fd65db21a --- /dev/null +++ b/libc/pwd_grp/pwent.c @@ -0,0 +1,62 @@ +/* + * pwent.c - This file is part of the libc-8086/pwd package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ + +#include <unistd.h> +#include <stdlib.h> +#include <errno.h> +#include <pwd.h> +#include <fcntl.h> + +/* + * setpwent(), endpwent(), and getpwent() are included in the same object + * file, since one cannot be used without the other two, so it makes sense to + * link them all in together. + */ + +/* file descriptor for the password file currently open */ +static int pw_fd = -1; + +void +setpwent(void) +{ + if (pw_fd!=-1) + close(pw_fd); + + pw_fd=open("/etc/passwd", O_RDONLY); +} + +void +endpwent(void) +{ + if (pw_fd!=-1) + close(pw_fd); + pw_fd=-1; +} + +struct passwd * +getpwent(void) +{ + if (pw_fd!=-1) + return __getpwent(pw_fd); + return NULL; +} + + + diff --git a/libc/stdio/Makefile b/libc/stdio/Makefile new file mode 100644 index 000000000..badf78c56 --- /dev/null +++ b/libc/stdio/Makefile @@ -0,0 +1,53 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -I../include + +ASRC=stdio.c +AOBJ=_stdio_init.o fputc.o fgetc.o fflush.o fgets.o gets.o fputs.o \ + puts.o fread.o fwrite.o fopen.o fclose.o fseek.o rewind.o ftell.o \ + setbuffer.o setvbuf.o ungetc.o + +PSRC=printf.c +POBJ=printf.o sprintf.o fprintf.o vprintf.o vsprintf.o vfprintf.o + +SSRC=scanf.c +SOBJ=scanf.o sscanf.o fscanf.o vscanf.o vsscanf.o vfscanf.o + +OBJ= $(AOBJ) $(POBJ) $(SOBJ) dputs.o + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(AOBJ)): $(ASRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)($(POBJ)): $(PSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)($(SOBJ)): $(SSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +transfer: + -@rm -f ../include/stdio.h + cp -p stdio.h ../include/. + +clean: + rm -f *.o libc.a + +$(LIBC)($(OBJ)): stdio.h + diff --git a/libc/stdio/printf.c b/libc/stdio/printf.c new file mode 100644 index 000000000..873f1cb41 --- /dev/null +++ b/libc/stdio/printf.c @@ -0,0 +1,387 @@ +/* + * This file based on printf.c from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ + +/* Altered to use stdarg, made the core function vfprintf. + * Hooked into the stdio package using 'inside information' + * Altered sizeof() assumptions, now assumes all integers except chars + * will be either + * sizeof(xxx) == sizeof(long) or sizeof(xxx) == sizeof(short) + * + * -RDB + */ + +#include <sys/types.h> +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> + +#ifdef __STDC__ +#include <stdarg.h> +#define va_strt va_start +#else +#include <varargs.h> +#define va_strt(p,i) va_start(p) +#endif + +#include "stdio.h" + +#ifdef L_printf + +#ifdef __STDC__ +int printf(const char * fmt, ...) +#else +int printf(fmt, va_alist) +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + + va_strt(ptr, fmt); + rv = vfprintf(stdout,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_sprintf +#ifdef __STDC__ +int sprintf(char * sp, const char * fmt, ...) +#else +int sprintf(sp, fmt, va_alist) +char * sp; +__const char *fmt; +va_dcl +#endif +{ +static FILE string[1] = +{ + {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_WRITE} +}; + + va_list ptr; + int rv; + va_strt(ptr, fmt); + string->bufpos = sp; + rv = vfprintf(string,fmt,ptr); + va_end(ptr); + *(string->bufpos) = 0; + return rv; +} +#endif + +#ifdef L_fprintf +#ifdef __STDC__ +int fprintf(FILE * fp, const char * fmt, ...) +#else +int fprintf(fp, fmt, va_alist) +FILE * fp; +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vfprintf(fp,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_vprintf +int vprintf(fmt, ap) +__const char *fmt; +va_list ap; +{ + return vfprintf(stdout,fmt,ap); +} +#endif + +#ifdef L_vsprintf +int vsprintf(sp, fmt, ap) +char * sp; +__const char *fmt; +va_list ap; +{ +static FILE string[1] = +{ + {0, 0, (char*)(unsigned) -1, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_WRITE} +}; + + int rv; + string->bufpos = sp; + rv = vfprintf(string,fmt,ap); + *(string->bufpos) = 0; + return rv; +} +#endif + +#ifdef L_vfprintf + +#if FLOATS +int _vfprintf_fp_ref = 1; +#else +int _vfprintf_fp_ref = 0; +#endif + +static int +prtfld(op, buf, ljustf, sign, pad, width, preci, buffer_mode) +register FILE *op; +register unsigned char *buf; +int ljustf; +register char sign; +char pad; +register int width; +int preci; +int buffer_mode; +/* + * Output the given field in the manner specified by the arguments. Return + * the number of characters output. + */ +{ + register int cnt = 0, len; + register unsigned char ch; + + len = strlen(buf); + + if (*buf == '-') + sign = *buf++; + else if (sign) + len++; + + if ((preci != -1) && (len > preci)) /* limit max data width */ + len = preci; + + if (width < len) /* flexible field width or width overflow */ + width = len; + + /* + * at this point: width = total field width len = actual data width + * (including possible sign character) + */ + cnt = width; + width -= len; + + while (width || len) + { + if (!ljustf && width) /* left padding */ + { + if (len && sign && (pad == '0')) + goto showsign; + ch = pad; + --width; + } + else if (len) + { + if (sign) + { + showsign:ch = sign; /* sign */ + sign = '\0'; + } + else + ch = *buf++; /* main field */ + --len; + } + else + { + ch = pad; /* right padding */ + --width; + } + putc(ch, op); + if( ch == '\n' && buffer_mode == _IOLBF ) fflush(op); + } + + return (cnt); +} + +int +vfprintf(op, fmt, ap) +FILE *op; +register __const char *fmt; +register va_list ap; +{ + register int i, cnt = 0, ljustf, lval; + int preci, dpoint, width; + char pad, sign, radix, hash; + register char *ptmp; + char tmp[64], *ltostr(), *ultostr(); + int buffer_mode; + + /* This speeds things up a bit for unbuffered */ + buffer_mode = (op->mode&__MODE_BUF); + op->mode &= (~__MODE_BUF); + + while (*fmt) + { + if (*fmt == '%') + { + if( buffer_mode == _IONBF ) fflush(op); + ljustf = 0; /* left justify flag */ + sign = '\0'; /* sign char & status */ + pad = ' '; /* justification padding char */ + width = -1; /* min field width */ + dpoint = 0; /* found decimal point */ + preci = -1; /* max data width */ + radix = 10; /* number base */ + ptmp = tmp; /* pointer to area to print */ + hash = 0; + lval = (sizeof(int)==sizeof(long)); /* long value flaged */ + fmtnxt: + i = 0; + for(;;) + { + ++fmt; + if(*fmt < '0' || *fmt > '9' ) break; + i = (i * 10) + (*fmt - '0'); + if (dpoint) + preci = i; + else if (!i && (pad == ' ')) + { + pad = '0'; + goto fmtnxt; + } + else + width = i; + } + + switch (*fmt) + { + case '\0': /* early EOS */ + --fmt; + goto charout; + + case '-': /* left justification */ + ljustf = 1; + goto fmtnxt; + + case ' ': + case '+': /* leading sign flag */ + sign = *fmt; + goto fmtnxt; + + case '*': /* parameter width value */ + i = va_arg(ap, int); + if (dpoint) + preci = i; + else + width = i; + goto fmtnxt; + + case '.': /* secondary width field */ + dpoint = 1; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'd': /* Signed decimal */ + case 'i': + ptmp = ltostr((long) ((lval) + ? va_arg(ap, long) + : va_arg(ap, short)), + 10, 0); + goto printit; + + case 'b': /* Unsigned binary */ + radix = 2; + goto usproc; + + case 'o': /* Unsigned octal */ + radix = 8; + goto usproc; + + case 'p': /* Pointer */ + lval = (sizeof(char*) == sizeof(long)); + pad = '0'; + width = 6; + preci = 8; + /* fall thru */ + + case 'x': /* Unsigned hexadecimal */ + case 'X': + radix = 16; + /* fall thru */ + + case 'u': /* Unsigned decimal */ + usproc: + ptmp = ultostr((unsigned long) ((lval) + ? va_arg(ap, unsigned long) + : va_arg(ap, unsigned short)), + radix, (*fmt == 'X') ? 1 : 0); + if( hash && radix == 8 ) { width = strlen(ptmp)+1; pad='0'; } + goto printit; + + case '#': + hash=1; + goto fmtnxt; + + case 'c': /* Character */ + ptmp[0] = va_arg(ap, int); + ptmp[1] = '\0'; + goto nopad; + + case 's': /* String */ + ptmp = va_arg(ap, char*); + nopad: + sign = '\0'; + pad = ' '; + printit: + cnt += prtfld(op, ptmp, ljustf, + sign, pad, width, preci, buffer_mode); + break; + +#if FLOATS + case 'e': /* float */ + case 'f': + case 'g': + case 'E': + case 'G': + fprintf(stderr, "LIBM:PRINTF"); + gcvt(va_arg(ap, double), preci, ptmp); + preci = -1; + goto printit; +#else + case 'e': /* float */ + case 'f': + case 'g': + case 'E': + case 'G': + fprintf(stderr, "LIBC:PRINTF"); + exit(-1); +#endif + + default: /* unknown character */ + goto charout; + } + } + else + { + charout: + putc(*fmt, op); /* normal char out */ + ++cnt; + if( *fmt == '\n' && buffer_mode == _IOLBF ) fflush(op); + } + ++fmt; + } + op->mode |= buffer_mode; + if( buffer_mode == _IONBF ) fflush(op); + if( buffer_mode == _IOLBF ) op->bufwrite = op->bufstart; + return (cnt); +} +#endif diff --git a/libc/stdio/scanf.c b/libc/stdio/scanf.c new file mode 100644 index 000000000..7c5f52183 --- /dev/null +++ b/libc/stdio/scanf.c @@ -0,0 +1,536 @@ +#include <stdio.h> +#include <ctype.h> +#include <string.h> + +#ifdef __STDC__ +#include <stdarg.h> +#define va_strt va_start +#else +#include <varargs.h> +#define va_strt(p,i) va_start(p) +#endif + +#ifdef L_scanf +#ifdef __STDC__ +int scanf(const char * fmt, ...) +#else +int scanf(fmt, va_alist) +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vfscanf(stdin,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_sscanf +#ifdef __STDC__ +int sscanf(char * sp, const char * fmt, ...) +#else +int sscanf(sp, fmt, va_alist) +char * sp; +__const char *fmt; +va_dcl +#endif +{ +static FILE string[1] = +{ + {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_READ} +}; + + va_list ptr; + int rv; + va_strt(ptr, fmt); + string->bufpos = sp; + rv = vfscanf(string,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_fscanf +#ifdef __STDC__ +int fscanf(FILE * fp, const char * fmt, ...) +#else +int fscanf(fp, fmt, va_alist) +FILE * fp; +__const char *fmt; +va_dcl +#endif +{ + va_list ptr; + int rv; + va_strt(ptr, fmt); + rv = vfscanf(fp,fmt,ptr); + va_end(ptr); + return rv; +} +#endif + +#ifdef L_vscanf +int vscanf(fmt, ap) +__const char *fmt; +va_list ap; +{ + return vfscanf(stdin,fmt,ap); +} +#endif + +#ifdef L_vsscanf +int vsscanf(sp, fmt, ap) +char * sp; +__const char *fmt; +{ +static FILE string[1] = +{ + {0, (char*)(unsigned) -1, 0, 0, (char*) (unsigned) -1, -1, + _IOFBF | __MODE_READ} +}; + + string->bufpos = sp; + return vfscanf(string,fmt,ap); +} +#endif + +#ifdef L_vfscanf + +#if FLOATS +int _vfscanf_fp_ref = 1; +#else +int _vfscanf_fp_ref = 0; +#endif + +/* #define skip() do{c=getc(fp); if (c<1) goto done;}while(isspace(c))*/ + +#define skip() while(isspace(c)) { if ((c=getc(fp))<1) goto done; } + +#if FLOATS +/* fp scan actions */ +#define F_NADA 0 /* just change state */ +#define F_SIGN 1 /* set sign */ +#define F_ESIGN 2 /* set exponent's sign */ +#define F_INT 3 /* adjust integer part */ +#define F_FRAC 4 /* adjust fraction part */ +#define F_EXP 5 /* adjust exponent part */ +#define F_QUIT 6 + +#define NSTATE 8 +#define FS_INIT 0 /* initial state */ +#define FS_SIGNED 1 /* saw sign */ +#define FS_DIGS 2 /* saw digits, no . */ +#define FS_DOT 3 /* saw ., no digits */ +#define FS_DD 4 /* saw digits and . */ +#define FS_E 5 /* saw 'e' */ +#define FS_ESIGN 6 /* saw exp's sign */ +#define FS_EDIGS 7 /* saw exp's digits */ + +#define FC_DIG 0 +#define FC_DOT 1 +#define FC_E 2 +#define FC_SIGN 3 + +/* given transition,state do what action? */ +int fp_do[][NSTATE] = { + {F_INT,F_INT,F_INT, + F_FRAC,F_FRAC, + F_EXP,F_EXP,F_EXP}, /* see digit */ + {F_NADA,F_NADA,F_NADA, + F_QUIT,F_QUIT,F_QUIT,F_QUIT,F_QUIT}, /* see '.' */ + {F_QUIT,F_QUIT, + F_NADA,F_QUIT,F_NADA, + F_QUIT,F_QUIT,F_QUIT}, /* see e/E */ + {F_SIGN,F_QUIT,F_QUIT,F_QUIT,F_QUIT, + F_ESIGN,F_QUIT,F_QUIT}, /* see sign */ +}; +/* given transition,state what is new state? */ +int fp_ns[][NSTATE] = { + {FS_DIGS,FS_DIGS,FS_DIGS, + FS_DD,FS_DD, + FS_EDIGS,FS_EDIGS,FS_EDIGS}, /* see digit */ + {FS_DOT,FS_DOT,FS_DD, + }, /* see '.' */ + {0,0, + FS_E,0,FS_E, + }, /* see e/E */ + {FS_SIGNED,0,0,0,0, + FS_ESIGN,0,0}, /* see sign */ +}; +/* which states are valid terminators? */ +int fp_sval[NSTATE] = { + 0,0,1,0,1,0,0,1 +}; +#endif + +int +vfscanf(fp, fmt, ap) +register FILE *fp; +register char *fmt; +va_list ap; + +{ + register long n; + register int c, width, lval, cnt = 0; + int store, neg, base, wide1, endnull, rngflag, c2; + register unsigned char *p; + unsigned char delim[128], digits[17], *q; +#if FLOATS + long frac, expo; + int eneg, fraclen, fstate, trans; + double fx, fp_scan(); +#endif + + if (!*fmt) + return (0); + + c = getc(fp); + while (c > 0) + { + store = 0; + if (*fmt == '%') + { + n = 0; + width = -1; + wide1 = 1; + base = 10; + lval = (sizeof(long) == sizeof(int)); + store = 1; + endnull = 1; + neg = -1; + + strcpy(delim, "\011\012\013\014\015 "); + strcpy(digits, "0123456789ABCDEF"); + + if (fmt[1] == '*') + { + endnull = store = 0; + ++fmt; + } + + while (isdigit(*++fmt))/* width digit(s) */ + { + if (width == -1) + width = 0; + wide1 = width = (width * 10) + (*fmt - '0'); + } + --fmt; + fmtnxt: + ++fmt; + switch (tolower(*fmt)) /* tolower() is a MACRO! */ + { + case '*': + endnull = store = 0; + goto fmtnxt; + + case 'l': /* long data */ + lval = 1; + goto fmtnxt; + case 'h': /* short data */ + lval = 0; + goto fmtnxt; + + case 'i': /* any-base numeric */ + base = 0; + goto numfmt; + + case 'b': /* unsigned binary */ + base = 2; + goto numfmt; + + case 'o': /* unsigned octal */ + base = 8; + goto numfmt; + + case 'x': /* unsigned hexadecimal */ + base = 16; + goto numfmt; + + case 'd': /* SIGNED decimal */ + neg = 0; + /* FALL-THRU */ + + case 'u': /* unsigned decimal */ + numfmt:skip(); + + if (isupper(*fmt)) + lval = 1; + + if (!base) + { + base = 10; + neg = 0; + if (c == '%') + { + base = 2; + goto skip1; + } + else if (c == '0') + { + c = getc(fp); + if (c < 1) + goto savnum; + if ((c != 'x') + && (c != 'X')) + { + base = 8; + digits[8] = '\0'; + goto zeroin; + } + base = 16; + goto skip1; + } + } + + if ((neg == 0) && (base == 10) + && ((neg = (c == '-')) || (c == '+'))) + { + skip1: + c = getc(fp); + if (c < 1) + goto done; + } + + digits[base] = '\0'; + p = ((unsigned char *) + strchr(digits, toupper(c))); + + if ((!c || !p) && width) + goto done; + + while (p && width-- && c) + { + n = (n * base) + (p - digits); + c = getc(fp); + zeroin: + p = ((unsigned char *) + strchr(digits, toupper(c))); + } + savnum: + if (store) + { + if (neg == 1) + n = -n; + if (lval) + *va_arg(ap, long*) = n; + else + *va_arg(ap, short*) = n; + ++cnt; + } + break; + +#if FLOATS + case 'e': /* float */ + case 'f': + case 'g': + skip(); + fprintf(stderr,"LIBM:SCANF"); + + if (isupper(*fmt)) + lval = 1; + + fstate = FS_INIT; + neg = 0; + eneg = 0; + n = 0; + frac = 0; + expo = 0; + fraclen = 0; + + while (c && width--) + { + if (c >= '0' && c <= '9') + trans = FC_DIG; + else if (c == '.') + trans = FC_DOT; + else if (c == '+' || c == '-') + trans = FC_SIGN; + else if (tolower(c) == 'e') + trans = FC_E; + else + goto fdone; + + switch (fp_do[trans][fstate]) + { + case F_SIGN: + neg = (c == '-'); + break; + case F_ESIGN: + eneg = (c == '-'); + break; + case F_INT: + n = 10 * n + (c - '0'); + break; + case F_FRAC: + frac = 10 * frac + (c - '0'); + fraclen++; + break; + case F_EXP: + expo = 10 * expo + (c - '0'); + break; + case F_QUIT: + goto fdone; + } + fstate = fp_ns[trans][fstate]; + c = getc(fp); + } + + fdone: + if (!fp_sval[fstate]) + goto done; + if (store) + { + fx = fp_scan(neg, eneg, n, frac, expo, fraclen); + if (lval) + *va_arg(ap, double *) = fx; + else + *va_arg(ap, float *) = fx; + ++cnt; + } + break; +#else + case 'e': /* float */ + case 'f': + case 'g': + fprintf(stderr, "LIBC:SCANF"); + exit(-1); +#endif + + case 'c': /* character data */ + width = wide1; + lval = endnull = 0; + delim[0] = '\0'; + goto strproc; + + case '[': /* string w/ delimiter set */ + + /* get delimiters */ + p = delim; + + if (*++fmt == '^') + { + fmt++; + lval = 0; + } + else + lval = 1; + + rngflag = 2; + if ((*fmt == ']') || (*fmt == '-')) + { + *p++ = *fmt++; + rngflag = 0; + } + + while (*fmt != ']') + { + if (*fmt == '\0') + goto done; + switch (rngflag) + { + case 1: + c2 = *(p - 2); + if (c2 <= *fmt) + { + p -= 2; + while (c2 < *fmt) + *p++ = c2++; + rngflag = 2; + break; + } + /* fall thru intentional */ + + case 0: + rngflag = (*fmt == '-'); + break; + + case 2: + rngflag = 0; + } + + *p++ = *fmt++; + } + + *p = '\0'; + goto strproc; + + case 's': /* string data */ + lval = 0; + skip(); + strproc: + /* process string */ + p = va_arg(ap, unsigned char *); + + /* if the 1st char fails, match fails */ + if (width) + { + q = ((unsigned char *) + strchr(delim, c)); + if ((c < 1) || lval == (q==0)) + { + if (endnull) + *p = '\0'; + goto done; + } + } + + for (;;) /* FOREVER */ + { + if (store) + *p++ = c; + if (((c = getc(fp)) < 1) || + (--width == 0)) + break; + + q = ((unsigned char *) + strchr(delim, c)); + if (lval == (q==0)) + break; + } + + if (store) + { + if (endnull) + *p = '\0'; + ++cnt; + } + break; + + case '\0': /* early EOS */ + --fmt; + /* FALL THRU */ + + default: + goto cmatch; + } + } + else if (isspace(*fmt)) /* skip whitespace */ + { + skip(); + } + else + { /* normal match char */ + cmatch: + if (c != *fmt) + break; + c = getc(fp); + } + + if (!*++fmt) + break; + } + + done: /* end of scan */ + if ((c == EOF) && (cnt == 0)) + return (EOF); + + if( c != EOF ) + ungetc(c, fp); + return (cnt); +} + +#endif diff --git a/libc/stdio/stdio.c b/libc/stdio/stdio.c new file mode 100644 index 000000000..98d0ba3b4 --- /dev/null +++ b/libc/stdio/stdio.c @@ -0,0 +1,925 @@ +/* Copyright (C) 1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* This is an implementation of the C standard IO package. + */ + +#include <stdio.h> + +#include <fcntl.h> +#include <sys/types.h> +#include <malloc.h> +#include <errno.h> + +#undef STUB_FWRITE + +extern FILE *__IO_list; /* For fflush at exit */ + +#define FIXED_BUFFERS 2 +struct fixed_buffer { + unsigned char data[BUFSIZ]; + int used; +}; + +extern struct fixed_buffer _fixed_buffers[2]; + +#define Inline_init __io_init_vars() + +#ifdef L__stdio_init + +#define buferr (stderr->unbuf) /* Stderr is unbuffered */ + +FILE *__IO_list = 0; /* For fflush at exit */ + +#if 0 +static char bufin[BUFSIZ]; +static char bufout[BUFSIZ]; +#ifndef buferr +static char buferr[BUFSIZ]; +#endif + +#else +static char *bufin; +static char *bufout; +#ifndef buferr +static char *buferr; +#endif +#endif + +FILE stdin[1] = +{ +#if 0 + {bufin, bufin, bufin, bufin, bufin + sizeof(bufin), +#else + {0, 0, 0, 0, 0, +#endif + 0, _IOFBF | __MODE_READ | __MODE_IOTRAN} +}; + +FILE stdout[1] = +{ +#if 0 + {bufout, bufout, bufout, bufout, bufout + sizeof(bufout), +#else + {0, 0, 0, 0, 0, +#endif + 1, _IOFBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +FILE stderr[1] = +{ +#if 0 + {buferr, buferr, buferr, buferr, buferr + sizeof(buferr), +#else + {0, 0, 0, 0, 0, +#endif + 2, _IONBF | __MODE_WRITE | __MODE_IOTRAN} +}; + +/* Call the stdio initiliser; it's main job it to call atexit */ + +#define STATIC + +STATIC int +__stdio_close_all() +{ + FILE *fp; + fflush(stdout); + fflush(stderr); + for (fp = __IO_list; fp; fp = fp->next) + { + fflush(fp); + close(fp->fd); + /* Note we're not de-allocating the memory */ + /* There doesn't seem to be much point :-) */ + fp->fd = -1; + } +} + +static int first_time = 0; + +struct fixed_buffer _fixed_buffers[2]; + + +STATIC void +__io_init_vars() +{ + if( first_time ) return; + first_time = 1; + + stdin->bufpos = bufin = _fixed_buffers[0].data; /*(char *)malloc(BUFSIZ)*/; + stdin->bufread = bufin; + stdin->bufwrite = bufin; + stdin->bufstart = bufin; + stdin->bufend = bufin + sizeof(bufin); + stdin->fd = 0; + stdin->mode = _IOFBF | __MODE_READ | __MODE_IOTRAN | __MODE_FREEBUF; + + _fixed_buffers[0].used = 1; + + stdout->bufpos = bufout = _fixed_buffers[1].data; /*(char *)malloc(BUFSIZ);*/ + stdout->bufread = bufout; + stdout->bufwrite = bufout; + stdout->bufstart = bufout; + stdout->bufend = bufout + sizeof(bufout); + stdout->fd = 1; + stdout->mode = _IOFBF | __MODE_WRITE | __MODE_IOTRAN | __MODE_FREEBUF; + + _fixed_buffers[1].used = 1; + +#if 0 + stderr->bufpos = buferr = (char *)malloc(BUFSIZ); +#else + stderr->bufpos = buferr; +#endif + stderr->bufread = buferr; + stderr->bufwrite = buferr; + stderr->bufstart = buferr; + stderr->bufend = buferr + sizeof(buferr); + stderr->fd = 2; + stderr->mode = _IONBF | __MODE_WRITE | __MODE_IOTRAN; + + if (isatty(1)) + stdout->mode |= _IOLBF; + atexit(__stdio_close_all); +} +#endif + +#ifdef L_fputc +int +fputc(ch, fp) +int ch; +FILE *fp; +{ + register int v; + Inline_init; + + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return EOF; + + /* Can't write or there's been an EOF or error then return EOF */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return EOF; + + /* In MSDOS translation mode */ +#if __MODE_IOTRAN + if (ch == '\n' && (v & __MODE_IOTRAN) && fputc('\r', fp) == EOF) + return EOF; +#endif + + /* Buffer is full */ + if (fp->bufpos >= fp->bufend && fflush(fp)) + return EOF; + + /* Right! Do it! */ + *(fp->bufpos++) = ch; + fp->mode |= __MODE_WRITING; + + /* Unbuffered or Line buffered and end of line */ + if (((ch == '\n' && (v & _IOLBF)) || (v & _IONBF)) + && fflush(fp)) + return EOF; + + /* Can the macro handle this by itself ? */ + if (v & (__MODE_IOTRAN | _IOLBF | _IONBF)) + fp->bufwrite = fp->bufstart; /* Nope */ + else + fp->bufwrite = fp->bufend; /* Yup */ + + /* Correct return val */ + return (unsigned char) ch; +} +#endif + +#ifdef L_fgetc +int +fgetc(fp) +FILE *fp; +{ + int ch; + Inline_init; + + if (fp->mode & __MODE_WRITING) + fflush(fp); + + try_again: + /* Can't read or there's been an EOF or error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return EOF; + + /* Nothing in the buffer - fill it up */ + if (fp->bufpos >= fp->bufread) + { + fp->bufpos = fp->bufread = fp->bufstart; + ch = fread(fp->bufpos, 1, fp->bufend - fp->bufstart, fp); + if (ch == 0) + return EOF; + fp->bufread += ch; + fp->mode |= __MODE_READING; + fp->mode &= ~__MODE_UNGOT; + } + ch = *(fp->bufpos++); + +#if __MODE_IOTRAN + /* In MSDOS translation mode; WARN: Doesn't work with UNIX macro */ + if (ch == '\r' && (fp->mode & __MODE_IOTRAN)) + goto try_again; +#endif + + return ch; +} +#endif + +#ifdef L_fflush +int +fflush(fp) +FILE *fp; +{ + int len, cc, rv=0; + char * bstart; + if (fp == NULL) /* On NULL flush the lot. */ + { + if (fflush(stdin)) + return EOF; + if (fflush(stdout)) + return EOF; + if (fflush(stderr)) + return EOF; + + for (fp = __IO_list; fp; fp = fp->next) + if (fflush(fp)) + return EOF; + + return 0; + } + + /* If there's output data pending */ + if (fp->mode & __MODE_WRITING) + { + len = fp->bufpos - fp->bufstart; + + if (len) + { + bstart = fp->bufstart; + /* + * The loop is so we don't get upset by signals or partial writes. + */ + do + { + cc = write(fp->fd, bstart, len); + if( cc > 0 ) + { + bstart+=cc; len-=cc; + } + } + while ( cc>0 || (cc == -1 && errno == EINTR)); + /* + * If we get here with len!=0 there was an error, exactly what to + * do about it is another matter ... + * + * I'll just clear the buffer. + */ + if (len) + { + fp->mode |= __MODE_ERR; + rv = EOF; + } + } + } + /* If there's data in the buffer sychronise the file positions */ + else if (fp->mode & __MODE_READING) + { + /* Humm, I think this means sync the file like fpurge() ... */ + /* Anyway the user isn't supposed to call this function when reading */ + + len = fp->bufread - fp->bufpos; /* Bytes buffered but unread */ + /* If it's a file, make it good */ + if (len > 0 && lseek(fp->fd, (long)-len, 1) < 0) + { + /* Hummm - Not certain here, I don't think this is reported */ + /* + * fp->mode |= __MODE_ERR; return EOF; + */ + } + } + + /* All done, no problem */ + fp->mode &= (~(__MODE_READING|__MODE_WRITING|__MODE_EOF|__MODE_UNGOT)); + fp->bufread = fp->bufwrite = fp->bufpos = fp->bufstart; + return rv; +} +#endif + +#ifdef L_fgets +/* Nothing special here ... */ +char * +fgets(s, count, f) +char *s; +size_t count; +FILE *f; +{ + char *ret; + register size_t i; + register int ch; + + ret = s; + for (i = count; i > 0; i--) + { + ch = getc(f); + if (ch == EOF) + { + if (s == ret) + return 0; + break; + } + *s++ = (char) ch; + if (ch == '\n') + break; + } + *s = 0; + + if (ferror(f)) + return 0; + return ret; +} +#endif + +#ifdef L_gets +char * +gets(str) /* BAD function; DON'T use it! */ +char *str; +{ + /* Auwlright it will work but of course _your_ program will crash */ + /* if it's given a too long line */ + register char *p = str; + register int c; + + while (((c = getc(stdin)) != EOF) && (c != '\n')) + *p++ = c; + *p = '\0'; + return (((c == EOF) && (p == str)) ? NULL : str); /* NULL == EOF */ +} +#endif + +#ifdef L_fputs +int +fputs(str, fp) +char *str; +FILE *fp; +{ + register int n = 0; + while (*str) + { + if (putc(*str++, fp) == EOF) + return (EOF); + ++n; + } + return (n); +} +#endif + +#ifdef L_puts +int +puts(str) +char *str; +{ + register int n; + + if (((n = fputs(str, stdout)) == EOF) + || (putc('\n', stdout) == EOF)) + return (EOF); + return (++n); +} +#endif + +#ifdef L_fread +/* + * fread will often be used to read in large chunks of data calling read() + * directly can be a big win in this case. Beware also fgetc calls this + * function to fill the buffer. + * + * This ignores __MODE__IOTRAN; probably exactly what you want. (It _is_ what + * fgetc wants) + */ +int +fread(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + int len, v; + unsigned bytes, got = 0; + Inline_init; + + v = fp->mode; + + /* Want to do this to bring the file pointer up to date */ + if (v & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an EOF or error then return zero */ + if ((v & (__MODE_READ | __MODE_EOF | __MODE_ERR)) != __MODE_READ) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufread - fp->bufpos; + if (len >= bytes) /* Enough buffered */ + { + memcpy(buf, fp->bufpos, (unsigned) bytes); + fp->bufpos += bytes; + return bytes; + } + else if (len > 0) /* Some buffered */ + { + memcpy(buf, fp->bufpos, len); + got = len; + } + + /* Need more; do it with a direct read */ + len = read(fp->fd, buf + got, (unsigned) (bytes - got)); + + /* Possibly for now _or_ later */ + if (len < 0) + { + fp->mode |= __MODE_ERR; + len = 0; + } + else if (len == 0) + fp->mode |= __MODE_EOF; + + return (got + len) / size; +} +#endif + +#ifdef L_fwrite +/* + * Like fread, fwrite will often be used to write out large chunks of + * data; calling write() directly can be a big win in this case. + * + * But first we check to see if there's space in the buffer. + * + * Again this ignores __MODE__IOTRAN. + */ +int +fwrite(buf, size, nelm, fp) +char *buf; +int size; +int nelm; +FILE *fp; +{ + register int v; + int len; + unsigned bytes, put; + +#ifdef STUB_FWRITE + bytes = size * nelm; + while(bytes>0) { + len=write(fp->fd, buf, bytes); + if (len<=0) { + break; + } + bytes -= len; + buf += len; + } + return nelm; +#else + + v = fp->mode; + /* If last op was a read ... */ + if ((v & __MODE_READING) && fflush(fp)) + return 0; + + /* Can't write or there's been an EOF or error then return 0 */ + if ((v & (__MODE_WRITE | __MODE_EOF | __MODE_ERR)) != __MODE_WRITE) + return 0; + + /* This could be long, doesn't seem much point tho */ + bytes = size * nelm; + + len = fp->bufend - fp->bufpos; + + /* Flush the buffer if not enough room */ + if (bytes > len) + if (fflush(fp)) + return 0; + + len = fp->bufend - fp->bufpos; + if (bytes <= len) /* It'll fit in the buffer ? */ + { + fp->mode |= __MODE_WRITING; + memcpy(fp->bufpos, buf, bytes); + fp->bufpos += bytes; + + /* If we're not fully buffered */ + if (v & (_IOLBF | _IONBF)) + fflush(fp); + + return nelm; + } + else + /* Too big for the buffer */ + { + put = bytes; + do + { + len = write(fp->fd, buf, bytes); + if( len > 0 ) + { + buf+=len; bytes-=len; + } + } + while (len > 0 || (len == -1 && errno == EINTR)); + + if (len < 0) + fp->mode |= __MODE_ERR; + + put -= bytes; + } + + return put / size; +#endif +} +#endif + +#ifdef L_rewind +void +rewind(fp) +FILE * fp; +{ + fseek(fp, (long)0, 0); + clearerr(fp); +} +#endif + +#ifdef L_fseek +int +fseek(fp, offset, ref) +FILE *fp; +long offset; +int ref; +{ +#if 0 + /* FIXME: this is broken! BROKEN!!!! */ + /* if __MODE_READING and no ungetc ever done can just move pointer */ + /* This needs testing! */ + + if ( (fp->mode &(__MODE_READING | __MODE_UNGOT)) == __MODE_READING && + ( ref == SEEK_SET || ref == SEEK_CUR )) + { + long fpos = lseek(fp->fd, 0L, SEEK_CUR); + if( fpos == -1 ) return EOF; + + if( ref == SEEK_CUR ) + { + ref = SEEK_SET; + offset = fpos + offset + fp->bufpos - fp->bufread; + } + if( ref == SEEK_SET ) + { + if ( offset < fpos && offset >= fpos + fp->bufstart - fp->bufread ) + { + fp->bufpos = offset - fpos + fp->bufread; + return 0; + } + } + } +#endif + + /* Use fflush to sync the pointers */ + + if (fflush(fp) == EOF) + return EOF; + if (lseek(fp->fd, offset, ref) < 0) + return EOF; + return 0; +} +#endif + +#ifdef L_ftell +long ftell(fp) +FILE * fp; +{ + long rv; + if (fflush(fp) == EOF) + return EOF; + return lseek(fp->fd, 0L, SEEK_CUR); +} +#endif + +#ifdef L_fopen +/* + * This Fopen is all three of fopen, fdopen and freopen. The macros in + * stdio.h show the other names. + */ +FILE * +__fopen(fname, fd, fp, mode) +char *fname; +int fd; +FILE *fp; +char *mode; +{ + int open_mode = 0; +#if __MODE_IOTRAN + int do_iosense = 1; +#endif + int fopen_mode = 0; + FILE *nfp = 0; + + /* If we've got an fp close the old one (freopen) */ + if (fp) + { + /* Careful, don't de-allocate it */ + fopen_mode |= (fp->mode & (__MODE_BUF | __MODE_FREEFIL | __MODE_FREEBUF)); + fp->mode &= ~(__MODE_FREEFIL | __MODE_FREEBUF); + fclose(fp); + } + + /* decode the new open mode */ + while (*mode) + switch (*mode++) + { + case 'r': + fopen_mode |= __MODE_READ; + break; + case 'w': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_TRUNC); + break; + case 'a': + fopen_mode |= __MODE_WRITE; + open_mode = (O_CREAT | O_APPEND); + break; + case '+': + fopen_mode |= __MODE_RDWR; + break; +#if __MODE_IOTRAN + case 'b': /* Binary */ + fopen_mode &= ~__MODE_IOTRAN; + do_iosense=0; + break; + case 't': /* Text */ + fopen_mode |= __MODE_IOTRAN; + do_iosense=0; + break; +#endif + } + + /* Add in the read/write options to mode for open() */ + switch (fopen_mode & (__MODE_READ | __MODE_WRITE)) + { + case 0: + return 0; + case __MODE_READ: + open_mode |= O_RDONLY; + break; + case __MODE_WRITE: + open_mode |= O_WRONLY; + break; + default: + open_mode |= O_RDWR; + break; + } + + /* Allocate the (FILE) before we do anything irreversable */ + if (fp == 0) + { + nfp = malloc(sizeof(FILE)); + if (nfp == 0) + return 0; + } + + /* Open the file itself */ + if (fname) + fd = open(fname, open_mode, 0666); + if (fd < 0) /* Grrrr */ + { + if (nfp) + free(nfp); + return 0; + } + + /* If this isn't freopen create a (FILE) and buffer for it */ + if (fp == 0) + { + int i; + fp = nfp; + fp->next = __IO_list; + __IO_list = fp; + + fp->mode = __MODE_FREEFIL; + if( isatty(fd) ) + { + fp->mode |= _IOLBF; +#if __MODE_IOTRAN + if( do_iosense ) fopen_mode |= __MODE_IOTRAN; +#endif + } + else + fp->mode |= _IOFBF; + + for(i=0;i<FIXED_BUFFERS;i++) + if (!_fixed_buffers[i].used) { + fp->bufstart = _fixed_buffers[i].data; + _fixed_buffers[i].used = 1; + break; + } + + if (i == FIXED_BUFFERS) + fp->bufstart = malloc(BUFSIZ); + + if (fp->bufstart == 0) /* Oops, no mem */ + { /* Humm, full buffering with a two(!) byte + * buffer. */ + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + } + else + { + fp->bufend = fp->bufstart + BUFSIZ; + fp->mode |= __MODE_FREEBUF; + } + } + /* Ok, file's ready clear the buffer and save important bits */ + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; + fp->mode |= fopen_mode; + fp->fd = fd; + return fp; +} +#endif + +#ifdef L_fclose +int +fclose(fp) +FILE *fp; +{ + int rv = 0; + + if (fp == 0) + { + errno = EINVAL; + return EOF; + } + if (fflush(fp)) + return EOF; + + if (close(fp->fd)) + rv = EOF; + fp->fd = -1; + + if (fp->mode & __MODE_FREEBUF) + { + int i; + for(i=0;i<FIXED_BUFFERS;i++) + if (fp->bufstart == _fixed_buffers[i].data) { + _fixed_buffers[i].used = 0; + break; + } + if(i==FIXED_BUFFERS) + free(fp->bufstart); + fp->mode &= ~__MODE_FREEBUF; + fp->bufstart = fp->bufend = 0; + } + + if (fp->mode & __MODE_FREEFIL) + { + FILE *prev = 0, *ptr; + fp->mode = 0; + + for (ptr = __IO_list; ptr && ptr != fp; ptr = ptr->next) + ; + if (ptr == fp) + { + if (prev == 0) + __IO_list = fp->next; + else + prev->next = fp->next; + } + free(fp); + } + else + fp->mode = 0; + + return rv; +} +#endif + +#ifdef L_setbuffer +void +setbuffer(fp, buf, size) +FILE * fp; +char * buf; +int size; +{ + fflush(fp); + + if ((fp->bufstart == (unsigned char*)buf) && (fp->bufend == ((unsigned char*)buf + size))) + return; + + if( fp->mode & __MODE_FREEBUF ) { + int i; + for(i=0;i<FIXED_BUFFERS;i++) + if (fp->bufstart == _fixed_buffers[i].data) { + _fixed_buffers[i].used = 0; + break; + } + if(i==FIXED_BUFFERS) + free(fp->bufstart); + } + fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); + + if( buf == 0 ) + { + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + } + else + { + fp->bufstart = buf; + fp->bufend = buf+size; + fp->mode |= _IOFBF; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; +} +#endif + +#ifdef L_setvbuf +int setvbuf(fp, buf, mode, size) +FILE * fp; +char * buf; +int mode; +size_t size; +{ + fflush(fp); + if( fp->mode & __MODE_FREEBUF ) { + int i; + for(i=0;i<FIXED_BUFFERS;i++) + if (fp->bufstart == _fixed_buffers[i].data) { + _fixed_buffers[i].used = 0; + break; + } + if(i==FIXED_BUFFERS) + free(fp->bufstart); + } + fp->mode &= ~(__MODE_FREEBUF|__MODE_BUF); + fp->bufstart = fp->unbuf; + fp->bufend = fp->unbuf + sizeof(fp->unbuf); + fp->mode |= _IONBF; + + if( mode == _IOFBF || mode == _IOLBF ) + { + if( size <= 0 ) size = BUFSIZ; + if( buf == 0 ) + if (size == BUFSIZ) { + int i; + for(i=0;i<FIXED_BUFFERS;i++) + if (!_fixed_buffers[i].used) { + _fixed_buffers[i].used = 1; + buf = _fixed_buffers[i].data; + break; + } + if(i==FIXED_BUFFERS) + buf = malloc(size); + } else + buf = malloc(size); + if( buf == 0 ) return EOF; + + fp->bufstart = buf; + fp->bufend = buf+size; + fp->mode |= mode; + } + fp->bufpos = fp->bufread = fp->bufwrite = fp->bufstart; +} +#endif + +#ifdef L_ungetc +int +ungetc(c, fp) +int c; +FILE *fp; +{ + if (fp->mode & __MODE_WRITING) + fflush(fp); + + /* Can't read or there's been an error then return EOF */ + if ((fp->mode & (__MODE_READ | __MODE_ERR)) != __MODE_READ) + return EOF; + + /* Can't do fast fseeks */ + fp->mode |= __MODE_UNGOT; + + if( fp->bufpos > fp->bufstart ) + return *--fp->bufpos = (unsigned char) c; + else if( fp->bufread == fp->bufstart ) + return *fp->bufread++ = (unsigned char) c; + else + return EOF; +} +#endif diff --git a/libc/stdlib/Makefile b/libc/stdlib/Makefile new file mode 100644 index 000000000..da8053f1d --- /dev/null +++ b/libc/stdlib/Makefile @@ -0,0 +1,64 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -fno-builtin -I../include + +MSRC=aliases.c +MOBJ=abs.o remove.o creat.o bcopy.o bzero.o +# raise.o bcmp.o index.o rindex.o + + +ESRC=atexit.c +EOBJ=on_exit.o atexit.o __do_exit.o exit.o + +GOBJ=atoi.o atol.o ltoa.o ltostr.o \ + ctype.o qsort.o bsearch.o rand.o lsearch.o getopt.o \ + itoa.o strtol.o crypt.o sleep.o mkstemp.o mktemp.o + +UOBJ=getenv.o putenv.o popen.o system.o getcwd.o setenv.o \ + execl.o execv.o execlp.o execvp.o execvep.o + + +OBJ=$(MOBJ) $(EOBJ) $(GOBJ) $(UOBJ) + +## No ELKS strtod() until BCC does 16 bit FP... +#ifneq ($(LIB_CPU),i86) +#OBJ+=strtod.o +#endif + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(MOBJ)): $(MSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)($(EOBJ)): $(ESRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +clean: + rm -f *.o libc.a + +$(LIBC)(strtol.o): strtol.c + $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)(strtod.o): strtod.c + $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c + $(AR) $(ARFLAGS) $@ $*.o + +$(LIBC)(crypt.o): crypt.c + $(CC) -c -ansi $(ARCH) $(CCFLAGS) $(DEFS) $*.c + $(AR) $(ARFLAGS) $@ $*.o diff --git a/libc/stdlib/atexit.c b/libc/stdlib/atexit.c new file mode 100644 index 000000000..2a82c6edb --- /dev/null +++ b/libc/stdlib/atexit.c @@ -0,0 +1,117 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +/* + * This deals with both the atexit and on_exit function calls + * + * Note calls installed with atexit are called with the same args as on_exit + * fuctions; the void* is given the NULL value. + * + */ + +#include <errno.h> + +/* ATEXIT.H */ +#define MAXONEXIT 20 /* AIUI Posix requires 10 */ + +typedef void (*vfuncp) (); + +extern vfuncp __cleanup; +extern void __do_exit(); + +extern struct exit_table +{ + vfuncp called; + void *argument; +} +__on_exit_table[MAXONEXIT]; + +extern int __on_exit_count; + +/* End ATEXIT.H */ + +#ifdef L_atexit +vfuncp __cleanup; + +int +atexit(ptr) +vfuncp ptr; +{ + if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT) + { + errno = ENOMEM; + return -1; + } + __cleanup = __do_exit; + if( ptr ) + { + __on_exit_table[__on_exit_count].called = ptr; + __on_exit_table[__on_exit_count].argument = 0; + __on_exit_count++; + } + return 0; +} + +#endif + +#ifdef L_on_exit +int +on_exit(ptr, arg) +vfuncp ptr; +void *arg; +{ + if( __on_exit_count < 0 || __on_exit_count >= MAXONEXIT) + { + errno = ENOMEM; + return -1; + } + __cleanup = __do_exit; + if( ptr ) + { + __on_exit_table[__on_exit_count].called = ptr; + __on_exit_table[__on_exit_count].argument = arg; + __on_exit_count++; + } + return 0; +} + +#endif + +#ifdef L___do_exit + +int __on_exit_count = 0; +struct exit_table __on_exit_table[MAXONEXIT]; + +void +__do_exit(rv) +int rv; +{ + register int count = __on_exit_count-1; + register vfuncp ptr; + __on_exit_count = -1; /* ensure no more will be added */ + __cleanup = 0; /* Calling exit won't re-do this */ + + /* In reverse order */ + for (; count >= 0; count--) + { + ptr = __on_exit_table[count].called; + (*ptr) (rv, __on_exit_table[count].argument); + } +} + +#endif + +#ifdef L_exit + +void +exit(rv) +int rv; +{ + if (__cleanup) + __cleanup(); + _exit(rv); +} + +#endif diff --git a/libc/stdlib/bsearch.c b/libc/stdlib/bsearch.c new file mode 100644 index 000000000..989866743 --- /dev/null +++ b/libc/stdlib/bsearch.c @@ -0,0 +1,46 @@ + +/* + * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ +#include <stdio.h> + +static int _bsearch; /* index of element found, or where to + * insert */ + +char * +bsearch(key, base, num, size, cmp) +register char *key; /* item to search for */ +register char *base; /* base address */ +int num; /* number of elements */ +register int size; /* element size in bytes */ +register int (*cmp) (); /* comparison function */ +{ + register int a, b, c, dir; + + a = 0; + b = num - 1; + while (a <= b) + { + c = (a + b) >> 1; /* == ((a + b) / 2) */ + if (dir = (*cmp) ((base + (c * size)), key)) + { + if (dir > 0) + b = c - 1; + else /* (dir < 0) */ + a = c + 1; + } + else + { + _bsearch = c; + return (base + (c * size)); + } + } + _bsearch = b; + return (NULL); +} diff --git a/libc/stdlib/getenv.c b/libc/stdlib/getenv.c new file mode 100644 index 000000000..1ed83a622 --- /dev/null +++ b/libc/stdlib/getenv.c @@ -0,0 +1,31 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + +extern char ** environ; + +char * +getenv(var) +const char * var; +{ + char **p; + int len; + + len = strlen(var); + + if (!environ) + return 0; + + for(p=environ; *p; p++) + { + if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' ) + return *p + len + 1; + } + return 0; +} + + diff --git a/libc/stdlib/malloc/Makefile b/libc/stdlib/malloc/Makefile new file mode 100644 index 000000000..36872c301 --- /dev/null +++ b/libc/stdlib/malloc/Makefile @@ -0,0 +1,33 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -I../include + + +MSRC=alloc.c +MOBJ=malloc.o free.o calloc.o malloc_dbg.o free_dbg.o calloc_dbg.o + +OBJ=$(MOBJ) + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(MOBJ)): $(MSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +clean: + rm -f *.o libc.a + + diff --git a/libc/stdlib/malloc/alloc.c b/libc/stdlib/malloc/alloc.c new file mode 100644 index 000000000..b92cb7c69 --- /dev/null +++ b/libc/stdlib/malloc/alloc.c @@ -0,0 +1,82 @@ +#include <unistd.h> +#include <sys/mman.h> +#include <stdio.h> +#include <stdlib.h> + +#ifdef L_calloc_dbg + +void * +calloc_dbg(size_t num, size_t size, char * function, char * file, int line) +{ + void * ptr; + fprintf(stderr, "calloc of %d bytes at %s @%s:%d = ", num*size, function, file, line); + ptr = calloc(num,size); + fprtinf(stderr, "%p\n", ptr); + return ptr; +} + +#endif + +#ifdef L_malloc_dbg + +void * +malloc_dbg(size_t len, char * function, char * file, int line) +{ + void * result; + fprintf(stderr, "malloc of %d bytes at %s @%s:%d = ", len, function, file, line); + result = malloc(len); + fprintf(stderr, "%p\n", result); + return result; +} + +#endif + +#ifdef L_free_dbg + +void +free_dbg(void * ptr, char * function, char * file, int line) +{ + fprintf(stderr, "free of %p at %s @%s:%d\n", ptr, function, file, line); + free(ptr); +} + +#endif + + +#ifdef L_calloc + +void * +calloc(size_t num, size_t size) +{ + void * ptr = malloc(num*size); + if (ptr) + memset(ptr, 0, num*size); + return ptr; +} + +#endif + +#ifdef L_malloc + +void * +malloc(size_t len) +{ + void * result = mmap((void *)0, len, PROT_READ | PROT_WRITE, + MAP_SHARED | MAP_ANONYMOUS, 0, 0); + if (result == (void*)-1) + return 0; + + return result; +} + +#endif + +#ifdef L_free + +void +free(void * ptr) +{ + munmap(ptr, 0); +} + +#endif diff --git a/libc/stdlib/mkstemp.c b/libc/stdlib/mkstemp.c new file mode 100644 index 000000000..d65ada4f7 --- /dev/null +++ b/libc/stdlib/mkstemp.c @@ -0,0 +1,43 @@ + +#include <features.h> +#include <unistd.h> +#include <fcntl.h> + +int mkstemp(template) +char * template; +{ + int i; + int num; /* UNINITIALIZED */ + int n2; + int l = strlen(template); + + if (l<6) { + errno = EINVAL; + return -1; + } + + for(i=l-6;i<l;i++) + if (template[i] != 'X') { + errno = EINVAL; + return -1; + } + +again: + n2 = num; + for(i=l-1;i>=l-6;i--) { + template[i] = '0' + n2 % 10; + n2 /= 10; + } + + i = open(template, O_RDWR|O_EXCL|O_CREAT, 0666); + + if (i==-1) { + if (errno == EEXIST) { + num++; + goto again; + } else + return -1; + } + + return i; +} diff --git a/libc/stdlib/mktemp.c b/libc/stdlib/mktemp.c new file mode 100644 index 000000000..08b356710 --- /dev/null +++ b/libc/stdlib/mktemp.c @@ -0,0 +1,40 @@ + +#include <features.h> +#include <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> + +char * mktemp(template) +char * template; +{ + int i; + int num; /* UNINITIALIZED */ + int n2; + int l = strlen(template); + struct stat stbuf; + + if (l<6) { + errno = EINVAL; + return 0; + } + + for(i=l-6;i<l;i++) + if (template[i] != 'X') { + errno = EINVAL; + return 0; + } + +again: + n2 = num; + for(i=l-1;i>=l-6;i--) { + template[i] = '0' + n2 % 10; + n2 /= 10; + } + + if (stat(template, &stbuf) == 0) { + num++; + goto again; + } + + return template; +} diff --git a/libc/stdlib/putenv.c b/libc/stdlib/putenv.c new file mode 100644 index 000000000..a7a453d5f --- /dev/null +++ b/libc/stdlib/putenv.c @@ -0,0 +1,62 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + +extern char ** environ; +#define ADD_NUM 4 + +int +putenv(var) +const char * var; +{ +static char ** mall_env = 0; +static int extras = 0; + char **p, **d; + char * r; + int len; + + r = strchr(var, '='); + if( r == 0 ) len = strlen(var); + else len = r-var; + + if (!environ) { + environ = (char**)malloc(ADD_NUM * sizeof(char*)); + memset(environ, 0, sizeof(char*)*ADD_NUM); + extras = ADD_NUM; + } + + for(p=environ; *p; p++) + { + if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' ) + { + while( p[0] = p[1] ) p++; + extras++; + break; + } + } + if( r == 0 ) return 0; + if( extras <= 0 ) /* Need more space */ + { + d = malloc((p-environ+1+ADD_NUM)*sizeof(char*)); + if( d == 0 ) return -1; + + memcpy((void*) d, (void*) environ, (p-environ+1)*sizeof(char*)); + p = d + (p-environ); + extras=ADD_NUM; + + if( mall_env ) free(mall_env); + environ = d; + mall_env = d; + } + *p++ = strdup((char*)var); + *p = '\0'; + extras--; + + return 0; +} + + diff --git a/libc/stdlib/qsort.c b/libc/stdlib/qsort.c new file mode 100644 index 000000000..cee53c398 --- /dev/null +++ b/libc/stdlib/qsort.c @@ -0,0 +1,166 @@ +/* + * This file lifted in toto from 'Dlibs' on the atari ST (RdeBath) + * + * + * Dale Schumacher 399 Beacon Ave. + * (alias: Dalnefre') St. Paul, MN 55104 + * dal@syntel.UUCP United States of America + * "It's not reality that's important, but how you perceive things." + */ +#include <string.h> + +char *_qbuf = 0; /* pointer to storage for qsort() */ + +#define PIVOT ((i+j)>>1) +#define moveitem(dst,src,size) if(dst != src) memcpy(dst, src, size) + +static +_wqsort(base, lo, hi, cmp) +register int *base; +register int lo; +register int hi; +register int (*cmp) (); +{ + int k; + register int i, j, t; + register int *p = &k; + + while (hi > lo) + { + i = lo; + j = hi; + t = PIVOT; + *p = base[t]; + base[t] = base[i]; + base[i] = *p; + while (i < j) + { + while (((*cmp) ((base + j), p)) > 0) + --j; + base[i] = base[j]; + while ((i < j) && (((*cmp) ((base + i), p)) <= 0)) + ++i; + base[j] = base[i]; + } + base[i] = *p; + if ((i - lo) < (hi - i)) + { + _wqsort(base, lo, (i - 1), cmp); + lo = i + 1; + } + else + { + _wqsort(base, (i + 1), hi, cmp); + hi = i - 1; + } + } +} + +static +_lqsort(base, lo, hi, cmp) +register long *base; +register int lo; +register int hi; +register int (*cmp) (); +{ + long k; + register int i, j, t; + register long *p = &k; + + while (hi > lo) + { + i = lo; + j = hi; + t = PIVOT; + *p = base[t]; + base[t] = base[i]; + base[i] = *p; + while (i < j) + { + while (((*cmp) ((base + j), p)) > 0) + --j; + base[i] = base[j]; + while ((i < j) && (((*cmp) ((base + i), p)) <= 0)) + ++i; + base[j] = base[i]; + } + base[i] = *p; + if ((i - lo) < (hi - i)) + { + _lqsort(base, lo, (i - 1), cmp); + lo = i + 1; + } + else + { + _lqsort(base, (i + 1), hi, cmp); + hi = i - 1; + } + } +} + +static +_nqsort(base, lo, hi, size, cmp) +register char *base; +register int lo; +register int hi; +register int size; +register int (*cmp) (); +{ + register int i, j; + register char *p = _qbuf; + + while (hi > lo) + { + i = lo; + j = hi; + p = (base + size * PIVOT); + moveitem(_qbuf, p, size); + moveitem(p, (base + size * i), size); + moveitem((base + size * i), _qbuf, size); + p = _qbuf; + while (i < j) + { + while (((*cmp) ((base + size * j), p)) > 0) + --j; + moveitem((base + size * i), (base + size * j), size); + while ((i < j) && (((*cmp) ((base + size * i), p)) <= 0)) + ++i; + moveitem((base + size * j), (base + size * i), size); + } + moveitem((base + size * i), p, size); + if ((i - lo) < (hi - i)) + { + _nqsort(base, lo, (i - 1), size, cmp); + lo = i + 1; + } + else + { + _nqsort(base, (i + 1), hi, size, cmp); + hi = i - 1; + } + } +} + +qsort(base, num, size, cmp) +char *base; +int num; +int size; +int (*cmp) (); +{ + char _qtemp[128]; + + if (_qbuf == 0) + { + if (size > sizeof(_qtemp))/* records too large! */ + return; + _qbuf = _qtemp; + } + if (size == 2) + _wqsort(base, 0, num - 1, cmp); + else if (size == 4) + _lqsort(base, 0, num - 1, cmp); + else + _nqsort(base, 0, num - 1, size, cmp); + if (_qbuf == _qtemp) + _qbuf = 0; +} diff --git a/libc/stdlib/rand.c b/libc/stdlib/rand.c new file mode 100644 index 000000000..4eb07894b --- /dev/null +++ b/libc/stdlib/rand.c @@ -0,0 +1,61 @@ +#ifdef ZX81_RNG +/* + * This is my favorite tiny RNG, If you had a ZX81 you may recognise it :-) + * (RdeBath) + */ + +#include <stdlib.h> + +#define MAXINT (((unsigned)-1)>>1) + +static unsigned int sseed = 0; + +int rand() +{ + return ( sseed = (((sseed+1L)*75L)%65537L)-1 ) & MAXINT; +} + +void srand(seed) +unsigned int seed; +{ + sseed=seed; +} + +#else + +/* + * This generator is a combination of three linear congruential generators + * with periods or 2^15-405, 2^15-1041 and 2^15-1111. It has a period that + * is the product of these three numbers. + */ + +static int seed1 = 1; +static int seed2 = 1; +static int seed3 = 1; +#define MAXINT (((unsigned)-1)>>1) + +#define CRANK(a,b,c,m,s) \ + q = s/a; \ + s = b*(s-a*q) - c*q; \ + if(s<0) s+=m; + +int rand() +{ + register int q, z; + CRANK(206, 157, 31, 32363, seed1); + CRANK(217, 146, 45, 31727, seed2); + CRANK(222, 142, 133, 31657, seed3); + + return seed1^seed2^seed3; +} + +void srand(seed) +unsigned int seed; +{ + seed &= MAXINT; + seed1= seed%32362 + 1; + seed2= seed%31726 + 1; + seed3= seed%31656 + 1; +} + +#endif diff --git a/libc/stdlib/setenv.c b/libc/stdlib/setenv.c new file mode 100644 index 000000000..0990fdec2 --- /dev/null +++ b/libc/stdlib/setenv.c @@ -0,0 +1,73 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ +#include <string.h> +#include <stdlib.h> +#include <malloc.h> + +extern char ** environ; +#define ADD_NUM 4 + +int +setenv(var, value, overwrite) +const char * var; +const char * value; +int overwrite; +{ +static char ** mall_env = 0; +static int extras = 0; + char **p, **d; + char * t; + int len; + + len = strlen(var); + + if (!environ) { + environ = (char**)malloc(ADD_NUM * sizeof(char*)); + memset(environ, 0, sizeof(char*)*ADD_NUM); + extras = ADD_NUM; + } + + for(p=environ; *p; p++) + { + if( memcmp(var, *p, len) == 0 && (*p)[len] == '=' ) + { + if (!overwrite) + return -1; + while( p[0] = p[1] ) p++; + extras++; + break; + } + } + + if( extras <= 0 ) /* Need more space */ + { + d = malloc((p-environ+1+ADD_NUM)*sizeof(char*)); + if( d == 0 ) return -1; + + memcpy((void*) d, (void*) environ, (p-environ+1)*sizeof(char*)); + p = d + (p-environ); + extras=ADD_NUM; + + if( mall_env ) free(mall_env); + environ = d; + mall_env = d; + } + + t = malloc(len + 1 + strlen(value) + 1); + if (!t) + return -1; + + strcpy(t, var); + strcat(t, "="); + strcat(t, value); + + *p++ = (char*)t; + *p = '\0'; + extras--; + + return 0; +} + + diff --git a/libc/stdlib/strtod.c b/libc/stdlib/strtod.c new file mode 100644 index 000000000..0d3bb790a --- /dev/null +++ b/libc/stdlib/strtod.c @@ -0,0 +1,96 @@ +/* + * strtod.c - This file is part of the libc-8086 package for ELKS, + * Copyright (C) 1995, 1996 Nat Friedman <ndf@linux.mit.edu>. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + * + */ +#include <stdlib.h> +#include <ctype.h> + +float +strtod(const char *nptr, char ** endptr) +{ + unsigned short negative; + float number; + float fp_part; + int exponent; + unsigned short exp_negative; + + /* advance beyond any leading whitespace */ + while (isspace(*nptr)) + nptr++; + + /* check for optional '+' or '-' */ + negative=0; + if (*nptr=='-') + { + negative=1; + nptr++; + } + else + if (*nptr=='+') + nptr++; + + number=0; + while (isdigit(*nptr)) + { + number=number*10+(*nptr-'0'); + nptr++; + } + + if (*nptr=='.') + { + nptr++; + fp_part=0; + while (isdigit(*nptr)) + { + fp_part=fp_part/10.0 + (*nptr-'0')/10.0; + nptr++; + } + number+=fp_part; + } + + if (*nptr=='e' || *nptr=='E') + { + nptr++; + exp_negative=0; + if (*nptr=='-') + { + exp_negative=1; + nptr++; + } + else + if (*nptr=='+') + nptr++; + + exponent=0; + while (isdigit(*nptr)) + { + exponent=exponent*10+(*nptr-'0'); + exponent++; + } + } + + while (exponent) + { + if (exp_negative) + number/=10; + else + number*=10; + exponent--; + } + return (negative ? -number:number); +} diff --git a/libc/stdlib/system.c b/libc/stdlib/system.c new file mode 100644 index 000000000..b764613be --- /dev/null +++ b/libc/stdlib/system.c @@ -0,0 +1,48 @@ + +#include <stddef.h> +#include <signal.h> +#include <unistd.h> + +int +system(command) +char * command; +{ + int wait_val, wait_ret, pid; + __sighandler_t save_quit, save_int, save_chld; + + if( command == 0 ) return 1; + + save_quit = signal(SIGQUIT, SIG_IGN); + save_int = signal(SIGINT, SIG_IGN); + save_chld = signal(SIGCHLD, SIG_DFL); + + if( (pid=vfork()) < 0 ) + { + signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + signal(SIGCHLD, save_chld); + return -1; + } + if( pid == 0 ) + { + signal(SIGQUIT, SIG_DFL); + signal(SIGINT, SIG_DFL); + signal(SIGCHLD, SIG_DFL); + + execl("/bin/sh", "sh", "-c", command, (char*)0); + _exit(127); + } + /* Signals are not absolutly guarenteed with vfork */ + signal(SIGQUIT, SIG_IGN); + signal(SIGINT, SIG_IGN); + + printf("Waiting for child %d\n", pid); + + if (wait4(pid, &wait_val, 0, 0) == -1) + wait_val = -1; + + signal(SIGQUIT, save_quit); + signal(SIGINT, save_int); + signal(SIGCHLD, save_chld); + return wait_val; +} diff --git a/libc/string/Makefile b/libc/string/Makefile new file mode 100644 index 000000000..af288e6e6 --- /dev/null +++ b/libc/string/Makefile @@ -0,0 +1,37 @@ +# Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -I../include + +SSRC=string.c +SOBJ=strlen.o strcat.o strcpy.o strcmp.o strncat.o strncpy.o strncmp.o \ + strchr.o strrchr.o strdup.o memcpy.o memccpy.o memchr.o memset.o \ + memcmp.o memmove.o movedata.o + +OBJ=$(SOBJ) strpbrk.o strsep.o strstr.o strtok.o strcspn.o \ + strspn.o strcasecmp.o strncasecmp.o config.o + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(SOBJ)): $(SSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +transfer: + -@rm -f ../include/string.h + cp -p string.h ../include/. + +clean: + rm -f *.o diff --git a/libc/string/config.c b/libc/string/config.c new file mode 100644 index 000000000..545207f6a --- /dev/null +++ b/libc/string/config.c @@ -0,0 +1,93 @@ +/* config.c: Config file reader. + * + * Copyright 1999 D. Jeff Dionne, <jeff@rt-control.com> + * + * This is free software, under the LGPL V2.0 + */ + +#include <stdio.h> +#include <string.h> +#include <errno.h> +#include <cfgfile.h> + +/* This is a quick and dirty config file parser. It reads the file once for + * each request, there is no cache. Each line must be less than 128bytes. + */ + +static char *args[16]; +static char cfgbuf[128]; + +static char * +ws(char **buf) +{ + char *b = *buf; + char *p; + + /* eat ws */ + while (*b && + (*b == ' ' || + *b == '\n' || + *b == '\t')) b++; + p = b; + + /* find the end */ + while (*p && + !(*p == ' ' || + *p == '\n' || + *p == '\t')) p++; + *p = 0; + *buf = p+1; + return b; +} + +char ** +cfgread(FILE *fp) +{ + char *ebuf; + char *p; + int i; + int j; + + if (!fp) { + errno = EIO; + return (void *)0; + } + + while (fgets(cfgbuf, sizeof(cfgbuf), fp)) { + + /* ship comment lines */ + if (cfgbuf[0] == '#') continue; + + ebuf = cfgbuf + strlen(cfgbuf); + + p = cfgbuf; + for (i = 0; i < 16 && p < ebuf; i++) { + args[i] = ws(&p); + } + args[i] = (void *)0; + + /* return if we found something */ + if (strlen(args[0])) return args; + } + return (void *)0; +} + +char ** +cfgfind(FILE *fp, char *var) +{ + char **ret; + char search[80]; + + if (!fp || !var) { + errno = EIO; + return (void *)0; + } + + strncpy(search, var, sizeof(search)); + + fseek(fp, 0, SEEK_SET); + while (ret = cfgread(fp)) { + if (!strcmp(ret[0], search)) return ret; + } + return (void *)0; +} diff --git a/libc/string/strcasecmp.c b/libc/string/strcasecmp.c new file mode 100644 index 000000000..0e7b0388f --- /dev/null +++ b/libc/string/strcasecmp.c @@ -0,0 +1,26 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> +#include <ctype.h> + +int +strcasecmp(s, d) +char *s; +char *d; +{ + for(;;) + { + if( *s != *d ) + { + if( tolower(*s) != tolower(*d) ) + return *s - *d; + } + else if( *s == '\0' ) break; + s++; d++; + } + return 0; +} + diff --git a/libc/string/strcspn.c b/libc/string/strcspn.c new file mode 100644 index 000000000..619c8be6b --- /dev/null +++ b/libc/string/strcspn.c @@ -0,0 +1,32 @@ +/* strcspn.c */ + +/* from Schumacher's Atari library, improved */ + +#include <string.h> + +size_t strcspn(string, set) +register char *string; +char *set; +/* + * Return the length of the sub-string of <string> that consists + * entirely of characters not found in <set>. The terminating '\0' + * in <set> is not considered part of the match set. If the first + * character if <string> is in <set>, 0 is returned. + */ +{ + register char *setptr; + char *start; + + start = string; + while (*string) + { + setptr = set; + do + if (*setptr == *string) + goto break2; + while (*setptr++); + ++string; + } +break2: + return string - start; +} diff --git a/libc/string/string.c b/libc/string/string.c new file mode 100644 index 000000000..664929b22 --- /dev/null +++ b/libc/string/string.c @@ -0,0 +1,672 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> +#include <malloc.h> + +#ifdef __AS386_16__ +#if __FIRST_ARG_IN_AX__ +#define BCC_AX_ASM /* BCC Assembler that can cope with arg in AX */ +#else +#define BCC_AX_ASM +#define BCC_ASM /* Use 16 bit BCC assembler */ +#endif + +#define PARANOID /* Include extra code for cld and ES register */ +#endif + +/* This is a basic string package; it includes the most used functions + + strlen strcat strcpy strcmp strncat strncpy strncmp strchr strrchr strdup + memcpy memccpy memchr memset memcmp memmove + + These functions are in seperate files. + strpbrk.o strsep.o strstr.o strtok.o strcspn.o + strspn.o strcasecmp.o strncasecmp.o + */ + +/********************** Function strlen ************************************/ + +#ifdef L_strlen +size_t strlen(str) +const char * str; +{ +#ifdef BCC_AX_ASM +#asm +#if !__FIRST_ARG_IN_AX__ + mov bx,sp +#endif + push di + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif ! This is almost the same as memchr, but it can + ! stay as a special. + +#if __FIRST_ARG_IN_AX__ + mov di,ax +#else + mov di,[bx+2] +#endif + mov cx,#-1 + xor ax,ax + repne + scasb + not cx + dec cx + mov ax,cx + +#ifdef PARANOID + pop es +#endif + pop di +#endasm +#else + register char * p =(char *) str; + while(*p) p++; + return p-str; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function strcat ************************************/ + +#ifdef L_strcat +char * strcat(d, s) +char *d; +const char * s; +{ + (void) strcpy(d+strlen(d), s); + return d; +} +#endif + +/********************** Function strcpy ************************************/ + +#ifdef L_strcpy +char * strcpy(d, s) +char *d; +const char * s; +{ + /* This is probably the quickest on an 8086 but a CPU with a cache will + * prefer to do this in one pass */ + return memcpy(d, s, strlen(s)+1); +} +#endif + +/********************** Function strcmp ************************************/ + +#ifdef L_strcmp +int strcmp(d, s) +const char *d; +const char * s; +{ + /* There are a number of ways to do this and it really does depend on the + types of strings given as to which is better, nevertheless the Glib + method is quite reasonable so we'll take that */ + +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push di + push si + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif + +#if __FIRST_ARG_IN_AX__ + mov di,ax ; dest + mov si,[bx+2] ; source +#else + mov di,[bx+2] ; dest + mov si,[bx+4] ; source +#endif +sc_1: + lodsb + scasb + jne sc_2 ; If bytes are diff skip out. + testb al,al + jne sc_1 ; If this byte in str1 is nul the strings are equal + xor ax,ax ; so return zero + jmp sc_3 +sc_2: + sbb ax,ax ; Collect correct val (-1,1). + orb al,#1 +sc_3: + +#ifdef PARANOID + pop es +#endif + pop si + pop di +#endasm +#else /* ifdef BCC_AX_ASM */ + register char *s1=(char *)d, *s2=(char *)s, c1,c2; + while((c1= *s1++) == (c2= *s2++) && c1 ); + return c1 - c2; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function strncat ************************************/ + +#ifdef L_strncat +char * strncat(d, s, l) +char *d; +const char *s; +size_t l; +{ + register char *s1=d+strlen(d), *s2; + + s2 = memchr(s, 0, l); + if( s2 ) + memcpy(s1, s, s2-s+1); + else + { + memcpy(s1, s, l); + s1[l] = '\0'; + } + return d; +} +#endif + +/********************** Function strncpy ************************************/ + +#ifdef L_strncpy +char * strncpy(d, s, l) /* FIXME need the fast version of this */ +char *d; +const char *s; +size_t l; +{ + register char *s1=d; + register const char *s2=s; + while(l > 0) + { + l--; + if( (*s1++ = *s2++) == '\0') + break; + } + + /* This _is_ correct strncpy is supposed to zap */ + for(; l>0; l--) *s1++ = '\0'; + return d; +} +#endif + +/********************** Function strncmp ************************************/ + +#ifdef L_strncmp +int strncmp(d, s, l) +const char *d, *s; +size_t l; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push si + push di + +#ifdef PARANOID + push es + push ds ! Im not sure if this is needed, so just in case. + pop es + cld +#endif + +#if __FIRST_ARG_IN_AX__ + mov si,ax + mov di,[bx+2] + mov cx,[bx+4] +#else + mov si,[bx+2] ! Fetch + mov di,[bx+4] + mov cx,[bx+6] +#endif + + inc cx +lp1: + dec cx + je lp2 + lodsb + scasb + jne lp3 + testb al,al + jne lp1 +lp2: + xor ax,ax + jmp lp4 +lp3: + sbb ax,ax + or al,#1 +lp4: + +#ifdef PARANOID + pop es +#endif + pop di + pop si +#endasm +#else + register char c1=0, c2=0; + while(l-- >0) + if( (c1= *d++) != (c2= *s++) || c1 == '\0' ) + break; + return c1-c2; +#endif +} +#endif + +/********************** Function strchr ************************************/ + +#ifdef L_strchr +char * +strchr(s, c) +char * s; +int c; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push si +#if __FIRST_ARG_IN_AX__ + mov bx,[bx+2] + mov si,ax +#else + mov si,[bx+2] + mov bx,[bx+4] +#endif + xor ax,ax + +#ifdef PARANOID + cld +#endif + +in_loop: + lodsb + cmp al,bl + jz got_it + or al,al + jnz in_loop + pop si + ret +got_it: + lea ax,[si-1] + pop si + +#endasm +#else /* ifdef BCC_AX_ASM */ + register char ch; + for(;;) + { + if( (ch= *s) == c ) return s; + if( ch == 0 ) return 0; + s++; + } +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function strrchr ************************************/ + +#ifdef L_strrchr +char * strrchr(s, c) +char * s; +int c; +{ + register char * prev = 0; + register char * p = s; + /* For null it's just like strlen */ + if( c == '\0' ) return p+strlen(p); + + /* everything else just step along the string. */ + while( (p=strchr(p, c)) != 0 ) + { + prev = p; p++; + } + return prev; +} +#endif + +/********************** Function strdup ************************************/ + +#ifdef L_strdup +char * strdup(s) +const char * s; +{ + register size_t len; + register char * p; + + len = strlen(s)+1; + p = (char *) malloc(len); + if(p) memcpy(p, s, len); /* Faster than strcpy */ + return p; +} +#endif + +/********************** Function memcpy ************************************/ + +#ifdef L_memcpy +void * +memcpy(d, s, l) +void *d; +const void *s; +size_t l; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push di + push si + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif + +#if __FIRST_ARG_IN_AX__ + mov di,ax ; dest + mov si,[bx+2] ; source + mov cx,[bx+4] ; count +#else + mov di,[bx+2] ; dest + mov si,[bx+4] ; source + mov cx,[bx+6] ; count + + mov ax,di +#endif + ; If di is odd mov 1 byte before doing word move + ; this will speed slightly but + ; NB 8086 has no problem with mis-aligned access. + + shr cx,#1 ; Do this faster by doing a mov word + rep + movsw + adc cx,cx ; Retrieve the leftover 1 bit from cflag. + rep + movsb + +#ifdef PARANOID + pop es +#endif + pop si + pop di +#endasm +#else /* ifdef BCC_AX_ASM */ + register char *s1=d, *s2=(char *)s; + for( ; l>0; l--) *((unsigned char*)s1++) = *((unsigned char*)s2++); + return d; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function memccpy ************************************/ + +#ifdef L_memccpy +void * memccpy(d, s, c, l) /* Do we need a fast one ? */ +void *s, *d; +int c; +size_t l; +{ + register char *s1=d, *s2=s; + while(l-- > 0) + if((*s1++ = *s2++) == c ) + return s1; + return 0; +} +#endif + +/********************** Function memchr ************************************/ + +#ifdef L_memchr +void * memchr(str, c, l) +const void * str; +int c; +size_t l; +{ +#ifdef BCC_ASM +#asm + mov bx,sp + push di + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif + + mov di,[bx+2] + mov ax,[bx+4] + mov cx,[bx+6] + test cx,cx + je is_z ! Zero length, do not find. + + repne ! Scan + scasb + jne is_z ! Not found, ret zero + dec di ! Adjust ptr + mov ax,di ! return + jmp xit +is_z: + xor ax,ax +xit: + +#ifdef PARANOID + pop es +#endif + pop di +#endasm +#else /* ifdef BCC_ASM */ + register char *p=(char *)str; + while(l-- > 0) + { + if(*p == c) return p; + p++; + } + return 0; +#endif /* ifdef BCC_ASM */ +} +#endif + +/********************** Function memset ************************************/ + +#ifdef L_memset +void * memset(str, c, l) +void * str; +int c; +size_t l; +{ +#ifdef BCC_AX_ASM +#asm + mov bx,sp + push di + +#ifdef PARANOID + push es + push ds ; Im not sure if this is needed, so just in case. + pop es + cld +#endif + +#if __FIRST_ARG_IN_AX__ + mov di,ax ; Fetch + mov ax,[bx+2] + mov cx,[bx+4] +#else + mov di,[bx+2] ; Fetch + mov ax,[bx+4] + mov cx,[bx+6] +#endif + +; How much difference does this alignment make ? +; I don`t think it`s significant cause most will already be aligned. + +; test cx,cx ; Zero size - skip +; je xit +; +; test di,#1 ; Line it up +; je s_1 +; stosb +; dec cx +;s_1: + + mov ah,al ; Replicate byte + shr cx,#1 ; Do this faster by doing a sto word + rep ; Bzzzzz ... + stosw + adc cx,cx ; Retrieve the leftover 1 bit from cflag. + + rep ; ... z + stosb + +xit: + mov ax,[bx+2] +#ifdef PARANOID + pop es +#endif + pop di +#endasm +#else /* ifdef BCC_AX_ASM */ + register char *s1=str; + while(l-->0) *s1++ = c; + return str; +#endif /* ifdef BCC_AX_ASM */ +} +#endif + +/********************** Function memcmp ************************************/ + +#ifdef L_memcmp +int memcmp(s, d, l) +const void *s, *d; +size_t l; +{ +#ifdef BCC_ASM +#asm + mov bx,sp + push di + push si + +#ifdef PARANOID + push es + push ds ! Im not sure if this is needed, so just in case. + pop es + cld +#endif + + mov si,[bx+2] ! Fetch + mov di,[bx+4] + mov cx,[bx+6] + xor ax,ax + + rep ! Bzzzzz + cmpsb + je xit ! All the same! + sbb ax,ax + sbb ax,#-1 ! choose +/-1 +xit: +#ifdef PARANOID + pop es +#endif + pop si + pop di +#endasm +#else /* ifdef BCC_ASM */ + register const char *s1=d, *s2=s; + register char c1=0, c2=0; + while(l-- > 0) + if( (c1= *s1++) != (c2= *s2++) ) + break; + return c1-c2; +#endif /* ifdef BCC_ASM */ +} +#endif + +/********************** Function memmove ************************************/ + +#ifdef L_memmove +void * +memmove(d, s, l) +void *d, *s; +size_t l; +{ + register char *s1=d, *s2=s; + /* This bit of sneakyness c/o Glibc, it assumes the test is unsigned */ + if( s1-s2 >= l ) return memcpy(d,s,l); + + /* This reverse copy only used if we absolutly have to */ + s1+=l; s2+=l; + while(l-- >0) + *(--s1) = *(--s2); + return d; +} +#endif + +/********************** Function movedata ***********************************/ + +#ifdef L_movedata + +/* NB There isn't any C version of this function ... */ + +#ifdef BCC_AX_ASM +void +__movedata(srcseg, srcoff, destseg, destoff, len) +unsigned int srcseg, srcoff, destseg, destoff, len; +{ +#asm + push bp + mov bp,sp + push si + push di + push ds +#ifdef PARANOID + push es + cld +#endif + + ! sei ! Are we _really_ paranoid ? + +#if !__FIRST_ARG_IN_AX__ + mov ds,[bp+4] ! Careful, [bp+xx] is SS based. + mov si,[bp+6] + mov es,[bp+8] + mov di,[bp+10] + mov cx,[bp+12] +#else + mov ds,ax + mov si,[bp+4] + mov es,[bp+6] + mov di,[bp+8] + mov cx,[bp+10] +#endif + rep + movsb + + ! cli ! Are we _really_ paranoid ? + +#ifdef PARANOID + pop es +#endif + pop ds + pop di + pop si + pop bp +#endasm +} +#endif + +#endif + +/********************** THE END ********************************************/ + diff --git a/libc/string/strncasecmp.c b/libc/string/strncasecmp.c new file mode 100644 index 000000000..561f72a76 --- /dev/null +++ b/libc/string/strncasecmp.c @@ -0,0 +1,28 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> +#include <ctype.h> + +int +strncasecmp(s, d, l) +char *s; +char *d; +size_t l; +{ + while(l>0) + { + if( *s != *d ) + { + if( tolower(*s) != tolower(*d) ) + return *s - *d; + } + else + if( *s == '\0' ) return 0; + s++; d++; l--; + } + return 0; +} + diff --git a/libc/string/strpbrk.c b/libc/string/strpbrk.c new file mode 100644 index 000000000..3fc27ec70 --- /dev/null +++ b/libc/string/strpbrk.c @@ -0,0 +1,21 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> + +/* This uses strchr, strchr should be in assembler */ + +char *strpbrk(str, set) +register char *str; +char *set; +{ + while (*str != '\0') + if (strchr(set, *str) == 0) + ++str; + else + return (char *) str; + + return 0; +} diff --git a/libc/string/strsep.c b/libc/string/strsep.c new file mode 100644 index 000000000..21aa1bb58 --- /dev/null +++ b/libc/string/strsep.c @@ -0,0 +1,38 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +char * +strsep(pp, delim) +char **pp; +char *delim; +{ + char *p, *q; + + if (!(p = *pp)) + return 0; + if (q = strpbrk (p, delim)) + { + *pp = q + 1; + *q = '\0'; + } + else + *pp = 0; + return p; +} diff --git a/libc/string/strspn.c b/libc/string/strspn.c new file mode 100644 index 000000000..2094caa86 --- /dev/null +++ b/libc/string/strspn.c @@ -0,0 +1,44 @@ +/* Copyright (C) 1992, 1993 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + +/* Return the length of the maximum initial segment + of S which contains only characters in ACCEPT. */ +size_t +strspn(s, accept) +char *s; +char *accept; +{ + register char *p; + register char *a; + register size_t count = 0; + + for (p = s; *p != '\0'; ++p) + { + for (a = accept; *a != '\0'; ++a) + if (*p == *a) + break; + if (*a == '\0') + return count; + else + ++count; + } + + return count; +} diff --git a/libc/string/strstr.c b/libc/string/strstr.c new file mode 100644 index 000000000..aafcaf967 --- /dev/null +++ b/libc/string/strstr.c @@ -0,0 +1,54 @@ +/* Copyright (C) 1995,1996 Robert de Bath <rdebath@cix.compulink.co.uk> + * This file is part of the Linux-8086 C library and is distributed + * under the GNU Library General Public License. + */ + +#include <string.h> + +#if 1 +/* We've now got a nice fast strchr and memcmp use them */ + +char * +strstr(s1, s2) +char *s1; char *s2; +{ + register int l = strlen(s2); + register char * p = s1; + + if( l==0 ) return p; + + while (p = strchr(p, *s2)) + { + if( memcmp(p, s2, l) == 0 ) + return p; + p++; + } + return (char *) 0; +} + +#else +/* This is a nice simple self contained strstr, + now go and work out why the GNU one is faster :-) */ + +char *strstr(str1, str2) +char *str1, *str2; +{ + register char *Sptr, *Tptr; + int len = strlen(str1) -strlen(str2) + 1; + + if (*str2) + for (; len > 0; len--, str1++){ + if (*str1 != *str2) + continue; + + for (Sptr = str1, Tptr = str2; *Tptr != '\0'; Sptr++, Tptr++) + if (*Sptr != *Tptr) + break; + + if (*Tptr == '\0') + return (char*) str1; + } + + return (char*)0; +} +#endif diff --git a/libc/string/strtok.c b/libc/string/strtok.c new file mode 100644 index 000000000..27d8f25b6 --- /dev/null +++ b/libc/string/strtok.c @@ -0,0 +1,71 @@ +/* Copyright (C) 1991 Free Software Foundation, Inc. +This file is part of the GNU C Library. + +The GNU C Library is free software; you can redistribute it and/or +modify it under the terms of the GNU Library General Public License as +published by the Free Software Foundation; either version 2 of the +License, or (at your option) any later version. + +The GNU C Library is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +Library General Public License for more details. + +You should have received a copy of the GNU Library General Public +License along with the GNU C Library; see the file COPYING.LIB. If +not, write to the Free Software Foundation, Inc., 675 Mass Ave, +Cambridge, MA 02139, USA. */ + +#include <string.h> + + +static char *olds = 0; + +/* Parse S into tokens separated by characters in DELIM. + If S is NULL, the last string strtok() was called with is + used. For example: + char s[] = "-abc=-def"; + x = strtok(s, "-"); // x = "abc" + x = strtok(NULL, "=-"); // x = "def" + x = strtok(NULL, "="); // x = NULL + // s = "abc\0-def\0" +*/ +char * +strtok(s, delim) +register char *s; +register char *delim; +{ + char *token; + + if (s == 0) + { + if (olds == 0) + { + return 0; + } + else + s = olds; + } + + /* Scan leading delimiters. */ + s += strspn(s, delim); + if (*s == '\0') + { + olds = 0; + return 0; + } + + /* Find the end of the token. */ + token = s; + s = strpbrk(token, delim); + if (s == 0) + /* This token finishes the string. */ + olds = 0; + else + { + /* Terminate the token and make OLDS point past it. */ + *s = '\0'; + olds = s + 1; + } + return token; +} diff --git a/libc/sysdeps/linux/i386/bits/setjmp.h b/libc/sysdeps/linux/i386/bits/setjmp.h new file mode 100644 index 000000000..20786d642 --- /dev/null +++ b/libc/sysdeps/linux/i386/bits/setjmp.h @@ -0,0 +1,176 @@ +#if defined(__arm__) || defined(__thumb__) +/* + * All callee preserved registers: + * v1 - v7, fp, ip, sp, lr, f4, f5, f6, f7 + */ +#define _JBLEN 23 +#endif + +#ifdef __sparc__ +/* + * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext). + * All else recovered by under/over(flow) handling. + */ +#define _JBLEN 13 +#endif + +/* necv70 was 9 as well. */ + +#ifdef __mc68000__ +/* + * onsstack,sigmask,sp,pc,psl,d2-d7,a2-a6, + * fp2-fp7 for 68881. + * All else recovered by under/over(flow) handling. + */ +#define _JBLEN 34 +#endif + +#if defined(__Z8001__) || defined(__Z8002__) +/* 16 regs + pc */ +#define _JBLEN 20 +#endif + +#ifdef _AM29K +/* + * onsstack,sigmask,sp,pc,npc,psr,g1,o0,wbcnt (sigcontext). + * All else recovered by under/over(flow) handling. + */ +#define _JBLEN 9 +#endif + +#ifdef __i386__ +#ifdef __unix__ +# define _JBLEN 36 +#elif defined(_WIN32) +#define _JBLEN (13 * 4) +#else +#include "setjmp-dj.h" +#endif +#endif + +#ifdef __i960__ +#define _JBLEN 35 +#endif + +#ifdef __M32R__ +/* Only 8 words are currently needed. 10 gives us some slop if we need + to expand. */ +#define _JBLEN 10 +#endif + +#ifdef __mips__ +#define _JBLEN 11 +#endif + +#ifdef __m88000__ +#define _JBLEN 21 +#endif + +#ifdef __H8300__ +#define _JBLEN 5 +typedef int jmp_buf[_JBLEN]; +#endif + +#ifdef __H8300H__ +/* same as H8/300 but registers are twice as big */ +#define _JBLEN 5 +#define _JBTYPE long +#endif + +#ifdef __H8300S__ +/* same as H8/300 but registers are twice as big */ +#define _JBLEN 5 +#define _JBTYPE long +#endif + +#ifdef __H8500__ +#define _JBLEN 4 +#endif + +#ifdef __sh__ +#define _JBLEN 20 +#endif + +#ifdef __v800 +#define _JBLEN 28 +#endif + +#ifdef __PPC__ +#define _JBLEN 32 +#define _JBTYPE double +#endif + +#ifdef __hppa__ +/* %r30, %r2-%r18, %r27, pad, %fr12-%fr15. + Note space exists for the FP registers, but they are not + saved. */ +#define _JBLEN 28 +#endif + +#if defined(mn10300) || defined(mn10200) +/* A guess */ +#define _JBLEN 10 +#endif + +#ifdef __v850 +/* I think our setjmp is saving 15 regs at the moment. Gives us one word + slop if we need to expand. */ +#define _JBLEN 16 +#endif + + +#ifdef __D10V__ +#define _JBLEN 8 +#endif + +/* start-sanitize-d30v */ +#ifdef __D30V__ +#define _JBLEN (64 /* GPR */ + (2*2) /* ACs */ + 18 /* CRs */) +#endif +/* end-sanitize-d30v */ + +#ifdef _JBLEN +#ifdef _JBTYPE +typedef _JBTYPE jmp_buf[_JBLEN]; +#else +typedef int jmp_buf[_JBLEN]; +#endif + +#ifdef __CYGWIN32__ +#include <signal.h> + +/* POSIX sigsetjmp/siglongjmp macros */ +typedef int sigjmp_buf[_JBLEN+2]; + +#define _SAVEMASK _JBLEN +#define _SIGMASK (_JBLEN+1) + +#define sigsetjmp(env, savemask) (env[_SAVEMASK] = savemask,\ + sigprocmask (SIG_SETMASK, 0, (sigset_t *) &env[_SIGMASK]),\ + setjmp (env)) + +#define siglongjmp(env, val) (((env[_SAVEMASK])?\ + sigprocmask (SIG_SETMASK, (sigset_t *) &env[_SIGMASK], 0):0),\ + longjmp (env, val)) + +#endif /* __CYGWIN32__*/ + +#if defined(__linux__) && defined(__mc68000__) +#include <signal.h> + +/* POSIX sigsetjmp/siglongjmp macros */ +typedef int sigjmp_buf[_JBLEN]; + +#define _SAVEMASK 4 +#define _SIGMASK 1 + +#define sigsetjmp(env, savemask) (env[_SAVEMASK] = savemask,\ + sigprocmask (SIG_SETMASK, 0, (sigset_t *) &env[_SIGMASK]),\ + setjmp (env)) + +#define siglongjmp(env, val) (((env[_SAVEMASK])?\ + sigprocmask (SIG_SETMASK, (sigset_t *) &env[_SIGMASK], 0):0),\ + longjmp (env, val)) + +#endif /* __linux__*/ +#endif diff --git a/libc/termios/Makefile b/libc/termios/Makefile new file mode 100644 index 000000000..089fdc0c4 --- /dev/null +++ b/libc/termios/Makefile @@ -0,0 +1,36 @@ +# Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> +# This file is part of the Linux-8086 C library and is distributed +# under the GNU Library General Public License. + +LIBC=../libc.a + +CC=m68k-pic-coff-gcc +AR=m68k-pic-coff-ar +RANLIB=m68k-pic-coff-ranlib + +CCFLAGS= -O2 -m68000 -msoft-float -I../include + +TSRC=termios.c +TOBJ=tcsetattr.o tcgetattr.o tcdrain.o tcflow.o tcflush.o tcsendbreak.o \ + tcsetpgrp.o tcgetpgrp.o isatty.o \ + cfgetospeed.o cfgetispeed.o cfsetospeed.o cfsetispeed.o cfmakeraw.o + +# cfgetospeedn.o cfgetispeedn.o cfsetospeedn.o cfsetispeedn.o tcspeed.o + +OBJ=$(TOBJ) ttyname.o +# unlike everything else, this does not compile out of the box... +# ttyname.o + +CFLAGS=$(ARCH) $(CCFLAGS) $(DEFS) + +all: $(LIBC) + @$(RM) $(OBJ) + +$(LIBC): $(LIBC)($(OBJ)) + +$(LIBC)($(TOBJ)): $(TSRC) + $(CC) $(CFLAGS) -DL_$* $< -c -o $*.o + $(AR) $(ARFLAGS) $@ $*.o + +clean: + rm -f *.o libc.a diff --git a/libc/termios/termios.c b/libc/termios/termios.c new file mode 100644 index 000000000..c6c0117f0 --- /dev/null +++ b/libc/termios/termios.c @@ -0,0 +1,348 @@ +/* Copyright (C) 1996 Robert de Bath <robert@mayday.compulink.co.uk> This + * file is part of the Linux-8086 C library and is distributed under the + * GNU Library General Public License. + */ + +/* Note: This is based loosely on the Glib termios routines. */ + +#ifndef __MSDOS__ + +#include <errno.h> +#include <stddef.h> +#include <sys/ioctl.h> +#include <termios.h> + +#ifdef L_isatty +isatty(fd) +int fd; +{ + struct termios term; + int rv, err = errno; + rv= (ioctl(fd, TCGETS, &term)==0); + if( rv==0 && errno == ENOSYS ) + rv = (fd<3); + errno = err; + return rv; +} +#endif + +#ifdef L_tcgetattr +int +tcgetattr(fd, term) +int fd; +struct termios *term; +{ + return ioctl(fd, TCGETS, term); +} +#endif + +#ifdef L_tcsetattr +int +tcsetattr(fildes, optional_actions, termios_p) +int fildes; +int optional_actions; +struct termios *termios_p; +{ + switch (optional_actions) + { + case TCSANOW: + return ioctl(fildes, TCSETS, termios_p); + case TCSADRAIN: + return ioctl(fildes, TCSETSW, termios_p); + case TCSAFLUSH: + return ioctl(fildes, TCSETSF, termios_p); + default: + errno = EINVAL; + return -1; + } +} +#endif + +#ifdef L_tcdrain +/* Wait for pending output to be written on FD. */ +int +tcdrain(fd) +int fd; +{ + /* With an argument of 1, TCSBRK just waits for output to drain. */ + return ioctl(fd, TCSBRK, 1); +} +#endif + +#ifdef L_tcflow +int +tcflow(fd, action) +int fd; +int action; +{ + return ioctl(fd, TCXONC, action); +} +#endif + +#ifdef L_tcflush +/* Flush pending data on FD. */ +int +tcflush(fd, queue_selector) +int fd; +int queue_selector; +{ + return ioctl(fd, TCFLSH, queue_selector); +} +#endif + +#ifdef L_tcsendbreak +/* Send zero bits on FD. */ +int +tcsendbreak(fd, duration) +int fd; +int duration; +{ + /* + * The break lasts 0.25 to 0.5 seconds if DURATION is zero, and an + * implementation-defined period if DURATION is nonzero. We define a + * positive DURATION to be number of milliseconds to break. + */ + if (duration <= 0) + return ioctl(fd, TCSBRK, 0); + + /* + * ioctl can't send a break of any other duration for us. This could be + * changed to use trickery (e.g. lower speed and send a '\0') to send + * the break, but for now just return an error. + */ + errno = EINVAL; + return -1; +} +#endif + +#ifdef L_tcsetpgrp +/* Set the foreground process group ID of FD set PGRP_ID. */ +int +tcsetpgrp(fd, pgrp_id) +int fd; +pid_t pgrp_id; +{ + return ioctl(fd, TIOCSPGRP, &pgrp_id); +} +#endif + +#ifdef L_tcgetpgrp +/* Return the foreground process group ID of FD. */ +pid_t +tcgetpgrp(fd) +int fd; +{ + int pgrp; + if (ioctl(fd, TIOCGPGRP, &pgrp) < 0) + return (pid_t) - 1; + return (pid_t) pgrp; +} +#endif + +#ifdef L_cfgetospeed +speed_t cfgetospeed(tp) +struct termios *tp; +{ + return (tp->c_cflag & CBAUD); +} +#endif + +#ifdef L_cfgetispeed +speed_t cfgetispeed(tp) +struct termios *tp; +{ + return (tp->c_cflag & CBAUD); +} +#endif + +#ifdef L_cfsetospeed +int cfsetospeed(tp, speed) +struct termios *tp; speed_t speed; +{ +#ifdef CBAUDEX + if ((speed & ~CBAUD) || + ((speed & CBAUDEX) && (speed < B57600 || speed > B115200))) + return 0; +#else + if (speed & ~CBAUD) + return 0; +#endif + tp->c_cflag &= ~CBAUD; + tp->c_cflag |= speed; + + return 0; +} +#endif + +#ifdef L_cfsetispeed +int cfsetispeed(tp, speed) +struct termios *tp; speed_t speed; +{ + return cfsetospeed(tp, speed); +} +#endif + +#if 0 + +/* Not POSIX standard, not worth the bother to keep it up */ + +#ifdef L_tcspeed +static struct { + int number; + speed_t code; +} tcspeeds[] = { +#ifdef B50 + {50, B50}, +#endif +#ifdef B75 + {75, B75}, +#endif +#ifdef B110 + {110, B110}, +#endif +#ifdef B134 + {134, B134}, +#endif +#ifdef B150 + {150, B150}, +#endif +#ifdef B200 + {200, B200}, +#endif +#ifdef B300 + {300, B300}, +#endif +#ifdef B600 + {600, B600}, +#endif +#ifdef B1200 + {1200, B1200}, +#endif +#ifdef B1800 + {1800, B1800}, +#endif +#ifdef B2400 + {2400, B2400}, +#endif +#ifdef B4800 + {4800, B4800}, +#endif +#ifdef B9600 + {9600, B9600}, +#endif +#ifdef B19200 + {19200, B19200}, +#endif +#ifdef B38400 + {38400, B38400}, +#endif +#ifdef B57600 + {57600, B57600}, +#endif +#ifdef B115200 + {115200, B115200}, +#endif +#ifdef B230400 + {230400, B230400}, +#endif +#ifdef B460800 + {460800, B460800}, +#endif +#ifdef B0 + {0, B0}, +#endif + {0, 0} +}; + +int tcspeed_to_number(code) +speed_t code; +{ + int i; + code &= CBAUD; + for(i=0;tcspeeds[i].code;i++) + if (tcspeeds[i].code == code) + return tcspeeds[i].number; + return 0; +} + +speed_t tcspeed_from_number(number) +int number; +{ + int i; + for(i=0;tcspeeds[i].code;i++) + if (tcspeeds[i].number == number) + return tcspeeds[i].code; + return B0; +} +#endif + +#ifdef L_cfgetospeedn +int cfgetospeedn(tp) +struct termios *tp; +{ + return tcspeed_to_number(cfgetospeed(tp)); +} +#endif + +#ifdef L_cfgetispeedn +int cfgetispeedn(tp) +struct termios *tp; +{ + return tcspeed_to_number(cfgetispeed(tp)); +} +#endif + +#ifdef L_cfsetospeedn +int cfsetospeedn(tp, speed) +struct termios *tp; int speed; +{ + return cfsetospeed(tp, tcspeed_from_number(speed)); +} +#endif + +#ifdef L_cfsetispeedn +int cfsetispeedn(tp, speed) +struct termios *tp; int speed; +{ + return cfsetispeedn(tp, tcspeed_from_number(speed)); +} +#endif + +#endif + +/* From linux libc-4.6.27 again */ +#ifdef L_cfmakeraw +/* Copyright (C) 1992 Free Software Foundation, Inc. +This file is part of the GNU C Library.*/ + +void +cfmakeraw(t) +struct termios *t; +{ +/* I changed it to the current form according to the suggestions + * from Bruce Evans. Thanks Bruce. Please report the problems to + * H.J. Lu (hlu@eecs.wsu.edu). + */ + +/* + * I took out the bits commented out by #if 1...#else - RHP + */ + + /* VMIN = 0 means non-blocking for Linux */ + t->c_cc[VMIN] = 1; t->c_cc[VTIME] = 1; + /* clear some bits with &= ~(bits), set others with |= */ + t->c_cflag &= ~(CSIZE|PARENB|CSTOPB); + t->c_cflag |= (CS8|HUPCL|CREAD); + t->c_iflag &= ~(IGNBRK|BRKINT|PARMRK|INPCK|ISTRIP); + t->c_iflag &= ~(INLCR|IGNCR|ICRNL|IXON|IXOFF); + t->c_iflag |= (BRKINT|IGNPAR); + t->c_oflag &= ~(OPOST|OLCUC|OCRNL|ONOCR|ONLRET|OFILL|OFDEL); + t->c_oflag &= ~(NLDLY|CRDLY|TABDLY|BSDLY|VTDLY|FFDLY); + t->c_oflag |= (ONLCR|NL0|CR0|TAB3|BS0|VT0|FF0); + t->c_lflag &= ~(ISIG|ICANON|IEXTEN|ECHO|ECHOE|ECHOK|ECHONL); + t->c_lflag &= ~(NOFLSH|XCASE); + t->c_lflag &= ~(ECHOPRT|ECHOCTL|ECHOKE); +} +#endif + +#endif diff --git a/libc/termios/ttyname.c b/libc/termios/ttyname.c new file mode 100644 index 000000000..897243e71 --- /dev/null +++ b/libc/termios/ttyname.c @@ -0,0 +1,45 @@ + +#include <errno.h> +#include <sys/stat.h> +#include <dirent.h> + +char * +ttyname(fd) +int fd; +{ + static char dev[] = "/dev"; + struct stat st, dst; + DIR *fp; + struct dirent *d; + static char name[NAME_MAX]; + int noerr = errno; + + if (fstat(fd, &st) < 0) + return 0; + if (!isatty(fd)) + { + errno = ENOTTY; + return 0; + } + + fp = opendir(dev); + if (fp == 0) + return 0; + strcpy(name, dev); + strcat(name, "/"); + + while ((d = readdir(fp)) != 0) + { + strcpy(name + sizeof(dev), d->d_name); + if (stat(name, &dst) == 0 + && st.st_dev == dst.st_dev && st.st_ino == dst.st_ino) + { + closedir(fp); + errno = noerr; + return name; + } + } + closedir(fp); + errno = noerr; + return 0; +} |