pmt: e2fsprogs: cleanup

This commit is contained in:
2024-10-02 22:59:34 +03:00
parent 5cbd362d72
commit e7c51ced1b
332 changed files with 379 additions and 0 deletions

View File

@@ -1,849 +0,0 @@
This package, the EXT2 filesystem utilities, are made available under
the GNU Public License version 2, with the exception of the lib/ext2fs
and lib/e2p libraries, which are made available under the GNU Library
General Public License Version 2, the lib/uuid library which is made
available under a BSD-style license and the lib/et and lib/ss
libraries which are made available under an MIT-style license. Please
see lib/uuid/COPYING for more details for the license for the files
comprising the libuuid library, and the source file headers of the
libet and libss libraries for more information.
The most recent officially distributed version can be found at
http://e2fsprogs.sourceforge.net. If you need to make a distribution,
that's the one you should use. If there is some reason why you'd like
a more recent version that is still in ALPHA testing (i.e., either
using the "WIP" test distributions or one from the hg or git
repository from the development branch, please contact me
(tytso@mit.edu) before you ship. The release schedules for this
package are flexible, if you give me enough lead time.
Theodore Ts'o
23-June-2007
----------------------------------------------------------------------
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, 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 software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, 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 redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
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 give any other recipients of the Program a copy of this License
along with the Program.
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 Program or any portion
of it, thus forming a work based on the Program, 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) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
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 Program, 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 Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) 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; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, 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 executable. 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.
If distribution of executable or 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 counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program 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.
5. 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 Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program 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.
7. 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 Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program 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 Program.
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.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program 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.
9. The Free Software Foundation may publish revised and/or new versions
of the 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 Program
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 Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, 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
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "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 PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. 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 PROGRAM 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 PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. 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 program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program 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 2 of the License, or
(at your option) any later version.
This program 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 this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.
----------------------------------------------------------------------
GNU LIBRARY GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1991 Free Software Foundation, Inc.
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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!

View File

@@ -1,209 +0,0 @@
/*
* cache.c - allocation/initialization/free routines for cache
*
* Copyright (C) 2001 Andreas Dilger
* Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#include "config.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#else
#define PR_GET_DUMPABLE 3
#endif
#if (!defined(HAVE_PRCTL) && defined(linux))
#include <sys/syscall.h>
#endif
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include "blkidP.h"
int blkid_debug_mask = 0;
static char *safe_getenv(const char *arg)
{
if ((getuid() != geteuid()) || (getgid() != getegid()))
return NULL;
#if HAVE_PRCTL
if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
return NULL;
#else
#if (defined(linux) && defined(SYS_prctl))
if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
return NULL;
#endif
#endif
#if defined(HAVE_SECURE_GETENV)
return secure_getenv(arg);
#elif defined(HAVE___SECURE_GETENV)
return __secure_getenv(arg);
#else
return getenv(arg);
#endif
}
#if 0 /* ifdef CONFIG_BLKID_DEBUG */
static blkid_debug_dump_cache(int mask, blkid_cache cache)
{
struct list_head *p;
if (!cache) {
printf("cache: NULL\n");
return;
}
printf("cache: time = %lu\n", cache->bic_time);
printf("cache: flags = 0x%08X\n", cache->bic_flags);
list_for_each(p, &cache->bic_devs) {
blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
blkid_debug_dump_dev(dev);
}
}
#endif
int blkid_get_cache(blkid_cache *ret_cache, const char *filename)
{
blkid_cache cache;
#ifdef CONFIG_BLKID_DEBUG
if (!(blkid_debug_mask & DEBUG_INIT)) {
char *dstr = getenv("BLKID_DEBUG");
if (dstr)
blkid_debug_mask = strtoul(dstr, 0, 0);
blkid_debug_mask |= DEBUG_INIT;
}
#endif
DBG(DEBUG_CACHE, printf("creating blkid cache (using %s)\n",
filename ? filename : "default cache"));
if (!(cache = (blkid_cache) calloc(1, sizeof(struct blkid_struct_cache))))
return -BLKID_ERR_MEM;
INIT_LIST_HEAD(&cache->bic_devs);
INIT_LIST_HEAD(&cache->bic_tags);
if (filename && !strlen(filename))
filename = 0;
if (!filename)
filename = safe_getenv("BLKID_FILE");
if (!filename)
filename = BLKID_CACHE_FILE;
cache->bic_filename = blkid_strdup(filename);
blkid_read_cache(cache);
*ret_cache = cache;
return 0;
}
void blkid_put_cache(blkid_cache cache)
{
if (!cache)
return;
(void) blkid_flush_cache(cache);
DBG(DEBUG_CACHE, printf("freeing cache struct\n"));
/* DBG(DEBUG_CACHE, blkid_debug_dump_cache(cache)); */
while (!list_empty(&cache->bic_devs)) {
blkid_dev dev = list_entry(cache->bic_devs.next,
struct blkid_struct_dev,
bid_devs);
blkid_free_dev(dev);
}
while (!list_empty(&cache->bic_tags)) {
blkid_tag tag = list_entry(cache->bic_tags.next,
struct blkid_struct_tag,
bit_tags);
while (!list_empty(&tag->bit_names)) {
blkid_tag bad = list_entry(tag->bit_names.next,
struct blkid_struct_tag,
bit_names);
DBG(DEBUG_CACHE, printf("warning: unfreed tag %s=%s\n",
bad->bit_name, bad->bit_val));
blkid_free_tag(bad);
}
blkid_free_tag(tag);
}
free(cache->bic_filename);
free(cache);
}
void blkid_gc_cache(blkid_cache cache)
{
struct list_head *p, *pnext;
struct stat st;
if (!cache)
return;
list_for_each_safe(p, pnext, &cache->bic_devs) {
blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
if (stat(dev->bid_name, &st) < 0) {
DBG(DEBUG_CACHE,
printf("freeing %s\n", dev->bid_name));
blkid_free_dev(dev);
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
} else {
DBG(DEBUG_CACHE,
printf("Device %s exists\n", dev->bid_name));
}
}
}
#ifdef TEST_PROGRAM
int main(int argc, char** argv)
{
blkid_cache cache = NULL;
int ret;
blkid_debug_mask = DEBUG_ALL;
if ((argc > 2)) {
fprintf(stderr, "Usage: %s [filename] \n", argv[0]);
exit(1);
}
if ((ret = blkid_get_cache(&cache, argv[1])) < 0) {
fprintf(stderr, "error %d parsing cache file %s\n", ret,
argv[1] ? argv[1] : BLKID_CACHE_FILE);
exit(1);
}
if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
fprintf(stderr, "%s: error creating cache (%d)\n",
argv[0], ret);
exit(1);
}
if ((ret = blkid_probe_all(cache) < 0))
fprintf(stderr, "error probing devices\n");
blkid_put_cache(cache);
return ret;
}
#endif

Binary file not shown.

View File

@@ -1,254 +0,0 @@
/*
* dev.c - allocation/initialization/free routines for dev
*
* Copyright (C) 2001 Andreas Dilger
* Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#include "config.h"
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include "blkidP.h"
blkid_dev blkid_new_dev(void)
{
blkid_dev dev;
if (!(dev = (blkid_dev) calloc(1, sizeof(struct blkid_struct_dev))))
return NULL;
INIT_LIST_HEAD(&dev->bid_devs);
INIT_LIST_HEAD(&dev->bid_tags);
return dev;
}
void blkid_free_dev(blkid_dev dev)
{
if (!dev)
return;
DBG(DEBUG_DEV,
printf(" freeing dev %s (%s)\n", dev->bid_name, dev->bid_type ?
dev->bid_type : "(null)"));
DBG(DEBUG_DEV, blkid_debug_dump_dev(dev));
list_del(&dev->bid_devs);
while (!list_empty(&dev->bid_tags)) {
blkid_tag tag = list_entry(dev->bid_tags.next,
struct blkid_struct_tag,
bit_tags);
blkid_free_tag(tag);
}
free(dev->bid_name);
free(dev);
}
/*
* Given a blkid device, return its name
*/
extern const char *blkid_dev_devname(blkid_dev dev)
{
return dev->bid_name;
}
#ifdef CONFIG_BLKID_DEBUG
void blkid_debug_dump_dev(blkid_dev dev)
{
struct list_head *p;
if (!dev) {
printf(" dev: NULL\n");
return;
}
printf(" dev: name = %s\n", dev->bid_name);
printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
printf(" dev: TIME=\"%ld\"\n", (long)dev->bid_time);
printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
printf(" dev: flags = 0x%08X\n", dev->bid_flags);
list_for_each(p, &dev->bid_tags) {
blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
if (tag)
printf(" tag: %s=\"%s\"\n", tag->bit_name,
tag->bit_val);
else
printf(" tag: NULL\n");
}
printf("\n");
}
#endif
/*
* dev iteration routines for the public libblkid interface.
*
* These routines do not expose the list.h implementation, which are a
* contamination of the namespace, and which force us to reveal far, far
* too much of our internal implementation. I'm not convinced I want
* to keep list.h in the long term, anyway. It's fine for kernel
* programming, but performance is not the #1 priority for this
* library, and I really don't like the tradeoff of type-safety for
* performance for this application. [tytso:20030125.2007EST]
*/
/*
* This series of functions iterate over all devices in a blkid cache
*/
#define DEV_ITERATE_MAGIC 0x01a5284c
struct blkid_struct_dev_iterate {
int magic;
blkid_cache cache;
char *search_type;
char *search_value;
struct list_head *p;
};
extern blkid_dev_iterate blkid_dev_iterate_begin(blkid_cache cache)
{
blkid_dev_iterate iter;
iter = malloc(sizeof(struct blkid_struct_dev_iterate));
if (iter) {
iter->magic = DEV_ITERATE_MAGIC;
iter->cache = cache;
iter->p = cache->bic_devs.next;
iter->search_type = 0;
iter->search_value = 0;
}
return (iter);
}
extern int blkid_dev_set_search(blkid_dev_iterate iter,
char *search_type, char *search_value)
{
char *new_type, *new_value;
if (!iter || iter->magic != DEV_ITERATE_MAGIC || !search_type ||
!search_value)
return -1;
new_type = malloc(strlen(search_type)+1);
new_value = malloc(strlen(search_value)+1);
if (!new_type || !new_value) {
free(new_type);
free(new_value);
return -1;
}
strcpy(new_type, search_type);
strcpy(new_value, search_value);
free(iter->search_type);
free(iter->search_value);
iter->search_type = new_type;
iter->search_value = new_value;
return 0;
}
/*
* Return 0 on success, -1 on error
*/
extern int blkid_dev_next(blkid_dev_iterate iter,
blkid_dev *ret_dev)
{
blkid_dev dev;
*ret_dev = 0;
if (!iter || iter->magic != DEV_ITERATE_MAGIC)
return -1;
while (iter->p != &iter->cache->bic_devs) {
dev = list_entry(iter->p, struct blkid_struct_dev, bid_devs);
iter->p = iter->p->next;
if (iter->search_type &&
!blkid_dev_has_tag(dev, iter->search_type,
iter->search_value))
continue;
*ret_dev = dev;
return 0;
}
return -1;
}
extern void blkid_dev_iterate_end(blkid_dev_iterate iter)
{
if (!iter || iter->magic != DEV_ITERATE_MAGIC)
return;
iter->magic = 0;
free(iter);
}
#ifdef TEST_PROGRAM
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern char *optarg;
extern int optind;
#endif
void usage(char *prog)
{
fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask]\n", prog);
fprintf(stderr, "\tList all devices and exit\n");
exit(1);
}
int main(int argc, char **argv)
{
blkid_dev_iterate iter;
blkid_cache cache = NULL;
blkid_dev dev;
int c, ret;
char *tmp;
char *file = NULL;
char *search_type = NULL;
char *search_value = NULL;
while ((c = getopt (argc, argv, "m:f:")) != EOF)
switch (c) {
case 'f':
file = optarg;
break;
case 'm':
blkid_debug_mask = strtoul (optarg, &tmp, 0);
if (*tmp) {
fprintf(stderr, "Invalid debug mask: %s\n",
optarg);
exit(1);
}
break;
case '?':
usage(argv[0]);
}
if (argc >= optind+2) {
search_type = argv[optind];
search_value = argv[optind+1];
optind += 2;
}
if (argc != optind)
usage(argv[0]);
if ((ret = blkid_get_cache(&cache, file)) != 0) {
fprintf(stderr, "%s: error creating cache (%d)\n",
argv[0], ret);
exit(1);
}
iter = blkid_dev_iterate_begin(cache);
if (search_type)
blkid_dev_set_search(iter, search_type, search_value);
while (blkid_dev_next(iter, &dev) == 0) {
printf("Device: %s\n", blkid_dev_devname(dev));
}
blkid_dev_iterate_end(iter);
blkid_put_cache(cache);
return (0);
}
#endif

Binary file not shown.

View File

@@ -1,561 +0,0 @@
/*
* devname.c - get a dev by its device inode name
*
* Copyright (C) Andries Brouwer
* Copyright (C) 1999, 2000, 2001, 2002, 2003 Theodore Ts'o
* Copyright (C) 2001 Andreas Dilger
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#define _GNU_SOURCE 1
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <limits.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include <dirent.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_SYS_MKDEV_H
#include <sys/mkdev.h>
#endif
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#include <time.h>
#include "blkidP.h"
/*
* Find a dev struct in the cache by device name, if available.
*
* If there is no entry with the specified device name, and the create
* flag is set, then create an empty device entry.
*/
blkid_dev blkid_get_dev(blkid_cache cache, const char *devname, int flags)
{
blkid_dev dev = NULL, tmp;
struct list_head *p, *pnext;
if (!cache || !devname)
return NULL;
list_for_each(p, &cache->bic_devs) {
tmp = list_entry(p, struct blkid_struct_dev, bid_devs);
if (strcmp(tmp->bid_name, devname))
continue;
DBG(DEBUG_DEVNAME,
printf("found devname %s in cache\n", tmp->bid_name));
dev = tmp;
break;
}
if (!dev && (flags & BLKID_DEV_CREATE)) {
if (access(devname, F_OK) < 0)
return NULL;
dev = blkid_new_dev();
if (!dev)
return NULL;
dev->bid_time = INT_MIN;
dev->bid_name = blkid_strdup(devname);
dev->bid_cache = cache;
list_add_tail(&dev->bid_devs, &cache->bic_devs);
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
}
if (flags & BLKID_DEV_VERIFY) {
dev = blkid_verify(cache, dev);
if (!dev || !(dev->bid_flags & BLKID_BID_FL_VERIFIED))
return dev;
/*
* If the device is verified, then search the blkid
* cache for any entries that match on the type, uuid,
* and label, and verify them; if a cache entry can
* not be verified, then it's stale and so we remove
* it.
*/
list_for_each_safe(p, pnext, &cache->bic_devs) {
blkid_dev dev2;
dev2 = list_entry(p, struct blkid_struct_dev, bid_devs);
if (dev2->bid_flags & BLKID_BID_FL_VERIFIED)
continue;
if (!dev->bid_type || !dev2->bid_type ||
strcmp(dev->bid_type, dev2->bid_type))
continue;
if (dev->bid_label && dev2->bid_label &&
strcmp(dev->bid_label, dev2->bid_label))
continue;
if (dev->bid_uuid && dev2->bid_uuid &&
strcmp(dev->bid_uuid, dev2->bid_uuid))
continue;
if ((dev->bid_label && !dev2->bid_label) ||
(!dev->bid_label && dev2->bid_label) ||
(dev->bid_uuid && !dev2->bid_uuid) ||
(!dev->bid_uuid && dev2->bid_uuid))
continue;
dev2 = blkid_verify(cache, dev2);
if (dev2 && !(dev2->bid_flags & BLKID_BID_FL_VERIFIED))
blkid_free_dev(dev2);
}
}
return dev;
}
/* Directories where we will try to search for device names */
static const char *dirlist[] = { "/dev", "/devfs", "/devices", NULL };
static int is_dm_leaf(const char *devname)
{
struct dirent *de, *d_de;
DIR *dir, *d_dir;
char path[300];
int ret = 1;
if ((dir = opendir("/sys/block")) == NULL)
return 0;
while ((de = readdir(dir)) != NULL) {
if (!strcmp(de->d_name, ".") || !strcmp(de->d_name, "..") ||
!strcmp(de->d_name, devname) ||
strncmp(de->d_name, "dm-", 3) ||
strlen(de->d_name) > sizeof(path)-32)
continue;
sprintf(path, "/sys/block/%s/slaves", de->d_name);
if ((d_dir = opendir(path)) == NULL)
continue;
while ((d_de = readdir(d_dir)) != NULL) {
if (!strcmp(d_de->d_name, devname)) {
ret = 0;
break;
}
}
closedir(d_dir);
if (!ret)
break;
}
closedir(dir);
return ret;
}
/*
* Since 2.6.29 (patch 784aae735d9b0bba3f8b9faef4c8b30df3bf0128) kernel sysfs
* provides the real DM device names in /sys/block/<ptname>/dm/name
*/
static char *get_dm_name(const char *ptname)
{
FILE *f;
size_t sz;
char path[300], name[256], *res = NULL;
snprintf(path, sizeof(path), "/sys/block/%s/dm/name", ptname);
if ((f = fopen(path, "r")) == NULL)
return NULL;
/* read "<name>\n" from sysfs */
if (fgets(name, sizeof(name), f) && (sz = strlen(name)) > 1) {
name[sz - 1] = '\0';
snprintf(path, sizeof(path), "/dev/mapper/%s", name);
res = blkid_strdup(path);
}
fclose(f);
return res;
}
/*
* Probe a single block device to add to the device cache.
*/
static void probe_one(blkid_cache cache, const char *ptname,
dev_t devno, int pri, int only_if_new)
{
blkid_dev dev = NULL;
struct list_head *p, *pnext;
const char **dir;
char *devname = NULL;
/* See if we already have this device number in the cache. */
list_for_each_safe(p, pnext, &cache->bic_devs) {
blkid_dev tmp = list_entry(p, struct blkid_struct_dev,
bid_devs);
if (tmp->bid_devno == devno) {
if (only_if_new && !access(tmp->bid_name, F_OK))
return;
dev = blkid_verify(cache, tmp);
if (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED))
break;
dev = 0;
}
}
if (dev && dev->bid_devno == devno)
goto set_pri;
/* Try to translate private device-mapper dm-<N> names
* to standard /dev/mapper/<name>.
*/
if (!strncmp(ptname, "dm-", 3) && isdigit(ptname[3])) {
devname = get_dm_name(ptname);
if (!devname)
blkid__scan_dir("/dev/mapper", devno, 0, &devname);
if (devname)
goto get_dev;
}
/*
* Take a quick look at /dev/ptname for the device number. We check
* all of the likely device directories. If we don't find it, or if
* the stat information doesn't check out, use blkid_devno_to_devname()
* to find it via an exhaustive search for the device major/minor.
*/
for (dir = dirlist; *dir; dir++) {
struct stat st;
char device[256];
sprintf(device, "%s/%s", *dir, ptname);
if ((dev = blkid_get_dev(cache, device, BLKID_DEV_FIND)) &&
dev->bid_devno == devno)
goto set_pri;
if (stat(device, &st) == 0 &&
blkidP_is_disk_device(st.st_mode) &&
st.st_rdev == devno) {
devname = blkid_strdup(device);
goto get_dev;
}
}
/* Do a short-cut scan of /dev/mapper first */
if (!devname)
devname = get_dm_name(ptname);
if (!devname)
blkid__scan_dir("/dev/mapper", devno, 0, &devname);
if (!devname) {
devname = blkid_devno_to_devname(devno);
if (!devname)
return;
}
get_dev:
dev = blkid_get_dev(cache, devname, BLKID_DEV_NORMAL);
free(devname);
set_pri:
if (dev) {
if (pri)
dev->bid_pri = pri;
else if (!strncmp(dev->bid_name, "/dev/mapper/", 11)) {
dev->bid_pri = BLKID_PRI_DM;
if (is_dm_leaf(ptname))
dev->bid_pri += 5;
} else if (!strncmp(ptname, "md", 2))
dev->bid_pri = BLKID_PRI_MD;
}
return;
}
#define PROC_PARTITIONS "/proc/partitions"
#define VG_DIR "/proc/lvm/VGs"
/*
* This function initializes the UUID cache with devices from the LVM
* proc hierarchy. We currently depend on the names of the LVM
* hierarchy giving us the device structure in /dev. (XXX is this a
* safe thing to do?)
*/
#ifdef VG_DIR
static dev_t lvm_get_devno(const char *lvm_device)
{
FILE *lvf;
char buf[1024];
int ma, mi;
dev_t ret = 0;
DBG(DEBUG_DEVNAME, printf("opening %s\n", lvm_device));
if ((lvf = fopen(lvm_device, "r")) == NULL) {
DBG(DEBUG_DEVNAME, printf("%s: (%d) %s\n", lvm_device, errno,
strerror(errno)));
return 0;
}
while (fgets(buf, sizeof(buf), lvf)) {
if (sscanf(buf, "device: %d:%d", &ma, &mi) == 2) {
ret = makedev(ma, mi);
break;
}
}
fclose(lvf);
return ret;
}
static void lvm_probe_all(blkid_cache cache, int only_if_new)
{
DIR *vg_list;
struct dirent *vg_iter;
int vg_len = strlen(VG_DIR);
dev_t dev;
if ((vg_list = opendir(VG_DIR)) == NULL)
return;
DBG(DEBUG_DEVNAME, printf("probing LVM devices under %s\n", VG_DIR));
while ((vg_iter = readdir(vg_list)) != NULL) {
DIR *lv_list;
char *vdirname;
char *vg_name;
struct dirent *lv_iter;
vg_name = vg_iter->d_name;
if (!strcmp(vg_name, ".") || !strcmp(vg_name, ".."))
continue;
vdirname = malloc(vg_len + strlen(vg_name) + 8);
if (!vdirname)
goto exit;
sprintf(vdirname, "%s/%s/LVs", VG_DIR, vg_name);
lv_list = opendir(vdirname);
free(vdirname);
if (lv_list == NULL)
continue;
while ((lv_iter = readdir(lv_list)) != NULL) {
char *lv_name, *lvm_device;
lv_name = lv_iter->d_name;
if (!strcmp(lv_name, ".") || !strcmp(lv_name, ".."))
continue;
lvm_device = malloc(vg_len + strlen(vg_name) +
strlen(lv_name) + 8);
if (!lvm_device) {
closedir(lv_list);
goto exit;
}
sprintf(lvm_device, "%s/%s/LVs/%s", VG_DIR, vg_name,
lv_name);
dev = lvm_get_devno(lvm_device);
sprintf(lvm_device, "%s/%s", vg_name, lv_name);
DBG(DEBUG_DEVNAME, printf("LVM dev %s: devno 0x%04X\n",
lvm_device,
(unsigned int) dev));
probe_one(cache, lvm_device, dev, BLKID_PRI_LVM,
only_if_new);
free(lvm_device);
}
closedir(lv_list);
}
exit:
closedir(vg_list);
}
#endif
#define PROC_EVMS_VOLUMES "/proc/evms/volumes"
static int
evms_probe_all(blkid_cache cache, int only_if_new)
{
char line[100];
int ma, mi, sz, num = 0;
FILE *procpt;
char device[110];
procpt = fopen(PROC_EVMS_VOLUMES, "r");
if (!procpt)
return 0;
while (fgets(line, sizeof(line), procpt)) {
if (sscanf (line, " %d %d %d %*s %*s %[^\n ]",
&ma, &mi, &sz, device) != 4)
continue;
DBG(DEBUG_DEVNAME, printf("Checking partition %s (%d, %d)\n",
device, ma, mi));
probe_one(cache, device, makedev(ma, mi), BLKID_PRI_EVMS,
only_if_new);
num++;
}
fclose(procpt);
return num;
}
/*
* Read the device data for all available block devices in the system.
*/
static int probe_all(blkid_cache cache, int only_if_new)
{
FILE *proc;
char line[1024];
char ptname0[129], ptname1[129], *ptname = 0;
char *ptnames[2];
dev_t devs[2];
int ma, mi;
unsigned long long sz;
int lens[2] = { 0, 0 };
int which = 0, last = 0;
struct list_head *p, *pnext;
ptnames[0] = ptname0;
ptnames[1] = ptname1;
if (!cache)
return -BLKID_ERR_PARAM;
if (cache->bic_flags & BLKID_BIC_FL_PROBED &&
time(0) - cache->bic_time < BLKID_PROBE_INTERVAL)
return 0;
blkid_read_cache(cache);
evms_probe_all(cache, only_if_new);
#ifdef VG_DIR
lvm_probe_all(cache, only_if_new);
#endif
proc = fopen(PROC_PARTITIONS, "r");
if (!proc)
return -BLKID_ERR_PROC;
while (fgets(line, sizeof(line), proc)) {
last = which;
which ^= 1;
ptname = ptnames[which];
if (sscanf(line, " %d %d %llu %128[^\n ]",
&ma, &mi, &sz, ptname) != 4)
continue;
devs[which] = makedev(ma, mi);
DBG(DEBUG_DEVNAME, printf("read partition name %s\n", ptname));
/* Skip whole disk devs unless they have no partitions.
* If base name of device has changed, also
* check previous dev to see if it didn't have a partn.
* heuristic: partition name ends in a digit, & partition
* names contain whole device name as substring.
*
* Skip extended partitions.
* heuristic: size is 1
*
* FIXME: skip /dev/{ida,cciss,rd} whole-disk devs
*/
lens[which] = strlen(ptname);
/* ends in a digit, clearly a partition, so check */
if (isdigit(ptname[lens[which] - 1])) {
DBG(DEBUG_DEVNAME,
printf("partition dev %s, devno 0x%04X\n",
ptname, (unsigned int) devs[which]));
if (sz > 1)
probe_one(cache, ptname, devs[which], 0,
only_if_new);
lens[which] = 0; /* mark as checked */
}
/*
* If last was a whole disk and we just found a partition
* on it, remove the whole-disk dev from the cache if
* it exists.
*/
if (lens[last] && !strncmp(ptnames[last], ptname, lens[last])) {
list_for_each_safe(p, pnext, &cache->bic_devs) {
blkid_dev tmp;
/* find blkid dev for the whole-disk devno */
tmp = list_entry(p, struct blkid_struct_dev,
bid_devs);
if (tmp->bid_devno == devs[last]) {
DBG(DEBUG_DEVNAME,
printf("freeing %s\n",
tmp->bid_name));
blkid_free_dev(tmp);
cache->bic_flags |= BLKID_BIC_FL_CHANGED;
break;
}
}
lens[last] = 0;
}
/*
* If last was not checked because it looked like a whole-disk
* dev, and the device's base name has changed,
* check last as well.
*/
if (lens[last] && strncmp(ptnames[last], ptname, lens[last])) {
DBG(DEBUG_DEVNAME,
printf("whole dev %s, devno 0x%04X\n",
ptnames[last], (unsigned int) devs[last]));
probe_one(cache, ptnames[last], devs[last], 0,
only_if_new);
lens[last] = 0;
}
}
/* Handle the last device if it wasn't partitioned */
if (lens[which])
probe_one(cache, ptname, devs[which], 0, only_if_new);
fclose(proc);
blkid_flush_cache(cache);
return 0;
}
int blkid_probe_all(blkid_cache cache)
{
int ret;
DBG(DEBUG_PROBE, printf("Begin blkid_probe_all()\n"));
ret = probe_all(cache, 0);
cache->bic_time = time(0);
cache->bic_flags |= BLKID_BIC_FL_PROBED;
DBG(DEBUG_PROBE, printf("End blkid_probe_all()\n"));
return ret;
}
int blkid_probe_all_new(blkid_cache cache)
{
int ret;
DBG(DEBUG_PROBE, printf("Begin blkid_probe_all_new()\n"));
ret = probe_all(cache, 1);
DBG(DEBUG_PROBE, printf("End blkid_probe_all_new()\n"));
return ret;
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
blkid_cache cache = NULL;
int ret;
blkid_debug_mask = DEBUG_ALL;
if (argc != 1) {
fprintf(stderr, "Usage: %s\n"
"Probe all devices and exit\n", argv[0]);
exit(1);
}
if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
fprintf(stderr, "%s: error creating cache (%d)\n",
argv[0], ret);
exit(1);
}
if (blkid_probe_all(cache) < 0)
printf("%s: error probing devices\n", argv[0]);
blkid_put_cache(cache);
return (0);
}
#endif

