diff options
author | Aaron Griffin <aaron@archlinux.org> | 2006-11-14 07:58:42 +0000 |
---|---|---|
committer | Aaron Griffin <aaron@archlinux.org> | 2006-11-14 07:58:42 +0000 |
commit | 4470e5ce011fef0c918b5c3d1d42ae333fb361ba (patch) | |
tree | 5ce8d77cc28f688d53fdea517434f6b1f4f10f10 | |
parent | 7e835366f15f98a1688e022a781483d5c5eeb114 (diff) | |
download | pacman-4470e5ce011fef0c918b5c3d1d42ae333fb361ba.tar.xz |
* Numerous mini valgrind fixes.
* Addition of hacky architecture check in the _splitname function
* Removal of libfetch from the archlinux proper - it has been renamed to
libdownload and can be found at http://phraktured.net/libdownload
* Merge of _some_ of the Frugalware makepkg change - this may still be
incomplete
* Removal of libftp from cvs proper
* PKGBUILD manpage now says 'PKGBUILD' instead of FrugalBuild (he he)
40 files changed, 548 insertions, 7137 deletions
diff --git a/Makefile.am b/Makefile.am index e292d025..35215350 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,4 +1,4 @@ -SUBDIRS = lib/libfetch lib/libalpm src/util src/pacman scripts doc doc/hu etc +SUBDIRS = lib/libalpm src/util src/pacman scripts doc doc/hu etc if HAS_PERL SUBDIRS += bindings/perl @@ -22,5 +22,4 @@ check: src/pacman tags: ctags -a lib/libalpm/*.[ch] - ctags -a lib/libftp/*.[ch] ctags -a src/pacman/*.[ch] diff --git a/doc/PKGBUILD.8 b/doc/PKGBUILD.8 index 61fc7208..024543cb 100644 --- a/doc/PKGBUILD.8 +++ b/doc/PKGBUILD.8 @@ -1,14 +1,14 @@ -.TH FrugalBuild 8 "June 13, 2006" "Frugalware Developer Manual" "" +.TH PKGBUILD 8 "June 13, 2006" "Archlinux Developer Manual" "" .SH NAME -FrugalBuild \- Frugalware package builder descriptor +PKGBUILD \- Archlinux package builder descriptor .SH DESCRIPTION -This manual page is meant to describe general rules about FrugalBuilds. If +This manual page is meant to describe general rules about PKGBUILDs. If you're interested in the package builder \fBmakepkg\fP itself, then see its manual page, not this one. .TP .TP -.SH FrugalBuild Example: +.SH PKGBUILD Example: .RS .nf # Last Modified: Sun, 19 Jun 2005 15:24:32 +0000 @@ -47,13 +47,13 @@ successful builds, and this SBU value will be equal on anyone's machine. If you wish to maintain the package, write your name or nick and e-mail address to the third line. If you don't plan to maintain the package just wrote -the FrugalBuild, then write Contributor instead of Maintainer, and then someone +the PKGBUILD, then write Contributor instead of Maintainer, and then someone can take it and will add his/her line later. Other lines like "Modified by" are not allowed. Use the darcs patch comments to mention others if you wish. pkgname defines the package name. It should not contain any uppercase letters. The package version defines the upstream version, while the package release -tracks the Frugalware-specific changes. pkgrel should be an integer, pkgrels +tracks the Archlinux-specific changes. pkgrel should be an integer, pkgrels like 5wanda1 are reserved for security updates. There the rule is the following: If the original package's pkgrel was 4, then increment it once when you add a security patch, but then use 5wanda1, 5wanda2 and so on. This way @@ -68,9 +68,9 @@ current one. If the dependency is runtime-only, then use rodepends(), if buildtime-only then use makedepends(). The next line is a special Finclude commands which allows you to inherit -any directive from a FrugalBuild scheme. They can be found in the FST, +any directive from a PKGBUILD scheme. They can be found in the FST, under /source/include. The "util" scheme always included, since its -provided functions are used by almost every FrugalBuild. Look at the +provided functions are used by almost every PKGBUILD. Look at the /source/include/sourceforge.sh, it provides the url, up2date and source() directives, so we don't have to specify them here. After the Finclude you can overwrite the inherited directives, for example define a custom up2date @@ -93,7 +93,7 @@ is to prevent compiling from wrong sources, especially when the build is automatic. Where it is available you can use signatures(), its goal is that you don't have to update it manually every time. -The last line will be added automatically to the end of the FrugalBuild if the +The last line will be added automatically to the end of the PKGBUILD if the build() function used your $CFLAGS or $CXXFLAGS. This is handy if you want to cross-compile on a faster machine for a slower architecture. Until the package doesn't use our $CFLAGS we can't cross-compile it, so please try to avoid @@ -150,7 +150,7 @@ script is run right after files are removed. .RE To use this feature, just create a file (eg, pkgname.install) and put it in -the same directory as the FrugalBuild script. Then use the \fIinstall\fP directive: +the same directory as the PKGBUILD script. Then use the \fIinstall\fP directive: .RS .nf install=pkgname.install @@ -176,7 +176,7 @@ post_upgrade() } .fi -.SH FrugalBuild Directives +.SH PKGBUILD Directives .TP .B pkgname The name of the package. This has be a unix-friendly name as it will be @@ -188,7 +188,7 @@ This is the version of the software as released from the author (eg, 2.7.1). .TP .B pkgrel -This is the release number specific to Frugalware Linux packages. +This is the release number specific to Archlinux Linux packages. .TP .B pkgdesc @@ -214,7 +214,7 @@ option is still in development and may change in the future) .TP .B install Specifies a special install script that is to be included in the package. -This file should reside in the same directory as the FrugalBuild, and will be +This file should reside in the same directory as the PKGBUILD, and will be copied into the package by makepkg. It does not need to be included in the \fIsource\fP array. (eg, install=modutils.install) @@ -227,7 +227,7 @@ manually the project's website (see above). .TP .B source \fI(array)\fP The \fIsource\fP line is an array of source files required to build the -package. Source files must reside in the same directory as the FrugalBuild +package. Source files must reside in the same directory as the PKGBUILD file, unless they have a fully-qualified URL. Then if the source file does not already exist in /var/cache/pacman/src, the file is downloaded by wget. @@ -237,8 +237,8 @@ by wget. If this field is present, it should contain an MD5 hash for every source file specified in the \fIsource\fP array (in the same order). makepkg will use this to verify source file integrity during subsequent builds. To easily -generate md5sums, first build using the FrugalBuild then run -\fBmakepkg -G >>FrugalBuild\fP. Then you can edit the FrugalBuild and move the +generate md5sums, first build using the PKGBUILD then run +\fBmakepkg -G >>PKGBUILD\fP. Then you can edit the PKGBUILD and move the \fImd5sums\fP line from the bottom to an appropriate location. .TP @@ -246,8 +246,8 @@ generate md5sums, first build using the FrugalBuild then run If this field is present, it should contain an SHA1 hash for every source file specified in the \fIsource\fP array (in the same order). makepkg will use this to verify source file integrity during subsequent builds. To easily -generate sha1sums, first build using the FrugalBuild then run -\fBmakepkg -g >>FrugalBuild\fP. Then you can edit the FrugalBuild and move the +generate sha1sums, first build using the PKGBUILD then run +\fBmakepkg -g >>PKGBUILD\fP. Then you can edit the PKGBUILD and move the \fIsha1sums\fP line from the bottom to an appropriate location. .TP @@ -285,7 +285,7 @@ in this list should be surrounded with single quotes and contain at least the package name. They can also include a version requirement of the form \fBname<>version\fP, where <> is one of these three comparisons: \fB>=\fP (greater than equal to), \fB<=\fP (less than or equal to), or \fB=\fP (equal to). -See the FrugalBuild example above for an example of the \fIdepends\fP directive. +See the PKGBUILD example above for an example of the \fIdepends\fP directive. .TP .B makedepends \fI(array)\fP @@ -365,7 +365,7 @@ devel-core' should show you the actial list. (We try to change this list rarely of course.) When you start building with makepkg -R, pacman will install these packages to -/var/chroot if necessary. This will produce a fully "clean" Frugalware system, +/var/chroot if necessary. This will produce a fully "clean" Archlinux system, that consits of base packages only. This /var/chroot is fully separated from the host system so that this will solve the problems mentioned above. (Linking to a library installed from source, etc.) @@ -380,7 +380,7 @@ installed depends() and makedepends(). This ensures us not to build from scratch the core chroot. This way we can prevent lots of dependency problems and it is even possible to -build packages for a different Frugalware version. This is quite efficent when +build packages for a different Archlinux version. This is quite efficent when building security updates or fixing critical bugs in the -stable tree. If the build is failed, the working directory will not be deleted, you can find @@ -425,7 +425,7 @@ array of arrays, then quotes are the major separators and spaces are the minor o Simple example: .nf -Add the followings to your bottom of your FrugalBuild +Add the followings to your bottom of your PKGBUILD subpkgs=('foo' 'bar') subdescs=('desc of foo' 'desc of bar') subdepends=('foodep1 foodep2' 'bardep1 bardep2') diff --git a/doc/hu/Makefile.am b/doc/hu/Makefile.am index 27e74e45..80ebba62 100644 --- a/doc/hu/Makefile.am +++ b/doc/hu/Makefile.am @@ -2,7 +2,6 @@ AUTOMAKE_OPTIONS=foreign mandir = @mandir@/hu man_MANS = pacman.8 makepkg.8 PKGBUILD.8 - $(man_MANS): EXTRA_DIST = pacman.8 makepkg.8 PKGBUILD.8 diff --git a/doc/po/hu.po b/doc/po/hu.po index 76cc35a3..dec8ec25 100644 --- a/doc/po/hu.po +++ b/doc/po/hu.po @@ -5,7 +5,7 @@ msgid "" msgstr "" "Project-Id-Version: pacman\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2006-10-30 8:14-0600\n" +"POT-Creation-Date: 2006-11-14 13:52-0600\n" "PO-Revision-Date: 2006-08-26 14:53+0200\n" "Last-Translator: Hungarian <frugalware-devel@frugalware.org>\n" "Language-Team: Hungarian <frugalware-devel@frugalware.org>\n" @@ -1012,7 +1012,7 @@ msgid "" msgstr "" # type: SH -#: makepkg.8:30 +#: makepkg.8:30 PKGBUILD.8:11 #, no-wrap msgid "PKGBUILD Example:" msgstr "" @@ -1248,7 +1248,7 @@ msgid "script is run right after files are removed." msgstr "" # type: Plain text -#: makepkg.8:149 +#: makepkg.8:149 PKGBUILD.8:154 msgid "" "To use this feature, just create a file (eg, pkgname.install) and put it in " "the same directory as the PKGBUILD script. Then use the I<install> " @@ -1369,7 +1369,7 @@ msgid "" msgstr "" # type: SH -#: makepkg.8:220 +#: makepkg.8:220 PKGBUILD.8:179 #, no-wrap msgid "PKGBUILD Directives" msgstr "" @@ -1522,7 +1522,7 @@ msgid "B<install>" msgstr "" # type: Plain text -#: makepkg.8:285 +#: makepkg.8:285 PKGBUILD.8:220 msgid "" "Specifies a special install script that is to be included in the package. " "This file should reside in the same directory as the PKGBUILD, and will be " @@ -1537,7 +1537,7 @@ msgid "B<source >I<(array)>" msgstr "" # type: Plain text -#: makepkg.8:293 +#: makepkg.8:293 PKGBUILD.8:234 msgid "" "The I<source> line is an array of source files required to build the " "package. Source files must reside in the same directory as the PKGBUILD " @@ -1600,7 +1600,7 @@ msgid "B<depends >I<(array)>" msgstr "" # type: Plain text -#: makepkg.8:325 +#: makepkg.8:325 PKGBUILD.8:289 msgid "" "An array of packages that this package depends on to build and run. " "Packages in this list should be surrounded with single quotes and contain at " @@ -1938,11 +1938,11 @@ msgid "" "to contribute packages to the Arch Linux project." msgstr "" -# type: SH +# type: TH #: PKGBUILD.8:1 -#, fuzzy, no-wrap -msgid "FrugalBuild" -msgstr "FrugalBuild példa:" +#, no-wrap +msgid "PKGBUILD" +msgstr "" # type: TH #: PKGBUILD.8:1 @@ -1952,29 +1952,23 @@ msgstr "2006. június 13." # type: TH #: PKGBUILD.8:1 -#, no-wrap -msgid "Frugalware Developer Manual" +#, fuzzy, no-wrap +msgid "Archlinux Developer Manual" msgstr "Frugalware Fejlesztői Kézikönyv" # type: Plain text #: PKGBUILD.8:4 -msgid "FrugalBuild - Frugalware package builder descriptor" +msgid "PKGBUILD - Archlinux package builder descriptor" msgstr "" # type: Plain text #: PKGBUILD.8:8 msgid "" -"This manual page is meant to describe general rules about FrugalBuilds. If " +"This manual page is meant to describe general rules about PKGBUILDs. If " "you're interested in the package builder B<makepkg> itself, then see its " "manual page, not this one." msgstr "" -# type: SH -#: PKGBUILD.8:11 -#, no-wrap -msgid "FrugalBuild Example:" -msgstr "FrugalBuild példa:" - # type: Plain text #: PKGBUILD.8:17 #, no-wrap @@ -2047,8 +2041,8 @@ msgstr "" msgid "" "If you wish to maintain the package, write your name or nick and e-mail " "address to the third line. If you don't plan to maintain the package just " -"wrote the FrugalBuild, then write Contributor instead of Maintainer, and " -"then someone can take it and will add his/her line later. Other lines like " +"wrote the PKGBUILD, then write Contributor instead of Maintainer, and then " +"someone can take it and will add his/her line later. Other lines like " "\"Modified by\" are not allowed. Use the darcs patch comments to mention " "others if you wish." msgstr "" @@ -2058,7 +2052,7 @@ msgstr "" msgid "" "pkgname defines the package name. It should not contain any uppercase " "letters. The package version defines the upstream version, while the " -"package release tracks the Frugalware-specific changes. pkgrel should be an " +"package release tracks the Archlinux-specific changes. pkgrel should be an " "integer, pkgrels like 5wanda1 are reserved for security updates. There the " "rule is the following: If the original package's pkgrel was 4, then " "increment it once when you add a security patch, but then use 5wanda1, " @@ -2086,9 +2080,9 @@ msgstr "" #: PKGBUILD.8:78 msgid "" "The next line is a special Finclude commands which allows you to inherit any " -"directive from a FrugalBuild scheme. They can be found in the FST, under /" +"directive from a PKGBUILD scheme. They can be found in the FST, under /" "source/include. The \"util\" scheme always included, since its provided " -"functions are used by almost every FrugalBuild. Look at the /source/include/" +"functions are used by almost every PKGBUILD. Look at the /source/include/" "sourceforge.sh, it provides the url, up2date and source() directives, so we " "don't have to specify them here. After the Finclude you can overwrite the " "inherited directives, for example define a custom up2date if the inherited " @@ -2128,13 +2122,13 @@ msgstr "" # type: Plain text #: PKGBUILD.8:103 msgid "" -"The last line will be added automatically to the end of the FrugalBuild if " -"the build() function used your $CFLAGS or $CXXFLAGS. This is handy if you " -"want to cross-compile on a faster machine for a slower architecture. Until " -"the package doesn't use our $CFLAGS we can't cross-compile it, so please try " -"to avoid creating \"unoptimized\" packages. If the package doesn't contain " -"any architecture-dependent file, then you can add this line manually as " -"makepkg will not detect this." +"The last line will be added automatically to the end of the PKGBUILD if the " +"build() function used your $CFLAGS or $CXXFLAGS. This is handy if you want " +"to cross-compile on a faster machine for a slower architecture. Until the " +"package doesn't use our $CFLAGS we can't cross-compile it, so please try to " +"avoid creating \"unoptimized\" packages. If the package doesn't contain any " +"architecture-dependent file, then you can add this line manually as makepkg " +"will not detect this." msgstr "" # type: Plain text @@ -2167,14 +2161,6 @@ msgid "" msgstr "" # type: Plain text -#: PKGBUILD.8:154 -msgid "" -"To use this feature, just create a file (eg, pkgname.install) and put it in " -"the same directory as the FrugalBuild script. Then use the I<install> " -"directive:" -msgstr "" - -# type: Plain text #: PKGBUILD.8:163 msgid "" "The install script does not need to be specified in the I<source> array. If " @@ -2209,15 +2195,9 @@ msgid "" "}\n" msgstr "" -# type: SH -#: PKGBUILD.8:179 -#, no-wrap -msgid "FrugalBuild Directives" -msgstr "" - # type: Plain text #: PKGBUILD.8:192 -msgid "This is the release number specific to Frugalware Linux packages." +msgid "This is the release number specific to Archlinux Linux packages." msgstr "" # type: TP @@ -2244,15 +2224,6 @@ msgid "" "option is still in development and may change in the future)" msgstr "" -# type: Plain text -#: PKGBUILD.8:220 -msgid "" -"Specifies a special install script that is to be included in the package. " -"This file should reside in the same directory as the FrugalBuild, and will " -"be copied into the package by makepkg. It does not need to be included in " -"the I<source> array. (eg, install=modutils.install)" -msgstr "" - # type: TP #: PKGBUILD.8:221 #, no-wrap @@ -2268,23 +2239,14 @@ msgid "" msgstr "" # type: Plain text -#: PKGBUILD.8:234 -msgid "" -"The I<source> line is an array of source files required to build the " -"package. Source files must reside in the same directory as the FrugalBuild " -"file, unless they have a fully-qualified URL. Then if the source file does " -"not already exist in /var/cache/pacman/src, the file is downloaded by wget." -msgstr "" - -# type: Plain text #: PKGBUILD.8:243 msgid "" "If this field is present, it should contain an MD5 hash for every source " "file specified in the I<source> array (in the same order). makepkg will use " "this to verify source file integrity during subsequent builds. To easily " -"generate md5sums, first build using the FrugalBuild then run B<makepkg -G " -"E<gt>E<gt>FrugalBuild>. Then you can edit the FrugalBuild and move the " -"I<md5sums> line from the bottom to an appropriate location." +"generate md5sums, first build using the PKGBUILD then run B<makepkg -G " +"E<gt>E<gt>PKGBUILD>. Then you can edit the PKGBUILD and move the I<md5sums> " +"line from the bottom to an appropriate location." msgstr "" # type: TP @@ -2299,8 +2261,8 @@ msgid "" "If this field is present, it should contain an SHA1 hash for every source " "file specified in the I<source> array (in the same order). makepkg will use " "this to verify source file integrity during subsequent builds. To easily " -"generate sha1sums, first build using the FrugalBuild then run B<makepkg -g " -"E<gt>E<gt>FrugalBuild>. Then you can edit the FrugalBuild and move the " +"generate sha1sums, first build using the PKGBUILD then run B<makepkg -g " +"E<gt>E<gt>PKGBUILD>. Then you can edit the PKGBUILD and move the " "I<sha1sums> line from the bottom to an appropriate location." msgstr "" @@ -2337,18 +2299,6 @@ msgid "" "generating package databases." msgstr "" -# type: Plain text -#: PKGBUILD.8:289 -msgid "" -"An array of packages that this package depends on to build and run. " -"Packages in this list should be surrounded with single quotes and contain at " -"least the package name. They can also include a version requirement of the " -"form B<nameE<lt>E<gt>version>, where E<lt>E<gt> is one of these three " -"comparisons: B<E<gt>=> (greater than equal to), B<E<lt>=> (less than or " -"equal to), or B<=> (equal to). See the FrugalBuild example above for an " -"example of the I<depends> directive." -msgstr "" - # type: TP #: PKGBUILD.8:295 #, no-wrap @@ -2445,7 +2395,7 @@ msgstr "" #: PKGBUILD.8:372 msgid "" "When you start building with makepkg -R, pacman will install these packages " -"to /var/chroot if necessary. This will produce a fully \"clean\" Frugalware " +"to /var/chroot if necessary. This will produce a fully \"clean\" Archlinux " "system, that consits of base packages only. This /var/chroot is fully " "separated from the host system so that this will solve the problems " "mentioned above. (Linking to a library installed from source, etc.)" @@ -2472,7 +2422,7 @@ msgstr "" #: PKGBUILD.8:385 msgid "" "This way we can prevent lots of dependency problems and it is even possible " -"to build packages for a different Frugalware version. This is quite efficent " +"to build packages for a different Archlinux version. This is quite efficent " "when building security updates or fixing critical bugs in the -stable tree." msgstr "" @@ -2559,7 +2509,7 @@ msgstr "" #: PKGBUILD.8:434 #, no-wrap msgid "" -"Add the followings to your bottom of your FrugalBuild\n" +"Add the followings to your bottom of your PKGBUILD\n" "subpkgs=('foo' 'bar')\n" "subdescs=('desc of foo' 'desc of bar')\n" "subdepends=('foodep1 foodep2' 'bardep1 bardep2')\n" @@ -2616,6 +2566,15 @@ msgid "" "and the Frugalware developers E<lt>frugalware-devel@frugalware.orgE<gt>\n" msgstr "" +# type: SH +#, fuzzy +#~ msgid "FrugalBuild" +#~ msgstr "FrugalBuild példa:" + +# type: SH +#~ msgid "FrugalBuild Example:" +#~ msgstr "FrugalBuild példa:" + # type: TH #~ msgid "Frugalware User Manual" #~ msgstr "Frugalware Felhasználói Kézikönyv" diff --git a/doc/po/pacman.pot b/doc/po/pacman.pot index 77c852fa..4f003b12 100644 --- a/doc/po/pacman.pot +++ b/doc/po/pacman.pot @@ -6,7 +6,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" -"POT-Creation-Date: 2006-10-30 8:14-0600\n" +"POT-Creation-Date: 2006-11-14 13:52-0600\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -1013,7 +1013,7 @@ msgid "" msgstr "" # type: SH -#: makepkg.8:30 +#: makepkg.8:30 PKGBUILD.8:11 #, no-wrap msgid "PKGBUILD Example:" msgstr "" @@ -1242,7 +1242,7 @@ msgid "script is run right after files are removed." msgstr "" # type: Plain text -#: makepkg.8:149 +#: makepkg.8:149 PKGBUILD.8:154 msgid "" "To use this feature, just create a file (eg, pkgname.install) and put it in " "the same directory as the PKGBUILD script. Then use the I<install> " @@ -1361,7 +1361,7 @@ msgid "This template is also available in your ABS tree (/var/abs/install.proto) msgstr "" # type: SH -#: makepkg.8:220 +#: makepkg.8:220 PKGBUILD.8:179 #, no-wrap msgid "PKGBUILD Directives" msgstr "" @@ -1513,7 +1513,7 @@ msgid "B<install>" msgstr "" # type: Plain text -#: makepkg.8:285 +#: makepkg.8:285 PKGBUILD.8:220 msgid "" "Specifies a special install script that is to be included in the package. " "This file should reside in the same directory as the PKGBUILD, and will be " @@ -1528,7 +1528,7 @@ msgid "B<source >I<(array)>" msgstr "" # type: Plain text -#: makepkg.8:293 +#: makepkg.8:293 PKGBUILD.8:234 msgid "" "The I<source> line is an array of source files required to build the " "package. Source files must reside in the same directory as the PKGBUILD " @@ -1591,7 +1591,7 @@ msgid "B<depends >I<(array)>" msgstr "" # type: Plain text -#: makepkg.8:325 +#: makepkg.8:325 PKGBUILD.8:289 msgid "" "An array of packages that this package depends on to build and run. " "Packages in this list should be surrounded with single quotes and contain at " @@ -1932,7 +1932,7 @@ msgstr "" # type: TH #: PKGBUILD.8:1 #, no-wrap -msgid "FrugalBuild" +msgid "PKGBUILD" msgstr "" # type: TH @@ -1944,28 +1944,22 @@ msgstr "" # type: TH #: PKGBUILD.8:1 #, no-wrap -msgid "Frugalware Developer Manual" +msgid "Archlinux Developer Manual" msgstr "" # type: Plain text #: PKGBUILD.8:4 -msgid "FrugalBuild - Frugalware package builder descriptor" +msgid "PKGBUILD - Archlinux package builder descriptor" msgstr "" # type: Plain text #: PKGBUILD.8:8 msgid "" -"This manual page is meant to describe general rules about FrugalBuilds. If " +"This manual page is meant to describe general rules about PKGBUILDs. If " "you're interested in the package builder B<makepkg> itself, then see its " "manual page, not this one." msgstr "" -# type: SH -#: PKGBUILD.8:11 -#, no-wrap -msgid "FrugalBuild Example:" -msgstr "" - # type: Plain text #: PKGBUILD.8:17 #, no-wrap @@ -2038,8 +2032,8 @@ msgstr "" msgid "" "If you wish to maintain the package, write your name or nick and e-mail " "address to the third line. If you don't plan to maintain the package just " -"wrote the FrugalBuild, then write Contributor instead of Maintainer, and " -"then someone can take it and will add his/her line later. Other lines like " +"wrote the PKGBUILD, then write Contributor instead of Maintainer, and then " +"someone can take it and will add his/her line later. Other lines like " "\"Modified by\" are not allowed. Use the darcs patch comments to mention " "others if you wish." msgstr "" @@ -2049,7 +2043,7 @@ msgstr "" msgid "" "pkgname defines the package name. It should not contain any uppercase " "letters. The package version defines the upstream version, while the " -"package release tracks the Frugalware-specific changes. pkgrel should be an " +"package release tracks the Archlinux-specific changes. pkgrel should be an " "integer, pkgrels like 5wanda1 are reserved for security updates. There the " "rule is the following: If the original package's pkgrel was 4, then " "increment it once when you add a security patch, but then use 5wanda1, " @@ -2077,9 +2071,9 @@ msgstr "" #: PKGBUILD.8:78 msgid "" "The next line is a special Finclude commands which allows you to inherit any " -"directive from a FrugalBuild scheme. They can be found in the FST, under " +"directive from a PKGBUILD scheme. They can be found in the FST, under " "/source/include. The \"util\" scheme always included, since its provided " -"functions are used by almost every FrugalBuild. Look at the " +"functions are used by almost every PKGBUILD. Look at the " "/source/include/sourceforge.sh, it provides the url, up2date and source() " "directives, so we don't have to specify them here. After the Finclude you " "can overwrite the inherited directives, for example define a custom up2date " @@ -2119,13 +2113,13 @@ msgstr "" # type: Plain text #: PKGBUILD.8:103 msgid "" -"The last line will be added automatically to the end of the FrugalBuild if " -"the build() function used your $CFLAGS or $CXXFLAGS. This is handy if you " -"want to cross-compile on a faster machine for a slower architecture. Until " -"the package doesn't use our $CFLAGS we can't cross-compile it, so please try " -"to avoid creating \"unoptimized\" packages. If the package doesn't contain " -"any architecture-dependent file, then you can add this line manually as " -"makepkg will not detect this." +"The last line will be added automatically to the end of the PKGBUILD if the " +"build() function used your $CFLAGS or $CXXFLAGS. This is handy if you want " +"to cross-compile on a faster machine for a slower architecture. Until the " +"package doesn't use our $CFLAGS we can't cross-compile it, so please try to " +"avoid creating \"unoptimized\" packages. If the package doesn't contain any " +"architecture-dependent file, then you can add this line manually as makepkg " +"will not detect this." msgstr "" # type: Plain text @@ -2158,14 +2152,6 @@ msgid "" msgstr "" # type: Plain text -#: PKGBUILD.8:154 -msgid "" -"To use this feature, just create a file (eg, pkgname.install) and put it in " -"the same directory as the FrugalBuild script. Then use the I<install> " -"directive:" -msgstr "" - -# type: Plain text #: PKGBUILD.8:163 msgid "" "The install script does not need to be specified in the I<source> array. If " @@ -2199,15 +2185,9 @@ msgid "" "}\n" msgstr "" -# type: SH -#: PKGBUILD.8:179 -#, no-wrap -msgid "FrugalBuild Directives" -msgstr "" - # type: Plain text #: PKGBUILD.8:192 -msgid "This is the release number specific to Frugalware Linux packages." +msgid "This is the release number specific to Archlinux Linux packages." msgstr "" # type: TP @@ -2233,15 +2213,6 @@ msgid "" "option is still in development and may change in the future)" msgstr "" -# type: Plain text -#: PKGBUILD.8:220 -msgid "" -"Specifies a special install script that is to be included in the package. " -"This file should reside in the same directory as the FrugalBuild, and will " -"be copied into the package by makepkg. It does not need to be included in " -"the I<source> array. (eg, install=modutils.install)" -msgstr "" - # type: TP #: PKGBUILD.8:221 #, no-wrap @@ -2257,23 +2228,14 @@ msgid "" msgstr "" # type: Plain text -#: PKGBUILD.8:234 -msgid "" -"The I<source> line is an array of source files required to build the " -"package. Source files must reside in the same directory as the FrugalBuild " -"file, unless they have a fully-qualified URL. Then if the source file does " -"not already exist in /var/cache/pacman/src, the file is downloaded by wget." -msgstr "" - -# type: Plain text #: PKGBUILD.8:243 msgid "" "If this field is present, it should contain an MD5 hash for every source " "file specified in the I<source> array (in the same order). makepkg will use " "this to verify source file integrity during subsequent builds. To easily " -"generate md5sums, first build using the FrugalBuild then run B<makepkg -G " -"E<gt>E<gt>FrugalBuild>. Then you can edit the FrugalBuild and move the " -"I<md5sums> line from the bottom to an appropriate location." +"generate md5sums, first build using the PKGBUILD then run B<makepkg -G " +"E<gt>E<gt>PKGBUILD>. Then you can edit the PKGBUILD and move the I<md5sums> " +"line from the bottom to an appropriate location." msgstr "" # type: TP @@ -2288,8 +2250,8 @@ msgid "" "If this field is present, it should contain an SHA1 hash for every source " "file specified in the I<source> array (in the same order). makepkg will use " "this to verify source file integrity during subsequent builds. To easily " -"generate sha1sums, first build using the FrugalBuild then run B<makepkg -g " -"E<gt>E<gt>FrugalBuild>. Then you can edit the FrugalBuild and move the " +"generate sha1sums, first build using the PKGBUILD then run B<makepkg -g " +"E<gt>E<gt>PKGBUILD>. Then you can edit the PKGBUILD and move the " "I<sha1sums> line from the bottom to an appropriate location." msgstr "" @@ -2326,18 +2288,6 @@ msgid "" "generating package databases." msgstr "" -# type: Plain text -#: PKGBUILD.8:289 -msgid "" -"An array of packages that this package depends on to build and run. " -"Packages in this list should be surrounded with single quotes and contain at " -"least the package name. They can also include a version requirement of the " -"form B<nameE<lt>E<gt>version>, where E<lt>E<gt> is one of these three " -"comparisons: B<E<gt>=> (greater than equal to), B<E<lt>=> (less than or " -"equal to), or B<=> (equal to). See the FrugalBuild example above for an " -"example of the I<depends> directive." -msgstr "" - # type: TP #: PKGBUILD.8:295 #, no-wrap @@ -2437,7 +2387,7 @@ msgstr "" #: PKGBUILD.8:372 msgid "" "When you start building with makepkg -R, pacman will install these packages " -"to /var/chroot if necessary. This will produce a fully \"clean\" Frugalware " +"to /var/chroot if necessary. This will produce a fully \"clean\" Archlinux " "system, that consits of base packages only. This /var/chroot is fully " "separated from the host system so that this will solve the problems " "mentioned above. (Linking to a library installed from source, etc.)" @@ -2464,7 +2414,7 @@ msgstr "" #: PKGBUILD.8:385 msgid "" "This way we can prevent lots of dependency problems and it is even possible " -"to build packages for a different Frugalware version. This is quite efficent " +"to build packages for a different Archlinux version. This is quite efficent " "when building security updates or fixing critical bugs in the -stable tree." msgstr "" @@ -2552,7 +2502,7 @@ msgstr "" #: PKGBUILD.8:434 #, no-wrap msgid "" -"Add the followings to your bottom of your FrugalBuild\n" +"Add the followings to your bottom of your PKGBUILD\n" "subpkgs=('foo' 'bar')\n" "subdescs=('desc of foo' 'desc of bar')\n" "subdepends=('foodep1 foodep2' 'bardep1 bardep2')\n" diff --git a/etc/makepkg.conf.in b/etc/makepkg.conf.in index 9b0dc96b..7a75cdf3 100644 --- a/etc/makepkg.conf.in +++ b/etc/makepkg.conf.in @@ -1,64 +1,71 @@ -# +# vim: set ft=sh ts=2 sw=2 et: # /etc/makepkg.conf # -# The FTP/HTTP download utility that makepkg should use to acquire sources -export FTPAGENT="/usr/bin/wget -U makepkg --continue --passive-ftp --tries=3 --waitretry=3 --no-check-certificate" -#export FTPAGENT="/usr/bin/snarf" -#export FTPAGENT="/usr/bin/lftpget -c" - -export CARCH="@CARCH@" -export CHOST="@CHOST@" - -# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon exclusive (binaries -# will use the P6 instruction set and only run on P6+ systems) -export CFLAGS="-@MARCHFLAG@=@CARCHFLAGS@ -O2 -pipe" -export CXXFLAGS="-@MARCHFLAG@=@CARCHFLAGS@ -O2 -pipe" -# Pentium Pro/Pentium II/Pentium III+/Pentium 4/Athlon optimized (but binaries -# will run on any x86 system) -#export CFLAGS="-mcpu=i686 -O2 -pipe" -#export CXXFLAGS="-mcpu=i686 -O2 -pipe" - -# SMP Systems -#export MAKEFLAGS="-j2" - -# Enable fakeroot for building packages as a non-root user -export USE_FAKEROOT="y" - -# Specify a directory for the chroot environment. -export CHROOTDIR="/var/chroot" -# Core package list to be installed in the chroot. -export COREPKGS="core chroot-core devel-core" +######################################################################### +# SOURCE ACQUISITION +######################################################################### +# +#-- The FTP/HTTP download utility that makepkg should use to acquire sources +FTPAGENT="/usr/bin/wget --continue --passive-ftp --tries=3 --waitretry=3 --no-check-certificate" +#FTPAGENT="/usr/bin/snarf" +#FTPAGENT="/usr/bin/lftpget -c" -# Enable distributed C/C++/ObjC compiler -# Don't forget to modify MAKEFLAGS to include -jN, where N is twice the -# number of CPUs +1 available -export DISTCC="n" -# Space-separated list of volunteer host specifications. -export DISTCC_HOSTS="" +######################################################################### +# ARCHITECTURE, COMPILE FLAGS +######################################################################### +# +CARCH="@CARCH@" +CHOST="@CHOST@" -# Enable colorized output messages -export USE_COLOR="y" +#-- Exclusive: will only run on i686 or higher (P6, Athlon) +CFLAGS="-@MARCHFLAG@=@CARCHFLAGS@ -O2 -pipe" +CXXFLAGS="-@MARCHFLAG@=@CARCHFLAGS@ -O2 -pipe" +#-- Optimized: will run on any x86, but optimized for i686 +#CFLAGS="-mcpu=i686 -O2 -pipe" +#CXXFLAGS="-mcpu=i686 -O2 -pipe" +#-- Make Flags: change this for DistCC/SMP systems +#MAKEFLAGS="-j2" -# Specify a fixed directory where all packages will be placed -#export PKGDEST=/home/packages +######################################################################### +# BUILD ENVIRONMENT +######################################################################### +# +#-- Fakeroot: for building packages as a non-root user +USE_FAKEROOT="y" +#-- DistCC: a distributed C/C++/ObjC compiler (modify MAKEFLAGS too) +DISTCC="n" +#-- A space-delimited list of hosts running in the DistCC cluster +DISTCC_HOSTS="" +#-- Colorized output messages +USE_COLOR="y" -# If you want your name to show up in the packages you build, change this. -export PACKAGER="Archlinux (http://archlinux.org)" +######################################################################### +# GLOBAL PACKAGE OPTIONS +######################################################################### +# +#-- Don't strip symbols from binaries/libraries +NOSTRIP=0 +#-- Keep doc and info directories +KEEPDOCS=0 -# Don't strip symbols from binaries/libraries -#export NOSTRIP="1" -# Don't prepare documentation -#export NODOCS="1" +######################################################################### +# PACKAGE OUTPUT +######################################################################### +# +#-- Destination: specify a fixed directory where all packages will be placed +#PKGDEST=/home/packages +#-- Packager: name/email of the person or organization building packages +#PACKAGER="John Doe <john@doe.com>" -# LOGDIR is the location where you would like to store a -# permanant copy of the build log. -# filename = [LOGDIR_APPEND]-[pkgname]-[pkgver]-[pkgrel] -LOGDIR_APPEND=`date +%Y-%m-%d-%s` -LOGDIR=/var/log/builds +######################################################################### +# Functionality Configuration +# Most of this will probably not need to be changed by and end user +######################################################################### +# +BUILDSCRIPT="PKGBUILD" +PKGEXT="pkg.tar.gz" +INTEGRITY_CHECK="sha1" -# The Standard Build Unit of this machine -# If 1, then the build time will be displayed in seconds -# Build the "binutils" package, and then write here the result you got, -# so that makepkg will could the right SBU value for you. -SBU="1" +source "/etc/abs/abs.conf" +SRCROOT=$ABSROOT diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index 9bee7b59..dbdc24db 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -1,6 +1,6 @@ AUTOMAKE_OPTIONS = gnu DEFINES = -pedantic -D_GNU_SOURCE -AM_CFLAGS = $(DEFINES) -I$(top_srcdir)/lib/libfetch +AM_CFLAGS = $(DEFINES) SUBDIRS = po localedir = $(datadir)/locale @@ -37,8 +37,8 @@ include_HEADERS = alpm.h libalpm_la_SOURCES = $(TARGETS) -libalpm_la_LDFLAGS = -no-undefined -version-info $(PM_VERSION_INFO) -L$(top_srcdir)/lib/libfetch -libalpm_la_LIBADD = -lfetch +libalpm_la_LDFLAGS = -no-undefined -version-info $(PM_VERSION_INFO) +libalpm_la_LIBADD = -ldownload if HAS_DOXYGEN all: doxygen.in diff --git a/lib/libalpm/add.c b/lib/libalpm/add.c index 16cb13a5..4ccac537 100644 --- a/lib/libalpm/add.c +++ b/lib/libalpm/add.c @@ -129,7 +129,7 @@ int _alpm_add_loadtarget(pmtrans_t *trans, pmdb_t *db, char *name) goto error; } - if(_alpm_pkg_splitname(name, pkgname, pkgver) == -1) { + if(_alpm_pkg_splitname(name, pkgname, pkgver, 1) == -1) { pm_errno = PM_ERR_PKG_INVALID_NAME; goto error; } diff --git a/lib/libalpm/alpm.c b/lib/libalpm/alpm.c index 37db1394..77f3632e 100644 --- a/lib/libalpm/alpm.c +++ b/lib/libalpm/alpm.c @@ -346,9 +346,9 @@ int alpm_db_update(int force, PM_DB *db) pm_errno = 0; return(1); } else if(ret == -1) { - /* we use fetchLastErrString and fetchLastErrCode here, error returns from - * libfetch */ - _alpm_log(PM_LOG_DEBUG, _("failed to sync db: %s [%d]"), fetchLastErrString, fetchLastErrCode); + /* we use downloadLastErrString and downloadLastErrCode here, error returns from + * libdownload */ + _alpm_log(PM_LOG_DEBUG, _("failed to sync db: %s [%d]"), downloadLastErrString, downloadLastErrCode); RET_ERR(PM_ERR_DB_SYNC, -1); } else { if(strlen(newmtime)) { @@ -1109,6 +1109,19 @@ int alpm_list_free(pmlist_t *entry) return(0); } +/** Free the outer list, but not the contained data + * @param entry list to free + * @return 0 on success, -1 on error + */ +int alpm_list_free_outer(pmlist_t *entry) +{ + ASSERT(entry != NULL, return(-1)); + + _FREELIST(entry, NULL); + + return(0); +} + /** Count the entries in a list. * @param list the list to count * @return number of entries on success, NULL on error diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index af0dbc31..155d09ad 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h @@ -72,7 +72,7 @@ int alpm_release(void); #define PM_LOG_FLOW1 0x08 #define PM_LOG_FLOW2 0x10 #define PM_LOG_FUNCTION 0x20 -#define PM_LOG_FETCH 0x40 +#define PM_LOG_DOWNLOAD 0x40 int alpm_logaction(char *fmt, ...); @@ -390,6 +390,7 @@ PM_LIST *alpm_list_first(PM_LIST *list); PM_LIST *alpm_list_next(PM_LIST *entry); void *alpm_list_getdata(PM_LIST *entry); int alpm_list_free(PM_LIST *entry); +int alpm_list_free_outer(PM_LIST *entry); int alpm_list_count(PM_LIST *list); /* md5sums */ diff --git a/lib/libalpm/be_files.c b/lib/libalpm/be_files.c index 563f3216..8f81235f 100644 --- a/lib/libalpm/be_files.c +++ b/lib/libalpm/be_files.c @@ -163,7 +163,7 @@ pmpkg_t *_alpm_db_scan(pmdb_t *db, char *target, unsigned int inforeq) if(pkg == NULL) { return(NULL); } - if(_alpm_pkg_splitname(ent->d_name, pkg->name, pkg->version) == -1) { + if(_alpm_pkg_splitname(ent->d_name, pkg->name, pkg->version, 0) == -1) { _alpm_log(PM_LOG_ERROR, _("invalid name for dabatase entry '%s'"), ent->d_name); return(NULL); } @@ -180,9 +180,8 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info) struct stat buf; char path[PATH_MAX+1]; char line[513]; - char *lang_tmp; pmlist_t *tmplist; - char *foo; + char *locale; if(db == NULL) { RET_ERR(PM_ERR_DB_NULL, -1); @@ -225,30 +224,26 @@ int _alpm_db_read(pmdb_t *db, unsigned int inforeq, pmpkg_t *info) info->desc_localized = _alpm_list_add(info->desc_localized, strdup(line)); } - if (setlocale(LC_ALL, "") == NULL) { /* To fix segfault when locale invalid */ + if((locale = setlocale(LC_ALL, "")) == NULL) { /* To fix segfault when locale invalid */ setenv("LC_ALL", "C", 1); + locale = setlocale(LC_ALL, ""); } - if((lang_tmp = (char *)malloc(strlen(setlocale(LC_ALL, "")))) == NULL) { - RET_ERR(PM_ERR_MEMORY, -1); - } - snprintf(lang_tmp, strlen(setlocale(LC_ALL, "")), "%s", setlocale(LC_ALL, "")); if(info->desc_localized && !info->desc_localized->next) { snprintf(info->desc, 512, "%s", (char*)info->desc_localized->data); } else { - for (tmplist = info->desc_localized; tmplist; tmplist = tmplist->next) { - if (tmplist->data && strncmp(tmplist->data, lang_tmp, strlen(lang_tmp))) { - snprintf(info->desc, 512, "%s", (char*)info->desc_localized->data); - } else { - foo = strdup(tmplist->data); - snprintf(info->desc, 512, "%s", foo+strlen(lang_tmp)+1); - FREE(foo); - break; + for (tmplist = info->desc_localized; tmplist; tmplist = tmplist->next) { + if (tmplist->data && strncmp(tmplist->data, locale, strlen(locale))) { + strncpy(info->desc, (char *)info->desc_localized->data, sizeof(info->desc)); + } else { + char *p = (char *)tmplist->data; + p += strlen(locale) + 1; + strncpy(info->desc, p, sizeof(info->desc)); + break; + } } - } } _alpm_strtrim(info->desc); - FREE(lang_tmp); } else if(!strcmp(line, "%GROUPS%")) { while(fgets(line, 512, fp) && strlen(_alpm_strtrim(line))) { info->groups = _alpm_list_add(info->groups, strdup(line)); diff --git a/lib/libalpm/package.c b/lib/libalpm/package.c index 16e0dc32..2686c00c 100644 --- a/lib/libalpm/package.c +++ b/lib/libalpm/package.c @@ -435,7 +435,7 @@ pmpkg_t *_alpm_pkg_isin(char *needle, pmlist_t *haystack) return(NULL); } -int _alpm_pkg_splitname(char *target, char *name, char *version) +int _alpm_pkg_splitname(char *target, char *name, char *version, int witharch) { char tmp[PKG_FULLNAME_LEN+7]; char *p, *q; @@ -453,7 +453,11 @@ int _alpm_pkg_splitname(char *target, char *name, char *version) STRNCPY(tmp, p, PKG_FULLNAME_LEN+7); /* trim file extension (if any) */ if((p = strstr(tmp, PM_EXT_PKG))) { - *p = 0; + *p = '\0'; + } + + if((p = _alpm_pkgname_has_arch(tmp))) { + *p = '\0'; } p = tmp + strlen(tmp); @@ -469,7 +473,7 @@ int _alpm_pkg_splitname(char *target, char *name, char *version) if(version) { STRNCPY(version, p+1, PKG_VERSION_LEN); } - *p = 0; + *p = '\0'; if(name) { STRNCPY(name, tmp, PKG_NAME_LEN); diff --git a/lib/libalpm/package.h b/lib/libalpm/package.h index 62ad7e4a..6dd092c8 100644 --- a/lib/libalpm/package.h +++ b/lib/libalpm/package.h @@ -98,7 +98,7 @@ void _alpm_pkg_free(void *data); int _alpm_pkg_cmp(const void *p1, const void *p2); pmpkg_t *_alpm_pkg_load(char *pkgfile); pmpkg_t *_alpm_pkg_isin(char *needle, pmlist_t *haystack); -int _alpm_pkg_splitname(char *target, char *name, char *version); +int _alpm_pkg_splitname(char *target, char *name, char *version, int witharch); #endif /* _ALPM_PACKAGE_H */ diff --git a/lib/libalpm/server.c b/lib/libalpm/server.c index ce39cb5a..aeaad6ae 100644 --- a/lib/libalpm/server.c +++ b/lib/libalpm/server.c @@ -52,7 +52,7 @@ pmserver_t *_alpm_server_new(const char *url) } memset(server, 0, sizeof(pmserver_t)); - u = fetchParseURL(url); + u = downloadParseURL(url); if(!u) { _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid, ignoring"), url); return(NULL); @@ -68,7 +68,7 @@ pmserver_t *_alpm_server_new(const char *url) } /* This isn't needed... we can actually kill the whole pmserver_t interface - * and replace it with libfetch's 'struct url' + * and replace it with libdownload's 'struct url' */ server->s_url = u; server->path = strdup(u->doc); @@ -86,7 +86,7 @@ void _alpm_server_free(void *data) /* free memory */ FREE(server->path); - fetchFreeURL(server->s_url); + downloadFreeURL(server->s_url); FREE(server); } @@ -165,24 +165,24 @@ int _alpm_downloadfiles_forreal(pmlist_t *servers, const char *localpath, server->s_url->doc = (char *)malloc(len); snprintf(server->s_url->doc, len, "%s/%s", server->path, fn); - /* libfetch does not reset the error code, reset it in the case of previous errors */ - fetchLastErrCode = 0; + /* libdownload does not reset the error code, reset it in the case of previous errors */ + downloadLastErrCode = 0; /* 10s timeout - TODO make a config option */ - fetchTimeout = 10000; + downloadTimeout = 10000; - /* Make libfetch super verbose... worthwhile for testing */ - if(pm_logmask & PM_LOG_FETCH) { - fetchDebug = 1; + /* Make libdownload super verbose... worthwhile for testing */ + if(pm_logmask & PM_LOG_DOWNLOAD) { + downloadDebug = 1; } if(pm_logmask & PM_LOG_DEBUG) { - dlf = fetchXGet(server->s_url, &ust, (handle->nopassiveftp ? "v" : "vp")); + dlf = downloadXGet(server->s_url, &ust, (handle->nopassiveftp ? "v" : "vp")); } else { - dlf = fetchXGet(server->s_url, &ust, (handle->nopassiveftp ? "" : "p")); + dlf = downloadXGet(server->s_url, &ust, (handle->nopassiveftp ? "" : "p")); } - if(fetchLastErrCode != 0 || dlf == NULL) { + if(downloadLastErrCode != 0 || dlf == NULL) { _alpm_log(PM_LOG_ERROR, _("failed retrieving file '%s' from %s://%s: %s"), fn, - server->s_url->scheme, server->s_url->host, fetchLastErrString); + server->s_url->scheme, server->s_url->host, downloadLastErrString); if(localf != NULL) { fclose(localf); } @@ -321,7 +321,7 @@ char *_alpm_fetch_pkgurl(char *target) struct stat st; struct url *s_url; - s_url = fetchParseURL(target); + s_url = downloadParseURL(target); if(!s_url) { _alpm_log(PM_LOG_ERROR, _("url '%s' is invalid, ignoring"), target); return(NULL); @@ -350,7 +350,7 @@ char *_alpm_fetch_pkgurl(char *target) } if(s_url->doc && (p = strrchr(s_url->doc,'/'))) { *p++ = '\0'; - _alpm_log(PM_LOG_DEBUG, _("fetching '%s' from '%s://%s%s"), p, s_url->scheme, s_url->host, s_url->doc); + _alpm_log(PM_LOG_DEBUG, _("downloading '%s' from '%s://%s%s"), p, s_url->scheme, s_url->host, s_url->doc); server->s_url = s_url; server->path = strdup(s_url->doc); @@ -366,10 +366,15 @@ char *_alpm_fetch_pkgurl(char *target) } } - fetchFreeURL(s_url); + /* dupe before we free the URL struct...*/ + if(p) { + p = strdup(p); + } + + downloadFreeURL(s_url); /* return the target with the raw filename, no URL */ - return(p ? strdup(p) : NULL); + return(p); } /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/server.h b/lib/libalpm/server.h index 73353189..5ce848cc 100644 --- a/lib/libalpm/server.h +++ b/lib/libalpm/server.h @@ -24,7 +24,7 @@ #include "list.h" #include <time.h> -#include <fetch.h> +#include <download.h> #define FREESERVER(p) \ do { \ diff --git a/lib/libalpm/sync.c b/lib/libalpm/sync.c index e0f1bc1d..b7ebe6b4 100644 --- a/lib/libalpm/sync.c +++ b/lib/libalpm/sync.c @@ -451,6 +451,7 @@ int _alpm_sync_prepare(pmtrans_t *trans, pmdb_t *db_local, pmlist_t *dbs_sync, p } } } + FREELISTPTR(k); FREELISTPTR(trans->packages); trans->packages = l; diff --git a/lib/libalpm/util.c b/lib/libalpm/util.c index 2d34ac58..38b0bced 100644 --- a/lib/libalpm/util.c +++ b/lib/libalpm/util.c @@ -243,6 +243,8 @@ int _alpm_lckmk(char *file) } } + free(dir); + return(fd > 0 ? fd : -1); } @@ -265,33 +267,34 @@ int _alpm_unpack(const char *archive, const char *prefix, const char *fn) struct archive_entry *entry; char expath[PATH_MAX]; - if ((_archive = archive_read_new ()) == NULL) + if((_archive = archive_read_new()) == NULL) RET_ERR(PM_ERR_LIBARCHIVE_ERROR, -1); archive_read_support_compression_all(_archive); - archive_read_support_format_all (_archive); + archive_read_support_format_all(_archive); - if (archive_read_open_file (_archive, archive, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) + if(archive_read_open_file(_archive, archive, ARCHIVE_DEFAULT_BYTES_PER_BLOCK) != ARCHIVE_OK) RET_ERR(PM_ERR_PKG_OPEN, -1); - while (archive_read_next_header (_archive, &entry) == ARCHIVE_OK) { - if (fn && strcmp (fn, archive_entry_pathname (entry))) { - if (archive_read_data_skip (_archive) != ARCHIVE_OK) + while(archive_read_next_header(_archive, &entry) == ARCHIVE_OK) { + if (fn && strcmp(fn, archive_entry_pathname(entry))) { + if (archive_read_data_skip(_archive) != ARCHIVE_OK) return(1); continue; } - snprintf(expath, PATH_MAX, "%s/%s", prefix, archive_entry_pathname (entry)); - archive_entry_set_pathname (entry, expath); - if (archive_read_extract (_archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { - fprintf(stderr, _("could not extract %s: %s\n"), archive_entry_pathname (entry), archive_error_string (_archive)); + snprintf(expath, PATH_MAX, "%s/%s", prefix, archive_entry_pathname(entry)); + archive_entry_set_pathname(entry, expath); + if(archive_read_extract(_archive, entry, ARCHIVE_EXTRACT_FLAGS) != ARCHIVE_OK) { + fprintf(stderr, _("could not extract %s: %s\n"), archive_entry_pathname(entry), archive_error_string(_archive)); return(1); } - if (fn) + if(fn) { break; + } } - archive_read_finish (_archive); + archive_read_finish(_archive); return(0); } @@ -543,16 +546,20 @@ static long long get_freespace() FILE *fp; long long ret=0; - fp = setmntent (table, "r"); - if(!fp) - return(-1); - while ((mnt = getmntent (fp))) + if((fp = setmntent(table, "r")) == NULL) { + return(-1); + } + + while ((mnt = getmntent(fp))) { struct statvfs64 buf; statvfs64(mnt->mnt_dir, &buf); ret += buf.f_bavail * buf.f_bsize; } + + endmntent(fp); + return(ret); } @@ -634,4 +641,44 @@ void _alpm_time2string(time_t t, char *buffer) } } +/* internal */ +char *_supported_archs[] = { + "i586", + "i686", + "ppc", + "x86_64", +}; + +char *_alpm_pkgname_has_arch(char *pkgname) +{ + /* TODO remove this when we transfer everything over to -ARCH + * + * this parsing sucks... it's done to support + * two package formats for the time being: + * package-name-foo-1.0.0-1-i686 + * and + * package-name-bar-1.2.3-1 + */ + int i = 0; + char *arch, *cmp, *p; + + if((p = strrchr(pkgname, '-'))) { + for(i=0; i < sizeof(_supported_archs)/sizeof(char*); ++i) { + cmp = p+1; + arch = _supported_archs[i]; + + /* whee, case insensitive compare */ + + while(*arch && *cmp && tolower(*arch++) == tolower(*cmp++)) ; + if(*arch || *cmp) continue; + + return p; + } + } + return NULL; +} + + + + /* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index 37b944cb..37a19e89 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -72,6 +72,7 @@ int _alpm_check_freespace(pmtrans_t *trans, pmlist_t **data); #endif int _alpm_reg_match(char *string, char *pattern); void _alpm_time2string(time_t t, char *buffer); +char *_alpm_pkgname_has_arch(char *pkgname); #ifdef __sun__ char* strsep(char** str, const char* delims); char* mkdtemp(char *template); diff --git a/lib/libfetch/Makefile b/lib/libfetch/Makefile deleted file mode 100644 index 631859bd..00000000 --- a/lib/libfetch/Makefile +++ /dev/null @@ -1,95 +0,0 @@ -prefix = /usr -DESTDIR = -DEBUG = true -ENABLE_HTTPS = true - -CFLAGS = -O2 -pipe -I. -DINET6 -WARNINGS = -Wall -Wstrict-prototypes -Wsign-compare -Wchar-subscripts \ - -Wpointer-arith -Wcast-align -Wsign-compare -CFLAGS += $(WARNINGS) - -ifeq ($(strip $(DEBUG)), true) -CFLAGS += -g -else -CFLAGS += -DNDEBUG -endif - -ifeq ($(strip $(ENALE_HTTPS)),true) -CFLAGS += -DWITH_SSL -LDFLAGS += -lssl -lcrypto -endif - -CC = gcc -LD = gcc -AR = ar -RANLIB = ranlib -INSTALL = install -c -D - -OBJS= fetch.o common.o ftp.o http.o file.o -INCS= fetch.h common.h -GEN = ftperr.h httperr.h -MAN = fetch.3 - -#pretty print! -E = @echo -Q = @ - -all: libfetch.so libfetch.a - $(E) " built with: " $(CFLAGS) -.PHONY: all - -%.o: %.c - $(E) " compile " $@ - $(Q) $(CC) $(CFLAGS) -c $< - -ftperr.h: ftp.errors - $(E) " generate " $@ - @echo "static struct fetcherr _ftp_errlist[] = {" > $@ - @cat $< \ - | grep -v ^# \ - | sort \ - | while read NUM CAT STRING; do \ - echo " { $${NUM}, FETCH_$${CAT}, \"$${STRING}\" },"; \ - done >> $@ - @echo -e " { -1, FETCH_UNKNOWN, \"Unknown FTP error\" }\n};" >> $@ - -httperr.h: http.errors - $(E) " generate " $@ - @echo "static struct fetcherr _http_errlist[] = {" > $@ - @cat $< \ - | grep -v ^# \ - | sort \ - | while read NUM CAT STRING; do \ - echo " { $${NUM}, FETCH_$${CAT}, \"$${STRING}\" },"; \ - done >> $@ - @echo -e " { -1, FETCH_UNKNOWN, \"Unknown HTTP error\" }\n};" >> $@ - -libfetch.so: $(GEN) $(INCS) $(OBJS) - $(E) " build " $@ - $(Q) rm -f $@ - $(Q) $(LD) $(LDFLAGS) *.o -shared -o $@ - -libfetch.a: $(GEN) $(INCS) $(OBJS) - $(E) " build " $@ - $(Q) rm -f $@ - $(Q) $(AR) rcs $@ *.o - $(Q) $(RANLIB) $@ - -clean: - $(E) " clean " - $(Q) rm -f libfetch.so libfetch.a *.o $(GEN) -.PHONY: clean - -install: all - $(Q) $(INSTALL) -m 755 libfetch.so $(DESTDIR)$(prefix)/lib/libfetch.so - $(Q) $(INSTALL) -m 644 libfetch.a $(DESTDIR)$(prefix)/lib/libfetch.a - $(Q) $(INSTALL) -m 644 fetch.h $(DESTDIR)$(prefix)/include/fetch.h - $(Q) $(INSTALL) -m 644 fetch.3 $(DESTDIR)$(prefix)/man/man3/fetch.3 -.PHONY: install - -uninstall: - $(Q) rm -f $(DESTDIR)$(prefix)/lib/libfetch.so - $(Q) rm -f $(DESTDIR)$(prefix)/lib/libfetch.a - $(Q) rm -f $(DESTDIR)$(prefix)/include/fetch.h - $(Q) rm -f $(DESTDIR)$(prefix)/man/man3/fetch.3 -.PHONY: uninstall diff --git a/lib/libfetch/common.c b/lib/libfetch/common.c deleted file mode 100644 index 92bfc687..00000000 --- a/lib/libfetch/common.c +++ /dev/null @@ -1,752 +0,0 @@ -/*- -* Copyright (c) 1998-2004 Dag-Erling Coďdan Smřrgrav -* 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 -* in this position and unchanged. -* 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. The name of the author may not be used to endorse or promote products -* derived from this software without specific prior written permission -* -* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/cdefs.h> - -#include <sys/param.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <sys/uio.h> -#include <netinet/in.h> - -#include <errno.h> -#include <netdb.h> -#include <pwd.h> -#include <stdarg.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <unistd.h> - -#include "fetch.h" -#include "common.h" - - -/*** Local data **************************************************************/ - -/* -* Error messages for resolver errors -*/ -static struct fetcherr _netdb_errlist[] = { -#ifdef EAI_NODATA -{ EAI_NODATA, FETCH_RESOLV, "Host not found" }, -#endif -{ EAI_AGAIN, FETCH_TEMP, "Transient resolver failure" }, -{ EAI_FAIL, FETCH_RESOLV, "Non-recoverable resolver failure" }, -{ EAI_NONAME, FETCH_RESOLV, "No address record" }, -{ -1, FETCH_UNKNOWN, "Unknown resolver error" } -}; - -/* End-of-Line */ -static const char ENDL[2] = "\r\n"; - - -/*** Error-reporting functions ***********************************************/ - -/* -* Map error code to string -*/ -static struct fetcherr * -_fetch_finderr(struct fetcherr *p, int e) -{ -while (p->num != -1 && p->num != e) - p++; -return (p); -} - -/* -* Set error code -*/ -void -_fetch_seterr(struct fetcherr *p, int e) -{ -p = _fetch_finderr(p, e); -fetchLastErrCode = p->cat; -snprintf(fetchLastErrString, MAXERRSTRING, "%s", p->string); -} - -/* -* Set error code according to errno -*/ -void -_fetch_syserr(void) -{ -switch (errno) { -case 0: - fetchLastErrCode = FETCH_OK; - break; -case EPERM: -case EACCES: -case EROFS: - fetchLastErrCode = FETCH_AUTH; - break; -case ENOENT: -case EISDIR: /* XXX */ - fetchLastErrCode = FETCH_UNAVAIL; - break; -case ENOMEM: - fetchLastErrCode = FETCH_MEMORY; - break; -case EBUSY: -case EAGAIN: - fetchLastErrCode = FETCH_TEMP; - break; -case EEXIST: - fetchLastErrCode = FETCH_EXISTS; - break; -case ENOSPC: - fetchLastErrCode = FETCH_FULL; - break; -case EADDRINUSE: -case EADDRNOTAVAIL: -case ENETDOWN: -case ENETUNREACH: -case ENETRESET: -case EHOSTUNREACH: - fetchLastErrCode = FETCH_NETWORK; - break; -case ECONNABORTED: -case ECONNRESET: - fetchLastErrCode = FETCH_ABORT; - break; -case ETIMEDOUT: - fetchLastErrCode = FETCH_TIMEOUT; - break; -case ECONNREFUSED: -case EHOSTDOWN: - fetchLastErrCode = FETCH_DOWN; - break; -default: - fetchLastErrCode = FETCH_UNKNOWN; -} -snprintf(fetchLastErrString, MAXERRSTRING, "%s", strerror(errno)); -} - - -/* -* Emit status message -*/ -void -_fetch_info(const char *fmt, ...) -{ -va_list ap; - -va_start(ap, fmt); -vfprintf(stderr, fmt, ap); -va_end(ap); -fputc('\n', stderr); -} - - -/*** Network-related utility functions ***************************************/ - -/* -* Return the default port for a scheme -*/ -int -_fetch_default_port(const char *scheme) -{ -struct servent *se; - -if ((se = getservbyname(scheme, "tcp")) != NULL) - return (ntohs(se->s_port)); -if (strcasecmp(scheme, SCHEME_FTP) == 0) - return (FTP_DEFAULT_PORT); -if (strcasecmp(scheme, SCHEME_HTTP) == 0) - return (HTTP_DEFAULT_PORT); -return (0); -} - -/* -* Return the default proxy port for a scheme -*/ -int -_fetch_default_proxy_port(const char *scheme) -{ -if (strcasecmp(scheme, SCHEME_FTP) == 0) - return (FTP_DEFAULT_PROXY_PORT); -if (strcasecmp(scheme, SCHEME_HTTP) == 0) - return (HTTP_DEFAULT_PROXY_PORT); -return (0); -} - - -/* -* Create a connection for an existing descriptor. -*/ -conn_t * -_fetch_reopen(int sd) -{ -conn_t *conn; - -/* allocate and fill connection structure */ -if ((conn = calloc(1, sizeof(*conn))) == NULL) - return (NULL); -conn->sd = sd; -++conn->ref; -return (conn); -} - - -/* -* Bump a connection's reference count. -*/ -conn_t * -_fetch_ref(conn_t *conn) -{ - -++conn->ref; -return (conn); -} - - -/* -* Bind a socket to a specific local address -*/ -int -_fetch_bind(int sd, int af, const char *addr) -{ -struct addrinfo hints, *res, *res0; -int err; - -memset(&hints, 0, sizeof(hints)); -hints.ai_family = af; -hints.ai_socktype = SOCK_STREAM; -hints.ai_protocol = 0; -if ((err = getaddrinfo(addr, NULL, &hints, &res0)) != 0) - return (-1); -for (res = res0; res; res = res->ai_next) - if (bind(sd, res->ai_addr, res->ai_addrlen) == 0) - return (0); -return (-1); -} - - -/* -* Establish a TCP connection to the specified port on the specified host. -*/ -conn_t * -_fetch_connect(const char *host, int port, int af, int verbose) -{ -conn_t *conn; -char pbuf[10]; -const char *bindaddr; -struct addrinfo hints, *res, *res0; -int sd, err; - -DEBUG(fprintf(stderr, "---> %s:%d\n", host, port)); - -if (verbose) - _fetch_info("looking up %s", host); - -/* look up host name and set up socket address structure */ -snprintf(pbuf, sizeof(pbuf), "%d", port); -memset(&hints, 0, sizeof(hints)); -hints.ai_family = af; -hints.ai_socktype = SOCK_STREAM; -hints.ai_protocol = 0; -if ((err = getaddrinfo(host, pbuf, &hints, &res0)) != 0) { - _netdb_seterr(err); - return (NULL); -} -bindaddr = getenv("FETCH_BIND_ADDRESS"); - -if (verbose) - _fetch_info("connecting to %s:%d", host, port); - -/* try to connect */ -for (sd = -1, res = res0; res; sd = -1, res = res->ai_next) { - if ((sd = socket(res->ai_family, res->ai_socktype, - res->ai_protocol)) == -1) - continue; - if (bindaddr != NULL && *bindaddr != '\0' && - _fetch_bind(sd, res->ai_family, bindaddr) != 0) { - _fetch_info("failed to bind to '%s'", bindaddr); - close(sd); - continue; - } - if (connect(sd, res->ai_addr, res->ai_addrlen) == 0) - break; - close(sd); -} -freeaddrinfo(res0); -if (sd == -1) { - _fetch_syserr(); - return (NULL); -} - -if ((conn = _fetch_reopen(sd)) == NULL) { - _fetch_syserr(); - close(sd); -} -return (conn); -} - - -/* -* Enable SSL on a connection. -*/ -int -_fetch_ssl(conn_t *conn, int verbose) -{ - -#ifdef WITH_SSL -/* Init the SSL library and context */ -if (!SSL_library_init()){ - fprintf(stderr, "SSL library init failed\n"); - return (-1); -} - -SSL_load_error_strings(); - -conn->ssl_meth = SSLv23_client_method(); -conn->ssl_ctx = SSL_CTX_new(conn->ssl_meth); -SSL_CTX_set_mode(conn->ssl_ctx, SSL_MODE_AUTO_RETRY); - -conn->ssl = SSL_new(conn->ssl_ctx); -if (conn->ssl == NULL){ - fprintf(stderr, "SSL context creation failed\n"); - return (-1); -} -SSL_set_fd(conn->ssl, conn->sd); -if (SSL_connect(conn->ssl) == -1){ - ERR_print_errors_fp(stderr); - return (-1); -} - -if (verbose) { - X509_NAME *name; - char *str; - - fprintf(stderr, "SSL connection established using %s\n", - SSL_get_cipher(conn->ssl)); - conn->ssl_cert = SSL_get_peer_certificate(conn->ssl); - name = X509_get_subject_name(conn->ssl_cert); - str = X509_NAME_oneline(name, 0, 0); - printf("Certificate subject: %s\n", str); - free(str); - name = X509_get_issuer_name(conn->ssl_cert); - str = X509_NAME_oneline(name, 0, 0); - printf("Certificate issuer: %s\n", str); - free(str); -} - -return (0); -#else -(void)conn; -(void)verbose; -fprintf(stderr, "SSL support disabled\n"); -return (-1); -#endif -} - - -/* -* Read a character from a connection w/ timeout -*/ -ssize_t -_fetch_read(conn_t *conn, char *buf, size_t len) -{ -struct timeval wait; -fd_set readfds; -ssize_t rlen, total; -int r; - -if (fetchTimeout) { - FD_ZERO(&readfds); - /* - gettimeofday(&timeout, NULL); - timeout.tv_sec += fetchTimeout; - */ -} - -total = 0; -while (len > 0) { - while (fetchTimeout && !FD_ISSET(conn->sd, &readfds)) { - FD_SET(conn->sd, &readfds); - /*gettimeofday(&now, NULL); - wait.tv_sec = timeout.tv_sec - now.tv_sec; - wait.tv_usec = timeout.tv_usec - now.tv_usec; - if (wait.tv_usec < 0) { - wait.tv_usec += 1000000; - wait.tv_sec--; - } - if (wait.tv_sec < 0) { - errno = ETIMEDOUT; - _fetch_syserr(); - return (-1); - } - */ - wait.tv_sec = fetchTimeout / 1000; - wait.tv_usec = (fetchTimeout % 1000) * 1000; - errno = 0; - r = select(conn->sd + 1, &readfds, NULL, NULL, &wait); - if (r == -1) { - if (errno == EINTR && fetchRestartCalls) - continue; - _fetch_syserr(); - return (-1); - } else if (r == 0) { - errno = ETIMEDOUT; - _fetch_syserr(); - return (-1); - } - } -#ifdef WITH_SSL - if (conn->ssl != NULL) - rlen = SSL_read(conn->ssl, buf, len); - else -#endif - rlen = read(conn->sd, buf, len); - if (rlen == 0) - break; - if (rlen < 0) { - if (errno == EINTR && fetchRestartCalls) - continue; - return (-1); - } - len -= rlen; - buf += rlen; - total += rlen; -} -return (total); -} - - -/* -* Read a line of text from a connection w/ timeout -*/ -#define MIN_BUF_SIZE 1024 - -int -_fetch_getln(conn_t *conn) -{ - char *tmp; - size_t tmpsize; - ssize_t len; - char c; - - if (conn->buf == NULL) { - if ((conn->buf = malloc(MIN_BUF_SIZE)) == NULL) { - errno = ENOMEM; - return (-1); - } - conn->bufsize = MIN_BUF_SIZE; - } - - conn->buf[0] = '\0'; - conn->buflen = 0; - - do { - len = _fetch_read(conn, &c, 1); - if (len == -1) - return (-1); - if (len == 0) - break; - conn->buf[conn->buflen++] = c; - if (conn->buflen == conn->bufsize) { - tmp = conn->buf; - tmpsize = conn->bufsize * 2 + 1; - if ((tmp = realloc(tmp, tmpsize)) == NULL) { - errno = ENOMEM; - return (-1); - } - conn->buf = tmp; - conn->bufsize = tmpsize; - } - } while (c != '\n'); - - conn->buf[conn->buflen] = '\0'; - DEBUG(fprintf(stderr, "<<< %s", conn->buf)); - return (0); -} - - -/* - * Write to a connection w/ timeout - */ -ssize_t -_fetch_write(conn_t *conn, const char *buf, size_t len) -{ - struct iovec iov; - - iov.iov_base = __DECONST(char *, buf); - iov.iov_len = len; - return _fetch_writev(conn, &iov, 1); -} - -/* - * Write a vector to a connection w/ timeout - * Note: can modify the iovec. - */ -ssize_t -_fetch_writev(conn_t *conn, struct iovec *iov, int iovcnt) -{ - struct timeval wait; - fd_set writefds; - ssize_t wlen, total; - int r; - - if (fetchTimeout) { - FD_ZERO(&writefds); - /* - gettimeofday(&timeout, NULL); - timeout.tv_sec += fetchTimeout; - */ - } - - total = 0; - while (iovcnt > 0) { - while (fetchTimeout && !FD_ISSET(conn->sd, &writefds)) { - FD_SET(conn->sd, &writefds); - /* - gettimeofday(&now, NULL); - wait.tv_sec = timeout.tv_sec - now.tv_sec; - wait.tv_usec = timeout.tv_usec - now.tv_usec; - if (wait.tv_usec < 0) { - wait.tv_usec += 1000000; - wait.tv_sec--; - } - if (wait.tv_sec < 0) { - errno = ETIMEDOUT; - _fetch_syserr(); - return (-1); - } - */ - wait.tv_sec = fetchTimeout / 1000; - wait.tv_usec = (fetchTimeout % 1000) * 1000; - errno = 0; - r = select(conn->sd + 1, NULL, &writefds, NULL, &wait); - if (r == -1) { - if (errno == EINTR && fetchRestartCalls) - continue; - return (-1); - } else if (r == 0) { - errno = ETIMEDOUT; - _fetch_syserr(); - return (-1); - } - } - errno = 0; -#ifdef WITH_SSL - if (conn->ssl != NULL) - wlen = SSL_write(conn->ssl, - iov->iov_base, iov->iov_len); - else -#endif - wlen = writev(conn->sd, iov, iovcnt); - if (wlen == 0) { - /* we consider a short write a failure */ - errno = EPIPE; - _fetch_syserr(); - return (-1); - } - if (wlen < 0) { - if (errno == EINTR && fetchRestartCalls) - continue; - return (-1); - } - total += wlen; - while (iovcnt > 0 && wlen >= (ssize_t)iov->iov_len) { - wlen -= iov->iov_len; - iov++; - iovcnt--; - } - if (iovcnt > 0) { - iov->iov_len -= wlen; - iov->iov_base = __DECONST(char *, iov->iov_base) + wlen; - } - } - return (total); -} - - -/* - * Write a line of text to a connection w/ timeout - */ -int -_fetch_putln(conn_t *conn, const char *str, size_t len) -{ - struct iovec iov[2]; - int ret; - - DEBUG(fprintf(stderr, ">>> %s\n", str)); - iov[0].iov_base = __DECONST(char *, str); - iov[0].iov_len = len; - iov[1].iov_base = __DECONST(char *, ENDL); - iov[1].iov_len = sizeof(ENDL); - if (len == 0) - ret = _fetch_writev(conn, &iov[1], 1); - else - ret = _fetch_writev(conn, iov, 2); - if (ret == -1) - return (-1); - return (0); -} - - -/* - * Close connection - */ -int -_fetch_close(conn_t *conn) -{ - int ret; - - if (--conn->ref > 0) - return (0); - ret = close(conn->sd); - free(conn->buf); - free(conn); - return (ret); -} - - -/*** Directory-related utility functions *************************************/ - -int -_fetch_add_entry(struct url_ent **p, int *size, int *len, - const char *name, struct url_stat *us) -{ - struct url_ent *tmp; - - if (*p == NULL) { - *size = 0; - *len = 0; - } - - if (*len >= *size - 1) { - tmp = realloc(*p, (*size * 2 + 1) * sizeof(**p)); - if (tmp == NULL) { - errno = ENOMEM; - _fetch_syserr(); - return (-1); - } - *size = (*size * 2 + 1); - *p = tmp; - } - - tmp = *p + *len; - snprintf(tmp->name, PATH_MAX, "%s", name); - bcopy(us, &tmp->stat, sizeof(*us)); - - (*len)++; - (++tmp)->name[0] = 0; - - return (0); -} - - -/*** Authentication-related utility functions ********************************/ - -static const char * -_fetch_read_word(FILE *f) -{ - static char word[1024]; - - if (fscanf(f, " %1024s ", word) != 1) - return (NULL); - return (word); -} - -/* - * Get authentication data for a URL from .netrc - */ -int -_fetch_netrc_auth(struct url *url) -{ - char fn[PATH_MAX]; - const char *word; - char *p; - FILE *f; - - if ((p = getenv("NETRC")) != NULL) { - if (snprintf(fn, sizeof(fn), "%s", p) >= (int)sizeof(fn)) { - _fetch_info("$NETRC specifies a file name " - "longer than PATH_MAX"); - return (-1); - } - } else { - if ((p = getenv("HOME")) != NULL) { - struct passwd *pwd; - - if ((pwd = getpwuid(getuid())) == NULL || - (p = pwd->pw_dir) == NULL) - return (-1); - } - if (snprintf(fn, sizeof(fn), "%s/.netrc", p) >= (int)sizeof(fn)) - return (-1); - } - - if ((f = fopen(fn, "r")) == NULL) - return (-1); - while ((word = _fetch_read_word(f)) != NULL) { - if (strcmp(word, "default") == 0) { - DEBUG(_fetch_info("Using default .netrc settings")); - break; - } - if (strcmp(word, "machine") == 0 && - (word = _fetch_read_word(f)) != NULL && - strcasecmp(word, url->host) == 0) { - DEBUG(_fetch_info("Using .netrc settings for %s", word)); - break; - } - } - if (word == NULL) - goto ferr; - while ((word = _fetch_read_word(f)) != NULL) { - if (strcmp(word, "login") == 0) { - if ((word = _fetch_read_word(f)) == NULL) - goto ferr; - if (snprintf(url->user, sizeof(url->user), - "%s", word) > (int)sizeof(url->user)) { - _fetch_info("login name in .netrc is too long"); - url->user[0] = '\0'; - } - } else if (strcmp(word, "password") == 0) { - if ((word = _fetch_read_word(f)) == NULL) - goto ferr; - if (snprintf(url->pwd, sizeof(url->pwd), - "%s", word) > (int)sizeof(url->pwd)) { - _fetch_info("password in .netrc is too long"); - url->pwd[0] = '\0'; - } - } else if (strcmp(word, "account") == 0) { - if ((word = _fetch_read_word(f)) == NULL) - goto ferr; - /* XXX not supported! */ - } else { - break; - } - } - fclose(f); - return (0); - ferr: - fclose(f); - return (-1); -} diff --git a/lib/libfetch/common.h b/lib/libfetch/common.h deleted file mode 100644 index c2c15d70..00000000 --- a/lib/libfetch/common.h +++ /dev/null @@ -1,127 +0,0 @@ -/*- - * Copyright (c) 1998-2004 Dag-Erling Coďdan Smřrgrav - * 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 - * in this position and unchanged. - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD: /repoman/r/ncvs/src/lib/libfetch/common.h,v 1.28 2004/09/21 18:35:20 des Exp $ - */ - -#ifndef _COMMON_H_INCLUDED -#define _COMMON_H_INCLUDED - -/* BSD seems to use this alot - we don't have it */ -#define __DECONST(type, v) (type)((uintptr_t)(void *)(v)) - -#define FTP_DEFAULT_PORT 21 -#define HTTP_DEFAULT_PORT 80 -#define FTP_DEFAULT_PROXY_PORT 21 -#define HTTP_DEFAULT_PROXY_PORT 3128 - -#ifdef WITH_SSL -#include <openssl/crypto.h> -#include <openssl/x509.h> -#include <openssl/pem.h> -#include <openssl/ssl.h> -#include <openssl/err.h> -#endif - -/* Connection */ -typedef struct fetchconn conn_t; -struct fetchconn { - int sd; /* socket descriptor */ - char *buf; /* buffer */ - size_t bufsize; /* buffer size */ - size_t buflen; /* length of buffer contents */ - int err; /* last protocol reply code */ -#ifdef WITH_SSL - SSL *ssl; /* SSL handle */ - SSL_CTX *ssl_ctx; /* SSL context */ - X509 *ssl_cert; /* server certificate */ - SSL_METHOD *ssl_meth; /* SSL method */ -#endif - int ref; /* reference count */ -}; - -/* Structure used for error message lists */ -struct fetcherr { - const int num; - const int cat; - const char *string; -}; - -/* for _fetch_writev */ -struct iovec; - -void _fetch_seterr(struct fetcherr *, int); -void _fetch_syserr(void); -void _fetch_info(const char *, ...); -int _fetch_default_port(const char *); -int _fetch_default_proxy_port(const char *); -int _fetch_bind(int, int, const char *); -conn_t *_fetch_connect(const char *, int, int, int); -conn_t *_fetch_reopen(int); -conn_t *_fetch_ref(conn_t *); -int _fetch_ssl(conn_t *, int); -ssize_t _fetch_read(conn_t *, char *, size_t); -int _fetch_getln(conn_t *); -ssize_t _fetch_write(conn_t *, const char *, size_t); -ssize_t _fetch_writev(conn_t *, struct iovec *, int); -int _fetch_putln(conn_t *, const char *, size_t); -int _fetch_close(conn_t *); -int _fetch_add_entry(struct url_ent **, int *, int *, - const char *, struct url_stat *); -int _fetch_netrc_auth(struct url *url); - -#define _ftp_seterr(n) _fetch_seterr(_ftp_errlist, n) -#define _http_seterr(n) _fetch_seterr(_http_errlist, n) -#define _netdb_seterr(n) _fetch_seterr(_netdb_errlist, n) -#define _url_seterr(n) _fetch_seterr(_url_errlist, n) - -#ifndef NDEBUG -#define DEBUG(x) do { if (fetchDebug) { x; } } while (0) -#else -#define DEBUG(x) do { } while (0) -#endif - -/* - * I don't really like exporting _http_request() and _ftp_request(), - * but the HTTP and FTP code occasionally needs to cross-call - * eachother, and this saves me from adding a lot of special-case code - * to handle those cases. - * - * Note that _*_request() free purl, which is way ugly but saves us a - * whole lot of trouble. - */ -FILE *_http_request(struct url *, const char *, - struct url_stat *, struct url *, const char *); -FILE *_ftp_request(struct url *, const char *, - struct url_stat *, struct url *, const char *); - -/* - * Check whether a particular flag is set - */ -#define CHECK_FLAG(x) (flags && strchr(flags, (x))) - -#endif diff --git a/lib/libfetch/fetch.3 b/lib/libfetch/fetch.3 deleted file mode 100644 index 67c29b08..00000000 --- a/lib/libfetch/fetch.3 +++ /dev/null @@ -1,668 +0,0 @@ -.\"- -.\" Copyright (c) 1998-2004 Dag-Erling Coďdan Smřrgrav -.\" 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. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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. -.\" -.\" $FreeBSD: /repoman/r/ncvs/src/lib/libfetch/fetch.3,v 1.61 2005/11/30 04:08:45 tmclaugh Exp $ -.\" -.Dd July 1, 1998 -.Dt FETCH 3 -.Os -.Sh NAME -.Nm fetchMakeURL , -.Nm fetchParseURL , -.Nm fetchFreeURL , -.Nm fetchXGetURL , -.Nm fetchGetURL , -.Nm fetchPutURL , -.Nm fetchStatURL , -.Nm fetchListURL , -.Nm fetchXGet , -.Nm fetchGet , -.Nm fetchPut , -.Nm fetchStat , -.Nm fetchList , -.Nm fetchXGetFile , -.Nm fetchGetFile , -.Nm fetchPutFile , -.Nm fetchStatFile , -.Nm fetchListFile , -.Nm fetchXGetHTTP , -.Nm fetchGetHTTP , -.Nm fetchPutHTTP , -.Nm fetchStatHTTP , -.Nm fetchListHTTP , -.Nm fetchXGetFTP , -.Nm fetchGetFTP , -.Nm fetchPutFTP , -.Nm fetchStatFTP , -.Nm fetchListFTP -.Nd file transfer functions -.Sh LIBRARY -.Lb libfetch -.Sh SYNOPSIS -.In sys/param.h -.In stdio.h -.In fetch.h -.Ft struct url * -.Fn fetchMakeURL "const char *scheme" "const char *host" "int port" "const char *doc" "const char *user" "const char *pwd" -.Ft struct url * -.Fn fetchParseURL "const char *URL" -.Ft void -.Fn fetchFreeURL "struct url *u" -.Ft FILE * -.Fn fetchXGetURL "const char *URL" "struct url_stat *us" "const char *flags" -.Ft FILE * -.Fn fetchGetURL "const char *URL" "const char *flags" -.Ft FILE * -.Fn fetchPutURL "const char *URL" "const char *flags" -.Ft int -.Fn fetchStatURL "const char *URL" "struct url_stat *us" "const char *flags" -.Ft struct url_ent * -.Fn fetchListURL "const char *URL" "const char *flags" -.Ft FILE * -.Fn fetchXGet "struct url *u" "struct url_stat *us" "const char *flags" -.Ft FILE * -.Fn fetchGet "struct url *u" "const char *flags" -.Ft FILE * -.Fn fetchPut "struct url *u" "const char *flags" -.Ft int -.Fn fetchStat "struct url *u" "struct url_stat *us" "const char *flags" -.Ft struct url_ent * -.Fn fetchList "struct url *u" "const char *flags" -.Ft FILE * -.Fn fetchXGetFile "struct url *u" "struct url_stat *us" "const char *flags" -.Ft FILE * -.Fn fetchGetFile "struct url *u" "const char *flags" -.Ft FILE * -.Fn fetchPutFile "struct url *u" "const char *flags" -.Ft int -.Fn fetchStatFile "struct url *u" "struct url_stat *us" "const char *flags" -.Ft struct url_ent * -.Fn fetchListFile "struct url *u" "const char *flags" -.Ft FILE * -.Fn fetchXGetHTTP "struct url *u" "struct url_stat *us" "const char *flags" -.Ft FILE * -.Fn fetchGetHTTP "struct url *u" "const char *flags" -.Ft FILE * -.Fn fetchPutHTTP "struct url *u" "const char *flags" -.Ft int -.Fn fetchStatHTTP "struct url *u" "struct url_stat *us" "const char *flags" -.Ft struct url_ent * -.Fn fetchListHTTP "struct url *u" "const char *flags" -.Ft FILE * -.Fn fetchXGetFTP "struct url *u" "struct url_stat *us" "const char *flags" -.Ft FILE * -.Fn fetchGetFTP "struct url *u" "const char *flags" -.Ft FILE * -.Fn fetchPutFTP "struct url *u" "const char *flags" -.Ft int -.Fn fetchStatFTP "struct url *u" "struct url_stat *us" "const char *flags" -.Ft struct url_ent * -.Fn fetchListFTP "struct url *u" "const char *flags" -.Sh DESCRIPTION -These functions implement a high-level library for retrieving and -uploading files using Uniform Resource Locators (URLs). -.Pp -.Fn fetchParseURL -takes a URL in the form of a null-terminated string and splits it into -its components function according to the Common Internet Scheme Syntax -detailed in RFC1738. -A regular expression which produces this syntax is: -.Bd -literal - <scheme>:(//(<user>(:<pwd>)?@)?<host>(:<port>)?)?/(<document>)? -.Ed -.Pp -If the URL does not seem to begin with a scheme name, the following -syntax is assumed: -.Bd -literal - ((<user>(:<pwd>)?@)?<host>(:<port>)?)?/(<document>)? -.Ed -.Pp -Note that some components of the URL are not necessarily relevant to -all URL schemes. -For instance, the file scheme only needs the <scheme> and <document> -components. -.Pp -.Fn fetchMakeURL -and -.Fn fetchParseURL -return a pointer to a -.Vt url -structure, which is defined as follows in -.In fetch.h : -.Bd -literal -#define URL_SCHEMELEN 16 -#define URL_USERLEN 256 -#define URL_PWDLEN 256 - -struct url { - char scheme[URL_SCHEMELEN+1]; - char user[URL_USERLEN+1]; - char pwd[URL_PWDLEN+1]; - char host[MAXHOSTNAMELEN+1]; - int port; - char *doc; - off_t offset; - size_t length; -}; -.Ed -.Pp -The pointer returned by -.Fn fetchMakeURL -or -.Fn fetchParseURL -should be freed using -.Fn fetchFreeURL . -.Pp -.Fn fetchXGetURL , -.Fn fetchGetURL , -and -.Fn fetchPutURL -constitute the recommended interface to the -.Nm fetch -library. -They examine the URL passed to them to determine the transfer -method, and call the appropriate lower-level functions to perform the -actual transfer. -.Fn fetchXGetURL -also returns the remote document's metadata in the -.Vt url_stat -structure pointed to by the -.Fa us -argument. -.Pp -The -.Fa flags -argument is a string of characters which specify transfer options. -The -meaning of the individual flags is scheme-dependent, and is detailed -in the appropriate section below. -.Pp -.Fn fetchStatURL -attempts to obtain the requested document's metadata and fill in the -structure pointed to by its second argument. -The -.Vt url_stat -structure is defined as follows in -.In fetch.h : -.Bd -literal -struct url_stat { - off_t size; - time_t atime; - time_t mtime; -}; -.Ed -.Pp -If the size could not be obtained from the server, the -.Fa size -field is set to -1. -If the modification time could not be obtained from the server, the -.Fa mtime -field is set to the epoch. -If the access time could not be obtained from the server, the -.Fa atime -field is set to the modification time. -.Pp -.Fn fetchListURL -attempts to list the contents of the directory pointed to by the URL -provided. -If successful, it returns a malloced array of -.Vt url_ent -structures. -The -.Vt url_ent -structure is defined as follows in -.In fetch.h : -.Bd -literal -struct url_ent { - char name[MAXPATHLEN]; - struct url_stat stat; -}; -.Ed -.Pp -The list is terminated by an entry with an empty name. -.Pp -The pointer returned by -.Fn fetchListURL -should be freed using -.Fn free . -.Pp -.Fn fetchXGet , -.Fn fetchGet , -.Fn fetchPut -and -.Fn fetchStat -are similar to -.Fn fetchXGetURL , -.Fn fetchGetURL , -.Fn fetchPutURL -and -.Fn fetchStatURL , -except that they expect a pre-parsed URL in the form of a pointer to -a -.Vt struct url -rather than a string. -.Pp -All of the -.Fn fetchXGetXXX , -.Fn fetchGetXXX -and -.Fn fetchPutXXX -functions return a pointer to a stream which can be used to read or -write data from or to the requested document, respectively. -Note that -although the implementation details of the individual access methods -vary, it can generally be assumed that a stream returned by one of the -.Fn fetchXGetXXX -or -.Fn fetchGetXXX -functions is read-only, and that a stream returned by one of the -.Fn fetchPutXXX -functions is write-only. -.Sh FILE SCHEME -.Fn fetchXGetFile , -.Fn fetchGetFile -and -.Fn fetchPutFile -provide access to documents which are files in a locally mounted file -system. -Only the <document> component of the URL is used. -.Pp -.Fn fetchXGetFile -and -.Fn fetchGetFile -do not accept any flags. -.Pp -.Fn fetchPutFile -accepts the -.Ql a -(append to file) flag. -If that flag is specified, the data written to -the stream returned by -.Fn fetchPutFile -will be appended to the previous contents of the file, instead of -replacing them. -.Sh FTP SCHEME -.Fn fetchXGetFTP , -.Fn fetchGetFTP -and -.Fn fetchPutFTP -implement the FTP protocol as described in RFC959. -.Pp -If the -.Ql p -(passive) flag is specified, a passive (rather than active) connection -will be attempted. -.Pp -If the -.Ql l -(low) flag is specified, data sockets will be allocated in the low (or -default) port range instead of the high port range (see -.Xr ip 4 ) . -.Pp -If the -.Ql d -(direct) flag is specified, -.Fn fetchXGetFTP , -.Fn fetchGetFTP -and -.Fn fetchPutFTP -will use a direct connection even if a proxy server is defined. -.Pp -If no user name or password is given, the -.Nm fetch -library will attempt an anonymous login, with user name "anonymous" -and password "anonymous@<hostname>". -.Sh HTTP SCHEME -The -.Fn fetchXGetHTTP , -.Fn fetchGetHTTP -and -.Fn fetchPutHTTP -functions implement the HTTP/1.1 protocol. -With a little luck, there is -even a chance that they comply with RFC2616 and RFC2617. -.Pp -If the -.Ql d -(direct) flag is specified, -.Fn fetchXGetHTTP , -.Fn fetchGetHTTP -and -.Fn fetchPutHTTP -will use a direct connection even if a proxy server is defined. -.Pp -Since there seems to be no good way of implementing the HTTP PUT -method in a manner consistent with the rest of the -.Nm fetch -library, -.Fn fetchPutHTTP -is currently unimplemented. -.Sh AUTHENTICATION -Apart from setting the appropriate environment variables and -specifying the user name and password in the URL or the -.Vt struct url , -the calling program has the option of defining an authentication -function with the following prototype: -.Pp -.Ft int -.Fn myAuthMethod "struct url *u" -.Pp -The callback function should fill in the -.Fa user -and -.Fa pwd -fields in the provided -.Vt struct url -and return 0 on success, or any other value to indicate failure. -.Pp -To register the authentication callback, simply set -.Va fetchAuthMethod -to point at it. -The callback will be used whenever a site requires authentication and -the appropriate environment variables are not set. -.Pp -This interface is experimental and may be subject to change. -.Sh RETURN VALUES -.Fn fetchParseURL -returns a pointer to a -.Vt struct url -containing the individual components of the URL. -If it is -unable to allocate memory, or the URL is syntactically incorrect, -.Fn fetchParseURL -returns a NULL pointer. -.Pp -The -.Fn fetchStat -functions return 0 on success and -1 on failure. -.Pp -All other functions return a stream pointer which may be used to -access the requested document, or NULL if an error occurred. -.Pp -The following error codes are defined in -.In fetch.h : -.Bl -tag -width 18n -.It Bq Er FETCH_ABORT -Operation aborted -.It Bq Er FETCH_AUTH -Authentication failed -.It Bq Er FETCH_DOWN -Service unavailable -.It Bq Er FETCH_EXISTS -File exists -.It Bq Er FETCH_FULL -File system full -.It Bq Er FETCH_INFO -Informational response -.It Bq Er FETCH_MEMORY -Insufficient memory -.It Bq Er FETCH_MOVED -File has moved -.It Bq Er FETCH_NETWORK -Network error -.It Bq Er FETCH_OK -No error -.It Bq Er FETCH_PROTO -Protocol error -.It Bq Er FETCH_RESOLV -Resolver error -.It Bq Er FETCH_SERVER -Server error -.It Bq Er FETCH_TEMP -Temporary error -.It Bq Er FETCH_TIMEOUT -Operation timed out -.It Bq Er FETCH_UNAVAIL -File is not available -.It Bq Er FETCH_UNKNOWN -Unknown error -.It Bq Er FETCH_URL -Invalid URL -.El -.Pp -The accompanying error message includes a protocol-specific error code -and message, e.g.\& "File is not available (404 Not Found)" -.Sh ENVIRONMENT -.Bl -tag -width ".Ev FETCH_BIND_ADDRESS" -.It Ev FETCH_BIND_ADDRESS -Specifies a hostname or IP address to which sockets used for outgoing -connections will be bound. -.It Ev FTP_LOGIN -Default FTP login if none was provided in the URL. -.It Ev FTP_PASSIVE_MODE -If set to anything but -.Ql no , -forces the FTP code to use passive mode. -.It Ev FTP_PASSWORD -Default FTP password if the remote server requests one and none was -provided in the URL. -.It Ev FTP_PROXY -URL of the proxy to use for FTP requests. -The document part is ignored. -FTP and HTTP proxies are supported; if no scheme is specified, FTP is -assumed. -If the proxy is an FTP proxy, -.Nm libfetch -will send -.Ql user@host -as user name to the proxy, where -.Ql user -is the real user name, and -.Ql host -is the name of the FTP server. -.Pp -If this variable is set to an empty string, no proxy will be used for -FTP requests, even if the -.Ev HTTP_PROXY -variable is set. -.It Ev ftp_proxy -Same as -.Ev FTP_PROXY , -for compatibility. -.It Ev HTTP_AUTH -Specifies HTTP authorization parameters as a colon-separated list of -items. -The first and second item are the authorization scheme and realm -respectively; further items are scheme-dependent. -Currently, only basic authorization is supported. -.Pp -Basic authorization requires two parameters: the user name and -password, in that order. -.Pp -This variable is only used if the server requires authorization and -no user name or password was specified in the URL. -.It Ev HTTP_PROXY -URL of the proxy to use for HTTP requests. -The document part is ignored. -Only HTTP proxies are supported for HTTP requests. -If no port number is specified, the default is 3128. -.Pp -Note that this proxy will also be used for FTP documents, unless the -.Ev FTP_PROXY -variable is set. -.It Ev http_proxy -Same as -.Ev HTTP_PROXY , -for compatibility. -.It Ev HTTP_PROXY_AUTH -Specifies authorization parameters for the HTTP proxy in the same -format as the -.Ev HTTP_AUTH -variable. -.Pp -This variable is used if and only if connected to an HTTP proxy, and -is ignored if a user and/or a password were specified in the proxy -URL. -.It Ev HTTP_REFERER -Specifies the referrer URL to use for HTTP requests. -If set to -.Dq auto , -the document URL will be used as referrer URL. -.It Ev HTTP_USER_AGENT -Specifies the User-Agent string to use for HTTP requests. -This can be useful when working with HTTP origin or proxy servers that -differentiate between user agents. -.It Ev NETRC -Specifies a file to use instead of -.Pa ~/.netrc -to look up login names and passwords for FTP sites. -See -.Xr ftp 1 -for a description of the file format. -This feature is experimental. -.El -.Sh EXAMPLES -To access a proxy server on -.Pa proxy.example.com -port 8080, set the -.Ev HTTP_PROXY -environment variable in a manner similar to this: -.Pp -.Dl HTTP_PROXY=http://proxy.example.com:8080 -.Pp -If the proxy server requires authentication, there are -two options available for passing the authentication data. -The first method is by using the proxy URL: -.Pp -.Dl HTTP_PROXY=http://<user>:<pwd>@proxy.example.com:8080 -.Pp -The second method is by using the -.Ev HTTP_PROXY_AUTH -environment variable: -.Bd -literal -offset indent -HTTP_PROXY=http://proxy.example.com:8080 -HTTP_PROXY_AUTH=basic:*:<user>:<pwd> -.Ed -.Sh SEE ALSO -.Xr fetch 1 , -.Xr ftpio 3 , -.Xr ip 4 -.Rs -.%A J. Postel -.%A J. K. Reynolds -.%D October 1985 -.%B File Transfer Protocol -.%O RFC959 -.Re -.Rs -.%A P. Deutsch -.%A A. Emtage -.%A A. Marine. -.%D May 1994 -.%T How to Use Anonymous FTP -.%O RFC1635 -.Re -.Rs -.%A T. Berners-Lee -.%A L. Masinter -.%A M. McCahill -.%D December 1994 -.%T Uniform Resource Locators (URL) -.%O RFC1738 -.Re -.Rs -.%A R. Fielding -.%A J. Gettys -.%A J. Mogul -.%A H. Frystyk -.%A L. Masinter -.%A P. Leach -.%A T. Berners-Lee -.%D January 1999 -.%B Hypertext Transfer Protocol -- HTTP/1.1 -.%O RFC2616 -.Re -.Rs -.%A J. Franks -.%A P. Hallam-Baker -.%A J. Hostetler -.%A S. Lawrence -.%A P. Leach -.%A A. Luotonen -.%A L. Stewart -.%D June 1999 -.%B HTTP Authentication: Basic and Digest Access Authentication -.%O RFC2617 -.Re -.Sh HISTORY -The -.Nm fetch -library first appeared in -.Fx 3.0 . -.Sh AUTHORS -.An -nosplit -The -.Nm fetch -library was mostly written by -.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org -with numerous suggestions from -.An Jordan K. Hubbard Aq jkh@FreeBSD.org , -.An Eugene Skepner Aq eu@qub.com -and other -.Fx -developers. -It replaces the older -.Nm ftpio -library written by -.An Poul-Henning Kamp Aq phk@FreeBSD.org -and -.An Jordan K. Hubbard Aq jkh@FreeBSD.org . -.Pp -This manual page was written by -.An Dag-Erling Sm\(/orgrav Aq des@FreeBSD.org . -.Sh BUGS -Some parts of the library are not yet implemented. -The most notable -examples of this are -.Fn fetchPutHTTP , -.Fn fetchListHTTP , -.Fn fetchListFTP -and FTP proxy support. -.Pp -There is no way to select a proxy at run-time other than setting the -.Ev HTTP_PROXY -or -.Ev FTP_PROXY -environment variables as appropriate. -.Pp -.Nm libfetch -does not understand or obey 305 (Use Proxy) replies. -.Pp -Error numbers are unique only within a certain context; the error -codes used for FTP and HTTP overlap, as do those used for resolver and -system errors. -For instance, error code 202 means "Command not -implemented, superfluous at this site" in an FTP context and -"Accepted" in an HTTP context. -.Pp -.Fn fetchStatFTP -does not check that the result of an MDTM command is a valid date. -.Pp -The man page is incomplete, poorly written and produces badly -formatted text. -.Pp -The error reporting mechanism is unsatisfactory. -.Pp -Some parts of the code are not fully reentrant. diff --git a/lib/libfetch/fetch.c b/lib/libfetch/fetch.c deleted file mode 100644 index 07afec0f..00000000 --- a/lib/libfetch/fetch.c +++ /dev/null @@ -1,437 +0,0 @@ -/*- - * Copyright (c) 1998-2004 Dag-Erling Coďdan Smřrgrav - * 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 - * in this position and unchanged. - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/cdefs.h> - -#include <sys/param.h> -#include <sys/errno.h> - -#include <ctype.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> - -#include "fetch.h" -#include "common.h" - -auth_t fetchAuthMethod; -int fetchLastErrCode; -char fetchLastErrString[MAXERRSTRING]; -int fetchTimeout; -int fetchRestartCalls = 1; -int fetchDebug; - - -/*** Local data **************************************************************/ - -/* - * Error messages for parser errors - */ -#define URL_MALFORMED 1 -#define URL_BAD_SCHEME 2 -#define URL_BAD_PORT 3 -static struct fetcherr _url_errlist[] = { - { URL_MALFORMED, FETCH_URL, "Malformed URL" }, - { URL_BAD_SCHEME, FETCH_URL, "Invalid URL scheme" }, - { URL_BAD_PORT, FETCH_URL, "Invalid server port" }, - { -1, FETCH_UNKNOWN, "Unknown parser error" } -}; - - -/*** Public API **************************************************************/ - -/* - * Select the appropriate protocol for the URL scheme, and return a - * read-only stream connected to the document referenced by the URL. - * Also fill out the struct url_stat. - */ -FILE * -fetchXGet(struct url *URL, struct url_stat *us, const char *flags) -{ - int direct; - - direct = CHECK_FLAG('d'); - if (us != NULL) { - us->size = -1; - us->atime = us->mtime = 0; - } - if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) - return (fetchXGetFile(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) - return (fetchXGetFTP(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) - return (fetchXGetHTTP(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) - return (fetchXGetHTTP(URL, us, flags)); - _url_seterr(URL_BAD_SCHEME); - return (NULL); -} - -/* - * Select the appropriate protocol for the URL scheme, and return a - * read-only stream connected to the document referenced by the URL. - */ -FILE * -fetchGet(struct url *URL, const char *flags) -{ - return (fetchXGet(URL, NULL, flags)); -} - -/* - * Select the appropriate protocol for the URL scheme, and return a - * write-only stream connected to the document referenced by the URL. - */ -FILE * -fetchPut(struct url *URL, const char *flags) -{ - int direct; - - direct = CHECK_FLAG('d'); - if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) - return (fetchPutFile(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) - return (fetchPutFTP(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) - return (fetchPutHTTP(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) - return (fetchPutHTTP(URL, flags)); - _url_seterr(URL_BAD_SCHEME); - return (NULL); -} - -/* - * Select the appropriate protocol for the URL scheme, and return the - * size of the document referenced by the URL if it exists. - */ -int -fetchStat(struct url *URL, struct url_stat *us, const char *flags) -{ - int direct; - - direct = CHECK_FLAG('d'); - if (us != NULL) { - us->size = -1; - us->atime = us->mtime = 0; - } - if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) - return (fetchStatFile(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) - return (fetchStatFTP(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) - return (fetchStatHTTP(URL, us, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) - return (fetchStatHTTP(URL, us, flags)); - _url_seterr(URL_BAD_SCHEME); - return (-1); -} - -/* - * Select the appropriate protocol for the URL scheme, and return a - * list of files in the directory pointed to by the URL. - */ -struct url_ent * -fetchList(struct url *URL, const char *flags) -{ - int direct; - - direct = CHECK_FLAG('d'); - if (strcasecmp(URL->scheme, SCHEME_FILE) == 0) - return (fetchListFile(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) - return (fetchListFTP(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTP) == 0) - return (fetchListHTTP(URL, flags)); - else if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0) - return (fetchListHTTP(URL, flags)); - _url_seterr(URL_BAD_SCHEME); - return (NULL); -} - -/* - * Attempt to parse the given URL; if successful, call fetchXGet(). - */ -FILE * -fetchXGetURL(const char *URL, struct url_stat *us, const char *flags) -{ - struct url *u; - FILE *f; - - if ((u = fetchParseURL(URL)) == NULL) - return (NULL); - - f = fetchXGet(u, us, flags); - - fetchFreeURL(u); - return (f); -} - -/* - * Attempt to parse the given URL; if successful, call fetchGet(). - */ -FILE * -fetchGetURL(const char *URL, const char *flags) -{ - return (fetchXGetURL(URL, NULL, flags)); -} - -/* - * Attempt to parse the given URL; if successful, call fetchPut(). - */ -FILE * -fetchPutURL(const char *URL, const char *flags) -{ - struct url *u; - FILE *f; - - if ((u = fetchParseURL(URL)) == NULL) - return (NULL); - - f = fetchPut(u, flags); - - fetchFreeURL(u); - return (f); -} - -/* - * Attempt to parse the given URL; if successful, call fetchStat(). - */ -int -fetchStatURL(const char *URL, struct url_stat *us, const char *flags) -{ - struct url *u; - int s; - - if ((u = fetchParseURL(URL)) == NULL) - return (-1); - - s = fetchStat(u, us, flags); - - fetchFreeURL(u); - return (s); -} - -/* - * Attempt to parse the given URL; if successful, call fetchList(). - */ -struct url_ent * -fetchListURL(const char *URL, const char *flags) -{ - struct url *u; - struct url_ent *ue; - - if ((u = fetchParseURL(URL)) == NULL) - return (NULL); - - ue = fetchList(u, flags); - - fetchFreeURL(u); - return (ue); -} - -/* - * Make a URL - */ -struct url * -fetchMakeURL(const char *scheme, const char *host, int port, const char *doc, - const char *user, const char *pwd) -{ - struct url *u; - - if (!scheme || (!host && !doc)) { - _url_seterr(URL_MALFORMED); - return (NULL); - } - - if (port < 0 || port > 65535) { - _url_seterr(URL_BAD_PORT); - return (NULL); - } - - /* allocate struct url */ - if ((u = calloc(1, sizeof(*u))) == NULL) { - _fetch_syserr(); - return (NULL); - } - - if ((u->doc = strdup(doc ? doc : "/")) == NULL) { - _fetch_syserr(); - free(u); - return (NULL); - } - -#define seturl(x) snprintf(u->x, sizeof(u->x), "%s", x) - seturl(scheme); - seturl(host); - seturl(user); - seturl(pwd); -#undef seturl - u->port = port; - - return (u); -} - -/* - * Split an URL into components. URL syntax is: - * [method:/][/[user[:pwd]@]host[:port]/][document] - * This almost, but not quite, RFC1738 URL syntax. - */ -struct url * -fetchParseURL(const char *URL) -{ - char *doc; - const char *p, *q; - struct url *u; - int i; - - /* allocate struct url */ - if ((u = calloc(1, sizeof(*u))) == NULL) { - _fetch_syserr(); - return (NULL); - } - - /* scheme name */ - if ((p = strstr(URL, ":/"))) { - snprintf(u->scheme, URL_SCHEMELEN+1, - "%.*s", (int)(p - URL), URL); - URL = ++p; - /* - * Only one slash: no host, leave slash as part of document - * Two slashes: host follows, strip slashes - */ - if (URL[1] == '/') - URL = (p += 2); - } else { - p = URL; - } - if (!*URL || *URL == '/' || *URL == '.' || - (u->scheme[0] == '\0' && - strchr(URL, '/') == NULL && strchr(URL, ':') == NULL)) - goto nohost; - - p = strpbrk(URL, "/@"); - if (p && *p == '@') { - /* username */ - for (q = URL, i = 0; (*q != ':') && (*q != '@'); q++) - if (i < URL_USERLEN) - u->user[i++] = *q; - - /* password */ - if (*q == ':') - for (q++, i = 0; (*q != ':') && (*q != '@'); q++) - if (i < URL_PWDLEN) - u->pwd[i++] = *q; - - p++; - } else { - p = URL; - } - - /* hostname */ -#ifdef INET6 - if (*p == '[' && (q = strchr(p + 1, ']')) != NULL && - (*++q == '\0' || *q == '/' || *q == ':')) { - if ((i = q - p - 2) > MAXHOSTNAMELEN) - i = MAXHOSTNAMELEN; - strncpy(u->host, ++p, i); - p = q; - } else -#endif - for (i = 0; *p && (*p != '/') && (*p != ':'); p++) - if (i < MAXHOSTNAMELEN) - u->host[i++] = *p; - - /* port */ - if (*p == ':') { - for (q = ++p; *q && (*q != '/'); q++) - if (isdigit(*q)) - u->port = u->port * 10 + (*q - '0'); - else { - /* invalid port */ - _url_seterr(URL_BAD_PORT); - goto ouch; - } - p = q; - } - -nohost: - /* document */ - if (!*p) - p = "/"; - - if (strcasecmp(u->scheme, SCHEME_HTTP) == 0 || - strcasecmp(u->scheme, SCHEME_HTTPS) == 0) { - const char hexnums[] = "0123456789abcdef"; - - /* percent-escape whitespace. */ - if ((doc = malloc(strlen(p) * 3 + 1)) == NULL) { - _fetch_syserr(); - goto ouch; - } - u->doc = doc; - while (*p != '\0') { - if (!isspace(*p)) { - *doc++ = *p++; - } else { - *doc++ = '%'; - *doc++ = hexnums[((unsigned int)*p) >> 4]; - *doc++ = hexnums[((unsigned int)*p) & 0xf]; - p++; - } - } - *doc = '\0'; - } else if ((u->doc = strdup(p)) == NULL) { - _fetch_syserr(); - goto ouch; - } - - DEBUG(fprintf(stderr, - "scheme: [%s]\n" - "user: [%s]\n" - "password: [%s]\n" - "host: [%s]\n" - "port: [%d]\n" - "document: [%s]\n", - u->scheme, u->user, u->pwd, - u->host, u->port, u->doc)); - - return (u); - -ouch: - free(u); - return (NULL); -} - -/* - * Free a URL - */ -void -fetchFreeURL(struct url *u) -{ - free(u->doc); - free(u); -} diff --git a/lib/libfetch/fetch.h b/lib/libfetch/fetch.h deleted file mode 100644 index 9ade3631..00000000 --- a/lib/libfetch/fetch.h +++ /dev/null @@ -1,153 +0,0 @@ -/*- - * Copyright (c) 1998-2004 Dag-Erling Coďdan Smřrgrav - * 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 - * in this position and unchanged. - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - * - * $FreeBSD: /repoman/r/ncvs/src/lib/libfetch/fetch.h,v 1.26 2004/09/21 18:35:20 des Exp $ - */ - -#ifndef _FETCH_H_INCLUDED -#define _FETCH_H_INCLUDED - -#include <stdio.h> -#include <sys/param.h> /* MAXHOSTNAMELEN */ - -#define _LIBFETCH_VER "libfetch/2.0" - -#define URL_SCHEMELEN 16 -#define URL_USERLEN 256 -#define URL_PWDLEN 256 - -struct url { - char scheme[URL_SCHEMELEN+1]; - char user[URL_USERLEN+1]; - char pwd[URL_PWDLEN+1]; - char host[MAXHOSTNAMELEN+1]; - int port; - char *doc; - off_t offset; - size_t length; -}; - -struct url_stat { - off_t size; - time_t atime; - time_t mtime; -}; - -struct url_ent { - char name[PATH_MAX]; - struct url_stat stat; -}; - -/* Recognized schemes */ -#define SCHEME_FTP "ftp" -#define SCHEME_HTTP "http" -#define SCHEME_HTTPS "https" -#define SCHEME_FILE "file" - -/* Error codes */ -#define FETCH_ABORT 1 -#define FETCH_AUTH 2 -#define FETCH_DOWN 3 -#define FETCH_EXISTS 4 -#define FETCH_FULL 5 -#define FETCH_INFO 6 -#define FETCH_MEMORY 7 -#define FETCH_MOVED 8 -#define FETCH_NETWORK 9 -#define FETCH_OK 10 -#define FETCH_PROTO 11 -#define FETCH_RESOLV 12 -#define FETCH_SERVER 13 -#define FETCH_TEMP 14 -#define FETCH_TIMEOUT 15 -#define FETCH_UNAVAIL 16 -#define FETCH_UNKNOWN 17 -#define FETCH_URL 18 -#define FETCH_VERBOSE 19 - -__BEGIN_DECLS - -/* FILE-specific functions */ -FILE *fetchXGetFile(struct url *, struct url_stat *, const char *); -FILE *fetchGetFile(struct url *, const char *); -FILE *fetchPutFile(struct url *, const char *); -int fetchStatFile(struct url *, struct url_stat *, const char *); -struct url_ent *fetchListFile(struct url *, const char *); - -/* HTTP-specific functions */ -FILE *fetchXGetHTTP(struct url *, struct url_stat *, const char *); -FILE *fetchGetHTTP(struct url *, const char *); -FILE *fetchPutHTTP(struct url *, const char *); -int fetchStatHTTP(struct url *, struct url_stat *, const char *); -struct url_ent *fetchListHTTP(struct url *, const char *); - -/* FTP-specific functions */ -FILE *fetchXGetFTP(struct url *, struct url_stat *, const char *); -FILE *fetchGetFTP(struct url *, const char *); -FILE *fetchPutFTP(struct url *, const char *); -int fetchStatFTP(struct url *, struct url_stat *, const char *); -struct url_ent *fetchListFTP(struct url *, const char *); - -/* Generic functions */ -FILE *fetchXGetURL(const char *, struct url_stat *, const char *); -FILE *fetchGetURL(const char *, const char *); -FILE *fetchPutURL(const char *, const char *); -int fetchStatURL(const char *, struct url_stat *, const char *); -struct url_ent *fetchListURL(const char *, const char *); -FILE *fetchXGet(struct url *, struct url_stat *, const char *); -FILE *fetchGet(struct url *, const char *); -FILE *fetchPut(struct url *, const char *); -int fetchStat(struct url *, struct url_stat *, const char *); -struct url_ent *fetchList(struct url *, const char *); - -/* URL parsing */ -struct url *fetchMakeURL(const char *, const char *, int, - const char *, const char *, const char *); -struct url *fetchParseURL(const char *); -void fetchFreeURL(struct url *); - -__END_DECLS - -/* Authentication */ -typedef int (*auth_t)(struct url *); -extern auth_t fetchAuthMethod; - -/* Last error code */ -extern int fetchLastErrCode; -#define MAXERRSTRING 256 -extern char fetchLastErrString[MAXERRSTRING]; - -/* I/O timeout */ -extern int fetchTimeout; - -/* Restart interrupted syscalls */ -extern int fetchRestartCalls; - -/* Extra verbosity */ -extern int fetchDebug; - -#endif diff --git a/lib/libfetch/file.c b/lib/libfetch/file.c deleted file mode 100644 index ea7a0fdb..00000000 --- a/lib/libfetch/file.c +++ /dev/null @@ -1,145 +0,0 @@ -/*- - * Copyright (c) 1998-2004 Dag-Erling Coďdan Smřrgrav - * 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 - * in this position and unchanged. - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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 <sys/cdefs.h> - -#include <sys/param.h> -#include <sys/stat.h> - -#include <dirent.h> -#include <stdio.h> -#include <string.h> - -#include "fetch.h" -#include "common.h" - -FILE * -fetchXGetFile(struct url *u, struct url_stat *us, const char *flags) -{ - FILE *f; - - if (us && fetchStatFile(u, us, flags) == -1) - return (NULL); - - f = fopen(u->doc, "r"); - - if (f == NULL) - _fetch_syserr(); - - if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { - fclose(f); - _fetch_syserr(); - } - - return (f); -} - -FILE * -fetchGetFile(struct url *u, const char *flags) -{ - return (fetchXGetFile(u, NULL, flags)); -} - -FILE * -fetchPutFile(struct url *u, const char *flags) -{ - FILE *f; - - if (CHECK_FLAG('a')) - f = fopen(u->doc, "a"); - else - f = fopen(u->doc, "w+"); - - if (f == NULL) - _fetch_syserr(); - - if (u->offset && fseeko(f, u->offset, SEEK_SET) == -1) { - fclose(f); - _fetch_syserr(); - } - - return (f); -} - -static int -_fetch_stat_file(const char *fn, struct url_stat *us) -{ - struct stat sb; - - us->size = -1; - us->atime = us->mtime = 0; - if (stat(fn, &sb) == -1) { - _fetch_syserr(); - return (-1); - } - us->size = sb.st_size; - us->atime = sb.st_atime; - us->mtime = sb.st_mtime; - return (0); -} - -int -fetchStatFile(struct url *u, struct url_stat *us, const char *flags) -{ - return (_fetch_stat_file(u->doc, us)); -} - -struct url_ent * -fetchListFile(struct url *u, const char *flags) -{ - struct dirent *de; - struct url_stat us; - struct url_ent *ue; - int size, len; - char fn[PATH_MAX], *p; - DIR *dir; - int l; - - if ((dir = opendir(u->doc)) == NULL) { - _fetch_syserr(); - return (NULL); - } - - ue = NULL; - strncpy(fn, u->doc, sizeof(fn) - 2); - fn[sizeof(fn) - 2] = 0; - strcat(fn, "/"); - p = strchr(fn, 0); - l = sizeof(fn) - strlen(fn) - 1; - - while ((de = readdir(dir)) != NULL) { - strncpy(p, de->d_name, l - 1); - p[l - 1] = 0; - if (_fetch_stat_file(fn, &us) == -1) - /* should I return a partial result, or abort? */ - break; - _fetch_add_entry(&ue, &size, &len, de->d_name, &us); - } - - return (ue); -} diff --git a/lib/libfetch/ftp.c b/lib/libfetch/ftp.c deleted file mode 100644 index a28ec2db..00000000 --- a/lib/libfetch/ftp.c +++ /dev/null @@ -1,1179 +0,0 @@ -/*- - * Copyright (c) 1998-2004 Dag-Erling Coďdan Smřrgrav - * 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 - * in this position and unchanged. - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -#define _GNU_SOURCE - -#include <sys/cdefs.h> - -/* - * Portions of this code were taken from or based on ftpio.c: - * - * ---------------------------------------------------------------------------- - * "THE BEER-WARE LICENSE" (Revision 42): - * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you - * can do whatever you want with this stuff. If we meet some day, and you think - * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp - * ---------------------------------------------------------------------------- - * - * Major Changelog: - * - * Dag-Erling Coďdan Smřrgrav - * 9 Jun 1998 - * - * Incorporated into libfetch - * - * Jordan K. Hubbard - * 17 Jan 1996 - * - * Turned inside out. Now returns xfers as new file ids, not as a special - * `state' of FTP_t - * - * $ftpioId: ftpio.c,v 1.30 1998/04/11 07:28:53 phk Exp $ - * - */ - -#include <sys/param.h> -#include <sys/socket.h> -#include <netinet/in.h> - -#include <ctype.h> -#include <libio.h> -#include <err.h> -#include <errno.h> -#include <fcntl.h> -#include <netdb.h> -#include <stdarg.h> -#include <stdint.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include "fetch.h" -#include "common.h" -#include "ftperr.h" - -#define FTP_ANONYMOUS_USER "anonymous" - -#define FTP_CONNECTION_ALREADY_OPEN 125 -#define FTP_OPEN_DATA_CONNECTION 150 -#define FTP_OK 200 -#define FTP_FILE_STATUS 213 -#define FTP_SERVICE_READY 220 -#define FTP_TRANSFER_COMPLETE 226 -#define FTP_PASSIVE_MODE 227 -#define FTP_LPASSIVE_MODE 228 -#define FTP_EPASSIVE_MODE 229 -#define FTP_LOGGED_IN 230 -#define FTP_FILE_ACTION_OK 250 -#define FTP_DIRECTORY_CREATED 257 /* multiple meanings */ -#define FTP_FILE_CREATED 257 /* multiple meanings */ -#define FTP_WORKING_DIRECTORY 257 /* multiple meanings */ -#define FTP_NEED_PASSWORD 331 -#define FTP_NEED_ACCOUNT 332 -#define FTP_FILE_OK 350 -#define FTP_SYNTAX_ERROR 500 -#define FTP_PROTOCOL_ERROR 999 - -static struct url cached_host; -static conn_t *cached_connection; - -#define isftpreply(foo) (isdigit(foo[0]) && isdigit(foo[1]) \ - && isdigit(foo[2]) \ - && (foo[3] == ' ' || foo[3] == '\0')) -#define isftpinfo(foo) (isdigit(foo[0]) && isdigit(foo[1]) \ - && isdigit(foo[2]) && foo[3] == '-') - -/* - * Translate IPv4 mapped IPv6 address to IPv4 address - */ -static void -unmappedaddr(struct sockaddr_in6 *sin6) -{ - struct sockaddr_in *sin4; - u_int32_t addr; - int port; - - if (sin6->sin6_family != AF_INET6 || - !IN6_IS_ADDR_V4MAPPED(&sin6->sin6_addr)) - return; - sin4 = (struct sockaddr_in *)sin6; - addr = *(u_int32_t *)&sin6->sin6_addr.s6_addr[12]; - port = sin6->sin6_port; - memset(sin4, 0, sizeof(struct sockaddr_in)); - sin4->sin_addr.s_addr = addr; - sin4->sin_port = port; - sin4->sin_family = AF_INET; - //sin6->sin_len = sizeof(struct sockaddr_in); -} - -/* - * Get server response - */ -static int -_ftp_chkerr(conn_t *conn) -{ - if (_fetch_getln(conn) == -1) { - _fetch_syserr(); - return (-1); - } - if (isftpinfo(conn->buf)) { - while (conn->buflen && !isftpreply(conn->buf)) { - if (_fetch_getln(conn) == -1) { - _fetch_syserr(); - return (-1); - } - } - } - - while (conn->buflen && isspace(conn->buf[conn->buflen - 1])) - conn->buflen--; - conn->buf[conn->buflen] = '\0'; - - if (!isftpreply(conn->buf)) { - _ftp_seterr(FTP_PROTOCOL_ERROR); - return (-1); - } - - conn->err = (conn->buf[0] - '0') * 100 - + (conn->buf[1] - '0') * 10 - + (conn->buf[2] - '0'); - - return (conn->err); -} - -/* - * Send a command and check reply - */ -static int -_ftp_cmd(conn_t *conn, const char *fmt, ...) -{ - va_list ap; - size_t len; - char *msg; - int r; - - va_start(ap, fmt); - len = vasprintf(&msg, fmt, ap); - va_end(ap); - - if (msg == NULL) { - errno = ENOMEM; - _fetch_syserr(); - return (-1); - } - - r = _fetch_putln(conn, msg, len); - free(msg); - - if (r == -1) { - _fetch_syserr(); - return (-1); - } - - return (_ftp_chkerr(conn)); -} - -/* - * Return a pointer to the filename part of a path - */ -static const char * -_ftp_filename(const char *file, int *len, int *type) -{ - const char *s; - - if ((s = strrchr(file, '/')) == NULL) - s = file; - else - s = s + 1; - *len = strlen(s); - if (*len > 7 && strncmp(s + *len - 7, ";type=", 6) == 0) { - *type = s[*len - 1]; - *len -= 7; - } else { - *type = '\0'; - } - return (s); -} - -/* - * Get current working directory from the reply to a CWD, PWD or CDUP - * command. - */ -static int -_ftp_pwd(conn_t *conn, char *pwd, size_t pwdlen) -{ - char *src, *dst, *end; - int q; - - if (conn->err != FTP_WORKING_DIRECTORY && - conn->err != FTP_FILE_ACTION_OK) - return (FTP_PROTOCOL_ERROR); - end = conn->buf + conn->buflen; - src = conn->buf + 4; - if (src >= end || *src++ != '"') - return (FTP_PROTOCOL_ERROR); - for (q = 0, dst = pwd; src < end && pwdlen--; ++src) { - if (!q && *src == '"') - q = 1; - else if (q && *src != '"') - break; - else if (q) - *dst++ = '"', q = 0; - else - *dst++ = *src; - } - if (!pwdlen) - return (FTP_PROTOCOL_ERROR); - *dst = '\0'; -#if 0 - DEBUG(fprintf(stderr, "pwd: [%s]\n", pwd)); -#endif - return (FTP_OK); -} - -/* - * Change working directory to the directory that contains the specified - * file. - */ -static int -_ftp_cwd(conn_t *conn, const char *file) -{ - const char *beg, *end; - char pwd[PATH_MAX]; - int e, i, len; - - if ((end = strrchr(file, '/')) == NULL) - return (0); - if ((e = _ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY || - (e = _ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) { - _ftp_seterr(e); - return (-1); - } - for (;;) { - len = strlen(pwd); - /* look for a common prefix */ - for (i = 0; i <= len && i <= end - file; ++i) - if (pwd[i] != file[i]) - break; -#if 0 - DEBUG(fprintf(stderr, "have: [%.*s|%s]\n", i, pwd, pwd + i)); - DEBUG(fprintf(stderr, "want: [%.*s|%s]\n", i, file, file + i)); -#endif - if (pwd[i] == '\0' && (file[i - 1] == '/' || file[i] == '/')) - break; - if ((e = _ftp_cmd(conn, "CDUP")) != FTP_FILE_ACTION_OK || - (e = _ftp_cmd(conn, "PWD")) != FTP_WORKING_DIRECTORY || - (e = _ftp_pwd(conn, pwd, sizeof(pwd))) != FTP_OK) { - _ftp_seterr(e); - return (-1); - } - } - for (beg = file + i; beg < end; beg = file + i + 1) { - while (*beg == '/') - ++beg, ++i; - for (++i; file + i < end && file[i] != '/'; ++i) - /* nothing */; - e = _ftp_cmd(conn, "CWD %.*s", file + i - beg, beg); - if (e != FTP_FILE_ACTION_OK) { - _ftp_seterr(e); - return (-1); - } - } - return (0); -} - -/* - * Set transfer mode and data type - */ -static int -_ftp_mode_type(conn_t *conn, int mode, int type) -{ - int e; - - switch (mode) { - case 0: - case 's': - mode = 'S'; - case 'S': - break; - default: - return (FTP_PROTOCOL_ERROR); - } - if ((e = _ftp_cmd(conn, "MODE %c", mode)) != FTP_OK) { - if (mode == 'S') { - /* - * Stream mode is supposed to be the default - so - * much so that some servers not only do not - * support any other mode, but do not support the - * MODE command at all. - * - * If "MODE S" fails, it is unlikely that we - * previously succeeded in setting a different - * mode. Therefore, we simply hope that the - * server is already in the correct mode, and - * silently ignore the failure. - */ - } else { - return (e); - } - } - - switch (type) { - case 0: - case 'i': - type = 'I'; - case 'I': - break; - case 'a': - type = 'A'; - case 'A': - break; - case 'd': - type = 'D'; - case 'D': - /* can't handle yet */ - default: - return (FTP_PROTOCOL_ERROR); - } - if ((e = _ftp_cmd(conn, "TYPE %c", type)) != FTP_OK) - return (e); - - return (FTP_OK); -} - -/* - * Request and parse file stats - */ -static int -_ftp_stat(conn_t *conn, const char *file, struct url_stat *us) -{ - char *ln; - const char *filename; - int filenamelen, type; - struct tm tm; - time_t t; - int e; - - us->size = -1; - us->atime = us->mtime = 0; - - filename = _ftp_filename(file, &filenamelen, &type); - - if ((e = _ftp_mode_type(conn, 0, type)) != FTP_OK) { - _ftp_seterr(e); - return (-1); - } - - e = _ftp_cmd(conn, "SIZE %.*s", filenamelen, filename); - if (e != FTP_FILE_STATUS) { - _ftp_seterr(e); - return (-1); - } - for (ln = conn->buf + 4; *ln && isspace(*ln); ln++) - /* nothing */ ; - for (us->size = 0; *ln && isdigit(*ln); ln++) - us->size = us->size * 10 + *ln - '0'; - if (*ln && !isspace(*ln)) { - _ftp_seterr(FTP_PROTOCOL_ERROR); - us->size = -1; - return (-1); - } - if (us->size == 0) - us->size = -1; - DEBUG(fprintf(stderr, "size: [%lld]\n", (long long)us->size)); - - e = _ftp_cmd(conn, "MDTM %.*s", filenamelen, filename); - if (e != FTP_FILE_STATUS) { - _ftp_seterr(e); - return (-1); - } - for (ln = conn->buf + 4; *ln && isspace(*ln); ln++) - /* nothing */ ; - switch (strspn(ln, "0123456789")) { - case 14: - break; - case 15: - ln++; - ln[0] = '2'; - ln[1] = '0'; - break; - default: - _ftp_seterr(FTP_PROTOCOL_ERROR); - return (-1); - } - if (sscanf(ln, "%04d%02d%02d%02d%02d%02d", - &tm.tm_year, &tm.tm_mon, &tm.tm_mday, - &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { - _ftp_seterr(FTP_PROTOCOL_ERROR); - return (-1); - } - tm.tm_mon--; - tm.tm_year -= 1900; - tm.tm_isdst = -1; - t = timegm(&tm); - if (t == (time_t)-1) - t = time(NULL); - us->mtime = t; - us->atime = t; - DEBUG(fprintf(stderr, - "last modified: [%04d-%02d-%02d %02d:%02d:%02d]\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec)); - return (0); -} - -/* - * I/O functions for FTP - */ -struct ftpio { - conn_t *cconn; /* Control connection */ - conn_t *dconn; /* Data connection */ - int dir; /* Direction */ - int eof; /* EOF reached */ - int err; /* Error code */ -}; - -static int _ftp_readfn(void *, char *, int); -static int _ftp_writefn(void *, const char *, int); -static fpos_t _ftp_seekfn(void *, fpos_t, int); -static int _ftp_closefn(void *); - -static int -_ftp_readfn(void *v, char *buf, int len) -{ - struct ftpio *io; - int r; - - io = (struct ftpio *)v; - if (io == NULL) { - errno = EBADF; - return (-1); - } - if (io->cconn == NULL || io->dconn == NULL || io->dir == O_WRONLY) { - errno = EBADF; - return (-1); - } - if (io->err) { - errno = io->err; - return (-1); - } - if (io->eof) - return (0); - r = _fetch_read(io->dconn, buf, len); - if (r > 0) - return (r); - if (r == 0) { - io->eof = 1; - return (0); - } - if (errno != EINTR) - io->err = errno; - return (-1); -} - -static int -_ftp_writefn(void *v, const char *buf, int len) -{ - struct ftpio *io; - int w; - - io = (struct ftpio *)v; - if (io == NULL) { - errno = EBADF; - return (-1); - } - if (io->cconn == NULL || io->dconn == NULL || io->dir == O_RDONLY) { - errno = EBADF; - return (-1); - } - if (io->err) { - errno = io->err; - return (-1); - } - w = _fetch_write(io->dconn, buf, len); - if (w >= 0) - return (w); - if (errno != EINTR) - io->err = errno; - return (-1); -} - -static fpos_t -_ftp_seekfn(void *v, fpos_t pos, int whence) -{ - fpos_t invalid = {0}; - struct ftpio *io; - - io = (struct ftpio *)v; - if (io == NULL) { - errno = EBADF; - return invalid; - } - errno = ESPIPE; - return invalid; -} - -static int -_ftp_closefn(void *v) -{ - struct ftpio *io; - int r; - - io = (struct ftpio *)v; - if (io == NULL) { - errno = EBADF; - return (-1); - } - if (io->dir == -1) - return (0); - if (io->cconn == NULL || io->dconn == NULL) { - errno = EBADF; - return (-1); - } - _fetch_close(io->dconn); - io->dir = -1; - io->dconn = NULL; - DEBUG(fprintf(stderr, "Waiting for final status\n")); - r = _ftp_chkerr(io->cconn); - if (io->cconn == cached_connection && io->cconn->ref == 1) - cached_connection = NULL; - _fetch_close(io->cconn); - free(io); - return (r == FTP_TRANSFER_COMPLETE) ? 0 : -1; -} - -static FILE * -_ftp_setup(conn_t *cconn, conn_t *dconn, int mode) -{ - struct ftpio *io; - FILE *f; - - if (cconn == NULL || dconn == NULL) - return (NULL); - if ((io = malloc(sizeof(*io))) == NULL) - return (NULL); - io->cconn = cconn; - io->dconn = dconn; - io->dir = mode; - io->eof = io->err = 0; - cookie_io_functions_t cookies; - cookies.read = (cookie_read_function_t *)_ftp_readfn; - cookies.write = (cookie_write_function_t *)_ftp_writefn; - cookies.seek = (cookie_seek_function_t *)_ftp_seekfn; - cookies.close = (cookie_close_function_t *)_ftp_closefn; - f = fopencookie(io, "rw", cookies); - if (f == NULL) - free(io); - return (f); -} - -/* - * Transfer file - */ -static FILE * -_ftp_transfer(conn_t *conn, const char *oper, const char *file, - int mode, off_t offset, const char *flags) -{ - struct sockaddr_storage sa; - struct sockaddr_in6 *sin6; - struct sockaddr_in *sin4; - const char *bindaddr; - const char *filename; - int filenamelen, type; - int low, pasv, verbose; - int e, sd = -1; - socklen_t l; - char *s; - FILE *df; - - /* check flags */ - low = CHECK_FLAG('l'); - pasv = CHECK_FLAG('p'); - verbose = CHECK_FLAG('v'); - - /* passive mode */ - if (!pasv) - pasv = ((s = getenv("FTP_PASSIVE_MODE")) != NULL && - strncasecmp(s, "no", 2) != 0); - - /* isolate filename */ - filename = _ftp_filename(file, &filenamelen, &type); - - /* set transfer mode and data type */ - if ((e = _ftp_mode_type(conn, 0, type)) != FTP_OK) - goto ouch; - - /* find our own address, bind, and listen */ - l = sizeof(sa); - if (getsockname(conn->sd, (struct sockaddr *)&sa, &l) == -1) - goto sysouch; - if (sa.ss_family == AF_INET6) - unmappedaddr((struct sockaddr_in6 *)&sa); - - /* open data socket */ - if ((sd = socket(sa.ss_family, SOCK_STREAM, IPPROTO_TCP)) == -1) { - _fetch_syserr(); - return (NULL); - } - - if (pasv) { - u_char addr[64]; - char *ln, *p; - unsigned int i; - int port; - - /* send PASV command */ - if (verbose) - _fetch_info("setting passive mode"); - switch (sa.ss_family) { - case AF_INET: - if ((e = _ftp_cmd(conn, "PASV")) != FTP_PASSIVE_MODE) - goto ouch; - break; - case AF_INET6: - if ((e = _ftp_cmd(conn, "EPSV")) != FTP_EPASSIVE_MODE) { - if (e == -1) - goto ouch; - if ((e = _ftp_cmd(conn, "LPSV")) != - FTP_LPASSIVE_MODE) - goto ouch; - } - break; - default: - e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ - goto ouch; - } - - /* - * Find address and port number. The reply to the PASV command - * is IMHO the one and only weak point in the FTP protocol. - */ - ln = conn->buf; - switch (e) { - case FTP_PASSIVE_MODE: - case FTP_LPASSIVE_MODE: - for (p = ln + 3; *p && !isdigit(*p); p++) - /* nothing */ ; - if (!*p) { - e = FTP_PROTOCOL_ERROR; - goto ouch; - } - l = (e == FTP_PASSIVE_MODE ? 6 : 21); - for (i = 0; *p && i < l; i++, p++) - addr[i] = strtol(p, &p, 10); - if (i < l) { - e = FTP_PROTOCOL_ERROR; - goto ouch; - } - break; - case FTP_EPASSIVE_MODE: - for (p = ln + 3; *p && *p != '('; p++) - /* nothing */ ; - if (!*p) { - e = FTP_PROTOCOL_ERROR; - goto ouch; - } - ++p; - if (sscanf(p, "%c%c%c%d%c", &addr[0], &addr[1], &addr[2], - &port, &addr[3]) != 5 || - addr[0] != addr[1] || - addr[0] != addr[2] || addr[0] != addr[3]) { - e = FTP_PROTOCOL_ERROR; - goto ouch; - } - break; - } - - /* seek to required offset */ - if (offset) - if (_ftp_cmd(conn, "REST %lu", (u_long)offset) != FTP_FILE_OK) - goto sysouch; - - /* construct sockaddr for data socket */ - l = sizeof(sa); - if (getpeername(conn->sd, (struct sockaddr *)&sa, &l) == -1) - goto sysouch; - if (sa.ss_family == AF_INET6) - unmappedaddr((struct sockaddr_in6 *)&sa); - switch (sa.ss_family) { - case AF_INET6: - sin6 = (struct sockaddr_in6 *)&sa; - if (e == FTP_EPASSIVE_MODE) - sin6->sin6_port = htons(port); - else { - bcopy(addr + 2, (char *)&sin6->sin6_addr, 16); - bcopy(addr + 19, (char *)&sin6->sin6_port, 2); - } - break; - case AF_INET: - sin4 = (struct sockaddr_in *)&sa; - if (e == FTP_EPASSIVE_MODE) - sin4->sin_port = htons(port); - else { - bcopy(addr, (char *)&sin4->sin_addr, 4); - bcopy(addr + 4, (char *)&sin4->sin_port, 2); - } - break; - default: - e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ - break; - } - - /* connect to data port */ - if (verbose) - _fetch_info("opening data connection"); - bindaddr = getenv("FETCH_BIND_ADDRESS"); - if (bindaddr != NULL && *bindaddr != '\0' && - _fetch_bind(sd, sa.ss_family, bindaddr) != 0) - goto sysouch; - if (connect(sd, (struct sockaddr *)&sa, sizeof(struct sockaddr_storage)) == -1) - goto sysouch; - - /* make the server initiate the transfer */ - if (verbose) - _fetch_info("initiating transfer"); - e = _ftp_cmd(conn, "%s %.*s", oper, filenamelen, filename); - if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) - goto ouch; - - } else { - u_int32_t a; - u_short p; - int d; -#ifdef IPV6_PORTRANGE - int arg; -#endif - char *ap; - char hname[INET6_ADDRSTRLEN]; - - switch (sa.ss_family) { - case AF_INET6: - ((struct sockaddr_in6 *)&sa)->sin6_port = 0; -#ifdef IPV6_PORTRANGE - arg = low ? IPV6_PORTRANGE_DEFAULT : IPV6_PORTRANGE_HIGH; - if (setsockopt(sd, IPPROTO_IPV6, IPV6_PORTRANGE, - (char *)&arg, sizeof(arg)) == -1) - goto sysouch; -#endif - break; - case AF_INET: - ((struct sockaddr_in *)&sa)->sin_port = 0; -#ifdef IP_PORTRANGE - arg = low ? IP_PORTRANGE_DEFAULT : IP_PORTRANGE_HIGH; - if (setsockopt(sd, IPPROTO_IP, IP_PORTRANGE, - (char *)&arg, sizeof(arg)) == -1) - goto sysouch; -#endif - break; - } - if (verbose) - _fetch_info("binding data socket"); - if (bind(sd, (struct sockaddr *)&sa, sizeof(struct sockaddr_storage)) == -1) - goto sysouch; - if (listen(sd, 1) == -1) - goto sysouch; - - /* find what port we're on and tell the server */ - if (getsockname(sd, (struct sockaddr *)&sa, &l) == -1) - goto sysouch; - switch (sa.ss_family) { - case AF_INET: - sin4 = (struct sockaddr_in *)&sa; - a = ntohl(sin4->sin_addr.s_addr); - p = ntohs(sin4->sin_port); - e = _ftp_cmd(conn, "PORT %d,%d,%d,%d,%d,%d", - (a >> 24) & 0xff, (a >> 16) & 0xff, - (a >> 8) & 0xff, a & 0xff, - (p >> 8) & 0xff, p & 0xff); - break; - case AF_INET6: -#define UC(b) (((int)b)&0xff) - e = -1; - sin6 = (struct sockaddr_in6 *)&sa; - sin6->sin6_scope_id = 0; - if (getnameinfo((struct sockaddr *)&sa,sizeof(struct sockaddr_storage), - hname, sizeof(hname), - NULL, 0, NI_NUMERICHOST) == 0) { - e = _ftp_cmd(conn, "EPRT |%d|%s|%d|", 2, hname, - htons(sin6->sin6_port)); - if (e == -1) - goto ouch; - } - if (e != FTP_OK) { - ap = (char *)&sin6->sin6_addr; - e = _ftp_cmd(conn, - "LPRT %d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d", - 6, 16, - UC(ap[0]), UC(ap[1]), UC(ap[2]), UC(ap[3]), - UC(ap[4]), UC(ap[5]), UC(ap[6]), UC(ap[7]), - UC(ap[8]), UC(ap[9]), UC(ap[10]), UC(ap[11]), - UC(ap[12]), UC(ap[13]), UC(ap[14]), UC(ap[15]), - 2, - (ntohs(sin6->sin6_port) >> 8) & 0xff, - ntohs(sin6->sin6_port) & 0xff); - } - break; - default: - e = FTP_PROTOCOL_ERROR; /* XXX: error code should be prepared */ - goto ouch; - } - if (e != FTP_OK) - goto ouch; - - /* seek to required offset */ - if (offset) - if (_ftp_cmd(conn, "REST %ju", (uintmax_t)offset) != FTP_FILE_OK) - goto sysouch; - - /* make the server initiate the transfer */ - if (verbose) - _fetch_info("initiating transfer"); - e = _ftp_cmd(conn, "%s %.*s", oper, filenamelen, filename); - if (e != FTP_CONNECTION_ALREADY_OPEN && e != FTP_OPEN_DATA_CONNECTION) - goto ouch; - - /* accept the incoming connection and go to town */ - if ((d = accept(sd, NULL, NULL)) == -1) - goto sysouch; - close(sd); - sd = d; - } - - if ((df = _ftp_setup(conn, _fetch_reopen(sd), mode)) == NULL) - goto sysouch; - return (df); - -sysouch: - _fetch_syserr(); - if (sd >= 0) - close(sd); - return (NULL); - -ouch: - if (e != -1) - _ftp_seterr(e); - if (sd >= 0) - close(sd); - return (NULL); -} - -/* - * Authenticate - */ -static int -_ftp_authenticate(conn_t *conn, struct url *url, struct url *purl) -{ - const char *user, *pwd, *logname; - char pbuf[MAXHOSTNAMELEN + MAXPATHLEN + 1]; - int e, len; - - /* XXX FTP_AUTH, and maybe .netrc */ - - /* send user name and password */ - if (url->user[0] == '\0') - _fetch_netrc_auth(url); - user = url->user; - if (*user == '\0') - user = getenv("FTP_LOGIN"); - if (user == NULL || *user == '\0') - user = FTP_ANONYMOUS_USER; - if (purl && url->port == _fetch_default_port(url->scheme)) - e = _ftp_cmd(conn, "USER %s@%s", user, url->host); - else if (purl) - e = _ftp_cmd(conn, "USER %s@%s@%d", user, url->host, url->port); - else - e = _ftp_cmd(conn, "USER %s", user); - - /* did the server request a password? */ - if (e == FTP_NEED_PASSWORD) { - pwd = url->pwd; - if (*pwd == '\0') - pwd = getenv("FTP_PASSWORD"); - if (pwd == NULL || *pwd == '\0') { - if ((logname = getlogin()) == 0) - logname = FTP_ANONYMOUS_USER; - if ((len = snprintf(pbuf, MAXPATHLEN + 1, "%s@", logname)) < 0) - len = 0; - else if (len > MAXPATHLEN) - len = MAXPATHLEN; - gethostname(pbuf + len, sizeof(pbuf) - len); - pwd = pbuf; - } - e = _ftp_cmd(conn, "PASS %s", pwd); - } - - return (e); -} - -/* - * Log on to FTP server - */ -static conn_t * -_ftp_connect(struct url *url, struct url *purl, const char *flags) -{ - conn_t *conn; - int e, direct, verbose; -#ifdef INET6 - int af = AF_UNSPEC; -#else - int af = AF_INET; -#endif - - direct = CHECK_FLAG('d'); - verbose = CHECK_FLAG('v'); - if (CHECK_FLAG('4')) - af = AF_INET; - else if (CHECK_FLAG('6')) - af = AF_INET6; - - if (direct) - purl = NULL; - - /* check for proxy */ - if (purl) { - /* XXX proxy authentication! */ - conn = _fetch_connect(purl->host, purl->port, af, verbose); - } else { - /* no proxy, go straight to target */ - conn = _fetch_connect(url->host, url->port, af, verbose); - purl = NULL; - } - - /* check connection */ - if (conn == NULL) - /* _fetch_connect() has already set an error code */ - return (NULL); - - /* expect welcome message */ - if ((e = _ftp_chkerr(conn)) != FTP_SERVICE_READY) - goto fouch; - - /* authenticate */ - if ((e = _ftp_authenticate(conn, url, purl)) != FTP_LOGGED_IN) - goto fouch; - - /* done */ - return (conn); - -fouch: - if (e != -1) - _ftp_seterr(e); - _fetch_close(conn); - return (NULL); -} - -/* - * Disconnect from server - */ -static void -_ftp_disconnect(conn_t *conn) -{ - (void)_ftp_cmd(conn, "QUIT"); - if (conn == cached_connection && conn->ref == 1) - cached_connection = NULL; - _fetch_close(conn); -} - -/* - * Check if we're already connected - */ -static int -_ftp_isconnected(struct url *url) -{ - return (cached_connection - && (strcmp(url->host, cached_host.host) == 0) - && (strcmp(url->user, cached_host.user) == 0) - && (strcmp(url->pwd, cached_host.pwd) == 0) - && (url->port == cached_host.port)); -} - -/* - * Check the cache, reconnect if no luck - */ -static conn_t * -_ftp_cached_connect(struct url *url, struct url *purl, const char *flags) -{ - conn_t *conn; - int e; - - /* set default port */ - if (!url->port) - url->port = _fetch_default_port(url->scheme); - - /* try to use previously cached connection */ - if (_ftp_isconnected(url)) { - e = _ftp_cmd(cached_connection, "NOOP"); - if (e == FTP_OK || e == FTP_SYNTAX_ERROR) - return (_fetch_ref(cached_connection)); - } - - /* connect to server */ - if ((conn = _ftp_connect(url, purl, flags)) == NULL) - return (NULL); - if (cached_connection) - _ftp_disconnect(cached_connection); - cached_connection = _fetch_ref(conn); - memcpy(&cached_host, url, sizeof(*url)); - return (conn); -} - -/* - * Check the proxy settings - */ -static struct url * -_ftp_get_proxy(const char *flags) -{ - struct url *purl; - char *p; - - if (flags != NULL && strchr(flags, 'd') != NULL) - return (NULL); - if (((p = getenv("FTP_PROXY")) || (p = getenv("ftp_proxy")) || - (p = getenv("HTTP_PROXY")) || (p = getenv("http_proxy"))) && - *p && (purl = fetchParseURL(p)) != NULL) { - if (!*purl->scheme) { - if (getenv("FTP_PROXY") || getenv("ftp_proxy")) - strcpy(purl->scheme, SCHEME_FTP); - else - strcpy(purl->scheme, SCHEME_HTTP); - } - if (!purl->port) - purl->port = _fetch_default_proxy_port(purl->scheme); - if (strcasecmp(purl->scheme, SCHEME_FTP) == 0 || - strcasecmp(purl->scheme, SCHEME_HTTP) == 0) - return (purl); - fetchFreeURL(purl); - } - return (NULL); -} - -/* - * Process an FTP request - */ -FILE * -_ftp_request(struct url *url, const char *op, struct url_stat *us, - struct url *purl, const char *flags) -{ - conn_t *conn; - int oflag; - - /* check if we should use HTTP instead */ - if (purl && strcasecmp(purl->scheme, SCHEME_HTTP) == 0) { - if (strcmp(op, "STAT") == 0) - return (_http_request(url, "HEAD", us, purl, flags)); - else if (strcmp(op, "RETR") == 0) - return (_http_request(url, "GET", us, purl, flags)); - /* - * Our HTTP code doesn't support PUT requests yet, so try - * a direct connection. - */ - } - - /* connect to server */ - conn = _ftp_cached_connect(url, purl, flags); - if (purl) - fetchFreeURL(purl); - if (conn == NULL) - return (NULL); - - /* change directory */ - if (_ftp_cwd(conn, url->doc) == -1) - return (NULL); - - /* stat file */ - if (us && _ftp_stat(conn, url->doc, us) == -1 - && fetchLastErrCode != FETCH_PROTO - && fetchLastErrCode != FETCH_UNAVAIL) - return (NULL); - - /* just a stat */ - if (strcmp(op, "STAT") == 0) - return (FILE *)1; /* bogus return value */ - if (strcmp(op, "STOR") == 0 || strcmp(op, "APPE") == 0) - oflag = O_WRONLY; - else - oflag = O_RDONLY; - - /* initiate the transfer */ - return (_ftp_transfer(conn, op, url->doc, oflag, url->offset, flags)); -} - -/* - * Get and stat file - */ -FILE * -fetchXGetFTP(struct url *url, struct url_stat *us, const char *flags) -{ - return (_ftp_request(url, "RETR", us, _ftp_get_proxy(flags), flags)); -} - -/* - * Get file - */ -FILE * -fetchGetFTP(struct url *url, const char *flags) -{ - return (fetchXGetFTP(url, NULL, flags)); -} - -/* - * Put file - */ -FILE * -fetchPutFTP(struct url *url, const char *flags) -{ - - return (_ftp_request(url, CHECK_FLAG('a') ? "APPE" : "STOR", NULL, - _ftp_get_proxy(flags), flags)); -} - -/* - * Get file stats - */ -int -fetchStatFTP(struct url *url, struct url_stat *us, const char *flags) -{ - FILE *f; - - f = _ftp_request(url, "STAT", us, _ftp_get_proxy(flags), flags); - if (f == NULL) - return (-1); - return (0); -} - -/* - * List a directory - */ -struct url_ent * -fetchListFTP(struct url *url, const char *flags) -{ - warnx("fetchListFTP(): not implemented"); - return (NULL); -} diff --git a/lib/libfetch/ftp.errors b/lib/libfetch/ftp.errors deleted file mode 100644 index 8d9d555f..00000000 --- a/lib/libfetch/ftp.errors +++ /dev/null @@ -1,47 +0,0 @@ -# $FreeBSD: /repoman/r/ncvs/src/lib/libfetch/ftp.errors,v 1.6 2002/10/30 06:06:16 des Exp $ -# -# This list is taken from RFC 959. -# It probably needs a going over. -# -110 OK Restart marker reply -120 TEMP Service ready in a few minutes -125 OK Data connection already open; transfer starting -150 OK File status okay; about to open data connection -200 OK Command okay -202 PROTO Command not implemented, superfluous at this site -211 INFO System status, or system help reply -212 INFO Directory status -213 INFO File status -214 INFO Help message -215 INFO Set system type -220 OK Service ready for new user -221 OK Service closing control connection -225 OK Data connection open; no transfer in progress -226 OK Requested file action successful -227 OK Entering Passive Mode -229 OK Entering Extended Passive Mode -230 OK User logged in, proceed -250 OK Requested file action okay, completed -257 OK File/directory created -331 AUTH User name okay, need password -332 AUTH Need account for login -350 OK Requested file action pending further information -421 DOWN Service not available, closing control connection -425 NETWORK Can't open data connection -426 ABORT Connection closed; transfer aborted -450 UNAVAIL File unavailable (e.g., file busy) -451 SERVER Requested action aborted: local error in processing -452 FULL Insufficient storage space in system -500 PROTO Syntax error, command unrecognized -501 PROTO Syntax error in parameters or arguments -502 PROTO Command not implemented -503 PROTO Bad sequence of commands -504 PROTO Command not implemented for that parameter -530 AUTH Not logged in -532 AUTH Need account for storing files -535 PROTO Bug in MediaHawk Video Kernel FTP server -550 UNAVAIL File unavailable (e.g., file not found, no access) -551 PROTO Requested action aborted. Page type unknown -552 FULL Exceeded storage allocation -553 EXISTS File name not allowed -999 PROTO Protocol error diff --git a/lib/libfetch/http.c b/lib/libfetch/http.c deleted file mode 100644 index c173b5d5..00000000 --- a/lib/libfetch/http.c +++ /dev/null @@ -1,1225 +0,0 @@ -/*- - * Copyright (c) 2000-2004 Dag-Erling Coďdan Smřrgrav - * 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 - * in this position and unchanged. - * 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. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -#define _GNU_SOURCE - -#include <sys/cdefs.h> - -/* - * The following copyright applies to the base64 code: - * - *- - * Copyright 1997 Massachusetts Institute of Technology - * - * Permission to use, copy, modify, and distribute this software and - * its documentation for any purpose and without fee is hereby - * granted, provided that both the above copyright notice and this - * permission notice appear in all copies, that both the above - * copyright notice and this permission notice appear in all - * supporting documentation, and that the name of M.I.T. not be used - * in advertising or publicity pertaining to distribution of the - * software without specific, written prior permission. M.I.T. makes - * no representations about the suitability of this software for any - * purpose. It is provided "as is" without express or implied - * warranty. - * - * THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS - * ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE, - * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT - * SHALL M.I.T. 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 <sys/param.h> -#include <sys/socket.h> - -#include <ctype.h> -#include <libio.h> -#include <err.h> -#include <errno.h> -#include <locale.h> -#include <netdb.h> -#include <stdarg.h> -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <time.h> -#include <unistd.h> - -#include <netinet/in.h> -#include <netinet/tcp.h> - -#include "fetch.h" -#include "common.h" -#include "httperr.h" - -/* Maximum number of redirects to follow */ -#define MAX_REDIRECT 5 - -/* Symbolic names for reply codes we care about */ -#define HTTP_OK 200 -#define HTTP_PARTIAL 206 -#define HTTP_MOVED_PERM 301 -#define HTTP_MOVED_TEMP 302 -#define HTTP_SEE_OTHER 303 -#define HTTP_NEED_AUTH 401 -#define HTTP_NEED_PROXY_AUTH 407 -#define HTTP_BAD_RANGE 416 -#define HTTP_PROTOCOL_ERROR 999 - -#define HTTP_REDIRECT(xyz) ((xyz) == HTTP_MOVED_PERM \ - || (xyz) == HTTP_MOVED_TEMP \ - || (xyz) == HTTP_SEE_OTHER) - -#define HTTP_ERROR(xyz) ((xyz) > 400 && (xyz) < 599) - - -/***************************************************************************** - * I/O functions for decoding chunked streams - */ - -struct httpio -{ - conn_t *conn; /* connection */ - int chunked; /* chunked mode */ - char *buf; /* chunk buffer */ - size_t bufsize; /* size of chunk buffer */ - ssize_t buflen; /* amount of data currently in buffer */ - int bufpos; /* current read offset in buffer */ - int eof; /* end-of-file flag */ - int error; /* error flag */ - size_t chunksize; /* remaining size of current chunk */ -#ifndef NDEBUG - size_t total; -#endif -}; - -/* - * Get next chunk header - */ -static int -_http_new_chunk(struct httpio *io) -{ - char hexdigits[23] = "0123456789abcdefABCDEF\0"; - char *p = NULL; - - if (_fetch_getln(io->conn) == -1) - return (-1); - - if (io->conn->buflen < 2 || !strchr(hexdigits, *p)) - return (-1); - - for (p = io->conn->buf; *p && !isspace(*p); ++p) { - if (*p == ';') - break; - if (!strchr(hexdigits, *p)) - return (-1); - if (isdigit(*p)) { - io->chunksize = io->chunksize * 16 + - *p - '0'; - } else { - io->chunksize = io->chunksize * 16 + - 10 + tolower(*p) - 'a'; - } - } - -#ifndef NDEBUG - if (fetchDebug) { - io->total += io->chunksize; - if (io->chunksize == 0) - fprintf(stderr, "%s(): end of last chunk\n", __func__); - else - fprintf(stderr, "%s(): new chunk: %lu (%lu)\n", - __func__, (unsigned long)io->chunksize, - (unsigned long)io->total); - } -#endif - - return (io->chunksize); -} - -/* - * Grow the input buffer to at least len bytes - */ -static inline int -_http_growbuf(struct httpio *io, size_t len) -{ - char *tmp; - - if (io->bufsize >= len) - return (0); - - if ((tmp = realloc(io->buf, len)) == NULL) - return (-1); - io->buf = tmp; - io->bufsize = len; - return (0); -} - -/* - * Fill the input buffer, do chunk decoding on the fly - */ -static int -_http_fillbuf(struct httpio *io, size_t len) -{ - if (io->error) - return (-1); - if (io->eof) - return (0); - - if (io->chunked == 0) { - if (_http_growbuf(io, len) == -1) - return (-1); - if ((io->buflen = _fetch_read(io->conn, io->buf, len)) == -1) { - io->error = 1; - return (-1); - } - io->bufpos = 0; - return (io->buflen); - } - - if (io->chunksize == 0) { - switch (_http_new_chunk(io)) { - case -1: - io->error = 1; - return (-1); - case 0: - io->eof = 1; - return (0); - } - } - - if (len > io->chunksize) - len = io->chunksize; - if (_http_growbuf(io, len) == -1) - return (-1); - if ((io->buflen = _fetch_read(io->conn, io->buf, len)) == -1) { - io->error = 1; - return (-1); - } - io->chunksize -= io->buflen; - - if (io->chunksize == 0) { - char endl[2]; - - if (_fetch_read(io->conn, endl, 2) != 2 || - endl[0] != '\r' || endl[1] != '\n') - return (-1); - } - - io->bufpos = 0; - - return (io->buflen); -} - -/* - * Read function - */ -static int -_http_readfn(void *v, char *buf, int len) -{ - struct httpio *io = (struct httpio *)v; - int l, pos; - - if (io->error) - return (-1); - if (io->eof) - return (0); - - for (pos = 0; len > 0; pos += l, len -= l) { - /* empty buffer */ - if (!io->buf || io->bufpos == io->buflen) - if (_http_fillbuf(io, len) < 1) - break; - l = io->buflen - io->bufpos; - if (len < l) - l = len; - bcopy(io->buf + io->bufpos, buf + pos, l); - io->bufpos += l; - } - - if (!pos && io->error) - return (-1); - return (pos); -} - -/* - * Write function - */ -static int -_http_writefn(void *v, const char *buf, int len) -{ - struct httpio *io = (struct httpio *)v; - - return (_fetch_write(io->conn, buf, len)); -} - -/* - * Close function - */ -static int -_http_closefn(void *v) -{ - struct httpio *io = (struct httpio *)v; - int r; - - r = _fetch_close(io->conn); - if (io->buf) - free(io->buf); - free(io); - return (r); -} - -/* - * Wrap a file descriptor up - */ -static FILE * -_http_funopen(conn_t *conn, int chunked) -{ - struct httpio *io; - FILE *f; - - if ((io = calloc(1, sizeof(*io))) == NULL) { - _fetch_syserr(); - return (NULL); - } - io->conn = conn; - io->chunked = chunked; - cookie_io_functions_t cookie; - cookie.read = (cookie_read_function_t *)_http_readfn; - cookie.write = (cookie_write_function_t *)_http_writefn; - cookie.seek = (cookie_seek_function_t *)NULL; - cookie.close = (cookie_close_function_t *)_http_closefn; - f = fopencookie(io, "rw", cookie); - if (f == NULL) { - _fetch_syserr(); - free(io); - return (NULL); - } - return (f); -} - - -/***************************************************************************** - * Helper functions for talking to the server and parsing its replies - */ - -/* Header types */ -typedef enum { - hdr_syserror = -2, - hdr_error = -1, - hdr_end = 0, - hdr_unknown = 1, - hdr_content_length, - hdr_content_range, - hdr_last_modified, - hdr_location, - hdr_transfer_encoding, - hdr_www_authenticate -} hdr_t; - -/* Names of interesting headers */ -static struct { - hdr_t num; - const char *name; -} hdr_names[] = { - { hdr_content_length, "Content-Length" }, - { hdr_content_range, "Content-Range" }, - { hdr_last_modified, "Last-Modified" }, - { hdr_location, "Location" }, - { hdr_transfer_encoding, "Transfer-Encoding" }, - { hdr_www_authenticate, "WWW-Authenticate" }, - { hdr_unknown, NULL }, -}; - -/* - * Send a formatted line; optionally echo to terminal - */ -static int -_http_cmd(conn_t *conn, const char *fmt, ...) -{ - va_list ap; - size_t len; - char *msg; - int r; - - va_start(ap, fmt); - len = vasprintf(&msg, fmt, ap); - va_end(ap); - - if (msg == NULL) { - errno = ENOMEM; - _fetch_syserr(); - return (-1); - } - - r = _fetch_putln(conn, msg, len); - free(msg); - - if (r == -1) { - _fetch_syserr(); - return (-1); - } - - return (0); -} - -/* - * Get and parse status line - */ -static int -_http_get_reply(conn_t *conn) -{ - char *p; - - if (_fetch_getln(conn) == -1) - return (-1); - /* - * A valid status line looks like "HTTP/m.n xyz reason" where m - * and n are the major and minor protocol version numbers and xyz - * is the reply code. - * Unfortunately, there are servers out there (NCSA 1.5.1, to name - * just one) that do not send a version number, so we can't rely - * on finding one, but if we do, insist on it being 1.0 or 1.1. - * We don't care about the reason phrase. - */ - if (strncmp(conn->buf, "HTTP", 4) != 0) - return (HTTP_PROTOCOL_ERROR); - p = conn->buf + 4; - if (*p == '/') { - if (p[1] != '1' || p[2] != '.' || (p[3] != '0' && p[3] != '1')) - return (HTTP_PROTOCOL_ERROR); - p += 4; - } - if (*p != ' ' || !isdigit(p[1]) || !isdigit(p[2]) || !isdigit(p[3])) - return (HTTP_PROTOCOL_ERROR); - - conn->err = (p[1] - '0') * 100 + (p[2] - '0') * 10 + (p[3] - '0'); - return (conn->err); -} - -/* - * Check a header; if the type matches the given string, return a pointer - * to the beginning of the value. - */ -static const char * -_http_match(const char *str, const char *hdr) -{ - while (*str && *hdr && tolower(*str++) == tolower(*hdr++)) - /* nothing */; - if (*str || *hdr != ':') - return (NULL); - while (*hdr && isspace(*++hdr)) - /* nothing */; - return (hdr); -} - -/* - * Get the next header and return the appropriate symbolic code. - */ -static hdr_t -_http_next_header(conn_t *conn, const char **p) -{ - int i; - - if (_fetch_getln(conn) == -1) - return (hdr_syserror); - while (conn->buflen && isspace(conn->buf[conn->buflen - 1])) - conn->buflen--; - conn->buf[conn->buflen] = '\0'; - if (conn->buflen == 0) - return (hdr_end); - /* - * We could check for malformed headers but we don't really care. - * A valid header starts with a token immediately followed by a - * colon; a token is any sequence of non-control, non-whitespace - * characters except "()<>@,;:\\\"{}". - */ - for (i = 0; hdr_names[i].num != hdr_unknown; i++) - if ((*p = _http_match(hdr_names[i].name, conn->buf)) != NULL) - return (hdr_names[i].num); - return (hdr_unknown); -} - -/* - * Parse a last-modified header - */ -static int -_http_parse_mtime(const char *p, time_t *mtime) -{ - char locale[64], *r; - struct tm tm; - - strncpy(locale, setlocale(LC_TIME, NULL), sizeof(locale)); - setlocale(LC_TIME, "C"); - r = (char *)strptime(p, "%a, %d %b %Y %H:%M:%S GMT", &tm); - /* XXX should add support for date-2 and date-3 */ - setlocale(LC_TIME, locale); - if (r == NULL) - return (-1); - DEBUG(fprintf(stderr, "last modified: [%04d-%02d-%02d " - "%02d:%02d:%02d]\n", - tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, - tm.tm_hour, tm.tm_min, tm.tm_sec)); - *mtime = timegm(&tm); - return (0); -} - -/* - * Parse a content-length header - */ -static int -_http_parse_length(const char *p, off_t *length) -{ - off_t len; - - for (len = 0; *p && isdigit(*p); ++p) - len = len * 10 + (*p - '0'); - if (*p) - return (-1); - DEBUG(fprintf(stderr, "content length: [%lld]\n", - (long long)len)); - *length = len; - return (0); -} - -/* - * Parse a content-range header - */ -static int -_http_parse_range(const char *p, off_t *offset, off_t *length, off_t *size) -{ - off_t first, last, len; - - if (strncasecmp(p, "bytes ", 6) != 0) - return (-1); - p += 6; - if (*p == '*') { - first = last = -1; - ++p; - } else { - for (first = 0; *p && isdigit(*p); ++p) - first = first * 10 + *p - '0'; - if (*p != '-') - return (-1); - for (last = 0, ++p; *p && isdigit(*p); ++p) - last = last * 10 + *p - '0'; - } - if (first > last || *p != '/') - return (-1); - for (len = 0, ++p; *p && isdigit(*p); ++p) - len = len * 10 + *p - '0'; - if (*p || len < last - first + 1) - return (-1); - if (first == -1) { - DEBUG(fprintf(stderr, "content range: [*/%lld]\n", - (long long)len)); - *length = 0; - } else { - DEBUG(fprintf(stderr, "content range: [%lld-%lld/%lld]\n", - (long long)first, (long long)last, (long long)len)); - *length = last - first + 1; - } - *offset = first; - *size = len; - return (0); -} - - -/***************************************************************************** - * Helper functions for authorization - */ - -/* - * Base64 encoding - */ -static char * -_http_base64(const char *src) -{ - static const char base64[] = - "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "abcdefghijklmnopqrstuvwxyz" - "0123456789+/"; - char *str, *dst; - size_t l; - int t, r; - - l = strlen(src); - if ((str = malloc(((l + 2) / 3) * 4 + 1)) == NULL) - return (NULL); - dst = str; - r = 0; - - while (l >= 3) { - t = (src[0] << 16) | (src[1] << 8) | src[2]; - dst[0] = base64[(t >> 18) & 0x3f]; - dst[1] = base64[(t >> 12) & 0x3f]; - dst[2] = base64[(t >> 6) & 0x3f]; - dst[3] = base64[(t >> 0) & 0x3f]; - src += 3; l -= 3; - dst += 4; r += 4; - } - - switch (l) { - case 2: - t = (src[0] << 16) | (src[1] << 8); - dst[0] = base64[(t >> 18) & 0x3f]; - dst[1] = base64[(t >> 12) & 0x3f]; - dst[2] = base64[(t >> 6) & 0x3f]; - dst[3] = '='; - dst += 4; - r += 4; - break; - case 1: - t = src[0] << 16; - dst[0] = base64[(t >> 18) & 0x3f]; - dst[1] = base64[(t >> 12) & 0x3f]; - dst[2] = dst[3] = '='; - dst += 4; - r += 4; - break; - case 0: - break; - } - - *dst = 0; - return (str); -} - -/* - * Encode username and password - */ -static int -_http_basic_auth(conn_t *conn, const char *hdr, const char *usr, const char *pwd) -{ - char *upw, *auth; - int r; - - DEBUG(fprintf(stderr, "usr: [%s]\n", usr)); - DEBUG(fprintf(stderr, "pwd: [%s]\n", pwd)); - if (asprintf(&upw, "%s:%s", usr, pwd) == -1) - return (-1); - auth = _http_base64(upw); - free(upw); - if (auth == NULL) - return (-1); - r = _http_cmd(conn, "%s: Basic %s", hdr, auth); - free(auth); - return (r); -} - -/* - * Send an authorization header - */ -static int -_http_authorize(conn_t *conn, const char *hdr, const char *p) -{ - /* basic authorization */ - if (strncasecmp(p, "basic:", 6) == 0) { - char *user, *pwd, *str; - int r; - - /* skip realm */ - for (p += 6; *p && *p != ':'; ++p) - /* nothing */ ; - if (!*p || strchr(++p, ':') == NULL) - return (-1); - if ((str = strdup(p)) == NULL) - return (-1); /* XXX */ - user = str; - pwd = strchr(str, ':'); - *pwd++ = '\0'; - r = _http_basic_auth(conn, hdr, user, pwd); - free(str); - return (r); - } - return (-1); -} - - -/***************************************************************************** - * Helper functions for connecting to a server or proxy - */ - -/* - * Connect to the correct HTTP server or proxy. - */ -static conn_t * -_http_connect(struct url *URL, struct url *purl, const char *flags) -{ - conn_t *conn; - int verbose; - int af; - -#ifdef INET6 - af = AF_UNSPEC; -#else - af = AF_INET; -#endif - - verbose = CHECK_FLAG('v'); - if (CHECK_FLAG('4')) - af = AF_INET; -#ifdef INET6 - else if (CHECK_FLAG('6')) - af = AF_INET6; -#endif - - if (purl && strcasecmp(URL->scheme, SCHEME_HTTPS) != 0) { - URL = purl; - } else if (strcasecmp(URL->scheme, SCHEME_FTP) == 0) { - /* can't talk http to an ftp server */ - /* XXX should set an error code */ - return (NULL); - } - - if ((conn = _fetch_connect(URL->host, URL->port, af, verbose)) == NULL) - /* _fetch_connect() has already set an error code */ - return (NULL); - if (strcasecmp(URL->scheme, SCHEME_HTTPS) == 0 && - _fetch_ssl(conn, verbose) == -1) { - _fetch_close(conn); - /* grrr */ - _fetch_syserr(); - return (NULL); - } - -#ifdef TCP_NOPUSH - int val = 1; - setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, sizeof(val)); -#endif - - return (conn); -} - -static struct url * -_http_get_proxy(const char *flags) -{ - struct url *purl; - char *p; - - if (flags != NULL && strchr(flags, 'd') != NULL) - return (NULL); - if (((p = getenv("HTTP_PROXY")) || (p = getenv("http_proxy"))) && - *p && (purl = fetchParseURL(p))) { - if (!*purl->scheme) - strcpy(purl->scheme, SCHEME_HTTP); - if (!purl->port) - purl->port = _fetch_default_proxy_port(purl->scheme); - if (strcasecmp(purl->scheme, SCHEME_HTTP) == 0) - return (purl); - fetchFreeURL(purl); - } - return (NULL); -} - -static void -_http_print_html(FILE *out, FILE *in) -{ - size_t len; - unsigned int sz = 1024; - char *line, *p, *q; - int comment, tag; - - line = (char *)calloc(1024, sizeof(char)); - comment = tag = 0; - while ((len = getline(&line, &sz, in)) > 0) { - while (len && isspace(line[len - 1])) - --len; - for (p = q = line; q < line + len; ++q) { - if (comment && *q == '-') { - if (q + 2 < line + len && - strcmp(q, "-->") == 0) { - tag = comment = 0; - q += 2; - } - } else if (tag && !comment && *q == '>') { - p = q + 1; - tag = 0; - } else if (!tag && *q == '<') { - if (q > p) - fwrite(p, q - p, 1, out); - tag = 1; - if (q + 3 < line + len && - strcmp(q, "<!--") == 0) { - comment = 1; - q += 3; - } - } - } - if (!tag && q > p) - fwrite(p, q - p, 1, out); - fputc('\n', out); - } -} - - -/***************************************************************************** - * Core - */ - -/* - * Send a request and process the reply - * - * XXX This function is way too long, the do..while loop should be split - * XXX off into a separate function. - */ -FILE * -_http_request(struct url *URL, const char *op, struct url_stat *us, - struct url *purl, const char *flags) -{ - conn_t *conn; - struct url *url, *new; - int chunked, direct, need_auth, noredirect, verbose; - int e, i, n, val; - off_t offset, clength, length, size; - time_t mtime; - const char *p; - FILE *f; - hdr_t h; - char hbuf[MAXHOSTNAMELEN + 7], *host; - - direct = CHECK_FLAG('d'); - noredirect = CHECK_FLAG('A'); - verbose = CHECK_FLAG('v'); - - if (direct && purl) { - fetchFreeURL(purl); - purl = NULL; - } - - /* try the provided URL first */ - url = URL; - - /* if the A flag is set, we only get one try */ - n = noredirect ? 1 : MAX_REDIRECT; - i = 0; - - e = HTTP_PROTOCOL_ERROR; - need_auth = 0; - do { - new = NULL; - chunked = 0; - offset = 0; - clength = -1; - length = -1; - size = -1; - mtime = 0; - - /* check port */ - if (!url->port) - url->port = _fetch_default_port(url->scheme); - - /* were we redirected to an FTP URL? */ - if (purl == NULL && strcmp(url->scheme, SCHEME_FTP) == 0) { - if (strcmp(op, "GET") == 0) - return (_ftp_request(url, "RETR", us, purl, flags)); - else if (strcmp(op, "HEAD") == 0) - return (_ftp_request(url, "STAT", us, purl, flags)); - } - - /* connect to server or proxy */ - if ((conn = _http_connect(url, purl, flags)) == NULL) - goto ouch; - - host = url->host; -#ifdef INET6 - if (strchr(url->host, ':')) { - snprintf(hbuf, sizeof(hbuf), "[%s]", url->host); - host = hbuf; - } -#endif - if (url->port != _fetch_default_port(url->scheme)) { - if (host != hbuf) { - strcpy(hbuf, host); - host = hbuf; - } - snprintf(hbuf + strlen(hbuf), - sizeof(hbuf) - strlen(hbuf), ":%d", url->port); - } - - /* send request */ - if (verbose) - _fetch_info("requesting %s://%s%s", - url->scheme, host, url->doc); - if (purl) { - _http_cmd(conn, "%s %s://%s%s HTTP/1.1", - op, url->scheme, host, url->doc); - } else { - _http_cmd(conn, "%s %s HTTP/1.1", - op, url->doc); - } - - /* virtual host */ - _http_cmd(conn, "Host: %s", host); - - /* proxy authorization */ - if (purl) { - if (*purl->user || *purl->pwd) - _http_basic_auth(conn, "Proxy-Authorization", - purl->user, purl->pwd); - else if ((p = getenv("HTTP_PROXY_AUTH")) != NULL && *p != '\0') - _http_authorize(conn, "Proxy-Authorization", p); - } - - /* server authorization */ - if (need_auth || *url->user || *url->pwd) { - if (*url->user || *url->pwd) - _http_basic_auth(conn, "Authorization", url->user, url->pwd); - else if ((p = getenv("HTTP_AUTH")) != NULL && *p != '\0') - _http_authorize(conn, "Authorization", p); - else if (fetchAuthMethod && fetchAuthMethod(url) == 0) { - _http_basic_auth(conn, "Authorization", url->user, url->pwd); - } else { - _http_seterr(HTTP_NEED_AUTH); - goto ouch; - } - } - - /* other headers */ - if ((p = getenv("HTTP_REFERER")) != NULL && *p != '\0') { - if (strcasecmp(p, "auto") == 0) - _http_cmd(conn, "Referer: %s://%s%s", - url->scheme, host, url->doc); - else - _http_cmd(conn, "Referer: %s", p); - } - if ((p = getenv("HTTP_USER_AGENT")) != NULL && *p != '\0') - _http_cmd(conn, "User-Agent: %s", p); - else - _http_cmd(conn, "User-Agent: " _LIBFETCH_VER); - if (url->offset > 0) - _http_cmd(conn, "Range: bytes=%lld-", (long long)url->offset); - _http_cmd(conn, "Connection: close"); - _http_cmd(conn, ""); - - /* - * Force the queued request to be dispatched. Normally, one - * would do this with shutdown(2) but squid proxies can be - * configured to disallow such half-closed connections. To - * be compatible with such configurations, fiddle with socket - * options to force the pending data to be written. - */ -#ifdef TCP_NOPUSH - val = 0; - setsockopt(conn->sd, IPPROTO_TCP, TCP_NOPUSH, &val, - sizeof(val)); -#endif - val = 1; - setsockopt(conn->sd, IPPROTO_TCP, TCP_NODELAY, &val, - sizeof(val)); - - /* get reply */ - switch (_http_get_reply(conn)) { - case HTTP_OK: - case HTTP_PARTIAL: - /* fine */ - break; - case HTTP_MOVED_PERM: - case HTTP_MOVED_TEMP: - case HTTP_SEE_OTHER: - /* - * Not so fine, but we still have to read the - * headers to get the new location. - */ - break; - case HTTP_NEED_AUTH: - if (need_auth) { - /* - * We already sent out authorization code, - * so there's nothing more we can do. - */ - _http_seterr(conn->err); - goto ouch; - } - /* try again, but send the password this time */ - if (verbose) - _fetch_info("server requires authorization"); - break; - case HTTP_NEED_PROXY_AUTH: - /* - * If we're talking to a proxy, we already sent - * our proxy authorization code, so there's - * nothing more we can do. - */ - _http_seterr(conn->err); - goto ouch; - case HTTP_BAD_RANGE: - /* - * This can happen if we ask for 0 bytes because - * we already have the whole file. Consider this - * a success for now, and check sizes later. - */ - break; - case HTTP_PROTOCOL_ERROR: - /* fall through */ - case -1: - _fetch_syserr(); - goto ouch; - default: - _http_seterr(conn->err); - goto ouch; - /* fall through so we can get the full error message */ - } - - /* get headers */ - do { - switch ((h = _http_next_header(conn, &p))) { - case hdr_syserror: - _fetch_syserr(); - goto ouch; - case hdr_error: - _http_seterr(HTTP_PROTOCOL_ERROR); - goto ouch; - case hdr_content_length: - _http_parse_length(p, &clength); - break; - case hdr_content_range: - _http_parse_range(p, &offset, &length, &size); - break; - case hdr_last_modified: - _http_parse_mtime(p, &mtime); - break; - case hdr_location: - if (!HTTP_REDIRECT(conn->err)) - break; - if (new) - free(new); - if (verbose) - _fetch_info("%d redirect to %s", conn->err, p); - if (*p == '/') - /* absolute path */ - new = fetchMakeURL(url->scheme, url->host, url->port, p, - url->user, url->pwd); - else - new = fetchParseURL(p); - if (new == NULL) { - /* XXX should set an error code */ - DEBUG(fprintf(stderr, "failed to parse new URL\n")); - goto ouch; - } - if (!*new->user && !*new->pwd) { - strcpy(new->user, url->user); - strcpy(new->pwd, url->pwd); - } - new->offset = url->offset; - new->length = url->length; - break; - case hdr_transfer_encoding: - /* XXX weak test*/ - chunked = (strcasecmp(p, "chunked") == 0); - break; - case hdr_www_authenticate: - if (conn->err != HTTP_NEED_AUTH) - break; - /* if we were smarter, we'd check the method and realm */ - break; - case hdr_end: - /* fall through */ - case hdr_unknown: - /* ignore */ - break; - } - } while (h > hdr_end); - - /* we need to provide authentication */ - if (conn->err == HTTP_NEED_AUTH) { - e = conn->err; - need_auth = 1; - _fetch_close(conn); - conn = NULL; - continue; - } - - /* requested range not satisfiable */ - if (conn->err == HTTP_BAD_RANGE) { - if (url->offset == size && url->length == 0) { - /* asked for 0 bytes; fake it */ - offset = url->offset; - conn->err = HTTP_OK; - break; - } else { - _http_seterr(conn->err); - goto ouch; - } - } - - /* we have a hit or an error */ - if (conn->err == HTTP_OK || conn->err == HTTP_PARTIAL || HTTP_ERROR(conn->err)) - break; - - /* all other cases: we got a redirect */ - e = conn->err; - need_auth = 0; - _fetch_close(conn); - conn = NULL; - if (!new) { - DEBUG(fprintf(stderr, "redirect with no new location\n")); - break; - } - if (url != URL) - fetchFreeURL(url); - url = new; - } while (++i < n); - - /* we failed, or ran out of retries */ - if (conn == NULL) { - _http_seterr(e); - goto ouch; - } - - DEBUG(fprintf(stderr, "offset %lld, length %lld," - " size %lld, clength %lld\n", - (long long)offset, (long long)length, - (long long)size, (long long)clength)); - - /* check for inconsistencies */ - if (clength != -1 && length != -1 && clength != length) { - _http_seterr(HTTP_PROTOCOL_ERROR); - goto ouch; - } - if (clength == -1) - clength = length; - if (clength != -1) - length = offset + clength; - if (length != -1 && size != -1 && length != size) { - _http_seterr(HTTP_PROTOCOL_ERROR); - goto ouch; - } - if (size == -1) - size = length; - - /* fill in stats */ - if (us) { - us->size = size; - us->atime = us->mtime = mtime; - } - - /* too far? */ - if (URL->offset > 0 && offset > URL->offset) { - _http_seterr(HTTP_PROTOCOL_ERROR); - goto ouch; - } - - /* report back real offset and size */ - URL->offset = offset; - URL->length = clength; - - /* wrap it up in a FILE */ - if ((f = _http_funopen(conn, chunked)) == NULL) { - _fetch_syserr(); - goto ouch; - } - - if (url != URL) - fetchFreeURL(url); - if (purl) - fetchFreeURL(purl); - - if (HTTP_ERROR(conn->err)) { - _http_print_html(stderr, f); - fclose(f); - f = NULL; - } - - return (f); - -ouch: - if (url != URL) - fetchFreeURL(url); - if (purl) - fetchFreeURL(purl); - if (conn != NULL) - _fetch_close(conn); - return (NULL); -} - - -/***************************************************************************** - * Entry points - */ - -/* - * Retrieve and stat a file by HTTP - */ -FILE * -fetchXGetHTTP(struct url *URL, struct url_stat *us, const char *flags) -{ - return (_http_request(URL, "GET", us, _http_get_proxy(flags), flags)); -} - -/* - * Retrieve a file by HTTP - */ -FILE * -fetchGetHTTP(struct url *URL, const char *flags) -{ - return (fetchXGetHTTP(URL, NULL, flags)); -} - -/* - * Store a file by HTTP - */ -FILE * -fetchPutHTTP(struct url *URL, const char *flags) -{ - warnx("fetchPutHTTP(): not implemented"); - return (NULL); -} - -/* - * Get an HTTP document's metadata - */ -int -fetchStatHTTP(struct url *URL, struct url_stat *us, const char *flags) -{ - FILE *f; - - f = _http_request(URL, "HEAD", us, _http_get_proxy(flags), flags); - if (f == NULL) - return (-1); - fclose(f); - return (0); -} - -/* - * List a directory - */ -struct url_ent * -fetchListHTTP(struct url *url, const char *flags) -{ - warnx("fetchListHTTP(): not implemented"); - return (NULL); -} diff --git a/lib/libfetch/http.errors b/lib/libfetch/http.errors deleted file mode 100644 index 9fee2277..00000000 --- a/lib/libfetch/http.errors +++ /dev/null @@ -1,45 +0,0 @@ -# $FreeBSD: /repoman/r/ncvs/src/lib/libfetch/http.errors,v 1.5 2001/05/23 18:52:02 des Exp $ -# -# This list is taken from RFC 2068. -# -100 OK Continue -101 OK Switching Protocols -200 OK OK -201 OK Created -202 OK Accepted -203 INFO Non-Authoritative Information -204 OK No Content -205 OK Reset Content -206 OK Partial Content -300 MOVED Multiple Choices -301 MOVED Moved Permanently -302 MOVED Moved Temporarily -303 MOVED See Other -304 OK Not Modified -305 INFO Use Proxy -307 MOVED Temporary Redirect -400 PROTO Bad Request -401 AUTH Unauthorized -402 AUTH Payment Required -403 AUTH Forbidden -404 UNAVAIL Not Found -405 PROTO Method Not Allowed -406 PROTO Not Acceptable -407 AUTH Proxy Authentication Required -408 TIMEOUT Request Time-out -409 EXISTS Conflict -410 UNAVAIL Gone -411 PROTO Length Required -412 SERVER Precondition Failed -413 PROTO Request Entity Too Large -414 PROTO Request-URI Too Large -415 PROTO Unsupported Media Type -416 UNAVAIL Requested Range Not Satisfiable -417 SERVER Expectation Failed -500 SERVER Internal Server Error -501 PROTO Not Implemented -502 SERVER Bad Gateway -503 TEMP Service Unavailable -504 TIMEOUT Gateway Time-out -505 PROTO HTTP Version not supported -999 PROTO Protocol error diff --git a/lib/libftp/.cvsignore b/lib/libftp/.cvsignore deleted file mode 100644 index 09980ae6..00000000 --- a/lib/libftp/.cvsignore +++ /dev/null @@ -1,6 +0,0 @@ -.deps -.libs -Makefile -Makefile.in -*.lo -*.la diff --git a/lib/libftp/Makefile.am b/lib/libftp/Makefile.am deleted file mode 100644 index b53e4972..00000000 --- a/lib/libftp/Makefile.am +++ /dev/null @@ -1,17 +0,0 @@ -AUTOMAKE_OPTIONS = gnu -DEFINES = -DFTPLIB_DEFMODE=FTPLIB_PORT -D_REENTRANT -AM_CFLAGS = $(DEFINES) - -#SOMAJOR = 3 -#SOMINOR = 1 -#SOMICRO = 1 -#SOVER = `expr $(SOMAJOR) + $(SOMINOR)`:$(SOMICRO):$(SOMINOR) - -noinst_LTLIBRARIES = libftp.la -#lib_LTLIBRARIES = libftp.la - -libftp_la_SOURCES = \ - ftplib.h \ - ftplib.c - -#libftp_la_LDFLAGS = -L. -version-info $(SOVER) diff --git a/lib/libftp/ftplib.c b/lib/libftp/ftplib.c deleted file mode 100644 index 24908c24..00000000 --- a/lib/libftp/ftplib.c +++ /dev/null @@ -1,1625 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftplib.c - callable ftp access routines */ -/* Copyright (C) 1996-2000 Thomas Pfau, pfau@cnj.digex.net */ -/* 73 Catherine Street, South Bound Brook, NJ, 08880 */ -/* */ -/* 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 progam; if not, write to the */ -/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */ -/* Boston, MA 02111-1307, USA. */ -/* */ -/***************************************************************************/ - -#if defined(__unix__) || defined(__VMS) -#include <unistd.h> -#endif -#if defined(_WIN32) -#include <windows.h> -#endif -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#include <ctype.h> -#include <time.h> -#if defined(__unix__) || defined(__APPLE__) -#include <sys/time.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <netdb.h> -#include <arpa/inet.h> -#elif defined(VMS) -#include <types.h> -#include <socket.h> -#include <in.h> -#include <netdb.h> -#include <inet.h> -#elif defined(_WIN32) -#include <winsock.h> -#endif - -#define BUILDING_LIBRARY -#include "ftplib.h" - -#if defined(_WIN32) -#define SETSOCKOPT_OPTVAL_TYPE (const char *) -#else -#define SETSOCKOPT_OPTVAL_TYPE (void *) -#endif - -#define FTPLIB_BUFSIZ 8192 -#define ACCEPT_TIMEOUT 30 - -#define FTPLIB_CONTROL 0 -#define FTPLIB_READ 1 -#define FTPLIB_WRITE 2 - -#if !defined FTPLIB_DEFMODE -#define FTPLIB_DEFMODE FTPLIB_PASSIVE -#endif - -struct NetBuf { - char *cput,*cget; - int handle; - int cavail,cleft; - char *buf; - int dir; - netbuf *ctrl; - netbuf *data; - int cmode; - struct timeval idletime; - FtpCallback idlecb; - void *idlearg; - int xfered; - int cbbytes; - int xfered1; - char response[256]; -}; - -static char *version = -"ftplib Release 3.1-1 9/16/00, copyright 1996-2000 Thomas Pfau"; - -GLOBALDEF int ftplib_debug = 0; - -#if defined(__unix__) || defined(VMS) || defined(__APPLE__) -#define net_read read -#define net_write write -#define net_close close -#elif defined(_WIN32) -#define net_read(x,y,z) recv(x,y,z,0) -#define net_write(x,y,z) send(x,y,z,0) -#define net_close closesocket -#endif - - /* - * VAX C does not supply a memccpy routine so I provide my own - */ -void *memccpy(void *dest, const void *src, int c, size_t n) -{ - unsigned int i=0; - const unsigned char *ip=src; - unsigned char *op=dest; - - while (i < n) - { - if ((*op++ = *ip++) == c) - break; - i++; - } - if (i == n) - return NULL; - return op; -} -/* - * strdup - return a malloc'ed copy of a string - */ -char *strdup(const char *src) -{ - int l = strlen(src) + 1; - char *dst = malloc(l); - if (dst) - strcpy(dst,src); - return dst; -} - -/* - * socket_wait - wait for socket to receive or flush data - * - * return 1 if no user callback, otherwise, return value returned by - * user callback - */ -static int socket_wait(netbuf *ctl) -{ - fd_set fd,*rfd = NULL,*wfd = NULL; - struct timeval tv; - int rv = 0; - if ((ctl->dir == FTPLIB_CONTROL) || (ctl->idlecb == NULL)) - return 1; - if (ctl->dir == FTPLIB_WRITE) - wfd = &fd; - else - rfd = &fd; - FD_ZERO(&fd); - do - { - FD_SET(ctl->handle,&fd); - tv = ctl->idletime; - rv = select(ctl->handle+1, rfd, wfd, NULL, &tv); - if (rv == -1) - { - rv = 0; - strncpy(ctl->ctrl->response, strerror(errno), - sizeof(ctl->ctrl->response)); - break; - } - else if (rv > 0) - { - rv = 1; - break; - } - } - while ((rv = ctl->idlecb(ctl, ctl->xfered, ctl->idlearg))); - return rv; -} - -/* - * read a line of text - * - * return -1 on error or bytecount - */ -static int readline(char *buf,int max,netbuf *ctl) -{ - int x,retval = 0; - char *end,*bp=buf; - int eof = 0; - - if ((ctl->dir != FTPLIB_CONTROL) && (ctl->dir != FTPLIB_READ)) - return -1; - if (max == 0) - return 0; - do - { - if (ctl->cavail > 0) - { - x = (max >= ctl->cavail) ? ctl->cavail : max-1; - end = memccpy(bp,ctl->cget,'\n',x); - if (end != NULL) - x = end - bp; - retval += x; - bp += x; - *bp = '\0'; - max -= x; - ctl->cget += x; - ctl->cavail -= x; - if (end != NULL) - { - bp -= 2; - if (strcmp(bp,"\r\n") == 0) - { - *bp++ = '\n'; - *bp++ = '\0'; - --retval; - } - break; - } - } - if (max == 1) - { - *buf = '\0'; - break; - } - if (ctl->cput == ctl->cget) - { - ctl->cput = ctl->cget = ctl->buf; - ctl->cavail = 0; - ctl->cleft = FTPLIB_BUFSIZ; - } - if (eof) - { - if (retval == 0) - retval = -1; - break; - } - if (!socket_wait(ctl)) - return retval; - if ((x = net_read(ctl->handle,ctl->cput,ctl->cleft)) == -1) - { - perror("read"); - retval = -1; - break; - } - if (x == 0) - eof = 1; - ctl->cleft -= x; - ctl->cavail += x; - ctl->cput += x; - } - while (1); - return retval; -} - -/* - * write lines of text - * - * return -1 on error or bytecount - */ -static int writeline(char *buf, int len, netbuf *nData) -{ - int x, nb=0, w; - char *ubp = buf, *nbp; - char lc=0; - - if (nData->dir != FTPLIB_WRITE) - return -1; - nbp = nData->buf; - for (x=0; x < len; x++) - { - if ((*ubp == '\n') && (lc != '\r')) - { - if (nb == FTPLIB_BUFSIZ) - { - if (!socket_wait(nData)) - return x; - w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); - if (w != FTPLIB_BUFSIZ) - { - printf("net_write(1) returned %d, errno = %d\n", w, errno); - return(-1); - } - nb = 0; - } - nbp[nb++] = '\r'; - } - if (nb == FTPLIB_BUFSIZ) - { - if (!socket_wait(nData)) - return x; - w = net_write(nData->handle, nbp, FTPLIB_BUFSIZ); - if (w != FTPLIB_BUFSIZ) - { - printf("net_write(2) returned %d, errno = %d\n", w, errno); - return(-1); - } - nb = 0; - } - nbp[nb++] = lc = *ubp++; - } - if (nb) - { - if (!socket_wait(nData)) - return x; - w = net_write(nData->handle, nbp, nb); - if (w != nb) - { - printf("net_write(3) returned %d, errno = %d\n", w, errno); - return(-1); - } - } - return len; -} - -/* - * read a response from the server - * - * return 0 if first char doesn't match - * return 1 if first char matches - */ -static int readresp(char c, netbuf *nControl) -{ - char match[5]; - if (readline(nControl->response,256,nControl) == -1) - { - perror("Control socket read failed"); - return 0; - } - if (ftplib_debug > 1) - fprintf(stderr,"%s",nControl->response); - if (nControl->response[3] == '-') - { - strncpy(match,nControl->response,3); - match[3] = ' '; - match[4] = '\0'; - do - { - if (readline(nControl->response,256,nControl) == -1) - { - perror("Control socket read failed"); - return 0; - } - if (ftplib_debug > 1) - fprintf(stderr,"%s",nControl->response); - } - while (strncmp(nControl->response,match,4)); - } - if (nControl->response[0] == c) - return 1; - return 0; -} - -/* - * FtpInit for stupid operating systems that require it (Windows NT) - */ -GLOBALDEF void FtpInit(void) -{ -#if defined(_WIN32) - WORD wVersionRequested; - WSADATA wsadata; - int err; - wVersionRequested = MAKEWORD(1,1); - if ((err = WSAStartup(wVersionRequested,&wsadata)) != 0) - fprintf(stderr,"Network failed to start: %d\n",err); -#endif - /* we don't use this 'version' variable */ - version=NULL; -} - -/* - * FtpLastResponse - return a pointer to the last response received - */ -GLOBALDEF char *FtpLastResponse(netbuf *nControl) -{ - if ((nControl) && (nControl->dir == FTPLIB_CONTROL)) - return nControl->response; - return NULL; -} - -/* - * FtpConnect - connect to remote server - * - * return 1 if connected, 0 if not - */ -GLOBALDEF int FtpConnect(const char *host, netbuf **nControl) -{ - int sControl; - struct sockaddr_in sin; - struct hostent *phe; - struct servent *pse; - int on=1; - netbuf *ctrl; - char *lhost; - char *pnum; - - memset(&sin,0,sizeof(sin)); - sin.sin_family = AF_INET; - lhost = strdup(host); - pnum = strchr(lhost,':'); - if (pnum == NULL) - { -#if defined(VMS) - sin.sin_port = htons(21); -#else - if ((pse = getservbyname("ftp","tcp")) == NULL) - { - perror("getservbyname"); - return 0; - } - sin.sin_port = pse->s_port; -#endif - } - else - { - *pnum++ = '\0'; - if (isdigit(*pnum)) - sin.sin_port = htons(atoi(pnum)); - else - { - pse = getservbyname(pnum,"tcp"); - if(pse == NULL) { - perror("getservbyname"); - return 0; - } - sin.sin_port = pse->s_port; - } - } - if ((signed)(sin.sin_addr.s_addr = inet_addr(lhost)) == -1) - { - if ((phe = gethostbyname(lhost)) == NULL) - { - perror("gethostbyname"); - return 0; - } - memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); - } - free(lhost); - sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sControl == -1) - { - perror("socket"); - return 0; - } - if (setsockopt(sControl,SOL_SOCKET,SO_REUSEADDR, - SETSOCKOPT_OPTVAL_TYPE &on, sizeof(on)) == -1) - { - perror("setsockopt"); - net_close(sControl); - return 0; - } - if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1) - { - perror("connect"); - net_close(sControl); - return 0; - } - ctrl = calloc(1,sizeof(netbuf)); - if (ctrl == NULL) - { - perror("calloc"); - net_close(sControl); - return 0; - } - ctrl->buf = malloc(FTPLIB_BUFSIZ); - if (ctrl->buf == NULL) - { - perror("calloc"); - net_close(sControl); - free(ctrl); - return 0; - } - ctrl->handle = sControl; - ctrl->dir = FTPLIB_CONTROL; - ctrl->ctrl = NULL; - ctrl->cmode = FTPLIB_DEFMODE; - ctrl->idlecb = NULL; - ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0; - ctrl->idlearg = NULL; - ctrl->xfered = 0; - ctrl->xfered1 = 0; - ctrl->cbbytes = 0; - if (readresp('2', ctrl) == 0) - { - net_close(sControl); - free(ctrl->buf); - free(ctrl); - return 0; - } - *nControl = ctrl; - return 1; -} - -/* - * FtpOptions - change connection options - * - * returns 1 if successful, 0 on error - */ -GLOBALDEF int FtpOptions(int opt, long val, netbuf *nControl) -{ - int v,rv=0; - switch (opt) - { - case FTPLIB_CONNMODE: - v = (int) val; - if ((v == FTPLIB_PASSIVE) || (v == FTPLIB_PORT)) - { - nControl->cmode = v; - rv = 1; - } - break; - case FTPLIB_CALLBACK: - nControl->idlecb = (FtpCallback) val; - rv = 1; - break; - case FTPLIB_IDLETIME: - v = (int) val; - rv = 1; - nControl->idletime.tv_sec = v / 1000; - nControl->idletime.tv_usec = (v % 1000) * 1000; - break; - case FTPLIB_CALLBACKARG: - rv = 1; - nControl->idlearg = (void *) val; - break; - case FTPLIB_CALLBACKBYTES: - rv = 1; - nControl->cbbytes = (int) val; - break; - } - return rv; -} - -/* - * FtpSendCmd - send a command and wait for expected response - * - * return 1 if proper response received, 0 otherwise - */ -static int FtpSendCmd(const char *cmd, char expresp, netbuf *nControl) -{ - char buf[256]; - if (nControl->dir != FTPLIB_CONTROL) - return 0; - if (ftplib_debug > 2) - fprintf(stderr,"%s\n",cmd); - if ((strlen(cmd) + 3) > sizeof(buf)) - return 0; - sprintf(buf,"%s\r\n",cmd); - if (net_write(nControl->handle,buf,strlen(buf)) <= 0) - { - perror("write"); - return 0; - } - return readresp(expresp, nControl); -} - -/* - * FtpLogin - log in to remote server - * - * return 1 if logged in, 0 otherwise - */ -GLOBALDEF int FtpLogin(const char *user, const char *pass, netbuf *nControl) -{ - char tempbuf[64]; - - if (((strlen(user) + 7) > sizeof(tempbuf)) || - ((strlen(pass) + 7) > sizeof(tempbuf))) - return 0; - sprintf(tempbuf,"USER %s",user); - if (!FtpSendCmd(tempbuf,'3',nControl)) - { - if (nControl->response[0] == '2') - return 1; - return 0; - } - sprintf(tempbuf,"PASS %s",pass); - return FtpSendCmd(tempbuf,'2',nControl); -} - -/* - * FtpOpenPort - set up data connection - * - * return 1 if successful, 0 otherwise - */ -static int FtpOpenPort(netbuf *nControl, netbuf **nData, int mode, int dir) -{ - int sData; - union { - struct sockaddr sa; - struct sockaddr_in in; - } sin; - struct linger lng = { 0, 0 }; - unsigned int l; - int on=1; - netbuf *ctrl; - char *cp; - unsigned int v[6]; - char buf[256]; - - if (nControl->dir != FTPLIB_CONTROL) - return -1; - if ((dir != FTPLIB_READ) && (dir != FTPLIB_WRITE)) - { - sprintf(nControl->response, "Invalid direction %d\n", dir); - return -1; - } - if ((mode != FTPLIB_ASCII) && (mode != FTPLIB_IMAGE)) - { - sprintf(nControl->response, "Invalid mode %c\n", mode); - return -1; - } - l = sizeof(sin); - if (nControl->cmode == FTPLIB_PASSIVE) - { - memset(&sin, 0, l); - sin.in.sin_family = AF_INET; - if (!FtpSendCmd("PASV",'2',nControl)) - return -1; - cp = strchr(nControl->response,'('); - if (cp == NULL) - return -1; - cp++; - sscanf(cp,"%u,%u,%u,%u,%u,%u",&v[2],&v[3],&v[4],&v[5],&v[0],&v[1]); - sin.sa.sa_data[2] = v[2]; - sin.sa.sa_data[3] = v[3]; - sin.sa.sa_data[4] = v[4]; - sin.sa.sa_data[5] = v[5]; - sin.sa.sa_data[0] = v[0]; - sin.sa.sa_data[1] = v[1]; - } - else - { - if (getsockname(nControl->handle, &sin.sa, &l) < 0) - { - perror("getsockname"); - return 0; - } - } - sData = socket(PF_INET,SOCK_STREAM,IPPROTO_TCP); - if (sData == -1) - { - perror("socket"); - return -1; - } - if (setsockopt(sData,SOL_SOCKET,SO_REUSEADDR, - SETSOCKOPT_OPTVAL_TYPE &on,sizeof(on)) == -1) - { - perror("setsockopt"); - net_close(sData); - return -1; - } - if (setsockopt(sData,SOL_SOCKET,SO_LINGER, - SETSOCKOPT_OPTVAL_TYPE &lng,sizeof(lng)) == -1) - { - perror("setsockopt"); - net_close(sData); - return -1; - } - if (nControl->cmode == FTPLIB_PASSIVE) - { - if (connect(sData, &sin.sa, sizeof(sin.sa)) == -1) - { - perror("connect"); - net_close(sData); - return -1; - } - } - else - { - sin.in.sin_port = 0; - if (bind(sData, &sin.sa, sizeof(sin)) == -1) - { - perror("bind"); - net_close(sData); - return 0; - } - if (listen(sData, 1) < 0) - { - perror("listen"); - net_close(sData); - return 0; - } - if (getsockname(sData, &sin.sa, &l) < 0) - return 0; - sprintf(buf, "PORT %d,%d,%d,%d,%d,%d", - (unsigned char) sin.sa.sa_data[2], - (unsigned char) sin.sa.sa_data[3], - (unsigned char) sin.sa.sa_data[4], - (unsigned char) sin.sa.sa_data[5], - (unsigned char) sin.sa.sa_data[0], - (unsigned char) sin.sa.sa_data[1]); - if (!FtpSendCmd(buf,'2',nControl)) - { - net_close(sData); - return 0; - } - } - ctrl = calloc(1,sizeof(netbuf)); - if (ctrl == NULL) - { - perror("calloc"); - net_close(sData); - return -1; - } - if ((mode == 'A') && ((ctrl->buf = malloc(FTPLIB_BUFSIZ)) == NULL)) - { - perror("calloc"); - net_close(sData); - free(ctrl); - return -1; - } - ctrl->handle = sData; - ctrl->dir = dir; - ctrl->idletime = nControl->idletime; - ctrl->idlearg = nControl->idlearg; - ctrl->xfered = 0; - ctrl->xfered1 = 0; - ctrl->cbbytes = nControl->cbbytes; - if (ctrl->idletime.tv_sec || ctrl->idletime.tv_usec || ctrl->cbbytes) - ctrl->idlecb = nControl->idlecb; - else - ctrl->idlecb = NULL; - *nData = ctrl; - return 1; -} - -/* - * FtpAcceptConnection - accept connection from server - * - * return 1 if successful, 0 otherwise - */ -static int FtpAcceptConnection(netbuf *nData, netbuf *nControl) -{ - int sData; - struct sockaddr addr; - unsigned int l; - int i; - struct timeval tv; - fd_set mask; - int rv; - - FD_ZERO(&mask); - FD_SET(nControl->handle, &mask); - FD_SET(nData->handle, &mask); - tv.tv_usec = 0; - tv.tv_sec = ACCEPT_TIMEOUT; - i = nControl->handle; - if (i < nData->handle) - i = nData->handle; - i = select(i+1, &mask, NULL, NULL, &tv); - if (i == -1) - { - strncpy(nControl->response, strerror(errno), - sizeof(nControl->response)); - net_close(nData->handle); - nData->handle = 0; - rv = 0; - } - else if (i == 0) - { - strcpy(nControl->response, "timed out waiting for connection"); - net_close(nData->handle); - nData->handle = 0; - rv = 0; - } - else - { - if (FD_ISSET(nData->handle, &mask)) - { - l = sizeof(addr); - sData = accept(nData->handle, &addr, &l); - i = errno; - net_close(nData->handle); - if (sData > 0) - { - rv = 1; - nData->handle = sData; - } - else - { - strncpy(nControl->response, strerror(i), - sizeof(nControl->response)); - nData->handle = 0; - rv = 0; - } - } - else if (FD_ISSET(nControl->handle, &mask)) - { - net_close(nData->handle); - nData->handle = 0; - readresp('2', nControl); - rv = 0; - } - } - return rv; -} - -/* - * FtpAccess - return a handle for a data stream - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, - netbuf **nData) -{ - char buf[256]; - int dir; - if ((path == NULL) && - ((typ == FTPLIB_FILE_WRITE) || (typ == FTPLIB_FILE_READ))) - { - sprintf(nControl->response, - "Missing path argument for file transfer\n"); - return 0; - } - sprintf(buf, "TYPE %c", mode); - if (!FtpSendCmd(buf, '2', nControl)) - return 0; - switch (typ) - { - case FTPLIB_DIR: - strcpy(buf,"NLST"); - dir = FTPLIB_READ; - break; - case FTPLIB_DIR_VERBOSE: - strcpy(buf,"LIST"); - dir = FTPLIB_READ; - break; - case FTPLIB_FILE_READ: - strcpy(buf,"RETR"); - dir = FTPLIB_READ; - break; - case FTPLIB_FILE_WRITE: - strcpy(buf,"STOR"); - dir = FTPLIB_WRITE; - break; - default: - sprintf(nControl->response, "Invalid open type %d\n", typ); - return 0; - } - if (path != NULL) - { - int i = strlen(buf); - buf[i++] = ' '; - if ((strlen(path) + i) >= sizeof(buf)) - return 0; - strcpy(&buf[i],path); - } - if (FtpOpenPort(nControl, nData, mode, dir) == -1) - return 0; - if (!FtpSendCmd(buf, '1', nControl)) - { - FtpClose(*nData); - *nData = NULL; - return 0; - } - (*nData)->ctrl = nControl; - nControl->data = *nData; - if (nControl->cmode == FTPLIB_PORT) - { - if (!FtpAcceptConnection(*nData,nControl)) - { - FtpClose(*nData); - *nData = NULL; - nControl->data = NULL; - return 0; - } - } - return 1; -} - -/* - * FtpRead - read from a data connection - */ -GLOBALDEF int FtpRead(void *buf, int max, netbuf *nData) -{ - int i; - if (nData->dir != FTPLIB_READ) - return 0; - if (nData->buf) - i = readline(buf, max, nData); - else - { - i = socket_wait(nData); - if (i != 1) - return 0; - i = net_read(nData->handle, buf, max); - } - if (i == -1) - return 0; - nData->xfered += i; - if (nData->idlecb && nData->cbbytes) - { - nData->xfered1 += i; - if (nData->xfered1 > nData->cbbytes) - { - if (nData->idlecb(nData, nData->xfered, nData->idlearg) == 0) - return 0; - nData->xfered1 = 0; - } - } - return i; -} - -/* - * FtpWrite - write to a data connection - */ -GLOBALDEF int FtpWrite(void *buf, int len, netbuf *nData) -{ - int i; - if (nData->dir != FTPLIB_WRITE) - return 0; - if (nData->buf) - i = writeline(buf, len, nData); - else - { - socket_wait(nData); - i = net_write(nData->handle, buf, len); - } - if (i == -1) - return 0; - nData->xfered += i; - if (nData->idlecb && nData->cbbytes) - { - nData->xfered1 += i; - if (nData->xfered1 > nData->cbbytes) - { - nData->idlecb(nData, nData->xfered, nData->idlearg); - nData->xfered1 = 0; - } - } - return i; -} - -/* - * FtpClose - close a data connection - */ -GLOBALDEF int FtpClose(netbuf *nData) -{ - netbuf *ctrl; - switch (nData->dir) - { - case FTPLIB_WRITE: - /* potential problem - if buffer flush fails, how to notify user? */ - if (nData->buf != NULL) - writeline(NULL, 0, nData); - case FTPLIB_READ: - if (nData->buf) - free(nData->buf); - shutdown(nData->handle,2); - net_close(nData->handle); - ctrl = nData->ctrl; - free(nData); - if (ctrl) - { - ctrl->data = NULL; - return(readresp('2', ctrl)); - } - return 1; - case FTPLIB_CONTROL: - if (nData->data) - { - nData->ctrl = NULL; - FtpClose(nData); - } - net_close(nData->handle); - free(nData); - return 0; - } - return 1; -} - -/* - * FtpSite - send a SITE command - * - * return 1 if command successful, 0 otherwise - */ -GLOBALDEF int FtpSite(const char *cmd, netbuf *nControl) -{ - char buf[256]; - - if ((strlen(cmd) + 7) > sizeof(buf)) - return 0; - sprintf(buf,"SITE %s",cmd); - if (!FtpSendCmd(buf,'2',nControl)) - return 0; - return 1; -} - -/* - * FtpSysType - send a SYST command - * - * Fills in the user buffer with the remote system type. If more - * information from the response is required, the user can parse - * it out of the response buffer returned by FtpLastResponse(). - * - * return 1 if command successful, 0 otherwise - */ -GLOBALDEF int FtpSysType(char *buf, int max, netbuf *nControl) -{ - int l = max; - char *b = buf; - char *s; - if (!FtpSendCmd("SYST",'2',nControl)) - return 0; - s = &nControl->response[4]; - while ((--l) && (*s != ' ')) - *b++ = *s++; - *b++ = '\0'; - return 1; -} - -/* - * FtpMkdir - create a directory at server - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpMkdir(const char *path, netbuf *nControl) -{ - char buf[256]; - - if ((strlen(path) + 6) > sizeof(buf)) - return 0; - sprintf(buf,"MKD %s",path); - if (!FtpSendCmd(buf,'2', nControl)) - return 0; - return 1; -} - -/* - * FtpChdir - change path at remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpChdir(const char *path, netbuf *nControl) -{ - char buf[256]; - - if ((strlen(path) + 6) > sizeof(buf)) - return 0; - sprintf(buf,"CWD %s",path); - if (!FtpSendCmd(buf,'2',nControl)) - return 0; - return 1; -} - -/* - * FtpCDUp - move to parent directory at remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpCDUp(netbuf *nControl) -{ - if (!FtpSendCmd("CDUP",'2',nControl)) - return 0; - return 1; -} - -/* - * FtpRmdir - remove directory at remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpRmdir(const char *path, netbuf *nControl) -{ - char buf[256]; - - if ((strlen(path) + 6) > sizeof(buf)) - return 0; - sprintf(buf,"RMD %s",path); - if (!FtpSendCmd(buf,'2',nControl)) - return 0; - return 1; -} - -/* - * FtpPwd - get working directory at remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpPwd(char *path, int max, netbuf *nControl) -{ - int l = max; - char *b = path; - char *s; - if (!FtpSendCmd("PWD",'2',nControl)) - return 0; - s = strchr(nControl->response, '"'); - if (s == NULL) - return 0; - s++; - while ((--l) && (*s) && (*s != '"')) - *b++ = *s++; - *b++ = '\0'; - return 1; -} - -/* - * FtpXfer - issue a command and transfer data - * - * return 1 if successful, 0 otherwise - */ -static int FtpXfer(const char *localfile, const char *path, - netbuf *nControl, int typ, int mode) -{ - int l,c; - char *dbuf; - FILE *local = NULL; - netbuf *nData; - int rv=1; - - if (localfile != NULL) - { - char ac[4] = "a"; - if (typ == FTPLIB_FILE_WRITE) - ac[0] = 'r'; - if (mode == FTPLIB_IMAGE) - ac[1] = 'b'; - local = fopen(localfile, ac); - if (local == NULL) - { - strncpy(nControl->response, strerror(errno), - sizeof(nControl->response)); - return 0; - } - } - if (local == NULL) - local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; - if (!FtpAccess(path, typ, mode, nControl, &nData)) - return 0; - dbuf = malloc(FTPLIB_BUFSIZ); - if (typ == FTPLIB_FILE_WRITE) - { - while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) - if ((c = FtpWrite(dbuf, l, nData)) < l) - { - printf("short write: passed %d, wrote %d\n", l, c); - rv = 0; - break; - } - } - else - { - while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nData)) > 0) - if (fwrite(dbuf, 1, l, local) < (unsigned)l) - { - perror("\nlocalfile write"); - rv = 0; - break; - } - } - free(dbuf); - fflush(local); - if (localfile != NULL) - fclose(local); - FtpClose(nData); - return rv; -} - -/* - * FtpNlst - issue an NLST command and write response to output - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpNlst(const char *outputfile, const char *path, - netbuf *nControl) -{ - return FtpXfer(outputfile, path, nControl, FTPLIB_DIR, FTPLIB_ASCII); -} - -/* - * FtpDir - issue a LIST command and write response to output - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpDir(const char *outputfile, const char *path, netbuf *nControl) -{ - return FtpXfer(outputfile, path, nControl, FTPLIB_DIR_VERBOSE, FTPLIB_ASCII); -} - -/* - * FtpSize - determine the size of a remote file - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpSize(const char *path, int *size, char mode, netbuf *nControl) -{ - char cmd[256]; - int resp,sz,rv=1; - - if ((strlen(path) + 7) > sizeof(cmd)) - return 0; - sprintf(cmd, "TYPE %c", mode); - if (!FtpSendCmd(cmd, '2', nControl)) - return 0; - sprintf(cmd,"SIZE %s",path); - if (!FtpSendCmd(cmd,'2',nControl)) - rv = 0; - else - { - if (sscanf(nControl->response, "%d %d", &resp, &sz) == 2) - *size = sz; - else - rv = 0; - } - return rv; -} - -/* - * FtpRestart - issue a REST command - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpRestart(int offset, netbuf *nControl) -{ - char cmd[256]; - int rv=1; - - sprintf(cmd,"REST %d",offset); - if (!FtpSendCmd(cmd,'3',nControl)) - rv = 0; - return rv; -} - -/* - * FtpModDate - determine the modification date of a remote file - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl) -{ - char buf[256]; - int rv = 1; - - if ((strlen(path) + 7) > sizeof(buf)) - return 0; - sprintf(buf,"MDTM %s",path); - if (!FtpSendCmd(buf,'2',nControl)) - rv = 0; - else - strncpy(dt, &nControl->response[4], max); - return rv; -} - -/* - * FtpGet - issue a GET command and write received data to output - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpGet(const char *outputfile, const char *path, - char mode, netbuf *nControl) -{ - return FtpXfer(outputfile, path, nControl, FTPLIB_FILE_READ, mode); -} - -/* - * FtpPut - issue a PUT command and send data from input - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpPut(const char *inputfile, const char *path, char mode, - netbuf *nControl) -{ - return FtpXfer(inputfile, path, nControl, FTPLIB_FILE_WRITE, mode); -} - -/* - * FtpRename - rename a file at remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpRename(const char *src, const char *dst, netbuf *nControl) -{ - char cmd[256]; - - if (((strlen(src) + 7) > sizeof(cmd)) || - ((strlen(dst) + 7) > sizeof(cmd))) - return 0; - sprintf(cmd,"RNFR %s",src); - if (!FtpSendCmd(cmd,'3',nControl)) - return 0; - sprintf(cmd,"RNTO %s",dst); - if (!FtpSendCmd(cmd,'2',nControl)) - return 0; - return 1; -} - -/* - * FtpDelete - delete a file at remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF int FtpDelete(const char *fnm, netbuf *nControl) -{ - char cmd[256]; - - if ((strlen(fnm) + 7) > sizeof(cmd)) - return 0; - sprintf(cmd,"DELE %s",fnm); - if (!FtpSendCmd(cmd,'2', nControl)) - return 0; - return 1; -} - -/* - * FtpQuit - disconnect from remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALDEF void FtpQuit(netbuf *nControl) -{ - if (nControl->dir != FTPLIB_CONTROL) - return; - FtpSendCmd("QUIT",'2',nControl); - net_close(nControl->handle); - free(nControl->buf); - free(nControl); -} - -/* - * HttpConnect - connect to remote server - * - * return 1 if connected, 0 if not - */ -GLOBALREF int HttpConnect(const char *host, unsigned short port, netbuf **nControl) -{ - int sControl; - struct sockaddr_in sin; - struct hostent *phe; - struct servent *pse; - netbuf *ctrl; - char *lhost; - char *pnum; - - memset(&sin,0,sizeof(sin)); - sin.sin_family = AF_INET; - lhost = strdup(host); - pnum = strchr(lhost,':'); - if (pnum == NULL) - { -#if defined(VMS) - sin.sin_port = htons(80); -#else - /* we pass a port variable instead (for use with proxies) - * - if ((pse = getservbyname("http","tcp")) == NULL) - { - perror("getservbyname"); - return 0; - } - sin.sin_port = pse->s_port; - */ - sin.sin_port = htons(port); -#endif - } - else - { - *pnum++ = '\0'; - if (isdigit(*pnum)) - sin.sin_port = htons(atoi(pnum)); - else - { - pse = getservbyname(pnum,"tcp"); - sin.sin_port = pse->s_port; - } - } - if ((signed)(sin.sin_addr.s_addr = inet_addr(lhost)) == -1) - { - if ((phe = gethostbyname(lhost)) == NULL) - { - perror("gethostbyname"); - return 0; - } - memcpy((char *)&sin.sin_addr, phe->h_addr, phe->h_length); - } - free(lhost); - sControl = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP); - if (sControl == -1) - { - perror("socket"); - return 0; - } - if (connect(sControl, (struct sockaddr *)&sin, sizeof(sin)) == -1) - { - perror("connect"); - net_close(sControl); - return 0; - } - ctrl = calloc(1,sizeof(netbuf)); - if (ctrl == NULL) - { - perror("calloc"); - net_close(sControl); - return 0; - } - ctrl->buf = NULL; - ctrl->handle = sControl; - ctrl->dir = FTPLIB_CONTROL; - ctrl->ctrl = NULL; - ctrl->cmode = FTPLIB_DEFMODE; - ctrl->idlecb = NULL; - ctrl->idletime.tv_sec = ctrl->idletime.tv_usec = 0; - ctrl->idlearg = NULL; - ctrl->xfered = 0; - ctrl->xfered1 = 0; - ctrl->cbbytes = 0; - *nControl = ctrl; - return 1; -} - -/* - * HttpSendCmd - send a command - * - * return 1 if proper response received, 0 otherwise - */ -static int HttpSendCmd(const char *cmd, char expresp, netbuf *nControl) -{ - int ret = 0; - char *buf = nControl->response; - /* if (nControl->dir != FTPLIB_CONTROL) - return 0; */ - if (ftplib_debug > 2) - fprintf(stderr,"%s\n",cmd); - if (net_write(nControl->handle,cmd,strlen(cmd)) <= 0) - { - perror("write"); - return 0; - } - while (ret < 256) { - if (socket_wait(nControl) != 1) - return 0; - if (net_read(nControl->handle,buf,1) != 1) { - break; - } - ret++; - if (*buf == '\r') continue; - if (*buf == '\n') break; - buf++; - } - *buf = 0; - if (nControl->response[9] == expresp) - return 1; - return 0; -} - -/* - * HttpXfer - issue a command and transfer data - * - * return 1 if successful, 0 otherwise - */ -static int HttpXfer(const char *localfile, const char *path, int *size, - netbuf *nControl, int typ, int mode) -{ - int l,c; - char *dbuf; - FILE *local = NULL; - int rv=1; - int bytes = 0; - - /* we don't use this 'path' variable */ - path=NULL; - - if (localfile != NULL) - { - char ac[4] = "a"; - if (typ == FTPLIB_FILE_WRITE) - ac[0] = 'r'; - if (mode == FTPLIB_IMAGE) - ac[1] = 'b'; - local = fopen(localfile, ac); - if (local == NULL) - { - strncpy(nControl->response, strerror(errno), - sizeof(nControl->response)); - return 0; - } - } - if (local == NULL) - local = (typ == FTPLIB_FILE_WRITE) ? stdin : stdout; - dbuf = malloc(FTPLIB_BUFSIZ); - if (typ == FTPLIB_FILE_WRITE) - { - while ((l = fread(dbuf, 1, FTPLIB_BUFSIZ, local)) > 0) - if ((c = FtpWrite(dbuf, l, nControl)) < l) - { - printf("short write: passed %d, wrote %d\n", l, c); - rv = 0; - break; - } - } - else - { - nControl->dir = FTPLIB_READ; - while ((l = FtpRead(dbuf, FTPLIB_BUFSIZ, nControl)) > 0) { - if ((signed)fwrite(dbuf, 1, l, local) < l) - { - perror("\nlocalfile write"); - rv = 0; - break; - } - bytes += l; - if(size && bytes >= *size) { - break; - } - } - } - free(dbuf); - fflush(local); - if (localfile != NULL) - fclose(local); - free(nControl->data); - return rv; -} - -/* - * HttpGet - issue a GET command and write received data to output - * - * return 1 if successful, 0 otherwise - */ -GLOBALREF int HttpGet(const char *host, const char *outputfile, const char *path, - int *size, netbuf *nControl, unsigned int offset, - const struct tm *mtime1, struct tm *mtime2) -{ - char buf[512]; - - sprintf(buf, "GET %s HTTP/1.1\r\nHost: %s\r\n", path, host); - if (offset > 0) - sprintf(buf, "%sRange: bytes=%d-\r\n", buf, offset); - if (mtime1 && mtime1->tm_year) - { - char mtime[30]; - /* Format: - * "If-Modified-Since: Sat, 29 Oct 1994 19:43:31 GMT\r\n" */ - strftime(mtime, sizeof(mtime), "%a, %d %b %Y %H:%M:%S GMT", mtime1); - sprintf(buf, "%sIf-Modified-Since: %s\r\n", buf, mtime); - } - sprintf(buf, "%s\r\n", buf); - - if (!HttpSendCmd(buf,'2',nControl)) - { - if (nControl->response[9] == '3') - { - /* If the answer from the server is 304, the requested file - * hasn't been modified: no need to retrieve it */ - if (mtime1 && mtime1->tm_year && nControl->response[11] == '4') - return 0; - /* otherwise, it is a redirection */ - printf("redirection not supported\n"); - } - return 0; - } - - while (1) - { - int ret = 0; - char *buf = nControl->response; - while (ret < 256) { - if (socket_wait(nControl) != 1) - return 0; - if (net_read(nControl->handle,buf,1) != 1) - break; - ret++; - if (*buf == '\r') continue; - if (*buf == '\n') break; - buf++; - } - *buf = 0; - if (strstr(nControl->response,"Content-Length")) - { - sscanf(nControl->response,"Content-Length: %d",size); - if (offset > 0) - *size += offset; - } - else if (mtime2 && strstr(nControl->response,"Last-Modified")) - { - /* Format: - * "Last-Modified: Sat, 29 Oct 1994 19:43:31 GMT\r\n" */ - char *c = nControl->response+20; - int mint, j; - static const int months[12] = { - ('J'<<16)|('a'<<8)|'n', - ('F'<<16)|('e'<<8)|'b', - ('M'<<16)|('a'<<8)|'r', - ('A'<<16)|('p'<<8)|'r', - ('M'<<16)|('a'<<8)|'y', - ('J'<<16)|('u'<<8)|'n', - ('J'<<16)|('u'<<8)|'l', - ('A'<<16)|('u'<<8)|'g', - ('S'<<16)|('e'<<8)|'p', - ('O'<<16)|('c'<<8)|'t', - ('N'<<16)|('o'<<8)|'v', - ('D'<<16)|('e'<<8)|'c' - }; - mtime2->tm_mday = (c[0]-'0')*10+c[1]-'0'; - mint = (c[3]<<16)|(c[4]<<8)|c[5]; - mtime2->tm_mon = 0; - for(j = 0; j < 12; j++) - { - if (mint == months[j]) - { - mtime2->tm_mon = j; - break; - } - } - mtime2->tm_year = ((c[7]-'0')*10+(c[8]-'0')-19)*100; - mtime2->tm_year += (c[9]-'0')*10+c[10]-'0'; - mtime2->tm_hour = (c[12]-'0')*10+c[13]-'0'; - mtime2->tm_min = (c[15]-'0')*10+c[16]-'0'; - mtime2->tm_sec = (c[18]-'0')*10+c[19]-'0'; - } - if (strlen(nControl->response) == 0) - break; - } - - return HttpXfer(outputfile, path, size, nControl, FTPLIB_FILE_READ, FTPLIB_IMAGE); -} - -/* - * HttpQuit - disconnect from remote - * - * return 1 if successful, 0 otherwise - */ -GLOBALREF void HttpQuit(netbuf *nControl) -{ - if(nControl) { - net_close(nControl->handle); - free(nControl); - } -} diff --git a/lib/libftp/ftplib.h b/lib/libftp/ftplib.h deleted file mode 100644 index f82ed9eb..00000000 --- a/lib/libftp/ftplib.h +++ /dev/null @@ -1,132 +0,0 @@ -/***************************************************************************/ -/* */ -/* ftplib.h - header file for callable ftp access routines */ -/* Copyright (C) 1996, 1997 Thomas Pfau, pfau@cnj.digex.net */ -/* 73 Catherine Street, South Bound Brook, NJ, 08880 */ -/* */ -/* 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 progam; if not, write to the */ -/* Free Software Foundation, Inc., 59 Temple Place - Suite 330, */ -/* Boston, MA 02111-1307, USA. */ -/* */ -/***************************************************************************/ - -#if !defined(__FTPLIB_H) -#define __FTPLIB_H - -#if defined(__unix__) || defined(VMS) || defined(__APPLE__) -#define GLOBALDEF -#define GLOBALREF extern -#elif defined(_WIN32) -#if defined BUILDING_LIBRARY -#define GLOBALDEF __declspec(dllexport) -#define GLOBALREF __declspec(dllexport) -#else -#define GLOBALREF __declspec(dllimport) -#endif -#endif - -/* FtpAccess() type codes */ -#define FTPLIB_DIR 1 -#define FTPLIB_DIR_VERBOSE 2 -#define FTPLIB_FILE_READ 3 -#define FTPLIB_FILE_WRITE 4 - -/* FtpAccess() mode codes */ -#define FTPLIB_ASCII 'A' -#define FTPLIB_IMAGE 'I' -#define FTPLIB_TEXT FTPLIB_ASCII -#define FTPLIB_BINARY FTPLIB_IMAGE - -/* connection modes */ -#define FTPLIB_PASSIVE 1 -#define FTPLIB_PORT 2 - -/* connection option names */ -#define FTPLIB_CONNMODE 1 -#define FTPLIB_CALLBACK 2 -#define FTPLIB_IDLETIME 3 -#define FTPLIB_CALLBACKARG 4 -#define FTPLIB_CALLBACKBYTES 5 - -#ifdef __cplusplus -extern "C" { -#endif - -typedef struct NetBuf netbuf; -typedef int (*FtpCallback)(netbuf *nControl, int xfered, void *arg); - -/* v1 compatibility stuff */ -#if !defined(_FTPLIB_NO_COMPAT) -netbuf *DefaultNetbuf; - -#define ftplib_lastresp FtpLastResponse(DefaultNetbuf) -#define ftpInit FtpInit -#define ftpOpen(x) FtpConnect(x, &DefaultNetbuf) -#define ftpLogin(x,y) FtpLogin(x, y, DefaultNetbuf) -#define ftpSite(x) FtpSite(x, DefaultNetbuf) -#define ftpMkdir(x) FtpMkdir(x, DefaultNetbuf) -#define ftpChdir(x) FtpChdir(x, DefaultNetbuf) -#define ftpRmdir(x) FtpRmdir(x, DefaultNetbuf) -#define ftpNlst(x, y) FtpNlst(x, y, DefaultNetbuf) -#define ftpDir(x, y) FtpDir(x, y, DefaultNetbuf) -#define ftpGet(x, y, z) FtpGet(x, y, z, DefaultNetbuf) -#define ftpPut(x, y, z) FtpPut(x, y, z, DefaultNetbuf) -#define ftpRename(x, y) FtpRename(x, y, DefaultNetbuf) -#define ftpDelete(x) FtpDelete(x, DefaultNetbuf) -#define ftpQuit() FtpQuit(DefaultNetbuf) -#endif /* (_FTPLIB_NO_COMPAT) */ -/* end v1 compatibility stuff */ - -GLOBALREF int ftplib_debug; -GLOBALREF void FtpInit(void); -GLOBALREF char *FtpLastResponse(netbuf *nControl); -GLOBALREF int FtpConnect(const char *host, netbuf **nControl); -GLOBALREF int FtpOptions(int opt, long val, netbuf *nControl); -GLOBALREF int FtpLogin(const char *user, const char *pass, netbuf *nControl); -GLOBALREF int FtpAccess(const char *path, int typ, int mode, netbuf *nControl, - netbuf **nData); -GLOBALREF int FtpRead(void *buf, int max, netbuf *nData); -GLOBALREF int FtpWrite(void *buf, int len, netbuf *nData); -GLOBALREF int FtpClose(netbuf *nData); -GLOBALREF int FtpSite(const char *cmd, netbuf *nControl); -GLOBALREF int FtpSysType(char *buf, int max, netbuf *nControl); -GLOBALREF int FtpMkdir(const char *path, netbuf *nControl); -GLOBALREF int FtpChdir(const char *path, netbuf *nControl); -GLOBALREF int FtpCDUp(netbuf *nControl); -GLOBALREF int FtpRmdir(const char *path, netbuf *nControl); -GLOBALREF int FtpPwd(char *path, int max, netbuf *nControl); -GLOBALREF int FtpNlst(const char *output, const char *path, netbuf *nControl); -GLOBALREF int FtpDir(const char *output, const char *path, netbuf *nControl); -GLOBALREF int FtpSize(const char *path, int *size, char mode, netbuf *nControl); -GLOBALREF int FtpRestart(int offset, netbuf *nControl); -GLOBALREF int FtpModDate(const char *path, char *dt, int max, netbuf *nControl); -GLOBALREF int FtpGet(const char *output, const char *path, char mode, - netbuf *nControl); -GLOBALREF int FtpPut(const char *input, const char *path, char mode, - netbuf *nControl); -GLOBALREF int FtpRename(const char *src, const char *dst, netbuf *nControl); -GLOBALREF int FtpDelete(const char *fnm, netbuf *nControl); -GLOBALREF void FtpQuit(netbuf *nControl); - -GLOBALREF int HttpConnect(const char *host, unsigned short port, netbuf **nControl); -GLOBALREF int HttpGet(const char *host, const char *output, const char *path, - int *size, netbuf *nControl, unsigned int offset, - const struct tm *mtime1, struct tm *mtime2); -GLOBALREF void HttpQuit(netbuf *nControl); - -#ifdef __cplusplus -}; -#endif - -#endif /* __FTPLIB_H */ diff --git a/scripts/makepkg b/scripts/makepkg index 55680b0d..ac3bda10 100755 --- a/scripts/makepkg +++ b/scripts/makepkg @@ -3,7 +3,11 @@ # makepkg # # Copyright (c) 2002-2006 by Judd Vinet <jvinet@zeroflux.org> +# Copyright (c) 2005 by Aurelien Foret <orelien@chez.com> # Copyright (c) 2006 by Miklos Vajna <vmiklos@frugalware.org> +# Copyright (c) 2005 by Christian Hamar <krics@linuxforum.hu> +# Copyright (c) 2006 by Alex Smith <alex@alex-smith.me.uk> +# Copyright (c) 2006 by Andras Voroskoi <voroskoi@frugalware.org> # # 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 @@ -27,15 +31,15 @@ PKGDEST=$startdir USE_COLOR="n" # Options -BUILDSCRIPT="./PKGBUILD" CLEANUP=0 CLEANCACHE=0 DEP_BIN=0 DEP_SRC=0 DEP_SUDO=0 FORCE=0 -GENMD5=0 +GENINTEG=0 INSTALL=0 +DOWNLOAD="" KEEPDOCS=0 NOBUILD=0 NOCCACHE=0 @@ -43,15 +47,10 @@ NODEPS=0 NOEXTRACT=0 NOSTRIP=0 RMDEPS=0 +LOGGING=0 PACMAN_OPTS= -# source Arch's abs.conf if it's present -[ -f /etc/abs/abs.conf ] && source /etc/abs/abs.conf - -# makepkg configuration -[ -f /etc/makepkg.conf ] && source /etc/makepkg.conf - INFAKEROOT= if [ "$1" = "-F" ]; then INFAKEROOT=1 @@ -74,6 +73,15 @@ msg() { echo "==> $1" >&2 fi } + +msg2() { + if [ "$USE_COLOR" = "Y" -o "$USE_COLOR" = "y" ]; then + echo -e " \033[1;34m->\033[1;0m \033[1;1m$1\033[1;0m" >&2 + else + echo " -> $1" >&2 + fi +} + warning() { if [ "$USE_COLOR" = "Y" -o "$USE_COLOR" = "y" ]; then echo -e "\033[1;33m==> WARNING:\033[1;0m \033[1;1m$1\033[1;0m" >&2 @@ -90,7 +98,7 @@ error() { } strip_url() { - echo $1 | sed 's|^.*://.*/||g' + echo "$1" | sed 's|^.*://.*/||g' } check_option() { @@ -105,6 +113,16 @@ check_option() { done } +in_array() { + needle=$1 + shift 1 + [ -z "$1" ] && return 1 + for i in $*; do + [ "$i" == "$needle" ] && return 0 + done + return 1 +} + checkdeps() { local missdep="" local deplist="" @@ -151,7 +169,7 @@ handledeps() { if [ "$DEP_BIN" = "1" ]; then # install missing deps from binary packages (using pacman -S) msg "Installing missing dependencies..." - pacman $PACMAN_OPTS -D $deplist + pacman $PACMAN_OPTS -D $deplist if [ "$?" = "127" ]; then error "Failed to install missing dependencies." exit 1 @@ -165,33 +183,33 @@ handledeps() { FAKEROOTKEY2=$FAKEROOTKEY unset FAKEROOTKEY fi - sudo pacman $PACMAN_OPTS -D $deplist - if [ "$INFAKEROOT" = "1" ]; then - export FAKEROOTKEY=$FAKEROOTKEY2 - unset FAKEROOTKEY2 - fi + sudo pacman $PACMAN_OPTS -D $deplist if [ "$?" = "127" ]; then error "Failed to install missing dependencies." exit 1 fi + if [ "$INFAKEROOT" = "1" ]; then + export FAKEROOTKEY=$FAKEROOTKEY2 + unset FAKEROOTKEY2 + fi elif [ "$DEP_SRC" = "1" ]; then # install missing deps by building them from source. - # we look for each package name in $ABSROOT and build it. - if [ "$ABSROOT" = "" ]; then - error "The ABSROOT environment variable is not defined." + # we look for each package name in $SRCROOT and build it. + if [ "$SRCROOT" = "" ]; then + error "Source root cannot be found - please make sure it is specified in /etc/makepkg.conf" exit 1 fi # TODO: handle version comparators (eg, glibc>=2.2.5) msg "Building missing dependencies..." for dep in $deplist; do - candidates=`find $ABSROOT -type d -name "$dep"` + candidates=$(find $SRCROOT -type d -name "$dep") if [ "$candidates" = "" ]; then - error "Could not find \"$dep\" under $ABSROOT" + error "Could not find \"$dep\" under $SRCROOT" exit 1 fi success=0 for pkgdir in $candidates; do - if [ -f $pkgdir/PKGBUILD ]; then + if [ -f $pkgdir/$BUILDSCRIPT ]; then cd $pkgdir if [ "$RMDEPS" = "1" ]; then makepkg -i -c -b -r -w $PKGDEST @@ -219,6 +237,16 @@ handledeps() { fi missingdeps=1 fi + # rerun any additional sh scripts found in /etc/profile.d/ + for i in /etc/profile.d/*.sh + do + if [ -x $i ]; then + . $i &>/dev/null + fi + done + # some applications (eg, blackbox) will not build with some languages + unset LC_ALL LANG + return $missingdeps } @@ -235,14 +263,15 @@ usage() { echo " -d, --nodeps Skip all dependency checks" echo " -e, --noextract Do not extract source files (use existing src/ dir)" echo " -f, --force Overwrite existing package" - echo " -g, --genmd5 Generate MD5sums for source files" + echo " -g, --geninteg Generate integrity checks for source files" echo " -h, --help This help" echo " -i, --install Install package after successful build" echo " -j <jobs> Set MAKEFLAGS to \"-j<jobs>\" before building" + echo " -L, --log Log package build process" echo " -m, --nocolor Disable colorized output messages" echo " -n, --nostrip Do not strip binaries/libraries" echo " -o, --nobuild Download and extract files only" - echo " -p <buildscript> Use an alternate build script (instead of PKGBUILD)" + echo " -p <buildscript> Use an alternate build script (instead of '$BUILDSCRIPT')" echo " -r, --rmdeps Remove installed dependencies after a successful build" echo " -s, --syncdeps Install missing dependencies with pacman" echo " -S, --sudosync Install missing dependencies with pacman and sudo" @@ -253,12 +282,22 @@ usage() { echo " --noconfirm Do not ask for confirmation when resolving dependencies" echo " --noprogressbar Do not show a progress bar when downloading files" echo - echo "If -p is not specified, makepkg will look for ./PKGBUILD" + echo "If -p is not specified, makepkg will look for './$BUILDSCRIPT'" echo } ARGLIST=$@ +if [ -f /etc//makepkg.conf ]; then + source /etc/makepkg.conf +else + error "/etc/makepkg.conf not found. cannot continue" + exit 1 +fi + +#Let's be courteous and support frugalware's extensions +[ -e /usr/lib/frugalware/fwmakepkg ] && . /usr/lib/frugalware/fwmakepkg + while [ "$#" -ne "0" ]; do case $1 in # pacman @@ -278,8 +317,9 @@ while [ "$#" -ne "0" ]; do --nostrip) NOSTRIP=1 ;; --nobuild) NOBUILD=1 ;; --nocolor) USE_COLOR="n" ;; - --genmd5) GENMD5=1 ;; + --geninteg) GENINTEG=1 ;; --rmdeps) RMDEPS=1 ;; + --log) LOGGING=1 ;; --help) usage exit 0 @@ -289,7 +329,7 @@ while [ "$#" -ne "0" ]; do exit 1 ;; -*) - while getopts "bBcCdefghij:mnop:rsSw:-" opt; do + while getopts "bBcCdefghij:Lmnop:rsSw:-" opt; do case $opt in b) DEP_SRC=1 ;; B) NOCCACHE=1 ;; @@ -298,13 +338,14 @@ while [ "$#" -ne "0" ]; do d) NODEPS=1 ;; e) NOEXTRACT=1 ;; f) FORCE=1 ;; - g) GENMD5=1 ;; + g) GENINTEG=1 ;; h) usage exit 0 ;; i) INSTALL=1 ;; j) export MAKEFLAGS="-j$OPTARG" ;; + L) LOGGING=1 ;; m) USE_COLOR="n" ;; n) NOSTRIP=1 ;; o) NOBUILD=1 ;; @@ -333,7 +374,7 @@ done # check for sudo if [ "$DEP_SUDO" = "1" -a ! "`type -p sudo`" ]; then - error "Cannot find the sudo binary! Is sudo installed?" + error "Cannot find the sudo binary! Is sudo installed?" exit 1 fi @@ -360,6 +401,8 @@ fi unset pkgname pkgver pkgrel pkgdesc url license groups provides md5sums force unset replaces depends conflicts backup source install build makedepends unset options + + # some applications (eg, blackbox) will not build with some languages unset LC_ALL LANG umask 0022 @@ -367,29 +410,47 @@ umask 0022 if [ ! -f $BUILDSCRIPT ]; then error "$BUILDSCRIPT does not exist." exit 1 +else + #this is fun.... we'll unset + for var in $(grep "=" $BUILDSCRIPT | sed "s|.*\(\<.*\>\)=.*|\1|g"); do + unset $var + done fi source $BUILDSCRIPT # check for no-no's -if [ `echo $pkgver | grep '-'` ]; then +if [ -z "$pkgver" ]; then + error "pkgver is not allowed to be empty." + exit 1 +fi +if [ -z "$pkgrel" ]; then + error "pkgrel is not allowed to be empty." + exit 1 +fi +if [ $(echo $pkgver | grep '-') ]; then error "pkgver is not allowed to contain hyphens." exit 1 fi -if [ `echo $pkgrel | grep '-'` ]; then +if [ $(echo $pkgrel | grep '-') ]; then error "pkgrel is not allowed to contain hyphens." exit 1 fi +if ! in_array $CARCH ${arch[@]}; then + error "$pkgname is not available for the '$CARCH' architecture." + exit 1 +fi + if [ "$install" -a ! -f "$install" ]; then error "install scriptlet ($install) does not exist." exit 1 fi -if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" -a "$GENMD5" = "0" ]; then +if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.${PKGEXT} -a "$FORCE" = "0" -a "$GENINTEG" = "0" ]; then if [ "$INSTALL" = "1" ]; then warning "a package has already been built, installing existing package." - echo pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz - pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz + echo pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.${PKGEXT} + pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.${PKGEXT} exit $? else error "a package has already been built. (use -f to overwrite)" @@ -397,6 +458,9 @@ if [ -f $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz -a "$FORCE" = "0" -a fi fi +# some applications (eg, blackbox) will not build with some languages +unset LC_ALL LANG + # Enter the fakeroot environment if necessary. This will call the makepkg script again # as the fake root user. We detect this by passing a sentinel option (-F) to makepkg if [ "`id -u`" != "0" ]; then @@ -498,111 +562,113 @@ for netfile in ${source[@]}; do fi done -if [ "$GENMD5" = "0" ]; then - if [ "$NOEXTRACT" = "1" ]; then - warning "Skipping source extraction -- using existing src/ tree" - warning "Skipping source integrity checks -- using existing src/ tree" - else - # MD5 validation - if [ ${#md5sums[@]} -ne ${#source[@]} ]; then - warning "MD5sums are missing or incomplete. Cannot verify source integrity." - #sleep 1 - elif [ `type -p md5sum` ]; then - msg "Validating source files with MD5sums" - errors=0 - idx=0 - for netfile in ${source[@]}; do - file=`strip_url $netfile` - echo -n " $file ... " >&2 - echo "${md5sums[$idx]} $file" | md5sum -c - >/dev/null 2>&1 - if [ $? -ne 0 ]; then - echo "FAILED" >&2 - errors=1 - else - echo "Passed" >&2 - fi - idx=$(($idx+1)) - done - if [ $errors -gt 0 ]; then - error "One or more files did not pass the validity check!" - exit 1 - fi - else - warning "The md5sum program is missing. Cannot verify source files!" - sleep 1 - fi - # extract sources - msg "Extracting Sources..." - for netfile in ${source[@]}; do - unziphack=0 - file=`strip_url $netfile` - unset cmd - case $file in - *.tar.gz|*.tar.Z|*.tgz) - cmd="tar --use-compress-program=gzip -xf $file" ;; - *.tar.bz2|*.tbz2) - cmd="tar --use-compress-program=bzip2 -xf $file" ;; - *.tar) - cmd="tar -xf $file" ;; - *.zip) - unziphack=1 - cmd="unzip -qqo $file" ;; - *.gz) - cmd="gunzip $file" ;; - *.bz2) - cmd="bunzip2 $file" ;; - esac - if [ "$cmd" != "" ]; then - msg " $cmd" - $cmd - if [ $? -ne 0 ]; then - # unzip will return a 1 as a warning, it is not an error - if [ "$unziphack" != "1" -o $? -ne 1 ]; then - error "Failed to extract $file" - msg "Aborting..." - exit 1 - fi - fi - fi - done - fi + + +if [ "$NOEXTRACT" = "1" ]; then + warning "Skipping source extraction -- using existing src/ tree" + warning "Skipping source integrity checks -- using existing src/ tree" else -# generate md5 hashes - if [ ! `type -p md5sum` ]; then - error "Cannot find the md5sum program." - exit 1 - fi - msg "Generating MD5sums for source files" - plain "" - ct=0 - newline=0 - numsrc=${#source[@]} - for netfile in ${source[@]}; do - file=`strip_url $netfile` - sum=`md5sum $file | cut -d' ' -f 1` - if [ $ct -eq 0 ]; then - echo -n "md5sums=(" - else - if [ $newline -eq 0 ]; then - echo -n " " - fi - fi - echo -n "'$sum'" - ct=$(($ct+1)) - if [ $ct -eq $numsrc ]; then - echo ')' - else - if [ $newline -eq 1 ]; then - echo '\' - newline=0 - else - echo -n ' ' - newline=1 - fi - fi - done - plain "" - exit 0 + integ="$(echo $INTEGRITY_CHECK | tr A-Z a-z)" + case "$integ" in + md5) integrity_name="md5sum" ;; + sha1) integrity_name="sha1sum" ;; + *) error "Invalid integrity algorithm '$integ' specified"; exit 1;; + esac + if [ ! $(type -p $integrity_name) ]; then + error "Cannot find the $integrity_name program." + exit 1 + fi + + if [ "$GENINTEG" = "1" ]; then + msg "Generating ${integrity_name}s for source files" + plain "" + ct=0 + newline=0 + numsrc=${#source[@]} + for netfile in "${source[@]}"; do + file=`strip_url "$netfile"` + sum=$(eval "$integrity_name '$file' | cut -d' ' -f 1") + if [ $ct -eq 0 ]; then + echo -n "${integrity_name}s=(" + else + echo -ne "\t " + fi + echo -n "'$sum'" + ct=$(($ct+1)) + if [ $ct -eq $numsrc ]; then + echo ')' + else + echo ' \' + newline=0 + fi + done + plain "" + exit 0 + else #validation + integrity_sums=($(eval echo \${${integrity_name}s[@]})) + + if [ ${#integrity_sums[@]} -eq ${#source[@]} ]; then + msg "Validating source files with ${integrity_name}s" + errors=0 + idx=0 + for netfile in "${source[@]}"; do + file=$(strip_url "$netfile") + echo -n " $file ... " >&2 + echo "${integrity_sums[$idx]} $file" | $integrity_name -c - >/dev/null 2>&1 + if [ $? -ne 0 ]; then + echo "FAILED" >&2 + errors=1 + else + echo "Passed" >&2 + fi + idx=$(($idx+1)) + done + if [ $errors -gt 0 ]; then + error "One or more files did not pass the validity check!" + exit 1 + fi + else + warning "Integrity checks ($INTEGRITY_CHECK) are missing or incomplete." + fi + + msg "Extracting Sources..." + for netfile in "${source[@]}"; do + unziphack=0 + file=`strip_url "$netfile"` + unset cmd + case "`echo $file |tr "A-Z" "a-z"`" in + *.tar.gz|*.tar.z|*.tgz) + cmd="tar --use-compress-program=gzip -xf $file" ;; + *.tar.bz2|*.tbz2) + cmd="tar --use-compress-program=bzip2 -xf $file" ;; + *.tar) + cmd="tar -xf $file" ;; + *.zip) + unziphack=1 + cmd="unzip -qqo $file" ;; + *.cpio.gz) + cmd="bsdtar -x -f $file" ;; + *.cpio.bz2) + cmd="bsdtar -x -f $file" ;; + *.gz) + cmd="gunzip -f $file" ;; + *.bz2) + cmd="bunzip2 -f $file" ;; + esac + if [ "$cmd" != "" ]; then + msg " $cmd" + $cmd + if [ $? -ne 0 ]; then + # unzip will return a 1 as a warning, it is not an error + if [ "$unziphack" != "1" -o $? -ne 1 ]; then + error "Failed to extract $file" + msg "Aborting..." + exit 1 + fi + fi + fi + done + fi fi if [ "`id -u`" = "0" ]; then @@ -625,10 +691,6 @@ fi # use distcc if requested if [ "$DISTCC" = "y" ]; then [ -d /usr/lib/distcc/bin ] && export PATH=/usr/lib/distcc/bin:$PATH - if [ "$INCHROOT" = "1" ]; then - [ -d /var/tmp/fst/.distcc ] || mkdir /var/tmp/fst/.distcc - export DISTCC_DIR=/var/tmp/fst/.distcc - fi fi # use ccache if it's available @@ -638,10 +700,30 @@ fi # build msg "Starting build()..." -build 2>&1 -if [ $? -gt 0 ]; then - error "Build Failed. Aborting..." - exit 2 +if [ "$LOGGING" = "1" ]; then + BUILDLOG="${startdir}/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log" + if [ -f "$BUILDLOG" ]; then + i=1 + while true; do + if [ -f "$BUILDLOG.$i" ]; then + i=$(($i +1)) + else + break + fi + done + mv "$BUILDLOG" "$BUILDLOG.$i" + fi + build 2>&1 | tee "$BUILDLOG" + if [ ${PIPESTATUS[0]} -gt 0 ]; then + error "Build Failed. Aborting..." + exit 2 + fi +else + build 2>&1 + if [ $? -gt 0 ]; then + error "Build Failed. Aborting..." + exit 2 + fi fi if [ ! "`check_option KEEPDOCS`" -a "$KEEPDOCS" = "0" ]; then @@ -772,9 +854,9 @@ tar cvf /dev/null * | sort >.FILELIST msg "Compressing package..." cd $startdir/pkg if [ -f $startdir/pkg/.INSTALL ]; then - cmd="tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO .FILELIST .INSTALL *" + cmd="tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel-${CARCH}.${PKGEXT} .PKGINFO .FILELIST .INSTALL *" else - cmd="tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel.pkg.tar.gz .PKGINFO .FILELIST *" + cmd="tar czvf $PKGDEST/$pkgname-$pkgver-$pkgrel-${CARCH}.${PKGEXT} .PKGINFO .FILELIST *" fi $cmd | sort >../filelist @@ -782,6 +864,7 @@ cd $startdir if [ "$CLEANUP" = "1" ]; then msg "Cleaning up..." rm -rf src pkg filelist + rm -rf ${pkgname}-${pkgver}-${pkgrel}-${CARCH}.log* fi if [ "$RMDEPS" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" -a \( ! -z "$deplist" -o ! -z "$makedeplist" \) ]; then @@ -804,7 +887,7 @@ msg "Finished making: $pkgname (`date`)" if [ "$INSTALL" = "1" -a "`id -u`" = "0" -a "$INFAKEROOT" != "1" ]; then msg "Installing package with pacman -U..." - pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz + pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.${PKGEXT} exit $? elif [ "$INSTALL" = "1" -a "$DEP_SUDO" = "1" ]; then msg "Installing package with pacman -U..." @@ -812,7 +895,7 @@ elif [ "$INSTALL" = "1" -a "$DEP_SUDO" = "1" ]; then FAKEROOTKEY2=$FAKEROOTKEY unset FAKEROOTKEY fi - sudo pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}.pkg.tar.gz + sudo pacman $PACMAN_OPTS -U $PKGDEST/${pkgname}-${pkgver}-${pkgrel}-${CARCH}.${PKGEXT} if [ "$INFAKEROOT" = "1" ]; then export FAKEROOTKEY=$FAKEROOTKEY2 unset FAKEROOTKEY2 diff --git a/src/pacman/Makefile.am b/src/pacman/Makefile.am index 0e11d82f..956cdecb 100644 --- a/src/pacman/Makefile.am +++ b/src/pacman/Makefile.am @@ -6,20 +6,17 @@ localedir = $(datadir)/locale DEFS = -DLOCALEDIR=\"$(localedir)\" @DEFS@ AM_CFLAGS = $(CFLAGS) -D_GNU_SOURCE \ - -I$(top_srcdir)/lib/libalpm \ - -I$(top_srcdir)/lib/libfetch + -I$(top_srcdir)/lib/libalpm -pacman_SOURCES = util.c log.c list.c package.c download.c trans.c add.c \ +pacman_SOURCES = util.c log.c list.c package.c downloadprog.c trans.c add.c \ remove.c upgrade.c query.c sync.c conf.c deptest.c pacman.c pacman_static_SOURCES = $(pacman_SOURCES) pacman_LDADD = -L$(top_srcdir)/lib/libalpm/.libs \ - -L$(top_srcdir)/lib/libfetch -lfetch \ - -larchive -lm -lalpm -lssl -lcrypto + -ldownload -larchive -lm -lalpm -lssl -lcrypto pacman_static_LDADD = -L$(top_srcdir)/lib/libalpm/.libs/ \ - -L$(top_srcdir)/lib/libfetch -lfetch \ - -larchive -lm -lalpm -lssl -lcrypto + -ldownload -larchive -lm -lalpm -lssl -lcrypto pacman_static_LDFLAGS = $(LDFLAGS) -all-static diff --git a/src/pacman/add.c b/src/pacman/add.c index 7c4cd909..600bc625 100644 --- a/src/pacman/add.c +++ b/src/pacman/add.c @@ -28,7 +28,7 @@ /* pacman */ #include "log.h" #include "list.h" -#include "download.h" +#include "downloadprog.h" #include "trans.h" #include "add.h" #include "conf.h" diff --git a/src/pacman/conf.c b/src/pacman/conf.c index dc7b64b6..72c55f35 100644 --- a/src/pacman/conf.c +++ b/src/pacman/conf.c @@ -31,7 +31,7 @@ #include "log.h" #include "list.h" #include "sync.h" -#include "download.h" +#include "downloadprog.h" #include "conf.h" extern list_t *pmc_syncs; diff --git a/src/pacman/pacman.c b/src/pacman/pacman.c index c5be07d6..79c15c3f 100644 --- a/src/pacman/pacman.c +++ b/src/pacman/pacman.c @@ -46,7 +46,7 @@ #include "list.h" #include "util.h" #include "log.h" -#include "download.h" +#include "downloadprog.h" #include "conf.h" #include "package.h" #include "add.h" @@ -187,8 +187,8 @@ static void cleanup(int signum) fprintf(stderr, "Internal pacman error: Segmentation fault\n" "Please submit a full bug report, with the given package if appropriate.\n"); exit(signum); - } else if((signum == SIGINT) && (alpm_trans_release() == -1) && (pm_errno == - PM_ERR_TRANS_COMMITING)) { + } else if((signum == SIGINT) && (alpm_trans_release() == -1) + && (pm_errno == PM_ERR_TRANS_COMMITING)) { return; } if(signum != 0 && config->op_d_vertest == 0) { @@ -411,7 +411,7 @@ int main(int argc, char *argv[]) list_t *lp; #if defined(PACMAN_DEBUG) && !defined(CYGWIN) && !defined(BSD) - setenv("MALLOC_TRACE","pacman.mtrace", 0); + /*setenv("MALLOC_TRACE","pacman.mtrace", 0);*/ mtrace(); #endif cenv = getenv("COLUMNS"); diff --git a/src/pacman/query.c b/src/pacman/query.c index 1736a935..517ade74 100644 --- a/src/pacman/query.c +++ b/src/pacman/query.c @@ -119,6 +119,7 @@ int pacman_query(list_t *targets) indentprint((char *)alpm_pkg_getinfo(pkg, PM_PKG_DESC), 4); printf("\n"); } + alpm_list_free_outer(ret); return(0); } diff --git a/src/pacman/sync.c b/src/pacman/sync.c index 113e1675..5c6c7ac5 100644 --- a/src/pacman/sync.c +++ b/src/pacman/sync.c @@ -37,11 +37,11 @@ #endif #include <alpm.h> -#include <fetch.h> /* fetchLastErrString */ +#include <download.h> /* downloadLastErrString */ /* pacman */ #include "util.h" #include "log.h" -#include "download.h" +#include "downloadprog.h" #include "list.h" #include "package.h" #include "trans.h" @@ -168,8 +168,8 @@ static int sync_synctree(int level, list_t *syncs) ret = alpm_db_update((level < 2 ? 0 : 1), sync->db); if(ret < 0) { if(pm_errno == PM_ERR_DB_SYNC) { - /* use libfetch error */ - ERR(NL, _("failed to synchronize %s: %s\n"), sync->treename, fetchLastErrString); + /* use libdownload error */ + ERR(NL, _("failed to synchronize %s: %s\n"), sync->treename, downloadLastErrString); } else { ERR(NL, _("failed to update %s (%s)\n"), sync->treename, alpm_strerror(pm_errno)); } @@ -216,6 +216,7 @@ static int sync_search(list_t *syncs, list_t *targets) indentprint((char *)alpm_pkg_getinfo(pkg, PM_PKG_DESC), 4); printf("\n"); } + alpm_list_free_outer(ret); } else { PM_LIST *lp; @@ -546,25 +547,22 @@ int pacman_sync(list_t *targets) } MSG(CL, "\n"); } - alpm_list_free(data); break; case PM_ERR_CONFLICTING_DEPS: - for(lp = alpm_list_first(data); lp; lp = alpm_list_next(lp)) { + for(lp = alpm_list_first(data); lp; lp = alpm_list_next(lp)) { PM_DEPMISS *miss = alpm_list_getdata(lp); MSG(NL, _(":: %s: conflicts with %s"), - alpm_dep_getinfo(miss, PM_DEP_TARGET), alpm_dep_getinfo(miss, PM_DEP_NAME)); + alpm_dep_getinfo(miss, PM_DEP_TARGET), alpm_dep_getinfo(miss, PM_DEP_NAME)); } - alpm_list_free(data); break; case PM_ERR_DISK_FULL: lp = alpm_list_first(data); pkgsize = alpm_list_getdata(lp); lp = alpm_list_next(lp); freespace = alpm_list_getdata(lp); - MSG(NL, _(":: %.1f MB required, have %.1f MB"), - (double)(*pkgsize / 1048576.0), (double)(*freespace / 1048576.0)); - alpm_list_free(data); + MSG(NL, _(":: %.1f MB required, have %.1f MB"), + (double)(*pkgsize / 1048576.0), (double)(*freespace / 1048576.0)); break; default: break; @@ -712,6 +710,10 @@ int pacman_sync(list_t *targets) /* Step 4: release transaction resources */ cleanup: + if(data) { + alpm_list_free(data); + data = NULL; + } if(alpm_trans_release() == -1) { ERR(NL, _("failed to release transaction (%s)\n"), alpm_strerror(pm_errno)); retval = 1; |