Binary file not shown.

View File

@@ -1,242 +0,0 @@
/*
* devno.c - find a particular device by its device number (major/minor)
*
* Copyright (C) 2000, 2001, 2003 Theodore Ts'o
* Copyright (C) 2001 Andreas Dilger
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#include <dirent.h>
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_SYS_MKDEV_H
#include <sys/mkdev.h>
#endif
#ifdef HAVE_SYS_SYSMACROS_H
#include <sys/sysmacros.h>
#endif
#include "blkidP.h"
#if defined(__GNUC__) && __GNUC__ >= 8
/* gcc incorrectly thinks the destination string is not being null-terminated */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wstringop-truncation"
#endif
char *blkid_strndup(const char *s, int length)
{
char *ret;
if (!s)
return NULL;
if (!length)
length = strlen(s);
ret = malloc(length + 1);
if (ret) {
strncpy(ret, s, length);
ret[length] = '\0';
}
return ret;
}
#if defined(__GNUC__) && __GNUC__ >= 8
#pragma GCC diagnostic pop
#endif
char *blkid_strdup(const char *s)
{
return blkid_strndup(s, 0);
}
/*
* This function adds an entry to the directory list
*/
static void add_to_dirlist(const char *name, struct dir_list **list)
{
struct dir_list *dp;
dp = malloc(sizeof(struct dir_list));
if (!dp)
return;
dp->name = blkid_strdup(name);
if (!dp->name) {
free(dp);
return;
}
dp->next = *list;
*list = dp;
}
/*
* This function frees a directory list
*/
static void free_dirlist(struct dir_list **list)
{
struct dir_list *dp, *next;
for (dp = *list; dp; dp = next) {
next = dp->next;
free(dp->name);
free(dp);
}
*list = NULL;
}
void blkid__scan_dir(const char *dirname, dev_t devno, struct dir_list **list,
char **devname)
{
DIR *dir;
struct dirent *dp;
char path[1024];
int dirlen;
struct stat st;
if ((dir = opendir(dirname)) == NULL)
return;
dirlen = strlen(dirname) + 2;
while ((dp = readdir(dir)) != 0) {
if (dirlen + strlen(dp->d_name) >= sizeof(path))
continue;
if (dp->d_name[0] == '.' &&
((dp->d_name[1] == 0) ||
((dp->d_name[1] == '.') && (dp->d_name[2] == 0))))
continue;
sprintf(path, "%s/%s", dirname, dp->d_name);
if (stat(path, &st) < 0)
continue;
if (blkidP_is_disk_device(st.st_mode) && st.st_rdev == devno) {
*devname = blkid_strdup(path);
DBG(DEBUG_DEVNO,
printf("found 0x%llx at %s (%p)\n", (long long)devno,
path, *devname));
break;
}
if (list && S_ISDIR(st.st_mode) && !lstat(path, &st) &&
S_ISDIR(st.st_mode))
add_to_dirlist(path, list);
}
closedir(dir);
return;
}
/* Directories where we will try to search for device numbers */
static const char *devdirs[] = { "/devices", "/devfs", "/dev", NULL };
/*
* This function finds the pathname to a block device with a given
* device number. It returns a pointer to allocated memory to the
* pathname on success, and NULL on failure.
*/
char *blkid_devno_to_devname(dev_t devno)
{
struct dir_list *list = NULL, *new_list = NULL;
char *devname = NULL;
const char **dir;
/*
* Add the starting directories to search in reverse order of
* importance, since we are using a stack...
*/
for (dir = devdirs; *dir; dir++)
add_to_dirlist(*dir, &list);
while (list) {
struct dir_list *current = list;
list = list->next;
DBG(DEBUG_DEVNO, printf("directory %s\n", current->name));
blkid__scan_dir(current->name, devno, &new_list, &devname);
free(current->name);
free(current);
if (devname)
break;
/*
* If we're done checking at this level, descend to
* the next level of subdirectories. (breadth-first)
*/
if (list == NULL) {
list = new_list;
new_list = NULL;
}
}
free_dirlist(&list);
free_dirlist(&new_list);
if (!devname) {
DBG(DEBUG_DEVNO,
printf("blkid: couldn't find devno 0x%04lx\n",
(unsigned long) devno));
} else {
DBG(DEBUG_DEVNO,
printf("found devno 0x%04llx as %s\n", (long long)devno, devname));
}
return devname;
}
#ifdef TEST_PROGRAM
int main(int argc, char** argv)
{
char *devname, *tmp;
int major, minor;
dev_t devno;
const char *errmsg = "Couldn't parse %s: %s\n";
blkid_debug_mask = DEBUG_ALL;
if ((argc != 2) && (argc != 3)) {
fprintf(stderr, "Usage:\t%s device_number\n\t%s major minor\n"
"Resolve a device number to a device name\n",
argv[0], argv[0]);
exit(1);
}
if (argc == 2) {
devno = strtoul(argv[1], &tmp, 0);
if (*tmp) {
fprintf(stderr, errmsg, "device number", argv[1]);
exit(1);
}
} else {
major = strtoul(argv[1], &tmp, 0);
if (*tmp) {
fprintf(stderr, errmsg, "major number", argv[1]);
exit(1);
}
minor = strtoul(argv[2], &tmp, 0);
if (*tmp) {
fprintf(stderr, errmsg, "minor number", argv[2]);
exit(1);
}
devno = makedev(major, minor);
}
printf("Looking for device 0x%04llx\n", (long long)devno);
devname = blkid_devno_to_devname(devno);
free(devname);
return 0;
}
#endif

Binary file not shown.

View File

@@ -1,217 +0,0 @@
/*
* getsize.c --- get the size of a partition.
*
* Copyright (C) 1995, 1995 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#include "blkidP.h"
#include <stdio.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#include <fcntl.h>
#ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#ifdef HAVE_LINUX_FD_H
#include <linux/fd.h>
#endif
#ifdef HAVE_SYS_DISKLABEL_H
#include <sys/disklabel.h>
#endif
#ifdef HAVE_SYS_DISK_H
#include <sys/disk.h>
#endif
#ifdef __linux__
#include <sys/utsname.h>
#endif
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if defined(__linux__) && defined(_IO) && !defined(BLKGETSIZE)
#define BLKGETSIZE _IO(0x12,96) /* return device size */
#endif
#if defined(__linux__) && defined(_IOR) && !defined(BLKGETSIZE64)
#define BLKGETSIZE64 _IOR(0x12,114,size_t) /* return device size in bytes (u64 *arg) */
#endif
#ifdef APPLE_DARWIN
#define BLKGETSIZE DKIOCGETBLOCKCOUNT32
#endif /* APPLE_DARWIN */
static int valid_offset(int fd, blkid_loff_t offset)
{
char ch;
if (blkid_llseek(fd, offset, 0) < 0)
return 0;
if (read(fd, &ch, 1) < 1)
return 0;
return 1;
}
/*
* Returns the number of bytes in a partition
*/
blkid_loff_t blkid_get_dev_size(int fd)
{
unsigned long long size64 __BLKID_ATTR((unused));
blkid_loff_t high, low;
#if defined DKIOCGETBLOCKCOUNT && defined DKIOCGETBLOCKSIZE /* For Apple Darwin */
unsigned int size;
if (ioctl(fd, DKIOCGETBLOCKCOUNT, &size64) >= 0 &&
ioctl(fd, DKIOCGETBLOCKSIZE, &size) >= 0) {
if (sizeof(blkid_loff_t) < sizeof(unsigned long long) &&
(size64 * size) > 0xFFFFFFFF)
return 0; /* EFBIG */
return (blkid_loff_t)size64 * size;
}
#endif
#ifdef BLKGETSIZE64
{
int valid_blkgetsize64 = 1;
#ifdef __linux__
struct utsname ut;
if ((uname(&ut) == 0) &&
((ut.release[0] == '2') && (ut.release[1] == '.') &&
(ut.release[2] < '6') && (ut.release[3] == '.')))
valid_blkgetsize64 = 0;
#endif
if (valid_blkgetsize64 &&
ioctl(fd, BLKGETSIZE64, &size64) >= 0) {
if (sizeof(blkid_loff_t) < sizeof(unsigned long long) &&
(size64 > 0xFFFFFFFF))
return 0; /* EFBIG */
return size64;
}
}
#endif /* BLKGETSIZE64 */
#ifdef BLKGETSIZE
{
unsigned long size;
if (ioctl(fd, BLKGETSIZE, &size) >= 0)
return (blkid_loff_t)size << 9;
}
#endif
/* tested on FreeBSD 6.1-RELEASE i386 */
#ifdef DIOCGMEDIASIZE
if (ioctl(fd, DIOCGMEDIASIZE, &size64) >= 0)
return (off_t)size64;
#endif /* DIOCGMEDIASIZE */
#ifdef FDGETPRM
{
struct floppy_struct this_floppy;
if (ioctl(fd, FDGETPRM, &this_floppy) >= 0)
return (blkid_loff_t)this_floppy.size << 9;
}
#endif
#if defined(HAVE_SYS_DISKLABEL_H) && defined(DIOCGDINFO)
{
int part = -1;
struct disklabel lab;
struct partition *pp;
char ch;
struct stat st;
/*
* This code works for FreeBSD 4.11 i386, except for the full
* device (such as /dev/ad0). It doesn't work properly for
* newer FreeBSD though. FreeBSD >= 5.0 should be covered by
* the DIOCGMEDIASIZE above however.
*
* Note that FreeBSD >= 4.0 has disk devices as unbuffered (raw,
* character) devices, so we need to check for S_ISCHR, too.
*/
if (fstat(fd, &st) >= 0 &&
blkidP_is_disk_device(st.st_mode))
part = st.st_rdev & 7;
if (part >= 0 && (ioctl(fd, DIOCGDINFO, (char *)&lab) >= 0)) {
pp = &lab.d_partitions[part];
if (pp->p_size)
return pp->p_size << 9;
}
}
#endif /* defined(HAVE_SYS_DISKLABEL_H) && defined(DIOCGDINFO) */
{
#if defined(HAVE_FSTAT64) && !defined(__OSX_AVAILABLE_BUT_DEPRECATED)
struct stat64 st;
if (fstat64(fd, &st) == 0)
#else
struct stat st;
if (fstat(fd, &st) == 0)
#endif
if (S_ISREG(st.st_mode))
return st.st_size;
}
/*
* OK, we couldn't figure it out by using a specialized ioctl,
* which is generally the best way. So do binary search to
* find the size of the partition.
*/
low = 0;
for (high = 1024; valid_offset(fd, high); high *= 2)
low = high;
while (low < high - 1) {
const blkid_loff_t mid = (low + high) / 2;
if (valid_offset(fd, mid))
low = mid;
else
high = mid;
}
return low + 1;
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
long long bytes;
int fd;
if (argc < 2) {
fprintf(stderr, "Usage: %s device\n"
"Determine the size of a device\n", argv[0]);
return 1;
}
if ((fd = open(argv[1], O_RDONLY)) < 0)
perror(argv[0]);
bytes = blkid_get_dev_size(fd);
printf("Device %s has %lld 1k blocks.\n", argv[1],
(unsigned long long)bytes >> 10);
return 0;
}
#endif

Binary file not shown.

View File

@@ -1,147 +0,0 @@
/*
* llseek.c -- stub calling the llseek system call
*
* Copyright (C) 1994, 1995, 1996, 1997 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#ifdef __MSDOS__
#include <io.h>
#endif
#include "blkidP.h"
#ifdef __linux__
#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
#define my_llseek lseek64
#elif defined(HAVE_LLSEEK)
#include <sys/syscall.h>
#ifndef HAVE_LLSEEK_PROTOTYPE
extern long long llseek(int fd, long long offset, int origin);
#endif
#define my_llseek llseek
#else /* ! HAVE_LLSEEK */
#if SIZEOF_LONG == SIZEOF_LONG_LONG
#define llseek lseek
#else /* SIZEOF_LONG != SIZEOF_LONG_LONG */
#include <linux/unistd.h>
#ifndef __NR__llseek
#define __NR__llseek 140
#endif
#ifndef __i386__
static int _llseek(unsigned int, unsigned long, unsigned long,
blkid_loff_t *, unsigned int);
static _syscall5(int, _llseek, unsigned int, fd, unsigned long, offset_high,
unsigned long, offset_low, blkid_loff_t *, result,
unsigned int, origin)
#endif
static blkid_loff_t my_llseek(int fd, blkid_loff_t offset, int origin)
{
blkid_loff_t result;
int retval;
#ifndef __i386__
retval = _llseek(fd, ((unsigned long long) offset) >> 32,
((unsigned long long)offset) & 0xffffffff,
&result, origin);
#else
retval = syscall(__NR__llseek, fd, ((unsigned long long) offset) >> 32,
((unsigned long long)offset) & 0xffffffff,
&result, origin);
#endif
return (retval == -1 ? (blkid_loff_t) retval : result);
}
#endif /* __alpha__ || __ia64__ */
#endif /* HAVE_LLSEEK */
blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int whence)
{
blkid_loff_t result;
static int do_compat = 0;
if ((sizeof(off_t) >= sizeof(blkid_loff_t)) ||
(offset < ((blkid_loff_t) 1 << ((sizeof(off_t)*8) -1))))
return lseek(fd, (off_t) offset, whence);
if (do_compat) {
errno = EOVERFLOW;
return -1;
}
result = my_llseek(fd, offset, whence);
if (result == -1 && errno == ENOSYS) {
/*
* Just in case this code runs on top of an old kernel
* which does not support the llseek system call
*/
do_compat++;
errno = EOVERFLOW;
}
return result;
}
#else /* !linux */
#ifndef EOVERFLOW
#ifdef EXT2_ET_INVALID_ARGUMENT
#define EOVERFLOW EXT2_ET_INVALID_ARGUMENT
#else
#define EOVERFLOW 112
#endif
#endif
blkid_loff_t blkid_llseek(int fd, blkid_loff_t offset, int origin)
{
#if defined(HAVE_LSEEK64) && defined(HAVE_LSEEK64_PROTOTYPE)
return lseek64 (fd, offset, origin);
#else
if ((sizeof(off_t) < sizeof(blkid_loff_t)) &&
(offset >= ((blkid_loff_t) 1 << ((sizeof(off_t)*8) - 1)))) {
errno = EOVERFLOW;
return -1;
}
return lseek(fd, (off_t) offset, origin);
#endif
}
#endif /* linux */

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@@ -1,494 +0,0 @@
/*
* read.c - read the blkid cache from disk, to avoid scanning all devices
*
* Copyright (C) 2001, 2003 Theodore Y. Ts'o
* Copyright (C) 2001 Andreas Dilger
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#define _XOPEN_SOURCE 600 /* for inclusion of strtoull */
#include "config.h"
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#include "blkidP.h"
#include "uuid/uuid.h"
#ifdef HAVE_STRTOULL
#define STRTOULL strtoull /* defined in stdlib.h if you try hard enough */
#else
/* FIXME: need to support real strtoull here */
#define STRTOULL strtoul
#endif
#if HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef TEST_PROGRAM
#define blkid_debug_dump_dev(dev) (debug_dump_dev(dev))
static void debug_dump_dev(blkid_dev dev);
#endif
/*
* File format:
*
* <device [<NAME="value"> ...]>device_name</device>
*
* The following tags are required for each entry:
* <ID="id"> unique (within this file) ID number of this device
* <TIME="time"> (ascii time_t) time this entry was last read from disk
* <TYPE="type"> (detected) type of filesystem/data for this partition
*
* The following tags may be present, depending on the device contents
* <LABEL="label"> (user supplied) label (volume name, etc)
* <UUID="uuid"> (generated) universally unique identifier (serial no)
*/
static char *skip_over_blank(char *cp)
{
while (*cp && isspace(*cp))
cp++;
return cp;
}
static char *skip_over_word(char *cp)
{
char ch;
while ((ch = *cp)) {
/* If we see a backslash, skip the next character */
if (ch == '\\') {
cp++;
if (*cp == '\0')
break;
cp++;
continue;
}
if (isspace(ch) || ch == '<' || ch == '>')
break;
cp++;
}
return cp;
}
static char *strip_line(char *line)
{
char *p;
line = skip_over_blank(line);
p = line + strlen(line) - 1;
while (*line) {
if (isspace(*p))
*p-- = '\0';
else
break;
}
return line;
}
#if 0
static char *parse_word(char **buf)
{
char *word, *next;
word = *buf;
if (*word == '\0')
return NULL;
word = skip_over_blank(word);
next = skip_over_word(word);
if (*next) {
char *end = next - 1;
if (*end == '"' || *end == '\'')
*end = '\0';
*next++ = '\0';
}
*buf = next;
if (*word == '"' || *word == '\'')
word++;
return word;
}
#endif
/*
* Start parsing a new line from the cache.
*
* line starts with "<device" return 1 -> continue parsing line
* line starts with "<foo", empty, or # return 0 -> skip line
* line starts with other, return -BLKID_ERR_CACHE -> error
*/
static int parse_start(char **cp)
{
char *p;
p = strip_line(*cp);
/* Skip comment or blank lines. We can't just NUL the first '#' char,
* in case it is inside quotes, or escaped.
*/
if (*p == '\0' || *p == '#')
return 0;
if (!strncmp(p, "<device", 7)) {
DBG(DEBUG_READ, printf("found device header: %8s\n", p));
p += 7;
*cp = p;
return 1;
}
if (*p == '<')
return 0;
return -BLKID_ERR_CACHE;
}
/* Consume the remaining XML on the line (cosmetic only) */
static int parse_end(char **cp)
{
*cp = skip_over_blank(*cp);
if (!strncmp(*cp, "</device>", 9)) {
DBG(DEBUG_READ, printf("found device trailer %9s\n", *cp));
*cp += 9;
return 0;
}
return -BLKID_ERR_CACHE;
}
/*
* Allocate a new device struct with device name filled in. Will handle
* finding the device on lines of the form:
* <device foo=bar>devname</device>
* <device>devname<foo>bar</foo></device>
*/
static int parse_dev(blkid_cache cache, blkid_dev *dev, char **cp)
{
char *start, *tmp, *end, *name;
int ret;
if ((ret = parse_start(cp)) <= 0)
return ret;
start = tmp = strchr(*cp, '>');
if (!start) {
DBG(DEBUG_READ,
printf("blkid: short line parsing dev: %s\n", *cp));
return -BLKID_ERR_CACHE;
}
start = skip_over_blank(start + 1);
end = skip_over_word(start);
DBG(DEBUG_READ, printf("device should be %.*s\n",
(int)(end - start), start));
if (**cp == '>')
*cp = end;
else
(*cp)++;
*tmp = '\0';
if (!(tmp = strrchr(end, '<')) || parse_end(&tmp) < 0) {
DBG(DEBUG_READ,
printf("blkid: missing </device> ending: %s\n", end));
} else if (tmp)
*tmp = '\0';
if (end - start <= 1) {
DBG(DEBUG_READ, printf("blkid: empty device name: %s\n", *cp));
return -BLKID_ERR_CACHE;
}
name = blkid_strndup(start, end-start);
if (name == NULL)
return -BLKID_ERR_MEM;
DBG(DEBUG_READ, printf("found dev %s\n", name));
if (!(*dev = blkid_get_dev(cache, name, BLKID_DEV_CREATE))) {
free(name);
return -BLKID_ERR_MEM;
}
free(name);
return 1;
}
/*
* Extract a tag of the form NAME="value" from the line.
*/
static int parse_token(char **name, char **value, char **cp)
{
char *end;
if (!name || !value || !cp)
return -BLKID_ERR_PARAM;
if (!(*value = strchr(*cp, '=')))
return 0;
**value = '\0';
*name = strip_line(*cp);
*value = skip_over_blank(*value + 1);
if (**value == '"') {
end = strchr(*value + 1, '"');
if (!end) {
DBG(DEBUG_READ,
printf("unbalanced quotes at: %s\n", *value));
*cp = *value;
return -BLKID_ERR_CACHE;
}
(*value)++;
*end = '\0';
end++;
} else {
end = skip_over_word(*value);
if (*end) {
*end = '\0';
end++;
}
}
*cp = end;
return 1;
}
/*
* Extract a tag of the form <NAME>value</NAME> from the line.
*/
/*
static int parse_xml(char **name, char **value, char **cp)
{
char *end;
if (!name || !value || !cp)
return -BLKID_ERR_PARAM;
*name = strip_line(*cp);
if ((*name)[0] != '<' || (*name)[1] == '/')
return 0;
FIXME: finish this.
}
*/
/*
* Extract a tag from the line.
*
* Return 1 if a valid tag was found.
* Return 0 if no tag found.
* Return -ve error code.
*/
static int parse_tag(blkid_cache cache, blkid_dev dev, char **cp)
{
char *name;
char *value;
int ret;
if (!cache || !dev)
return -BLKID_ERR_PARAM;
if ((ret = parse_token(&name, &value, cp)) <= 0 /* &&
(ret = parse_xml(&name, &value, cp)) <= 0 */)
return ret;
/* Some tags are stored directly in the device struct */
if (!strcmp(name, "DEVNO"))
dev->bid_devno = STRTOULL(value, 0, 0);
else if (!strcmp(name, "PRI"))
dev->bid_pri = strtol(value, 0, 0);
else if (!strcmp(name, "TIME"))
dev->bid_time = STRTOULL(value, 0, 0);
else
ret = blkid_set_tag(dev, name, value, strlen(value));
DBG(DEBUG_READ, printf(" tag: %s=\"%s\"\n", name, value));
return ret < 0 ? ret : 1;
}
/*
* Parse a single line of data, and return a newly allocated dev struct.
* Add the new device to the cache struct, if one was read.
*
* Lines are of the form <device [TAG="value" ...]>/dev/foo</device>
*
* Returns -ve value on error.
* Returns 0 otherwise.
* If a valid device was read, *dev_p is non-NULL, otherwise it is NULL
* (e.g. comment lines, unknown XML content, etc).
*/
static int blkid_parse_line(blkid_cache cache, blkid_dev *dev_p, char *cp)
{
blkid_dev dev;
int ret;
if (!cache || !dev_p)
return -BLKID_ERR_PARAM;
*dev_p = NULL;
DBG(DEBUG_READ, printf("line: %s\n", cp));
if ((ret = parse_dev(cache, dev_p, &cp)) <= 0)
return ret;
dev = *dev_p;
while ((ret = parse_tag(cache, dev, &cp)) > 0) {
;
}
if (dev->bid_type == NULL) {
DBG(DEBUG_READ,
printf("blkid: device %s has no TYPE\n",dev->bid_name));
blkid_free_dev(dev);
}
DBG(DEBUG_READ, blkid_debug_dump_dev(dev));
return ret;
}
/*
* Parse the specified filename, and return the data in the supplied or
* a newly allocated cache struct. If the file doesn't exist, return a
* new empty cache struct.
*/
void blkid_read_cache(blkid_cache cache)
{
FILE *file;
char buf[4096];
int fd, lineno = 0;
struct stat st;
if (!cache)
return;
/*
* If the file doesn't exist, then we just return an empty
* struct so that the cache can be populated.
*/
if ((fd = open(cache->bic_filename, O_RDONLY)) < 0)
return;
if (fstat(fd, &st) < 0)
goto errout;
if ((st.st_mtime == cache->bic_ftime) ||
(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
DBG(DEBUG_CACHE, printf("skipping re-read of %s\n",
cache->bic_filename));
goto errout;
}
DBG(DEBUG_CACHE, printf("reading cache file %s\n",
cache->bic_filename));
file = fdopen(fd, "r");
if (!file)
goto errout;
while (fgets(buf, sizeof(buf), file)) {
blkid_dev dev;
unsigned int end;
lineno++;
if (buf[0] == 0)
continue;
end = strlen(buf) - 1;
/* Continue reading next line if it ends with a backslash */
while (buf[end] == '\\' && end < sizeof(buf) - 2 &&
fgets(buf + end, sizeof(buf) - end, file)) {
end = strlen(buf) - 1;
lineno++;
}
if (blkid_parse_line(cache, &dev, buf) < 0) {
DBG(DEBUG_READ,
printf("blkid: bad format on line %d\n", lineno));
continue;
}
}
fclose(file);
/*
* Initially we do not need to write out the cache file.
*/
cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
cache->bic_ftime = st.st_mtime;
return;
errout:
close(fd);
return;
}
#ifdef TEST_PROGRAM
static void debug_dump_dev(blkid_dev dev)
{
struct list_head *p;
if (!dev) {
printf(" dev: NULL\n");
return;
}
printf(" dev: name = %s\n", dev->bid_name);
printf(" dev: DEVNO=\"0x%0llx\"\n", (long long)dev->bid_devno);
printf(" dev: TIME=\"%lld\"\n", (long long)dev->bid_time);
printf(" dev: PRI=\"%d\"\n", dev->bid_pri);
printf(" dev: flags = 0x%08X\n", dev->bid_flags);
list_for_each(p, &dev->bid_tags) {
blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
if (tag)
printf(" tag: %s=\"%s\"\n", tag->bit_name,
tag->bit_val);
else
printf(" tag: NULL\n");
}
printf("\n");
}
int main(int argc, char**argv)
{
blkid_cache cache = NULL;
int ret;
blkid_debug_mask = DEBUG_ALL;
if (argc > 2) {
fprintf(stderr, "Usage: %s [filename]\n"
"Test parsing of the cache (filename)\n", argv[0]);
exit(1);
}
if ((ret = blkid_get_cache(&cache, argv[1])) < 0)
fprintf(stderr, "error %d reading cache file %s\n", ret,
argv[1] ? argv[1] : BLKID_CACHE_FILE);
blkid_put_cache(cache);
return ret;
}
#endif

Binary file not shown.

View File

@@ -1,140 +0,0 @@
/*
* resolve.c - resolve names and tags into specific devices
*
* Copyright (C) 2001, 2003 Theodore Ts'o.
* Copyright (C) 2001 Andreas Dilger
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "blkidP.h"
/*
* Find a tagname (e.g. LABEL or UUID) on a specific device.
*/
char *blkid_get_tag_value(blkid_cache cache, const char *tagname,
const char *devname)
{
blkid_tag found;
blkid_dev dev;
blkid_cache c = cache;
char *ret = NULL;
DBG(DEBUG_RESOLVE, printf("looking for %s on %s\n", tagname, devname));
if (!devname)
return NULL;
if (!cache) {
if (blkid_get_cache(&c, NULL) < 0)
return NULL;
}
if ((dev = blkid_get_dev(c, devname, BLKID_DEV_NORMAL)) &&
(found = blkid_find_tag_dev(dev, tagname)))
ret = blkid_strdup(found->bit_val);
if (!cache)
blkid_put_cache(c);
return ret;
}
/*
* Locate a device name from a token (NAME=value string), or (name, value)
* pair. In the case of a token, value is ignored. If the "token" is not
* of the form "NAME=value" and there is no value given, then it is assumed
* to be the actual devname and a copy is returned.
*/
char *blkid_get_devname(blkid_cache cache, const char *token,
const char *value)
{
blkid_dev dev;
blkid_cache c = cache;
char *t = 0, *v = 0;
char *ret = NULL;
if (!token)
return NULL;
if (!cache) {
if (blkid_get_cache(&c, NULL) < 0)
return NULL;
}
DBG(DEBUG_RESOLVE,
printf("looking for %s%s%s %s\n", token, value ? "=" : "",
value ? value : "", cache ? "in cache" : "from disk"));
if (!value) {
if (!strchr(token, '=')) {
ret = blkid_strdup(token);
goto out;
}
blkid_parse_tag_string(token, &t, &v);
if (!t || !v)
goto out;
token = t;
value = v;
}
dev = blkid_find_dev_with_tag(c, token, value);
if (!dev)
goto out;
ret = blkid_strdup(blkid_dev_devname(dev));
out:
free(t);
free(v);
if (!cache) {
blkid_put_cache(c);
}
return (ret);
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
char *value;
blkid_cache cache;
blkid_debug_mask = DEBUG_ALL;
if (argc != 2 && argc != 3) {
fprintf(stderr, "Usage:\t%s tagname=value\n"
"\t%s tagname devname\n"
"Find which device holds a given token or\n"
"Find what the value of a tag is in a device\n",
argv[0], argv[0]);
exit(1);
}
if (blkid_get_cache(&cache, "/dev/null") < 0) {
fprintf(stderr, "Couldn't get blkid cache\n");
exit(1);
}
if (argv[2]) {
value = blkid_get_tag_value(cache, argv[1], argv[2]);
printf("%s has tag %s=%s\n", argv[2], argv[1],
value ? value : "<missing>");
} else {
value = blkid_get_devname(cache, argv[1], NULL);
printf("%s has tag %s\n", value ? value : "<none>", argv[1]);
}
blkid_put_cache(cache);
return value ? 0 : 1;
}
#endif

Binary file not shown.

View File

@@ -1,213 +0,0 @@
/*
* save.c - write the cache struct to disk
*
* Copyright (C) 2001 by Andreas Dilger
* Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#ifdef HAVE_SYS_MKDEV_H
#include <sys/mkdev.h>
#endif
#ifdef HAVE_ERRNO_H
#include <errno.h>
#endif
#include "blkidP.h"
#ifdef _WIN32
#include "windows.h"
#endif
static int save_dev(blkid_dev dev, FILE *file)
{
struct list_head *p;
if (!dev || dev->bid_name[0] != '/')
return 0;
DBG(DEBUG_SAVE,
printf("device %s, type %s\n", dev->bid_name, dev->bid_type ?
dev->bid_type : "(null)"));
fprintf(file,
"<device DEVNO=\"0x%04lx\" TIME=\"%ld\"",
(unsigned long) dev->bid_devno, (long) dev->bid_time);
if (dev->bid_pri)
fprintf(file, " PRI=\"%d\"", dev->bid_pri);
list_for_each(p, &dev->bid_tags) {
blkid_tag tag = list_entry(p, struct blkid_struct_tag, bit_tags);
fprintf(file, " %s=\"%s\"", tag->bit_name,tag->bit_val);
}
fprintf(file, ">%s</device>\n", dev->bid_name);
return 0;
}
/*
* Write out the cache struct to the cache file on disk.
*/
int blkid_flush_cache(blkid_cache cache)
{
struct list_head *p;
char *tmp = NULL;
const char *opened = NULL;
const char *filename;
FILE *file = NULL;
int fd, ret = 0;
struct stat st;
if (!cache)
return -BLKID_ERR_PARAM;
if (list_empty(&cache->bic_devs) ||
!(cache->bic_flags & BLKID_BIC_FL_CHANGED)) {
DBG(DEBUG_SAVE, printf("skipping cache file write\n"));
return 0;
}
filename = cache->bic_filename ? cache->bic_filename: BLKID_CACHE_FILE;
/* If we can't write to the cache file, then don't even try */
if (((ret = stat(filename, &st)) < 0 && errno != ENOENT) ||
(ret == 0 && access(filename, W_OK) < 0)) {
DBG(DEBUG_SAVE,
printf("can't write to cache file %s\n", filename));
return 0;
}
/*
* Try and create a temporary file in the same directory so
* that in case of error we don't overwrite the cache file.
* If the cache file doesn't yet exist, it isn't a regular
* file (e.g. /dev/null or a socket), or we couldn't create
* a temporary file then we open it directly.
*/
if (ret == 0 && S_ISREG(st.st_mode)) {
tmp = malloc(strlen(filename) + 8);
if (tmp) {
mode_t save_umask = umask(022);
sprintf(tmp, "%s-XXXXXX", filename);
fd = mkstemp(tmp);
umask(save_umask);
if (fd >= 0) {
file = fdopen(fd, "w");
opened = tmp;
}
#ifndef _WIN32
fchmod(fd, 0644);
#else
chmod(tmp, 0644);
#endif
}
}
if (!file) {
file = fopen(filename, "w");
opened = filename;
}
DBG(DEBUG_SAVE,
printf("writing cache file %s (really %s)\n",
filename, opened));
if (!file) {
ret = errno;
goto errout;
}
list_for_each(p, &cache->bic_devs) {
blkid_dev dev = list_entry(p, struct blkid_struct_dev, bid_devs);
if (!dev->bid_type)
continue;
if ((ret = save_dev(dev, file)) < 0)
break;
}
if (ret >= 0) {
cache->bic_flags &= ~BLKID_BIC_FL_CHANGED;
ret = 1;
}
fclose(file);
if (opened != filename) {
if (ret < 0) {
(void) unlink(opened);
DBG(DEBUG_SAVE,
printf("unlinked temp cache %s\n", opened));
} else {
char *backup;
backup = malloc(strlen(filename) + 5);
if (backup) {
sprintf(backup, "%s.old", filename);
unlink(backup);
#if defined(__GNUC__) && __GNUC__ >= 5
/* explicit (void) cast is not enough with glibc and _FORTIFY_SOURCE */
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wunused-result"
#endif
(void) link(filename, backup);
#if defined(__GNUC__) && __GNUC__ >= 5
#pragma GCC diagnostic pop
#endif
free(backup);
}
if (rename(opened, filename) < 0)
(void) unlink(opened);
DBG(DEBUG_SAVE,
printf("moved temp cache %s\n", opened));
}
}
errout:
free(tmp);
return ret;
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
blkid_cache cache = NULL;
int ret;
blkid_debug_mask = DEBUG_ALL;
if (argc > 2) {
fprintf(stderr, "Usage: %s [filename]\n"
"Test loading/saving a cache (filename)\n", argv[0]);
exit(1);
}
if ((ret = blkid_get_cache(&cache, "/dev/null")) != 0) {
fprintf(stderr, "%s: error creating cache (%d)\n",
argv[0], ret);
exit(1);
}
if ((ret = blkid_probe_all(cache)) < 0) {
fprintf(stderr, "error (%d) probing devices\n", ret);
exit(1);
}
cache->bic_filename = blkid_strdup(argv[1]);
if ((ret = blkid_flush_cache(cache)) < 0) {
fprintf(stderr, "error (%d) saving cache\n", ret);
exit(1);
}
blkid_put_cache(cache);
return ret;
}
#endif

Binary file not shown.

View File

@@ -1,471 +0,0 @@
/*
* tag.c - allocation/initialization/free routines for tag structs
*
* Copyright (C) 2001 Andreas Dilger
* Copyright (C) 2003 Theodore Ts'o
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#include "config.h"
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "blkidP.h"
static blkid_tag blkid_new_tag(void)
{
blkid_tag tag;
if (!(tag = (blkid_tag) calloc(1, sizeof(struct blkid_struct_tag))))
return NULL;
INIT_LIST_HEAD(&tag->bit_tags);
INIT_LIST_HEAD(&tag->bit_names);
return tag;
}
#ifdef CONFIG_BLKID_DEBUG
void blkid_debug_dump_tag(blkid_tag tag)
{
if (!tag) {
printf(" tag: NULL\n");
return;
}
printf(" tag: %s=\"%s\"\n", tag->bit_name, tag->bit_val);
}
#endif
void blkid_free_tag(blkid_tag tag)
{
if (!tag)
return;
DBG(DEBUG_TAG, printf(" freeing tag %s=%s\n", tag->bit_name,
tag->bit_val ? tag->bit_val : "(NULL)"));
DBG(DEBUG_TAG, blkid_debug_dump_tag(tag));
list_del(&tag->bit_tags); /* list of tags for this device */
list_del(&tag->bit_names); /* list of tags with this type */
free(tag->bit_name);
free(tag->bit_val);
free(tag);
}
/*
* Find the desired tag on a device. If value is NULL, then the
* first such tag is returned, otherwise return only exact tag if found.
*/
blkid_tag blkid_find_tag_dev(blkid_dev dev, const char *type)
{
struct list_head *p;
if (!dev || !type)
return NULL;
list_for_each(p, &dev->bid_tags) {
blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
bit_tags);
if (!strcmp(tmp->bit_name, type))
return tmp;
}
return NULL;
}
extern int blkid_dev_has_tag(blkid_dev dev, const char *type,
const char *value)
{
blkid_tag tag;
if (!dev || !type)
return -1;
tag = blkid_find_tag_dev(dev, type);
if (!value)
return (tag != NULL);
if (!tag || strcmp(tag->bit_val, value))
return 0;
return 1;
}
/*
* Find the desired tag type in the cache.
* We return the head tag for this tag type.
*/
static blkid_tag blkid_find_head_cache(blkid_cache cache, const char *type)
{
blkid_tag head = NULL, tmp;
struct list_head *p;
if (!cache || !type)
return NULL;
list_for_each(p, &cache->bic_tags) {
tmp = list_entry(p, struct blkid_struct_tag, bit_tags);
if (!strcmp(tmp->bit_name, type)) {
DBG(DEBUG_TAG,
printf(" found cache tag head %s\n", type));
head = tmp;
break;
}
}
return head;
}
/*
* Set a tag on an existing device.
*
* If value is NULL, then delete the tagsfrom the device.
*/
int blkid_set_tag(blkid_dev dev, const char *name,
const char *value, const int vlength)
{
blkid_tag t = 0, head = 0;
char *val = 0;
char **dev_var = 0;
if (!dev || !name)
return -BLKID_ERR_PARAM;
if (!(val = blkid_strndup(value, vlength)) && value)
return -BLKID_ERR_MEM;
/*
* Certain common tags are linked directly to the device struct
* We need to know what they are before we do anything else because
* the function name parameter might get freed later on.
*/
if (!strcmp(name, "TYPE"))
dev_var = &dev->bid_type;
else if (!strcmp(name, "LABEL"))
dev_var = &dev->bid_label;
else if (!strcmp(name, "UUID"))
dev_var = &dev->bid_uuid;
t = blkid_find_tag_dev(dev, name);
if (!value) {
if (t)
blkid_free_tag(t);
} else if (t) {
if (!strcmp(t->bit_val, val)) {
/* Same thing, exit */
free(val);
return 0;
}
free(t->bit_val);
t->bit_val = val;
} else {
/* Existing tag not present, add to device */
if (!(t = blkid_new_tag()))
goto errout;
t->bit_name = blkid_strdup(name);
t->bit_val = val;
t->bit_dev = dev;
list_add_tail(&t->bit_tags, &dev->bid_tags);
if (dev->bid_cache) {
head = blkid_find_head_cache(dev->bid_cache,
t->bit_name);
if (!head) {
head = blkid_new_tag();
if (!head)
goto errout;
DBG(DEBUG_TAG,
printf(" creating new cache tag head %s\n", name));
head->bit_name = blkid_strdup(name);
if (!head->bit_name)
goto errout;
list_add_tail(&head->bit_tags,
&dev->bid_cache->bic_tags);
}
list_add_tail(&t->bit_names, &head->bit_names);
}
}
/* Link common tags directly to the device struct */
if (dev_var)
*dev_var = val;
if (dev->bid_cache)
dev->bid_cache->bic_flags |= BLKID_BIC_FL_CHANGED;
return 0;
errout:
if (t)
blkid_free_tag(t);
else free(val);
if (head)
blkid_free_tag(head);
return -BLKID_ERR_MEM;
}
/*
* Parse a "NAME=value" string. This is slightly different than
* parse_token, because that will end an unquoted value at a space, while
* this will assume that an unquoted value is the rest of the token (e.g.
* if we are passed an already quoted string from the command-line we don't
* have to both quote and escape quote so that the quotes make it to
* us).
*
* Returns 0 on success, and -1 on failure.
*/
int blkid_parse_tag_string(const char *token, char **ret_type, char **ret_val)
{
char *name, *value, *cp;
DBG(DEBUG_TAG, printf("trying to parse '%s' as a tag\n", token));
if (!token || !(cp = strchr(token, '=')))
return -1;
name = blkid_strdup(token);
if (!name)
return -1;
value = name + (cp - token);
*value++ = '\0';
if (*value == '"' || *value == '\'') {
char c = *value++;
if (!(cp = strrchr(value, c)))
goto errout; /* missing closing quote */
*cp = '\0';
}
value = blkid_strdup(value);
if (!value)
goto errout;
*ret_type = name;
*ret_val = value;
return 0;
errout:
free(name);
return -1;
}
/*
* Tag iteration routines for the public libblkid interface.
*
* These routines do not expose the list.h implementation, which are a
* contamination of the namespace, and which force us to reveal far, far
* too much of our internal implementation. I'm not convinced I want
* to keep list.h in the long term, anyway. It's fine for kernel
* programming, but performance is not the #1 priority for this
* library, and I really don't like the tradeoff of type-safety for
* performance for this application. [tytso:20030125.2007EST]
*/
/*
* This series of functions iterate over all tags in a device
*/
#define TAG_ITERATE_MAGIC 0x01a5284c
struct blkid_struct_tag_iterate {
int magic;
blkid_dev dev;
struct list_head *p;
};
extern blkid_tag_iterate blkid_tag_iterate_begin(blkid_dev dev)
{
blkid_tag_iterate iter;
iter = malloc(sizeof(struct blkid_struct_tag_iterate));
if (iter) {
iter->magic = TAG_ITERATE_MAGIC;
iter->dev = dev;
iter->p = dev->bid_tags.next;
}
return (iter);
}
/*
* Return 0 on success, -1 on error
*/
extern int blkid_tag_next(blkid_tag_iterate iter,
const char **type, const char **value)
{
blkid_tag tag;
*type = 0;
*value = 0;
if (!iter || iter->magic != TAG_ITERATE_MAGIC ||
iter->p == &iter->dev->bid_tags)
return -1;
tag = list_entry(iter->p, struct blkid_struct_tag, bit_tags);
*type = tag->bit_name;
*value = tag->bit_val;
iter->p = iter->p->next;
return 0;
}
extern void blkid_tag_iterate_end(blkid_tag_iterate iter)
{
if (!iter || iter->magic != TAG_ITERATE_MAGIC)
return;
iter->magic = 0;
free(iter);
}
/*
* This function returns a device which matches a particular
* type/value pair. If there is more than one device that matches the
* search specification, it returns the one with the highest priority
* value. This allows us to give preference to EVMS or LVM devices.
*/
extern blkid_dev blkid_find_dev_with_tag(blkid_cache cache,
const char *type,
const char *value)
{
blkid_tag head;
blkid_dev dev;
int pri;
struct list_head *p;
int probe_new = 0;
if (!cache || !type || !value)
return NULL;
blkid_read_cache(cache);
DBG(DEBUG_TAG, printf("looking for %s=%s in cache\n", type, value));
try_again:
pri = -1;
dev = 0;
head = blkid_find_head_cache(cache, type);
if (head) {
list_for_each(p, &head->bit_names) {
blkid_tag tmp = list_entry(p, struct blkid_struct_tag,
bit_names);
if (!strcmp(tmp->bit_val, value) &&
(tmp->bit_dev->bid_pri > pri) &&
!access(tmp->bit_dev->bid_name, F_OK)) {
dev = tmp->bit_dev;
pri = dev->bid_pri;
}
}
}
if (dev && !(dev->bid_flags & BLKID_BID_FL_VERIFIED)) {
dev = blkid_verify(cache, dev);
if (!dev || (dev && (dev->bid_flags & BLKID_BID_FL_VERIFIED)))
goto try_again;
}
if (!dev && !probe_new) {
if (blkid_probe_all_new(cache) < 0)
return NULL;
probe_new++;
goto try_again;
}
if (!dev && !(cache->bic_flags & BLKID_BIC_FL_PROBED)) {
if (blkid_probe_all(cache) < 0)
return NULL;
goto try_again;
}
return dev;
}
#ifdef TEST_PROGRAM
#ifdef HAVE_GETOPT_H
#include <getopt.h>
#else
extern char *optarg;
extern int optind;
#endif
void usage(char *prog)
{
fprintf(stderr, "Usage: %s [-f blkid_file] [-m debug_mask] device "
"[type value]\n",
prog);
fprintf(stderr, "\tList all tags for a device and exit\n");
exit(1);
}
int main(int argc, char **argv)
{
blkid_tag_iterate iter;
blkid_cache cache = NULL;
blkid_dev dev;
int c, ret, found;
int flags = BLKID_DEV_FIND;
char *tmp;
char *file = NULL;
char *devname = NULL;
char *search_type = NULL;
char *search_value = NULL;
const char *type, *value;
while ((c = getopt (argc, argv, "m:f:")) != EOF)
switch (c) {
case 'f':
file = optarg;
break;
case 'm':
blkid_debug_mask = strtoul (optarg, &tmp, 0);
if (*tmp) {
fprintf(stderr, "Invalid debug mask: %s\n",
optarg);
exit(1);
}
break;
case '?':
usage(argv[0]);
}
if (argc > optind)
devname = argv[optind++];
if (argc > optind)
search_type = argv[optind++];
if (argc > optind)
search_value = argv[optind++];
if (!devname || (argc != optind))
usage(argv[0]);
if ((ret = blkid_get_cache(&cache, file)) != 0) {
fprintf(stderr, "%s: error creating cache (%d)\n",
argv[0], ret);
exit(1);
}
dev = blkid_get_dev(cache, devname, flags);
if (!dev) {
fprintf(stderr, "%s: Can not find device in blkid cache\n",
devname);
exit(1);
}
if (search_type) {
found = blkid_dev_has_tag(dev, search_type, search_value);
printf("Device %s: (%s, %s) %s\n", blkid_dev_devname(dev),
search_type, search_value ? search_value : "NULL",
found ? "FOUND" : "NOT FOUND");
return(!found);
}
printf("Device %s...\n", blkid_dev_devname(dev));
iter = blkid_tag_iterate_begin(dev);
while (blkid_tag_next(iter, &type, &value) == 0) {
printf("\tTag %s has value %s\n", type, value);
}
blkid_tag_iterate_end(iter);
blkid_put_cache(cache);
return (0);
}
#endif

Binary file not shown.

View File

@@ -1,50 +0,0 @@
/*
* version.c --- Return the version of the blkid library
*
* Copyright (C) 2004 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the
* GNU Lesser General Public License.
* %End-Header%
*/
#include "config.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <blkid/blkid_local.h>
#include "version.h"
static const char *lib_version = E2FSPROGS_VERSION;
static const char *lib_date = E2FSPROGS_DATE;
int blkid_parse_version_string(const char *ver_string)
{
const char *cp;
int version = 0;
for (cp = ver_string; *cp; cp++) {
if (*cp == '.')
continue;
if (!isdigit(*cp))
break;
version = (version * 10) + (*cp - '0');
}
return version;
}
int blkid_get_library_version(const char **ver_string,
const char **date_string)
{
if (ver_string)
*ver_string = lib_version;
if (date_string)
*date_string = lib_date;
return blkid_parse_version_string(lib_version);
}

Binary file not shown.

View File

@@ -1,74 +0,0 @@
/*
* crypto_mode.c --- convert between encryption modes and strings
*
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <errno.h>
#include "e2p.h"
struct mode {
int num;
const char *string;
};
static struct mode mode_list[] = {
{ EXT4_ENCRYPTION_MODE_INVALID, "Invalid"},
{ EXT4_ENCRYPTION_MODE_AES_256_XTS, "AES-256-XTS"},
{ EXT4_ENCRYPTION_MODE_AES_256_GCM, "AES-256-GCM"},
{ EXT4_ENCRYPTION_MODE_AES_256_CBC, "AES-256-CBC"},
{ 0, 0 },
};
const char *e2p_encmode2string(int num)
{
struct mode *p;
static char buf[20];
for (p = mode_list; p->string; p++) {
if (num == p->num)
return p->string;
}
sprintf(buf, "ENC_MODE_%d", num);
return buf;
}
/*
* Returns the hash algorithm, or -1 on error
*/
int e2p_string2encmode(char *string)
{
struct mode *p;
char *eptr;
int num;
for (p = mode_list; p->string; p++) {
if (!strcasecmp(string, p->string)) {
return p->num;
}
}
if (strncasecmp(string, "ENC_MODE_", 9))
return -1;
if (string[9] == 0)
return -1;
num = strtol(string+9, &eptr, 10);
if (num > 255 || num < 0)
return -1;
if (*eptr)
return -1;
return num;
}

Binary file not shown.

View File

@@ -1,118 +0,0 @@
/*
* encoding.c --- convert between encoding magic numbers and strings
*
* Copyright (C) 2018 Collabora Ltd.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include "e2p.h"
#define ARRAY_SIZE(array) \
(sizeof(array) / sizeof(array[0]))
static const struct {
const char *name;
__u16 encoding_magic;
__u16 default_flags;
} ext4_encoding_map[] = {
{
.encoding_magic = EXT4_ENC_UTF8_12_1,
.name = "utf8-12.1",
.default_flags = 0,
},
{
.encoding_magic = EXT4_ENC_UTF8_12_1,
.name = "utf8",
.default_flags = 0,
},
};
static const struct enc_flags {
__u16 flag;
const char *param;
} encoding_flags[] = {
{ EXT4_ENC_STRICT_MODE_FL, "strict" },
};
/* Return a positive number < 0xff indicating the encoding magic number
* or a negative value indicating error. */
int e2p_str2encoding(const char *string)
{
unsigned int i;
for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
if (!strcmp(string, ext4_encoding_map[i].name))
return ext4_encoding_map[i].encoding_magic;
return -EINVAL;
}
/* Return the name of an encoding or NULL */
const char *e2p_encoding2str(int encoding)
{
unsigned int i;
static char buf[32];
for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
if (ext4_encoding_map[i].encoding_magic == encoding)
return ext4_encoding_map[i].name;
sprintf(buf, "UNKNOWN_ENCODING_%d", encoding);
return buf;
}
int e2p_get_encoding_flags(int encoding)
{
unsigned int i;
for (i = 0 ; i < ARRAY_SIZE(ext4_encoding_map); i++)
if (ext4_encoding_map[i].encoding_magic == encoding)
return ext4_encoding_map[i].default_flags;
return 0;
}
int e2p_str2encoding_flags(int encoding, char *param, __u16 *flags)
{
char *f = strtok(param, "-");
const struct enc_flags *fl;
unsigned int i, neg = 0;
if (encoding != EXT4_ENC_UTF8_12_1)
return -EINVAL;
while (f) {
neg = 0;
if (!strncmp("no", f, 2)) {
neg = 1;
f += 2;
}
for (i = 0; i < ARRAY_SIZE(encoding_flags); i++) {
fl = &encoding_flags[i];
if (!strcmp(fl->param, f)) {
if (neg)
*flags &= ~fl->flag;
else
*flags |= fl->flag;
goto next_flag;
}
}
return -EINVAL;
next_flag:
f = strtok(NULL, "-");
}
return 0;
}

Binary file not shown.

View File

@@ -1,48 +0,0 @@
/*
* errcode.c - convert an error code to a string
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "e2p.h"
static const char *err_string[] = {
"",
"UNKNOWN", /* 1 */
"EIO", /* 2 */
"ENOMEM", /* 3 */
"EFSBADCRC", /* 4 */
"EFSCORRUPTED", /* 5 */
"ENOSPC", /* 6 */
"ENOKEY", /* 7 */
"EROFS", /* 8 */
"EFBIG", /* 9 */
"EEXIST", /* 10 */
"ERANGE", /* 11 */
"EOVERFLOW", /* 12 */
"EBUSY", /* 13 */
"ENOTDIR", /* 14 */
"ENOTEMPTY", /* 15 */
"ESHUTDOWN", /* 16 */
"EFAULT", /* 17 */
};
#define ARRAY_SIZE(array) \
(sizeof(array) / sizeof(array[0]))
/* Return the name of an encoding or NULL */
const char *e2p_errcode2str(unsigned int err)
{
static char buf[32];
if (err < ARRAY_SIZE(err_string))
return err_string[err];
sprintf(buf, "UNKNOWN_ERRCODE_%u", err);
return buf;
}

Binary file not shown.

View File

@@ -1,445 +0,0 @@
/*
* feature.c --- convert between features and strings
*
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "e2p.h"
#include <ext2fs/ext2fs.h>
#include <ext2fs/kernel-jbd.h>
struct feature {
int compat;
unsigned int mask;
const char *string;
};
static struct feature feature_list[] = {
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_PREALLOC,
"dir_prealloc" },
{ E2P_FEATURE_COMPAT, EXT3_FEATURE_COMPAT_HAS_JOURNAL,
"has_journal" },
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_IMAGIC_INODES,
"imagic_inodes" },
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXT_ATTR,
"ext_attr" },
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_DIR_INDEX,
"dir_index" },
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_RESIZE_INODE,
"resize_inode" },
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_LAZY_BG,
"lazy_bg" },
{ E2P_FEATURE_COMPAT, EXT2_FEATURE_COMPAT_EXCLUDE_BITMAP,
"snapshot_bitmap" },
{ E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_SPARSE_SUPER2,
"sparse_super2" },
{ E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_FAST_COMMIT,
"fast_commit" },
{ E2P_FEATURE_COMPAT, EXT4_FEATURE_COMPAT_STABLE_INODES,
"stable_inodes" },
{ E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_SPARSE_SUPER,
"sparse_super" },
{ E2P_FEATURE_RO_INCOMPAT, EXT2_FEATURE_RO_COMPAT_LARGE_FILE,
"large_file" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_HUGE_FILE,
"huge_file" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
"uninit_bg" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_GDT_CSUM,
"uninit_groups" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_DIR_NLINK,
"dir_nlink" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_EXTRA_ISIZE,
"extra_isize" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_QUOTA,
"quota" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_BIGALLOC,
"bigalloc"},
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_METADATA_CSUM,
"metadata_csum"},
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_REPLICA,
"replica" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_READONLY,
"read-only" },
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_PROJECT,
"project"},
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_SHARED_BLOCKS,
"shared_blocks"},
{ E2P_FEATURE_RO_INCOMPAT, EXT4_FEATURE_RO_COMPAT_VERITY,
"verity"},
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_COMPRESSION,
"compression" },
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_FILETYPE,
"filetype" },
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_RECOVER,
"needs_recovery" },
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_JOURNAL_DEV,
"journal_dev" },
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
"extent" },
{ E2P_FEATURE_INCOMPAT, EXT3_FEATURE_INCOMPAT_EXTENTS,
"extents" },
{ E2P_FEATURE_INCOMPAT, EXT2_FEATURE_INCOMPAT_META_BG,
"meta_bg" },
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_64BIT,
"64bit" },
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_MMP,
"mmp" },
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_FLEX_BG,
"flex_bg"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_EA_INODE,
"ea_inode"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_DIRDATA,
"dirdata"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CSUM_SEED,
"metadata_csum_seed"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_LARGEDIR,
"large_dir"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_INLINE_DATA,
"inline_data"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_ENCRYPT,
"encrypt"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD,
"casefold"},
{ E2P_FEATURE_INCOMPAT, EXT4_FEATURE_INCOMPAT_CASEFOLD,
"fname_encoding"},
{ 0, 0, 0 },
};
static struct feature jrnl_feature_list[] = {
{ E2P_FEATURE_COMPAT, JBD2_FEATURE_COMPAT_CHECKSUM,
"journal_checksum" },
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_REVOKE,
"journal_incompat_revoke" },
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_64BIT,
"journal_64bit" },
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_ASYNC_COMMIT,
"journal_async_commit" },
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_CSUM_V2,
"journal_checksum_v2" },
{ E2P_FEATURE_INCOMPAT, JBD2_FEATURE_INCOMPAT_CSUM_V3,
"journal_checksum_v3" },
{ 0, 0, 0 },
};
void e2p_feature_to_string(int compat, unsigned int mask, char *buf,
size_t buf_len)
{
struct feature *f;
char fchar;
int fnum;
for (f = feature_list; f->string; f++) {
if ((compat == f->compat) &&
(mask == f->mask)) {
strncpy(buf, f->string, buf_len);
buf[buf_len - 1] = 0;
return;
}
}
switch (compat) {
case E2P_FEATURE_COMPAT:
fchar = 'C';
break;
case E2P_FEATURE_INCOMPAT:
fchar = 'I';
break;
case E2P_FEATURE_RO_INCOMPAT:
fchar = 'R';
break;
default:
fchar = '?';
break;
}
for (fnum = 0; mask >>= 1; fnum++);
sprintf(buf, "FEATURE_%c%d", fchar, fnum);
}
const char *e2p_feature2string(int compat, unsigned int mask)
{
static char buf[20];
e2p_feature_to_string(compat, mask, buf, sizeof(buf) / sizeof(buf[0]));
return buf;
}
int e2p_string2feature(char *string, int *compat_type, unsigned int *mask)
{
struct feature *f;
char *eptr;
int num;
for (f = feature_list; f->string; f++) {
if (!strcasecmp(string, f->string)) {
*compat_type = f->compat;
*mask = f->mask;
return 0;
}
}
if (strncasecmp(string, "FEATURE_", 8))
return 1;
switch (string[8]) {
case 'c':
case 'C':
*compat_type = E2P_FEATURE_COMPAT;
break;
case 'i':
case 'I':
*compat_type = E2P_FEATURE_INCOMPAT;
break;
case 'r':
case 'R':
*compat_type = E2P_FEATURE_RO_INCOMPAT;
break;
default:
return 1;
}
if (string[9] == 0)
return 1;
num = strtol(string+9, &eptr, 10);
if (num > 31 || num < 0)
return 1;
if (*eptr)
return 1;
*mask = 1 << num;
return 0;
}
const char *e2p_jrnl_feature2string(int compat, unsigned int mask)
{
struct feature *f;
static char buf[20];
char fchar;
int fnum;
for (f = jrnl_feature_list; f->string; f++) {
if ((compat == f->compat) &&
(mask == f->mask))
return f->string;
}
switch (compat) {
case E2P_FEATURE_COMPAT:
fchar = 'C';
break;
case E2P_FEATURE_INCOMPAT:
fchar = 'I';
break;
case E2P_FEATURE_RO_INCOMPAT:
fchar = 'R';
break;
default:
fchar = '?';
break;
}
for (fnum = 0; mask >>= 1; fnum++);
sprintf(buf, "FEATURE_%c%d", fchar, fnum);
return buf;
}
int e2p_jrnl_string2feature(char *string, int *compat_type, unsigned int *mask)
{
struct feature *f;
char *eptr;
int num;
for (f = jrnl_feature_list; f->string; f++) {
if (!strcasecmp(string, f->string)) {
*compat_type = f->compat;
*mask = f->mask;
return 0;
}
}
if (strncasecmp(string, "FEATURE_", 8))
return 1;
switch (string[8]) {
case 'c':
case 'C':
*compat_type = E2P_FEATURE_COMPAT;
break;
case 'i':
case 'I':
*compat_type = E2P_FEATURE_INCOMPAT;
break;
case 'r':
case 'R':
*compat_type = E2P_FEATURE_RO_INCOMPAT;
break;
default:
return 1;
}
if (string[9] == 0)
return 1;
num = strtol(string+9, &eptr, 10);
if (num > 31 || num < 0)
return 1;
if (*eptr)
return 1;
*mask = 1 << num;
return 0;
}
static char *skip_over_blanks(char *cp)
{
while (*cp && isspace(*cp))
cp++;
return cp;
}
static char *skip_over_word(char *cp)
{
while (*cp && !isspace(*cp) && *cp != ',')
cp++;
return cp;
}
/*
* Edit a feature set array as requested by the user. The ok_array,
* if set, allows the application to limit what features the user is
* allowed to set or clear using this function. If clear_ok_array is set,
* then use it tell whether or not it is OK to clear a filesystem feature.
*/
int e2p_edit_feature2(const char *str, __u32 *compat_array, __u32 *ok_array,
__u32 *clear_ok_array, int *type_err,
unsigned int *mask_err)
{
char *cp, *buf, *next;
int neg;
unsigned int mask;
int compat_type;
int rc = 0;
if (!clear_ok_array)
clear_ok_array = ok_array;
if (type_err)
*type_err = 0;
if (mask_err)
*mask_err = 0;
buf = malloc(strlen(str)+1);
if (!buf)
return 1;
strcpy(buf, str);
for (cp = buf; cp && *cp; cp = next ? next+1 : 0) {
neg = 0;
cp = skip_over_blanks(cp);
next = skip_over_word(cp);
if (*next == 0)
next = 0;
else
*next = 0;
if ((strcasecmp(cp, "none") == 0) ||
(strcasecmp(cp, "clear") == 0)) {
compat_array[0] = 0;
compat_array[1] = 0;
compat_array[2] = 0;
continue;
}
switch (*cp) {
case '-':
case '^':
neg++;
/* fallthrough */
case '+':
cp++;
break;
}
if (e2p_string2feature(cp, &compat_type, &mask)) {
rc = 1;
break;
}
if (neg) {
if (clear_ok_array &&
!(clear_ok_array[compat_type] & mask)) {
rc = 1;
if (type_err)
*type_err = (compat_type |
E2P_FEATURE_NEGATE_FLAG);
if (mask_err)
*mask_err = mask;
break;
}
compat_array[compat_type] &= ~mask;
} else {
if (ok_array && !(ok_array[compat_type] & mask)) {
rc = 1;
if (type_err)
*type_err = compat_type;
if (mask_err)
*mask_err = mask;
break;
}
compat_array[compat_type] |= mask;
}
}
free(buf);
return rc;
}
int e2p_edit_feature(const char *str, __u32 *compat_array, __u32 *ok_array)
{
return e2p_edit_feature2(str, compat_array, ok_array, 0, 0, 0);
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
int compat, compat2, i;
unsigned int mask, mask2;
const char *str;
struct feature *f;
for (i = 0; i < 2; i++) {
if (i == 0) {
f = feature_list;
printf("Feature list:\n");
} else {
printf("\nJournal feature list:\n");
f = jrnl_feature_list;
}
for (; f->string; f++) {
if (i == 0) {
e2p_string2feature((char *)f->string, &compat,
&mask);
str = e2p_feature2string(compat, mask);
} else {
e2p_jrnl_string2feature((char *)f->string,
&compat, &mask);
str = e2p_jrnl_feature2string(compat, mask);
}
printf("\tCompat = %d, Mask = %u, %s\n",
compat, mask, f->string);
if (strcmp(f->string, str)) {
if (e2p_string2feature((char *) str, &compat2,
&mask2) ||
(compat2 != compat) ||
(mask2 != mask)) {
fprintf(stderr, "Failure!\n");
exit(1);
}
}
}
}
exit(0);
}
#endif

Binary file not shown.

View File

@@ -1,117 +0,0 @@
/*
* fgetflags.c - Get a file flags on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_EXT2_IOCTLS
#include <fcntl.h>
#include <sys/ioctl.h>
#endif
#include "e2p.h"
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#ifndef O_NOFOLLOW
#define O_NOFOLLOW 0
#endif
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW)
int fgetflags (const char * name, unsigned long * flags)
{
#if HAVE_STAT_FLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS)
struct stat buf;
if (stat (name, &buf) == -1)
return -1;
*flags = 0;
#ifdef UF_IMMUTABLE
if (buf.st_flags & UF_IMMUTABLE)
*flags |= EXT2_IMMUTABLE_FL;
#endif
#ifdef UF_APPEND
if (buf.st_flags & UF_APPEND)
*flags |= EXT2_APPEND_FL;
#endif
#ifdef UF_NODUMP
if (buf.st_flags & UF_NODUMP)
*flags |= EXT2_NODUMP_FL;
#endif
return 0;
#elif APPLE_DARWIN && HAVE_EXT2_IOCTLS
int f, save_errno = 0;
f = -1;
save_errno = syscall(SYS_fsctl, name, EXT2_IOC_GETFLAGS, &f, 0);
*flags = f;
return (save_errno);
#elif HAVE_EXT2_IOCTLS
struct stat buf;
int fd, r, f, save_errno = 0;
if (!stat(name, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
errno = EOPNOTSUPP;
return -1;
}
fd = open(name, OPEN_FLAGS);
if (fd == -1) {
if (errno == ELOOP || errno == ENXIO)
errno = EOPNOTSUPP;
return -1;
}
if (!fstat(fd, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
close(fd);
errno = EOPNOTSUPP;
return -1;
}
r = ioctl(fd, EXT2_IOC_GETFLAGS, &f);
if (r == -1) {
if (errno == ENOTTY)
errno = EOPNOTSUPP;
save_errno = errno;
}
*flags = f;
close(fd);
if (save_errno)
errno = save_errno;
return r;
#else
errno = EOPNOTSUPP;
return -1;
#endif
}

Binary file not shown.

View File

@@ -1,63 +0,0 @@
/*
* fgetproject.c --- get project id
*
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_EXT2_IOCTLS
#include <fcntl.h>
#include <sys/ioctl.h>
#include "project.h"
#endif
#include "e2p.h"
#ifdef O_LARGEFILE
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
#else
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
#endif
int fgetproject(const char *name, unsigned long *project)
{
#ifndef FS_IOC_FSGETXATTR
errno = EOPNOTSUPP;
return -1;
#else
int fd, r, save_errno = 0;
struct fsxattr fsx;
fd = open (name, OPEN_FLAGS);
if (fd == -1)
return -1;
r = ioctl (fd, FS_IOC_FSGETXATTR, &fsx);
if (r == 0)
*project = fsx.fsx_projid;
save_errno = errno;
close (fd);
if (save_errno)
errno = save_errno;
return r;
#endif
}

Binary file not shown.

View File

@@ -1,74 +0,0 @@
/*
* fgetversion.c - Get a file version on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include "e2p.h"
#ifdef O_LARGEFILE
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
#else
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
#endif
int fgetversion(const char *name, unsigned long *version)
{
unsigned int ver = -1;
int rc = -1;
#if HAVE_EXT2_IOCTLS
# if !APPLE_DARWIN
int fd, save_errno = 0;
fd = open(name, OPEN_FLAGS);
if (fd == -1)
return -1;
rc = ioctl(fd, EXT2_IOC_GETVERSION, &ver);
if (rc == -1)
save_errno = errno;
close(fd);
if (rc == -1)
errno = save_errno;
# else /* APPLE_DARWIN */
rc = syscall(SYS_fsctl, name, EXT2_IOC_GETVERSION, &ver, 0);
# endif /* !APPLE_DARWIN */
#else /* ! HAVE_EXT2_IOCTLS */
errno = EOPNOTSUPP;
#endif /* ! HAVE_EXT2_IOCTLS */
if (rc == 0)
*version = ver;
return rc;
}

Binary file not shown.

View File

@@ -1,118 +0,0 @@
/*
* fsetflags.c - Set a file flags on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_EXT2_IOCTLS
#include <fcntl.h>
#include <sys/ioctl.h>
#endif
#include "e2p.h"
/*
* Deal with lame glibc's that define this function without actually
* implementing it. Can you say "attractive nuisance", boys and girls?
* I knew you could!
*/
#ifdef __linux__
#undef HAVE_CHFLAGS
#endif
#ifndef O_LARGEFILE
#define O_LARGEFILE 0
#endif
#ifndef O_NOFOLLOW
#define O_NOFOLLOW 0
#endif
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_NOFOLLOW)
int fsetflags (const char * name, unsigned long flags)
{
#if HAVE_CHFLAGS && !(APPLE_DARWIN && HAVE_EXT2_IOCTLS)
unsigned long bsd_flags = 0;
#ifdef UF_IMMUTABLE
if (flags & EXT2_IMMUTABLE_FL)
bsd_flags |= UF_IMMUTABLE;
#endif
#ifdef UF_APPEND
if (flags & EXT2_APPEND_FL)
bsd_flags |= UF_APPEND;
#endif
#ifdef UF_NODUMP
if (flags & EXT2_NODUMP_FL)
bsd_flags |= UF_NODUMP;
#endif
return chflags (name, bsd_flags);
#elif APPLE_DARWIN && HAVE_EXT2_IOCTLS
int f = (int) flags;
return syscall(SYS_fsctl, name, EXT2_IOC_SETFLAGS, &f, 0);
#elif HAVE_EXT2_IOCTLS
struct stat buf;
int fd, r, f, save_errno = 0;
if (!stat(name, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
errno = EOPNOTSUPP;
return -1;
}
fd = open(name, OPEN_FLAGS);
if (fd == -1) {
if (errno == ELOOP || errno == ENXIO)
errno = EOPNOTSUPP;
return -1;
}
if (!fstat(fd, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
close(fd);
errno = EOPNOTSUPP;
return -1;
}
f = (int) flags;
r = ioctl(fd, EXT2_IOC_SETFLAGS, &f);
if (r == -1) {
if (errno == ENOTTY)
errno = EOPNOTSUPP;
save_errno = errno;
}
close(fd);
if (save_errno)
errno = save_errno;
return r;
#else
errno = EOPNOTSUPP;
return -1;
#endif
}

Binary file not shown.

View File

@@ -1,69 +0,0 @@
/*
* fgetproject.c --- get project id
*
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_EXT2_IOCTLS
#include <fcntl.h>
#include <sys/ioctl.h>
#include "project.h"
#endif
#include "e2p.h"
#ifdef O_LARGEFILE
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
#else
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
#endif
int fsetproject(const char *name, unsigned long project)
{
#ifndef FS_IOC_FSGETXATTR
errno = EOPNOTSUPP;
return -1;
#else
int fd, r, save_errno = 0;
struct fsxattr fsx;
fd = open (name, OPEN_FLAGS);
if (fd == -1)
return -1;
r = ioctl (fd, FS_IOC_FSGETXATTR, &fsx);
if (r == -1) {
save_errno = errno;
goto errout;
}
fsx.fsx_projid = project;
r = ioctl (fd, FS_IOC_FSSETXATTR, &fsx);
if (r == -1)
save_errno = errno;
errout:
close (fd);
if (save_errno)
errno = save_errno;
return r;
#endif
}

Binary file not shown.

View File

@@ -1,71 +0,0 @@
/*
* fsetversion.c - Set a file version on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include "e2p.h"
#ifdef O_LARGEFILE
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK|O_LARGEFILE)
#else
#define OPEN_FLAGS (O_RDONLY|O_NONBLOCK)
#endif
int fsetversion (const char * name, unsigned long version)
{
#if HAVE_EXT2_IOCTLS
#if !APPLE_DARWIN
int fd, r, ver, save_errno = 0;
fd = open (name, OPEN_FLAGS);
if (fd == -1)
return -1;
ver = (int) version;
r = ioctl (fd, EXT2_IOC_SETVERSION, &ver);
if (r == -1)
save_errno = errno;
close (fd);
if (save_errno)
errno = save_errno;
return r;
#else
int ver = (int)version;
return syscall(SYS_fsctl, name, EXT2_IOC_SETVERSION, &ver, 0);
#endif
#else /* ! HAVE_EXT2_IOCTLS */
errno = EOPNOTSUPP;
return -1;
#endif /* ! HAVE_EXT2_IOCTLS */
}

Binary file not shown.

View File

@@ -1,71 +0,0 @@
/*
* getflags.c - Get a file flags on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_EXT2_IOCTLS
#include <sys/ioctl.h>
#endif
#include "e2p.h"
int getflags (int fd, unsigned long * flags)
{
#if HAVE_STAT_FLAGS
struct stat buf;
if (fstat (fd, &buf) == -1)
return -1;
*flags = 0;
#ifdef UF_IMMUTABLE
if (buf.st_flags & UF_IMMUTABLE)
*flags |= EXT2_IMMUTABLE_FL;
#endif
#ifdef UF_APPEND
if (buf.st_flags & UF_APPEND)
*flags |= EXT2_APPEND_FL;
#endif
#ifdef UF_NODUMP
if (buf.st_flags & UF_NODUMP)
*flags |= EXT2_NODUMP_FL;
#endif
return 0;
#else
#if HAVE_EXT2_IOCTLS
struct stat buf;
int r, f;
if (!fstat(fd, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode))
goto notsupp;
r = ioctl(fd, EXT2_IOC_GETFLAGS, &f);
*flags = f;
return r;
notsupp:
#endif /* HAVE_EXT2_IOCTLS */
#endif
errno = EOPNOTSUPP;
return -1;
}

Binary file not shown.

View File

@@ -1,41 +0,0 @@
/*
* getversion.c - Get a file version on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include "e2p.h"
int getversion (int fd, unsigned long * version)
{
#if HAVE_EXT2_IOCTLS
int r, ver;
r = ioctl (fd, EXT2_IOC_GETVERSION, &ver);
*version = ver;
return r;
#else /* ! HAVE_EXT2_IOCTLS */
errno = EOPNOTSUPP;
return -1;
#endif /* ! HAVE_EXT2_IOCTLS */
}

Binary file not shown.

View File

@@ -1,72 +0,0 @@
/*
* feature.c --- convert between features and strings
*
* Copyright (C) 1999 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "e2p.h"
struct hash {
int num;
const char *string;
};
static struct hash hash_list[] = {
{ EXT2_HASH_LEGACY, "legacy" },
{ EXT2_HASH_HALF_MD4, "half_md4" },
{ EXT2_HASH_TEA, "tea" },
{ 0, 0 },
};
const char *e2p_hash2string(int num)
{
struct hash *p;
static char buf[20];
for (p = hash_list; p->string; p++) {
if (num == p->num)
return p->string;
}
sprintf(buf, "HASHALG_%d", num);
return buf;
}
/*
* Returns the hash algorithm, or -1 on error
*/
int e2p_string2hash(char *string)
{
struct hash *p;
char *eptr;
int num;
for (p = hash_list; p->string; p++) {
if (!strcasecmp(string, p->string)) {
return p->num;
}
}
if (strncasecmp(string, "HASHALG_", 8))
return -1;
if (string[8] == 0)
return -1;
num = strtol(string+8, &eptr, 10);
if (num > 255 || num < 0)
return -1;
if (*eptr)
return -1;
return num;
}

Binary file not shown.

View File

@@ -1,76 +0,0 @@
/*
* iod.c - Iterate a function on each entry of a directory
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#include "config.h"
#include "e2p.h"
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <stdlib.h>
#include <string.h>
int iterate_on_dir (const char * dir_name,
int (*func) (const char *, struct dirent *, void *),
void * private)
{
DIR * dir;
struct dirent *de, *dep;
int max_len = -1, len, ret = 0;
#if HAVE_PATHCONF && defined(_PC_NAME_MAX)
max_len = pathconf(dir_name, _PC_NAME_MAX);
#endif
if (max_len == -1) {
#ifdef _POSIX_NAME_MAX
max_len = _POSIX_NAME_MAX;
#else
#ifdef NAME_MAX
max_len = NAME_MAX;
#else
max_len = 256;
#endif /* NAME_MAX */
#endif /* _POSIX_NAME_MAX */
}
max_len += sizeof(struct dirent);
de = malloc(max_len+1);
if (!de)
return -1;
memset(de, 0, max_len+1);
dir = opendir (dir_name);
if (dir == NULL) {
free(de);
return -1;
}
while ((dep = readdir (dir))) {
#ifdef HAVE_RECLEN_DIRENT
len = dep->d_reclen;
if (len > max_len)
len = max_len;
#else
len = sizeof(struct dirent);
#endif
memcpy(de, dep, len);
if ((*func)(dir_name, de, private))
ret++;
}
free(de);
closedir(dir);
return ret;
}

Binary file not shown.

View File

@@ -1,134 +0,0 @@
/*
* ljs.c - List the contents of an journal superblock
*
* Copyright (C) 1995, 1996, 1997 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
#include "ext2fs/ext2_fs.h"
#include "ext2fs/ext2fs.h"
#include "e2p.h"
#include "ext2fs/kernel-jbd.h"
#ifdef WORDS_BIGENDIAN
#define e2p_be32(x) (x)
#else
static __u32 e2p_swab32(__u32 val)
{
return ((val>>24) | ((val>>8)&0xFF00) |
((val<<8)&0xFF0000) | (val<<24));
}
#define e2p_be32(x) e2p_swab32(x)
#endif
/*
* This function is copied from kernel-jbd.h's function
* jbd2_journal_get_num_fc_blks() to avoid inter-library dependencies.
*/
static inline int get_num_fc_blks(journal_superblock_t *jsb)
{
int num_fc_blocks = e2p_be32(jsb->s_num_fc_blks);
return num_fc_blocks ? num_fc_blocks : JBD2_DEFAULT_FAST_COMMIT_BLOCKS;
}
static const char *journal_checksum_type_str(__u8 type)
{
switch (type) {
case JBD2_CRC32C_CHKSUM:
return "crc32c";
default:
return "unknown";
}
}
void e2p_list_journal_super(FILE *f, char *journal_sb_buf,
int exp_block_size, int flags)
{
journal_superblock_t *jsb = (journal_superblock_t *) journal_sb_buf;
__u32 *mask_ptr, mask, m;
unsigned int size;
int j, printed = 0;
unsigned int i, nr_users;
int num_fc_blks = 0;
int journal_blks = 0;
if (flags & E2P_LIST_JOURNAL_FLAG_FC)
num_fc_blks = get_num_fc_blks((journal_superblock_t *)journal_sb_buf);
journal_blks = ntohl(jsb->s_maxlen) - num_fc_blks;
fprintf(f, "%s", "Journal features: ");
for (i=0, mask_ptr=&jsb->s_feature_compat; i <3; i++,mask_ptr++) {
mask = e2p_be32(*mask_ptr);
for (j=0,m=1; j < 32; j++, m<<=1) {
if (mask & m) {
fprintf(f, " %s", e2p_jrnl_feature2string(i, m));
printed++;
}
}
}
if (printed == 0)
fprintf(f, " (none)");
fputc('\n', f);
fputs("Total journal size: ", f);
size = (ntohl(jsb->s_blocksize) / 1024) * ntohl(jsb->s_maxlen);
if (size < 8192)
fprintf(f, "%uk\n", size);
else
fprintf(f, "%uM\n", size >> 10);
nr_users = (unsigned int) ntohl(jsb->s_nr_users);
if (exp_block_size != (int) ntohl(jsb->s_blocksize))
fprintf(f, "Journal block size: %u\n",
(unsigned int)ntohl(jsb->s_blocksize));
fprintf(f, "Total journal blocks: %u\n",
(unsigned int)(journal_blks + num_fc_blks));
fprintf(f, "Max transaction length: %u\n",
(unsigned int)journal_blks);
fprintf(f, "Fast commit length: %u\n",
(unsigned int)num_fc_blks);
if (ntohl(jsb->s_first) != 1)
fprintf(f, "Journal first block: %u\n",
(unsigned int)ntohl(jsb->s_first));
fprintf(f, "Journal sequence: 0x%08x\n"
"Journal start: %u\n",
(unsigned int)ntohl(jsb->s_sequence),
(unsigned int)ntohl(jsb->s_start));
if (nr_users != 1)
fprintf(f, "Journal number of users: %u\n", nr_users);
if (jsb->s_feature_compat & e2p_be32(JBD2_FEATURE_COMPAT_CHECKSUM))
fprintf(f, "%s", "Journal checksum type: crc32\n");
if ((jsb->s_feature_incompat &
e2p_be32(JBD2_FEATURE_INCOMPAT_CSUM_V3)) ||
(jsb->s_feature_incompat &
e2p_be32(JBD2_FEATURE_INCOMPAT_CSUM_V2)))
fprintf(f, "Journal checksum type: %s\n"
"Journal checksum: 0x%08x\n",
journal_checksum_type_str(jsb->s_checksum_type),
e2p_be32(jsb->s_checksum));
if ((nr_users > 1) ||
!e2p_is_null_uuid(&jsb->s_users[0])) {
for (i=0; i < nr_users && i < JBD2_USERS_MAX; i++) {
printf(i ? " %s\n"
: "Journal users: %s\n",
e2p_uuid2str(&jsb->s_users[i * UUID_SIZE]));
}
}
if (jsb->s_errno != 0)
fprintf(f, "Journal errno: %d\n",
(int) ntohl(jsb->s_errno));
}

Binary file not shown.

View File

@@ -1,491 +0,0 @@
/*
* ls.c - List the contents of an ext2fs superblock
*
* Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* Copyright (C) 1995, 1996, 1997 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <string.h>
#include <grp.h>
#include <pwd.h>
#include <time.h>
#include "e2p.h"
#include "support/quotaio.h"
static void print_user (unsigned short uid, FILE *f)
{
struct passwd *pw;
fprintf(f, "%u ", uid);
pw = getpwuid (uid);
if (pw == NULL)
fprintf(f, "(user unknown)\n");
else
fprintf(f, "(user %s)\n", pw->pw_name);
}
static void print_group (unsigned short gid, FILE *f)
{
struct group *gr;
fprintf(f, "%u ", gid);
gr = getgrgid (gid);
if (gr == NULL)
fprintf(f, "(group unknown)\n");
else
fprintf(f, "(group %s)\n", gr->gr_name);
}
#define MONTH_INT (86400 * 30)
#define WEEK_INT (86400 * 7)
#define DAY_INT (86400)
#define HOUR_INT (60 * 60)
#define MINUTE_INT (60)
static const char *interval_string(unsigned int secs)
{
static char buf[256], tmp[80];
int hr, min, num;
buf[0] = 0;
if (secs == 0)
return "<none>";
if (secs >= MONTH_INT) {
num = secs / MONTH_INT;
secs -= num*MONTH_INT;
sprintf(buf, "%d month%s", num, (num>1) ? "s" : "");
}
if (secs >= WEEK_INT) {
num = secs / WEEK_INT;
secs -= num*WEEK_INT;
sprintf(tmp, "%s%d week%s", buf[0] ? ", " : "",
num, (num>1) ? "s" : "");
strcat(buf, tmp);
}
if (secs >= DAY_INT) {
num = secs / DAY_INT;
secs -= num*DAY_INT;
sprintf(tmp, "%s%d day%s", buf[0] ? ", " : "",
num, (num>1) ? "s" : "");
strcat(buf, tmp);
}
if (secs > 0) {
hr = secs / HOUR_INT;
secs -= hr*HOUR_INT;
min = secs / MINUTE_INT;
secs -= min*MINUTE_INT;
sprintf(tmp, "%s%d:%02d:%02d", buf[0] ? ", " : "",
hr, min, secs);
strcat(buf, tmp);
}
return buf;
}
static void print_features(struct ext2_super_block * s, FILE *f)
{
#ifdef EXT2_DYNAMIC_REV
int i, j, printed=0;
__u32 *mask = &s->s_feature_compat, m;
fprintf(f, "Filesystem features: ");
for (i=0; i <3; i++,mask++) {
for (j=0,m=1; j < 32; j++, m<<=1) {
if (*mask & m) {
fprintf(f, " %s", e2p_feature2string(i, m));
printed++;
}
}
}
if (printed == 0)
fprintf(f, " (none)");
fprintf(f, "\n");
#endif
}
static void print_mntopts(struct ext2_super_block * s, FILE *f)
{
#ifdef EXT2_DYNAMIC_REV
int i, printed=0;
__u32 mask = s->s_default_mount_opts, m;
fprintf(f, "Default mount options: ");
if (mask & EXT3_DEFM_JMODE) {
fprintf(f, " %s", e2p_mntopt2string(mask & EXT3_DEFM_JMODE));
printed++;
}
for (i=0,m=1; i < 32; i++, m<<=1) {
if (m & EXT3_DEFM_JMODE)
continue;
if (mask & m) {
fprintf(f, " %s", e2p_mntopt2string(m));
printed++;
}
}
if (printed == 0)
fprintf(f, " (none)");
fprintf(f, "\n");
#endif
}
static void print_super_flags(struct ext2_super_block * s, FILE *f)
{
int flags_found = 0;
if (s->s_flags == 0)
return;
fputs("Filesystem flags: ", f);
if (s->s_flags & EXT2_FLAGS_SIGNED_HASH) {
fputs("signed_directory_hash ", f);
flags_found++;
}
if (s->s_flags & EXT2_FLAGS_UNSIGNED_HASH) {
fputs("unsigned_directory_hash ", f);
flags_found++;
}
if (s->s_flags & EXT2_FLAGS_TEST_FILESYS) {
fputs("test_filesystem ", f);
flags_found++;
}
if (flags_found)
fputs("\n", f);
else
fputs("(none)\n", f);
}
static __u64 e2p_blocks_count(struct ext2_super_block *super)
{
return super->s_blocks_count |
(ext2fs_has_feature_64bit(super) ?
(__u64) super->s_blocks_count_hi << 32 : 0);
}
static __u64 e2p_r_blocks_count(struct ext2_super_block *super)
{
return super->s_r_blocks_count |
(ext2fs_has_feature_64bit(super) ?
(__u64) super->s_r_blocks_count_hi << 32 : 0);
}
static __u64 e2p_free_blocks_count(struct ext2_super_block *super)
{
return super->s_free_blocks_count |
(ext2fs_has_feature_64bit(super) ?
(__u64) super->s_free_blocks_hi << 32 : 0);
}
#ifndef EXT2_INODE_SIZE
#define EXT2_INODE_SIZE(s) sizeof(struct ext2_inode)
#endif
#ifndef EXT2_GOOD_OLD_REV
#define EXT2_GOOD_OLD_REV 0
#endif
static const char *checksum_type(__u8 type)
{
switch (type) {
case EXT2_CRC32C_CHKSUM:
return "crc32c";
default:
return "unknown";
}
}
static const char *quota_prefix[MAXQUOTAS] = {
[USRQUOTA] = "User quota inode:",
[GRPQUOTA] = "Group quota inode:",
[PRJQUOTA] = "Project quota inode:",
};
/**
* Convert type of quota to written representation
*/
static const char *quota_type2prefix(enum quota_type qtype)
{
return quota_prefix[qtype];
}
void list_super2(struct ext2_super_block * sb, FILE *f)
{
int inode_blocks_per_group;
char *str;
time_t tm;
enum quota_type qtype;
inode_blocks_per_group = (((sb->s_inodes_per_group *
EXT2_INODE_SIZE(sb)) +
EXT2_BLOCK_SIZE(sb) - 1) /
EXT2_BLOCK_SIZE(sb));
if (sb->s_volume_name[0])
fprintf(f, "Filesystem volume name: %.*s\n",
EXT2_LEN_STR(sb->s_volume_name));
else
fprintf(f, "Filesystem volume name: <none>\n");
if (sb->s_last_mounted[0])
fprintf(f, "Last mounted on: %.*s\n",
EXT2_LEN_STR(sb->s_last_mounted));
else
fprintf(f, "Last mounted on: <not available>\n");
fprintf(f, "Filesystem UUID: %s\n", e2p_uuid2str(sb->s_uuid));
fprintf(f, "Filesystem magic number: 0x%04X\n", sb->s_magic);
fprintf(f, "Filesystem revision #: %d", sb->s_rev_level);
if (sb->s_rev_level == EXT2_GOOD_OLD_REV) {
fprintf(f, " (original)\n");
#ifdef EXT2_DYNAMIC_REV
} else if (sb->s_rev_level == EXT2_DYNAMIC_REV) {
fprintf(f, " (dynamic)\n");
#endif
} else
fprintf(f, " (unknown)\n");
print_features(sb, f);
print_super_flags(sb, f);
print_mntopts(sb, f);
if (sb->s_mount_opts[0])
fprintf(f, "Mount options: %.*s\n",
EXT2_LEN_STR(sb->s_mount_opts));
fprintf(f, "Filesystem state: ");
print_fs_state (f, sb->s_state);
fprintf(f, "\n");
fprintf(f, "Errors behavior: ");
print_fs_errors(f, sb->s_errors);
fprintf(f, "\n");
str = e2p_os2string(sb->s_creator_os);
fprintf(f, "Filesystem OS type: %s\n", str);
free(str);
fprintf(f, "Inode count: %u\n", sb->s_inodes_count);
fprintf(f, "Block count: %llu\n",
(unsigned long long) e2p_blocks_count(sb));
fprintf(f, "Reserved block count: %llu\n",
(unsigned long long) e2p_r_blocks_count(sb));
if (sb->s_overhead_clusters)
fprintf(f, "Overhead clusters: %u\n",
sb->s_overhead_clusters);
fprintf(f, "Free blocks: %llu\n",
(unsigned long long) e2p_free_blocks_count(sb));
fprintf(f, "Free inodes: %u\n", sb->s_free_inodes_count);
fprintf(f, "First block: %u\n", sb->s_first_data_block);
fprintf(f, "Block size: %u\n", EXT2_BLOCK_SIZE(sb));
if (ext2fs_has_feature_bigalloc(sb))
fprintf(f, "Cluster size: %u\n",
EXT2_CLUSTER_SIZE(sb));
else
fprintf(f, "Fragment size: %u\n",
EXT2_CLUSTER_SIZE(sb));
if (ext2fs_has_feature_64bit(sb))
fprintf(f, "Group descriptor size: %u\n", sb->s_desc_size);
if (sb->s_reserved_gdt_blocks)
fprintf(f, "Reserved GDT blocks: %u\n",
sb->s_reserved_gdt_blocks);
fprintf(f, "Blocks per group: %u\n", sb->s_blocks_per_group);
if (ext2fs_has_feature_bigalloc(sb))
fprintf(f, "Clusters per group: %u\n",
sb->s_clusters_per_group);
else
fprintf(f, "Fragments per group: %u\n",
sb->s_clusters_per_group);
fprintf(f, "Inodes per group: %u\n", sb->s_inodes_per_group);
fprintf(f, "Inode blocks per group: %u\n", inode_blocks_per_group);
if (sb->s_raid_stride)
fprintf(f, "RAID stride: %u\n",
sb->s_raid_stride);
if (sb->s_raid_stripe_width)
fprintf(f, "RAID stripe width: %u\n",
sb->s_raid_stripe_width);
if (sb->s_first_meta_bg)
fprintf(f, "First meta block group: %u\n",
sb->s_first_meta_bg);
if (sb->s_log_groups_per_flex)
fprintf(f, "Flex block group size: %u\n",
1U << sb->s_log_groups_per_flex);
if (sb->s_mkfs_time) {
tm = sb->s_mkfs_time;
fprintf(f, "Filesystem created: %s", ctime(&tm));
}
tm = sb->s_mtime;
fprintf(f, "Last mount time: %s",
sb->s_mtime ? ctime(&tm) : "n/a\n");
tm = sb->s_wtime;
fprintf(f, "Last write time: %s", ctime(&tm));
fprintf(f, "Mount count: %u\n", sb->s_mnt_count);
fprintf(f, "Maximum mount count: %d\n", sb->s_max_mnt_count);
tm = sb->s_lastcheck;
fprintf(f, "Last checked: %s", ctime(&tm));
fprintf(f, "Check interval: %u (%s)\n", sb->s_checkinterval,
interval_string(sb->s_checkinterval));
if (sb->s_checkinterval)
{
time_t next;
next = sb->s_lastcheck + sb->s_checkinterval;
fprintf(f, "Next check after: %s", ctime(&next));
}
#define POW2(x) ((__u64) 1 << (x))
if (sb->s_kbytes_written) {
fprintf(f, "Lifetime writes: ");
if (sb->s_kbytes_written < POW2(13))
fprintf(f, "%llu kB\n",
(unsigned long long) sb->s_kbytes_written);
else if (sb->s_kbytes_written < POW2(23))
fprintf(f, "%llu MB\n", (unsigned long long)
(sb->s_kbytes_written + POW2(9)) >> 10);
else if (sb->s_kbytes_written < POW2(33))
fprintf(f, "%llu GB\n", (unsigned long long)
(sb->s_kbytes_written + POW2(19)) >> 20);
else if (sb->s_kbytes_written < POW2(43))
fprintf(f, "%llu TB\n", (unsigned long long)
(sb->s_kbytes_written + POW2(29)) >> 30);
else
fprintf(f, "%llu PB\n", (unsigned long long)
(sb->s_kbytes_written + POW2(39)) >> 40);
}
fprintf(f, "Reserved blocks uid: ");
print_user(sb->s_def_resuid, f);
fprintf(f, "Reserved blocks gid: ");
print_group(sb->s_def_resgid, f);
if (sb->s_rev_level >= EXT2_DYNAMIC_REV) {
fprintf(f, "First inode: %d\n", sb->s_first_ino);
fprintf(f, "Inode size: %d\n", sb->s_inode_size);
if (sb->s_min_extra_isize)
fprintf(f, "Required extra isize: %d\n",
sb->s_min_extra_isize);
if (sb->s_want_extra_isize)
fprintf(f, "Desired extra isize: %d\n",
sb->s_want_extra_isize);
}
if (!e2p_is_null_uuid(sb->s_journal_uuid))
fprintf(f, "Journal UUID: %s\n",
e2p_uuid2str(sb->s_journal_uuid));
if (sb->s_journal_inum)
fprintf(f, "Journal inode: %u\n",
sb->s_journal_inum);
if (sb->s_journal_dev)
fprintf(f, "Journal device: 0x%04x\n",
sb->s_journal_dev);
if (sb->s_last_orphan)
fprintf(f, "First orphan inode: %u\n",
sb->s_last_orphan);
if (ext2fs_has_feature_dir_index(sb) ||
sb->s_def_hash_version)
fprintf(f, "Default directory hash: %s\n",
e2p_hash2string(sb->s_def_hash_version));
if (!e2p_is_null_uuid(sb->s_hash_seed))
fprintf(f, "Directory Hash Seed: %s\n",
e2p_uuid2str(sb->s_hash_seed));
if (sb->s_jnl_backup_type) {
fprintf(f, "Journal backup: ");
switch (sb->s_jnl_backup_type) {
case 1:
fprintf(f, "inode blocks\n");
break;
default:
fprintf(f, "type %u\n", sb->s_jnl_backup_type);
}
}
if (sb->s_backup_bgs[0] || sb->s_backup_bgs[1]) {
fprintf(f, "Backup block groups: ");
if (sb->s_backup_bgs[0])
fprintf(f, "%u ", sb->s_backup_bgs[0]);
if (sb->s_backup_bgs[1])
fprintf(f, "%u ", sb->s_backup_bgs[1]);
fputc('\n', f);
}
if (sb->s_snapshot_inum) {
fprintf(f, "Snapshot inode: %u\n",
sb->s_snapshot_inum);
fprintf(f, "Snapshot ID: %u\n",
sb->s_snapshot_id);
fprintf(f, "Snapshot reserved blocks: %llu\n",
(unsigned long long) sb->s_snapshot_r_blocks_count);
}
if (sb->s_snapshot_list)
fprintf(f, "Snapshot list head: %u\n",
sb->s_snapshot_list);
if (sb->s_error_count)
fprintf(f, "FS Error count: %u\n",
sb->s_error_count);
if (sb->s_first_error_time) {
tm = sb->s_first_error_time;
fprintf(f, "First error time: %s", ctime(&tm));
fprintf(f, "First error function: %.*s\n",
EXT2_LEN_STR(sb->s_first_error_func));
fprintf(f, "First error line #: %u\n",
sb->s_first_error_line);
if (sb->s_first_error_ino)
fprintf(f, "First error inode #: %u\n",
sb->s_first_error_ino);
if (sb->s_first_error_block)
fprintf(f, "First error block #: %llu\n",
(unsigned long long) sb->s_first_error_block);
if (sb->s_first_error_errcode)
fprintf(f, "First error err: %s\n",
e2p_errcode2str(sb->s_first_error_errcode));
}
if (sb->s_last_error_time) {
tm = sb->s_last_error_time;
fprintf(f, "Last error time: %s", ctime(&tm));
fprintf(f, "Last error function: %.*s\n",
EXT2_LEN_STR(sb->s_last_error_func));
fprintf(f, "Last error line #: %u\n",
sb->s_last_error_line);
if (sb->s_last_error_ino)
fprintf(f, "Last error inode #: %u\n",
sb->s_last_error_ino);
if (sb->s_last_error_block)
fprintf(f, "Last error block #: %llu\n",
(unsigned long long) sb->s_last_error_block);
if (sb->s_last_error_errcode)
fprintf(f, "Last error err: %s\n",
e2p_errcode2str(sb->s_last_error_errcode));
}
if (ext2fs_has_feature_mmp(sb)) {
fprintf(f, "MMP block number: %llu\n",
(unsigned long long) sb->s_mmp_block);
fprintf(f, "MMP update interval: %u\n",
sb->s_mmp_update_interval);
}
for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
if (*quota_sb_inump(sb, qtype) != 0)
fprintf(f, "%-26s%u\n",
quota_type2prefix(qtype),
*quota_sb_inump(sb, qtype));
}
if (ext2fs_has_feature_metadata_csum(sb)) {
fprintf(f, "Checksum type: %s\n",
checksum_type(sb->s_checksum_type));
fprintf(f, "Checksum: 0x%08x\n",
sb->s_checksum);
}
if (!e2p_is_null_uuid(sb->s_encrypt_pw_salt))
fprintf(f, "Encryption PW Salt: %s\n",
e2p_uuid2str(sb->s_encrypt_pw_salt));
if (ext2fs_has_feature_csum_seed(sb))
fprintf(f, "Checksum seed: 0x%08x\n",
sb->s_checksum_seed);
if (ext2fs_has_feature_casefold(sb))
fprintf(f, "Character encoding: %s\n",
e2p_encoding2str(sb->s_encoding));
}
void list_super (struct ext2_super_block * s)
{
list_super2(s, stdout);
}

Binary file not shown.

View File

@@ -1,150 +0,0 @@
/*
* mountopts.c --- convert between default mount options and strings
*
* Copyright (C) 2002 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <ctype.h>
#include <errno.h>
#include "e2p.h"
struct mntopt {
unsigned int mask;
const char *string;
};
static struct mntopt mntopt_list[] = {
{ EXT2_DEFM_DEBUG, "debug" },
{ EXT2_DEFM_BSDGROUPS, "bsdgroups" },
{ EXT2_DEFM_XATTR_USER, "user_xattr" },
{ EXT2_DEFM_ACL, "acl" },
{ EXT2_DEFM_UID16, "uid16" },
{ EXT3_DEFM_JMODE_DATA, "journal_data" },
{ EXT3_DEFM_JMODE_ORDERED, "journal_data_ordered" },
{ EXT3_DEFM_JMODE_WBACK, "journal_data_writeback" },
{ EXT4_DEFM_NOBARRIER, "nobarrier" },
{ EXT4_DEFM_BLOCK_VALIDITY, "block_validity" },
{ EXT4_DEFM_DISCARD, "discard"},
{ EXT4_DEFM_NODELALLOC, "nodelalloc"},
{ 0, 0 },
};
const char *e2p_mntopt2string(unsigned int mask)
{
struct mntopt *f;
static char buf[20];
int fnum;
for (f = mntopt_list; f->string; f++) {
if (mask == f->mask)
return f->string;
}
for (fnum = 0; mask >>= 1; fnum++);
sprintf(buf, "MNTOPT_%d", fnum);
return buf;
}
int e2p_string2mntopt(char *string, unsigned int *mask)
{
struct mntopt *f;
char *eptr;
int num;
for (f = mntopt_list; f->string; f++) {
if (!strcasecmp(string, f->string)) {
*mask = f->mask;
return 0;
}
}
if (strncasecmp(string, "MNTOPT_", 7))
return 1;
if (string[8] == 0)
return 1;
num = strtol(string+8, &eptr, 10);
if (num > 31 || num < 0)
return 1;
if (*eptr)
return 1;
*mask = 1 << num;
return 0;
}
static char *skip_over_blanks(char *cp)
{
while (*cp && isspace(*cp))
cp++;
return cp;
}
static char *skip_over_word(char *cp)
{
while (*cp && !isspace(*cp) && *cp != ',')
cp++;
return cp;
}
/*
* Edit a mntopt set array as requested by the user. The ok
* parameter, if non-zero, allows the application to limit what
* mntopts the user is allowed to set or clear using this function.
*/
int e2p_edit_mntopts(const char *str, __u32 *mntopts, __u32 ok)
{
char *cp, *buf, *next;
int neg;
unsigned int mask;
int rc = 0;
buf = malloc(strlen(str)+1);
if (!buf)
return 1;
strcpy(buf, str);
cp = buf;
while (cp && *cp) {
neg = 0;
cp = skip_over_blanks(cp);
next = skip_over_word(cp);
if (*next == 0)
next = 0;
else
*next = 0;
switch (*cp) {
case '-':
case '^':
neg++;
/* fallthrough */
case '+':
cp++;
break;
}
if (e2p_string2mntopt(cp, &mask)) {
rc = 1;
break;
}
if (ok && !(ok & mask)) {
rc = 1;
break;
}
if (mask & EXT3_DEFM_JMODE)
*mntopts &= ~EXT3_DEFM_JMODE;
if (neg)
*mntopts &= ~mask;
else
*mntopts |= mask;
cp = next ? next+1 : 0;
}
free(buf);
return rc;
}

Binary file not shown.

View File

@@ -1,79 +0,0 @@
/*
* getostype.c - Get the Filesystem OS type
*
* Copyright (C) 2004,2005 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include "e2p.h"
#include <string.h>
#include <stdlib.h>
static const char *os_tab[] =
{ "Linux",
"Hurd",
"Masix",
"FreeBSD",
"Lites",
0 };
/*
* Convert an os_type to a string
*/
char *e2p_os2string(int os_type)
{
const char *os;
char *ret;
if (os_type >= 0 && os_type <= EXT2_OS_LITES)
os = os_tab[os_type];
else
os = "(unknown os)";
ret = malloc(strlen(os)+1);
if (ret)
strcpy(ret, os);
return ret;
}
/*
* Convert an os_type to a string
*/
int e2p_string2os(char *str)
{
const char **cpp;
int i = 0;
for (cpp = os_tab; *cpp; cpp++, i++) {
if (!strcasecmp(str, *cpp))
return i;
}
return -1;
}
#ifdef TEST_PROGRAM
int main(int argc, char **argv)
{
char *s;
int i, os;
for (i=0; i <= EXT2_OS_LITES; i++) {
s = e2p_os2string(i);
os = e2p_string2os(s);
printf("%d: %s (%d)\n", i, s, os);
free(s);
if (i != os) {
fprintf(stderr, "Failure!\n");
exit(1);
}
}
exit(0);
}
#endif

Binary file not shown.

View File

@@ -1,91 +0,0 @@
/*
* parse_num.c - Parse the number of blocks
*
* Copyright (C) 2004,2005 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include "e2p.h"
#include <stdlib.h>
unsigned long long parse_num_blocks2(const char *arg, int log_block_size)
{
char *p;
unsigned long long num;
num = strtoull(arg, &p, 0);
if (p[0] && p[1])
return 0;
switch (*p) { /* Using fall-through logic */
case 'T': case 't':
num <<= 10;
/* fallthrough */
case 'G': case 'g':
num <<= 10;
/* fallthrough */
case 'M': case 'm':
num <<= 10;
/* fallthrough */
case 'K': case 'k':
if (log_block_size < 0)
num <<= 10;
else
num >>= log_block_size;
break;
case 's':
if (log_block_size < 0)
num <<= 9;
else
num >>= (1+log_block_size);
break;
case '\0':
break;
default:
return 0;
}
return num;
}
unsigned long parse_num_blocks(const char *arg, int log_block_size)
{
return parse_num_blocks2(arg, log_block_size);
}
#ifdef DEBUG
#include <unistd.h>
#include <stdio.h>
main(int argc, char **argv)
{
unsigned long num;
int log_block_size = 0;
if (argc != 2 && argc != 3) {
fprintf(stderr, "Usage: %s arg [log_block_size]\n", argv[0]);
exit(1);
}
if (argc == 3) {
char *p;
log_block_size = strtol(argv[2], &p, 0);
if (*p) {
fprintf(stderr, "Bad log_block_size: %s\n", argv[2]);
exit(1);
}
}
num = parse_num_blocks(argv[1], log_block_size);
printf("Parsed number: %lu\n", num);
exit(0);
}
#endif

Binary file not shown.

View File

@@ -1,40 +0,0 @@
/*
* pe.c - Print a second extended filesystem errors behavior
*
* Copyright (C) 1992, 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 94/01/09 - Creation
*/
#include "config.h"
#include <stdio.h>
#include "e2p.h"
void print_fs_errors (FILE * f, unsigned short errors)
{
switch (errors)
{
case EXT2_ERRORS_CONTINUE:
fprintf (f, "Continue");
break;
case EXT2_ERRORS_RO:
fprintf (f, "Remount read-only");
break;
case EXT2_ERRORS_PANIC:
fprintf (f, "Panic");
break;
default:
fprintf (f, "Unknown (continue)");
}
}

Binary file not shown.

View File

@@ -1,67 +0,0 @@
/*
* percent.c - Take percentage of a number
*
* Copyright (C) 2006 Theodore Ts'o <tytso@mit.edu>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include "e2p.h"
#include <stdlib.h>
/*
* We work really hard to calculate this accurately, while avoiding
* an overflow. "Is there a hyphen in anal-retentive?" :-)
*/
unsigned int e2p_percent(int percent, unsigned int base)
{
unsigned int mask = ~((1 << (sizeof(unsigned int) - 1) * 8) - 1);
if (!percent)
return 0;
if (100 % percent == 0)
return base / (100 / percent);
if (mask & base)
return (base / 100) * percent;
return base * percent / 100;
}
#ifdef DEBUG
#include <unistd.h>
#include <stdio.h>
main(int argc, char **argv)
{
unsigned int base;
int percent;
char *p;
int log_block_size = 0;
if (argc != 3) {
fprintf(stderr, "Usage: %s percent base\n", argv[0]);
exit(1);
}
percent = strtoul(argv[1], &p, 0);
if (p[0] && p[1]) {
fprintf(stderr, "Bad percent: %s\n", argv[1]);
exit(1);
}
base = strtoul(argv[2], &p, 0);
if (p[0] && p[1]) {
fprintf(stderr, "Bad base: %s\n", argv[2]);
exit(1);
}
printf("%d percent of %u is %u.\n", percent, base,
e2p_percent(percent, base));
exit(0);
}
#endif

Binary file not shown.

View File

@@ -1,79 +0,0 @@
/*
* pf.c - Print file attributes on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#include "config.h"
#include <stdio.h>
#include "e2p.h"
struct flags_name {
unsigned long flag;
const char *short_name;
const char *long_name;
};
static struct flags_name flags_array[] = {
{ EXT2_SECRM_FL, "s", "Secure_Deletion" },
{ EXT2_UNRM_FL, "u" , "Undelete" },
{ EXT2_SYNC_FL, "S", "Synchronous_Updates" },
{ EXT2_DIRSYNC_FL, "D", "Synchronous_Directory_Updates" },
{ EXT2_IMMUTABLE_FL, "i", "Immutable" },
{ EXT2_APPEND_FL, "a", "Append_Only" },
{ EXT2_NODUMP_FL, "d", "No_Dump" },
{ EXT2_NOATIME_FL, "A", "No_Atime" },
{ EXT2_COMPR_FL, "c", "Compression_Requested" },
{ EXT4_ENCRYPT_FL, "E", "Encrypted" },
{ EXT3_JOURNAL_DATA_FL, "j", "Journaled_Data" },
{ EXT2_INDEX_FL, "I", "Indexed_directory" },
{ EXT2_NOTAIL_FL, "t", "No_Tailmerging" },
{ EXT2_TOPDIR_FL, "T", "Top_of_Directory_Hierarchies" },
{ EXT4_EXTENTS_FL, "e", "Extents" },
{ FS_NOCOW_FL, "C", "No_COW" },
{ FS_DAX_FL, "x", "DAX" },
{ EXT4_CASEFOLD_FL, "F", "Casefold" },
{ EXT4_INLINE_DATA_FL, "N", "Inline_Data" },
{ EXT4_PROJINHERIT_FL, "P", "Project_Hierarchy" },
{ EXT4_VERITY_FL, "V", "Verity" },
{ EXT2_NOCOMPR_FL, "m", "Dont_Compress" },
{ 0, NULL, NULL }
};
void print_flags (FILE * f, unsigned long flags, unsigned options)
{
int long_opt = (options & PFOPT_LONG);
struct flags_name *fp;
int first = 1;
for (fp = flags_array; fp->flag != 0; fp++) {
if (flags & fp->flag) {
if (long_opt) {
if (first)
first = 0;
else
fputs(", ", f);
fputs(fp->long_name, f);
} else
fputs(fp->short_name, f);
} else {
if (!long_opt)
fputs("-", f);
}
}
if (long_opt && first)
fputs("---", f);
}

Binary file not shown.

View File

@@ -1,32 +0,0 @@
/*
* ps.c - Print filesystem state
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/12/22 - Creation
*/
#include "config.h"
#include <stdio.h>
#include "e2p.h"
void print_fs_state (FILE * f, unsigned short state)
{
if (state & EXT2_VALID_FS)
fprintf (f, " clean");
else
fprintf (f, " not clean");
if (state & EXT2_ERROR_FS)
fprintf (f, " with errors");
}

Binary file not shown.

View File

@@ -1,77 +0,0 @@
/*
* setflags.c - Set a file flags on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#if HAVE_EXT2_IOCTLS
#include <sys/ioctl.h>
#endif
#include "e2p.h"
/*
* Deal with lame glibc's that define this function without actually
* implementing it. Can you say "attractive nuisance", boys and girls?
* I knew you could!
*/
#ifdef __linux__
#undef HAVE_CHFLAGS
#endif
int setflags (int fd, unsigned long flags)
{
#if HAVE_CHFLAGS
unsigned long bsd_flags = 0;
#ifdef UF_IMMUTABLE
if (flags & EXT2_IMMUTABLE_FL)
bsd_flags |= UF_IMMUTABLE;
#endif
#ifdef UF_APPEND
if (flags & EXT2_APPEND_FL)
bsd_flags |= UF_APPEND;
#endif
#ifdef UF_NODUMP
if (flags & EXT2_NODUMP_FL)
bsd_flags |= UF_NODUMP;
#endif
return fchflags (fd, bsd_flags);
#else /* ! HAVE_CHFLAGS */
#if HAVE_EXT2_IOCTLS
struct stat buf;
int f;
if (!fstat(fd, &buf) &&
!S_ISREG(buf.st_mode) && !S_ISDIR(buf.st_mode)) {
errno = EOPNOTSUPP;
return -1;
}
f = (int) flags;
return ioctl(fd, EXT2_IOC_SETFLAGS, &f);
#else
errno = EOPNOTSUPP;
return -1;
#endif /* HAVE_EXT2_IOCTLS */
#endif /* HAVE_CHFLAGS */
}

Binary file not shown.

View File

@@ -1,40 +0,0 @@
/*
* setversion.c - Set a file version on an ext2 file system
*
* Copyright (C) 1993, 1994 Remy Card <card@masi.ibp.fr>
* Laboratoire MASI, Institut Blaise Pascal
* Universite Pierre et Marie Curie (Paris VI)
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
/*
* History:
* 93/10/30 - Creation
*/
#include "config.h"
#if HAVE_ERRNO_H
#include <errno.h>
#endif
#if HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#include "e2p.h"
int setversion (int fd, unsigned long version)
{
#if HAVE_EXT2_IOCTLS
int ver;
ver = (int) version;
return ioctl (fd, EXT2_IOC_SETVERSION, &ver);
#else /* ! HAVE_EXT2_IOCTLS */
errno = EOPNOTSUPP;
return -1;
#endif /* ! HAVE_EXT2_IOCTLS */
}

Binary file not shown.

View File

@@ -1,85 +0,0 @@
/*
* uuid.c -- utility routines for manipulating UUID's.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#include <ext2fs/ext2_types.h>
#include "e2p.h"
struct uuid {
__u32 time_low;
__u16 time_mid;
__u16 time_hi_and_version;
__u16 clock_seq;
__u8 node[6];
};
/* Returns 1 if the uuid is the NULL uuid */
int e2p_is_null_uuid(void *uu)
{
__u8 *cp;
int i;
for (i=0, cp = uu; i < 16; i++)
if (*cp++)
return 0;
return 1;
}
static void e2p_unpack_uuid(void *in, struct uuid *uu)
{
__u8 *ptr = in;
__u32 tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
tmp = (tmp << 8) | *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->time_low = tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->time_mid = tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->time_hi_and_version = tmp;
tmp = *ptr++;
tmp = (tmp << 8) | *ptr++;
uu->clock_seq = tmp;
memcpy(uu->node, ptr, 6);
}
void e2p_uuid_to_str(void *uu, char *out)
{
struct uuid uuid;
e2p_unpack_uuid(uu, &uuid);
sprintf(out,
"%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",
uuid.time_low, uuid.time_mid, uuid.time_hi_and_version,
uuid.clock_seq >> 8, uuid.clock_seq & 0xFF,
uuid.node[0], uuid.node[1], uuid.node[2],
uuid.node[3], uuid.node[4], uuid.node[5]);
}
const char *e2p_uuid2str(void *uu)
{
static char buf[80];
if (e2p_is_null_uuid(uu))
return "<none>";
e2p_uuid_to_str(uu, buf);
return buf;
}

Binary file not shown.

View File

@@ -1,105 +0,0 @@
/*
* Copyright 1987, 1988 by MIT Student Information Processing Board.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose is hereby granted, provided that
* the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. M.I.T. and the
* M.I.T. S.I.P.B. make no representations about the suitability of
* this software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#include "config.h"
#include <stdio.h>
#ifdef HAVE_TERMIOS_H
#include <termios.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "com_err.h"
#include "error_table.h"
#include "internal.h"
static void
default_com_err_proc (const char *whoami, errcode_t code, const
char *fmt, va_list args)
COM_ERR_ATTR((format(printf, 3, 0)));
static void
default_com_err_proc (const char *whoami, errcode_t code, const
char *fmt, va_list args)
{
int do_cr = 1, fd = fileno(stderr);
if (whoami) {
fputs(whoami, stderr);
fputs(": ", stderr);
}
if (code) {
fputs(error_message(code), stderr);
fputs(" ", stderr);
}
if (fmt) {
vfprintf (stderr, fmt, args);
}
if (!isatty(fd))
do_cr = 0;
#ifdef HAVE_TERMIOS_H
else {
struct termios t;
if ((tcgetattr(fd, &t)) == 0 &&
(t.c_oflag & OPOST) && (t.c_oflag & ONLCR))
do_cr = 0;
}
#endif
if (do_cr)
fputc('\r', stderr);
fputc('\n', stderr);
fflush(stderr);
}
typedef void (*errf) (const char *, errcode_t, const char *, va_list)
COM_ERR_ATTR((format(printf, 3, 0)));
errf com_err_hook = default_com_err_proc;
void com_err_va (const char *whoami, errcode_t code, const char *fmt,
va_list args)
{
(*com_err_hook) (whoami, code, fmt, args);
}
void com_err (const char *whoami,
errcode_t code,
const char *fmt, ...)
{
va_list pvar;
if (!com_err_hook)
com_err_hook = default_com_err_proc;
va_start(pvar, fmt);
com_err_va (whoami, code, fmt, pvar);
va_end(pvar);
}
errf set_com_err_hook(errf new_proc)
{
errf x = com_err_hook;
if (new_proc)
com_err_hook = new_proc;
else
com_err_hook = default_com_err_proc;
return x;
}
errf reset_com_err_hook(void) {
errf x = com_err_hook;
com_err_hook = default_com_err_proc;
return x;
}

Binary file not shown.

View File

@@ -1,120 +0,0 @@
/*
* com_right.c -- provide Heimdall / Kerberos4kth com_err interfaces
* for backwards compatibility
*
* Copyright (c) 2003 by Theodore Ts'o
*
* Taken from lib/com_err/error.c from Kerberos4kth distribution.
*
* Copyright (c) 1997, 1998, 2001 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* 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. Neither the name of the Institute 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 INSTITUTE 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 INSTITUTE 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.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "com_err.h"
#include "error_table.h"
const char *
com_right(struct et_list *list, long code)
{
struct et_list *p;
for (p = list; p; p = p->next) {
if (code >= p->table->base && code < p->table->base + p->table->n_msgs)
return p->table->msgs[code - p->table->base];
}
return NULL;
}
const char *
com_right_r(struct et_list *list, long code, char *str, size_t len)
{
struct et_list *p;
for (p = list; p; p = p->next) {
if ((code >= p->table->base) &&
(code < p->table->base + p->table->n_msgs)) {
strncpy(str, p->table->msgs[code - p->table->base], len);
str[len-1] = '\0';
return str;
}
}
return NULL;
}
struct foobar {
struct et_list etl;
struct error_table tab;
};
/*
* We provide this routine for compatibility with Heimdall generated
* foo_err.c files, but we don't use this ourselves for foo_err.c
* files generated by our compile_et. This is so our foo_err.c
* files can be used with older com_err libraries without running
* afoul of dependencies.
*/
void
initialize_error_table_r(struct et_list **list,
const char **messages,
int num_errors,
long base)
{
struct et_list *et, **end;
struct error_table *tab;
struct foobar *f;
for (end = list, et = *list; et; end = &et->next, et = et->next)
if (et->table->msgs == messages)
return;
f = malloc(sizeof(*f));
if (f == NULL)
return;
et = &f->etl;
et->table = tab = &f->tab;
tab->msgs = messages;
tab->n_msgs = num_errors;
tab->base = base;
et->next = NULL;
*end = et;
}
void
free_error_table(struct et_list *et)
{
while(et){
struct et_list *p = et;
et = et->next;
free(p);
}
}

Binary file not shown.

View File

@@ -1,355 +0,0 @@
/*
* $Header$
* $Source$
* $Locker$
*
* Copyright 1987 by the Student Information Processing Board
* of the Massachusetts Institute of Technology
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose is hereby granted, provided that
* the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. M.I.T. and the
* M.I.T. S.I.P.B. make no representations about the suitability of
* this software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#ifdef HAVE_SYS_PRCTL_H
#include <sys/prctl.h>
#else
#define PR_GET_DUMPABLE 3
#endif
#if (!defined(HAVE_PRCTL) && defined(linux))
#include <sys/syscall.h>
#endif
#ifdef HAVE_SEMAPHORE_H
#include <semaphore.h>
#endif
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#if HAVE_FCNTL
#include <fcntl.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include "com_err.h"
#include "error_table.h"
#include "internal.h"
#ifdef TLS
#define THREAD_LOCAL static TLS
#else
#define THREAD_LOCAL static
#endif
THREAD_LOCAL char buffer[25];
struct et_list * _et_list = (struct et_list *) NULL;
struct et_list * _et_dynamic_list = (struct et_list *) NULL;
#ifdef __GNUC__
#define COMERR_ATTR(x) __attribute__(x)
#else
#define COMERR_ATTR(x)
#endif
#ifdef HAVE_SEM_INIT
static sem_t _et_lock;
static int _et_lock_initialized;
static void COMERR_ATTR((constructor)) setup_et_lock(void)
{
sem_init(&_et_lock, 0, 1);
_et_lock_initialized = 1;
}
static void COMERR_ATTR((destructor)) fini_et_lock(void)
{
sem_destroy(&_et_lock);
_et_lock_initialized = 0;
}
#endif
int et_list_lock(void)
{
#ifdef HAVE_SEM_INIT
if (!_et_lock_initialized)
setup_et_lock();
return sem_wait(&_et_lock);
#else
return 0;
#endif
}
int et_list_unlock(void)
{
#ifdef HAVE_SEM_INIT
if (_et_lock_initialized)
return sem_post(&_et_lock);
#endif
return 0;
}
typedef char *(*gettextf) (const char *);
static gettextf com_err_gettext = NULL;
gettextf set_com_err_gettext(gettextf new_proc)
{
gettextf x = com_err_gettext;
com_err_gettext = new_proc;
return x;
}
#ifdef __GNU__
#define SYS_ERR_BASE 0x40000000
#else
#define SYS_ERR_BASE 0
#endif
const char * error_message (errcode_t code)
{
int offset;
struct et_list *et;
errcode_t table_num;
int started = 0;
char *cp;
offset = (int) (code & ((1<<ERRCODE_RANGE)-1));
table_num = code - offset;
if (table_num == SYS_ERR_BASE) {
#ifdef HAS_SYS_ERRLIST
if (code < sys_nerr)
return(sys_errlist[code]);
else
goto oops;
#else
cp = strerror(code);
if (cp)
return(cp);
else
goto oops;
#endif
}
et_list_lock();
for (et = _et_list; et; et = et->next) {
if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
/* This is the right table */
if (et->table->n_msgs <= offset) {
break;
} else {
const char *msg = et->table->msgs[offset];
et_list_unlock();
if (com_err_gettext)
return (*com_err_gettext)(msg);
else
return msg;
}
}
}
for (et = _et_dynamic_list; et; et = et->next) {
if ((et->table->base & 0xffffffL) == (table_num & 0xffffffL)) {
/* This is the right table */
if (et->table->n_msgs <= offset) {
break;
} else {
const char *msg = et->table->msgs[offset];
et_list_unlock();
if (com_err_gettext)
return (*com_err_gettext)(msg);
else
return msg;
}
}
}
et_list_unlock();
oops:
strcpy (buffer, "Unknown code ");
if (table_num) {
strcat (buffer, error_table_name (table_num));
strcat (buffer, " ");
}
for (cp = buffer; *cp; cp++)
;
if (offset >= 100) {
*cp++ = '0' + offset / 100;
offset %= 100;
started++;
}
if (started || offset >= 10) {
*cp++ = '0' + offset / 10;
offset %= 10;
}
*cp++ = '0' + offset;
*cp = '\0';
return(buffer);
}
/*
* This routine will only return a value if the we are not running as
* a privileged process.
*/
static char *safe_getenv(const char *arg)
{
#if !defined(_WIN32)
if ((getuid() != geteuid()) || (getgid() != getegid()))
return NULL;
#endif
#if HAVE_PRCTL
if (prctl(PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
return NULL;
#else
#if (defined(linux) && defined(SYS_prctl))
if (syscall(SYS_prctl, PR_GET_DUMPABLE, 0, 0, 0, 0) == 0)
return NULL;
#endif
#endif
#if defined(HAVE_SECURE_GETENV)
return secure_getenv(arg);
#elif defined(HAVE___SECURE_GETENV)
return __secure_getenv(arg);
#else
return getenv(arg);
#endif
}
#define DEBUG_INIT 0x8000
#define DEBUG_ADDREMOVE 0x0001
static int debug_mask = 0;
static FILE *debug_f = 0;
static void init_debug(void)
{
char *dstr, *fn, *tmp;
if (debug_mask & DEBUG_INIT)
return;
dstr = getenv("COMERR_DEBUG");
if (dstr) {
debug_mask = strtoul(dstr, &tmp, 0);
if (*tmp || errno)
debug_mask = 0;
}
debug_mask |= DEBUG_INIT;
if (debug_mask == DEBUG_INIT)
return;
fn = safe_getenv("COMERR_DEBUG_FILE");
if (fn)
debug_f = fopen(fn, "a");
if (!debug_f)
debug_f = fopen("/dev/tty", "a");
if (debug_f) {
#ifdef HAVE_FCNTL
int fd = fileno(debug_f);
if (fd >= 0) {
int flags = fcntl(fd, F_GETFD);
if (flags >= 0)
flags = fcntl(fd, F_SETFD, flags | FD_CLOEXEC);
if (flags < 0) {
fprintf(debug_f, "Couldn't set FD_CLOEXEC "
"on debug FILE: %s\n", strerror(errno));
fclose(debug_f);
debug_f = NULL;
debug_mask = DEBUG_INIT;
}
}
#endif
} else
debug_mask = DEBUG_INIT;
}
/*
* New interface provided by krb5's com_err library
*/
errcode_t add_error_table(const struct error_table * et)
{
struct et_list *el;
if (!(el = (struct et_list *) malloc(sizeof(struct et_list))))
return ENOMEM;
if (et_list_lock() != 0) {
free(el);
return errno;
}
el->table = et;
el->next = _et_dynamic_list;
_et_dynamic_list = el;
init_debug();
if (debug_mask & DEBUG_ADDREMOVE)
fprintf(debug_f, "add_error_table: %s (0x%p)\n",
error_table_name(et->base),
(const void *) et);
et_list_unlock();
return 0;
}
/*
* New interface provided by krb5's com_err library
*/
errcode_t remove_error_table(const struct error_table * et)
{
struct et_list *el;
struct et_list *el2 = 0;
if (et_list_lock() != 0)
return ENOENT;
el = _et_dynamic_list;
init_debug();
while (el) {
if (el->table->base == et->base) {
if (el2) /* Not the beginning of the list */
el2->next = el->next;
else
_et_dynamic_list = el->next;
(void) free(el);
if (debug_mask & DEBUG_ADDREMOVE)
fprintf(debug_f,
"remove_error_table: %s (0x%p)\n",
error_table_name(et->base),
(const void *) et);
et_list_unlock();
return 0;
}
el2 = el;
el = el->next;
}
if (debug_mask & DEBUG_ADDREMOVE)
fprintf(debug_f, "remove_error_table FAILED: %s (0x%p)\n",
error_table_name(et->base),
(const void *) et);
et_list_unlock();
return ENOENT;
}
/*
* Variant of the interface provided by Heimdal's com_err library
*/
void
add_to_error_table(struct et_list *new_table)
{
add_error_table(new_table->table);
}

Binary file not shown.

View File

@@ -1,43 +0,0 @@
/*
* Copyright 1987 by MIT Student Information Processing Board
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose is hereby granted, provided that
* the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. M.I.T. and the
* M.I.T. S.I.P.B. make no representations about the suitability of
* this software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#include "config.h"
#include "com_err.h"
#include "error_table.h"
#include "internal.h"
static const char char_set[] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_";
static char buf[6];
const char * error_table_name(errcode_t num)
{
int ch;
int i;
char *p;
/* num = aa aaa abb bbb bcc ccc cdd ddd d?? ??? ??? */
p = buf;
num >>= ERRCODE_RANGE;
/* num = ?? ??? ??? aaa aaa bbb bbb ccc ccc ddd ddd */
num &= 077777777L;
/* num = 00 000 000 aaa aaa bbb bbb ccc ccc ddd ddd */
for (i = 4; i >= 0; i--) {
ch = (int)((num >> BITS_PER_CHAR * i) & ((1 << BITS_PER_CHAR) - 1));
if (ch != 0)
*p++ = char_set[ch-1];
}
*p = '\0';
return(buf);
}

Binary file not shown.

View File

@@ -1,53 +0,0 @@
/*
* $Header$
* $Source$
* $Locker$
*
* Copyright 1986, 1987, 1988 by MIT Information Systems and
* the MIT Student Information Processing Board.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose is hereby granted, provided that
* the names of M.I.T. and the M.I.T. S.I.P.B. not be used in
* advertising or publicity pertaining to distribution of the software
* without specific, written prior permission. M.I.T. and the
* M.I.T. S.I.P.B. make no representations about the suitability of
* this software for any purpose. It is provided "as is" without
* express or implied warranty.
*/
#include "config.h"
#include <stdio.h>
#include <errno.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#include "com_err.h"
#include "error_table.h"
struct foobar {
struct et_list etl;
struct error_table et;
};
extern struct et_list * _et_dynamic_list;
int init_error_table(const char * const *msgs, long base, int count)
{
struct foobar * new_et;
if (!base || !count || !msgs)
return 0;
new_et = (struct foobar *) malloc(sizeof(struct foobar));
if (!new_et)
return ENOMEM; /* oops */
new_et->etl.table = &new_et->et;
new_et->et.msgs = msgs;
new_et->et.base = base;
new_et->et.n_msgs= count;
new_et->etl.next = _et_dynamic_list;
_et_dynamic_list = &new_et->etl;
return 0;
}

Binary file not shown.

View File

@@ -1,554 +0,0 @@
/*
* alloc.c --- allocate new inodes, blocks for ext2fs
*
* Copyright (C) 1993, 1994, 1995, 1996 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <time.h>
#include <string.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include "ext2_fs.h"
#include "ext2fs.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
#undef DEBUG
#ifdef DEBUG
# define dbg_printf(f, a...) do {printf(f, ## a); fflush(stdout); } while (0)
#else
# define dbg_printf(f, a...)
#endif
/*
* Clear the uninit block bitmap flag if necessary
*/
void ext2fs_clear_block_uninit(ext2_filsys fs, dgrp_t group)
{
if (group >= fs->group_desc_count ||
!ext2fs_has_group_desc_csum(fs) ||
!(ext2fs_bg_flags_test(fs, group, EXT2_BG_BLOCK_UNINIT)))
return;
/* uninit block bitmaps are now initialized in read_bitmaps() */
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group);
ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs);
}
/*
* Check for uninit inode bitmaps and deal with them appropriately
*/
static void check_inode_uninit(ext2_filsys fs, ext2fs_inode_bitmap map,
dgrp_t group)
{
ext2_ino_t i, ino;
if (group >= fs->group_desc_count ||
!ext2fs_has_group_desc_csum(fs) ||
!(ext2fs_bg_flags_test(fs, group, EXT2_BG_INODE_UNINIT)))
return;
ino = (group * fs->super->s_inodes_per_group) + 1;
for (i=0; i < fs->super->s_inodes_per_group; i++, ino++)
ext2fs_fast_unmark_inode_bitmap2(map, ino);
ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
/* Mimics what the kernel does */
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group);
ext2fs_mark_ib_dirty(fs);
ext2fs_mark_super_dirty(fs);
}
/*
* Right now, just search forward from the parent directory's block
* group to find the next free inode.
*
* Should have a special policy for directories.
*/
errcode_t ext2fs_new_inode(ext2_filsys fs, ext2_ino_t dir,
int mode EXT2FS_ATTR((unused)),
ext2fs_inode_bitmap map, ext2_ino_t *ret)
{
ext2_ino_t start_inode = 0;
ext2_ino_t i, ino_in_group, upto, first_zero;
errcode_t retval;
dgrp_t group;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (!map)
map = fs->inode_map;
if (!map)
return EXT2_ET_NO_INODE_BITMAP;
if (dir > 0) {
group = (dir - 1) / EXT2_INODES_PER_GROUP(fs->super);
start_inode = (group * EXT2_INODES_PER_GROUP(fs->super)) + 1;
}
if (start_inode < EXT2_FIRST_INODE(fs->super))
start_inode = EXT2_FIRST_INODE(fs->super);
if (start_inode > fs->super->s_inodes_count)
return EXT2_ET_INODE_ALLOC_FAIL;
i = start_inode;
do {
ino_in_group = (i - 1) % EXT2_INODES_PER_GROUP(fs->super);
group = (i - 1) / EXT2_INODES_PER_GROUP(fs->super);
check_inode_uninit(fs, map, group);
upto = i + (EXT2_INODES_PER_GROUP(fs->super) - ino_in_group);
if (i < start_inode && upto >= start_inode)
upto = start_inode - 1;
if (upto > fs->super->s_inodes_count)
upto = fs->super->s_inodes_count;
retval = ext2fs_find_first_zero_inode_bitmap2(map, i, upto,
&first_zero);
if (retval == 0) {
i = first_zero;
break;
}
if (retval != ENOENT)
return EXT2_ET_INODE_ALLOC_FAIL;
i = upto + 1;
if (i > fs->super->s_inodes_count)
i = EXT2_FIRST_INODE(fs->super);
} while (i != start_inode);
if (ext2fs_test_inode_bitmap2(map, i))
return EXT2_ET_INODE_ALLOC_FAIL;
*ret = i;
return 0;
}
/*
* Stupid algorithm --- we now just search forward starting from the
* goal. Should put in a smarter one someday....
*/
errcode_t ext2fs_new_block3(ext2_filsys fs, blk64_t goal,
ext2fs_block_bitmap map, blk64_t *ret,
struct blk_alloc_ctx *ctx)
{
errcode_t retval;
blk64_t b = 0;
errcode_t (*gab)(ext2_filsys fs, blk64_t goal, blk64_t *ret);
errcode_t (*gab2)(ext2_filsys, blk64_t, blk64_t *,
struct blk_alloc_ctx *);
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (!map) {
/*
* In case there are clients out there whose get_alloc_block
* handlers call ext2fs_new_block2 with a NULL block map,
* temporarily swap out the function pointer so that we don't
* end up in an infinite loop.
*/
if (fs->get_alloc_block2) {
gab2 = fs->get_alloc_block2;
fs->get_alloc_block2 = NULL;
retval = gab2(fs, goal, &b, ctx);
fs->get_alloc_block2 = gab2;
goto allocated;
} else if (fs->get_alloc_block) {
gab = fs->get_alloc_block;
fs->get_alloc_block = NULL;
retval = gab(fs, goal, &b);
fs->get_alloc_block = gab;
goto allocated;
}
}
if (!map)
map = fs->block_map;
if (!map)
return EXT2_ET_NO_BLOCK_BITMAP;
if (!goal || (goal >= ext2fs_blocks_count(fs->super)))
goal = fs->super->s_first_data_block;
goal &= ~EXT2FS_CLUSTER_MASK(fs);
retval = ext2fs_find_first_zero_block_bitmap2(map,
goal, ext2fs_blocks_count(fs->super) - 1, &b);
if ((retval == ENOENT) && (goal != fs->super->s_first_data_block))
retval = ext2fs_find_first_zero_block_bitmap2(map,
fs->super->s_first_data_block, goal - 1, &b);
allocated:
if (retval == ENOENT)
return EXT2_ET_BLOCK_ALLOC_FAIL;
if (retval)
return retval;
ext2fs_clear_block_uninit(fs, ext2fs_group_of_blk2(fs, b));
*ret = b;
return 0;
}
errcode_t ext2fs_new_block2(ext2_filsys fs, blk64_t goal,
ext2fs_block_bitmap map, blk64_t *ret)
{
return ext2fs_new_block3(fs, goal, map, ret, NULL);
}
errcode_t ext2fs_new_block(ext2_filsys fs, blk_t goal,
ext2fs_block_bitmap map, blk_t *ret)
{
errcode_t retval;
blk64_t val;
retval = ext2fs_new_block2(fs, goal, map, &val);
if (!retval)
*ret = (blk_t) val;
return retval;
}
/*
* This function zeros out the allocated block, and updates all of the
* appropriate filesystem records.
*/
errcode_t ext2fs_alloc_block3(ext2_filsys fs, blk64_t goal, char *block_buf,
blk64_t *ret, struct blk_alloc_ctx *ctx)
{
errcode_t retval;
blk64_t block;
if (fs->get_alloc_block2) {
retval = (fs->get_alloc_block2)(fs, goal, &block, ctx);
if (retval)
goto fail;
} else if (fs->get_alloc_block) {
retval = (fs->get_alloc_block)(fs, goal, &block);
if (retval)
goto fail;
} else {
if (!fs->block_map) {
retval = ext2fs_read_block_bitmap(fs);
if (retval)
goto fail;
}
retval = ext2fs_new_block3(fs, goal, 0, &block, ctx);
if (retval)
goto fail;
}
if (block_buf) {
memset(block_buf, 0, fs->blocksize);
retval = io_channel_write_blk64(fs->io, block, 1, block_buf);
} else
retval = ext2fs_zero_blocks2(fs, block, 1, NULL, NULL);
if (retval)
goto fail;
ext2fs_block_alloc_stats2(fs, block, +1);
*ret = block;
fail:
return retval;
}
errcode_t ext2fs_alloc_block2(ext2_filsys fs, blk64_t goal,
char *block_buf, blk64_t *ret)
{
return ext2fs_alloc_block3(fs, goal, block_buf, ret, NULL);
}
errcode_t ext2fs_alloc_block(ext2_filsys fs, blk_t goal,
char *block_buf, blk_t *ret)
{
errcode_t retval;
blk64_t ret64, goal64 = goal;
retval = ext2fs_alloc_block3(fs, goal64, block_buf, &ret64, NULL);
if (!retval)
*ret = (blk_t)ret64;
return retval;
}
errcode_t ext2fs_get_free_blocks2(ext2_filsys fs, blk64_t start, blk64_t finish,
int num, ext2fs_block_bitmap map, blk64_t *ret)
{
blk64_t b = start;
int c_ratio;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (!map)
map = fs->block_map;
if (!map)
return EXT2_ET_NO_BLOCK_BITMAP;
if (!b)
b = fs->super->s_first_data_block;
if (!finish)
finish = start;
if (!num)
num = 1;
c_ratio = 1 << ext2fs_get_bitmap_granularity(map);
b &= ~(c_ratio - 1);
finish &= ~(c_ratio -1);
do {
if (b + num - 1 >= ext2fs_blocks_count(fs->super)) {
if (finish > start)
return EXT2_ET_BLOCK_ALLOC_FAIL;
b = fs->super->s_first_data_block;
}
if (ext2fs_fast_test_block_bitmap_range2(map, b, num)) {
*ret = b;
return 0;
}
b += c_ratio;
} while (b != finish);
return EXT2_ET_BLOCK_ALLOC_FAIL;
}
errcode_t ext2fs_get_free_blocks(ext2_filsys fs, blk_t start, blk_t finish,
int num, ext2fs_block_bitmap map, blk_t *ret)
{
errcode_t retval;
blk64_t val;
retval = ext2fs_get_free_blocks2(fs, start, finish, num, map, &val);
if(!retval)
*ret = (blk_t) val;
return retval;
}
void ext2fs_set_alloc_block_callback(ext2_filsys fs,
errcode_t (*func)(ext2_filsys fs,
blk64_t goal,
blk64_t *ret),
errcode_t (**old)(ext2_filsys fs,
blk64_t goal,
blk64_t *ret))
{
if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
return;
if (old)
*old = fs->get_alloc_block;
fs->get_alloc_block = func;
}
blk64_t ext2fs_find_inode_goal(ext2_filsys fs, ext2_ino_t ino,
struct ext2_inode *inode, blk64_t lblk)
{
dgrp_t group;
__u8 log_flex;
struct ext2fs_extent extent;
ext2_extent_handle_t handle = NULL;
errcode_t err;
/* Make sure data stored in inode->i_block is neither fast symlink nor
* inline data.
*/
if (inode == NULL || ext2fs_is_fast_symlink(inode) ||
inode->i_flags & EXT4_INLINE_DATA_FL)
goto no_blocks;
if (inode->i_flags & EXT4_EXTENTS_FL) {
err = ext2fs_extent_open2(fs, ino, inode, &handle);
if (err)
goto no_blocks;
err = ext2fs_extent_goto2(handle, 0, lblk);
if (err)
goto no_blocks;
err = ext2fs_extent_get(handle, EXT2_EXTENT_CURRENT, &extent);
if (err)
goto no_blocks;
ext2fs_extent_free(handle);
return extent.e_pblk + (lblk - extent.e_lblk);
}
/* block mapped file; see if block zero is mapped? */
if (inode->i_block[0])
return inode->i_block[0];
no_blocks:
ext2fs_extent_free(handle);
log_flex = fs->super->s_log_groups_per_flex;
group = ext2fs_group_of_ino(fs, ino);
if (log_flex)
group = group & ~((1 << (log_flex)) - 1);
return ext2fs_group_first_block2(fs, group);
}
/*
* Starting at _goal_, scan around the filesystem to find a run of free blocks
* that's at least _len_ blocks long. Possible flags:
* - EXT2_NEWRANGE_EXACT_GOAL: The range of blocks must start at _goal_.
* - EXT2_NEWRANGE_MIN_LENGTH: do not return a allocation shorter than _len_.
* - EXT2_NEWRANGE_ZERO_BLOCKS: Zero blocks pblk to pblk+plen before returning.
*
* The starting block is returned in _pblk_ and the length is returned via
* _plen_. The blocks are not marked in the bitmap; the caller must mark
* however much of the returned run they actually use, hopefully via
* ext2fs_block_alloc_stats_range().
*
* This function can return a range that is longer than what was requested.
*/
errcode_t ext2fs_new_range(ext2_filsys fs, int flags, blk64_t goal,
blk64_t len, ext2fs_block_bitmap map, blk64_t *pblk,
blk64_t *plen)
{
errcode_t retval;
blk64_t start, end, b;
int looped = 0;
blk64_t max_blocks = ext2fs_blocks_count(fs->super);
errcode_t (*nrf)(ext2_filsys fs, int flags, blk64_t goal,
blk64_t len, blk64_t *pblk, blk64_t *plen);
dbg_printf("%s: flags=0x%x goal=%llu len=%llu\n", __func__, flags,
goal, len);
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (len == 0 || (flags & ~EXT2_NEWRANGE_ALL_FLAGS))
return EXT2_ET_INVALID_ARGUMENT;
if (!map && fs->new_range) {
/*
* In case there are clients out there whose new_range
* handlers call ext2fs_new_range with a NULL block map,
* temporarily swap out the function pointer so that we don't
* end up in an infinite loop.
*/
nrf = fs->new_range;
fs->new_range = NULL;
retval = nrf(fs, flags, goal, len, pblk, plen);
fs->new_range = nrf;
if (retval)
return retval;
start = *pblk;
end = *pblk + *plen;
goto allocated;
}
if (!map)
map = fs->block_map;
if (!map)
return EXT2_ET_NO_BLOCK_BITMAP;
if (!goal || goal >= ext2fs_blocks_count(fs->super))
goal = fs->super->s_first_data_block;
start = goal;
while (!looped || start <= goal) {
retval = ext2fs_find_first_zero_block_bitmap2(map, start,
max_blocks - 1,
&start);
if (retval == ENOENT) {
/*
* If there are no free blocks beyond the starting
* point, try scanning the whole filesystem, unless the
* user told us only to allocate from _goal_, or if
* we're already scanning the whole filesystem.
*/
if (flags & EXT2_NEWRANGE_FIXED_GOAL ||
start == fs->super->s_first_data_block)
goto fail;
start = fs->super->s_first_data_block;
continue;
} else if (retval)
goto errout;
if (flags & EXT2_NEWRANGE_FIXED_GOAL && start != goal)
goto fail;
b = min(start + len - 1, max_blocks - 1);
retval = ext2fs_find_first_set_block_bitmap2(map, start, b,
&end);
if (retval == ENOENT)
end = b + 1;
else if (retval)
goto errout;
if (!(flags & EXT2_NEWRANGE_MIN_LENGTH) ||
(end - start) >= len) {
/* Success! */
*pblk = start;
*plen = end - start;
dbg_printf("%s: new_range goal=%llu--%llu "
"blk=%llu--%llu %llu\n",
__func__, goal, goal + len - 1,
*pblk, *pblk + *plen - 1, *plen);
allocated:
for (b = start; b < end;
b += fs->super->s_blocks_per_group)
ext2fs_clear_block_uninit(fs,
ext2fs_group_of_blk2(fs, b));
return 0;
}
if (flags & EXT2_NEWRANGE_FIXED_GOAL)
goto fail;
start = end;
if (start >= max_blocks) {
if (looped)
goto fail;
looped = 1;
start = fs->super->s_first_data_block;
}
}
fail:
retval = EXT2_ET_BLOCK_ALLOC_FAIL;
errout:
return retval;
}
void ext2fs_set_new_range_callback(ext2_filsys fs,
errcode_t (*func)(ext2_filsys fs, int flags, blk64_t goal,
blk64_t len, blk64_t *pblk, blk64_t *plen),
errcode_t (**old)(ext2_filsys fs, int flags, blk64_t goal,
blk64_t len, blk64_t *pblk, blk64_t *plen))
{
if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
return;
if (old)
*old = fs->new_range;
fs->new_range = func;
}
errcode_t ext2fs_alloc_range(ext2_filsys fs, int flags, blk64_t goal,
blk_t len, blk64_t *ret)
{
int newr_flags = EXT2_NEWRANGE_MIN_LENGTH;
errcode_t retval;
blk64_t plen;
EXT2_CHECK_MAGIC(fs, EXT2_ET_MAGIC_EXT2FS_FILSYS);
if (len == 0 || (flags & ~EXT2_ALLOCRANGE_ALL_FLAGS))
return EXT2_ET_INVALID_ARGUMENT;
if (flags & EXT2_ALLOCRANGE_FIXED_GOAL)
newr_flags |= EXT2_NEWRANGE_FIXED_GOAL;
retval = ext2fs_new_range(fs, newr_flags, goal, len, NULL, ret, &plen);
if (retval)
return retval;
if (plen < len)
return EXT2_ET_BLOCK_ALLOC_FAIL;
if (flags & EXT2_ALLOCRANGE_ZERO_BLOCKS) {
retval = ext2fs_zero_blocks2(fs, *ret, len, NULL, NULL);
if (retval)
return retval;
}
ext2fs_block_alloc_stats_range(fs, *ret, len, +1);
return retval;
}

Binary file not shown.

View File

@@ -1,81 +0,0 @@
/*
* alloc_sb.c --- Allocate the superblock and block group descriptors for a
* newly initialized filesystem. Used by mke2fs when initializing a filesystem
*
* Copyright (C) 1994, 1995, 1996, 2003 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <time.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include "ext2_fs.h"
#include "ext2fs.h"
/*
* This function reserves the superblock and block group descriptors
* for a given block group. It currently returns the number of free
* blocks assuming that inode table and allocation bitmaps will be in
* the group. This is not necessarily the case when the flex_bg
* feature is enabled, so callers should take care! It was only
* really intended for use by mke2fs, and even there it's not that
* useful. In the future, when we redo this function for 64-bit block
* numbers, we should probably return the number of blocks used by the
* super block and group descriptors instead.
*
* See also the comment for ext2fs_super_and_bgd_loc()
*/
int ext2fs_reserve_super_and_bgd(ext2_filsys fs,
dgrp_t group,
ext2fs_block_bitmap bmap)
{
blk64_t super_blk, old_desc_blk, new_desc_blk;
blk_t used_blks;
int old_desc_blocks, num_blocks;
ext2fs_super_and_bgd_loc2(fs, group, &super_blk,
&old_desc_blk, &new_desc_blk, &used_blks);
if (ext2fs_has_feature_meta_bg(fs->super))
old_desc_blocks = fs->super->s_first_meta_bg;
else
old_desc_blocks =
fs->desc_blocks + fs->super->s_reserved_gdt_blocks;
if (super_blk || (group == 0))
ext2fs_mark_block_bitmap2(bmap, super_blk);
if ((group == 0) && (fs->blocksize == 1024) &&
EXT2FS_CLUSTER_RATIO(fs) > 1)
ext2fs_mark_block_bitmap2(bmap, 0);
if (old_desc_blk) {
num_blocks = old_desc_blocks;
if (old_desc_blk + num_blocks >= ext2fs_blocks_count(fs->super))
num_blocks = ext2fs_blocks_count(fs->super) -
old_desc_blk;
ext2fs_mark_block_bitmap_range2(bmap, old_desc_blk, num_blocks);
}
if (new_desc_blk)
ext2fs_mark_block_bitmap2(bmap, new_desc_blk);
num_blocks = ext2fs_group_blocks_count(fs, group);
num_blocks -= 2 + fs->inode_blocks_per_group + used_blks;
return num_blocks ;
}

Binary file not shown.

View File

@@ -1,165 +0,0 @@
/*
* alloc_stats.c --- Update allocation statistics for ext2fs
*
* Copyright (C) 2001 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include "ext2_fs.h"
#include "ext2fs.h"
void ext2fs_inode_alloc_stats2(ext2_filsys fs, ext2_ino_t ino,
int inuse, int isdir)
{
int group = ext2fs_group_of_ino(fs, ino);
if (ino > fs->super->s_inodes_count) {
#ifndef OMIT_COM_ERR
com_err("ext2fs_inode_alloc_stats2", 0,
"Illegal inode number: %lu", (unsigned long) ino);
#endif
return;
}
if (inuse > 0)
ext2fs_mark_inode_bitmap2(fs->inode_map, ino);
else
ext2fs_unmark_inode_bitmap2(fs->inode_map, ino);
ext2fs_bg_free_inodes_count_set(fs, group, ext2fs_bg_free_inodes_count(fs, group) - inuse);
if (isdir)
ext2fs_bg_used_dirs_count_set(fs, group, ext2fs_bg_used_dirs_count(fs, group) + inuse);
/* We don't strictly need to be clearing the uninit flag if inuse < 0
* (i.e. freeing inodes) but it also means something is bad. */
ext2fs_bg_flags_clear(fs, group, EXT2_BG_INODE_UNINIT);
if (ext2fs_has_group_desc_csum(fs)) {
ext2_ino_t first_unused_inode = fs->super->s_inodes_per_group -
ext2fs_bg_itable_unused(fs, group) +
group * fs->super->s_inodes_per_group + 1;
if (ino >= first_unused_inode)
ext2fs_bg_itable_unused_set(fs, group, group * fs->super->s_inodes_per_group + fs->super->s_inodes_per_group - ino);
ext2fs_group_desc_csum_set(fs, group);
}
fs->super->s_free_inodes_count -= inuse;
ext2fs_mark_super_dirty(fs);
ext2fs_mark_ib_dirty(fs);
}
void ext2fs_inode_alloc_stats(ext2_filsys fs, ext2_ino_t ino, int inuse)
{
ext2fs_inode_alloc_stats2(fs, ino, inuse, 0);
}
void ext2fs_block_alloc_stats2(ext2_filsys fs, blk64_t blk, int inuse)
{
int group = ext2fs_group_of_blk2(fs, blk);
if (blk < fs->super->s_first_data_block ||
blk >= ext2fs_blocks_count(fs->super)) {
#ifndef OMIT_COM_ERR
com_err("ext2fs_block_alloc_stats", 0,
"Illegal block number: %lu", (unsigned long) blk);
#endif
return;
}
if (inuse > 0)
ext2fs_mark_block_bitmap2(fs->block_map, blk);
else
ext2fs_unmark_block_bitmap2(fs->block_map, blk);
ext2fs_bg_free_blocks_count_set(fs, group, ext2fs_bg_free_blocks_count(fs, group) - inuse);
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group);
ext2fs_free_blocks_count_add(fs->super,
-inuse * (blk64_t) EXT2FS_CLUSTER_RATIO(fs));
ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs);
if (fs->block_alloc_stats)
(fs->block_alloc_stats)(fs, (blk64_t) blk, inuse);
}
void ext2fs_block_alloc_stats(ext2_filsys fs, blk_t blk, int inuse)
{
ext2fs_block_alloc_stats2(fs, blk, inuse);
}
void ext2fs_set_block_alloc_stats_callback(ext2_filsys fs,
void (*func)(ext2_filsys fs,
blk64_t blk,
int inuse),
void (**old)(ext2_filsys fs,
blk64_t blk,
int inuse))
{
if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
return;
if (old)
*old = fs->block_alloc_stats;
fs->block_alloc_stats = func;
}
void ext2fs_block_alloc_stats_range(ext2_filsys fs, blk64_t blk,
blk_t num, int inuse)
{
#ifndef OMIT_COM_ERR
if (blk + num > ext2fs_blocks_count(fs->super)) {
com_err("ext2fs_block_alloc_stats_range", 0,
"Illegal block range: %llu (%u) ",
(unsigned long long) blk, num);
return;
}
#endif
if (inuse == 0)
return;
if (inuse > 0) {
ext2fs_mark_block_bitmap_range2(fs->block_map, blk, num);
inuse = 1;
} else {
ext2fs_unmark_block_bitmap_range2(fs->block_map, blk, num);
inuse = -1;
}
while (num) {
int group = ext2fs_group_of_blk2(fs, blk);
blk64_t last_blk = ext2fs_group_last_block2(fs, group);
blk64_t n = num;
if (blk + num > last_blk)
n = last_blk - blk + 1;
ext2fs_bg_free_blocks_count_set(fs, group,
ext2fs_bg_free_blocks_count(fs, group) -
inuse*n/EXT2FS_CLUSTER_RATIO(fs));
ext2fs_bg_flags_clear(fs, group, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, group);
ext2fs_free_blocks_count_add(fs->super, -inuse * (blk64_t) n);
blk += n;
num -= n;
}
ext2fs_mark_super_dirty(fs);
ext2fs_mark_bb_dirty(fs);
if (fs->block_alloc_stats_range)
(fs->block_alloc_stats_range)(fs, blk, num, inuse);
}
void ext2fs_set_block_alloc_stats_range_callback(ext2_filsys fs,
void (*func)(ext2_filsys fs, blk64_t blk,
blk_t num, int inuse),
void (**old)(ext2_filsys fs, blk64_t blk,
blk_t num, int inuse))
{
if (!fs || fs->magic != EXT2_ET_MAGIC_EXT2FS_FILSYS)
return;
if (old)
*old = fs->block_alloc_stats_range;
fs->block_alloc_stats_range = func;
}

View File

@@ -1,278 +0,0 @@
/*
* alloc_tables.c --- Allocate tables for a newly initialized
* filesystem. Used by mke2fs when initializing a filesystem
*
* Copyright (C) 1996 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <time.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include "ext2_fs.h"
#include "ext2fs.h"
#include "ext2fsP.h"
/*
* This routine searches for free blocks that can allocate a full
* group of bitmaps or inode tables for a flexbg group. Returns the
* block number with a correct offset were the bitmaps and inode
* tables can be allocated continuously and in order.
*/
static blk64_t flexbg_offset(ext2_filsys fs, dgrp_t group, blk64_t start_blk,
ext2fs_block_bitmap bmap, int rem_grp,
int elem_size)
{
int flexbg, flexbg_size, size;
blk64_t last_blk, first_free = 0;
dgrp_t last_grp;
flexbg_size = 1U << fs->super->s_log_groups_per_flex;
flexbg = group / flexbg_size;
size = rem_grp * elem_size;
if (size > (int) (fs->super->s_blocks_per_group / 4))
size = (int) fs->super->s_blocks_per_group / 4;
/*
* Don't do a long search if the previous block search is still valid,
* but skip minor obstructions such as group descriptor backups.
*/
if (start_blk && start_blk < ext2fs_blocks_count(fs->super) &&
ext2fs_get_free_blocks2(fs, start_blk, start_blk + size, elem_size,
bmap, &first_free) == 0)
return first_free;
start_blk = ext2fs_group_first_block2(fs, flexbg_size * flexbg);
last_grp = group | (flexbg_size - 1);
if (last_grp > fs->group_desc_count-1)
last_grp = fs->group_desc_count-1;
last_blk = ext2fs_group_last_block2(fs, last_grp);
/* Find the first available block */
if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, size,
bmap, &first_free) == 0)
return first_free;
if (ext2fs_get_free_blocks2(fs, start_blk, last_blk, elem_size,
bmap, &first_free) == 0)
return first_free;
if (ext2fs_get_free_blocks2(fs, 0, last_blk, elem_size, bmap,
&first_free) == 0)
return first_free;
return first_free;
}
errcode_t ext2fs_allocate_group_table(ext2_filsys fs, dgrp_t group,
ext2fs_block_bitmap bmap)
{
errcode_t retval;
blk64_t group_blk, start_blk, last_blk, new_blk;
dgrp_t last_grp = 0;
int rem_grps = 0, flexbg_size = 0, table_offset = 0;
group_blk = ext2fs_group_first_block2(fs, group);
last_blk = ext2fs_group_last_block2(fs, group);
if (!bmap)
bmap = fs->block_map;
if (ext2fs_has_feature_flex_bg(fs->super) &&
fs->super->s_log_groups_per_flex) {
flexbg_size = 1U << fs->super->s_log_groups_per_flex;
last_grp = group | (flexbg_size - 1);
if (last_grp > fs->group_desc_count-1)
last_grp = fs->group_desc_count-1;
rem_grps = last_grp - group + 1;
}
/*
* Allocate the block and inode bitmaps, if necessary
*/
if (fs->stride && !flexbg_size) {
retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
1, bmap, &start_blk);
if (retval)
return retval;
start_blk += fs->inode_blocks_per_group;
start_blk += ((fs->stride * group) %
(last_blk - start_blk + 1));
if (start_blk >= last_blk)
start_blk = group_blk;
} else
start_blk = group_blk;
if (flexbg_size) {
blk64_t prev_block = 0;
table_offset = flexbg_size;
if (group % flexbg_size)
prev_block = ext2fs_block_bitmap_loc(fs, group - 1) + 1;
else if (last_grp == fs->group_desc_count-1) {
/*
* If we are allocating for the last flex_bg
* keep the metadata tables contiguous
*/
table_offset = last_grp & (flexbg_size - 1);
if (table_offset == 0)
table_offset = flexbg_size;
else
table_offset++;
}
/* FIXME: Take backup group descriptor blocks into account
* if the flexbg allocations will grow to overlap them... */
start_blk = flexbg_offset(fs, group, prev_block, bmap,
rem_grps, 1);
last_blk = ext2fs_group_last_block2(fs, last_grp);
}
if (!ext2fs_block_bitmap_loc(fs, group)) {
retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
1, bmap, &new_blk);
if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
retval = ext2fs_get_free_blocks2(fs, group_blk,
last_blk, 1, bmap, &new_blk);
if (retval)
return retval;
ext2fs_mark_block_bitmap2(bmap, new_blk);
ext2fs_block_bitmap_loc_set(fs, group, new_blk);
if (flexbg_size) {
dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
ext2fs_free_blocks_count_add(fs->super, -1);
ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, gr);
}
}
if (flexbg_size) {
blk64_t prev_block = 0;
if (group % flexbg_size)
prev_block = ext2fs_inode_bitmap_loc(fs, group - 1) + 1;
else
prev_block = ext2fs_block_bitmap_loc(fs, group) +
table_offset;
/* FIXME: Take backup group descriptor blocks into account
* if the flexbg allocations will grow to overlap them... */
start_blk = flexbg_offset(fs, group, prev_block, bmap,
rem_grps, 1);
last_blk = ext2fs_group_last_block2(fs, last_grp);
}
if (!ext2fs_inode_bitmap_loc(fs, group)) {
retval = ext2fs_get_free_blocks2(fs, start_blk, last_blk,
1, bmap, &new_blk);
if (retval == EXT2_ET_BLOCK_ALLOC_FAIL)
retval = ext2fs_get_free_blocks2(fs, group_blk,
last_blk, 1, bmap, &new_blk);
if (retval)
return retval;
ext2fs_mark_block_bitmap2(bmap, new_blk);
ext2fs_inode_bitmap_loc_set(fs, group, new_blk);
if (flexbg_size) {
dgrp_t gr = ext2fs_group_of_blk2(fs, new_blk);
ext2fs_bg_free_blocks_count_set(fs, gr, ext2fs_bg_free_blocks_count(fs, gr) - 1);
ext2fs_free_blocks_count_add(fs->super, -1);
ext2fs_bg_flags_clear(fs, gr, EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, gr);
}
}
/*
* Allocate the inode table
*/
if (flexbg_size) {
blk64_t prev_block = 0;
if (group % flexbg_size)
prev_block = ext2fs_inode_table_loc(fs, group - 1) +
fs->inode_blocks_per_group;
else
prev_block = ext2fs_inode_bitmap_loc(fs, group) +
table_offset;
/* FIXME: Take backup group descriptor blocks into account
* if the flexbg allocations will grow to overlap them... */
group_blk = flexbg_offset(fs, group, prev_block, bmap,
rem_grps, fs->inode_blocks_per_group);
last_blk = ext2fs_group_last_block2(fs, last_grp);
}
if (!ext2fs_inode_table_loc(fs, group)) {
retval = ext2fs_get_free_blocks2(fs, group_blk, last_blk,
fs->inode_blocks_per_group,
bmap, &new_blk);
if (retval)
return retval;
ext2fs_mark_block_bitmap_range2(bmap,
new_blk, fs->inode_blocks_per_group);
if (flexbg_size) {
blk64_t num, blk;
num = fs->inode_blocks_per_group;
blk = new_blk;
while (num) {
int gr = ext2fs_group_of_blk2(fs, blk);
last_blk = ext2fs_group_last_block2(fs, gr);
blk64_t n = num;
if (blk + num > last_blk)
n = last_blk - blk + 1;
ext2fs_bg_free_blocks_count_set(fs, gr,
ext2fs_bg_free_blocks_count(fs, gr) -
n/EXT2FS_CLUSTER_RATIO(fs));
ext2fs_bg_flags_clear(fs, gr,
EXT2_BG_BLOCK_UNINIT);
ext2fs_group_desc_csum_set(fs, gr);
ext2fs_free_blocks_count_add(fs->super, -n);
blk += n;
num -= n;
}
}
ext2fs_inode_table_loc_set(fs, group, new_blk);
}
ext2fs_group_desc_csum_set(fs, group);
return 0;
}
errcode_t ext2fs_allocate_tables(ext2_filsys fs)
{
errcode_t retval;
dgrp_t i;
struct ext2fs_numeric_progress_struct progress;
if (fs->progress_ops && fs->progress_ops->init)
(fs->progress_ops->init)(fs, &progress, NULL,
fs->group_desc_count);
for (i = 0; i < fs->group_desc_count; i++) {
if (fs->progress_ops && fs->progress_ops->update)
(fs->progress_ops->update)(fs, &progress, i);
retval = ext2fs_allocate_group_table(fs, i, fs->block_map);
if (retval)
return retval;
}
if (fs->progress_ops && fs->progress_ops->close)
(fs->progress_ops->close)(fs, &progress, NULL);
return 0;
}

View File

@@ -1,116 +0,0 @@
/*
* atexit.c --- Clean things up when we exit normally.
*
* Copyright Oracle, 2014
* Author Darrick J. Wong <darrick.wong@oracle.com>
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#ifndef _LARGEFILE_SOURCE
#define _LARGEFILE_SOURCE
#endif
#ifndef _LARGEFILE64_SOURCE
#define _LARGEFILE64_SOURCE
#endif
#include "config.h"
#include <stdlib.h>
#include "ext2_fs.h"
#include "ext2fs.h"
#include "ext2fsP.h"
struct exit_data {
ext2_exit_fn func;
void *data;
};
static struct exit_data *items;
static size_t nr_items;
static void handle_exit(void)
{
struct exit_data *ed;
for (ed = items + nr_items - 1; ed >= items; ed--) {
if (ed->func == NULL)
continue;
ed->func(ed->data);
}
ext2fs_free_mem(&items);
nr_items = 0;
}
/*
* Schedule a function to be called at (normal) program termination.
* If you want this to be called during a signal exit, you must capture
* the signal and call exit() yourself!
*/
errcode_t ext2fs_add_exit_fn(ext2_exit_fn func, void *data)
{
struct exit_data *ed, *free_ed = NULL;
size_t x;
errcode_t ret;
if (func == NULL)
return EXT2_ET_INVALID_ARGUMENT;
for (x = 0, ed = items; x < nr_items; x++, ed++) {
if (ed->func == func && ed->data == data)
return EXT2_ET_FILE_EXISTS;
if (ed->func == NULL)
free_ed = ed;
}
if (free_ed) {
free_ed->func = func;
free_ed->data = data;
return 0;
}
if (nr_items == 0) {
ret = atexit(handle_exit);
if (ret)
return ret;
}
ret = ext2fs_resize_mem(0, (nr_items + 1) * sizeof(struct exit_data),
&items);
if (ret)
return ret;
items[nr_items].func = func;
items[nr_items].data = data;
nr_items++;
return 0;
}
/* Remove a function from the exit cleanup list. */
errcode_t ext2fs_remove_exit_fn(ext2_exit_fn func, void *data)
{
struct exit_data *ed;
size_t x;
if (func == NULL)
return EXT2_ET_INVALID_ARGUMENT;
for (x = 0, ed = items; x < nr_items; x++, ed++) {
if (ed->func == NULL)
return 0;
if (ed->func == func && ed->data == data) {
size_t sz = (nr_items - (x + 1)) *
sizeof(struct exit_data);
memmove(ed, ed + 1, sz);
memset(items + nr_items - 1, 0,
sizeof(struct exit_data));
}
}
return 0;
}

Binary file not shown.

View File

@@ -1,328 +0,0 @@
/*
* badblocks.c --- routines to manipulate the bad block structure
*
* Copyright (C) 1994, 1995, 1996 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <time.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include "ext2_fs.h"
#include "ext2fsP.h"
/*
* Helper function for making a badblocks list
*/
static errcode_t make_u32_list(int size, int num, __u32 *list,
ext2_u32_list *ret)
{
ext2_u32_list bb;
errcode_t retval;
retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_list), &bb);
if (retval)
return retval;
memset(bb, 0, sizeof(struct ext2_struct_u32_list));
bb->magic = EXT2_ET_MAGIC_BADBLOCKS_LIST;
bb->size = size ? size : 10;
bb->num = num;
retval = ext2fs_get_array(bb->size, sizeof(blk_t), &bb->list);
if (retval) {
ext2fs_free_mem(&bb);
return retval;
}
if (list)
memcpy(bb->list, list, bb->size * sizeof(blk_t));
else
memset(bb->list, 0, bb->size * sizeof(blk_t));
*ret = bb;
return 0;
}
/*
* This procedure creates an empty u32 list.
*/
errcode_t ext2fs_u32_list_create(ext2_u32_list *ret, int size)
{
return make_u32_list(size, 0, 0, ret);
}
/*
* This procedure creates an empty badblocks list.
*/
errcode_t ext2fs_badblocks_list_create(ext2_badblocks_list *ret, int size)
{
return make_u32_list(size, 0, 0, (ext2_badblocks_list *) ret);
}
/*
* This procedure copies a badblocks list
*/
errcode_t ext2fs_u32_copy(ext2_u32_list src, ext2_u32_list *dest)
{
errcode_t retval;
retval = make_u32_list(src->size, src->num, src->list, dest);
if (retval)
return retval;
(*dest)->badblocks_flags = src->badblocks_flags;
return 0;
}
errcode_t ext2fs_badblocks_copy(ext2_badblocks_list src,
ext2_badblocks_list *dest)
{
return ext2fs_u32_copy((ext2_u32_list) src,
(ext2_u32_list *) dest);
}
/*
* This procedure frees a badblocks list.
*
* (note: moved to closefs.c)
*/
/*
* This procedure adds a block to a badblocks list.
*/
errcode_t ext2fs_u32_list_add(ext2_u32_list bb, __u32 blk)
{
errcode_t retval;
int i, j;
unsigned long old_size;
EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
if (bb->num >= bb->size) {
old_size = bb->size * sizeof(__u32);
bb->size += 100;
retval = ext2fs_resize_mem(old_size, bb->size * sizeof(__u32),
&bb->list);
if (retval) {
bb->size -= 100;
return retval;
}
}
/*
* Add special case code for appending to the end of the list
*/
i = bb->num-1;
if ((bb->num != 0) && (bb->list[i] == blk))
return 0;
if ((bb->num == 0) || (bb->list[i] < blk)) {
bb->list[bb->num++] = blk;
return 0;
}
j = bb->num;
for (i=0; i < bb->num; i++) {
if (bb->list[i] == blk)
return 0;
if (bb->list[i] > blk) {
j = i;
break;
}
}
for (i=bb->num; i > j; i--)
bb->list[i] = bb->list[i-1];
bb->list[j] = blk;
bb->num++;
return 0;
}
errcode_t ext2fs_badblocks_list_add(ext2_badblocks_list bb, blk_t blk)
{
return ext2fs_u32_list_add((ext2_u32_list) bb, (__u32) blk);
}
/*
* This procedure finds a particular block is on a badblocks
* list.
*/
int ext2fs_u32_list_find(ext2_u32_list bb, __u32 blk)
{
int low, high, mid;
if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
return -1;
if (bb->num == 0)
return -1;
low = 0;
high = bb->num-1;
if (blk == bb->list[low])
return low;
if (blk == bb->list[high])
return high;
while (low < high) {
mid = ((unsigned)low + (unsigned)high)/2;
if (mid == low || mid == high)
break;
if (blk == bb->list[mid])
return mid;
if (blk < bb->list[mid])
high = mid;
else
low = mid;
}
return -1;
}
/*
* This procedure tests to see if a particular block is on a badblocks
* list.
*/
int ext2fs_u32_list_test(ext2_u32_list bb, __u32 blk)
{
if (ext2fs_u32_list_find(bb, blk) < 0)
return 0;
else
return 1;
}
int ext2fs_badblocks_list_test(ext2_badblocks_list bb, blk_t blk)
{
return ext2fs_u32_list_test((ext2_u32_list) bb, (__u32) blk);
}
/*
* Remove a block from the badblock list
*/
int ext2fs_u32_list_del(ext2_u32_list bb, __u32 blk)
{
int remloc, i;
if (bb->num == 0)
return -1;
remloc = ext2fs_u32_list_find(bb, blk);
if (remloc < 0)
return -1;
for (i = remloc ; i < bb->num-1; i++)
bb->list[i] = bb->list[i+1];
bb->num--;
return 0;
}
void ext2fs_badblocks_list_del(ext2_u32_list bb, __u32 blk)
{
ext2fs_u32_list_del(bb, blk);
}
errcode_t ext2fs_u32_list_iterate_begin(ext2_u32_list bb,
ext2_u32_iterate *ret)
{
ext2_u32_iterate iter;
errcode_t retval;
EXT2_CHECK_MAGIC(bb, EXT2_ET_MAGIC_BADBLOCKS_LIST);
retval = ext2fs_get_mem(sizeof(struct ext2_struct_u32_iterate), &iter);
if (retval)
return retval;
iter->magic = EXT2_ET_MAGIC_BADBLOCKS_ITERATE;
iter->bb = bb;
iter->ptr = 0;
*ret = iter;
return 0;
}
errcode_t ext2fs_badblocks_list_iterate_begin(ext2_badblocks_list bb,
ext2_badblocks_iterate *ret)
{
return ext2fs_u32_list_iterate_begin((ext2_u32_list) bb,
(ext2_u32_iterate *) ret);
}
int ext2fs_u32_list_iterate(ext2_u32_iterate iter, __u32 *blk)
{
ext2_u32_list bb;
if (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE)
return 0;
bb = iter->bb;
if (bb->magic != EXT2_ET_MAGIC_BADBLOCKS_LIST)
return 0;
if (iter->ptr < bb->num) {
*blk = bb->list[iter->ptr++];
return 1;
}
*blk = 0;
return 0;
}
int ext2fs_badblocks_list_iterate(ext2_badblocks_iterate iter, blk_t *blk)
{
return ext2fs_u32_list_iterate((ext2_u32_iterate) iter,
(__u32 *) blk);
}
void ext2fs_u32_list_iterate_end(ext2_u32_iterate iter)
{
if (!iter || (iter->magic != EXT2_ET_MAGIC_BADBLOCKS_ITERATE))
return;
iter->bb = 0;
ext2fs_free_mem(&iter);
}
void ext2fs_badblocks_list_iterate_end(ext2_badblocks_iterate iter)
{
ext2fs_u32_list_iterate_end((ext2_u32_iterate) iter);
}
int ext2fs_u32_list_equal(ext2_u32_list bb1, ext2_u32_list bb2)
{
EXT2_CHECK_MAGIC(bb1, EXT2_ET_MAGIC_BADBLOCKS_LIST);
EXT2_CHECK_MAGIC(bb2, EXT2_ET_MAGIC_BADBLOCKS_LIST);
if (bb1->num != bb2->num)
return 0;
if (memcmp(bb1->list, bb2->list, bb1->num * sizeof(blk_t)) != 0)
return 0;
return 1;
}
int ext2fs_badblocks_equal(ext2_badblocks_list bb1, ext2_badblocks_list bb2)
{
return ext2fs_u32_list_equal((ext2_u32_list) bb1,
(ext2_u32_list) bb2);
}
int ext2fs_u32_list_count(ext2_u32_list bb)
{
return bb->num;
}

Binary file not shown.

View File

@@ -1,64 +0,0 @@
/*
* bb_compat.c --- compatibility badblocks routines
*
* Copyright (C) 1997 Theodore Ts'o.
*
* %Begin-Header%
* This file may be redistributed under the terms of the GNU Library
* General Public License, version 2.
* %End-Header%
*/
#include "config.h"
#include <stdio.h>
#include <string.h>
#if HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <fcntl.h>
#include <time.h>
#if HAVE_SYS_STAT_H
#include <sys/stat.h>
#endif
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
#include "ext2_fs.h"
#include "ext2fsP.h"
errcode_t badblocks_list_create(badblocks_list *ret, int size)
{
return ext2fs_badblocks_list_create(ret, size);
}
void badblocks_list_free(badblocks_list bb)
{
ext2fs_badblocks_list_free(bb);
}
errcode_t badblocks_list_add(badblocks_list bb, blk_t blk)
{
return ext2fs_badblocks_list_add(bb, blk);
}
int badblocks_list_test(badblocks_list bb, blk_t blk)
{
return ext2fs_badblocks_list_test(bb, blk);
}
errcode_t badblocks_list_iterate_begin(badblocks_list bb,
badblocks_iterate *ret)
{
return ext2fs_badblocks_list_iterate_begin(bb, ret);
}
int badblocks_list_iterate(badblocks_iterate iter, blk_t *blk)
{
return ext2fs_badblocks_list_iterate(iter, blk);
}
void badblocks_list_iterate_end(badblocks_iterate iter)
{
ext2fs_badblocks_list_iterate_end(iter);
}

Some files were not shown because too many files have changed in this diff Show More