commit e3ad0ef694f133d068009bfbbc057220db0d647b Author: Dmitry V. Levin Date: Wed Mar 27 15:18:37 2002 +0000 0.3.19cnc55-alt3 - Added librpm-4.0.4 build support. - Built with librpm-4.0.4, updated buildrequires. diff --git a/.gear-rules b/.gear-rules new file mode 100644 index 0000000..bb7c6e7 --- /dev/null +++ b/.gear-rules @@ -0,0 +1,4 @@ +copy: *.conf +copy: *.patch +tar.bz2: apt +copy: rpmpriorities diff --git a/apt-0.3.19cnc32-alt-distro.patch b/apt-0.3.19cnc32-alt-distro.patch new file mode 100644 index 0000000..4bcd1c0 --- /dev/null +++ b/apt-0.3.19cnc32-alt-distro.patch @@ -0,0 +1,21 @@ +diff -k.orig -urN apt-0.3.19cnc32/cmdline/apt-cdrom.cc.orig apt-0.3.19cnc32/cmdline/apt-cdrom.cc +--- apt-0.3.19cnc32/cmdline/apt-cdrom.cc.orig Thu Jan 4 23:26:14 2001 ++++ apt-0.3.19cnc32/cmdline/apt-cdrom.cc Mon Jan 22 17:22:32 2001 +@@ -723,7 +723,7 @@ + if (0) + return _error->Error(_("Unable to locate any package files, perhaps this is not a Debian Disc")); + else +- return _error->Error(_("Unable to locate any package files, perhaps this is not a Conectiva Disc")); ++ return _error->Error(_("Unable to locate any package files, perhaps this is not a ALT Linux Disc")); + } + // Check if the CD is in the database + string Name; +@@ -748,7 +748,7 @@ + if (_config->FindB("APT::CDROM::Rename",false) == true || + Name.empty() == true) + { +- cout << _("Please provide a name for this Disc, such as 'MyDistro 6.0 Disk 1'"); ++ cout << _("Please provide a name for this Disc, such as 'Spring 2001 Disk 1'"); + + while (1) + { diff --git a/apt-0.3.19cnc52-alt-INLINEDEPFLAG.patch b/apt-0.3.19cnc52-alt-INLINEDEPFLAG.patch new file mode 100644 index 0000000..e59f4a6 --- /dev/null +++ b/apt-0.3.19cnc52-alt-INLINEDEPFLAG.patch @@ -0,0 +1,11 @@ +--- apt-0.3.19cnc52/buildlib/environment.mak.in.orig Thu Aug 2 01:31:58 2001 ++++ apt-0.3.19cnc52/buildlib/environment.mak.in Sun Aug 5 13:49:41 2001 +@@ -22,7 +22,7 @@ + + # Dep generation - this only works for gnu stuff + GCC3DEP = @GCC3DEP@ +-INLINEDEPFLAG = -MD ++#INLINEDEPFLAG = -MD + + # Debian doc stuff + DEBIANDOC_HTML = @DEBIANDOC_HTML@ diff --git a/apt-0.3.19cnc53-alt-configure-build.patch b/apt-0.3.19cnc53-alt-configure-build.patch new file mode 100644 index 0000000..8afb261 --- /dev/null +++ b/apt-0.3.19cnc53-alt-configure-build.patch @@ -0,0 +1,63 @@ +diff -ur apt-0.3.19cnc55~/configure.in apt-0.3.19cnc55/configure.in +--- apt-0.3.19cnc55~/configure.in Wed Mar 6 20:17:10 2002 ++++ apt-0.3.19cnc55/configure.in Tue Mar 26 21:14:21 2002 +@@ -64,20 +64,12 @@ + dnl AC_MSG_ERROR(failed: I need posix threads, pthread) + dnl fi + +-dnl Check for DB2 +-AC_CHECK_HEADER(db2/db.h, +- [AC_CHECK_LIB(db2,db_open, +- [AC_DEFINE(HAVE_DB2) DB2LIB="-ldb2"])]) +-AC_SUBST(DB2LIB) +- +- + dnl Check for rpm version --akk + rpm_version="none" + SAVE_LIBS="$LIBS" + SAVE_CPPFLAGS="$CPPFLAGS" + + CPPFLAGS="$SAVE_CPPFLAGS -I/usr/include/rpm" +-AC_CHECK_HEADERS(db1/db.h) + AC_CHECK_HEADER(rpm/rpmlib.h, rpm_header_ok=1, rpm_header_ok=0) + + if test $rpm_header_ok = 1; then +@@ -85,7 +77,7 @@ + LIBS="$SAVE_LIBS -lrpm -lrpmio -lz -lbz2 -lpopt" + AC_CHECK_LIB(rpmdb,rpmdbOpen, + [RPMDBLIBS="-lrpmdb"], +- [RPMDBLIBS="-ldb-3.1"]) ++ [RPMDBLIBS="-ldb"]) + + LIBS="$SAVE_LIBS $RPMDBLIBS -lrpmio -lz -lbz2 -lpopt" + AC_CHECK_LIB(rpm,rpmdbGetIteratorOffset, +@@ -100,6 +92,7 @@ + [AC_DEFINE_UNQUOTED(HAVE_RPM, 1) + RPMLIBS="-lrpm -ldb1 -lz -lbz2 -lpopt" + SAVE_CPPFLAGS="$SAVE_CPPFLAGS -I/usr/include/rpm" ++ AC_CHECK_HEADERS(db1/db.h) + rpm_version="3"]) + fi + fi +diff -ur apt-0.3.19cnc55~/tools/cached_md5.cc apt-0.3.19cnc55/tools/cached_md5.cc +--- apt-0.3.19cnc55~/tools/cached_md5.cc Sun Feb 17 01:46:11 2002 ++++ apt-0.3.19cnc55/tools/cached_md5.cc Sun Feb 17 01:46:25 2002 +@@ -39,6 +39,7 @@ + #include + #include + #include ++#include + #include + #include + #include +diff -ur apt-0.3.19cnc55~/tools/hdlist2pkglist.cc apt-0.3.19cnc55/tools/hdlist2pkglist.cc +--- apt-0.3.19cnc55~/tools/hdlist2pkglist.cc Sun Feb 17 01:46:11 2002 ++++ apt-0.3.19cnc55/tools/hdlist2pkglist.cc Sun Feb 17 01:46:46 2002 +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + #include diff --git a/apt-0.3.19cnc53-alt-strsignal.patch b/apt-0.3.19cnc53-alt-strsignal.patch new file mode 100644 index 0000000..a25c452 --- /dev/null +++ b/apt-0.3.19cnc53-alt-strsignal.patch @@ -0,0 +1,11 @@ +--- apt-0.3.19cnc53/apt-pkg/rpm/rpmpm.cc~ Tue Nov 13 20:32:08 2001 ++++ apt-0.3.19cnc53/apt-pkg/rpm/rpmpm.cc Fri Nov 16 19:10:19 2001 +@@ -402,7 +402,7 @@ + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + { + if (WIFSIGNALED(Status) != 0) +- return _error->Error(_("Sub-process %s terminated by signal (%i)") ,Args[0], WTERMSIG(Status) ); ++ return _error->Error(_("Sub-process %s terminated by signal (%s)") ,Args[0], strsignal(WTERMSIG(Status)) ); + + if (WIFEXITED(Status) != 0) + return _error->Error(_("Sub-process %s returned an error code (%u)"),Args[0], diff --git a/apt-0.3.19cnc53-stelian-apt-pkg-algorithms-scores.patch b/apt-0.3.19cnc53-stelian-apt-pkg-algorithms-scores.patch new file mode 100644 index 0000000..4c934fe --- /dev/null +++ b/apt-0.3.19cnc53-stelian-apt-pkg-algorithms-scores.patch @@ -0,0 +1,47 @@ +On Tue, Nov 20, 2001 at 02:28:53PM +0200, Matilainen Panu wrote: + +> > I think this is the same bug (if it's a bug of course). +[...] +> The sane-split? I got it working by changing sane-frontends to have +> Provides: sane = %{version} +> and sane-backends +> Conflicts: sane < %{version} +> +> With the additional version information it manages to sort this out +> correctly. + +I managed to find a hack permitting this to work without any +package modifications: when package scores are calculated +(based on package priorities and Depends:), I've added some +additionnal code to increment the priority of a package which +obsoletes another. This additionnal 'point' score makes the +right package to be selected for installation. + +It works for me in simple cases, but it definately needs more +testing. + +Comments ? + +Stelian. + + +--- apt-0.3.19cnc53/apt-pkg/algorithms.cc.orig Wed Nov 21 17:45:34 2001 ++++ apt-0.3.19cnc53/apt-pkg/algorithms.cc Wed Nov 21 17:46:12 2001 +@@ -454,6 +454,8 @@ + { + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + Scores[D.TargetPkg()->ID]++; ++ if (D->Type == pkgCache::Dep::Obsoletes) ++ Scores[I->ID]++; + } + } + +-- +Stelian Pop +|---------------- Free Software Engineer -----------------| +| Alcфve - http://www.alcove.com - Tel: +33 1 49 22 68 00 | +|------------- Alcфve, liberating software ---------------| +_______________________________________________ +Apt-rpm mailing list +Apt-rpm@distro.conectiva.com.br +http://distro.conectiva.com.br/mailman/listinfo/apt-rpm diff --git a/apt-0.3.19cnc55-alt-AllowedDupPkgs-HoldPkgs.patch b/apt-0.3.19cnc55-alt-AllowedDupPkgs-HoldPkgs.patch new file mode 100644 index 0000000..fc3384a --- /dev/null +++ b/apt-0.3.19cnc55-alt-AllowedDupPkgs-HoldPkgs.patch @@ -0,0 +1,18 @@ +diff -ur apt-0.3.19cnc55~/apt-pkg/init.cc apt-0.3.19cnc55/apt-pkg/init.cc +--- apt-0.3.19cnc55~/apt-pkg/init.cc Thu Aug 2 01:35:12 2001 ++++ apt-0.3.19cnc55/apt-pkg/init.cc Thu Mar 21 18:47:24 2002 +@@ -38,12 +38,9 @@ + Cnf.Set("Dir::State::status","/var/lib/dpkg/status"); + } else { + Cnf.Set("Acquire::cdrom::mount", "/mnt/cdrom"); +- Cnf.Set("RPM::AllowedDupPkgs::","^kernel$"); +- Cnf.Set("RPM::AllowedDupPkgs::", "kernel-smp"); +- Cnf.Set("RPM::AllowedDupPkgs::", "kernel-enterprise"); ++ Cnf.Set("RPM::AllowedDupPkgs::", "^(NVIDIA_)?(kernel|alsa)[0-9]*($|-up|-smp|-secure|-custom|-enterprise|-BOOT|-tape|-aureal)"); + +- Cnf.Set("RPM::HoldPkgs::", "kernel-source"); +- Cnf.Set("RPM::HoldPkgs::", "kernel-headers"); ++ Cnf.Set("RPM::HoldPkgs::", "^(kernel|alsa)[0-9]*-source"); + + Cnf.Set("Dir::State::status","/var/lib/rpm/status"); + } diff --git a/apt-0.3.19cnc55-alt-apt-pkg-rpmpm-execute_rpm.patch b/apt-0.3.19cnc55-alt-apt-pkg-rpmpm-execute_rpm.patch new file mode 100644 index 0000000..92b91b5 --- /dev/null +++ b/apt-0.3.19cnc55-alt-apt-pkg-rpmpm-execute_rpm.patch @@ -0,0 +1,56 @@ +--- apt-0.3.19cnc55~/apt-pkg/rpm/rpmpm.cc Wed Mar 6 20:17:13 2002 ++++ apt-0.3.19cnc55/apt-pkg/rpm/rpmpm.cc Thu Mar 21 22:35:05 2002 +@@ -287,14 +287,16 @@ + case OInstall: + options = "-i"; + +- Args[n++] = "-i"; ++ Args[n++] = "-iv"; + + Args[n++] = "--replacepkgs"; + + if (noninteractive) + Args[n++] = "--percent"; +- else ++ else { + Args[n++] = "-h"; ++ Args[n++] = "--fancypercent"; ++ } + + if (_config->FindB("RPM::Force", false) == true) + Args[n++] = "--force"; +@@ -309,8 +311,10 @@ + + if (noninteractive) + Args[n++] = "--percent"; +- else ++ else { + Args[n++] = "-h"; ++ Args[n++] = "--fancypercent"; ++ } + + if (_config->FindB("RPM::Force", false) == true) + Args[n++] = "--force"; +@@ -330,6 +334,13 @@ + if (nodeps) + Args[n++] = "--nodeps"; + ++ string cmd; ++ for (unsigned i = 0; i < n; ++i) ++ { ++ if (cmd.length()) ++ cmd += ' '; ++ cmd += Args[i]; ++ } + + for (slist::iterator i = files->begin(); + i != files->end() && n < sizeof(Args); +@@ -349,7 +360,7 @@ + return true; + } + +- cout << _("Executing RPM (")<Errno("read","Problem hashing file"); + return false; + } +@@ -323,7 +323,7 @@ + } + MyLen += Res; + +- Hash.Add(Buffer,Res); ++ MD5.Add(Buffer,Res); + if (To.Write(Buffer,Res) == false) + { + Close(); +@@ -428,7 +428,7 @@ + } + + // Open the file +- Hashes Hash; ++ MD5Summation MD5; + { + FileFd Fd(Itm->DestFile,FileFd::WriteAny); + if (_error->PendingError() == true) +@@ -441,7 +441,7 @@ + FailFd = Fd.Fd(); + + bool Missing; +- if (Server->Get(File,Fd,Res.ResumePoint,Hash,Missing,Res.Size) == false) ++ if (Server->Get(File,Fd,Res.ResumePoint,MD5,Missing,Res.Size) == false) + { + Fd.Close(); + +@@ -462,7 +462,7 @@ + } + + Res.LastModified = FailTime; +- Res.TakeHashes(Hash); ++ Res.MD5Sum = MD5.Result(); + + // Timestamp + struct utimbuf UBuf; +diff -ur apt-0.3.19cnc55/methods/rsh.h apt-0.3.19cnc53/methods/rsh.h +--- apt-0.3.19cnc55/methods/rsh.h Fri Nov 30 23:34:13 2001 ++++ apt-0.3.19cnc53/methods/rsh.h Thu Mar 21 20:05:08 2002 +@@ -12,7 +12,7 @@ + + #include + #include +-#include ++#include + #include + #include + +@@ -44,7 +44,7 @@ + bool Size(const char *Path,unsigned long &Size); + bool ModTime(const char *Path, time_t &Time); + bool Get(const char *Path,FileFd &To,unsigned long Resume, +- Hashes &Hash,bool &Missing, unsigned long Size); ++ MD5Summation &MD5,bool &Missing, unsigned long Size); + + RSHConn(URI Srv); + ~RSHConn(); diff --git a/apt-0.3.19cnc55-alt-genbasedir.patch b/apt-0.3.19cnc55-alt-genbasedir.patch new file mode 100644 index 0000000..b7c5b48 --- /dev/null +++ b/apt-0.3.19cnc55-alt-genbasedir.patch @@ -0,0 +1,489 @@ +--- apt-0.3.19cnc55~/tools/genbasedir Wed Mar 6 20:17:13 2002 ++++ apt-0.3.19cnc55/tools/genbasedir Thu Mar 21 22:15:32 2002 +@@ -69,99 +69,103 @@ + # Language setting to generate a consistent pkglist. + # + +-usage="\ +-Usage: genbasedir [] [ ... ]\n\ +-Options:\n\ +- -s, --sign Generate and sign hashfile\n\ +- --hashonly Do hashfile stuff only\n\ +- --listonly Generate pkglists/srclists and quit\n\ +- --bz2only Generate only compressed lists\n\ +- --topdir=dir Top directory of repository\n\ +- --progress Show progress bars for genpkglist/gensrclist\n\ +- --updateinfo=file Update information file\n" ++PROG="${0##*/}" + + basedir=. + signature=0 + listonly=0 + hashonly=0 +-updateinfo="" +-mapi=0 +-bz2only=0 ++updateinfo= ++mapi= ++gpguid= ++topdir= ++bz2only=k + progress= + + # bloat is necessary for non-Conectiva distros, at least RH, + # because they use file dependencies with a non-predictable + # heuristic. So we can't strip-off paths that will probably + # never appear in dependencies. +-bloat="" +- ++bloat= + + # flat is for repositories where RPMS and SRPMS are kept in the + # same directory level. + flat="" + +-while test $# -gt 0 ; do +- case "${1}" in +- -h | --help) +- echo -e "${usage}" +- exit 0 +- ;; +- --mapi) +- # hee hee hee.. +- mapi=1 +- ;; +- --listonly) +- listonly=1 +- ;; +- --hashonly) +- hashonly=1 +- ;; +- --bz2only) +- bz2only=1 +- ;; +- --updateinfo=*) +- updateinfo=${1} +- ;; +- --bloat) +- bloat="--bloat" +- ;; +- --flat) +- flat="--flat" +- ;; +- --topdir=*) +- topdir="`echo \"${1}\" | sed -e 's/^[^=]*=//'`" +- if [ ! -d $topdir ]; then +- echo "Invalid top directory for distribution ${topdir}" 1>&2 +- exit 1 +- fi +- ;; +- --progress) +- progress="--progress" +- ;; +- -s | --sign) +- signature=1; +- ;; +- -*) +- echo -e "${usage}" 1>&2 +- exit 1 +- ;; +- *) +- break +- ;; +- esac +- shift ++USAGE() ++{ ++ cat >&2 <] [ ... ] ++Options: ++ -s, --sign Generate and sign hashfile ++ --hashonly Do hashfile stuff only ++ --listonly Generate pkglists/srclists and quit ++ --bz2only Generate only compressed lists ++ --topdir=dir Top directory of repository ++ --updateinfo=file Update information file ++ --bloat Do not strip the package file list. Needed for some ++ distributions that use non-automatically generated file dependencies ++ --uid=uid Pass different GPG user ID for signing ++ --progress Show progress bars for genpkglist/gensrclist ++EOF ++ [ -n "$1" ] && exit "$1" || exit ++} ++ ++TEMP=`getopt -n $PROG -o hs -l help,mapi,listonly,bz2only,hashonly,updateinfo:,bloat,topdir:,sign,uid:,progress -- "$@"` || USAGE ++eval set -- "$TEMP" ++ ++while :; do ++ case "$1" in ++ --listonly) shift; listonly=1 ++ ;; ++ --bz2only) shift; bz2only= ++ ;; ++ --hashonly) shift; hashonly=1 ++ ;; ++ -s|--sign) shift; signature=1 ++ ;; ++ --bloat) shift; bloat="--bloat" ++ ;; ++ --mapi) shift; mapi="--mapi" ++ ;; ++ --updateinfo) shift; updateinfo="$1"; shift ++ ;; ++ --uid) shift; gpguid="$1"; shift ++ ;; ++ --topdir) shift; topdir="$1"; shift ++ ;; ++ --flat) shift; float="--float" ++ ;; ++ --progress) shift; progress="--progress" ++ ;; ++ -h|--help) USAGE 0 ++ ;; ++ --) shift; break ++ ;; ++ *) echo "$PROG: unrecognized option: $1" >&2; exit 1 ++ ;; ++ esac + done + +-distro=${1} +-shift ++topdir="$(echo "$topdir" |sed ' ++s:/\(\./\)\+:/:g ++s:/\+:/:g ++s:/$:: ++')" + +-components=$* ++[ -n "$topdir" ] || USAGE 1 + +-if [ -z "$components" ]; then +- echo -e "${usage}" +- exit 0 ++if [ ! -d "$topdir" ]; then ++ echo "Invalid top directory for distribution: $topdir" >&2 ++ exit 1 + fi + ++distro=${1} ++shift ++ ++components="$*" ++ ++[ -n "$components" ] || USAGE 1 + + getsize() { + tmp=`wc -c $1` +@@ -186,75 +190,88 @@ + basedir_=`echo ${distro}/base|tr -s /` + basedir=${topdir}/$basedir_ + ++WORKDIR= ++ ++Exit() ++{ ++ RETVAL=$? ++ trap '' EXIT ++ [ -z "$WORKDIR" ] || rm -rf "$WORKDIR" ++ exit $RETVAL ++} ++ ++trap 'Exit ' SIGHUP SIGPIPE SIGINT SIGQUIT SIGTERM EXIT ++ ++WORKDIR="$(mktemp -dt "$PROG.XXXXXXXXXX")" ++ ++SRCIDX_COMP="$WORKDIR/comp" ++SRCIDX="$WORKDIR/total" ++ ++saved_list= ++ ++save_file() ++{ ++ saved_list="$1" ++ ++ if [ -f "$saved_list" ]; then ++ mv -f "$saved_list" "$saved_list.old" ++ else ++ saved_list= ++ fi ++} + +-# release file +-# ------------ ++compare_file() ++{ ++ if [ -n "$saved_list" -a -f "$saved_list.old" ]; then ++ if cmp -s "$saved_list.old" "$saved_list"; then ++ mv -f "$saved_list.old" "$saved_list" ++ else ++ rm -f "$saved_list.old" ++ fi ++ fi ++} + +-#for comp in ${components}; do +-# true > ${basedir}/release.$comp +-# +-#done ++for comp in ${components}; do ++ [ -f "$basedir/release.$comp" ] || touch "$basedir/release.$comp" ++done + + +-if [ $hashonly -ne 1 ]; then ++if [ "$hashonly" -ne 1 ]; then + # package lists + # ------------- + +-true > /tmp/srcidx.$$ +- + for comp in ${components}; do + echo -n "${comp}: " + + echo -n "pkglist " + ++ newlist="$basedir/pkglist.$comp" ++ + # Save older pkglist +- if [ -f $basedir/pkglist.$comp ]; then +- mv -f $basedir/pkglist.$comp $basedir/pkglist.$comp.old +- fi ++ save_file "$newlist" + +- if test x$updateinfo = x; then +- (cd $basedir; genpkglist $progress $bloat --index /tmp/srcidx.$comp.$$ $topdir/${distro} $comp) ++ :>"$SRCIDX_COMP" ++ if [ -z "$updateinfo" ]; then ++ (cd "$basedir"; genpkglist $progress $bloat --index "$SRCIDX_COMP" "$topdir/$distro" "$comp") + else +- (cd $basedir; genpkglist $progress $bloat --index /tmp/srcidx.$comp.$$ --info $updateinfo $topdir/${distro} $comp) ++ (cd "$basedir"; genpkglist $progress $bloat --index "$SRCIDX_COMP" --info "$updateinfo" "$topdir/$distro" "$comp") + fi ++ + if [ $? -ne 0 ]; then + echo + echo "Error executing genpkglist." + exit 1 + fi + +- if [ -f $basedir/pkglist.$comp ]; then +- +- # Compare with older pkglist. +- if [ -f $basedir/pkglist.$comp.old ]; then +- if cmp -s $basedir/pkglist.$comp.old $basedir/pkglist.$comp; then +- mv -f $basedir/pkglist.$comp.old $basedir/pkglist.$comp +- fi +- fi +- +- # Save older compressed pkglist +- if [ -f $basedir/pkglist.$comp.bz2 ]; then +- mv -f $basedir/pkglist.$comp.bz2 $basedir/pkglist.$comp.bz2.old +- fi +- +- bzip2 -c $basedir/pkglist.$comp > $basedir/pkglist.$comp.bz2 +- +- # Compare with older compressed pkglist. +- if [ -f $basedir/pkglist.$comp.bz2.old ]; then +- if cmp -s $basedir/pkglist.$comp.bz2.old $basedir/pkglist.$comp.bz2; then +- mv -f $basedir/pkglist.$comp.bz2.old $basedir/pkglist.$comp.bz2 +- fi +- fi +- +- if [ $bz2only -eq 1 ]; then +- rm -f $basedir/pkglist.$comp +- fi ++ # Compare with older pkglist. ++ compare_file + +- rm -f $basedir/pkglist.$comp.old +- rm -f $basedir/pkglist.$comp.bz2.old ++ if [ -f "$newlist" ]; then ++ rm -f "$newlist.bz2" ++ bzip2 -9$bz2only "$newlist" + fi + +- cat /tmp/srcidx.$comp.$$ >> /tmp/srcidx.$$ ++ cat "$SRCIDX_COMP" >> "$SRCIDX" + + echo "done" + done +@@ -264,77 +281,38 @@ + + echo -n "srclist " + +- # Save older srclist +- if [ -f $basedir/srclist.$comp ]; then +- mv -f $basedir/srclist.$comp $basedir/srclist.$comp.old +- fi ++ newlist="$basedir/srclist.$comp" + ++ # Save older srclist ++ save_file "$newlist" + +- sfix="/.." +- if test x$flat != x; then +- sfix="" +- fi ++ :>"$SRCIDX_COMP" ++ (cd "$basedir"; gensrclist $progress $flat $mapi "$topdir/$distro/.." "$comp" "$SRCIDX_COMP") + +- if [ $mapi -ne 0 ]; then +- (cd $basedir; gensrclist $progress $flat --mapi $topdir/${distro}${sfix} $comp /tmp/srcidx.$comp.$$) +- else +- (cd $basedir; gensrclist $progress $flat $topdir/${distro}${sfix} $comp /tmp/srcidx.$$) +- fi + if [ $? -ne 0 ]; then + echo + echo "Error executing gensrclist." + exit 1 + fi + ++ # Compare with older srclist. ++ compare_file + +- +- if [ -f $basedir/srclist.$comp ]; then +- +- # Compare with older srclist. +- if [ -f $basedir/srclist.$comp.old ]; then +- if cmp -s $basedir/srclist.$comp.old $basedir/srclist.$comp; then +- mv -f $basedir/srclist.$comp.old $basedir/srclist.$comp +- fi +- fi +- +- # Save older compressed srclist +- if [ -f $basedir/srclist.$comp.bz2 ]; then +- mv -f $basedir/srclist.$comp.bz2 $basedir/srclist.$comp.bz2.old +- fi +- +- bzip2 -c $basedir/srclist.$comp > $basedir/srclist.$comp.bz2 +- +- # Compare with older compressed srclist. +- if [ -f $basedir/srclist.$comp.bz2.old ]; then +- if cmp -s $basedir/srclist.$comp.bz2.old $basedir/srclist.$comp.bz2; then +- mv -f $basedir/srclist.$comp.bz2.old $basedir/srclist.$comp.bz2 +- fi +- fi +- +- if [ $bz2only -eq 1 ]; then +- rm -f $basedir/srclist.$comp +- fi +- +- rm -f $basedir/srclist.$comp.old +- rm -f $basedir/srclist.$comp.bz2.old ++ if [ -f "$newlist" ]; then ++ rm -f "$newlist.bz2" ++ bzip2 -9$bz2only "$newlist" + fi + +- rm -f /tmp/srcidx.$comp.$$ +- + echo "done" + done + + fi + +-rm -f /tmp/srcidx.$$ +- +-if [ $listonly -eq 0 ]; then ++if [ "$listonly" -eq 0 ]; then + # Save older hashfile +- if [ -f $basedir/hashfile ]; then +- mv -f $basedir/hashfile $basedir/hashfile.old +- fi ++ save_file "$basedir/hashfile" + hf=${basedir}/hashfile +- true > $hf ++ : > $hf + else + hf=/dev/null + fi +@@ -348,27 +326,21 @@ + srclist=${basedir}/srclist + release=${basedir}/release + +-for comp in ${components}; do +- echo -n "${comp}: " +- +- echo -n "hashfile " +- if [ -f ${pkglist}.$comp ]; then +- phashstuff ${pkglist}.$comp ${pkglist_}.$comp >> $hf +- fi +- if [ -f ${srclist}.$comp ]; then +- phashstuff ${srclist}.$comp ${srclist_}.$comp >> $hf +- fi ++phash() ++{ ++ if [ -f "$1" ]; then ++ phashstuff "$1" "$2" >> "$3" ++ fi ++} + +- if [ -f ${pkglist}.$comp.bz2 ]; then +- phashstuff ${pkglist}.$comp.bz2 ${pkglist_}.$comp.bz2 >> $hf +- fi +- if [ -f ${srclist}.$comp.bz2 ]; then +- phashstuff ${srclist}.$comp.bz2 ${srclist_}.$comp.bz2 >> $hf +- fi ++for comp in ${components}; do ++ echo -n "$comp: hashfile " + +- if [ -f ${release}.$comp ]; then +- phashstuff ${release}.$comp ${release_}.$comp >> $hf +- fi ++ phash "$pkglist.$comp" "$pkglist_.$comp" "$hf" ++ phash "$srclist.$comp" "$srclist_.$comp" "$hf" ++ phash "$pkglist.$comp.bz2" "$pkglist_.$comp.bz2" "$hf" ++ phash "$srclist.$comp.bz2" "$srclist_.$comp.bz2" "$hf" ++ phash "$release.$comp" "$release_.$comp" "$hf" + + echo "done" + done +@@ -377,34 +349,26 @@ + + if [ $listonly -eq 0 ]; then + # Compare with older hashfile. +- if [ -f $basedir/hashfile.old ]; then +- if cmp -s $basedir/hashfile.old $basedir/hashfile; then +- mv -f $basedir/hashfile.old $basedir/hashfile +- fi +- fi ++ compare_file + fi + +-if [ $signature -ne 0 -a $listonly -eq 0 ]; then ++if [ "$signature" -ne 0 -a "$listonly" -eq 0 ]; then ++ if [ -n "$gpguid" ]; then ++ DEFAULTKEY="--default-key $gpguid" ++ else ++ DEFAULTKEY= ++ fi + + # Save older hashfile.gpg +- if [ -f $basedir/hashfile.gpg ]; then +- mv -f $basedir/hashfile.gpg $basedir/hashfile.gpg.old +- fi ++ save_file "$basedir/hashfile.gpg" + +- gpg -armour -qs --yes $basedir/hashfile +- mv -f $basedir/hashfile.asc $basedir/hashfile.gpg +- rm -f $basedir/hashfile ++ gpg -armour $DEFAULTKEY -qs --yes $basedir/hashfile ++ mv -f "$basedir/hashfile.asc" "$basedir/hashfile.gpg" ++ rm -f "$basedir/hashfile" + + # Compare with older hashfile.gpg +- if [ -f $basedir/hashfile.gpg.old ]; then +- if cmp -s $basedir/hashfile.gpg.old $basedir/hashfile.gpg; then +- mv -f $basedir/hashfile.gpg.old $basedir/hashfile.gpg +- fi +- fi ++ compare_file + fi +- +-rm -f $basedir/hashfile.old +-rm -f $basedir/hashfile.gpg.old + + echo "All your base are belong to us !!" + diff --git a/apt.conf b/apt.conf new file mode 100644 index 0000000..767039b --- /dev/null +++ b/apt.conf @@ -0,0 +1,36 @@ +Dir +{ + Bin + { + Methods "/usr/lib/apt"; + } +} + +APT +{ + Get + { + Show-Upgraded "true"; + } + + GPG + { + PubringPath "/usr/lib/rpm/gnupg"; + } + + Architecture "i586"; +} + +Debug +{ + pkgRPMPM "false"; +} + +Acquire::CDROM::Copy "true"; + +RPM +{ + Options "-vv"; +} + + diff --git a/apt.spec b/apt.spec new file mode 100644 index 0000000..befbd4c --- /dev/null +++ b/apt.spec @@ -0,0 +1,600 @@ +# hey Emacs, its -*- rpm-spec -*- +# $Id: apt,v 1.5 2002/03/13 19:01:26 ab Exp $ + +Name: apt +Version: 0.3.19cnc55 +Release: alt3 + +Summary: Debian's Advanced Packaging Tool with RPM support +Summary(ru_RU.CP1251): Debian APT - Усовершенствованное средство управления пакетами с поддержкой RPM +License: GPL +Group: System/Configuration/Packaging +Packager: APT Development Team + +Source0: %name-%version.tar.bz2 +Source1: %name.conf +Source2: rpmpriorities + +Patch1: %name-0.3.19cnc32-alt-distro.patch +Patch2: %name-0.3.19cnc55-alt-AllowedDupPkgs-HoldPkgs.patch +Patch3: %name-0.3.19cnc52-alt-INLINEDEPFLAG.patch +Patch4: %name-0.3.19cnc53-alt-configure-build.patch +Patch5: %name-0.3.19cnc53-alt-strsignal.patch +Patch6: %name-0.3.19cnc55-alt-genbasedir.patch +Patch7: %name-0.3.19cnc55-alt-apt-pkg-rpmpm-execute_rpm.patch +Patch8: %name-0.3.19cnc53-stelian-apt-pkg-algorithms-scores.patch +Patch9: %name-0.3.19cnc55-alt-enable-rsh-method.patch + +Requires: lib%name = %version-%release, mktemp >= 1:1.3.1, getopt +Requires: %{get_dep rpm}, gnupg, apt-conf + +BuildPreReq: librpm-devel >= 4.0.4, rpm-build >= 4.0.4 + +# Automatically added by buildreq on Tue Mar 26 2002 +BuildRequires: bison bzlib-devel gcc-c++ libbeecrypt libdb4 libpopt-devel librpm-devel libstdc++-devel openjade perl-SGMLSpm zlib-devel + +%description +A port of Debian's APT tools for RPM based distributions, +or at least for Conectiva. It provides the %name-get utility that +provides a simpler, safer way to install and upgrade packages. +APT features complete installation ordering, multiple source +capability and several other unique features. + +This package is still under development. + +%define risk_usage Данный пакет пока еще находится в стадии разработки. + +%description -l ru_RU.CP1251 +Перенесенные из Debian средства управления пакетами APT, включающие +в себя поддержку RPM, выполненную компанией Conectiva (Бразилия). +Этот пакет содержит утилиту %name-get для простой и надежной установки +и обновления пакетов. APT умеет автоматически разрешать зависимости +при установке, обеспечивает установку из нескольких источников и +целый ряд других уникальных возможностей. + +%risk_usage + +%package -n lib%name +Summary: APT's lib%name-pkg +Group: System/Libraries +Conflicts: %name < %version-%release + +%package -n lib%name-devel +Summary: Development files and documentation for APT's lib%name-pkg +Summary(ru_RU.CP1251): Файлы и документация для разработчиков, использующих lib%name-pkg +Group: Development/C +Requires: lib%name = %version-%release +Provides: %name-devel = %version +Obsoletes: %name-devel lib%name-pkg-devel lib%name-pkg-doc + +%package -n lib%name-devel-static +Summary: Development static library for APT's lib%name-pkg +Summary(ru_RU.CP1251): Статическая библиотека APT для разработчиков, использующих lib%name-pkg +Group: Development/C +Requires: lib%name-devel = %version-%release +Provides: %name-devel-static = %version +Obsoletes: %name-devel-static + +%description -n lib%name +This package contains APT's lib%name-pkg package manipulation library, +modified for RPM. + +This package is still under development. + +%description -n lib%name-devel +This package contains the header files and libraries for developing with +APT's lib%name-pkg package manipulation library, modified for RPM. + +This package is still under development. + +%description -n lib%name-devel-static +This package contains static libraries for developing with APT's +lib%name-pkg package manipulation library, modified for RPM. + +This package is still under development. + +%description -n lib%name -l ru_RU.CP1251 +В этом пакете находится lib%name-pkg -- библиотека управления пакетами +из комплекта APT. В отличие от оригинальной версии для Debian, этот +пакет содержит поддержку для формата RPM. + +%risk_usage + +%description -n lib%name-devel -l ru_RU.CP1251 +В этом пакете находятся заголовочные файлы и библиотеки для разработки +программ, использующих lib%name-pkg -- библиотеку управления пакетами +из комплекта APT. В отличие от оригинальной версии для Debian, этот +пакет содержит поддержку для формата RPM. + +%risk_usage + +%description -n lib%name-devel-static -l ru_RU.CP1251 +В этом пакете находятся статические библиотеки для разработки программ, +использующих lib%name-pkg -- библиотеку управления пакетами из +комплекта APT. В отличие от оригинальной версии для Debian, этот пакет +содержит поддержку для формата RPM. + +%risk_usage + +%prep +%setup -q +%patch1 -p1 +%patch2 -p1 +%patch3 -p1 +%patch4 -p1 +%patch5 -p1 +%patch6 -p1 +%patch7 -p1 +%patch8 -p1 +%patch9 -p1 + +#install -p -m644 %SOURCE3 po/ru.po + +%build +%add_optflags -fno-exceptions -D_GNU_SOURCE + +libtoolize --copy --force +aclocal -I buildlib +autoconf + +# BEGIN HACK: fix broken files. +%configure --with-proc-multiply=1 --with-procs=%__nprocs +for n in LOCALEDIR `sed -ne 's/.*}\(ENABLE\|HAVE\|NEED\)\(_[A-Z_0-9]*\)\$.*/\1\2/pg' config.status |LC_COLLATE=C sort -u`; do + %__grep -Fqs "$n" buildlib/config.h.in || echo "#undef $n" +done >config.h.add +cat config.h.add >>buildlib/config.h.in +# END HACK + +%configure --with-proc-multiply=1 --with-procs=%__nprocs + +find -type f -print0 | + xargs -r0 %__grep -EZl '/var(/lib)?/state/%name' | + xargs -r0 %__perl -pi -e 's,/var(/lib)?/state/%name,%_localstatedir/%name,g' +for f in `find -type f -name '*.[58]'`; do + [ -f "$f.yo" ] || touch -r "$f" "$f.yo" +done +%make clean + +%make_build STATICLIBS=1 NOISY=1 +tar xzf docs.tar.gz +bzip2 -9 docs/*.text + +%install +mkdir -p $RPM_BUILD_ROOT{%_bindir,%_libdir/%name,%_mandir/man{5,8},%_includedir/%name-pkg,%_sysconfdir/%name} +mkdir -p $RPM_BUILD_ROOT%_localstatedir/%name/lists/partial +mkdir -p $RPM_BUILD_ROOT/var/cache/%name/{archives/partial,genpkglist,gensrclist} + +cp -a bin/lib*.so* $RPM_BUILD_ROOT%_libdir +cp -a bin/lib*.a* $RPM_BUILD_ROOT%_libdir + +install -p -m755 bin/methods/* $RPM_BUILD_ROOT%_libdir/%name +install -p -m755 bin/{%name-*,*list} tools/genbasedir $RPM_BUILD_ROOT%_bindir + +install -p -m644 %name-pkg/{,*/}*.h $RPM_BUILD_ROOT%_includedir/%name-pkg + +install -p -m644 doc/*.5 $RPM_BUILD_ROOT%_man5dir/ +install -p -m644 doc/*.8 $RPM_BUILD_ROOT%_man8dir/ + +install -p -m644 %SOURCE1 %SOURCE2 $RPM_BUILD_ROOT%_sysconfdir/%name + +# Make possible SSH method via RSH one. +%__ln_s rsh $RPM_BUILD_ROOT%_libdir/%name/ssh + +%make_install install -C po DESTDIR=$RPM_BUILD_ROOT +%find_lang %name + +%post -n lib%name -p /sbin/ldconfig +%postun -n lib%name -p /sbin/ldconfig + +%files -f %name.lang +%_bindir/* +%_libdir/%name +%dir %_sysconfdir/%name +%config(noreplace) %_sysconfdir/%name/%name.conf +%config(noreplace) %_sysconfdir/%name/rpmpriorities +%_mandir/man?/* +%doc README* TODO docs/examples REPOSITORIO-APT-HOWTO + +%defattr(2770,root,rpm,2770) +%_localstatedir/%name +%_cachedir/%name + +%files -n lib%name +%_libdir/*.so.* + +%files -n lib%name-devel +%_libdir/*.so +%_includedir/* +%doc docs/*.{text.*,html} + +%files -n lib%name-devel-static +%_libdir/*.a + +%changelog +* Tue Mar 26 2002 Dmitry V. Levin 0.3.19cnc55-alt3 +- Added librpm-4.0.4 build support. +- Built with librpm-4.0.4, updated buildrequires. + +* Thu Mar 21 2002 Dmitry V. Levin 0.3.19cnc55-alt2 +- Added kernel-aureal and NVIDIA_kernel to default AllowedDupPkgs. +- Updated patch for pkgRPMPM::ExecRPM. +- Reenabled rsh method. +- Updated rpmpriorities. +- fixed genbasedir patch. +- Set explicit Packager tag. +- Dropped obsolete trigger. +- lib%name: Conflicts: %name < %%version-%%release. +- Renamed patches. + +* Wed Mar 13 2002 Alexander Bokovoy 0.3.19cnc55-alt1 +- apt-0.3.19cnc55 integrated +- Fixed: + + rpmpm-exec_rpm patch + + genbasedir +- Removed: + + rpmpm-nodeps patch (already upstream) + + rsh method (already upstream) + +* Mon Dec 10 2001 Dmitry V. Levin 0.3.19cnc53-alt6 +- Fixed rpm --nodeps option usage in pkgRPMPM::ExecRPM (#0000215). + +* Fri Nov 23 2001 Dmitry V. Levin 0.3.19cnc53-alt5 +- Applied scoring algorithm patch (Stelian Pop ) +- Updated package requires. + +* Mon Nov 19 2001 Dmitry V. Levin 0.3.19cnc53-alt4 +- Dropped outdated pofile (already upstream). +- Corrected "Executing RPM" message generation. + +* Fri Nov 16 2001 Dmitry V. Levin 0.3.19cnc53-alt3 +- Updated patches: genbasedir, configure-db3, i18n. + +* Wed Nov 15 2001 Alexander Bokovoy 0.3.19cnc53-alt2 ++ apt-0.3.19cnc53-2cl integrated. Most of our patches moved to upstream +- Fixed (from Conectiva's changelog): + + fixed bug in mirror patch + + cleaned up gen{pkg,src}list (Alexander Bokovoy ) + + * Skips correctly over empty package directories + + * Adds the --bz2only argument which makes genbasedir + + to generate only the .bz2 compressed versions of pkglist + + and srclist (space gain...) + + * Doesn't change the timestamps on pkglists/srclists if + + the contents are not modified (making possible for example + + to make several consecutive runs of genbasedir without + + having the apt clients download the indexes again and again). + + * Some minor cleanups (remove the temporary files in /tmp + + at the end of the script etc). + + (Stelian Pop ) + + cleanup patch for gensrclist (Stelian Pop ) + + fixed multi-arch pkg handling (Stelian Pop ) + + updated russian translation (Alexander Bokovoy + + updated i18n (Dmitry Levin ) + + replaced Apt::GPG::Pubring with Apt::GPG::PubringPath + also uses --homedir instead of --keyring in gpg + (Alexander Bokovoy ) + + patch to detect replaced (instead of just removed) packages + Dmitry Levin + + updated mirrors patch + + Fixed mirrors infinite loop bug (closes: #4420). + + Fixed error handling. +- Added: + + added kernel-tape to default AllowedDupPkgs + + added patch to fix bug in genbasedir with empty dirs + (Stelian Pop ) + + added -K (RPM::Check-Signatures) option to verify rpm sigs + + Added mirrors patch. + +* Fri Nov 02 2001 Dmitry V. Levin 0.3.19cnc52-alt6 +- Initial build with rpm4. + +* Thu Oct 04 2001 Dmitry V. Levin 0.3.19cnc52-alt5 +- Fixed i18n support and probably smth else + (configure.in, config.h.in and i18n.h were broken, kojima sux). +- Implemented 18n for apt-pkg/rpm, updated POTFILES.in and russian translation. + +* Mon Oct 01 2001 Dmitry V. Levin 0.3.19cnc52-alt4 +- Removed "^(kernel|alsa)[0-9]*-headers" from RPM::HoldPkgs list. +- Added (experimental) replaced packages support. + +* Fri Sep 07 2001 Ivan Zakharyaschev 0.3.19cnc52-alt3.1 +- apt-cdrom fix (patch 6) reworked: apt-cdrom used to not detect a second + list file (srclist) if both (pkglist and srclist) were present in one + directory on the disk (in non-thorough mode); hopefully now it works how + we expect it to do. + +* Thu Aug 09 2001 Dmitry V. Levin 0.3.19cnc52-alt3 +- Libification. +- Reworked compilation options again: we add only '-fno-exceptions' now. + +* Tue Aug 07 2001 Dmitry V. Levin 0.3.19cnc52-alt2 +- More code cleanup in tools/gen{pkg,src}list.cc. +- Added %%optflags_nocpp to compilation options. + +* Mon Aug 06 2001 Alexander Bokovoy 0.3.19cnc52-alt1 +- cnc52, gcc 3 and Solaris fixes +- RPM4 check is disabled for the moment +- File method fix has been integrated into mainstream +- RPM::RemoveOptions, RPM::UpdateOptions have been added +- Generation of Package list fixed + +* Thu Aug 02 2001 Dmitry V. Levin 0.3.19cnc51-alt4 +- Added trigger for better apt-conf-* migration. + +* Tue Jul 31 2001 Dmitry V. Levin 0.3.19cnc51-alt3 +- Updated: + + rpmpriorities, + + AllowedDupPkgs, + + HoldPkgs. +- Moved *.list to apt-conf-* packages. + +* Fri Jul 20 2001 Alexander Bokovoy 0.3.19cnc51-alt2 +- Fixed: + + Bug in file method which prevented authentication from working correctly + +* Fri Jul 20 2001 Alexander Bokovoy 0.3.19cnc51-alt1 +- cnc51 + +* Wed Jun 27 2001 Alexander Bokovoy 0.3.19cnc46-alt2 +- cnc46 +- kernel(|24)-{headers,source} added to HoldPkgs +- REPOSITORIO-APT-HOWTO added (Portugal) +- AllowedDupPackages -> AllowedDupPkgs + +* Thu Jun 07 2001 Dmitry V. Levin 0.3.19cnc38-alt4 +- Various fixes in %_bindir/genbasedir. + +* Thu May 17 2001 Dmitry V. Levin 0.3.19cnc38-alt3 +- Fixed build. +- Updated rpmpriorities. + +* Mon Apr 16 2001 Alexander Bokovoy 0.3.19cnc38-alt2 +- More duplicate packages from kernel series allowed. + +* Sun Apr 15 2001 Alexander Bokovoy 0.3.19cnc38-alt1 +- cnc38 +- Updated: + + apt-cdrom now works correctly + + default architecture has been changed to i586 + + ssh method as wrapper to rsh one + +* Mon Mar 19 2001 Alexander Bokovoy 0.3.19cnc37-ipl3mdk +- Updated: + + New patch for genbasedir to allow pass default key to GnuPG + +* Sun Mar 18 2001 Dmitry V. Levin 0.3.19cnc37-ipl2mdk +- Fixed: + + Build/installation of manpages without yodl sources; + + Uncompressed small patches. +- Updated: + + AllowedDupPackages list according to new kernel naming scheme; + + URLs to use new domain name. + +* Sat Mar 17 2001 Alexander Bokovoy 0.3.19cnc37-ipl1mdk +- Fixed: + + APT::GPG::Pubring renamed to APT::GPG::PubringPath + + Pubring support patch changed to use --homedir instead of --keyring +- Updated: + + APT cnc37 + + Fingerprint and repository sources changed to reflect ALT Linux + new public key ring + +* Mon Feb 19 2001 Alexander Bokovoy 0.3.19cnc36-ipl4mdk +- Sisyphus source repository added to sources.list + +* Mon Feb 19 2001 Alexander Bokovoy 0.3.19cnc36-ipl3mdk +- New version + +* Fri Feb 16 2001 Alexander Bokovoy 0.3.19cnc35-ipl2mdk +- Static library compilation added +- Static library goes to apt-devel-static due sizes of library + +* Thu Feb 15 2001 Alexander Bokovoy 0.3.19cnc35-ipl1mdk +- New version +- Rsh method from upstream apt-get ported +- Spec file follows libification of rpm now + +* Mon Jan 22 2001 Alexander Bokovoy 0.3.19cnc32-ipl4mdk +- New upstream version +- Russian translation updated +- Rebuild with new RPM library + +* Mon Jan 22 2001 Alexander Bokovoy 0.3.19cnc28-ipl1mdk +- New upstream version +- cnc28 still lacks correct GNUPG checking code, our patch is neccessary. +- Genbasedir slightly patched again. + +* Sun Jan 21 2001 Alexander Bokovoy ipl11mdk +- Typo in methods/gpg.cc fixed. + +* Sun Jan 21 2001 Alexander Bokovoy ipl10mdk +- APT::GPG::Pubring option to specify default gnupg public ring added to check + distributors' signs automatically via default pubring in RPM package +- ftp user password changed to IPL one. + +* Tue Jan 09 2001 Dmitry V. Levin 0.3.19cnc27-ipl7mdk +- Specfile cleanup. + +* Mon Jan 08 2001 Alexander Bokovoy ipl5mdk +- genbasedir help message fixed + +* Mon Jan 08 2001 Alexander Bokovoy ipl4mdk +- Integration with main IPL package: +- Russian translation for command line messages added +- Russian translation of package summary/description + +* Thu Jan 04 2001 AEN +- Real Sisyphus URL & IPLabs Fingerptint added +- changed rpmpriorities + +* Thu Jan 04 2001 AEN +- build for RE + +* Tue Dec 12 2000 Frederic Lepied 0.3.19cnc27-1mdk +- first mandrake version. + +* Thu Dec 07 2000 Andreas Hasenack +- damn! Wrong URL in sources.list, atualizacoes.conectiva.com + doesn't exist, of course... + +* Thu Dec 07 2000 Andreas Hasenack +- updated sources.list with new mirrors and new download tree +- removed (noreplace) for the sources.list file for this + upgrade. It will be easier for the user. The (noreplace) + should be back in place after this update as we expect no + further big modifications for that file, only new mirrors. + +* Wed Dec 06 2000 Alfredo K. Kojima +- fixed prob in vendors.list + +* Tue Dec 05 2000 Alfredo K. Kojima +- released version 0.3.19cnc27 + +* Wed Nov 08 2000 Alfredo K. Kojima +- released version 0.3.19cnc26 + +* Mon Nov 06 2000 Alfredo K. Kojima +- released version 0.3.19cnc25 + +* Thu Nov 02 2000 Alfredo K. Kojima +- released version 0.3.19cnc24 + +* Thu Nov 02 2000 Rud Moura +- updated source.list (again) + +* Thu Nov 02 2000 Rud Moura +- updated source.list + +* Wed Nov 01 2000 Alfredo K. Kojima +- released version 0.3.19cnc23 +- added cache directories for gen{pkg,src}list +- pt_BR manpages + +* Tue Oct 31 2000 Alfredo K. Kojima +- released version 0.3.19cnc22 +- Requires -> PreReq in apt-devel + +* Mon Oct 30 2000 Alfredo Kojima +- collapsed libapt-pkg-devel and -doc to apt-devel + +* Mon Oct 30 2000 Alfredo K. Kojima +- released version 0.3.19cnc21 + +* Sun Oct 29 2000 Alfredo K. Kojima +- released version 0.3.19cnc20 + +* Sun Oct 29 2000 Alfredo K. Kojima +- released version 0.3.19cnc19 +- added gensrclist +- support for apt-get source + +* Fri Oct 27 2000 Alfredo K. Kojima +- released version 0.3.19cnc18 + +* Thu Oct 26 2000 Alfredo K. Kojima +- released version 0.3.19cnc17 +- new manpages + +* Wed Oct 25 2000 Alfredo K. Kojima +- released version 0.3.19cnc16 + +* Sun Oct 22 2000 Alfredo K. Kojima +- released version 0.3.19cnc15 + +* Sat Oct 21 2000 Alfredo K. Kojima +- released version 0.3.19cnc14 + +* Thu Oct 19 2000 Claudio Matsuoka +- new upstream release: 0.3.9cnc13 + +* Tue Oct 17 2000 Eliphas Levy Theodoro +- added rpmpriorities to filelist and install + +* Tue Oct 17 2000 Claudio Matsuoka +- updated to 0.3.19cnc12 +- fresh CVS snapshot including: support to Acquire::ComprExtension, + debug messages removed, fixed apt-cdrom, RPM DB path, rpmlib call + in pkgRpmLock::Close(), package priority kludge removed, i18n + improvements, and genbasedir/genpkglist updates. +- handling language setting in genpkglist to make aptitude happy + +* Wed Oct 11 2000 Alfredo K. Kojima +- released version 0.3.19cnc11 +- fixed problem with shard lib symlinks + +* Tue Oct 10 2000 Alfredo K. Kojima +- released version 0.3.19cnc10 + +* Mon Oct 2 2000 Claudio Matsuoka +- fixed brown paper bag bug with method permissions +- added parameter --sign to genbasedir +- added html/text doc files + +* Sat Sep 30 2000 Claudio Matsuoka +- bumped to 0.3.19cnc9 +- added vendors.list +- added gpg method +- fixed minor stuff to make Aptitude work +- added missing manpages +- fixed shared libs +- split in apt, libapt-pkg, libapt-pkg-devel, libapt-pkg-doc +- rewrote genbasedir in shell script (original was in TCL) +- misc cosmetic changes + +* Tue Sep 26 2000 Alfredo K. Kojima +- released version 0.3.19cnc8 + +* Wed Sep 20 2000 Alfredo K. Kojima +- released version 0.3.19cnc7 + +* Mon Sep 18 2000 Alfredo K. Kojima +- released version 0.3.19cnc6 + +* Sat Sep 16 2000 Alfredo K. Kojima +- released version 0.3.19cnc5 + +* Fri Sep 15 2000 Alfredo K. Kojima +- released version 0.3.19cnc4 + +* Mon Sep 12 2000 Alfredo K. Kojima +- released version 0.3.19cnc3 + +* Mon Sep 5 2000 Alfredo K. Kojima +- renamed package to apt, with version 0.3.19cncV + +* Mon Sep 5 2000 Alfredo K. Kojima +- 0.10 +- added genpkglist and rapt-config +- program names changed back to apt-* + +* Mon Sep 4 2000 Alfredo K. Kojima +- 0.9 + +* Mon Sep 4 2000 Alfredo K. Kojima +- 0.8 + +* Mon Sep 4 2000 Alfredo K. Kojima +- 0.7 + +* Fri Sep 1 2000 Alfredo K. Kojima +- fixed typo in sources.list + +* Tue Aug 31 2000 Alfredo K. Kojima +- version 0.6 + +* Tue Aug 31 2000 Alfredo K. Kojima +- version 0.5 + +* Tue Aug 31 2000 Alfredo K. Kojima +- version 0.4 + +* Wed Aug 30 2000 Alfredo K. Kojima +- version 0.3 + +* Thu Aug 28 2000 Alfredo K. Kojima +- second try. new release with direct hdlist handling + +* Thu Aug 10 2000 Alfredo K. Kojima +- initial package creation. Yeah, it's totally broken for sure. + diff --git a/apt/AUTHORS b/apt/AUTHORS new file mode 100644 index 0000000..07cd919 --- /dev/null +++ b/apt/AUTHORS @@ -0,0 +1,28 @@ +The project hierachy stands at: + +CVS:jgg Jason Gunthorpe +- Project leader + +CVS:srivasta Manoj Srivastava +- Dependency Expert + +CVS:che Ben Gertzfield +- Packaging and Releases + +CVS:branden Branden Robinson +- Man Page Documentation + +CVS:doogie Adam Heath +- FTP method author + +Past Contributures: + +Brian White - Project originator +Tom Lees - DPKG documentation and ideas +Behan Webster - Original GUI design +Scott Ellis - Original packaging and beta releases +Many other bug reports through the Debian Bug system + +NOTE: The ChangeLog generator will parse for names and email addresses. The +'CVS:' tag should indicate who this pair refers to. + diff --git a/apt/AUTHORS.RPM b/apt/AUTHORS.RPM new file mode 100644 index 0000000..eb1c437 --- /dev/null +++ b/apt/AUTHORS.RPM @@ -0,0 +1,15 @@ + +RPM port brought to you by +Alfredo K. Kojima +with consulting help from: +Packaging: Ruda Moura +Security: Andreas Hasenack +Misc.: Claudio Matsuoka + + +added user specified public keyring option for gpg, fixed a bug +in the file method with authentication + Alexander Bokovoy + +solaris portability fixes + AUSTIN MURPHY diff --git a/apt/COMPILING b/apt/COMPILING new file mode 100644 index 0000000..7b12572 --- /dev/null +++ b/apt/COMPILING @@ -0,0 +1,71 @@ +General Information +~~~~~~~~~~~~~~~~~~~ +To compile this you need a couple things + - A working POSIX system with working POSIX gcc, g++, make (GNU), + ar, sh, awk and sed in the path + - GNU Make 3.74 or so, -- normal UNIX make will NOT work + * Note 3.77 is broken. + - A working ANSI C++ compiler, this is not g++ 2.7.* + g++ 2.8 works OK and newer egcs work well also. Nobody has tried it + on other compilers :< You will need a properly working STL as well. + - A C library with the usual POSIX functions and a BSD socket layer. + If you OS conforms to the Single User Spec then you are fine: + http://www.opengroup.org/onlinepubs/7908799/index.html + +Guidelines +~~~~~~~~~~ +I am not interested in making 'ultra portable code'. I will accept patches +to make the code that already exists conform more to SUS or POSIX, but +I don't really care if your not-SUS OS doesn't work. It is simply too +much work to maintain patches for dysfunctional OSs. I highly suggest you +contact your vendor and express intrest in a conforming C library. + +That said, there are lots of finniky problems that must be delt with even +between the supported OS's. Primarily the path I choose to take is to put +a shim header file in build/include that transparently adds the required +functionality. Patches to make autoconf detect these cases and generate the +required shims are OK. + +Current shims: + * C9x integer types 'inttypes.h' + * sys/statvfs.h to convert from BSD/Linux statfs to SUS statvfs + * rfc2553 hostname resolution (methods/rfc*), shims to normal gethostbyname. + The more adventerous could steal the KAME IPv6 enabled resolvers for those + OS's with IPv6 support but no rfc2553 (why?) + * define _XOPEN_EXTENDES_SOURCE to bring in h_errno on HP-UX + * socklen_t shim in netdb.h if the OS does not have socklen_t + +The only completely non-shimed OS is Linux with glibc2.1, glibc2.0 requires +the first three shims. + +Platform Notes +~~~~~~~~~~~~~~ +Debian GNU Linux 2.1 'slink' +Debian GNU Linux 'potato' + * All Archs + - Works flawlessly + - You will want to have debiandoc-sgml and yodl installed to get + best results. + - No IPv6 Support in glibc's < 2.1. + +Sun Solaris + SunOS cab101 5.7 Generic_106541-04 sun4u sparc + - Works fine + - Note, no IPv6 Support, OS lacks RFC 2553 hostname resolution + +OpenBSD + OpenBSD gsb086 2.5 CMPUT#0 i386 unknown + - Works fine + - OS needs 'ranlib' to generate the symbol table after 'ar'.. (not using + GNU ar with the gnu tool chain :<) + - Note, no IPv6 Support, OS lacks RFC 2553 hostname resolution + +HP-UX + HP-UX nyquist B.10.20 C 9000/780 2016574337 32-user license + - Evil OS, does not conform very well to SUS + 1) snprintf exists but is not prototyped, ignore spurios warnings + 2) No socklen_t + 3) Requires -D_XOPEN_SOURCE_EXTENDED for h_errno + configure should fix the last two (see above) + - Note, no IPv6 Support, OS lacks RFC 2553 hostname resolution + diff --git a/apt/COPYING b/apt/COPYING new file mode 100644 index 0000000..9e277e5 --- /dev/null +++ b/apt/COPYING @@ -0,0 +1,142 @@ +Apt is copyright 1997, 1998, 1999 Jason Gunthorpe and others. + +Apt is licened under the terms of the GNU General Public License (GPL), +version 2.0 or later, as published by the Free Software Foundation. See +the file COPYING.GPL [included], /usr/share/common-licenses/GPL, or + for the terms of the latest version +of the GNU General Public License. + +In addition, prior to November 15th, 2000, apt may be distributed under +terms identical to the above with the following addition: + +Works using apt may link against the GUI library "libqt", copyright by +Troll Tech AS, Norway, provided that: + +1. The version of "libqt" is licensed under the terms of the "Qt Free Edition + License" published by Troll Tech AS. The license terms identified as + the Qt Free Edition License below are the only such terms under which + distribution of works derived from both apt and "libqt" are permitted; + +and + +2. The source code of the version of "libqt" used is + + a) Distributed with the binary version; + + or + + b) Downloadable by anyone, without fee, using a publicly-announced + URL on the Internet, for a duration of at least three years + starting with distribution of the binary version. + +On and after November 15th, 2000, the above additional terms lose all +force, and apt will be licensed only under the terms of the GNU General +Public License, version 2.0 or later. + + _______________________________________________________________ + +The following text, up to the text of the Qt Free Edition License, is +informational and not part of the license terms on apt. + +Modifications to apt in either source or compiled form must be licensed +under the terms of the GNU General Public License, version 2.0 (or later), +but need not include the above clause permitting usage of the "libqt" +library under the Qt Free Edition License. Note that removal of this +clause will result in software which is not licensed for binary +redistribution linked against software governed by the Qt Free Edition +License. In the event that a version of "libqt" is released that is +licensed under terms that do not conflict with the GPL, the additional +clause above is not required to grant permission for distribution of works +that are derived from both apt and "libqt". + +No part of apt is licensed under the Qt Free Edition License. The terms +below are provided to help identify the circumstances under which the +"libqt" library may be used with apt (or a work derived from both). The +terms below are copied from the LICENSE file of the qt-1.44 distribution, +as of November 10th, 1999. + + _______________________________________________________________ + + QT FREE EDITION LICENSE + +Copyright (C) 1992-1999 Troll Tech AS. All rights reserved. + +This is the license for Qt Free Edition version 1.44; it covers private use, +use of third-party application programs based on Qt, and development of +free software for the free software community. + + + COPYRIGHT AND RESTRICTIONS + +The Qt toolkit is a product of Troll Tech AS. The Qt Free Edition is limited +to use with the X Window System. + +You may copy this version of the Qt Free Edition provided that the entire +archive is distributed unchanged and as a whole, including this notice. + +You may use this version of the Qt Free Edition to compile, link and run +application programs legally developed by third parties. + +You may use the Qt Free Edition to create application programs +provided that: + + You accept this license. + Your software does not require modifications to Qt Free Edition. + You satisfy ONE of the following three requirements + EITHER + Users of your software can freely obtain source code for the + software, freely modify the source code (possibly with + restrictions on copyright notices, attributions and legal + responsibility), and freely redistribute original or modified + versions of the software. + OR + Your software is distributed under the GNU GENERAL + PUBLIC LICENSE, version 2 or later, as defined by the + Free Software Foundation. + OR + Your software is distributed under the GNU LIBRARY + GENERAL PUBLIC LICENSE, version 2 or later, as + defined by the Free Software Foundation. + +If you are paid to develop something with Qt Free Edition or it is a part of +your job the following conditions also apply: + + Your software must not require libraries, programs, data or + documentation that are not available outside your organization in + order to compile or use. + If and when your organization starts using the software, you must + notify Troll Tech AS of the following: + Your organization's name and purpose. + The software's name and purpose. + The software's license. + That your organization considers the software to be free + software. + +You may also use the Qt Free Edition to create reusable components +(such as libraries) provided that you accept the terms above, and in +addition that: + + Your components' license includes the following text: + + [Your package] requires the Qt library, which is + copyright Troll Tech AS. Freely distributable + programs may generally use Qt Free Edition free of + charge, see [README.QT] for details. + + README.QT is distributed along with your components. + Qt Free Edition is not distributed as an integral part of your + components. + + LIMITATIONS OF LIABILITY + +Troll Tech AS makes no obligation under this license to support or +upgrade Qt Free Edition, or assist in the use of Qt Free Edition. + +In no event shall Troll Tech AS be liable for any lost revenue or profits or +other direct, indirect, special, incidental or consequential damages, even +if Troll Tech has been advised of the possibility of such damages. + +QT FREE EDITION IS PROVIDED AS IS WITH NO WARRANTY OF ANY KIND, +INCLUDING THE WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE. + _______________________________________________________________ diff --git a/apt/COPYING.GPL b/apt/COPYING.GPL new file mode 100644 index 0000000..60549be --- /dev/null +++ b/apt/COPYING.GPL @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) 19yy + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) 19yy name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/apt/CVS/Entries b/apt/CVS/Entries new file mode 100644 index 0000000..e3bed12 --- /dev/null +++ b/apt/CVS/Entries @@ -0,0 +1,30 @@ +/AUTHORS.RPM/1.4/Wed Aug 1 21:35:12 2001// +/Makefile/1.4/Wed Aug 1 22:05:11 2001// +D/apt-pkg//// +D/buildlib//// +D/cmdline//// +D/debian//// +D/deity//// +D/doc//// +D/dselect//// +D/gui//// +D/intl//// +D/methods//// +D/po//// +D/test//// +D/tools//// +/AUTHORS/1.1.1.1/Fri Aug 10 13:57:00 2001// +/COMPILING/1.1.1.1/Fri Aug 10 13:57:00 2001// +/COPYING/1.1.1.1/Fri Aug 10 13:57:01 2001// +/COPYING.GPL/1.1.1.1/Fri Aug 10 13:57:02 2001// +/ChangeLog/1.2/Fri Aug 10 13:57:23 2001// +/README.RPM/1.12/Fri Aug 10 13:57:23 2001// +/README.make/1.1.1.1/Fri Aug 10 13:57:24 2001// +/REPOSITORIO-APT-HOWTO/1.2/Fri Aug 10 13:57:24 2001// +/TODO/1.2/Fri Aug 10 13:57:24 2001// +/apt.dia/1.3/Fri Aug 10 13:57:26 2001// +/docs.tar.gz/1.1/Fri Aug 10 13:58:18 2001// +/mkinstalldirs/1.1/Fri Aug 10 13:58:18 2001// +/rpmpriorities/1.2/Fri Aug 10 13:58:19 2001// +/configure.in/1.75/Wed Mar 6 17:17:10 2002// +/release/1.73/Wed Mar 6 17:17:10 2002// diff --git a/apt/CVS/Repository b/apt/CVS/Repository new file mode 100644 index 0000000..935fcea --- /dev/null +++ b/apt/CVS/Repository @@ -0,0 +1 @@ +rapt diff --git a/apt/CVS/Root b/apt/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/ChangeLog b/apt/ChangeLog new file mode 100644 index 0000000..402e058 --- /dev/null +++ b/apt/ChangeLog @@ -0,0 +1,1780 @@ +2002-01-14 18:53 kojima + + * release, apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmversion.cc: fixed + bug in order of rpm --nodeps + +2001-12-12 16:50 kojima + + * tools/: genbasedir, gensrclist.cc: fixed genbasedir for --flat + and relative --topdir specifications fixed --flat in gensrclist + +2001-12-11 22:50 kojima + + * configure.in, release, apt-pkg/pkgcachegen.cc, + apt-pkg/rpm/rpmlistparser.cc: minor fixes release cnc55 + +2001-12-11 15:51 kojima + + * tools/gensrclist.cc: added --flat option to srclist, patched + gensrclist with stelian's patch + +2001-11-30 22:40 kojima + + * tools/: genbasedir, genpkglist.cc: patched --progress stuff from + stelian + +2001-11-30 22:34 kojima + + * configure.in, release, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmlistparser.h, apt-pkg/rpm/rpmpm.cc, methods/rsh.cc, + methods/rsh.h: added RPM::IgnorePkgs kluge + +2001-11-13 22:33 kojima + + * deity/: anchor.cc, anchor.h, basic.cc, basic.h, button.cc, + button.h, columnbar.cc, columnbar.h, event.cc, event.h, gpmdev.cc, + gpmdev.h, graphics.cc, graphics.h, makefile, menubar.cc, menubar.h, + notify.cc, notify.h, progress.cc, progress.h, selectloop.cc, + selectloop.h, slangdev.cc, slangdev.h, tabdialog.cc, tabdialog.h, + textwidg.cc, textwidg.h, tree.cc, tree.h, utils.cc, utils.h, + widget-thread.cc, widget-thread.h, widget.cc, widget.h, + widgetinit.cc, widgetinit.h, window.cc, window.h, x11dev.cc, + x11dev.h, x11xpm.cc, xpm.cc, xpm.h: removed junk + +2001-11-13 20:00 kojima + + * cmdline/apt-get.cc: removed stale code + +2001-11-13 19:32 kojima + + * configure.in, release, apt-pkg/algorithms.cc, + apt-pkg/depcache.cc, apt-pkg/depcache.h, apt-pkg/packagemanager.cc, + apt-pkg/contrib/i18n.h, apt-pkg/contrib/progress.cc, + apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpminit.cc, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmpackagedata.cc, + apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmsrcrecords.cc, + cmdline/apt-cdrom.cc, cmdline/apt-get.cc, methods/gpg.cc, + po/POTFILES.in, po/ru.po, tools/cached_md5.cc: Patches from Dmitry + Levin apt-0.3.19cnc52-configure.patch -- patch + for configure to add Russian + translation and better support of + RPM4's db3 usage. apt-0.3.19cnc52-i18n.patch -- i18n patch. + All APT messages now can be + localized. apt-0.3.19cnc52-replace-support.patch + -- support for Replace option. It is + better detection whether package is truly + removed or is going to be replaced by + package with different name. Patch from + Ivan Zakharyashev: apt-cdrom.newfix_imz.patch -- Fixes + apt-cdrom to better manage + repository search when CD has both RPMS + and SRPMS. Alexander Bokovoy : + apt-gpg-pubring.patch -- uses --homedir instead of + --keyring option to GPG. It is + generally better because you + also can specify GPG options in + ${Apt::GPG::PubringPath}/options + apt-ru.po -- updated Russian translation for + APT (Dmitry Levin and me). + +2001-11-12 18:34 kojima + + * apt-pkg/: acquire-item.cc, acquire-item.h, sourcelist.cc, + sourcelist.h: cleanup half-way mirror support + +2001-11-12 18:04 kojima + + * configure.in, release, apt-pkg/acquire-item.cc, + apt-pkg/acquire-item.h, apt-pkg/pkgcachegen.cc, + apt-pkg/sourcelist.cc, apt-pkg/sourcelist.h, + apt-pkg/contrib/error.cc, apt-pkg/rpm/rpmpm.cc, + apt-pkg/rpm/rpmpm.h, buildlib/archtable, cmdline/apt-get.cc, + methods/connect.cc, po/pt_BR.po, tools/Makefile: added -K option, + new release (cnc53) + +2001-11-09 23:14 kojima + + * configure.in: * Enables configure to autodetect the + presence of + rpmdb library, enabling apt to build correctly + on RedHat 7.2 as well as oldest versions. + +2001-11-09 23:13 kojima + + * tools/genbasedir: * Skips correctly over empty package + directories + + * Adds the --bz2only argument which makes genbasedir + to generate only the .bz2 compressed versions of pkglist + and srclist (space gain...) + + * Doesn't change the timestamps on pkglists/srclists if + the contents are not modified (making possible for example + to make several consecutive runs of genbasedir without + having the apt clients download the indexes again and + again). + + * Some minor cleanups (remove the temporary files in /tmp + at the end of the script etc). + +2001-11-09 23:13 kojima + + * tools/genpkglist.cc: * Corrects the use of 'scandir' and + makes genpkglist behave + correctly when it finds empty RPMS directories (instead of + dumping core). + + * Better package progression indicator. + +2001-11-09 23:11 kojima + + * tools/gensrclist.cc: * Use 'scandir' for directory traversal + (instead of opendir/ readdir) like in genpkglist. * Better + package progression indicator. + +2001-08-07 23:46 kojima + + * tools/: Makefile, cached_md5.cc, cached_md5.h, genpkglist.cc, + gensrclist.cc: Alexander Bokovoy 's + patch for cleaning up genpkglist + +2001-08-02 19:28 kojima + + * configure.in: [no log message] + +2001-08-02 17:38 kojima + + * configure.in: [no log message] + +2001-08-02 17:30 kojima + + * configure.in, buildlib/configure.mak: various make fixes + +2001-08-02 17:15 kojima + + * buildlib/fail.mak: [no log message] + +2001-08-02 01:11 kojima + + * configure.in: readded po dir + +2001-08-02 01:05 kojima + + * Makefile: readded tools dir + +2001-08-02 00:57 kojima + + * release, apt-pkg/rpm/rpmpm.cc, cmdline/apt-cache.cc, + cmdline/apt-cdrom.cc, cmdline/apt-config.cc, cmdline/apt-get.cc: + fixed tipoes + +2001-08-02 00:38 kojima + + * aclocal.m4: removed stale file + +2001-08-02 00:35 kojima + + * AUTHORS.RPM, Makefile, acinclude.m4, aclocal.m4, configure.in, + apt-pkg/init.cc, apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpminit.cc, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmpm.cc, + apt-pkg/rpm/rpmrecords.cc, methods/file.cc: misc changes bug fix in + file method with auth start using 0.5 build system + +2001-08-02 00:31 kojima + + * buildlib/: config.guess, config.h.in, config.sub, copy.mak, + debiandoc.mak, defaults.mak, environment.mak.in, library.mak, + makefile.in, manpage.mak, mkChangeLog, ostable, program.mak, + sizetable, staticlibrary.mak, tools.m4: added ostable updated to + 0.5 buildsystem + +2001-07-13 00:47 kojima + + * configure.in, release, apt-pkg/cachefile.cc, apt-pkg/cachefile.h, + apt-pkg/depcache.cc, apt-pkg/pkgcachegen.cc, + apt-pkg/systemfactory.cc, apt-pkg/contrib/error.cc, + apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpminit.cc, + apt-pkg/rpm/rpmpackagedata.cc, apt-pkg/rpm/rpmpm.cc, + cmdline/apt-cache.cc, cmdline/apt-get.cc, methods/gpg.cc, + po/pt_BR.po, tools/genpkglist.cc, tools/gensrclist.cc, + tools/hdlist2pkglist.cc: ignore duplicated version/diff deps + packages new release (cnc51) + +2001-06-29 09:49 kojima + + * configure.in, release, cmdline/apt-cdrom.cc: fixed bug in + apt-cdrom detection of srclists + +2001-06-27 23:47 kojima + + * configure.in, release: new release + +2001-06-27 23:37 kojima + + * apt-pkg/rpm/: rpminit.cc, rpmpm.cc, rpmpm.h: added --nodeps when + isntalling packages + +2001-06-26 06:51 kojima + + * apt-pkg/: init.cc, rpm/rpmpackagedata.cc: added config option + Dir::Etc::RpmPriorities + +2001-06-26 01:35 kojima + + * configure.in, release, apt-pkg/rpm/rpmpm.cc: added + RPM::AutoRebuildDB + +2001-06-25 19:16 kojima + + * apt-pkg/pkgcache.cc, apt-pkg/rpm/rpminit.cc, cmdline/apt-get.cc, + methods/cdrom.cc: added some misc enhancements + +2001-06-22 21:21 kojima + + * configure.in, release, apt-pkg/rpm/rpmlistparser.cc, + cmdline/apt-get.cc: removed debug msg fixed HoldPkgs + +2001-06-19 21:08 kojima + + * configure.in, release: new release + +2001-06-19 18:19 kojima + + * apt-pkg/rpm/rpminit.cc: iterate over Packages instead of Names to + figure package coutn + +2001-06-18 23:52 kojima + + * apt-pkg/rpm/rpmfactory.cc: fixed arch selection + +2001-06-16 04:59 kojima + + * apt-pkg/acquire-item.cc: added a delay before file fetch retry + +2001-06-16 04:51 kojima + + * release, cmdline/apt-get.cc, methods/cdrom.cc: added + acquire::cdrom::copy which will copy all files from all cds before + installing + +2001-06-16 04:50 kojima + + * apt-pkg/: acquire-item.cc, acquire-method.cc, acquire.cc, + packagemanager.cc: fixed typos + +2001-06-14 01:29 kojima + + * configure.in, apt-pkg/sourcelist.cc, apt-pkg/rpm/rpmfactory.cc, + apt-pkg/rpm/rpminit.cc, cmdline/apt-cdrom.cc: fixed cache update + progress info + +2001-06-11 20:57 kojima + + * configure.in, release, apt-pkg/init.cc, tools/Makefile: [no log + message] + +2001-06-11 20:56 kojima + + * apt-pkg/rpm/: rpmlistparser.cc, rpmlistparser.h: added holdpkgs + and renamed allowedduppackages -> allowedduppkgs + +2001-06-05 20:14 kojima + + * release, apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmrecords.h, + cmdline/apt-get.cc: added rpm::post-invoke-pkgs + +2001-06-05 15:26 kojima + + * tools/genpkglist.cc: added fileflags tag to pkglist + +2001-05-21 18:01 kojima + + * apt-pkg/rpm/rpminit.cc: consertado: mrbrocoli: Parece + que o apt estб dando core-dump quando executando "apt-get install + blah" como usuбrio normal. Nгo sei se vais ter tempo de ver isso ou + se mando pro bugzilla... + +2001-05-18 20:55 kojima + + * configure.in: new release + +2001-05-18 20:55 kojima + + * apt-pkg/rpm/rpmsrcrecords.cc: fixed apt-get source crash bug + +2001-05-18 20:38 kojima + + * apt-pkg/rpm/rpminit.cc: fixed bug with record offset tracking in + rpm4 + +2001-05-18 03:45 kojima + + * apt-pkg/: acquire-item.cc, acquire-item.h: added Acquire::Retries + to pkglist and hashfile retrieval + +2001-05-18 01:28 kojima + + * release, cmdline/makefile: [no log message] + +2001-05-18 01:22 kojima + + * configure.in: [no log message] + +2001-05-18 01:22 kojima + + * apt-pkg/rpm/rpminit.cc, cmdline/makefile: fixed dumb errors.. + +2001-05-18 01:18 kojima + + * release, apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpminit.cc, + apt-pkg/rpm/rpminit.h, apt-pkg/rpm/rpmlistparser.cc, + buildlib/archtable, cmdline/apt-cache.cc, cmdline/apt-get.cc, + cmdline/makefile: merged patches for ia64, some code cleanup on + rpminit (niemeyer) and cosmetic line-break stuff (vanyaz) + +2001-03-29 23:19 kojima + + * apt-pkg/rpm/: rpminit.cc, rpmpm.cc: rpmdbrebuild fixes + +2001-03-29 23:19 kojima + + * configure.in: new release + +2001-03-29 22:11 kojima + + * apt-pkg/rpm/rpmpm.cc: rpmrebuild on rpm upgrade + +2001-03-28 00:18 kojima + + * configure.in: new release + +2001-03-28 00:18 kojima + + * apt-pkg/: depcache.cc, makefile, packagemanager.cc, + pkgcachegen.cc, contrib/sptr.h: started backport of (commented out) + new MarkInstall from 0.5 custom, stripped down OrderInstall() + +2001-03-23 20:25 kojima + + * apt-pkg/rpm/: rpmfactory.cc, rpmrecords.cc: extra headers for rpm + stuff + +2001-03-23 18:52 kojima + + * configure.in: new release + +2001-03-23 18:47 kojima + + * apt-pkg/rpm/: rpmfactory.cc, rpmrecords.cc: fixed bug with rpm4 + +2001-03-22 14:11 kojima + + * apt-pkg/algorithms.cc: uncommented previous fix on dep resolver + :P + +2001-03-22 14:03 kojima + + * configure.in: new release (38) + +2001-03-22 14:01 kojima + + * AUTHORS.RPM, configure.in, rpmpriorities, apt-pkg/depcache.cc, + apt-pkg/packagemanager.cc, apt-pkg/pkgcachegen.cc, + apt-pkg/sourcelist.h, cmdline/apt-cache.cc, cmdline/apt-get.cc, + methods/gpg.cc, methods/gzip.cc, methods/makefile, po/it_IT.po, + po/pt_BR.po: italian potfile many fixes + +2001-03-22 14:00 kojima + + * apt-pkg/algorithms.cc: fixed upstream bug on dep resolution + +2001-03-11 16:36 claudio + + * tools/genbasedir: Added appropriate message at the end of script. + +2001-02-20 20:20 kojima + + * configure.in, release, methods/ftp.cc, methods/http.cc: fixed + bugs in no_proxy handling + +2001-02-17 21:36 kojima + + * configure.in, release, apt-pkg/acquire-item.cc, + apt-pkg/cachefile.cc, apt-pkg/cachefile.h, + apt-pkg/packagemanager.cc, apt-pkg/pkgcache.cc, + apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpminit.cc, + apt-pkg/rpm/rpminit.h, apt-pkg/rpm/rpmlistparser.cc: fixed arch + selection code. really. this time it works. I SWEAR IT DOES!!! + +2001-02-15 00:42 kojima + + * configure.in: new release + +2001-02-15 00:41 kojima + + * apt-pkg/: pkgcache.cc, rpm/rpmlistparser.cc: fixed problem with + package name case sensitiveness + +2001-02-14 21:59 kojima + + * configure.in, release, apt-pkg/rpm/rpminit.cc: [no log message] + +2001-02-14 21:51 kojima + + * release, apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmpm.cc, cmdline/apt-get.cc: [no log message] + +2001-01-25 01:07 kojima + + * configure.in: new release + +2001-01-25 01:07 kojima + + * apt-pkg/rpm/: rpmpm.cc, rpmpm.h: added hooks for GUI + +2001-01-24 20:42 kojima + + * configure.in, release, apt-pkg/rpm/rpmfactory.cc, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmrecords.cc, + cmdline/apt-get.cc: fixed prob with rpm4 + +2001-01-19 19:32 kojima + + * apt-pkg/: makefile, rpm/rpmlistparser.cc, rpm/rpmpackagedata.h: + fixed bug with section/priority in packages + +2001-01-19 17:23 kojima + + * po/pt_BR.po: [no log message] + +2001-01-18 02:36 kojima + + * apt-pkg/rpm/: rpmfactory.cc, rpmlistparser.cc: fixed arch + selection bug + +2001-01-16 21:28 kojima + + * configure.in, release, po/es_ES.po, po/pt_BR.po: updated potfiles + new release + +2001-01-16 01:58 kojima + + * apt-pkg/: depcache.cc, rpm/rpmversion.cc: fixed bug upgrading + packages and missing reverse dependency upgrades + +2001-01-15 20:14 kojima + + * configure.in, release, apt-pkg/rpm/rpminit.h: new release + +2001-01-15 17:29 kojima + + * po/: es_ES.po, pt_BR.po: new potfiles + +2001-01-13 19:05 kojima + + * release, apt-pkg/cachefile.cc, apt-pkg/rpm/rpminit.cc, + apt-pkg/rpm/rpminit.h, cmdline/apt-cache.cc: fixed a few bugs + +2001-01-13 04:17 kojima + + * configure.in: new release + +2001-01-13 03:50 kojima + + * apt-pkg/: packagemanager.cc, rpm/rpmlistparser.cc, + rpm/rpmlistparser.h, rpm/rpmrecords.cc: fixed early remove bug with + vim-enhanced prob + +2001-01-11 04:03 kojima + + * release, apt-pkg/acquire-item.cc, apt-pkg/acquire-worker.cc, + apt-pkg/acquire.cc, apt-pkg/cachefile.cc, apt-pkg/clean.cc, + apt-pkg/depcache.cc, apt-pkg/packagemanager.cc, + apt-pkg/pkgcache.cc, apt-pkg/pkgcachegen.cc, apt-pkg/pkgrecords.cc, + apt-pkg/sourcelist.cc, apt-pkg/srcrecords.cc, + apt-pkg/systemfactory.cc, apt-pkg/tagfile.cc, + apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmlistparser.h, apt-pkg/rpm/rpmrecords.cc, + po/POTFILES.in, po/apt.pot, po/cat-id-tbl.c, po/es_ES.po, + po/pt_BR.po: fixed several bugs + +2001-01-04 23:26 kojima + + * AUTHORS.RPM, configure.in, release, apt-pkg/acquire-item.cc, + apt-pkg/acquire-method.cc, apt-pkg/sourcelist.h, + apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmrecords.cc, + apt-pkg/rpm/rpmsrcrecords.cc, buildlib/config.guess, + cmdline/apt-cdrom.cc, cmdline/apt-get.cc, doc/apt-cache.8, + doc/apt.conf.5, doc/sources.list.5, doc/vendors.list.5, + doc/examples/configure-index, methods/gpg.cc, tools/genbasedir, + tools/genpkglist.cc: fixed some mem leaks + +2001-01-02 16:08 kojima + + * apt-pkg/rpm/rpmrecords.cc: fixed mem leaks + +2000-12-10 15:42 claudio + + * tools/genbasedir: Added linefeeds to usage message, replaced + spaces for tabs + +2000-12-05 22:51 kojima + + * release, apt-pkg/acquire-item.cc, apt-pkg/acquire-item.h, + apt-pkg/sourcelist.cc: finished md5 verificatoin of already + downloaded files + +2000-12-05 18:40 kojima + + * apt-pkg/rpm/rpmlistparser.cc: fixed stupid bug in arch handling + +2000-12-05 06:28 kojima + + * apt-pkg/: pkgcachegen.cc, rpm/rpmlistparser.cc: removed some + debug msgs + +2000-12-05 06:17 kojima + + * apt-pkg/rpm/rpmfactory.cc: fixed bug in arch selection + +2000-12-05 06:07 kojima + + * apt-pkg/rpm/rpmfactory.cc: temp bla + +2000-12-05 05:56 kojima + + * apt-pkg/rpm/rpmlistparser.cc: fixed bug in rpmlistparser, wrt + arch selection + +2000-12-05 05:30 kojima + + * apt-pkg/: init.cc, pkgcachegen.cc, systemfactory.h, + rpm/rpmfactory.cc, rpm/rpmfactory.h, rpm/rpmlistparser.cc, + rpm/rpmlistparser.h: remade multi-arch support + +2000-12-04 22:16 kojima + + * apt-pkg/pkgcachegen.cc: tmp test stuff for arch + +2000-12-04 21:15 kojima + + * configure.in, release, apt-pkg/acquire-item.cc, apt-pkg/init.cc, + apt-pkg/pkgcachegen.cc, apt-pkg/rpm/rpmfactory.cc, + apt-pkg/rpm/rpmfactory.h, apt-pkg/rpm/rpmlistparser.cc, + cmdline/apt-get.cc: added some architecture handling stuffs + +2000-12-02 20:44 kojima + + * apt-pkg/rpm/rpmlistparser.cc: fixed stupid little bug + +2000-12-02 20:02 kojima + + * apt-pkg/: acquire-item.cc, packagemanager.cc, pkgcachegen.cc, + pkgcachegen.h, systemfactory.h, rpm/rpmfactory.cc, + rpm/rpmfactory.h, rpm/rpmlistparser.cc, rpm/rpmlistparser.h, + rpm/rpmpm.cc: added better multi-architecture support + +2000-12-02 17:48 kojima + + * apt-pkg/rpm/rpmlistparser.cc: merged PreReq and Req into Depends + +2000-12-01 00:12 kojima + + * apt-pkg/rpm/rpmfactory.cc: fixed crash with apt-get source when + srclist is undownloaded + +2000-11-30 20:31 kojima + + * tools/genpkglist.cc: removed kluges in filelist stripper and + added a --bloat flag + +2000-11-29 22:27 kojima + + * apt-pkg/rpm/rpmlistparser.cc: made all packages that are + installed ignore the architecture check + +2000-11-29 22:13 kojima + + * tools/genpkglist.cc: added lib to filelist + +2000-11-29 21:48 kojima + + * tools/genpkglist.cc: include /etc files in list of files in + pkglist + +2000-11-28 00:02 kojima + + * apt-pkg/rpm/rpmlistparser.cc: fixed more rpm4 incompats + +2000-11-27 23:00 kojima + + * apt-pkg/rpm/: rpminit.cc, rpmlistparser.cc: added handling of + rpmlib(blal) style requires + +2000-11-27 22:23 kojima + + * apt-pkg/rpm/rpminit.cc: fixed some more rpm4 compat stuff + +2000-11-27 20:39 kojima + + * apt-pkg/rpm/: rpmfactory.cc, rpminit.cc, rpmrecords.cc: some new + rpm4 compat changes + +2000-11-27 20:01 kojima + + * doc/pt_BR/: apt-cache.8, apt-cdrom.8, apt-config.8, apt-get.8, + apt.8, apt.conf.5, sources.list.5, vendors.list.5: added portuguese + transl. of docs + +2000-11-08 23:30 kojima + + * configure.in, release, apt-pkg/sourcelist.cc, tools/genbasedir: + fixed bug in release retrieval code + +2000-11-08 22:40 kojima + + * tools/genbasedir: fixed compat prob with bash1 + +2000-11-08 21:09 kojima + + * apt-pkg/rpm/: rpminit.cc, rpminit.h: fixed bug with rpm4 support + +2000-11-08 20:25 kojima + + * TODO, configure.in, apt-pkg/rpm/rpminit.h, buildlib/config.h.in, + buildlib/environment.mak.in, cmdline/makefile, methods/makefile, + po/pt_BR.po, tools/Makefile: support for rpm4 + +2000-11-08 19:52 kojima + + * apt-pkg/rpm/rpminit.cc: added support for rpm4 + +2000-11-06 18:36 kojima + + * README.RPM: updated docs to point at HOWTO + +2000-11-06 14:53 kojima + + * configure.in, release, apt-pkg/acquire.h, apt-pkg/algorithms.cc, + apt-pkg/pkgcachegen.h, apt-pkg/systemfactory.cc, + apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmsrcrecords.cc, + cmdline/apt-cache.cc, cmdline/apt-cdrom.cc, cmdline/apt-get.cc, + cmdline/rpmindexcopy.cc, tools/genbasedir, tools/genpkglist.cc, + tools/gensrclist.cc, tools/hdlist2pkglist.cc: fixed compile errors + for RedHat 6.x (with gcc -Wall -Werror) + +2000-11-02 23:04 kojima + + * apt-pkg/: sourcelist.cc, rpm/rpmlistparser.cc: fixed bug in + vendor authentication + +2000-11-02 03:44 kojima + + * po/pt_BR.po: fixed trans + +2000-11-02 00:38 kojima + + * apt-pkg/init.cc: [no log message] + +2000-11-02 00:29 kojima + + * doc/: apt-cache.8.pt_BR, apt-cdrom.8.pt_BR, apt-config.8.pt_BR, + apt-get.8.pt_BR, apt.8.pt_BR, apt.conf.5.pt_BR, makefile, + sources.list.5.pt_BR, vendors.list.5.pt_BR: fixed manpage dir struc + +2000-11-01 23:54 kojima + + * configure.in, release, doc/makefile: fixed manpage makefile + +2000-11-01 23:32 kojima + + * doc/apt-cache.8, doc/apt-cache.8.pt_BR, doc/apt-cdrom.8.pt_BR, + doc/apt-config.8.pt_BR, doc/apt-get.8, doc/apt-get.8.pt_BR, + doc/apt.8.pt_BR, doc/apt.conf.5.pt_BR, doc/sources.list.5.pt_BR, + doc/vendors.list.5.pt_BR, tools/genpkglist.cc, tools/gensrclist.cc: + added manpage + +2000-11-01 20:27 kojima + + * tools/: Makefile, genpkglist.cc, gensrclist.cc, + hdlist2pkglist.cc: added md5 caching to pkglist generators + +2000-10-31 22:30 kojima + + * configure.in, release, apt-pkg/init.cc, cmdline/apt-get.cc, + doc/apt-cache.8, methods/ftp.cc, methods/http.cc, tools/Makefile, + tools/genbasedir, tools/genpkglist.cc: some updates + +2000-10-30 20:49 kojima + + * apt-pkg/sourcelist.cc, apt-pkg/contrib/configuration.cc, + apt-pkg/contrib/configuration.h, apt-pkg/contrib/strutl.cc, + apt-pkg/contrib/strutl.h, doc/sources.list.5, doc/vendors.list.5, + doc/examples/vendors.list: new vendor.list format and parser, from + Jason + +2000-10-30 18:41 kojima + + * tools/genbasedir: fixed genbasedir + +2000-10-30 04:17 kojima + + * configure.in, release, apt-pkg/sourcelist.cc, cmdline/apt-get.cc, + tools/genbasedir, tools/gensrclist.cc: fixed bugs in source d/l + +2000-10-29 23:50 kojima + + * configure.in: new release + +2000-10-29 23:49 kojima + + * tools/: genbasedir, genpkglist.cc: fixed gensrclist/pkglist bug + +2000-10-29 22:37 kojima + + * configure.in, release: new release + +2000-10-29 22:25 kojima + + * apt-pkg/rpm/: rpmsrcrecords.cc, rpmsrcrecords.h: srcrecord for + rpm + +2000-10-29 22:25 kojima + + * release, apt-pkg/makefile, apt-pkg/pkgrecords.cc, + apt-pkg/sourcelist.cc, apt-pkg/srcrecords.cc, apt-pkg/srcrecords.h, + apt-pkg/systemfactory.h, apt-pkg/deb/debfactory.cc, + apt-pkg/deb/debfactory.h, apt-pkg/deb/debsrcrecords.cc, + apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpmfactory.h, + apt-pkg/rpm/rpminit.h, apt-pkg/rpm/rpmpm.cc, + apt-pkg/rpm/rpmrecords.cc, cmdline/apt-get.cc, tools/genpkglist.cc, + tools/gensrclist.cc: added support for source download + +2000-10-28 05:23 kojima + + * apt-pkg/sourcelist.cc, cmdline/apt-get.cc, tools/Makefile, + tools/gensrclist.cc: started source support + +2000-10-28 04:49 kojima + + * configure.in: new release + +2000-10-28 04:48 kojima + + * apt-pkg/depcache.cc, apt-pkg/pkgrecords.h, + apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpmfactory.h, + apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmlistparser.h, apt-pkg/rpm/rpmrecords.h, + cmdline/apt-cache.cc, po/apt.pot, po/cat-id-tbl.c, po/es_ES.po, + po/pt_BR.po: fixed bug with apt-cache fixed bug with package + descriptions/pkgRecords + +2000-10-27 00:15 kojima + + * release, apt-pkg/orderlist.cc, apt-pkg/pkgcache.cc, + tools/genpkglist.cc: [no log message] + +2000-10-26 19:32 kojima + + * doc/makefile: updated doc manpage + +2000-10-26 19:23 kojima + + * release, apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpmpm.cc, + configure.in: new release + +2000-10-26 19:22 kojima + + * doc/: apt-cache.8, apt-cdrom.8, apt-config.8, apt-get.8, apt.8, + apt.conf.5, sources.list.5, vendors.list.5: updated manpages for + cnc + +2000-10-25 20:17 kojima + + * tools/genbasedir: [no log message] + +2000-10-25 18:49 kojima + + * configure.in: new release + +2000-10-25 18:48 kojima + + * release, apt-pkg/rpm/rpmrecords.cc, cmdline/apt-get.cc, + tools/genbasedir: [no log message] + +2000-10-23 17:31 kojima + + * tools/genbasedir: [no log message] + +2000-10-22 23:08 kojima + + * release, buildlib/makefile.in: [no log message] + +2000-10-22 23:05 kojima + + * tools/genpkglist.c: [no log message] + +2000-10-22 22:57 kojima + + * tools/genpkglist.cc: added new c++ genpkglist + +2000-10-22 22:49 kojima + + * configure.in, release: new release + +2000-10-22 22:48 kojima + + * Makefile, release, apt-pkg/rpm/extra_rpmtags.h, + apt-pkg/rpm/rpminit.h, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmpackagedata.cc, apt-pkg/rpm/rpmpackagedata.h, + apt-pkg/rpm/rpmpm.h, apt-pkg/rpm/rpmrecords.cc, + cmdline/apt-cache.cc, cmdline/apt-get.cc, cmdline/makefile, + tools/Makefile: added upgrade summary information + +2000-10-21 21:30 kojima + + * configure.in, release: new release + +2000-10-21 21:29 kojima + + * apt-pkg/: packagemanager.cc, rpm/rpmlistparser.cc: added release + # to the kernel name hack for supporting multiple installed + versions + +2000-10-19 22:33 claudio + + * ChangeLog: Updated from CVS logs. + +2000-10-19 22:32 claudio + + * tools/: genbasedir, genpkglist.c: Language setting to generate a + consistent pkglist. + +2000-10-19 22:30 claudio + + * po/: es_ES.po, pt_BR.po: Updated es_ES, pt_BR translations. + +2000-10-19 22:28 claudio + + * apt-pkg/rpm/: rpmfactory.cc, rpminit.cc, rpmlistparser.cc: Fixed + uninitialized variables in dependency checking progress bar. + +2000-10-19 22:26 claudio + + * FAQ, apt.spec, configure: Repository cleanup. + +2000-10-16 22:29 kojima + + * rpmpriorities: added priorities file + +2000-10-16 21:22 kojima + + * apt.spec: [no log message] + +2000-10-16 17:28 kojima + + * apt.spec, configure, release, apt-pkg/rpm/rpmfactory.cc, + apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpminit.h, + apt-pkg/rpm/rpmpm.cc, cmdline/apt-get.cc: [no log message] + +2000-10-15 00:56 kojima + + * apt.spec, configure.in, release, apt-pkg/rpm/rpmlistparser.cc, + cmdline/apt-cache.cc, cmdline/apt-cdrom.cc, cmdline/apt-config.cc, + po/POTFILES.in, po/apt.pot, po/cat-id-tbl.c, tools/genpkglist.c: + i18nlazation of other utilities + +2000-10-14 22:30 kojima + + * apt-pkg/: makefile, systemfactory.cc, rpm/rpmlistparser.cc, + rpm/rpmlistparser.h, rpm/rpmpackagedata.cc, rpm/rpmpackagedata.h: + replaced package priority hardcoded kluge with a dynamic kluge + +2000-10-14 20:19 kojima + + * po/pt_BR.po: updated potfiles + +2000-10-14 03:52 kojima + + * apt.spec, apt.spec.in, apt-pkg/acquire-item.cc, apt-pkg/init.cc, + apt-pkg/sourcelist.cc, apt-pkg/sourcelist.h: cdrom support sutff + and others + +2000-10-14 03:51 kojima + + * cmdline/: apt-cdrom.cc, makefile, rpmindexcopy.cc, + rpmindexcopy.h: support for cdrom stuff + +2000-10-14 03:50 kojima + + * tools/: Makefile, genbasedir, genpkglist.c: genpkglist heuristic + file stripping + +2000-10-13 19:39 kojima + + * apt-pkg/rpm/rpminit.h: + #ifndef RPMINIT_H_ + +2000-10-12 22:31 kojima + + * apt.spec, release, apt-pkg/depcache.cc, apt-pkg/systemfactory.cc, + apt-pkg/rpm/rpmlistparser.cc, cmdline/apt-cdrom.cc, + tools/genbasedir: fixed some stuffs added release file support + +2000-10-11 21:35 kojima + + * apt.spec, configure, configure.in, release, apt-pkg/init.cc, + apt-pkg/systemfactory.cc, apt-pkg/rpm/rpmfactory.cc, + apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmpm.cc: fixed cache up-to-dateness check new release + +2000-10-11 20:51 kojima + + * buildlib/sizetable: fixed buglet in sizetable (tab vs space) + +2000-10-11 01:47 kojima + + * tools/genbasedir: fixed bug in genbasedir + +2000-10-11 00:36 kojima + + * apt-pkg/acquire-item.cc, apt-pkg/sourcelist.cc, + apt-pkg/sourcelist.h, methods/gpg.cc: made gpg stuff use + fingerprints + +2000-10-10 23:19 kojima + + * apt.spec.in, docs.tar, docs.tar.gz: aupdate docs tarball + +2000-10-10 23:05 kojima + + * docs.tar: fixed docs tarball + +2000-10-10 22:56 kojima + + * cmdline/makefile, methods/makefile: make it compile dyamic + +2000-10-10 22:41 kojima + + * apt.spec, buildlib/environment.mak.in: [no log message] + +2000-10-10 21:49 kojima + + * configure: new release + +2000-10-10 21:49 kojima + + * README.RPM, REPOSITORIO-APT-HOWTO, apt.spec.in, configure.in, + docs.tar, release, apt-pkg/acquire-item.cc, apt-pkg/depcache.cc, + apt-pkg/init.cc, apt-pkg/packagemanager.cc, apt-pkg/pkgcachegen.cc, + apt-pkg/sourcelist.cc, apt-pkg/sourcelist.h, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmpm.cc, + buildlib/environment.mak.in, cmdline/apt-get.cc, po/apt.pot, + po/cat-id-tbl.c, po/es_ES.po: new release updates changed + authentication code to comply to Jason's stuff use bzip2 + +2000-10-10 19:37 kojima + + * tools/: genbasedir, genbasedir.tcl, genpkglist.c: updated basedir + generator + +2000-10-05 20:55 kojima + + * po/: es_ES.po, pt_BR.po: updated pots + +2000-09-29 00:51 kojima + + * FAQ, apt.spec, apt.spec.in, release, apt-pkg/contrib/strutl.cc, + apt-pkg/contrib/strutl.h, apt-pkg/rpm/rpmrecords.cc, + cmdline/acqprogress.cc, cmdline/apt-cache.cc, cmdline/apt-get.cc, + tools/mkpackages.c: added claudio's patch to make it work with + aptitude + +2000-09-26 20:03 kojima + + * AUTHORS.RPM: added RPM port credits file + +2000-09-26 19:58 kojima + + * configure, configure.in: enw release + +2000-09-26 19:58 kojima + + * apt.spec, apt.spec.in, release, apt-pkg/contrib/error.cc, + cmdline/apt-get.cc, doc/examples/vendors.list, methods/gpg.cc, + po/apt.pot, po/cat-id-tbl.c, tools/genbasedir.tcl: better msgs for + gpg errors + +2000-09-26 18:05 kojima + + * FAQ: updated with auth stuff + +2000-09-26 17:42 kojima + + * methods/gpg.cc: added gpg method + +2000-09-26 17:37 kojima + + * configure, configure.in, release, apt-pkg/sourcelist.cc: more + authentication stuff new release + +2000-09-26 17:22 kojima + + * REPOSITORIO-APT-HOWTO, apt.spec, apt.spec.in, release, + apt-pkg/acquire-item.cc, apt-pkg/acquire-item.h, + apt-pkg/acquire-method.cc, apt-pkg/acquire-method.h, + apt-pkg/init.cc, apt-pkg/makefile, apt-pkg/packagemanager.h, + apt-pkg/sourcelist.cc, apt-pkg/sourcelist.h, apt-pkg/srcrecords.cc, + apt-pkg/systemfactory.cc, apt-pkg/systemfactory.h, + apt-pkg/contrib/fileutl.cc, apt-pkg/contrib/fileutl.h, + apt-pkg/deb/debfactory.cc, apt-pkg/rpm/rpmfactory.cc, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmlistparser.h, + apt-pkg/rpm/rpmpm.cc, cmdline/apt-get.cc, cmdline/makefile, + methods/makefile, po/apt.pot, po/pt_BR.po: digital signature + authentication + +2000-09-25 23:26 kojima + + * tools/: genbasedir.tcl, genpkglist.c: added base dir generator + +2000-09-22 03:07 kojima + + * po/pt_BR.po: update portug. po + +2000-09-20 20:12 kojima + + * FAQ: updated faq + +2000-09-20 18:20 kojima + + * configure, configure.in: new release + +2000-09-20 18:20 kojima + + * FAQ, apt.spec, apt.spec.in, release, apt-pkg/acquire-item.cc, + apt-pkg/cacheiterators.h, apt-pkg/depcache.cc, apt-pkg/pkgcache.cc, + apt-pkg/pkgcachegen.cc, apt-pkg/pkgcachegen.h, + apt-pkg/rpm/rpmfactory.cc, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmpm.h, + apt-pkg/rpm/rpmrecords.cc, cmdline/apt-get.cc, po/pt_BR.po: added + pt_BR potfile added support for duplicated package names + +2000-09-18 21:34 kojima + + * README.RPM, apt.spec, apt.spec.in, configure, configure.in, + release, apt-pkg/acquire-item.cc, apt-pkg/algorithms.cc, + apt-pkg/depcache.cc, apt-pkg/orderlist.cc, + apt-pkg/packagemanager.cc, apt-pkg/pkgcache.cc, apt-pkg/pkgcache.h, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmrecords.cc: new + release fixed md5 stuff + +2000-09-18 20:56 kojima + + * tools/genpkglist.c: fixed bug with md5 data + +2000-09-16 22:37 kojima + + * po/pt_BR.gmo: [no log message] + +2000-09-16 22:36 kojima + + * apt.spec, apt.spec.in, configure, configure.in, release, + apt-pkg/depcache.cc, apt-pkg/init.cc, apt-pkg/pkgcachegen.cc, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmlistparser.h, + apt-pkg/rpm/rpmpm.cc, cmdline/makefile, po/apt.pot, po/pt_BR.gmo: + made obsoleter packages automatically add conflicts new release + +2000-09-16 00:49 kojima + + * po/pt_BR.po: [no log message] + +2000-09-16 00:37 kojima + + * configure, configure.in: added AC_PROG_INSTALL in configure + +2000-09-15 23:06 kojima + + * release, apt-pkg/depcache.cc, apt-pkg/rpm/rpmversion.cc, + cmdline/apt-cache.cc, cmdline/apt-get.cc, po/apt.pot: fixed bug + with versioned requires and unversioned provides + +2000-09-15 22:23 kojima + + * README.RPM: update doc to apt-get isntead of rapt + +2000-09-14 02:27 kojima + + * apt-pkg/: makefile, cnc/cncfactory.cc, cnc/cncfactory.h, + cnc/cncversion.cc, rpm/rpmfactory.cc, rpm/rpmfactory.h, + rpm/rpminit.cc, rpm/rpminit.h, rpm/rpmversion.cc: [no log message] + +2000-09-14 00:58 kojima + + * mkinstalldirs, configure, configure.in: [no log message] + +2000-09-14 00:55 kojima + + * apt.spec, release, intl/ChangeLog, intl/Makefile.in, + intl/VERSION, intl/bindtextdom.c, intl/cat-compat.c, + intl/dcgettext.c, intl/dgettext.c, intl/explodename.c, + intl/finddomain.c, intl/gettext.c, intl/gettext.h, intl/gettextP.h, + intl/hash-string.h, intl/intl-compat.c, intl/l10nflist.c, + intl/libgettext.h, intl/linux-msg.sed, intl/loadinfo.h, + intl/loadmsgcat.c, intl/localealias.c, intl/po2tbl.sed.in, + intl/textdomain.c, intl/xopen-msg.sed: added gettext + +2000-09-14 00:50 kojima + + * apt.spec.in, release, cmdline/apt-get.cc, po/apt.pot: some i18n + updates + +2000-09-14 00:39 kojima + + * FAQ, acinclude.m4, aclocal.m4, apt.spec, apt.spec.in, configure, + configure.in, release, apt-pkg/makefile, apt-pkg/contrib/i18n.h, + apt-pkg/rpm/rpmlistparser.cc, buildlib/acconfig.h, + buildlib/config.h.in, buildlib/environment.mak.in, + cmdline/apt-get.cc, cmdline/makefile, po/Makefile.in.in, + po/POTFILES.in, po/apt.pot, po/cat-id-tbl.c, po/pt_BR.gmo, + po/pt_BR.po, po/stamp-cat-id: i18n + +2000-09-13 17:59 kojima + + * apt-pkg/rpm/rpmlistparser.cc: faster file dependency processing + +2000-09-13 00:58 kojima + + * apt-pkg/algorithms.cc: removed temp test code + +2000-09-13 00:22 kojima + + * apt.spec, apt.spec.in, release, doc/examples/rapt.conf, + doc/examples/rsources.list: new release changed specs + +2000-09-13 00:11 kojima + + * FAQ, apt.spec, apt.spec.in, rapt.spec, rapt.spec.in, release, + apt-pkg/rpm/rpmlistparser.cc, cmdline/apt-cache.cc: new release, + test code to fix prob with conflict/obsolete + +2000-09-13 00:00 kojima + + * doc/examples/rsources.list: fixed typo + +2000-09-12 23:17 kojima + + * apt-pkg/depcache.cc: removed debug msgs + +2000-09-12 23:13 kojima + + * apt-pkg/algorithms.cc: fixed problem with dependencies that can + be resolved by a package that's not installed + +2000-09-12 20:44 kojima + + * doc/examples/rsources.list: config file suitable for outside use + +2000-09-12 20:03 kojima + + * rapt.spec, release, cmdline/makefile: back to static + +2000-09-12 00:04 kojima + + * configure, configure.in, rapt.spec, release, + apt-pkg/algorithms.cc, apt-pkg/depcache.cc, apt-pkg/init.cc, + apt-pkg/sourcelist.cc, apt-pkg/rpm/rpmlistparser.cc, + cmdline/makefile, doc/examples/rsources.list: new release changed + source.list format + +2000-09-06 22:02 kojima + + * configure, configure.in, rapt.spec, release, apt-pkg/init.cc, + apt-pkg/rpm/rpmlistparser.cc, cmdline/makefile, tools/Makefile: new + release fixed bug with versionhashing + +2000-09-06 17:44 kojima + + * rapt.spec, rapt.spec.in: localizado p/ portugues + +2000-09-06 17:34 kojima + + * FAQ, README.RPM, configure, configure.in, prepare, rapt.spec, + rapt.spec.in, release, cmdline/apt-get.cc: renamed everything back + from rapt to apt/apt-get + +2000-09-06 17:04 kojima + + * configure: new release + +2000-09-06 17:03 kojima + + * rapt.spec.in, cmdline/makefile: changed name of binaries + +2000-09-06 16:57 kojima + + * FAQ, configure.in, rapt.spec, rapt.spec.in, release, + apt-pkg/init.cc, apt-pkg/pkgcachegen.cc, + apt-pkg/rpm/rpmlistparser.h: new release changed some error + messages + +2000-09-05 22:21 kojima + + * apt-pkg/rpm/rpmlistparser.cc: added exception package list config + option support + +2000-09-05 20:59 kojima + + * cmdline/apt-get.cc: removed lc_all lang kluge message + +2000-09-05 20:58 kojima + + * tools/genpkglist.c: fix cmd line parse + +2000-09-05 01:29 kojima + + * configure, configure.in: new release + +2000-09-05 01:29 kojima + + * FAQ, rapt.spec, rapt.spec.in, release, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmpm.cc, + cmdline/apt-get.cc: new release added message before exec()ing rpm + temp hack to not upgrade kernel + +2000-09-04 23:39 kojima + + * configure, configure.in, rapt.spec, rapt.spec.in, release: new + version + +2000-09-04 23:39 kojima + + * cmdline/apt-get.cc: put back dist-upgrade + +2000-09-04 23:32 kojima + + * apt-pkg/rpm/rpmlistparser.cc: added tmp hardcoded + essential/required packages + +2000-09-04 18:58 kojima + + * FAQ, configure, configure.in, rapt.spec, rapt.spec.in, release, + cmdline/apt-cache.cc, cmdline/apt-get.cc: updated release +stuffs + +2000-09-04 18:55 kojima + + * apt-pkg/: algorithms.cc, cachefile.cc, depcache.cc, + distrofactory.cc, distrofactory.h, makefile, packagemanager.cc, + pkgcache.cc, pkgcachegen.cc, pkgrecords.cc, systemfactory.cc, + systemfactory.h, version.cc, cnc/cncfactory.h, deb/debfactory.h, + rpm/rpminit.h, rpm/rpmlistparser.cc: renamed abstract distribut6ion + factory to from distro to system added temp kluge to add + essential/important tags to packages + +2000-09-01 03:12 kojima + + * rapt.spec, release, apt-pkg/distrofactory.cc: remove debug msg + +2000-09-01 03:12 kojima + + * doc/examples/rsources.list: fixed typo + +2000-09-01 02:53 kojima + + * apt-pkg/contrib/progress.cc, cmdline/apt-get.cc: fixed prob with + progress update ingterval + +2000-09-01 02:50 kojima + + * configure, configure.in, rapt.spec, release, + apt-pkg/packagemanager.cc, apt-pkg/rpm/rpmpm.cc, + cmdline/apt-get.cc: version 0.6 removed cmd line length limitation + to be passed to rpm by rpmpm + +2000-09-01 02:13 kojima + + * apt-pkg/cnc/cncfactory.cc: progress indicator sorta fixed + +2000-08-31 22:25 kojima + + * release: updated release script + +2000-08-31 22:15 kojima + + * rapt.spec, rapt.spec.in, release, doc/examples/rsources.list: + added zaphod to the list of repositories (to get latest rapt from + here) + +2000-08-31 21:18 kojima + + * configure, configure.in: udpated version to 0.5 + +2000-08-31 21:09 kojima + + * apt-pkg/: acquire-item.cc, rpm/rpmlistparser.cc, + rpm/rpmrecords.cc: fixed problem with provides + +2000-08-31 20:48 kojima + + * apt-pkg/rpm/rpmlistparser.cc: added versioned provides + +2000-08-31 20:42 kojima + + * tools/genpkglist.c: added full provide tags + +2000-08-31 18:52 kojima + + * FAQ: added faq + +2000-08-31 18:50 kojima + + * tools/genpkglist.c: added m5d sum tag to pkglist + +2000-08-31 18:49 kojima + + * apt-pkg/rpm/extra_rpmtags.h: new md5 tag + +2000-08-31 18:48 kojima + + * apt-pkg/rpm/rpmrecords.cc: MD5 sum works + +2000-08-31 16:59 kojima + + * cmdline/apt-cache.cc: fixed rapt-cache show for rpm + +2000-08-31 02:17 kojima + + * apt-pkg/rpm/rpmpm.cc: debug msgs + +2000-08-31 00:50 kojima + + * apt-pkg/rpm/rpmpm.cc: removed debug message for pkg configuration + +2000-08-31 00:27 kojima + + * cmdline/: apt-cache.cc, apt-get.cc: removed stale version.h + +2000-08-31 00:13 kojima + + * cmdline/makefile: changed binary name from rapt to rapt-get + +2000-08-31 00:11 kojima + + * apt-pkg/: orderlist.cc, pkgcachegen.cc, version.cc: removed stale + version.h references + +2000-08-31 00:07 kojima + + * configure, configure.in: updated version + +2000-08-31 00:05 kojima + + * README.RPM, apt-pkg/pkgcachegen.cc, apt-pkg/cnc/cncfactory.h, + apt-pkg/cnc/cncversion.cc, apt-pkg/rpm/rpmlistparser.cc: fixed some + versioning check bugs + +2000-08-30 21:32 kojima + + * apt-pkg/depcache.cc, apt-pkg/distrofactory.h, apt-pkg/makefile, + apt-pkg/packagemanager.cc, apt-pkg/pkgcache.cc, + apt-pkg/pkgcachegen.cc, apt-pkg/version.cc, apt-pkg/version.h, + apt-pkg/cnc/cncfactory.h, apt-pkg/cnc/cncversion.cc, + apt-pkg/rpm/rpmlistparser.cc, cmdline/apt-cache.cc, + cmdline/apt-get.cc, tools/genpkglist.c: made version comparison + code distribution dependent + + added code for rpm version comparison (partially ripped from rpm) + +2000-08-30 17:32 kojima + + * configure: removed architecture kluge + +2000-08-30 17:18 kojima + + * configure, configure.in, rapt.spec, rapt.spec.in, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmlistparser.h, + cmdline/apt-get.cc: fixed ix86 architecture family problem + +2000-08-30 15:04 kojima + + * configure.in: changed ARCHITECTURE define to include the real + machine architecture too, along the family + +2000-08-30 13:46 kojima + + * apt-pkg/rpm/rpmlistparser.cc: added more kluges for ix86 family + detection + +2000-08-30 03:21 kojima + + * apt-pkg/sourcelist.cc: removed some debug msgs + +2000-08-30 02:51 kojima + + * methods/makefile: make everything static + +2000-08-30 02:45 kojima + + * apt-pkg/sourcelist.cc: fixed typo + +2000-08-30 02:32 kojima + + * cmdline/makefile: make everything static + +2000-08-30 01:51 kojima + + * doc/examples/rsources.list: [no log message] + +2000-08-30 00:02 kojima + + * apt-pkg/sourcelist.cc: typo fix + +2000-08-29 23:59 kojima + + * configure, rapt.spec, rapt.spec.in, apt-pkg/sourcelist.cc, + doc/examples/rapt.conf, doc/examples/rsources.list: [no log + message] + +2000-08-29 23:31 kojima + + * buildlib/environment.mak.in: update to make only static lib + +2000-08-29 23:23 kojima + + * configure.in: updated vesion number + +2000-08-29 23:15 kojima + + * rapt.spec, apt-pkg/pkgcachegen.cc, tools/genpkglist.c: [no log + message] + +2000-08-29 23:10 kojima + + * rapt.spec, rapt.spec.in, apt-pkg/sourcelist.cc, + apt-pkg/rpm/rpmpm.cc, cmdline/apt-get.cc, cmdline/makefile: + modified stuff to build as static + +2000-08-29 22:38 kojima + + * README.RPM: [no log message] + +2000-08-29 20:32 kojima + + * README.RPM, apt-pkg/makefile, apt-pkg/rpm/rpmpm.cc, + cmdline/makefile, methods/makefile, tools/genpkglist.c: fixed + problem with halfway system ugprade + +2000-08-26 00:15 kojima + + * apt-pkg/rpm/: rpminit.cc, rpmstatusgen.cc, rpmstatusgen.h: [no + log message] + +2000-08-26 00:07 kojima + + * rapt.spec, apt-pkg/rpm/extra_rpmtags.h, apt-pkg/rpm/rpmpm.cc, + tools/genpkglist.c: [no log message] + +2000-08-25 22:58 kojima + + * apt-pkg/: cachefile.cc, distrofactory.cc, pkgcache.cc, + sourcelist.cc, cnc/cncfactory.cc, rpm/rpmrecords.cc: fixed pkg + cache check + +2000-08-25 22:58 kojima + + * README.RPM: [no log message] + +2000-08-25 17:39 kojima + + * tools/Makefile: [no log message] + +2000-08-25 17:39 kojima + + * cmdline/: apt-cache.cc, apt-get.cc, makefile: updated cmd line + utils + +2000-08-25 17:39 kojima + + * apt-pkg/rpm/: rpmlistparser.cc, rpmlistparser.h, rpmrecords.cc: + fixed list parser and finished reocrd parser + +2000-08-25 17:39 kojima + + * apt-pkg/deb/: debfactory.cc, debfactory.h: updated classes with + new factory methods + +2000-08-25 17:38 kojima + + * apt-pkg/: acquire-item.cc, algorithms.cc, depcache.cc, + depcache.h, distrofactory.cc, distrofactory.h, pkgcachegen.cc, + pkgrecords.cc, pkgrecords.h, cnc/cncfactory.cc, cnc/cncfactory.h: + updated record parsing to rpm + +2000-08-25 17:38 kojima + + * configure.in: version change + +2000-08-22 22:24 kojima + + * apt.dia, rapt.spec, apt-pkg/cachefile.h, apt-pkg/depcache.cc, + apt-pkg/distrofactory.cc, apt-pkg/distrofactory.h, + apt-pkg/makefile, apt-pkg/pkgcachegen.cc, apt-pkg/sourcelist.cc, + apt-pkg/cnc/cncfactory.cc, apt-pkg/cnc/cncfactory.h, + apt-pkg/contrib/fileutl.cc, apt-pkg/deb/debfactory.cc, + apt-pkg/deb/debfactory.h, apt-pkg/rpm/rpminit.cc, + apt-pkg/rpm/rpminit.h, apt-pkg/rpm/rpmlistparser.cc, + apt-pkg/rpm/rpmlistparser.h, apt-pkg/rpm/rpmrecords.cc, + apt-pkg/rpm/rpmrecords.h, cmdline/apt-cache.cc, cmdline/makefile, + tools/mkpackages.c: [no log message] + +2000-08-19 00:08 kojima + + * apt-pkg/cachefile.cc, apt-pkg/distrofactory.cc, + apt-pkg/distrofactory.h, apt-pkg/pkgcachegen.cc, + apt-pkg/pkgcachegen.h, apt-pkg/cnc/cncfactory.cc, + apt-pkg/cnc/cncfactory.h, apt-pkg/deb/debfactory.cc, + apt-pkg/deb/debfactory.h, cmdline/apt-cache.cc, cmdline/makefile: + cache generator abstracted for debian and cnc + +2000-08-17 23:40 kojima + + * README.RPM, apt.dia: documentation update + +2000-08-17 03:31 kojima + + * apt-pkg/rpm/rpmpm.cc: [no log message] + +2000-08-17 00:35 kojima + + * tools/mkpackages.c: [no log message] + +2000-08-11 00:10 kojima + + * README.RPM, prepare, rapt.spec, doc/examples/rapt.conf, + doc/examples/rsources.list: [no log message] + +2000-08-10 23:20 kojima + + * prepare, rapt.spec: [no log message] + +2000-08-10 22:47 kojima + + * tools/: Packages, hdlist.pkgs, status, Makefile, dumprpmdb, + mkpackages, mkstatus, update: [no log message] + +2000-08-10 22:47 kojima + + * prepare: added file + +2000-08-10 22:43 kojima + + * README.RPM, apt.dia, cmdline/apt-get.cc, cmdline/makefile: added + some docs files + +2000-08-10 18:57 kojima + + * status: [no log message] + +2000-08-10 15:42 kojima + + * AUTHORS, COMPILING, COPYING, COPYING.GPL, ChangeLog, Makefile, + README.make, TODO, aclocal.m4, configure, configure.in, status, + cmdline/acqprogress.cc, cmdline/apt-cache.cc, cmdline/apt-get.cc, + cmdline/indexcopy.cc, cmdline/makefile, deity/anchor.cc, + deity/anchor.h, deity/basic.cc, deity/basic.h, deity/button.cc, + deity/button.h, deity/columnbar.cc, deity/columnbar.h, + deity/event.cc, deity/event.h, deity/gpmdev.cc, deity/gpmdev.h, + deity/graphics.cc, deity/graphics.h, deity/makefile, + deity/menubar.cc, deity/menubar.h, deity/notify.cc, deity/notify.h, + deity/progress.cc, deity/progress.h, deity/selectloop.cc, + deity/selectloop.h, deity/slangdev.cc, deity/slangdev.h, + deity/tabdialog.cc, deity/tabdialog.h, deity/textwidg.cc, + deity/textwidg.h, deity/tree.cc, deity/tree.h, deity/utils.cc, + deity/utils.h, deity/widget-thread.cc, deity/widget-thread.h, + deity/widget.cc, deity/widget.h, deity/widgetinit.cc, + deity/widgetinit.h, deity/window.cc, deity/window.h, + deity/x11dev.cc, deity/x11dev.h, deity/x11xpm.cc, deity/xpm.cc, + deity/xpm.h, methods/cdrom.cc, methods/connect.cc, + methods/connect.h, methods/copy.cc, methods/file.cc, + methods/ftp.cc, methods/ftp.h, methods/gzip.cc, methods/http.cc, + methods/http.h, methods/makefile, methods/rfc2553emu.cc, + methods/rfc2553emu.h, apt-pkg/acquire-item.cc, + apt-pkg/acquire-item.h, apt-pkg/acquire-method.cc, + apt-pkg/acquire-method.h, apt-pkg/acquire-worker.cc, + apt-pkg/acquire-worker.h, apt-pkg/acquire.cc, apt-pkg/acquire.h, + apt-pkg/algorithms.cc, apt-pkg/algorithms.h, apt-pkg/cachefile.cc, + apt-pkg/cachefile.h, apt-pkg/cacheiterators.h, apt-pkg/clean.cc, + apt-pkg/clean.h, apt-pkg/depcache.cc, apt-pkg/depcache.h, + apt-pkg/distrofactory.cc, apt-pkg/distrofactory.h, apt-pkg/init.cc, + apt-pkg/init.h, apt-pkg/makefile, apt-pkg/orderlist.cc, + apt-pkg/orderlist.h, apt-pkg/packagemanager.cc, + apt-pkg/packagemanager.h, apt-pkg/pkgcache.cc, apt-pkg/pkgcache.h, + apt-pkg/pkgcachegen.cc, apt-pkg/pkgcachegen.h, + apt-pkg/pkgrecords.cc, apt-pkg/pkgrecords.h, apt-pkg/sourcelist.cc, + apt-pkg/sourcelist.h, apt-pkg/srcrecords.cc, apt-pkg/srcrecords.h, + apt-pkg/tagfile.cc, apt-pkg/tagfile.h, apt-pkg/version.cc, + apt-pkg/version.h, apt-pkg/cnc/cncfactory.cc, + apt-pkg/cnc/cncfactory.h, apt-pkg/contrib/cdromutl.cc, + apt-pkg/contrib/cdromutl.h, apt-pkg/contrib/cmndline.cc, + apt-pkg/contrib/cmndline.h, apt-pkg/contrib/configuration.cc, + apt-pkg/contrib/configuration.h, apt-pkg/contrib/crc-16.cc, + apt-pkg/contrib/crc-16.h, apt-pkg/contrib/error.cc, + apt-pkg/contrib/error.h, apt-pkg/contrib/fileutl.cc, + apt-pkg/contrib/fileutl.h, apt-pkg/contrib/md5.cc, + apt-pkg/contrib/md5.h, apt-pkg/contrib/mmap.cc, + apt-pkg/contrib/mmap.h, apt-pkg/contrib/progress.cc, + apt-pkg/contrib/progress.h, apt-pkg/contrib/strutl.cc, + apt-pkg/contrib/strutl.h, apt-pkg/contrib/system.h, + apt-pkg/deb/debfactory.cc, apt-pkg/deb/debfactory.h, + apt-pkg/deb/deblistparser.cc, apt-pkg/deb/deblistparser.h, + apt-pkg/deb/debrecords.cc, apt-pkg/deb/debrecords.h, + apt-pkg/deb/debsrcrecords.cc, apt-pkg/deb/debsrcrecords.h, + apt-pkg/deb/dpkginit.cc, apt-pkg/deb/dpkginit.h, + apt-pkg/deb/dpkgpm.cc, apt-pkg/deb/dpkgpm.h, + apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpminit.h, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmlistparser.h, + apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmpm.h, + apt-pkg/rpm/rpmstatusgen.cc, apt-pkg/rpm/rpmstatusgen.h, + buildlib/archtable, buildlib/config.guess, buildlib/config.h.in, + buildlib/config.sub, buildlib/configure.mak, buildlib/copy.mak, + buildlib/debiandoc.mak, buildlib/defaults.mak, + buildlib/environment.mak.in, buildlib/install-sh, + buildlib/inttypes.h.in, buildlib/library.mak, buildlib/makefile.in, + buildlib/manpage.mak, buildlib/mkChangeLog, buildlib/netdb.h.in, + buildlib/program.mak, buildlib/sizetable, + buildlib/staticlibrary.mak, buildlib/statvfs.h.in, + buildlib/tools.m4, buildlib/yodl_manpage.mak, + cmdline/acqprogress.h, cmdline/apt-cdrom.cc, cmdline/apt-config.cc, + cmdline/indexcopy.h, debian/changelog, debian/control, + debian/copyright, debian/dhelp, debian/dirs, debian/examples, + debian/libapt-pkg-dev.dirs, debian/libapt-pkg-doc.dhelp, + debian/libapt-pkg-doc.postinst, debian/libapt-pkg-doc.prerm, + debian/postinst, debian/postrm, debian/rules, debian/shlibs.local, + doc/Bugs, doc/apt-cache.8, doc/apt-cache.8.yo, doc/apt-cdrom.8, + doc/apt-cdrom.8.yo, doc/apt-config.8, doc/apt-config.8.yo, + doc/apt-get.8, doc/apt-get.8.yo, doc/apt.8, doc/apt.conf.5, + doc/apt.conf.5.yo, doc/cache.sgml, doc/design.sgml, + doc/dpkg-tech.sgml, doc/files.sgml, doc/guide.sgml, doc/makefile, + doc/method.sgml, doc/offline.sgml, doc/sources.list.5, + doc/sources.list.5.yo, doc/examples/apt.conf, + doc/examples/configure-index, doc/examples/sources.list, + dselect/desc.apt, dselect/install, dselect/makefile, dselect/names, + dselect/setup, dselect/update, gui/apt.cc, gui/aptwidgets.cc, + gui/aptwidgets.h, gui/checkoff.xpm, gui/checkon.xpm, + gui/conflicts.xpm, gui/depends.xpm, gui/downgrade.xpm, + gui/errorshow.cc, gui/errorshow.h, gui/extracache.cc, + gui/extracache.h, gui/makefile, gui/minus.xpm, gui/package.xpm, + gui/pkgtree.cc, gui/pkgtree.h, gui/pkgtreeitem.cc, + gui/pkgtreeitem.h, gui/plus.xpm, gui/policy.cc, gui/policy.h, + gui/progressmeter.cc, gui/progressmeter.h, gui/radiooff.xpm, + gui/radioon.xpm, gui/recommends.xpm, gui/section.xpm, + gui/statuswidgets.cc, gui/statuswidgets.h, gui/suggests.xpm, + gui/upgrade.xpm, test/makefile, test/mthdcat.cc, test/scratch.cc, + test/versions.lst, test/versiontest.cc, tools/Makefile, + tools/Packages, tools/dumprpmdb, tools/dumprpmdb.c, + tools/hashtable.c, tools/hashtable.h, tools/hdlist.pkgs, + tools/mkpackages, tools/mkpackages.c, tools/mkstatus, + tools/mkstatus.c, tools/status, tools/update: Initial revision + +2000-08-10 15:42 kojima + + * AUTHORS, COMPILING, COPYING, COPYING.GPL, ChangeLog, Makefile, + README.make, TODO, aclocal.m4, configure, configure.in, status, + cmdline/acqprogress.cc, cmdline/apt-cache.cc, cmdline/apt-get.cc, + cmdline/indexcopy.cc, cmdline/makefile, deity/anchor.cc, + deity/anchor.h, deity/basic.cc, deity/basic.h, deity/button.cc, + deity/button.h, deity/columnbar.cc, deity/columnbar.h, + deity/event.cc, deity/event.h, deity/gpmdev.cc, deity/gpmdev.h, + deity/graphics.cc, deity/graphics.h, deity/makefile, + deity/menubar.cc, deity/menubar.h, deity/notify.cc, deity/notify.h, + deity/progress.cc, deity/progress.h, deity/selectloop.cc, + deity/selectloop.h, deity/slangdev.cc, deity/slangdev.h, + deity/tabdialog.cc, deity/tabdialog.h, deity/textwidg.cc, + deity/textwidg.h, deity/tree.cc, deity/tree.h, deity/utils.cc, + deity/utils.h, deity/widget-thread.cc, deity/widget-thread.h, + deity/widget.cc, deity/widget.h, deity/widgetinit.cc, + deity/widgetinit.h, deity/window.cc, deity/window.h, + deity/x11dev.cc, deity/x11dev.h, deity/x11xpm.cc, deity/xpm.cc, + deity/xpm.h, methods/cdrom.cc, methods/connect.cc, + methods/connect.h, methods/copy.cc, methods/file.cc, + methods/ftp.cc, methods/ftp.h, methods/gzip.cc, methods/http.cc, + methods/http.h, methods/makefile, methods/rfc2553emu.cc, + methods/rfc2553emu.h, apt-pkg/acquire-item.cc, + apt-pkg/acquire-item.h, apt-pkg/acquire-method.cc, + apt-pkg/acquire-method.h, apt-pkg/acquire-worker.cc, + apt-pkg/acquire-worker.h, apt-pkg/acquire.cc, apt-pkg/acquire.h, + apt-pkg/algorithms.cc, apt-pkg/algorithms.h, apt-pkg/cachefile.cc, + apt-pkg/cachefile.h, apt-pkg/cacheiterators.h, apt-pkg/clean.cc, + apt-pkg/clean.h, apt-pkg/depcache.cc, apt-pkg/depcache.h, + apt-pkg/distrofactory.cc, apt-pkg/distrofactory.h, apt-pkg/init.cc, + apt-pkg/init.h, apt-pkg/makefile, apt-pkg/orderlist.cc, + apt-pkg/orderlist.h, apt-pkg/packagemanager.cc, + apt-pkg/packagemanager.h, apt-pkg/pkgcache.cc, apt-pkg/pkgcache.h, + apt-pkg/pkgcachegen.cc, apt-pkg/pkgcachegen.h, + apt-pkg/pkgrecords.cc, apt-pkg/pkgrecords.h, apt-pkg/sourcelist.cc, + apt-pkg/sourcelist.h, apt-pkg/srcrecords.cc, apt-pkg/srcrecords.h, + apt-pkg/tagfile.cc, apt-pkg/tagfile.h, apt-pkg/version.cc, + apt-pkg/version.h, apt-pkg/cnc/cncfactory.cc, + apt-pkg/cnc/cncfactory.h, apt-pkg/contrib/cdromutl.cc, + apt-pkg/contrib/cdromutl.h, apt-pkg/contrib/cmndline.cc, + apt-pkg/contrib/cmndline.h, apt-pkg/contrib/configuration.cc, + apt-pkg/contrib/configuration.h, apt-pkg/contrib/crc-16.cc, + apt-pkg/contrib/crc-16.h, apt-pkg/contrib/error.cc, + apt-pkg/contrib/error.h, apt-pkg/contrib/fileutl.cc, + apt-pkg/contrib/fileutl.h, apt-pkg/contrib/md5.cc, + apt-pkg/contrib/md5.h, apt-pkg/contrib/mmap.cc, + apt-pkg/contrib/mmap.h, apt-pkg/contrib/progress.cc, + apt-pkg/contrib/progress.h, apt-pkg/contrib/strutl.cc, + apt-pkg/contrib/strutl.h, apt-pkg/contrib/system.h, + apt-pkg/deb/debfactory.cc, apt-pkg/deb/debfactory.h, + apt-pkg/deb/deblistparser.cc, apt-pkg/deb/deblistparser.h, + apt-pkg/deb/debrecords.cc, apt-pkg/deb/debrecords.h, + apt-pkg/deb/debsrcrecords.cc, apt-pkg/deb/debsrcrecords.h, + apt-pkg/deb/dpkginit.cc, apt-pkg/deb/dpkginit.h, + apt-pkg/deb/dpkgpm.cc, apt-pkg/deb/dpkgpm.h, + apt-pkg/rpm/rpminit.cc, apt-pkg/rpm/rpminit.h, + apt-pkg/rpm/rpmlistparser.cc, apt-pkg/rpm/rpmlistparser.h, + apt-pkg/rpm/rpmpm.cc, apt-pkg/rpm/rpmpm.h, + apt-pkg/rpm/rpmstatusgen.cc, apt-pkg/rpm/rpmstatusgen.h, + buildlib/archtable, buildlib/config.guess, buildlib/config.h.in, + buildlib/config.sub, buildlib/configure.mak, buildlib/copy.mak, + buildlib/debiandoc.mak, buildlib/defaults.mak, + buildlib/environment.mak.in, buildlib/install-sh, + buildlib/inttypes.h.in, buildlib/library.mak, buildlib/makefile.in, + buildlib/manpage.mak, buildlib/mkChangeLog, buildlib/netdb.h.in, + buildlib/program.mak, buildlib/sizetable, + buildlib/staticlibrary.mak, buildlib/statvfs.h.in, + buildlib/tools.m4, buildlib/yodl_manpage.mak, + cmdline/acqprogress.h, cmdline/apt-cdrom.cc, cmdline/apt-config.cc, + cmdline/indexcopy.h, debian/changelog, debian/control, + debian/copyright, debian/dhelp, debian/dirs, debian/examples, + debian/libapt-pkg-dev.dirs, debian/libapt-pkg-doc.dhelp, + debian/libapt-pkg-doc.postinst, debian/libapt-pkg-doc.prerm, + debian/postinst, debian/postrm, debian/rules, debian/shlibs.local, + doc/Bugs, doc/apt-cache.8, doc/apt-cache.8.yo, doc/apt-cdrom.8, + doc/apt-cdrom.8.yo, doc/apt-config.8, doc/apt-config.8.yo, + doc/apt-get.8, doc/apt-get.8.yo, doc/apt.8, doc/apt.conf.5, + doc/apt.conf.5.yo, doc/cache.sgml, doc/design.sgml, + doc/dpkg-tech.sgml, doc/files.sgml, doc/guide.sgml, doc/makefile, + doc/method.sgml, doc/offline.sgml, doc/sources.list.5, + doc/sources.list.5.yo, doc/examples/apt.conf, + doc/examples/configure-index, doc/examples/sources.list, + dselect/desc.apt, dselect/install, dselect/makefile, dselect/names, + dselect/setup, dselect/update, gui/apt.cc, gui/aptwidgets.cc, + gui/aptwidgets.h, gui/checkoff.xpm, gui/checkon.xpm, + gui/conflicts.xpm, gui/depends.xpm, gui/downgrade.xpm, + gui/errorshow.cc, gui/errorshow.h, gui/extracache.cc, + gui/extracache.h, gui/makefile, gui/minus.xpm, gui/package.xpm, + gui/pkgtree.cc, gui/pkgtree.h, gui/pkgtreeitem.cc, + gui/pkgtreeitem.h, gui/plus.xpm, gui/policy.cc, gui/policy.h, + gui/progressmeter.cc, gui/progressmeter.h, gui/radiooff.xpm, + gui/radioon.xpm, gui/recommends.xpm, gui/section.xpm, + gui/statuswidgets.cc, gui/statuswidgets.h, gui/suggests.xpm, + gui/upgrade.xpm, test/makefile, test/mthdcat.cc, test/scratch.cc, + test/versions.lst, test/versiontest.cc, tools/Makefile, + tools/Packages, tools/dumprpmdb, tools/dumprpmdb.c, + tools/hashtable.c, tools/hashtable.h, tools/hdlist.pkgs, + tools/mkpackages, tools/mkpackages.c, tools/mkstatus, + tools/mkstatus.c, tools/status, tools/update: inicial + diff --git a/apt/Makefile b/apt/Makefile new file mode 100644 index 0000000..04f75a6 --- /dev/null +++ b/apt/Makefile @@ -0,0 +1,28 @@ +# -*- make -*- + +# This is the top level make file for APT, it recurses to each lower +# level make file and runs it with the proper target +ifndef NOISY +.SILENT: +endif + +.PHONY: headers library clean veryclean all binary program doc +all headers library clean veryclean binary program doc dirs: + $(MAKE) -C apt-pkg $@ + $(MAKE) -C methods $@ + $(MAKE) -C cmdline $@ + $(MAKE) -C dselect $@ + $(MAKE) -C tools $@ + $(MAKE) -C doc $@ + +# Some very common aliases +.PHONY: maintainer-clean dist-clean distclean pristine sanity +maintainer-clean dist-clean distclean pristine sanity: veryclean + +# The startup target builds the necessary configure scripts. It should +# be used after a CVS checkout. +CONVERTED=environment.mak include/config.h makefile +include buildlib/configure.mak +$(BUILDDIR)/include/config.h: buildlib/config.h.in +$(BUILDDIR)/environment.mak: buildlib/environment.mak.in +$(BUILDDIR)/makefile: buildlib/makefile.in diff --git a/apt/README.RPM b/apt/README.RPM new file mode 100644 index 0000000..46a7d7c --- /dev/null +++ b/apt/README.RPM @@ -0,0 +1,41 @@ + + +RPM enabled APT + +WARNING +======= +This is an EARLY DEVELOPMENT release of apt-get. It might +F*&# UP YOUR SYSTEM BEYOND REPAIR. So use at your own +risk etc etc bla bla. + +DO NOT TRY TO COMPILE THIS ON A DEBIAN SYSTEM. +THIS IS A WORK IN PROGRESS AND WILL NOT WORK ON DEBIAN +RIGHT NOW. + +If you find a problem, contact kojima@conectiva.com.br, +not the original developers. + + +WTF is this?? +============= + +This is a port of debian's apt tools to RPM based +distro (at least Conectiva). apt-get is an advanced +package management utility frontend (dpkg in debian, +rpm in Conectiva and similars), which allows you to easily +perform package installation, upgrading and removal. +Dependencies are automatically handled, so if you +try to install a package that needs others to be installed, +it will download all needed packages and install them. + + +How to Use It +============= + +The manpages are properly updated, but if you +want simpler/friendlier documentation, you can +get the APT+RPM HOWTO at: +http://bazar.conectiva.com.br/~godoy/apt-howto/ + + + diff --git a/apt/README.make b/apt/README.make new file mode 100644 index 0000000..7fd6ae5 --- /dev/null +++ b/apt/README.make @@ -0,0 +1,114 @@ +The Make System +~~~ ~~~~ ~~~~~~ +To compile this program you require GNU Make. In fact you probably need +GNU Make 3.76.1 or newer. The makefiles contained make use of many +GNU Make specific features and will not run on other makes. + +The make system has a number of interesting properties that are not found +in other systems such as automake or the GNU makefile standards. In +general some semblance of expectedness is kept so as not to be too +surprising. Basically the following will work as expected: + + ./configure + make + or + cd build + ../configure + make + +There are a number of other things that are possible that may make software +development and software packaging simpler. The first of these is the +environment.mak file. When configure is run it creates an environment.mak +file in the build directory. This contains -all- configurable parameters +for all of the make files in all of the subdirectories. Changing one +of these parameters will have an immediate effect. The use of makefile.in +and configure substitutions across build makefiles is not used at all. + +Furthermore, the make system runs with a current directory equal to the +source directory irregardless of the destination directory. This means +#include "" and #include <> work as epected and more importantly +running 'make' in the source directory will work as expected. The +environment variable or make parameter 'BUILD' set the build directory. +It may be an absolute path or a path relative to the top level directory. +By default build/ will be used with a fall back to ./ This means +you can get all the advantages of a build directory without having to +cd into it to edit your source code! + +The make system also performs dependency generation on the fly as the +compiler runs. This is extremely fast and accurate. There is however +one failure condition that occures when a header file is erased. In +this case you should run make clean to purge the .o and .d files to +rebuild. + +The final significant deviation from normal make practicies is +in how the build directory is managed. It is not mearly a mirror of +the source directory but is logically divided in the following manner + bin/ + methods/ + doc/ + examples/ + include/ + apt-pkg/ + deity/ + obj/ + apt-pkg/ + deity/ + cmndline/ + [...] +Only .o and .d files are placed in the obj/ subdirectory. The final compiled +binaries are placed in bin, published headers for inter-component linking +are placed in include/ and documentation is generated into doc/. This means +all runnable programs are within the bin/ directory, a huge benifit for +debugging inter-program relationships. The .so files are also placed in +bin/ for simplicity. + +By default make is put into silent mode. During operation there should be +no shell or compiler messages only status messages from the makefiles, +if any pop up that indicates there may be a problem with your environment. +For debugging you can disable this by setting NOISY=1, ala + make NOISY=1 + +Using the makefiles +~~~~~ ~~~ ~~~~~~~~~ +The makefiles for the components are really simple. The complexity is hidden +within the buildlib/ directory. Each makefile defines a set of make variables +for the bit it is going to make then includes a makefile fragment from +the buildlib/. This fragment generates the necessary rules based on the +originally defined variables. This process can be repeated as many times as +necessary for as many programs or libraries as are in the directory. + +Many of the make fragments have some useful properties involving sub +directories and other interesting features. They are more completely +described in the fragment code in buildlib. Some tips on writing fragments +are included in buildlib/defaults.mak + +The fragments are NEVER processed by configure, so if you make changes to +them they will have an immediate effect. + +Autoconf +~~~~~~~~ +Straight out of CVS you have to initialize autoconf. This requires +automake (I really don't know why) and autoconf and requires doing + aclocal -I buidlib + autoconf +[Altertatively you can run make startup in the top level build dir] + +Autoconf is configured to do some basic system probes for optional and +required functionality and generate an environment.mak and include/config.h +from it's findings. It will then write a 'makefile' and run make dirs to +create the output directory tree. + +It is not my belief that autoconf should be used to generate substantial +source code markup to escape OS problems. If an OS problem does crop up +it can likely be corrected by installing the correct files into the +build include/ dir and perhaps writing some replacement code and +linking it in. To the fullest extent possible the source code should conform +to standards and not cater to broken systems. + +Autoconf will also wite a makefile into the top level of the build dir, +this simply acts as a wrapper to the main top level make in the source tree. +There is one big warning, you can't use both this make file and the +ones in the top level tree. Make is not able to resolve rules that +go to the same file through different paths and this will confuse the +depends mechanism. I recommend always using the makefiles in the +source directory and exporting BUILD. diff --git a/apt/REPOSITORIO-APT-HOWTO b/apt/REPOSITORIO-APT-HOWTO new file mode 100644 index 0000000..7a548b4 --- /dev/null +++ b/apt/REPOSITORIO-APT-HOWTO @@ -0,0 +1,117 @@ + + +Repositуrio de APT HOWTO + + +** Ingredientes + +- 1 mбquina com acesso rбpido а rede e bastante largura de banda +- 1 servidor de ftp (anфnimo) ou http rodando + +** Modo de Preparo + +1) Vб ao diretуrio raiz do servidor de ftp/http +2) Crie a seguinte estrutura de diretуrios nele: + +/SRPMS/ +/conectiva/RPMS./ +/conectiva/RPMS./ + ... +/conectiva/RPMS./ +/conectiva/base/ + +Vocк pode substituir pela versгo da distribuiзгo +que serб disponibilizada ou se vocк estiver disponibilizando +algum outro software, a versгo da distribuiзгo a que se destinam +os pacotes. + +... sгo os diretуrios dos componentes da distribuiзгo +e podem ser qualquer string. + +No diretуrio SRPMS devem estar contidos os srpms dos pacotes +do repositуrio. + +3) Crie os arquivos de нndice do apt (os pkglists) no diretуrio base. +Para isso, vб ao diretуrio base e execute o seguinte comando para +cada componente: + +genpkglist / + +Onde: + +/ й o caminho completo atй o topo do diretуrio onde +estб o repositуrio + + й o nome do componente. + +Repita a operaзгo para cada um dos componentes que vocк criou. + +4) Comprima os arquivos de нndice com gzip. + +5) Distribua a linha do sources.list para o seu repositуrio. Ela +tem o seguinte formato: + +rpm URL/ /conectiva ... + ^ ^ ^ ^ ^ ^ ^ + | | | +------+------+-----+- Nomes dos + | | | componentes + | | | + | | versao da distribuiзгo e nome da distribuiзгo + | | + | URL para o diretуrio raiz do repositуrio + | + Tipo de distribuiзгo. No caso, rpm + +** Exemplos: + +## Quer se fazer um repositуrio de pacotes para o Conectiva 6.0, na mбquina +repo.conectiva.com.br, usando http: + +cd /home/httpd +mkdir -p coisas/6.0 +cd coisas/6.0 +mkdir SRPMS +mkdir -p conectiva/RPMS.bla +mkdir -p conectiva/base +cp /meus/pacotes/*src.rpm SRPMS +cp /meus/pacotes/*i386.rpm conectiva/RPMS.bla +cd conectiva/base +genpkglist /home/httpd/coisas/6.0/conectiva bla +gzip pkglist.bla + +Em sources.list deve se adicionar: + +rpm http://repo.conectiva.com.br/coisas 6.0/conectiva bla + + +## Quer se fazer um repositуrio de pacotes para a distribuiзгo RedRat 20.0, +em bla.redrat.com, usando ftp: + +cd /home/ftp/pub +mkdir -p stuff/20.0 +cd stuff/20.0 +mkdir SRPMS +mkdir -p redrat/RPMS.1 +mkdir -p redrat/RPMS.2 +mkdir -p redrat/base +cp /tmp/pacotes*src.rpm SRPMS +cp redrat/RPMS.1 +cp redrat/RPMS.2 +cd redrat/base +genpkglist /home/ftp/stuff/20.0/redrat 1 +genpkglist /home/ftp/stuff/20.0/redrat 2 +gzip pkglist.1 +gzip pkglist.2 + +Em sources.list deve se adicionar: + +rpm ftp://bla.redrat.com/pub/stuff 20.0/redrat 1 2 + + + + + + + + + diff --git a/apt/TODO b/apt/TODO new file mode 100644 index 0000000..ed746b3 --- /dev/null +++ b/apt/TODO @@ -0,0 +1,6 @@ +- check support for installation of packages scattered across multiple CDs +- port the authentication stuff to the aliencode branch of APT +- port the RPM support to the aliencode branch of APT +- rewrite rpm repository maintenance tools +- package "hold"ing +- package ignoring (exclude from apt-get check) diff --git a/apt/apt-pkg/CVS/Entries b/apt/apt-pkg/CVS/Entries new file mode 100644 index 0000000..4ba56bb --- /dev/null +++ b/apt/apt-pkg/CVS/Entries @@ -0,0 +1,43 @@ +/init.cc/1.16/Wed Aug 1 21:35:12 2001// +D/cnc//// +D/contrib//// +D/deb//// +D/rpm//// +/acquire-method.cc/1.4/Fri Aug 10 13:58:21 2001// +/acquire-method.h/1.2/Fri Aug 10 13:58:24 2001// +/acquire-worker.cc/1.2/Fri Aug 10 13:58:24 2001// +/acquire-worker.h/1.1.1.1/Fri Aug 10 13:58:24 2001// +/acquire.cc/1.3/Fri Aug 10 13:58:24 2001// +/acquire.h/1.2/Fri Aug 10 13:58:26 2001// +/algorithms.h/1.1.1.1/Fri Aug 10 13:58:29 2001// +/cachefile.cc/1.8/Fri Aug 10 13:58:29 2001// +/cachefile.h/1.4/Fri Aug 10 13:58:29 2001// +/cacheiterators.h/1.2/Fri Aug 10 13:58:31 2001// +/clean.cc/1.2/Fri Aug 10 13:58:31 2001// +/clean.h/1.1.1.1/Fri Aug 10 13:58:31 2001// +/init.h/1.1.1.1/Fri Aug 10 13:58:33 2001// +/makefile/1.12/Fri Aug 10 13:58:33 2001// +/orderlist.cc/1.4/Fri Aug 10 13:58:34 2001// +/orderlist.h/1.1.1.1/Fri Aug 10 13:58:34 2001// +/packagemanager.h/1.2/Fri Aug 10 13:59:57 2001// +/pkgcache.cc/1.11/Fri Aug 10 14:00:19 2001// +/pkgcache.h/1.2/Fri Aug 10 14:00:19 2001// +/pkgcachegen.h/1.5/Fri Aug 10 14:00:20 2001// +/pkgrecords.cc/1.5/Fri Aug 10 14:00:20 2001// +/pkgrecords.h/1.3/Fri Aug 10 14:00:20 2001// +/srcrecords.cc/1.4/Fri Aug 10 14:00:21 2001// +/srcrecords.h/1.2/Fri Aug 10 14:00:21 2001// +/systemfactory.cc/1.8/Fri Aug 10 14:00:23 2001// +/systemfactory.h/1.5/Fri Aug 10 14:00:23 2001// +/tagfile.cc/1.2/Fri Aug 10 14:00:23 2001// +/tagfile.h/1.1.1.1/Fri Aug 10 14:00:23 2001// +/version.cc/1.4/Fri Aug 10 14:00:23 2001// +/acquire-item.cc/1.20/Tue Nov 13 14:24:16 2001// +/acquire-item.h/1.6/Tue Nov 13 14:24:16 2001// +/sourcelist.cc/1.25/Tue Nov 13 14:24:16 2001// +/sourcelist.h/1.9/Tue Nov 13 14:24:16 2001// +/algorithms.cc/1.11/Fri Nov 16 01:13:06 2001// +/depcache.cc/1.20/Fri Nov 16 01:13:06 2001// +/depcache.h/1.3/Fri Nov 16 01:13:06 2001// +/packagemanager.cc/1.15/Fri Nov 16 01:13:06 2001// +/pkgcachegen.cc/1.24/Wed Mar 6 17:17:10 2002// diff --git a/apt/apt-pkg/CVS/Repository b/apt/apt-pkg/CVS/Repository new file mode 100644 index 0000000..33b04e4 --- /dev/null +++ b/apt/apt-pkg/CVS/Repository @@ -0,0 +1 @@ +rapt/apt-pkg diff --git a/apt/apt-pkg/CVS/Root b/apt/apt-pkg/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/apt-pkg/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/apt-pkg/acquire-item.cc b/apt/apt-pkg/acquire-item.cc new file mode 100644 index 0000000..e5be322 --- /dev/null +++ b/apt/apt-pkg/acquire-item.cc @@ -0,0 +1,1016 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire-item.cc,v 1.20 2001/11/12 16:34:00 kojima Exp $ +/* ###################################################################### + + Acquire Item - Item to acquire + + Each item can download to exactly one file at a time. This means you + cannot create an item that fetches two uri's to two files at the same + time. The pkgAcqIndex class creates a second class upon instantiation + to fetch the other index files because of this. + + ##################################################################### + */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/acquire-item.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + + /*}}}*/ + +// Acquire::Item::Item - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Item::Item(pkgAcquire *Owner) : Owner(Owner), FileSize(0), + PartialSize(0), Mode(0), ID(0), Complete(false), + Local(false), QueueCounter(0) +{ + Owner->Add(this); + Status = StatIdle; +} + /*}}}*/ +// Acquire::Item::~Item - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Item::~Item() +{ + Owner->Remove(this); +} + /*}}}*/ +// Acquire::Item::Failed - Item failed to download /*{{{*/ +// --------------------------------------------------------------------- +/* We return to an idle state if there are still other queues that could + fetch this object */ +void pkgAcquire::Item::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +{ + Status = StatIdle; + ErrorText = LookupTag(Message,"Message"); + if (QueueCounter <= 1) + { + /* This indicates that the file is not available right now but might + be sometime later. If we do a retry cycle then this should be + retried [CDROMs] */ + if (Cnf->LocalOnly == true && + StringToBool(LookupTag(Message,"Transient-Failure"),false) == true) + { + Status = StatIdle; + Dequeue(); + return; + } + + Status = StatError; + Dequeue(); + } +} + /*}}}*/ +// Acquire::Item::Start - Item has begun to download /*{{{*/ +// --------------------------------------------------------------------- +/* Stash status and the file size. Note that setting Complete means + sub-phases of the acquire process such as decompresion are operating */ +void pkgAcquire::Item::Start(string /*Message*/,unsigned long Size) +{ + Status = StatFetching; + if (FileSize == 0 && Complete == false) + FileSize = Size; +} + /*}}}*/ +// Acquire::Item::Done - Item downloaded OK /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcquire::Item::Done(string Message,unsigned long Size,string, + pkgAcquire::MethodConfig *Cnf) +{ + // We just downloaded something.. + string FileName = LookupTag(Message,"Filename"); + if (Complete == false && FileName == DestFile) + { + if (Owner->Log != 0) + Owner->Log->Fetched(Size,atoi(LookupTag(Message,"Resume-Point","0").c_str())); + } + + if (FileSize == 0) + FileSize= Size; + + Status = StatDone; + ErrorText = string(); + Owner->Dequeue(this); +} + /*}}}*/ +// Acquire::Item::Rename - Rename a file /*{{{*/ +// --------------------------------------------------------------------- +/* This helper function is used by alot of item methods as thier final + step */ +void pkgAcquire::Item::Rename(string From,string To) +{ + if (rename(From.c_str(),To.c_str()) != 0) + { + char S[300]; + snprintf(S,sizeof(S),"rename failed, %s (%s -> %s).",strerror(errno), + From.c_str(),To.c_str()); + Status = StatError; + ErrorText = S; + } +} + /*}}}*/ +bool pkgAcquire::Item::RecheckFile(string path, string MD5, unsigned long Size) +{ + struct stat Buf; + + if (stat(path.c_str(),&Buf) == 0) + { + if (Buf.st_size != Size) + { + if (_config->FindB("Acquire::Verbose", false) == true) + _error->Warning(_("Size of %s did not match what's in the hashfile and was redownloaded."), + path.c_str()); + return false; + } + + MD5Summation md5sum = MD5Summation(); + FileFd file = FileFd(path, FileFd::ReadOnly); + + md5sum.AddFD(file.Fd(), file.Size()); + if (md5sum.Result().Value() != MD5) + { + if (_config->FindB("Acquire::Verbose", false) == true) + _error->Warning(_("MD5 of %s did not match what's int the hashfile and was redownloaded."), + path.c_str()); + return false; + } + file.Close(); + } + + return true; +} + + +// AcqIndex::AcqIndex - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* The package file is added to the queue and a second class is + instantiated to fetch the revision file */ +pkgAcqIndex::pkgAcqIndex(pkgAcquire *Owner,const pkgSourceList::Item *Location) : + Item(Owner), Location(Location) +{ + Decompression = false; + Erase = false; + + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(Location->PackagesURI()); + + // Create the item + Desc.URI = Location->PackagesURI()+_config->Find("Acquire::ComprExtension"); + Desc.Description = Location->PackagesInfo(); + Desc.Owner = this; + + // If we're verifying authentication, check whether the size and + // MD5 matches, if not, delete the cached files and force redownload + string fname = Location->PackagesURI(true); + string hash; + unsigned int size; + + if (Location->Repository->MD5HashForFile(fname, hash, size) + && !hash.empty() && size != 0) + { + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(Location->PackagesURI()); + + if (!RecheckFile(FinalFile, hash, size)) + { + unlink(FinalFile.c_str()); + unlink(DestFile.c_str()); + } + } + + // Set the short description to the archive component + if (Location->Dist[Location->Dist.size() - 1] == '/') + Desc.ShortDesc = Location->Dist; + else + Desc.ShortDesc = Location->Dist + '/' + Location->Section; + + QueueURI(Desc); + + // Create the Release fetch class + new pkgAcqIndexRel(Owner,Location); +} + /*}}}*/ +// AcqIndex::Custom600Headers - Insert custom request headers /*{{{*/ +// --------------------------------------------------------------------- +/* The only header we use is the last-modified header. */ +string pkgAcqIndex::Custom600Headers() +{ + string Final = _config->FindDir("Dir::State::lists"); + Final += URItoFileName(Location->PackagesURI()); + + struct stat Buf; + if (stat(Final.c_str(),&Buf) != 0) + return "\nIndex-File: true"; + + return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); +} + /*}}}*/ +// AcqIndex::Done - Finished a fetch /*{{{*/ +// --------------------------------------------------------------------- +/* This goes through a number of states.. On the initial fetch the + method could possibly return an alternate filename which points + to the uncompressed version of the file. If this is so the file + is copied into the partial directory. In all other cases the file + is decompressed with a gzip uri. */ +void pkgAcqIndex::Done(string Message,unsigned long Size,string MD5, + pkgAcquire::MethodConfig *Cfg) +{ + Item::Done(Message,Size,MD5,Cfg); + + if (Decompression == true) + { + unsigned int size; + string hash; + + string fname = Location->PackagesURI(true); + + if (!Location->Repository->MD5HashForFile(fname, hash, size)) + { + Status = StatAuthError; + ErrorText = "Unauthenticated file"; + return; + } + // Check the size + if (size != 0 && Size != size) + { + Status = StatAuthError; + if (_config->FindB("Debug::pkgAcquire::Auth", false)) { + cout << "size mismatch: " << size << "!=" <FindB("Debug::pkgAcquire::Auth", false)) { + cout << "md5 mismatch: " << hash << "!=" << MD5 << endl; + } + Rename(DestFile,DestFile + ".FAILED"); + return; + } + + // Done, move it into position + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(Location->PackagesURI()); + Rename(DestFile,FinalFile); + + /* We restore the original name to DestFile so that the clean operation + will work OK */ + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(Location->PackagesURI()); + + // Remove the compressed version. + if (Erase == true) + unlink(DestFile.c_str()); + + return; + } + + Erase = false; + Complete = true; + + // Handle the unzipd case + string FileName = LookupTag(Message,"Alt-Filename"); + if (FileName.empty() == false) + { + // The files timestamp matches + if (StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true) + return; + + Decompression = true; + Local = true; + DestFile += ".decomp"; + Desc.URI = "copy:" + FileName; + QueueURI(Desc); + Mode = "copy"; + return; + } + + FileName = LookupTag(Message,"Filename"); + if (FileName.empty() == true) + { + Status = StatError; + ErrorText = "Method gave a blank filename"; + } + + // The files timestamp matches + if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true) + return; + + unsigned int size; + string hash; + + string fname = Location->PackagesURI(true) + + _config->Find("Acquire::ComprExtension"); + + if (!Location->Repository->MD5HashForFile(fname, hash, size)) + { + Status = StatAuthError; + ErrorText = "Unauthenticated file"; + return; + } + + // Check the size + if (size != 0 && Size != size) + { + Status = StatAuthError; + if (_config->FindB("Debug::pkgAcquire::Auth", false)) { + cout << "compressed size: " << size << "!=" <FindB("Debug::pkgAcquire::Auth", false)) { + cout << "compressed md5: " << hash << "!=" << MD5 << endl; + } + Rename(DestFile,DestFile + ".FAILED"); + return; + } + + if (FileName == DestFile) + Erase = true; + else + Local = true; + + Decompression = true; + DestFile += ".decomp"; + Desc.URI = "gzip:" + FileName,Location->PackagesInfo(); + QueueURI(Desc); + Mode = "gzip"; +} + /*}}}*/ + +// AcqHashes::AcqHashes - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* The package file is added to the queue and a second class is + instantiated to fetch the revision file */ +pkgAcqHashes::pkgAcqHashes(pkgAcquire *Owner, + pkgSourceList::RepositoryItem *Location) : + Item(Owner), Location(Location) +{ + Retries = _config->FindI("Acquire::Retries",0); + + Authentication = false; + + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(Location->HashesURI()); + + // Remove the file, it must be always downloaded + unlink(DestFile.c_str()); + string OldFile = _config->FindDir("Dir::State::lists"); + OldFile += URItoFileName(Location->HashesURI()); + unlink(OldFile.c_str()); + + // Create the item + Desc.URI = Location->HashesURI() + ".gpg"; + Desc.Description = Location->HashesInfo(); + Desc.Owner = this; + + Desc.ShortDesc = Location->Dist; + + QueueURI(Desc); +} + /*}}}*/ +// AcqHashes::Done - Finished a fetch /*{{{*/ +// --------------------------------------------------------------------- +void pkgAcqHashes::Done(string Message,unsigned long Size,string MD5, + pkgAcquire::MethodConfig *Cfg) +{ + Item::Done(Message,Size,MD5,Cfg); + + if (Authentication == true) + { + // Done, move it into position + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(Location->HashesURI()); + Rename(DestFile,FinalFile); + + /* We restore the original name to DestFile so that the clean operation + will work OK */ + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(Location->HashesURI()); + + string SignerFingerprint = LookupTag(Message,"Signature-Key"); + + if (SignerFingerprint != Location->Vendor->Fingerprint) + { + Status = StatError; + ErrorText = _("Hashfile signer is not who it's supposed to be " + "(expected ")+Location->Vendor->Fingerprint + +_(", got ")+SignerFingerprint+")"; + return; + } + + // Update the hashes and file sizes for this repository + if (!Location->UpdateHashes(FinalFile)) { + Status = StatError; + ErrorText = "Could not stash MD5 hashes to index files"; + } + + return; + } + + Complete = true; + + string FileName = LookupTag(Message,"Filename"); + if (FileName.empty() == true) + { + Status = StatError; + ErrorText = "Method gave a blank filename"; + } + + if (FileName != DestFile) + Local = true; + + Authentication = true; + DestFile += ".extracted"; + Desc.URI = "gpg:" + FileName,Location->HashesInfo(); + QueueURI(Desc); + Mode = "gpg"; +} + /*}}}*/ +// AcqHashes::Failed - Failure handler /*{{{*/ +// --------------------------------------------------------------------- +/* Here we try other sources */ +void pkgAcqHashes::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +{ + ErrorText = LookupTag(Message,"Message"); + + // This is the retry counter + if (Retries != 0 && + Cnf->LocalOnly == false && + StringToBool(LookupTag(Message,"Transient-Failure"),false) == true) + { + Retries--; + // wait a little before retrying + sleep(1); + QueueURI(Desc); + return; + } + + Item::Failed(Message,Cnf); +} + /*}}}*/ +// AcqIndexRel::pkgAcqIndexRel - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* The Release file is added to the queue */ +pkgAcqIndexRel::pkgAcqIndexRel(pkgAcquire *Owner, + const pkgSourceList::Item *Location) : + Item(Owner), Location(Location) +{ + Retries = _config->FindI("Acquire::Retries",0); + + DestFile = _config->FindDir("Dir::State::lists") + "partial/"; + DestFile += URItoFileName(Location->ReleaseURI()); + + // Create the item + Desc.URI = Location->ReleaseURI(); + Desc.Description = Location->ReleaseInfo(); + Desc.Owner = this; + + // If we're verifying authentication, check whether the size and + // MD5 matches, if not, delete the cached files and force redownload + string hash; + unsigned int size; + if (Location->Repository->MD5HashForFile(Location->ReleaseURI(true), hash, size) + && !hash.empty() && size != 0) + { + string FinalFile = _config->FindDir("Dir::State::lists"); + FinalFile += URItoFileName(Location->ReleaseURI()); + + if (!RecheckFile(FinalFile, hash, size)) + { + unlink(FinalFile.c_str()); + unlink(DestFile.c_str()); + } + } + + // Set the short description to the archive component + if (Location->Dist[Location->Dist.size() - 1] == '/') + Desc.ShortDesc = Location->Dist; + else + Desc.ShortDesc = Location->Dist + '/' + Location->Section; + + QueueURI(Desc); +} + /*}}}*/ +// AcqIndexRel::Custom600Headers - Insert custom request headers /*{{{*/ +// --------------------------------------------------------------------- +/* The only header we use is the last-modified header. */ +string pkgAcqIndexRel::Custom600Headers() +{ + string Final = _config->FindDir("Dir::State::lists"); + Final += URItoFileName(Location->ReleaseURI()); + + struct stat Buf; + if (stat(Final.c_str(),&Buf) != 0) + return "\nIndex-File: true"; + + return "\nIndex-File: true\nLast-Modified: " + TimeRFC1123(Buf.st_mtime); +} + /*}}}*/ +// AcqIndexRel::Done - Item downloaded OK /*{{{*/ +// --------------------------------------------------------------------- +/* The release file was not placed into the download directory then + a copy URI is generated and it is copied there otherwise the file + in the partial directory is moved into .. and the URI is finished. */ +void pkgAcqIndexRel::Done(string Message,unsigned long Size,string MD5, + pkgAcquire::MethodConfig *Cfg) +{ + Item::Done(Message,Size,MD5,Cfg); + + string FileName = LookupTag(Message,"Filename"); + if (FileName.empty() == true) + { + Status = StatError; + ErrorText = "Method gave a blank filename"; + return; + } + + + + unsigned int size; + string hash; + + string fname = Location->ReleaseURI(true); + + if (!Location->Repository->MD5HashForFile(fname, hash, size)) + { + Status = StatAuthError; + ErrorText = "Unauthenticated file"; + return; + } + + // Check the size + if (size != 0 && Size != 0 && Size != size) + { + if (_config->FindB("Debug::pkgAcquire::Auth", false)) { + cout << "size: " << size << "!=" <FindB("Debug::pkgAcquire::Auth", false)) { + cout << "md5: " << hash << "!=" <FindDir("Dir::State::lists"); + FinalFile += URItoFileName(Location->ReleaseURI()); + Rename(DestFile,FinalFile); +} + /*}}}*/ +// AcqIndexRel::Failed - Silence failure messages for missing rel files /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqIndexRel::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +{ + + ErrorText = LookupTag(Message,"Message"); + + // This is the retry counter + if (Retries != 0 && + Cnf->LocalOnly == false && + StringToBool(LookupTag(Message,"Transient-Failure"),false) == true) + { + Retries--; + // wait a little before retrying + sleep(1); + QueueURI(Desc); + return; + } + + + if (Cnf->LocalOnly == true || + StringToBool(LookupTag(Message,"Transient-Failure"),false) == false) + { + // Ignore this + Status = StatDone; + Complete = false; + Dequeue(); + return; + } + + Item::Failed(Message,Cnf); +} + /*}}}*/ + +// AcqArchive::AcqArchive - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* This just sets up the initial fetch environment and queues the first + possibilitiy */ +pkgAcqArchive::pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources, + pkgRecords *Recs,pkgCache::VerIterator const &Version, + string &StoreFilename) : + Item(Owner), Version(Version), Sources(Sources), Recs(Recs), + StoreFilename(StoreFilename), Vf(Version.FileList()) +{ + Retries = _config->FindI("Acquire::Retries",0); + + if (Version.Arch() == 0) + { + _error->Error("I wasn't able to locate file for the %s package. " + "This might mean you need to manually fix this package. (due to missing arch)", + Version.ParentPkg().Name()); + return; + } + + /* We need to find a filename to determine the extension. We make the + assumption here that all the available sources for this version share + the same extension.. */ + // Skip not source sources, they do not have file fields. + for (; Vf.end() == false; Vf++) + { + if ((Vf.File()->Flags & pkgCache::Flag::NotSource) != 0) + continue; + break; + } + + // Does not really matter here.. we are going to fail out below + if (Vf.end() != true) + { + // If this fails to get a file name we will bomb out below. + pkgRecords::Parser &Parse = Recs->Lookup(Vf); + if (_error->PendingError() == true) + return; + + // Generate the final file name as: package_version_arch.foo + StoreFilename = QuoteString(Version.ParentPkg().Name(),"_:") + '_' + + QuoteString(Version.VerStr(),"_:") + '_' + + QuoteString(Version.Arch(),"_:.") + + "." + flExtension(Parse.FileName()); + } + + // Select a source + if (QueueNext() == false && _error->PendingError() == false) + _error->Error("I wasn't able to locate file for the %s package. " + "This might mean you need to manually fix this package.", + Version.ParentPkg().Name()); +} + /*}}}*/ +// AcqArchive::QueueNext - Queue the next file source /*{{{*/ +// --------------------------------------------------------------------- +/* This queues the next available file version for download. It checks if + the archive is already available in the cache and stashs the MD5 for + checking later. */ +bool pkgAcqArchive::QueueNext() +{ + for (; Vf.end() == false; Vf++) + { + // Ignore not source sources + if ((Vf.File()->Flags & pkgCache::Flag::NotSource) != 0) + continue; + + // Try to cross match against the source list + string PkgFile = flNotDir(Vf.File().FileName()); + pkgSourceList::const_iterator Location; + for (Location = Sources->begin(); Location != Sources->end(); Location++) + if (PkgFile == URItoFileName(Location->PackagesURI())) + break; + + if (Location == Sources->end()) + continue; + + // Grab the text package record + pkgRecords::Parser &Parse = Recs->Lookup(Vf); + if (_error->PendingError() == true) + return false; + + PkgFile = Parse.FileName(); + MD5 = Parse.MD5Hash(); + if (PkgFile.empty() == true) + return _error->Error("The package index files are corrupted. No Filename: " + "field for package %s." + ,Version.ParentPkg().Name()); + + // See if we already have the file. (Legacy filenames) + FileSize = Version->Size; + string FinalFile = _config->FindDir("Dir::Cache::Archives") + flNotDir(PkgFile); + struct stat Buf; + if (stat(FinalFile.c_str(),&Buf) == 0) + { + // Make sure the size matches + if ((unsigned)Buf.st_size == Version->Size) + { + Complete = true; + Local = true; + Status = StatDone; + StoreFilename = DestFile = FinalFile; + return true; + } + + /* Hmm, we have a file and its size does not match, this means it is + an old style mismatched arch */ + unlink(FinalFile.c_str()); + } + + // Check it again using the new style output filenames + FinalFile = _config->FindDir("Dir::Cache::Archives") + flNotDir(StoreFilename); + if (stat(FinalFile.c_str(),&Buf) == 0) + { + // Make sure the size matches + if ((unsigned)Buf.st_size == Version->Size) + { + Complete = true; + Local = true; + Status = StatDone; + StoreFilename = DestFile = FinalFile; + return true; + } + + /* Hmm, we have a file and its size does not match, this shouldnt + happen.. */ + unlink(FinalFile.c_str()); + } + + DestFile = _config->FindDir("Dir::Cache::Archives") + "partial/" + flNotDir(StoreFilename); + + // Check the destination file + if (stat(DestFile.c_str(),&Buf) == 0) + { + // Hmm, the partial file is too big, erase it + if ((unsigned)Buf.st_size > Version->Size) + unlink(DestFile.c_str()); + else + PartialSize = Buf.st_size; + } + + // Create the item + Desc.URI = Location->ArchiveURI(PkgFile); + Desc.Description = Location->ArchiveInfo(Version); + Desc.Owner = this; + Desc.ShortDesc = Version.ParentPkg().Name(); + QueueURI(Desc); + + Vf++; + return true; + } + return false; +} + /*}}}*/ +// AcqArchive::Done - Finished fetching /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqArchive::Done(string Message,unsigned long Size,string Md5Hash, + pkgAcquire::MethodConfig *Cfg) +{ + Item::Done(Message,Size,Md5Hash,Cfg); + + // Check the size + if (Size != Version->Size) + { + Status = StatError; + ErrorText = "Size mismatch"; + return; + } + + // Check the md5 + if (Md5Hash.empty() == false && MD5.empty() == false) + { + if (Md5Hash != MD5) + { + Status = StatError; + ErrorText = "MD5Sum mismatch"; + Rename(DestFile,DestFile + ".FAILED"); + return; + } + } + + // Grab the output filename + string FileName = LookupTag(Message,"Filename"); + if (FileName.empty() == true) + { + Status = StatError; + ErrorText = "Method gave a blank filename"; + return; + } + + Complete = true; + + // Reference filename + if (FileName != DestFile) + { + StoreFilename = DestFile = FileName; + Local = true; + return; + } + + // Done, move it into position + string FinalFile = _config->FindDir("Dir::Cache::Archives"); + FinalFile += flNotDir(StoreFilename); + Rename(DestFile,FinalFile); + + StoreFilename = DestFile = FinalFile; + Complete = true; +} + /*}}}*/ +// AcqArchive::Failed - Failure handler /*{{{*/ +// --------------------------------------------------------------------- +/* Here we try other sources */ +void pkgAcqArchive::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +{ + ErrorText = LookupTag(Message,"Message"); + if (QueueNext() == false) + { + // This is the retry counter + if (Retries != 0 && + Cnf->LocalOnly == false && + StringToBool(LookupTag(Message,"Transient-Failure"),false) == true) + { + Retries--; + // wait a little before retrying + sleep(1); + Vf = Version.FileList(); + if (QueueNext() == true) + return; + } + StoreFilename = string(); + Item::Failed(Message,Cnf); + } +} + /*}}}*/ +// AcqArchive::Finished - Fetching has finished, tidy up /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqArchive::Finished() +{ + if (Status == pkgAcquire::Item::StatDone && + Complete == true) + return; + StoreFilename = string(); +} + /*}}}*/ +// AcqFile::pkgAcqFile - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* The file is added to the queue */ +pkgAcqFile::pkgAcqFile(pkgAcquire *Owner,string URI,string MD5, + unsigned long Size,string Dsc,string ShortDesc) : + Item(Owner), Md5Hash(MD5) +{ + Retries = _config->FindI("Acquire::Retries",0); + + DestFile = flNotDir(URI); + + // Create the item + Desc.URI = URI; + Desc.Description = Dsc; + Desc.Owner = this; + + // Set the short description to the archive component + Desc.ShortDesc = ShortDesc; + + // Get the transfer sizes + FileSize = Size; + struct stat Buf; + if (stat(DestFile.c_str(),&Buf) == 0) + { + // Hmm, the partial file is too big, erase it + if ((unsigned)Buf.st_size > Size) + unlink(DestFile.c_str()); + else + PartialSize = Buf.st_size; + } + + QueueURI(Desc); +} + /*}}}*/ +// AcqFile::Done - Item downloaded OK /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqFile::Done(string Message,unsigned long Size,string MD5, + pkgAcquire::MethodConfig *Cnf) +{ + // Check the md5 + if (Md5Hash.empty() == false && MD5.empty() == false) + { + if (Md5Hash != MD5) + { + Status = StatError; + ErrorText = "MD5Sum mismatch"; + Rename(DestFile,DestFile + ".FAILED"); + return; + } + } + + Item::Done(Message,Size,MD5,Cnf); + + string FileName = LookupTag(Message,"Filename"); + if (FileName.empty() == true) + { + Status = StatError; + ErrorText = "Method gave a blank filename"; + return; + } + + Complete = true; + + // The files timestamp matches + if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true) + return; + + // We have to copy it into place + if (FileName != DestFile) + { + Local = true; + if (_config->FindB("Acquire::Source-Symlinks",true) == false || + Cnf->Removable == true) + { + Desc.URI = "copy:" + FileName; + QueueURI(Desc); + return; + } + + // Erase the file if it is a symlink so we can overwrite it + struct stat St; + if (lstat(DestFile.c_str(),&St) == 0) + { + if (S_ISLNK(St.st_mode) != 0) + unlink(DestFile.c_str()); + } + + // Symlink the file + if (symlink(FileName.c_str(),DestFile.c_str()) != 0) + { + ErrorText = "Link to " + DestFile + " failure "; + Status = StatError; + Complete = false; + } + } +} + /*}}}*/ +// AcqFile::Failed - Failure handler /*{{{*/ +// --------------------------------------------------------------------- +/* Here we try other sources */ +void pkgAcqFile::Failed(string Message,pkgAcquire::MethodConfig *Cnf) +{ + ErrorText = LookupTag(Message,"Message"); + + // This is the retry counter + if (Retries != 0 && + Cnf->LocalOnly == false && + StringToBool(LookupTag(Message,"Transient-Failure"),false) == true) + { + Retries--; + // wait a little before retrying + sleep(1); + QueueURI(Desc); + return; + } + + Item::Failed(Message,Cnf); +} + /*}}}*/ diff --git a/apt/apt-pkg/acquire-item.h b/apt/apt-pkg/acquire-item.h new file mode 100644 index 0000000..65dd9ae --- /dev/null +++ b/apt/apt-pkg/acquire-item.h @@ -0,0 +1,200 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire-item.h,v 1.6 2001/11/12 16:34:00 kojima Exp $ +/* ###################################################################### + + Acquire Item - Item to acquire + + When an item is instantiated it will add it self to the local list in + the Owner Acquire class. Derived classes will then call QueueURI to + register all the URI's they wish to fetch at the initial moment. + + Two item classes are provided to provide functionality for downloading + of Index files and downloading of Packages. + + A Archive class is provided for downloading .deb files. It does Md5 + checking and source location as well as a retry algorithm. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_ACQUIRE_ITEM_H +#define PKGLIB_ACQUIRE_ITEM_H + +#include +#include +#include + +#ifdef __GNUG__ +#pragma interface "apt-pkg/acquire-item.h" +#endif + +// Item to acquire +class pkgAcquire::Item +{ + protected: + bool RecheckFile(string path, string MD5, unsigned long Size); + + // Some private helper methods for registering URIs + pkgAcquire *Owner; + inline void QueueURI(ItemDesc &Item) + {Owner->Enqueue(Item);}; + inline void Dequeue() {Owner->Dequeue(this);}; + + // Safe rename function with timestamp preservation + void Rename(string From,string To); + + public: + + // State of the item + enum {StatIdle, StatFetching, StatDone, StatError, StatAuthError} Status; + string ErrorText; + unsigned long FileSize; + unsigned long PartialSize; + char *Mode; + unsigned long ID; + bool Complete; + bool Local; + + // Number of queues we are inserted into + unsigned int QueueCounter; + + // File to write the fetch into + string DestFile; + + // Action members invoked by the worker + virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); + virtual void Done(string Message,unsigned long Size,string Md5Hash, + pkgAcquire::MethodConfig *Cnf); + virtual void Start(string Message,unsigned long Size); + virtual string Custom600Headers() {return string();}; + virtual string DescURI() = 0; + virtual void Finished() {}; + + // Inquire functions + virtual string MD5Sum() {return string();}; + pkgAcquire *GetOwner() {return Owner;}; + + Item(pkgAcquire *Owner); + virtual ~Item(); +}; + +// Item class for index files +class pkgAcqIndex : public pkgAcquire::Item +{ + protected: + + const pkgSourceList::Item *Location; + bool Decompression; + bool Erase; + pkgAcquire::ItemDesc Desc; + unsigned int Retries; + + public: + + // Specialized action members + virtual void Done(string Message,unsigned long Size,string Md5Hash, + pkgAcquire::MethodConfig *Cnf); + virtual string Custom600Headers(); + virtual string DescURI() {return Location->PackagesURI();}; + + pkgAcqIndex(pkgAcquire *Owner,const pkgSourceList::Item *Location); +}; + +// Item class for index files +class pkgAcqIndexRel : public pkgAcquire::Item +{ + protected: + + const pkgSourceList::Item *Location; + pkgAcquire::ItemDesc Desc; + unsigned int Retries; + + public: + + // Specialized action members + virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); + virtual void Done(string Message,unsigned long Size,string Md5Hash, + pkgAcquire::MethodConfig *Cnf); + virtual string Custom600Headers(); + virtual string DescURI() {return Location->ReleaseURI();}; + + pkgAcqIndexRel(pkgAcquire *Owner,const pkgSourceList::Item *Location); +}; + +// Item class for archive files +class pkgAcqArchive : public pkgAcquire::Item +{ + protected: + + // State information for the retry mechanism + pkgCache::VerIterator Version; + pkgAcquire::ItemDesc Desc; + pkgSourceList *Sources; + pkgRecords *Recs; + string MD5; + string &StoreFilename; + pkgCache::VerFileIterator Vf; + unsigned int Retries; + + // Queue the next available file for download. + bool QueueNext(); + + public: + + // Specialized action members + virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); + virtual void Done(string Message,unsigned long Size,string Md5Hash, + pkgAcquire::MethodConfig *Cnf); + virtual string MD5Sum() {return MD5;}; + virtual string DescURI() {return Desc.URI;}; + virtual void Finished(); + + pkgAcqArchive(pkgAcquire *Owner,pkgSourceList *Sources, + pkgRecords *Recs,pkgCache::VerIterator const &Version, + string &StoreFilename); +}; + + +// Item class for index files +class pkgAcqHashes : public pkgAcquire::Item +{ + protected: + + bool Authentication; + pkgSourceList::RepositoryItem *Location; + pkgAcquire::ItemDesc Desc; + unsigned int Retries; + + public: + + // Specialized action members + virtual void Done(string Message,unsigned long Size,string Md5Hash, + pkgAcquire::MethodConfig *Cnf); + virtual string DescURI() {return Location->HashesURI();}; + virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); + + pkgAcqHashes(pkgAcquire *Owner, + pkgSourceList::RepositoryItem *Location); +}; + +// Fetch a generic file to the current directory +class pkgAcqFile : public pkgAcquire::Item +{ + pkgAcquire::ItemDesc Desc; + string Md5Hash; + unsigned int Retries; + + public: + + // Specialized action members + virtual void Failed(string Message,pkgAcquire::MethodConfig *Cnf); + virtual void Done(string Message,unsigned long Size,string Md5Hash, + pkgAcquire::MethodConfig *Cnf); + virtual string MD5Sum() {return Md5Hash;}; + virtual string DescURI() {return Desc.URI;}; + + pkgAcqFile(pkgAcquire *Owner,string URI,string MD5,unsigned long Size, + string Desc,string ShortDesc); +}; + +#endif diff --git a/apt/apt-pkg/acquire-method.cc b/apt/apt-pkg/acquire-method.cc new file mode 100644 index 0000000..1d43761 --- /dev/null +++ b/apt/apt-pkg/acquire-method.cc @@ -0,0 +1,442 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire-method.cc,v 1.4 2001/06/16 01:50:22 kojima Exp $ +/* ###################################################################### + + Acquire Method + + This is a skeleton class that implements most of the functionality + of a method and some usefull functions to make method implementation + simpler. The methods all derive this and specialize it. The most + complex implementation is the http method which needs to provide + pipelining, it runs the message engine at the same time it is + downloading files.. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/acquire-method.h" +#endif +#include +#include +#include +#include +#include + +#include +#include +#include + /*}}}*/ + +// AcqMethod::pkgAcqMethod - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* This constructs the initialization text */ +pkgAcqMethod::pkgAcqMethod(const char *Ver,unsigned long Flags) +{ + char S[300] = ""; + char *End = S; + strcat(End,"100 Capabilities\n"); + snprintf(End+strlen(End),sizeof(S),"Version: %s\n",Ver); + + if ((Flags & SingleInstance) == SingleInstance) + strcat(End,"Single-Instance: true\n"); + + if ((Flags & Pipeline) == Pipeline) + strcat(End,"Pipeline: true\n"); + + if ((Flags & SendConfig) == SendConfig) + strcat(End,"Send-Config: true\n"); + + if ((Flags & LocalOnly) == LocalOnly) + strcat(End,"Local-Only: true\n"); + + if ((Flags & NeedsCleanup) == NeedsCleanup) + strcat(End,"Needs-Cleanup: true\n"); + + if ((Flags & Removable) == Removable) + strcat(End,"Removable: true\n"); + strcat(End,"\n"); + + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); + + SetNonBlock(STDIN_FILENO,true); + + Queue = 0; + QueueBack = 0; +} + /*}}}*/ +// AcqMethod::Fail - A fetch has failed /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::Fail(bool Transient) +{ + string Err = "Undetermined Error"; + if (_error->empty() == false) + _error->PopMessage(Err); + _error->Discard(); + Fail(Err,Transient); +} + /*}}}*/ +// AcqMethod::Fail - A fetch has failed /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::Fail(string Err,bool Transient) +{ + // Strip out junk from the error messages + for (char *I = Err.begin(); I != Err.end(); I++) + { + if (*I == '\r') + *I = ' '; + if (*I == '\n') + *I = ' '; + } + + char S[1024]; + if (Queue != 0) + { + snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: %s\n" + "Message: %s\n",Queue->Uri.c_str(),Err.c_str()); + + // Dequeue + FetchItem *Tmp = Queue; + Queue = Queue->Next; + delete Tmp; + if (Tmp == QueueBack) + QueueBack = Queue; + } + else + snprintf(S,sizeof(S)-50,"400 URI Failure\nURI: \n" + "Message: %s\n",Err.c_str()); + + // Set the transient flag + if (Transient == true) + strcat(S,"Transient-Failure: true\n\n"); + else + strcat(S,"\n"); + + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ +// AcqMethod::URIStart - Indicate a download is starting /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::URIStart(FetchResult &Res) +{ + if (Queue == 0) + abort(); + + char S[1024] = ""; + char *End = S; + + End += snprintf(S,sizeof(S),"200 URI Start\nURI: %s\n",Queue->Uri.c_str()); + if (Res.Size != 0) + End += snprintf(End,sizeof(S)-4 - (End - S),"Size: %lu\n",Res.Size); + + if (Res.LastModified != 0) + End += snprintf(End,sizeof(S)-4 - (End - S),"Last-Modified: %s\n", + TimeRFC1123(Res.LastModified).c_str()); + + if (Res.ResumePoint != 0) + End += snprintf(End,sizeof(S)-4 - (End - S),"Resume-Point: %lu\n", + Res.ResumePoint); + + strcat(End,"\n"); + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ +// AcqMethod::URIDone - A URI is finished /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::URIDone(FetchResult &Res, FetchResult *Alt) +{ + if (Queue == 0) + abort(); + + char S[1024] = ""; + char *End = S; + + End += snprintf(S,sizeof(S),"201 URI Done\nURI: %s\n",Queue->Uri.c_str()); + + if (Res.Filename.empty() == false) + End += snprintf(End,sizeof(S)-50 - (End - S),"Filename: %s\n",Res.Filename.c_str()); + + if (Res.Size != 0) + End += snprintf(End,sizeof(S)-50 - (End - S),"Size: %lu\n",Res.Size); + + if (Res.LastModified != 0) + End += snprintf(End,sizeof(S)-50 - (End - S),"Last-Modified: %s\n", + TimeRFC1123(Res.LastModified).c_str()); + + if (Res.MD5Sum.empty() == false) + End += snprintf(End,sizeof(S)-50 - (End - S),"MD5-Hash: %s\n",Res.MD5Sum.c_str()); + + if (Res.SignatureKeyID.empty() == false) + End += snprintf(End,sizeof(S)-80 - (End - S),"Signature-Key: %s\n", + Res.SignatureKeyID.c_str()); + + if (Res.ResumePoint != 0) + End += snprintf(End,sizeof(S)-50 - (End - S),"Resume-Point: %lu\n", + Res.ResumePoint); + + if (Res.IMSHit == true) + strcat(End,"IMS-Hit: true\n"); + End = S + strlen(S); + + if (Alt != 0) + { + if (Alt->Filename.empty() == false) + End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Filename: %s\n",Alt->Filename.c_str()); + + if (Alt->Size != 0) + End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Size: %lu\n",Alt->Size); + + if (Alt->LastModified != 0) + End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-Last-Modified: %s\n", + TimeRFC1123(Alt->LastModified).c_str()); + + if (Alt->MD5Sum.empty() == false) + End += snprintf(End,sizeof(S)-50 - (End - S),"Alt-MD5-Hash: %s\n", + Alt->MD5Sum.c_str()); + + if (Alt->SignatureKeyID.empty() == false) + End += snprintf(End,sizeof(S)-80 - (End - S),"Alt-Signature-Key: %s\n", + Alt->SignatureKeyID.c_str()); + + if (Alt->IMSHit == true) + strcat(End,"Alt-IMS-Hit: true\n"); + } + + strcat(End,"\n"); + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); + + // Dequeue + FetchItem *Tmp = Queue; + Queue = Queue->Next; + delete Tmp; + if (Tmp == QueueBack) + QueueBack = Queue; +} + /*}}}*/ +// AcqMethod::MediaFail - Syncronous request for new media /*{{{*/ +// --------------------------------------------------------------------- +/* This sends a 403 Media Failure message to the APT and waits for it + to be ackd */ +bool pkgAcqMethod::MediaFail(string Required,string Drive) +{ + char S[1024]; + snprintf(S,sizeof(S),"403 Media Failure\nMedia: %s\nDrive: %s\n\n", + Required.c_str(),Drive.c_str()); + + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); + + vector MyMessages; + + /* Here we read messages until we find a 603, each non 603 message is + appended to the main message list for later processing */ + while (1) + { + if (WaitFd(STDIN_FILENO) == false) + return false; + + if (ReadMessages(STDIN_FILENO,MyMessages) == false) + return false; + + string Message = MyMessages.front(); + MyMessages.erase(MyMessages.begin()); + + // Fetch the message number + char *End; + int Number = strtol(Message.c_str(),&End,10); + if (End == Message.c_str()) + { + cerr << "Malformed message!" << endl; + exit(100); + } + + // Change ack + if (Number == 603) + { + while (MyMessages.empty() == false) + { + Messages.push_back(MyMessages.front()); + MyMessages.erase(MyMessages.begin()); + } + + return !StringToBool(LookupTag(Message,"Failed"),false); + } + + Messages.push_back(Message); + } +} + /*}}}*/ +// AcqMethod::Configuration - Handle the configuration message /*{{{*/ +// --------------------------------------------------------------------- +/* This parses each configuration entry and puts it into the _config + Configuration class. */ +bool pkgAcqMethod::Configuration(string Message) +{ + ::Configuration &Cnf = *_config; + + const char *I = Message.begin(); + + unsigned int Length = strlen("Config-Item"); + for (; I + Length < Message.end(); I++) + { + // Not a config item + if (I[Length] != ':' || stringcasecmp(I,I+Length,"Config-Item") != 0) + continue; + + I += Length + 1; + + for (; I < Message.end() && *I == ' '; I++); + const char *Equals = I; + for (; Equals < Message.end() && *Equals != '='; Equals++); + const char *End = Equals; + for (; End < Message.end() && *End != '\n'; End++); + if (End == Equals) + return false; + + Cnf.Set(DeQuoteString(string(I,Equals-I)), + DeQuoteString(string(Equals+1,End-Equals-1))); + I = End; + } + + return true; +} + /*}}}*/ +// AcqMethod::Run - Run the message engine /*{{{*/ +// --------------------------------------------------------------------- +/* Fetch any messages and execute them. In single mode it returns 1 if + there are no more available messages - any other result is a + fatal failure code! */ +int pkgAcqMethod::Run(bool Single) +{ + while (1) + { + // Block if the message queue is empty + if (Messages.empty() == true) + { + if (Single == false) + if (WaitFd(STDIN_FILENO) == false) + break; + if (ReadMessages(STDIN_FILENO,Messages) == false) + break; + } + + // Single mode exits if the message queue is empty + if (Single == true && Messages.empty() == true) + return -1; + + string Message = Messages.front(); + Messages.erase(Messages.begin()); + + // Fetch the message number + char *End; + int Number = strtol(Message.c_str(),&End,10); + if (End == Message.c_str()) + { + cerr << "Malformed message!" << endl; + return 100; + } + + switch (Number) + { + case 601: + if (Configuration(Message) == false) + return 100; + break; + + case 600: + { + FetchItem *Tmp = new FetchItem; + + Tmp->Uri = LookupTag(Message,"URI"); + Tmp->DestFile = LookupTag(Message,"FileName"); + if (StrToTime(LookupTag(Message,"Last-Modified"),Tmp->LastModified) == false) + Tmp->LastModified = 0; + Tmp->IndexFile = StringToBool(LookupTag(Message,"Index-File"),false); + Tmp->Next = 0; + + // Append it to the list + FetchItem **I = &Queue; + for (; *I != 0; I = &(*I)->Next); + *I = Tmp; + if (QueueBack == 0) + QueueBack = Tmp; + + // Notify that this item is to be fetched. + if (Fetch(Tmp) == false) + Fail(); + + break; + } + } + } + + Exit(); + return 0; +} + /*}}}*/ +// AcqMethod::Log - Send a log message /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::Log(const char *Format,...) +{ + string CurrentURI = ""; + if (Queue != 0) + CurrentURI = Queue->Uri; + + va_list args; + va_start(args,Format); + + // sprintf the description + char S[1024]; + unsigned int Len = snprintf(S,sizeof(S)-4,"101 Log\nURI: %s\n" + "Message: ",CurrentURI.c_str()); + + vsnprintf(S+Len,sizeof(S)-4-Len,Format,args); + strcat(S,"\n\n"); + + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ +// AcqMethod::Status - Send a status message /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcqMethod::Status(const char *Format,...) +{ + string CurrentURI = ""; + if (Queue != 0) + CurrentURI = Queue->Uri; + + va_list args; + va_start(args,Format); + + // sprintf the description + char S[1024]; + unsigned int Len = snprintf(S,sizeof(S)-4,"102 Status\nURI: %s\n" + "Message: ",CurrentURI.c_str()); + + vsnprintf(S+Len,sizeof(S)-4-Len,Format,args); + strcat(S,"\n\n"); + + if (write(STDOUT_FILENO,S,strlen(S)) != (signed)strlen(S)) + exit(100); +} + /*}}}*/ + +// AcqMethod::FetchResult::FetchResult - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcqMethod::FetchResult::FetchResult() : LastModified(0), + IMSHit(false), Size(0), ResumePoint(0) +{ +} + /*}}}*/ diff --git a/apt/apt-pkg/acquire-method.h b/apt/apt-pkg/acquire-method.h new file mode 100644 index 0000000..4322ead --- /dev/null +++ b/apt/apt-pkg/acquire-method.h @@ -0,0 +1,83 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire-method.h,v 1.2 2000/09/26 14:22:14 kojima Exp $ +/* ###################################################################### + + Acquire Method - Method helper class + functions + + These functions are designed to be used within the method task to + ease communication with APT. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_ACQUIRE_METHOD_H +#define PKGLIB_ACQUIRE_METHOD_H + +#include +#include + +#ifdef __GNUG__ +#pragma interface "apt-pkg/acquire-method.h" +#endif + +class pkgAcqMethod +{ + protected: + + struct FetchItem + { + FetchItem *Next; + + string Uri; + string DestFile; + time_t LastModified; + bool IndexFile; + }; + + struct FetchResult + { + string MD5Sum; + string SignatureKeyID; + time_t LastModified; + bool IMSHit; + string Filename; + unsigned long Size; + unsigned long ResumePoint; + FetchResult(); + }; + + // State + vector Messages; + FetchItem *Queue; + FetchItem *QueueBack; + + // Handlers for messages + virtual bool Configuration(string Message); + virtual bool Fetch(FetchItem * /*Item*/) {return true;}; + + // Outgoing messages + void Fail(bool Transient = false); + inline void Fail(const char *Why, bool Transient = false) {Fail(string(Why),Transient);}; + void Fail(string Why, bool Transient = false); + void URIStart(FetchResult &Res); + void URIDone(FetchResult &Res,FetchResult *Alt = 0); + bool MediaFail(string Required,string Drive); + virtual void Exit() {}; + + public: + + enum CnfFlags {SingleInstance = (1<<0), + Pipeline = (1<<1), SendConfig = (1<<2), + LocalOnly = (1<<3), NeedsCleanup = (1<<4), + Removable = (1<<5)}; + + void Log(const char *Format,...); + void Status(const char *Format,...); + + int Run(bool Single = false); + + pkgAcqMethod(const char *Ver,unsigned long Flags = 0); + virtual ~pkgAcqMethod() {}; +}; + +#endif diff --git a/apt/apt-pkg/acquire-worker.cc b/apt/apt-pkg/acquire-worker.cc new file mode 100644 index 0000000..b24160b --- /dev/null +++ b/apt/apt-pkg/acquire-worker.cc @@ -0,0 +1,547 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire-worker.cc,v 1.2 2001/01/11 02:03:26 kojima Exp $ +/* ###################################################################### + + Acquire Worker + + The worker process can startup either as a Configuration prober + or as a queue runner. As a configuration prober it only reads the + configuration message and + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/acquire-worker.h" +#endif +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + + /*}}}*/ + +// Worker::Worker - Constructor for Queue startup /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Worker::Worker(Queue *Q,MethodConfig *Cnf, + pkgAcquireStatus *Log) : Log(Log) +{ + OwnerQ = Q; + Config = Cnf; + Access = Cnf->Access; + CurrentItem = 0; + TotalSize = 0; + CurrentSize = 0; + + Construct(); +} + /*}}}*/ +// Worker::Worker - Constructor for method config startup /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Worker::Worker(MethodConfig *Cnf) +{ + OwnerQ = 0; + Config = Cnf; + Access = Cnf->Access; + CurrentItem = 0; + TotalSize = 0; + CurrentSize = 0; + + Construct(); +} + /*}}}*/ +// Worker::Construct - Constructor helper /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcquire::Worker::Construct() +{ + NextQueue = 0; + NextAcquire = 0; + Process = -1; + InFd = -1; + OutFd = -1; + OutReady = false; + InReady = false; + Debug = _config->FindB("Debug::pkgAcquire::Worker",false); +} + /*}}}*/ +// Worker::~Worker - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Worker::~Worker() +{ + close(InFd); + close(OutFd); + + if (Process > 0) + { + /* Closing of stdin is the signal to exit and die when the process + indicates it needs cleanup */ + if (Config->NeedsCleanup == false) + kill(Process,SIGINT); + ExecWait(Process,Access.c_str(),true); + } +} + /*}}}*/ +// Worker::Start - Start the worker process /*{{{*/ +// --------------------------------------------------------------------- +/* This forks the method and inits the communication channel */ +bool pkgAcquire::Worker::Start() +{ + // Get the method path + string Method = _config->FindDir("Dir::Bin::Methods") + Access; + if (FileExists(Method) == false) + return _error->Error(_("The method driver %s could not be found."),Method.c_str()); + + if (Debug == true) + clog << "Starting method '" << Method << '\'' << endl; + + // Create the pipes + int Pipes[4] = {-1,-1,-1,-1}; + if (pipe(Pipes) != 0 || pipe(Pipes+2) != 0) + { + _error->Errno("pipe",_("Failed to create IPC pipe to subprocess")); + for (int I = 0; I != 4; I++) + close(Pipes[I]); + return false; + } + for (int I = 0; I != 4; I++) + SetCloseExec(Pipes[I],true); + + // Fork off the process + Process = ExecFork(); + + // Spawn the subprocess + if (Process == 0) + { + // Setup the FDs + dup2(Pipes[1],STDOUT_FILENO); + dup2(Pipes[2],STDIN_FILENO); + dup2(((filebuf *)clog.rdbuf())->fd(),STDERR_FILENO); + SetCloseExec(STDOUT_FILENO,false); + SetCloseExec(STDIN_FILENO,false); + SetCloseExec(STDERR_FILENO,false); + + const char *Args[2]; + Args[0] = Method.c_str(); + Args[1] = 0; + execv(Args[0],(char **)Args); + cerr << "Failed to exec method " << Args[0] << endl; + _exit(100); + } + + // Fix up our FDs + InFd = Pipes[0]; + OutFd = Pipes[3]; + SetNonBlock(Pipes[0],true); + SetNonBlock(Pipes[3],true); + close(Pipes[1]); + close(Pipes[2]); + OutReady = false; + InReady = true; + + // Read the configuration data + if (WaitFd(InFd) == false || + ReadMessages() == false) + return _error->Error(_("Method %s did not start correctly"),Method.c_str()); + + RunMessages(); + if (OwnerQ != 0) + SendConfiguration(); + + return true; +} + /*}}}*/ +// Worker::ReadMessages - Read all pending messages into the list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgAcquire::Worker::ReadMessages() +{ + if (::ReadMessages(InFd,MessageQueue) == false) + return MethodFailure(); + return true; +} + /*}}}*/ +// Worker::RunMessage - Empty the message queue /*{{{*/ +// --------------------------------------------------------------------- +/* This takes the messages from the message queue and runs them through + the parsers in order. */ +bool pkgAcquire::Worker::RunMessages() +{ + while (MessageQueue.empty() == false) + { + string Message = MessageQueue.front(); + MessageQueue.erase(MessageQueue.begin()); + + if (Debug == true) + clog << " <- " << Access << ':' << QuoteString(Message,"\n") << endl; + + // Fetch the message number + char *End; + int Number = strtol(Message.c_str(),&End,10); + if (End == Message.c_str()) + return _error->Error(_("Invalid message from method %s: %s"),Access.c_str(),Message.c_str()); + + string URI = LookupTag(Message,"URI"); + pkgAcquire::Queue::QItem *Itm = 0; + if (URI.empty() == false) + Itm = OwnerQ->FindItem(URI,this); + + // Determine the message number and dispatch + switch (Number) + { + // 100 Capabilities + case 100: + if (Capabilities(Message) == false) + return _error->Error(_("Unable to process Capabilities message from %s"),Access.c_str()); + break; + + // 101 Log + case 101: + if (Debug == true) + clog << " <- (log) " << LookupTag(Message,"Message") << endl; + break; + + // 102 Status + case 102: + Status = LookupTag(Message,"Message"); + break; + + // 200 URI Start + case 200: + { + if (Itm == 0) + { + _error->Error(_("Method gave invalid 200 URI Start message")); + break; + } + + CurrentItem = Itm; + CurrentSize = 0; + TotalSize = atoi(LookupTag(Message,"Size","0").c_str()); + ResumePoint = atoi(LookupTag(Message,"Resume-Point","0").c_str()); + Itm->Owner->Start(Message,atoi(LookupTag(Message,"Size","0").c_str())); + + // Display update before completion + if (Log != 0 && Log->MorePulses == true) + Log->Pulse(Itm->Owner->GetOwner()); + + if (Log != 0) + Log->Fetch(*Itm); + + break; + } + + // 201 URI Done + case 201: + { + if (Itm == 0) + { + _error->Error("Method gave invalid 201 URI Done message"); + break; + } + + pkgAcquire::Item *Owner = Itm->Owner; + pkgAcquire::ItemDesc Desc = *Itm; + + // Display update before completion + if (Log != 0 && Log->MorePulses == true) + Log->Pulse(Owner->GetOwner()); + + OwnerQ->ItemDone(Itm); + if (TotalSize != 0 && + (unsigned)atoi(LookupTag(Message,"Size","0").c_str()) != TotalSize) + _error->Warning(_("Bizzar Error - File size is not what the server reported %s %u"), + LookupTag(Message,"Size","0").c_str(),TotalSize); + + Owner->Done(Message,atoi(LookupTag(Message,"Size","0").c_str()), + LookupTag(Message,"MD5-Hash"),Config); + ItemDone(); + + // Log that we are done + if (Log != 0) + { + if (StringToBool(LookupTag(Message,"IMS-Hit"),false) == true || + StringToBool(LookupTag(Message,"Alt-IMS-Hit"),false) == true) + { + /* Hide 'hits' for local only sources - we also manage to + hide gets */ + if (Config->LocalOnly == false) + Log->IMSHit(Desc); + } + else + Log->Done(Desc); + } + break; + } + + // 400 URI Failure + case 400: + { + if (Itm == 0) + { + _error->Error(_("Method gave invalid 400 URI Failure message")); + break; + } + + // Display update before completion + if (Log != 0 && Log->MorePulses == true) + Log->Pulse(Itm->Owner->GetOwner()); + + pkgAcquire::Item *Owner = Itm->Owner; + pkgAcquire::ItemDesc Desc = *Itm; + OwnerQ->ItemDone(Itm); + Owner->Failed(Message,Config); + ItemDone(); + + if (Log != 0) + Log->Fail(Desc); + + break; + } + + // 401 General Failure + case 401: + _error->Error(_("Method %s General failure: %s"),LookupTag(Message,"Message").c_str()); + break; + + // 403 Media Change + case 403: + MediaChange(Message); + break; + } + } + return true; +} + /*}}}*/ +// Worker::Capabilities - 100 Capabilities handler /*{{{*/ +// --------------------------------------------------------------------- +/* This parses the capabilities message and dumps it into the configuration + structure. */ +bool pkgAcquire::Worker::Capabilities(string Message) +{ + if (Config == 0) + return true; + + Config->Version = LookupTag(Message,"Version"); + Config->SingleInstance = StringToBool(LookupTag(Message,"Single-Instance"),false); + Config->Pipeline = StringToBool(LookupTag(Message,"Pipeline"),false); + Config->SendConfig = StringToBool(LookupTag(Message,"Send-Config"),false); + Config->LocalOnly = StringToBool(LookupTag(Message,"Local-Only"),false); + Config->NeedsCleanup = StringToBool(LookupTag(Message,"Needs-Cleanup"),false); + Config->Removable = StringToBool(LookupTag(Message,"Removable"),false); + + // Some debug text + if (Debug == true) + { + clog << "Configured access method " << Config->Access << endl; + clog << "Version:" << Config->Version << + " SingleInstance:" << Config->SingleInstance << + " Pipeline:" << Config->Pipeline << + " SendConfig:" << Config->SendConfig << + " LocalOnly: " << Config->LocalOnly << + " NeedsCleanup: " << Config->NeedsCleanup << + " Removable: " << Config->Removable << endl; + } + + return true; +} + /*}}}*/ +// Worker::MediaChange - Request a media change /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgAcquire::Worker::MediaChange(string Message) +{ + if (Log == 0 || Log->MediaChange(LookupTag(Message,"Media"), + LookupTag(Message,"Drive")) == false) + { + char S[300]; + sprintf(S,"603 Media Changed\nFailed: true\n\n"); + if (Debug == true) + clog << " -> " << Access << ':' << QuoteString(S,"\n") << endl; + OutQueue += S; + OutReady = true; + return true; + } + + char S[300]; + sprintf(S,"603 Media Changed\n\n"); + if (Debug == true) + clog << " -> " << Access << ':' << QuoteString(S,"\n") << endl; + OutQueue += S; + OutReady = true; + return true; +} + /*}}}*/ +// Worker::SendConfiguration - Send the config to the method /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgAcquire::Worker::SendConfiguration() +{ + if (Config->SendConfig == false) + return true; + + if (OutFd == -1) + return false; + + string Message = "601 Configuration\n"; + Message.reserve(2000); + + /* Write out all of the configuration directives by walking the + configuration tree */ + const Configuration::Item *Top = _config->Tree(0); + for (; Top != 0;) + { + if (Top->Value.empty() == false) + { + string Line = "Config-Item: " + Top->FullTag() + "="; + Line += QuoteString(Top->Value,"\n") + '\n'; + Message += Line; + } + + if (Top->Child != 0) + { + Top = Top->Child; + continue; + } + + while (Top != 0 && Top->Next == 0) + Top = Top->Parent; + if (Top != 0) + Top = Top->Next; + } + Message += '\n'; + + if (Debug == true) + clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl; + OutQueue += Message; + OutReady = true; + + return true; +} + /*}}}*/ +// Worker::QueueItem - Add an item to the outbound queue /*{{{*/ +// --------------------------------------------------------------------- +/* Send a URI Acquire message to the method */ +bool pkgAcquire::Worker::QueueItem(pkgAcquire::Queue::QItem *Item) +{ + if (OutFd == -1) + return false; + + string Message = "600 URI Acquire\n"; + Message.reserve(300); + Message += "URI: " + Item->URI; + Message += "\nFilename: " + Item->Owner->DestFile; + Message += Item->Owner->Custom600Headers(); + Message += "\n\n"; + + if (Debug == true) + clog << " -> " << Access << ':' << QuoteString(Message,"\n") << endl; + OutQueue += Message; + OutReady = true; + + return true; +} + /*}}}*/ +// Worker::OutFdRead - Out bound FD is ready /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgAcquire::Worker::OutFdReady() +{ + int Res; + do + { + Res = write(OutFd,OutQueue.begin(),OutQueue.length()); + } + while (Res < 0 && errno == EINTR); + + if (Res <= 0) + return MethodFailure(); + + // Hmm.. this should never happen. + if (Res < 0) + return true; + + OutQueue.erase(0,Res); + if (OutQueue.empty() == true) + OutReady = false; + + return true; +} + /*}}}*/ +// Worker::InFdRead - In bound FD is ready /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgAcquire::Worker::InFdReady() +{ + if (ReadMessages() == false) + return false; + RunMessages(); + return true; +} + /*}}}*/ +// Worker::MethodFailure - Called when the method fails /*{{{*/ +// --------------------------------------------------------------------- +/* This is called when the method is belived to have failed, probably because + read returned -1. */ +bool pkgAcquire::Worker::MethodFailure() +{ + _error->Error(_("Method %s has died unexpectedly!"),Access.c_str()); + + ExecWait(Process,Access.c_str(),true); + Process = -1; + close(InFd); + close(OutFd); + InFd = -1; + OutFd = -1; + OutReady = false; + InReady = false; + OutQueue = string(); + MessageQueue.erase(MessageQueue.begin(),MessageQueue.end()); + + return false; +} + /*}}}*/ +// Worker::Pulse - Called periodically /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcquire::Worker::Pulse() +{ + if (CurrentItem == 0) + return; + + struct stat Buf; + if (stat(CurrentItem->Owner->DestFile.c_str(),&Buf) != 0) + return; + CurrentSize = Buf.st_size; + + // Hmm? Should not happen... + if (CurrentSize > TotalSize && TotalSize != 0) + TotalSize = CurrentSize; +} + /*}}}*/ +// Worker::ItemDone - Called when the current item is finished /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcquire::Worker::ItemDone() +{ + CurrentItem = 0; + CurrentSize = 0; + TotalSize = 0; + Status = string(); +} + /*}}}*/ diff --git a/apt/apt-pkg/acquire-worker.h b/apt/apt-pkg/acquire-worker.h new file mode 100644 index 0000000..49c96b5 --- /dev/null +++ b/apt/apt-pkg/acquire-worker.h @@ -0,0 +1,89 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire-worker.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Acquire Worker - Worker process manager + + Each worker class is associated with exaclty one subprocess. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_ACQUIRE_WORKER_H +#define PKGLIB_ACQUIRE_WORKER_H + +#include + +#ifdef __GNUG__ +#pragma interface "apt-pkg/acquire-worker.h" +#endif + +// Interfacing to the method process +class pkgAcquire::Worker +{ + friend pkgAcquire; + + protected: + friend Queue; + + /* Linked list starting at a Queue and a linked list starting + at Acquire */ + Worker *NextQueue; + Worker *NextAcquire; + + // The access association + Queue *OwnerQ; + pkgAcquireStatus *Log; + MethodConfig *Config; + string Access; + + // This is the subprocess IPC setup + pid_t Process; + int InFd; + int OutFd; + bool InReady; + bool OutReady; + + // Various internal things + bool Debug; + vector MessageQueue; + string OutQueue; + + // Private constructor helper + void Construct(); + + // Message handling things + bool ReadMessages(); + bool RunMessages(); + bool InFdReady(); + bool OutFdReady(); + + // The message handlers + bool Capabilities(string Message); + bool SendConfiguration(); + bool MediaChange(string Message); + + bool MethodFailure(); + void ItemDone(); + + public: + + // The curent method state + pkgAcquire::Queue::QItem *CurrentItem; + string Status; + unsigned long CurrentSize; + unsigned long TotalSize; + unsigned long ResumePoint; + + // Load the method and do the startup + bool QueueItem(pkgAcquire::Queue::QItem *Item); + bool Start(); + void Pulse(); + inline const MethodConfig *GetConf() const {return Config;}; + + Worker(Queue *OwnerQ,MethodConfig *Config,pkgAcquireStatus *Log); + Worker(MethodConfig *Config); + ~Worker(); +}; + +#endif diff --git a/apt/apt-pkg/acquire.cc b/apt/apt-pkg/acquire.cc new file mode 100644 index 0000000..003dfe9 --- /dev/null +++ b/apt/apt-pkg/acquire.cc @@ -0,0 +1,842 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire.cc,v 1.3 2001/06/16 01:50:22 kojima Exp $ +/* ###################################################################### + + Acquire - File Acquiration + + The core element for the schedual system is the concept of a named + queue. Each queue is unique and each queue has a name derived from the + URI. The degree of paralization can be controled by how the queue + name is derived from the URI. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/acquire.h" +#endif +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + + /*}}}*/ + +// Acquire::pkgAcquire - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* We grab some runtime state from the configuration space */ +pkgAcquire::pkgAcquire(pkgAcquireStatus *Log) : Log(Log) +{ + Queues = 0; + Configs = 0; + Workers = 0; + ToFetch = 0; + Running = false; + + string Mode = _config->Find("Acquire::Queue-Mode","host"); + if (strcasecmp(Mode.c_str(),"host") == 0) + QueueMode = QueueHost; + if (strcasecmp(Mode.c_str(),"access") == 0) + QueueMode = QueueAccess; + + Debug = _config->FindB("Debug::pkgAcquire",false); + + // This is really a stupid place for this + struct stat St; + if (stat((_config->FindDir("Dir::State::lists") + "partial/").c_str(),&St) != 0 || + S_ISDIR(St.st_mode) == 0) + _error->Error(_("Lists directory %spartial is missing."), + _config->FindDir("Dir::State::lists").c_str()); + if (stat((_config->FindDir("Dir::Cache::Archives") + "partial/").c_str(),&St) != 0 || + S_ISDIR(St.st_mode) == 0) + _error->Error(_("Archive directory %spartial is missing."), + _config->FindDir("Dir::Cache::Archives").c_str()); +} + /*}}}*/ +// Acquire::~pkgAcquire - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* Free our memory, clean up the queues (destroy the workers) */ +pkgAcquire::~pkgAcquire() +{ + Shutdown(); + + while (Configs != 0) + { + MethodConfig *Jnk = Configs; + Configs = Configs->Next; + delete Jnk; + } +} + /*}}}*/ +// Acquire::Shutdown - Clean out the acquire object /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcquire::Shutdown() +{ + while (Items.size() != 0) + delete Items[0]; + + while (Queues != 0) + { + Queue *Jnk = Queues; + Queues = Queues->Next; + delete Jnk; + } +} + /*}}}*/ +// Acquire::Add - Add a new item /*{{{*/ +// --------------------------------------------------------------------- +/* This puts an item on the acquire list. This list is mainly for tracking + item status */ +void pkgAcquire::Add(Item *Itm) +{ + Items.push_back(Itm); +} + /*}}}*/ +// Acquire::Remove - Remove a item /*{{{*/ +// --------------------------------------------------------------------- +/* Remove an item from the acquire list. This is usually not used.. */ +void pkgAcquire::Remove(Item *Itm) +{ + Dequeue(Itm); + + for (vector::iterator I = Items.begin(); I < Items.end(); I++) + { + if (*I == Itm) + Items.erase(I); + } +} + /*}}}*/ +// Acquire::Add - Add a worker /*{{{*/ +// --------------------------------------------------------------------- +/* A list of workers is kept so that the select loop can direct their FD + usage. */ +void pkgAcquire::Add(Worker *Work) +{ + Work->NextAcquire = Workers; + Workers = Work; +} + /*}}}*/ +// Acquire::Remove - Remove a worker /*{{{*/ +// --------------------------------------------------------------------- +/* A worker has died. This can not be done while the select loop is running + as it would require that RunFds could handling a changing list state and + it cant.. */ +void pkgAcquire::Remove(Worker *Work) +{ + if (Running == true) + abort(); + + Worker **I = &Workers; + for (; *I != 0;) + { + if (*I == Work) + *I = (*I)->NextAcquire; + else + I = &(*I)->NextAcquire; + } +} + /*}}}*/ +// Acquire::Enqueue - Queue an URI for fetching /*{{{*/ +// --------------------------------------------------------------------- +/* This is the entry point for an item. An item calls this function when + it is constructed which creates a queue (based on the current queue + mode) and puts the item in that queue. If the system is running then + the queue might be started. */ +void pkgAcquire::Enqueue(ItemDesc &Item) +{ + // Determine which queue to put the item in + const MethodConfig *Config; + string Name = QueueName(Item.URI,Config); + if (Name.empty() == true) + return; + + // Find the queue structure + Queue *I = Queues; + for (; I != 0 && I->Name != Name; I = I->Next); + if (I == 0) + { + I = new Queue(Name,this); + I->Next = Queues; + Queues = I; + + if (Running == true) + I->Startup(); + } + + // See if this is a local only URI + if (Config->LocalOnly == true && Item.Owner->Complete == false) + Item.Owner->Local = true; + Item.Owner->Status = Item::StatIdle; + + // Queue it into the named queue + I->Enqueue(Item); + ToFetch++; + + // Some trace stuff + if (Debug == true) + { + clog << "Fetching " << Item.URI << endl; + clog << " to " << Item.Owner->DestFile << endl; + clog << " Queue is: " << Name << endl; + } +} + /*}}}*/ +// Acquire::Dequeue - Remove an item from all queues /*{{{*/ +// --------------------------------------------------------------------- +/* This is called when an item is finished being fetched. It removes it + from all the queues */ +void pkgAcquire::Dequeue(Item *Itm) +{ + Queue *I = Queues; + bool Res = false; + for (; I != 0; I = I->Next) + Res |= I->Dequeue(Itm); + + if (Debug == true) + clog << "Dequeuing " << Itm->DestFile << endl; + if (Res == true) + ToFetch--; +} + /*}}}*/ +// Acquire::QueueName - Return the name of the queue for this URI /*{{{*/ +// --------------------------------------------------------------------- +/* The string returned depends on the configuration settings and the + method parameters. Given something like http://foo.org/bar it can + return http://foo.org or http */ +string pkgAcquire::QueueName(string Uri,MethodConfig const *&Config) +{ + URI U(Uri); + + Config = GetConfig(U.Access); + if (Config == 0) + return string(); + + /* Single-Instance methods get exactly one queue per URI. This is + also used for the Access queue method */ + if (Config->SingleInstance == true || QueueMode == QueueAccess) + return U.Access; + + return U.Access + ':' + U.Host; +} + /*}}}*/ +// Acquire::GetConfig - Fetch the configuration information /*{{{*/ +// --------------------------------------------------------------------- +/* This locates the configuration structure for an access method. If + a config structure cannot be found a Worker will be created to + retrieve it */ +pkgAcquire::MethodConfig *pkgAcquire::GetConfig(string Access) +{ + // Search for an existing config + MethodConfig *Conf; + for (Conf = Configs; Conf != 0; Conf = Conf->Next) + if (Conf->Access == Access) + return Conf; + + // Create the new config class + Conf = new MethodConfig; + Conf->Access = Access; + Conf->Next = Configs; + Configs = Conf; + + // Create the worker to fetch the configuration + Worker Work(Conf); + if (Work.Start() == false) + return 0; + + return Conf; +} + /*}}}*/ +// Acquire::SetFds - Deal with readable FDs /*{{{*/ +// --------------------------------------------------------------------- +/* Collect FDs that have activity monitors into the fd sets */ +void pkgAcquire::SetFds(int &Fd,fd_set *RSet,fd_set *WSet) +{ + for (Worker *I = Workers; I != 0; I = I->NextAcquire) + { + if (I->InReady == true && I->InFd >= 0) + { + if (Fd < I->InFd) + Fd = I->InFd; + FD_SET(I->InFd,RSet); + } + if (I->OutReady == true && I->OutFd >= 0) + { + if (Fd < I->OutFd) + Fd = I->OutFd; + FD_SET(I->OutFd,WSet); + } + } +} + /*}}}*/ +// Acquire::RunFds - Deal with active FDs /*{{{*/ +// --------------------------------------------------------------------- +/* Dispatch active FDs over to the proper workers. It is very important + that a worker never be erased while this is running! The queue class + should never erase a worker except during shutdown processing. */ +void pkgAcquire::RunFds(fd_set *RSet,fd_set *WSet) +{ + for (Worker *I = Workers; I != 0; I = I->NextAcquire) + { + if (I->InFd >= 0 && FD_ISSET(I->InFd,RSet) != 0) + I->InFdReady(); + if (I->OutFd >= 0 && FD_ISSET(I->OutFd,WSet) != 0) + I->OutFdReady(); + } +} + /*}}}*/ +// Acquire::Run - Run the fetch sequence /*{{{*/ +// --------------------------------------------------------------------- +/* This runs the queues. It manages a select loop for all of the + Worker tasks. The workers interact with the queues and items to + manage the actual fetch. */ +pkgAcquire::RunResult pkgAcquire::Run() +{ + Running = true; + + for (Queue *I = Queues; I != 0; I = I->Next) + I->Startup(); + + if (Log != 0) + Log->Start(); + + bool WasCancelled = false; + + // Run till all things have been acquired + struct timeval tv; + tv.tv_sec = 0; + tv.tv_usec = 500000; + while (ToFetch > 0) + { + fd_set RFds; + fd_set WFds; + int Highest = 0; + FD_ZERO(&RFds); + FD_ZERO(&WFds); + SetFds(Highest,&RFds,&WFds); + + int Res; + do + { + Res = select(Highest+1,&RFds,&WFds,0,&tv); + } + while (Res < 0 && errno == EINTR); + + if (Res < 0) + { + _error->Errno("select","Select has failed"); + break; + } + + RunFds(&RFds,&WFds); + if (_error->PendingError() == true) + break; + + // Timeout, notify the log class + if (Res == 0 || (Log != 0 && Log->Update == true)) + { + tv.tv_usec = 500000; + for (Worker *I = Workers; I != 0; I = I->NextAcquire) + I->Pulse(); + if (Log != 0 && Log->Pulse(this) == false) + { + WasCancelled = true; + break; + } + } + } + + if (Log != 0) + Log->Stop(); + + // Shut down the acquire bits + Running = false; + for (Queue *I = Queues; I != 0; I = I->Next) + I->Shutdown(false); + + // Shut down the items + for (Item **I = Items.begin(); I != Items.end(); I++) + (*I)->Finished(); + + if (_error->PendingError()) + return Failed; + if (WasCancelled) + return Cancelled; + return Continue; +} + /*}}}*/ +// Acquire::Bump - Called when an item is dequeued /*{{{*/ +// --------------------------------------------------------------------- +/* This routine bumps idle queues in hopes that they will be able to fetch + the dequeued item */ +void pkgAcquire::Bump() +{ + for (Queue *I = Queues; I != 0; I = I->Next) + I->Bump(); +} + /*}}}*/ +// Acquire::WorkerStep - Step to the next worker /*{{{*/ +// --------------------------------------------------------------------- +/* Not inlined to advoid including acquire-worker.h */ +pkgAcquire::Worker *pkgAcquire::WorkerStep(Worker *I) +{ + return I->NextAcquire; +}; + /*}}}*/ +// Acquire::Clean - Cleans a directory /*{{{*/ +// --------------------------------------------------------------------- +/* This is a bit simplistic, it looks at every file in the dir and sees + if it is part of the download set. */ +bool pkgAcquire::Clean(string Dir) +{ + DIR *D = opendir(Dir.c_str()); + if (D == 0) + return _error->Errno("opendir","Unable to read %s",Dir.c_str()); + + string StartDir = SafeGetCWD(); + if (chdir(Dir.c_str()) != 0) + { + closedir(D); + return _error->Errno("chdir","Unable to change to ",Dir.c_str()); + } + + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + // Skip some files.. + if (strcmp(Dir->d_name,"lock") == 0 || + strcmp(Dir->d_name,"partial") == 0 || + strcmp(Dir->d_name,".") == 0 || + strcmp(Dir->d_name,"..") == 0) + continue; + + // Look in the get list + vector::iterator I = Items.begin(); + for (; I != Items.end(); I++) + if (flNotDir((*I)->DestFile) == Dir->d_name) + break; + + // Nothing found, nuke it + if (I == Items.end()) + unlink(Dir->d_name); + }; + + chdir(StartDir.c_str()); + closedir(D); + return true; +} + /*}}}*/ +// Acquire::TotalNeeded - Number of bytes to fetch /*{{{*/ +// --------------------------------------------------------------------- +/* This is the total number of bytes needed */ +unsigned long pkgAcquire::TotalNeeded() +{ + unsigned long Total = 0; + for (pkgAcquire::Item **I = ItemsBegin(); I != ItemsEnd(); I++) + Total += (*I)->FileSize; + return Total; +} + /*}}}*/ +// Acquire::FetchNeeded - Number of bytes needed to get /*{{{*/ +// --------------------------------------------------------------------- +/* This is the number of bytes that is not local */ +unsigned long pkgAcquire::FetchNeeded() +{ + unsigned long Total = 0; + for (pkgAcquire::Item **I = ItemsBegin(); I != ItemsEnd(); I++) + if ((*I)->Local == false) + Total += (*I)->FileSize; + return Total; +} + /*}}}*/ +// Acquire::PartialPresent - Number of partial bytes we already have /*{{{*/ +// --------------------------------------------------------------------- +/* This is the number of bytes that is not local */ +unsigned long pkgAcquire::PartialPresent() +{ + unsigned long Total = 0; + for (pkgAcquire::Item **I = ItemsBegin(); I != ItemsEnd(); I++) + if ((*I)->Local == false) + Total += (*I)->PartialSize; + return Total; +} + /*}}}*/ +// Acquire::UriBegin - Start iterator for the uri list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::UriIterator pkgAcquire::UriBegin() +{ + return UriIterator(Queues); +} + /*}}}*/ +// Acquire::UriEnd - End iterator for the uri list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::UriIterator pkgAcquire::UriEnd() +{ + return UriIterator(0); +} + /*}}}*/ + +// Acquire::MethodConfig::MethodConfig - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::MethodConfig::MethodConfig() +{ + SingleInstance = false; + Pipeline = false; + SendConfig = false; + LocalOnly = false; + Removable = false; + Next = 0; +} + /*}}}*/ + +// Queue::Queue - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Queue::Queue(string Name,pkgAcquire *Owner) : Name(Name), + Owner(Owner) +{ + Items = 0; + Next = 0; + Workers = 0; + MaxPipeDepth = 1; + PipeDepth = 0; +} + /*}}}*/ +// Queue::~Queue - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Queue::~Queue() +{ + Shutdown(true); + + while (Items != 0) + { + QItem *Jnk = Items; + Items = Items->Next; + delete Jnk; + } +} + /*}}}*/ +// Queue::Enqueue - Queue an item to the queue /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgAcquire::Queue::Enqueue(ItemDesc &Item) +{ + QItem **I = &Items; + for (; *I != 0; I = &(*I)->Next); + + // Create a new item + QItem *Itm = new QItem; + *Itm = Item; + Itm->Next = 0; + *I = Itm; + + Item.Owner->QueueCounter++; + if (Items->Next == 0) + Cycle(); +} + /*}}}*/ +// Queue::Dequeue - Remove an item from the queue /*{{{*/ +// --------------------------------------------------------------------- +/* We return true if we hit something */ +bool pkgAcquire::Queue::Dequeue(Item *Owner) +{ + if (Owner->Status == pkgAcquire::Item::StatFetching) + return _error->Error("Tried to dequeue a fetching object"); + + bool Res = false; + + QItem **I = &Items; + for (; *I != 0;) + { + if ((*I)->Owner == Owner) + { + QItem *Jnk= *I; + *I = (*I)->Next; + Owner->QueueCounter--; + delete Jnk; + Res = true; + } + else + I = &(*I)->Next; + } + + return Res; +} + /*}}}*/ +// Queue::Startup - Start the worker processes /*{{{*/ +// --------------------------------------------------------------------- +/* It is possible for this to be called with a pre-existing set of + workers. */ +bool pkgAcquire::Queue::Startup() +{ + if (Workers == 0) + { + URI U(Name); + pkgAcquire::MethodConfig *Cnf = Owner->GetConfig(U.Access); + if (Cnf == 0) + return false; + + Workers = new Worker(this,Cnf,Owner->Log); + Owner->Add(Workers); + if (Workers->Start() == false) + return false; + + /* When pipelining we commit 10 items. This needs to change when we + added other source retry to have cycle maintain a pipeline depth + on its own. */ + if (Cnf->Pipeline == true) + MaxPipeDepth = 10; + else + MaxPipeDepth = 1; + } + + return Cycle(); +} + /*}}}*/ +// Queue::Shutdown - Shutdown the worker processes /*{{{*/ +// --------------------------------------------------------------------- +/* If final is true then all workers are eliminated, otherwise only workers + that do not need cleanup are removed */ +bool pkgAcquire::Queue::Shutdown(bool Final) +{ + // Delete all of the workers + pkgAcquire::Worker **Cur = &Workers; + while (*Cur != 0) + { + pkgAcquire::Worker *Jnk = *Cur; + if (Final == true || Jnk->GetConf()->NeedsCleanup == false) + { + *Cur = Jnk->NextQueue; + Owner->Remove(Jnk); + delete Jnk; + } + else + Cur = &(*Cur)->NextQueue; + } + + return true; +} + /*}}}*/ +// Queue::FindItem - Find a URI in the item list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquire::Queue::QItem *pkgAcquire::Queue::FindItem(string URI,pkgAcquire::Worker *Owner) +{ + for (QItem *I = Items; I != 0; I = I->Next) + if (I->URI == URI && I->Worker == Owner) + return I; + return 0; +} + /*}}}*/ +// Queue::ItemDone - Item has been completed /*{{{*/ +// --------------------------------------------------------------------- +/* The worker signals this which causes the item to be removed from the + queue. If this is the last queue instance then it is removed from the + main queue too.*/ +bool pkgAcquire::Queue::ItemDone(QItem *Itm) +{ + PipeDepth--; + if (Itm->Owner->Status == pkgAcquire::Item::StatFetching) + Itm->Owner->Status = pkgAcquire::Item::StatDone; + + if (Itm->Owner->QueueCounter <= 1) + Owner->Dequeue(Itm->Owner); + else + { + Dequeue(Itm->Owner); + Owner->Bump(); + } + + return Cycle(); +} + /*}}}*/ +// Queue::Cycle - Queue new items into the method /*{{{*/ +// --------------------------------------------------------------------- +/* This locates a new idle item and sends it to the worker. If pipelining + is enabled then it keeps the pipe full. */ +bool pkgAcquire::Queue::Cycle() +{ + if (Items == 0 || Workers == 0) + return true; + + if (PipeDepth < 0) + return _error->Error("Pipedepth failure"); + + // Look for a queable item + QItem *I = Items; + while (PipeDepth < (signed)MaxPipeDepth) + { + for (; I != 0; I = I->Next) + if (I->Owner->Status == pkgAcquire::Item::StatIdle) + break; + + // Nothing to do, queue is idle. + if (I == 0) + return true; + + I->Worker = Workers; + I->Owner->Status = pkgAcquire::Item::StatFetching; + PipeDepth++; + if (Workers->QueueItem(I) == false) + return false; + } + + return true; +} + /*}}}*/ +// Queue::Bump - Fetch any pending objects if we are idle /*{{{*/ +// --------------------------------------------------------------------- +/* This is called when an item in multiple queues is dequeued */ +void pkgAcquire::Queue::Bump() +{ + Cycle(); +} + /*}}}*/ + +// AcquireStatus::pkgAcquireStatus - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgAcquireStatus::pkgAcquireStatus() : Update(true), MorePulses(false) +{ + Start(); +} + /*}}}*/ +// AcquireStatus::Pulse - Called periodically /*{{{*/ +// --------------------------------------------------------------------- +/* This computes some internal state variables for the derived classes to + use. It generates the current downloaded bytes and total bytes to download + as well as the current CPS estimate. */ +bool pkgAcquireStatus::Pulse(pkgAcquire *Owner) +{ + TotalBytes = 0; + CurrentBytes = 0; + TotalItems = 0; + CurrentItems = 0; + + // Compute the total number of bytes to fetch + unsigned int Unknown = 0; + unsigned int Count = 0; + for (pkgAcquire::Item **I = Owner->ItemsBegin(); I != Owner->ItemsEnd(); + I++, Count++) + { + TotalItems++; + if ((*I)->Status == pkgAcquire::Item::StatDone) + CurrentItems++; + + // Totally ignore local items + if ((*I)->Local == true) + continue; + + TotalBytes += (*I)->FileSize; + if ((*I)->Complete == true) + CurrentBytes += (*I)->FileSize; + if ((*I)->FileSize == 0 && (*I)->Complete == false) + Unknown++; + } + + // Compute the current completion + unsigned long ResumeSize = 0; + for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0; + I = Owner->WorkerStep(I)) + if (I->CurrentItem != 0 && I->CurrentItem->Owner->Complete == false) + { + CurrentBytes += I->CurrentSize; + ResumeSize += I->ResumePoint; + + // Files with unknown size always have 100% completion + if (I->CurrentItem->Owner->FileSize == 0 && + I->CurrentItem->Owner->Complete == false) + TotalBytes += I->CurrentSize; + } + + // Normalize the figures and account for unknown size downloads + if (TotalBytes <= 0) + TotalBytes = 1; + if (Unknown == Count) + TotalBytes = Unknown; + + // Wha?! Is not supposed to happen. + if (CurrentBytes > TotalBytes) + CurrentBytes = TotalBytes; + + // Compute the CPS + struct timeval NewTime; + gettimeofday(&NewTime,0); + if (NewTime.tv_sec - Time.tv_sec == 6 && NewTime.tv_usec > Time.tv_usec || + NewTime.tv_sec - Time.tv_sec > 6) + { + double Delta = NewTime.tv_sec - Time.tv_sec + + (NewTime.tv_usec - Time.tv_usec)/1000000.0; + + // Compute the CPS value + if (Delta < 0.01) + CurrentCPS = 0; + else + CurrentCPS = ((CurrentBytes - ResumeSize) - LastBytes)/Delta; + LastBytes = CurrentBytes - ResumeSize; + ElapsedTime = (unsigned long)Delta; + Time = NewTime; + } + + return true; +} + /*}}}*/ +// AcquireStatus::Start - Called when the download is started /*{{{*/ +// --------------------------------------------------------------------- +/* We just reset the counters */ +void pkgAcquireStatus::Start() +{ + gettimeofday(&Time,0); + gettimeofday(&StartTime,0); + LastBytes = 0; + CurrentCPS = 0; + CurrentBytes = 0; + TotalBytes = 0; + FetchedBytes = 0; + ElapsedTime = 0; + TotalItems = 0; + CurrentItems = 0; +} + /*}}}*/ +// AcquireStatus::Stop - Finished downloading /*{{{*/ +// --------------------------------------------------------------------- +/* This accurately computes the elapsed time and the total overall CPS. */ +void pkgAcquireStatus::Stop() +{ + // Compute the CPS and elapsed time + struct timeval NewTime; + gettimeofday(&NewTime,0); + + double Delta = NewTime.tv_sec - StartTime.tv_sec + + (NewTime.tv_usec - StartTime.tv_usec)/1000000.0; + + // Compute the CPS value + if (Delta < 0.01) + CurrentCPS = 0; + else + CurrentCPS = FetchedBytes/Delta; + LastBytes = CurrentBytes; + ElapsedTime = (unsigned int)Delta; +} + /*}}}*/ +// AcquireStatus::Fetched - Called when a byte set has been fetched /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to get accurate final transfer rate reporting. */ +void pkgAcquireStatus::Fetched(unsigned long Size,unsigned long Resume) +{ + FetchedBytes += Size - Resume; +} + /*}}}*/ diff --git a/apt/apt-pkg/acquire.h b/apt/apt-pkg/acquire.h new file mode 100644 index 0000000..3a5ef64 --- /dev/null +++ b/apt/apt-pkg/acquire.h @@ -0,0 +1,276 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acquire.h,v 1.2 2000/11/06 12:53:49 kojima Exp $ +/* ###################################################################### + + Acquire - File Acquiration + + This module contians the Acquire system. It is responsible for bringing + files into the local pathname space. It deals with URIs for files and + URI handlers responsible for downloading or finding the URIs. + + Each file to download is represented by an Acquire::Item class subclassed + into a specialization. The Item class can add itself to several URI + acquire queues each prioritized by the download scheduler. When the + system is run the proper URI handlers are spawned and the the acquire + queues are fed into the handlers by the schedular until the queues are + empty. This allows for an Item to be downloaded from an alternate source + if the first try turns out to fail. It also alows concurrent downloading + of multiple items from multiple sources as well as dynamic balancing + of load between the sources. + + Schedualing of downloads is done on a first ask first get basis. This + preserves the order of the download as much as possible. And means the + fastest source will tend to process the largest number of files. + + Internal methods and queues for performing gzip decompression, + md5sum hashing and file copying are provided to allow items to apply + a number of transformations to the data files they are working with. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_ACQUIRE_H +#define PKGLIB_ACQUIRE_H + +#include +#include + +#ifdef __GNUG__ +#pragma interface "apt-pkg/acquire.h" +#endif + +#include +#include + +class pkgAcquireStatus; +class pkgAcquire +{ + public: + + class Item; + class Queue; + class Worker; + struct MethodConfig; + struct ItemDesc; + friend Item; + friend Queue; + + protected: + + // List of items to fetch + vector Items; + + // List of active queues and fetched method configuration parameters + Queue *Queues; + Worker *Workers; + MethodConfig *Configs; + pkgAcquireStatus *Log; + unsigned long ToFetch; + + // Configurable parameters for the schedular + enum {QueueHost,QueueAccess} QueueMode; + bool Debug; + bool Running; + + void Add(Item *Item); + void Remove(Item *Item); + void Add(Worker *Work); + void Remove(Worker *Work); + + void Enqueue(ItemDesc &Item); + void Dequeue(Item *Item); + string QueueName(string URI,MethodConfig const *&Config); + + // FDSET managers for derived classes + virtual void SetFds(int &Fd,fd_set *RSet,fd_set *WSet); + virtual void RunFds(fd_set *RSet,fd_set *WSet); + + // A queue calls this when it dequeues an item + void Bump(); + + public: + + MethodConfig *GetConfig(string Access); + + enum RunResult {Continue,Failed,Cancelled}; + + RunResult Run(); + void Shutdown(); + + // Simple iteration mechanism + inline Worker *WorkersBegin() {return Workers;}; + Worker *WorkerStep(Worker *I); + inline Item **ItemsBegin() {return Items.begin();}; + inline Item **ItemsEnd() {return Items.end();}; + + // Iterate over queued Item URIs + class UriIterator; + UriIterator UriBegin(); + UriIterator UriEnd(); + + // Cleans out the download dir + bool Clean(string Dir); + + // Returns the size of the total download set + unsigned long TotalNeeded(); + unsigned long FetchNeeded(); + unsigned long PartialPresent(); + + pkgAcquire(pkgAcquireStatus *Log = 0); + virtual ~pkgAcquire(); +}; + +// Description of an Item+URI +struct pkgAcquire::ItemDesc +{ + string URI; + string Description; + string ShortDesc; + Item *Owner; +}; + +// List of possible items queued for download. +class pkgAcquire::Queue +{ + friend pkgAcquire; + friend pkgAcquire::UriIterator; + Queue *Next; + + public: + // Queued item + struct QItem : pkgAcquire::ItemDesc + { + QItem *Next; + pkgAcquire::Worker *Worker; + + void operator =(pkgAcquire::ItemDesc const &I) + { + URI = I.URI; + Description = I.Description; + ShortDesc = I.ShortDesc; + Owner = I.Owner; + }; + }; + protected: + // Name of the queue + string Name; + + // Items queued into this queue + QItem *Items; + pkgAcquire::Worker *Workers; + pkgAcquire *Owner; + signed long PipeDepth; + unsigned long MaxPipeDepth; + + public: + + // Put an item into this queue + void Enqueue(ItemDesc &Item); + bool Dequeue(Item *Owner); + + // Find a Queued item + QItem *FindItem(string URI,pkgAcquire::Worker *Owner); + bool ItemStart(QItem *Itm,unsigned long Size); + bool ItemDone(QItem *Itm); + + bool Startup(); + bool Shutdown(bool Final); + bool Cycle(); + void Bump(); + + Queue(string Name,pkgAcquire *Owner); + ~Queue(); +}; + +class pkgAcquire::UriIterator +{ + pkgAcquire::Queue *CurQ; + pkgAcquire::Queue::QItem *CurItem; + + public: + + // Advance to the next item + inline void operator ++() {operator ++();}; + void operator ++(int) + { + CurItem = CurItem->Next; + while (CurItem == 0 && CurQ != 0) + { + CurItem = CurQ->Items; + CurQ = CurQ->Next; + } + }; + + // Accessors + inline pkgAcquire::ItemDesc const *operator ->() const {return CurItem;}; + inline bool operator !=(UriIterator const &rhs) const {return rhs.CurQ != CurQ || rhs.CurItem != CurItem;}; + inline bool operator ==(UriIterator const &rhs) const {return rhs.CurQ == CurQ && rhs.CurItem == CurItem;}; + + UriIterator(pkgAcquire::Queue *Q) : CurQ(Q), CurItem(0) + { + while (CurItem == 0 && CurQ != 0) + { + CurItem = CurQ->Items; + CurQ = CurQ->Next; + } + } +}; + +// Configuration information from each method +struct pkgAcquire::MethodConfig +{ + MethodConfig *Next; + + string Access; + + string Version; + bool SingleInstance; + bool Pipeline; + bool SendConfig; + bool LocalOnly; + bool NeedsCleanup; + bool Removable; + + MethodConfig(); +}; + +class pkgAcquireStatus +{ + protected: + + struct timeval Time; + struct timeval StartTime; + unsigned long LastBytes; + double CurrentCPS; + unsigned long CurrentBytes; + unsigned long TotalBytes; + unsigned long FetchedBytes; + unsigned long ElapsedTime; + unsigned long TotalItems; + unsigned long CurrentItems; + + public: + + bool Update; + bool MorePulses; + + // Called by items when they have finished a real download + virtual void Fetched(unsigned long Size,unsigned long ResumePoint); + + // Called to change media + virtual bool MediaChange(string Media,string Drive) = 0; + + // Each of these is called by the workers when an event occures + virtual void IMSHit(pkgAcquire::ItemDesc &/*Itm*/) {}; + virtual void Fetch(pkgAcquire::ItemDesc &/*Itm*/) {}; + virtual void Done(pkgAcquire::ItemDesc &/*Itm*/) {}; + virtual void Fail(pkgAcquire::ItemDesc &/*Itm*/) {}; + virtual bool Pulse(pkgAcquire *Owner); // returns false on user cancel + virtual void Start(); + virtual void Stop(); + + pkgAcquireStatus(); + virtual ~pkgAcquireStatus() {}; +}; + +#endif diff --git a/apt/apt-pkg/algorithms.cc b/apt/apt-pkg/algorithms.cc new file mode 100644 index 0000000..0a37d76 --- /dev/null +++ b/apt/apt-pkg/algorithms.cc @@ -0,0 +1,1177 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: algorithms.cc,v 1.11 2001/11/13 17:32:07 kojima Exp $ +/* ###################################################################### + + Algorithms - A set of misc algorithms + + The pkgProblemResolver class has become insanely complex and + very sophisticated, it handles every test case I have thrown at it + to my satisfaction. Understanding exactly why all the steps the class + does are required is difficult and changing though not very risky + may result in other cases not working. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/algorithms.h" +#endif +#include +#include +#include +#include + /*}}}*/ +#include + +pkgProblemResolver *pkgProblemResolver::This = 0; + +// Simulate::Simulate - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgSimulate::pkgSimulate(pkgDepCache &Cache) : pkgPackageManager(Cache), + Sim(Cache.GetMap()) +{ + Flags = new unsigned char[Cache.HeaderP->PackageCount]; + memset(Flags,0,sizeof(*Flags)*Cache.HeaderP->PackageCount); + + // Fake a filename so as not to activate the media swapping + string Jnk = "SIMULATE"; + for (unsigned int I = 0; I != Cache.Head().PackageCount; I++) + FileNames[I] = Jnk; +} + /*}}}*/ +// Simulate::Install - Simulate unpacking of a package /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSimulate::Install(PkgIterator iPkg,string /*File*/) +{ + // Adapt the iterator + PkgIterator Pkg = Sim.FindPkg(iPkg.Name()); + Flags[Pkg->ID] = 1; + + cout << "Inst " << Pkg.Name(); + Sim.MarkInstall(Pkg,false); + + // Look for broken conflicts+predepends. + for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++) + { + if (Sim[I].InstallVer == 0) + continue; + + for (DepIterator D = Sim[I].InstVerIter(Sim).DependsList(); D.end() == false; D++) + if (D->Type == pkgCache::Dep::Conflicts + || D->Type == pkgCache::Dep::Obsoletes + || D->Type == pkgCache::Dep::PreDepends) + { + if ((Sim[D] & pkgDepCache::DepInstall) == 0) + { + cout << " [" << I.Name() << " on " << D.TargetPkg().Name() << ']'; + if (D->Type == pkgCache::Dep::Conflicts) + _error->Error("Fatal, conflicts violated %s",I.Name()); + } + } + } + + if (Sim.BrokenCount() != 0) + ShortBreaks(); + else + cout << endl; + return true; +} + /*}}}*/ +// Simulate::Configure - Simulate configuration of a Package /*{{{*/ +// --------------------------------------------------------------------- +/* This is not an acurate simulation of relatity, we should really not + install the package.. For some investigations it may be necessary + however. */ +bool pkgSimulate::Configure(PkgIterator iPkg) +{ + // Adapt the iterator + PkgIterator Pkg = Sim.FindPkg(iPkg.Name()); + + Flags[Pkg->ID] = 2; +// Sim.MarkInstall(Pkg,false); + if (Sim[Pkg].InstBroken() == true) + { + cout << "Conf " << Pkg.Name() << " broken" << endl; + + Sim.Update(); + + // Print out each package and the failed dependencies + for (pkgCache::DepIterator D = Sim[Pkg].InstVerIter(Sim).DependsList(); D.end() == false; D++) + { + if (Sim.IsImportantDep(D) == false || + (Sim[D] & pkgDepCache::DepInstall) != 0) + continue; + + if (D->Type == pkgCache::Dep::Obsoletes) + cout << " Obsoletes:" << D.TargetPkg().Name(); + else if (D->Type == pkgCache::Dep::Conflicts) + cout << " Conflicts:" << D.TargetPkg().Name(); + else + cout << " Depends:" << D.TargetPkg().Name(); + } + cout << endl; + + _error->Error("Conf Broken %s",Pkg.Name()); + } + else + cout << "Conf " << Pkg.Name(); + + if (Sim.BrokenCount() != 0) + ShortBreaks(); + else + cout << endl; + + return true; +} + /*}}}*/ +// Simulate::Remove - Simulate the removal of a package /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSimulate::Remove(PkgIterator iPkg,bool Purge) +{ + // Adapt the iterator + PkgIterator Pkg = Sim.FindPkg(iPkg.Name()); + + Flags[Pkg->ID] = 3; + Sim.MarkDelete(Pkg); + if (Purge == true) + cout << "Purg " << Pkg.Name(); + else + cout << "Remv " << Pkg.Name(); + + if (Sim.BrokenCount() != 0) + ShortBreaks(); + else + cout << endl; + + return true; +} + /*}}}*/ +// Simulate::ShortBreaks - Print out a short line describing all breaks /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgSimulate::ShortBreaks() +{ + cout << " ["; + for (PkgIterator I = Sim.PkgBegin(); I.end() == false; I++) + { + if (Sim[I].InstBroken() == true) + { + if (Flags[I->ID] == 0) + cout << I.Name() << ' '; +/* else + cout << I.Name() << "! ";*/ + } + } + cout << ']' << endl; +} + /*}}}*/ +// ApplyStatus - Adjust for non-ok packages /*{{{*/ +// --------------------------------------------------------------------- +/* We attempt to change the state of the all packages that have failed + installation toward their real state. The ordering code will perform + the necessary calculations to deal with the problems. */ +bool pkgApplyStatus(pkgDepCache &Cache) +{ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + // Only choice for a ReInstReq package is to reinstall + if (I->InstState == pkgCache::State::ReInstReq || + I->InstState == pkgCache::State::HoldReInstReq) + { + if (I.CurrentVer().Downloadable() == true) + Cache.MarkKeep(I); + else + { + // Is this right? Will dpkg choke on an upgrade? + if (Cache[I].CandidateVerIter(Cache).Downloadable() == true) + Cache.MarkInstall(I); + else + return _error->Error(_("The package %s needs to be reinstalled, " + "but I can't find an archive for it."),I.Name()); + } + + continue; + } + + switch (I->CurrentState) + { + /* This means installation failed somehow - it does not need to be + re-unpacked (probably) */ + case pkgCache::State::UnPacked: + case pkgCache::State::HalfConfigured: + if (I.CurrentVer().Downloadable() == true || + I.State() != pkgCache::PkgIterator::NeedsUnpack) + Cache.MarkKeep(I); + else + { + if (Cache[I].CandidateVerIter(Cache).Downloadable() == true) + Cache.MarkInstall(I); + else + Cache.MarkDelete(I); + } + break; + + // This means removal failed + case pkgCache::State::HalfInstalled: + Cache.MarkDelete(I); + break; + + default: + if (I->InstState != pkgCache::State::Ok) + return _error->Error(_("The package %s is not ok and I " + "don't know how to fix it!"),I.Name()); + } + } + return true; +} + /*}}}*/ +// FixBroken - Fix broken packages /*{{{*/ +// --------------------------------------------------------------------- +/* This autoinstalls every broken package and then runs the problem resolver + on the result. */ +bool pkgFixBroken(pkgDepCache &Cache) +{ + // Auto upgrade all broken packages + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + if (Cache[I].NowBroken() == true) + Cache.MarkInstall(I,true); + + /* Fix packages that are in a NeedArchive state but don't have a + downloadable install version */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (I.State() != pkgCache::PkgIterator::NeedsUnpack || + Cache[I].Delete() == true) + continue; + + if (Cache[I].InstVerIter(Cache).Downloadable() == false) + continue; + + Cache.MarkInstall(I,true); + } + + pkgProblemResolver Fix(Cache); + return Fix.Resolve(true); +} + /*}}}*/ + +// DistUpgrade - Distribution upgrade /*{{{*/ +// --------------------------------------------------------------------- +/* This autoinstalls every package and then force installs every + pre-existing package. This creates the initial set of conditions which + most likely contain problems because too many things were installed. + + The problem resolver is used to resolve the problems. + */ +bool pkgDistUpgrade(pkgDepCache &Cache) +{ + /* Auto upgrade all installed packages, this provides the basis + for the installation */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + if (I->CurrentVer != 0) + Cache.MarkInstall(I,true); + + /* Now, auto upgrade all essential packages - this ensures that + the essential packages are present and working */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + Cache.MarkInstall(I,true); + + /* We do it again over all previously installed packages to force + conflict resolution on them all. */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + if (I->CurrentVer != 0) + Cache.MarkInstall(I,false); + + pkgProblemResolver Fix(Cache); + + // Hold back held packages. + if (_config->FindB("APT::Ignore-Hold",false) == false) + { + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (I->SelectedState == pkgCache::State::Hold) + { + Fix.Protect(I); + Cache.MarkKeep(I); + } + } + } + + return Fix.Resolve(); +} + /*}}}*/ +// AllUpgrade - Upgrade as many packages as possible /*{{{*/ +// --------------------------------------------------------------------- +/* Right now the system must be consistent before this can be called. + It also will not change packages marked for install, it only tries + to install packages not marked for install */ +bool pkgAllUpgrade(pkgDepCache &Cache) +{ + pkgProblemResolver Fix(Cache); + + if (Cache.BrokenCount() != 0) + return false; + + // Upgrade all installed packages + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (Cache[I].Install() == true) + Fix.Protect(I); + + if (_config->FindB("APT::Ignore-Hold",false) == false) { + if (I->SelectedState == pkgCache::State::Hold) + continue; + } + + if (I->CurrentVer != 0 && Cache[I].InstallVer != 0) { + Cache.MarkInstall(I,false); + } + } + + return Fix.ResolveByKeep(); +} + /*}}}*/ +// MinimizeUpgrade - Minimizes the set of packages to be upgraded /*{{{*/ +// --------------------------------------------------------------------- +/* This simply goes over the entire set of packages and tries to keep + each package marked for upgrade. If a conflict is generated then + the package is restored. */ +bool pkgMinimizeUpgrade(pkgDepCache &Cache) +{ + if (Cache.BrokenCount() != 0) + return false; + + // We loop indefinately to get the minimal set size. + bool Change = false; + unsigned int Count = 0; + do + { + Change = false; + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + // Not interesting + if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) + continue; + + // Keep it and see if that is OK + Cache.MarkKeep(I); + if (Cache.BrokenCount() != 0) + Cache.MarkInstall(I,false); + else + { + // If keep didnt actually do anything then there was no change.. + if (Cache[I].Upgrade() == false) + Change = true; + } + } + Count++; + } + while (Change == true && Count < 10); + + if (Cache.BrokenCount() != 0) + return _error->Error(_("Internal Error in pkgMinimizeUpgrade")); + + return true; +} + /*}}}*/ + +// ProblemResolver::pkgProblemResolver - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgProblemResolver::pkgProblemResolver(pkgDepCache &Cache) : Cache(Cache) +{ + // Allocate memory + unsigned long Size = Cache.HeaderP->PackageCount; + Scores = new signed short[Size]; + Flags = new unsigned char[Size]; + memset(Flags,0,sizeof(*Flags)*Size); + + // Set debug to true to see its decision logic + Debug = _config->FindB("Debug::pkgProblemResolver",false); +} + /*}}}*/ +// ProblemResolver::ScoreSort - Sort the list by score /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int pkgProblemResolver::ScoreSort(const void *a,const void *b) +{ + Package const **A = (Package const **)a; + Package const **B = (Package const **)b; + if (This->Scores[(*A)->ID] > This->Scores[(*B)->ID]) + return -1; + if (This->Scores[(*A)->ID] < This->Scores[(*B)->ID]) + return 1; + return 0; +} + /*}}}*/ +// ProblemResolver::MakeScores - Make the score table /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgProblemResolver::MakeScores() +{ + unsigned long Size = Cache.HeaderP->PackageCount; + memset(Scores,0,sizeof(*Scores)*Size); + + // Generate the base scores for a package based on its properties + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (Cache[I].InstallVer == 0) + continue; + + signed short &Score = Scores[I->ID]; + + /* This is arbitary, it should be high enough to elevate an + essantial package above most other packages but low enough + to allow an obsolete essential packages to be removed by + a conflicts on a powerfull normal package (ie libc6) */ + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + Score += 100; + + // We transform the priority + // Important Required Standard Optional Extra + signed short PrioMap[] = {0,3,2,1,-1,-2}; + if (Cache[I].InstVerIter(Cache)->Priority <= 5) + Score += PrioMap[Cache[I].InstVerIter(Cache)->Priority]; + + /* This helps to fix oddball problems with conflicting packages + on the same level. We enhance the score of installed packages */ + if (I->CurrentVer != 0) + Score += 1; + } + + // Now that we have the base scores we go and propogate dependencies + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (Cache[I].InstallVer == 0) + continue; + + for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false; D++) + { + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + Scores[D.TargetPkg()->ID]++; + } + } + + // Copy the scores to advoid additive looping + signed short *OldScores = new signed short[Size]; + memcpy(OldScores,Scores,sizeof(*Scores)*Size); + + /* Now we cause 1 level of dependency inheritance, that is we add the + score of the packages that depend on the target Package. This + fortifies high scoring packages */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (Cache[I].InstallVer == 0) + continue; + + for (pkgCache::DepIterator D = I.RevDependsList(); D.end() == false; D++) + { + // Only do it for the install version + if ((pkgCache::Version *)D.ParentVer() != Cache[D.ParentPkg()].InstallVer || + (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends)) + continue; + + Scores[I->ID] += abs(OldScores[D.ParentPkg()->ID]); + } + } + + /* Now we propogate along provides. This makes the packages that + provide important packages extremely important */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + for (pkgCache::PrvIterator P = I.ProvidesList(); P.end() == false; P++) + { + // Only do it once per package + if ((pkgCache::Version *)P.OwnerVer() != Cache[P.OwnerPkg()].InstallVer) + continue; + Scores[P.OwnerPkg()->ID] += abs(Scores[I->ID] - OldScores[I->ID]); + } + } + + /* Protected things are pushed really high up. This number should put them + ahead of everything */ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if ((Flags[I->ID] & Protected) != 0) + Scores[I->ID] += 10000; + if ((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + Scores[I->ID] += 5000; + } + + delete [] OldScores; +} + /*}}}*/ +// ProblemResolver::DoUpgrade - Attempt to upgrade this package /*{{{*/ +// --------------------------------------------------------------------- +/* This goes through and tries to reinstall packages to make this package + installable */ +bool pkgProblemResolver::DoUpgrade(pkgCache::PkgIterator Pkg) +{ + if ((Flags[Pkg->ID] & Upgradable) == 0 || Cache[Pkg].Upgradable() == false) + return false; + + Flags[Pkg->ID] &= ~Upgradable; + + bool WasKept = Cache[Pkg].Keep(); + Cache.MarkInstall(Pkg,false); + + // This must be a virtual package or something like that. + if (Cache[Pkg].InstVerIter(Cache).end() == true) + return false; + + // Isolate the problem dependency + bool Fail = false; + for (pkgCache::DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;) + { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start = D; + pkgCache::DepIterator End = D; + unsigned char State = 0; + for (bool LastOR = true; D.end() == false && LastOR == true;) + { + State |= Cache[D]; + LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + D++; + if (LastOR == true) + End = D; + } + + // We only worry about critical deps. + if (End.IsCritical() != true) + continue; + + // Iterate over all the members in the or group + while (1) + { + // Dep is ok now + if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) + break; + + // Do not change protected packages + PkgIterator P = Start.SmartTargetPkg(); + if ((Flags[P->ID] & Protected) == Protected) + { + if (Debug == true) + clog << " Reinst Failed because of protected " << P.Name() << endl; + Fail = true; + } + else + { + // Upgrade the package if the candidate version will fix the problem. + if ((Cache[Start] & pkgDepCache::DepCVer) == pkgDepCache::DepCVer) + { + if (DoUpgrade(P) == false) + { + if (Debug == true) + clog << " Reinst Failed because of " << P.Name() << endl; + Fail = true; + } + else + { + Fail = false; + break; + } + } + else + { + /* We let the algorithm deal with conflicts on its next iteration, + it is much smarter than us */ + if (Start->Type == pkgCache::Dep::Conflicts + || Start->Type == pkgCache::Dep::Obsoletes) + break; + + if (Debug == true) + clog << " Reinst Failed early because of " << Start.TargetPkg().Name() << endl; + Fail = true; + } + } + + if (Start == End) + break; + Start++; + } + if (Fail == true) + break; + } + + // Undo our operations - it might be smart to undo everything this did.. + if (Fail == true) + { + if (WasKept == true) + Cache.MarkKeep(Pkg); + else + Cache.MarkDelete(Pkg); + return false; + } + + if (Debug == true) + clog << " Re-Instated " << Pkg.Name() << endl; + return true; +} + /*}}}*/ +// ProblemResolver::Resolve - Run the resolution pass /*{{{*/ +// --------------------------------------------------------------------- +/* This routines works by calculating a score for each package. The score + is derived by considering the package's priority and all reverse + dependents giving an integer that reflects the amount of breakage that + adjusting the package will inflict. + + It goes from highest score to lowest and corrects all of the breaks by + keeping or removing the dependant packages. If that fails then it removes + the package itself and goes on. The routine should be able to intelligently + go from any broken state to a fixed state. + + The BrokenFix flag enables a mode where the algorithm tries to + upgrade packages to advoid problems. */ +bool pkgProblemResolver::Resolve(bool BrokenFix) +{ + unsigned long Size = Cache.HeaderP->PackageCount; + + // Record which packages are marked for install + bool Again = false; + do + { + Again = false; + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (Cache[I].Install() == true) + Flags[I->ID] |= PreInstalled; + else + { + if (Cache[I].InstBroken() == true && BrokenFix == true) + { + Cache.MarkInstall(I,false); + if (Cache[I].Install() == true) + Again = true; + } + + Flags[I->ID] &= ~PreInstalled; + } + Flags[I->ID] |= Upgradable; + } + } + while (Again == true); + + if (Debug == true) + clog << "Starting" << endl; + + MakeScores(); + + /* We have to order the packages so that the broken fixing pass + operates from highest score to lowest. This prevents problems when + high score packages cause the removal of lower score packages that + would cause the removal of even lower score packages. */ + pkgCache::Package **PList = new pkgCache::Package *[Size]; + pkgCache::Package **PEnd = PList; + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + *PEnd++ = I; + This = this; + qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort); + +/* for (pkgCache::Package **K = PList; K != PEnd; K++) + if (Scores[(*K)->ID] != 0) + { + pkgCache::PkgIterator Pkg(Cache,*K); + clog << Scores[(*K)->ID] << ' ' << Pkg.Name() << + ' ' << (pkgCache::Version *)Pkg.CurrentVer() << ' ' << + Cache[Pkg].InstallVer << ' ' << Cache[Pkg].CandidateVer << endl; + } */ + + if (Debug == true) + clog << "Starting 2" << endl; + + /* Now consider all broken packages. For each broken package we either + remove the package or fix it's problem. We do this once, it should + not be possible for a loop to form (that is a < b < c and fixing b by + changing a breaks c) */ + bool Change = true; + for (int Counter = 0; Counter != 10 && Change == true; Counter++) + { + Change = false; + for (pkgCache::Package **K = PList; K != PEnd; K++) + { + pkgCache::PkgIterator I(Cache,*K); + + /* We attempt to install this and see if any breaks result, + this takes care of some strange cases */ + if (Cache[I].CandidateVer != Cache[I].InstallVer && + I->CurrentVer != 0 && Cache[I].InstallVer != 0 && + (Flags[I->ID] & PreInstalled) != 0 && + (Flags[I->ID] & Protected) == 0 && + (Flags[I->ID] & ReInstateTried) == 0) + { + if (Debug == true) + clog << " Try to Re-Instate " << I.Name() << endl; + unsigned long OldBreaks = Cache.BrokenCount(); + pkgCache::Version *OldVer = Cache[I].InstallVer; + Flags[I->ID] &= ReInstateTried; + + Cache.MarkInstall(I,false); + if (Cache[I].InstBroken() == true || + OldBreaks < Cache.BrokenCount()) + { + if (OldVer == 0) + Cache.MarkDelete(I); + else + Cache.MarkKeep(I); + } + else + if (Debug == true) + clog << "Re-Instated " << I.Name() << " (" << OldBreaks << " vs " << Cache.BrokenCount() << ')' << endl; + } + + if (Cache[I].InstallVer == 0 || Cache[I].InstBroken() == false) + continue; + + // Isolate the problem dependency + PackageKill KillList[100]; + PackageKill *LEnd = KillList; + bool InOr = false; + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + PackageKill *OldEnd = 0; + + enum {OrRemove,OrKeep} OrOp = OrRemove; + for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); + D.end() == false || InOr == true;) + { + // Compute a single dependency element (glob or) + if (Start == End) + { + // Decide what to do + if (InOr == true) + { + if (OldEnd == LEnd && OrOp == OrRemove) + { + if ((Flags[I->ID] & Protected) != Protected) + Cache.MarkDelete(I); + } + if (OldEnd == LEnd && OrOp == OrKeep) + Cache.MarkKeep(I); + } + + OrOp = OrRemove; + D.GlobOr(Start,End); + InOr = Start != End; + OldEnd = LEnd; + } + else + Start++; + + // We only worry about critical deps. + if (End.IsCritical() != true) + continue; + + // Dep is ok + if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) + continue; + + if (Debug == true) + clog << "Package " << I.Name() << " has broken dep on " << Start.TargetPkg().Name() << endl; + + /* Look across the version list. If there are no possible + targets then we keep the package and bail. This is necessary + if a package has a dep on another package that cant be found */ + pkgCache::Version **VList = Start.AllTargets(); + + if (*VList == 0 && (Flags[I->ID] & Protected) != Protected && + Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::Obsoletes && + Cache[I].NowBroken() == false) + { + if (InOr == true) + { + /* No keep choice because the keep being OK could be the + result of another element in the OR group! */ + continue; + } + + Change = true; + Cache.MarkKeep(I); + break; + } + + bool Done = false; + for (pkgCache::Version **V = VList; *V != 0; V++) + { + pkgCache::VerIterator Ver(Cache,*V); + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + + if (Debug == true) + clog << " Considering " << Pkg.Name() << ' ' << (int)Scores[Pkg->ID] << + " as a solution to " << I.Name() << ' ' << (int)Scores[I->ID] << endl; + if (Scores[I->ID] <= Scores[Pkg->ID] || + ((Cache[Start] & pkgDepCache::DepNow) == 0 && + End->Type != pkgCache::Dep::Conflicts && + End->Type != pkgCache::Dep::Obsoletes)) + { + // Try a little harder to fix protected packages.. + if ((Flags[I->ID] & Protected) == Protected) + { + + if (DoUpgrade(Pkg) == true) + { + Scores[Pkg->ID] = Scores[I->ID]; + break; + } + + continue; + } + + /* See if a keep will do, unless the package is protected, + then installing it will be necessary */ + bool Installed = Cache[I].Install(); + Cache.MarkKeep(I); + if (Cache[I].InstBroken() == false) + { + // Unwind operation will be keep now + if (OrOp == OrRemove) + OrOp = OrKeep; + + // Restore + if (InOr == true && Installed == true) + Cache.MarkInstall(I,false); + + if (Debug == true) + clog << " Holding Back " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; + } + else + { + if (BrokenFix == false || DoUpgrade(I) == false) + { + // Consider other options + if (InOr == false) + { + pkgCache::Version **VV = V; + VV++; + if (*VV!=0) { + // Consider other options that might not be in a Or + continue; + } + if (Debug == true) + clog << " Removing " << I.Name() << " rather than change " << Start.TargetPkg().Name() << endl; + Cache.MarkDelete(I); + if (Counter > 1) + Scores[I->ID] = Scores[Pkg->ID]; + } + } + } + + Change = true; + Done = true; + break; + } + else + { + // Skip adding to the kill list if it is protected + if ((Flags[Pkg->ID] & Protected) != 0) + continue; + + if (*(V+1) != 0)//xxx look for other solutions? + continue; + + LEnd->Pkg = Pkg; + LEnd->Dep = End; + LEnd++; + + if (Start->Type != pkgCache::Dep::Conflicts + || Start->Type != pkgCache::Dep::Obsoletes) + break; + } + } + + // Hm, nothing can possibly satisify this dep. Nuke it. + if (VList[0] == 0 && Start->Type != pkgCache::Dep::Conflicts && + Start->Type != pkgCache::Dep::Obsoletes && + (Flags[I->ID] & Protected) != Protected) + { + bool Installed = Cache[I].Install(); + Cache.MarkKeep(I); + if (Cache[I].InstBroken() == false) + { + // Unwind operation will be keep now + if (OrOp == OrRemove) + OrOp = OrKeep; + + // Restore + if (InOr == true && Installed == true) + Cache.MarkInstall(I,false); + + if (Debug == true) + clog << " Holding Back " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl; + } + else + { + if (Debug == true) + clog << " Removing " << I.Name() << " because I can't find " << Start.TargetPkg().Name() << endl; + if (InOr == false) + Cache.MarkDelete(I); + } + + Change = true; + Done = true; + } + + delete [] VList; + + // Try some more + if (InOr == true) + continue; + + if (Done == true) + break; + } + + // Apply the kill list now + if (Cache[I].InstallVer != 0) + { + for (PackageKill *J = KillList; J != LEnd; J++) + { + Change = true; + if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0) + { + if (J->Dep->Type == pkgCache::Dep::Conflicts + || J->Dep->Type == pkgCache::Dep::Obsoletes) + { + if (Debug == true) + clog << " Fixing " << I.Name() << " via remove of " << J->Pkg.Name() << endl; + Cache.MarkDelete(J->Pkg, J->Dep->Type == pkgCache::Dep::Obsoletes); + } + } + else + { + if (Cache[J->Pkg].Install()) { + if (Debug == true) + clog << " Fixing " << I.Name() << " via keep of " << J->Pkg.Name() << endl; + Cache.MarkKeep(J->Pkg); + } else { + if (Debug == true) + clog << " Fixing " << I.Name() << " via install of " << J->Pkg.Name() << endl; + Cache.MarkInstall(J->Pkg, true); + } + } + + if (Counter > 1) + Scores[J->Pkg->ID] = Scores[I->ID]; + } + } + } + } + + if (Debug == true) + clog << "Done" << endl; + + delete [] Scores; + delete [] PList; + + if (Cache.BrokenCount() != 0) + { + // See if this is the result of a hold + pkgCache::PkgIterator I = Cache.PkgBegin(); + for (;I.end() != true; I++) + { + if (Cache[I].InstBroken() == false) + continue; + if ((Flags[I->ID] & Protected) != Protected) + return _error->Error(_("Error, pkgProblemResolver::Resolve generated breaks, this may be caused by held packages.")); + } + return _error->Error(_("Unable to correct problems, you have held broken packages.")); + } + + return true; +} + /*}}}*/ +// ProblemResolver::ResolveByKeep - Resolve problems using keep /*{{{*/ +// --------------------------------------------------------------------- +/* This is the work horse of the soft upgrade routine. It is very gental + in that it does not install or remove any packages. It is assumed that the + system was non-broken previously. */ +bool pkgProblemResolver::ResolveByKeep() +{ + unsigned long Size = Cache.HeaderP->PackageCount; + + if (Debug == true) + clog << "Entering ResolveByKeep" << endl; + + MakeScores(); + + /* We have to order the packages so that the broken fixing pass + operates from highest score to lowest. This prevents problems when + high score packages cause the removal of lower score packages that + would cause the removal of even lower score packages. */ + pkgCache::Package **PList = new pkgCache::Package *[Size]; + pkgCache::Package **PEnd = PList; + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + *PEnd++ = I; + This = this; + qsort(PList,PEnd - PList,sizeof(*PList),&ScoreSort); + + // Consider each broken package + pkgCache::Package **LastStop = 0; + for (pkgCache::Package **K = PList; K != PEnd; K++) + { + pkgCache::PkgIterator I(Cache,*K); + + if (Cache[I].InstallVer == 0 || Cache[I].InstBroken() == false) + continue; + + /* Keep the package. If this works then great, otherwise we have + to be significantly more agressive and manipulate its dependencies */ + if ((Flags[I->ID] & Protected) == 0) + { + if (Debug == true) + clog << "Keeping package " << I.Name() << endl; + Cache.MarkKeep(I); + if (Cache[I].InstBroken() == false) + { + K = PList; + continue; + } + } + + // Isolate the problem dependencies + for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;) + { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start = D; + pkgCache::DepIterator End = D; + unsigned char State = 0; + for (bool LastOR = true; D.end() == false && LastOR == true; D++) + { + State |= Cache[D]; + LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + if (LastOR == true) + End = D; + } + + // We only worry about critical deps. + if (End.IsCritical() != true) + continue; + + // Dep is ok + if ((Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) + continue; + + // Hm, the group is broken.. I have no idea how to handle this + if (Start != End) + { + clog << _("Note, a broken package or group was found in ") << I.Name() << "." << endl; + if ((Flags[I->ID] & Protected) == 0) + Cache.MarkKeep(I); + break; + } + + if (Debug == true) + clog << "Package " << I.Name() << " has broken dep on " << End.TargetPkg().Name() << endl; + + // Look at all the possible provides on this package + pkgCache::Version **VList = End.AllTargets(); + for (pkgCache::Version **V = VList; *V != 0; V++) + { + pkgCache::VerIterator Ver(Cache,*V); + pkgCache::PkgIterator Pkg = Ver.ParentPkg(); + + // It is not keepable + if (Cache[Pkg].InstallVer == 0 || + Pkg->CurrentVer == 0) + continue; + + if ((Flags[I->ID] & Protected) == 0) + { + if (Debug == true) + clog << " Keeping Package " << Pkg.Name() << " due to dep" << endl; + Cache.MarkKeep(Pkg); + } + + if (Cache[I].InstBroken() == false) + break; + } + + if (Cache[I].InstBroken() == false) + break; + } + + if (Cache[I].InstBroken() == true) + continue; + + // Restart again. + if (K == LastStop) + return _error->Error("Internal Error, pkgProblemResolver::ResolveByKeep is looping on package %s.",I.Name()); + LastStop = K; + K = PList; + } + + return true; +} /*}}}*/ +// ProblemResolver::InstallProtect - Install all protected packages /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to make sure protected packages are installed */ +void pkgProblemResolver::InstallProtect() +{ + for (pkgCache::PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if ((Flags[I->ID] & Protected) == Protected) + { + if ((Flags[I->ID] & ToRemove) == ToRemove) + Cache.MarkDelete(I); + else + Cache.MarkInstall(I,false); + } + } +} + /*}}}*/ +#if 0 + +class pkgMyUpgrader { + pkgCache::Package *packL; + + void topoSort(); + + public: + pkgMyUpgrader(pkgDepCache &Cache); + ~pkgMyUpgrader(); +}; + + +pkgMyUpgrader::pkgMyUpgrader(pkgDepCache &Cache) +{ + unsigned long size = Cache.HeaderP->PackageCount; + int i; + + packL = new PackInfo[size]; + + // topologically sort the packages, so that if A depends on B, + // then index of B is < index of A + topoSort(); +} + + + +pkgMyUpgrader::~pkgMyUpgrader() +{ + free(packL); +} + + + +void pkgMyUpgrader::topoSort() +{ + char *colours = new char[Size]; + + + + + + delete [] colours; +} + + + + + +#endif diff --git a/apt/apt-pkg/algorithms.h b/apt/apt-pkg/algorithms.h new file mode 100644 index 0000000..1ba31a1 --- /dev/null +++ b/apt/apt-pkg/algorithms.h @@ -0,0 +1,113 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: algorithms.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Algorithms - A set of misc algorithms + + This simulate class displays what the ordering code has done and + analyses it with a fresh new dependency cache. In this way we can + see all of the effects of an upgrade run. + + pkgDistUpgrade computes an upgrade that causes as many packages as + possible to move to the newest verison. + + pkgApplyStatus sets the target state based on the content of the status + field in the status file. It is important to get proper crash recovery. + + pkgFixBroken corrects a broken system so that it is in a sane state. + + pkgAllUpgrade attempts to upgade as many packages as possible but + without installing new packages. + + The problem resolver class contains a number of complex algorithms + to try to best-guess an upgrade state. It solves the problem of + maximizing the number of install state packages while having no broken + packages. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_ALGORITHMS_H +#define PKGLIB_ALGORITHMS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/algorithms.h" +#endif + +#include +#include + +class pkgSimulate : public pkgPackageManager +{ + protected: + + unsigned char *Flags; + + pkgDepCache Sim; + + // The Actuall installation implementation + virtual bool Install(PkgIterator Pkg,string File); + virtual bool Configure(PkgIterator Pkg); + virtual bool Remove(PkgIterator Pkg,bool Purge); + void ShortBreaks(); + + public: + + pkgSimulate(pkgDepCache &Cache); +}; + +class pkgProblemResolver +{ + pkgDepCache &Cache; + typedef pkgCache::PkgIterator PkgIterator; + typedef pkgCache::VerIterator VerIterator; + typedef pkgCache::DepIterator DepIterator; + typedef pkgCache::PrvIterator PrvIterator; + typedef pkgCache::Version Version; + typedef pkgCache::Package Package; + + enum Flags {Protected = (1 << 0), PreInstalled = (1 << 1), + Upgradable = (1 << 2), ReInstateTried = (1 << 3), + ToRemove = (1 << 4)}; + signed short *Scores; + unsigned char *Flags; + bool Debug; + + // Sort stuff + static pkgProblemResolver *This; + static int ScoreSort(const void *a,const void *b); + + struct PackageKill + { + PkgIterator Pkg; + DepIterator Dep; + }; + + void MakeScores(); + bool DoUpgrade(pkgCache::PkgIterator Pkg); + + public: + + inline void Protect(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= Protected;}; + inline void Remove(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] |= ToRemove;}; + inline void Clear(pkgCache::PkgIterator Pkg) {Flags[Pkg->ID] &= ~(Protected | ToRemove);}; + + // Try to intelligently resolve problems by installing and removing packages + bool Resolve(bool BrokenFix = false); + + // Try to resolve problems only by using keep + bool ResolveByKeep(); + + void InstallProtect(); + + pkgProblemResolver(pkgDepCache &Cache); +}; + +bool pkgDistUpgrade(pkgDepCache &Cache); +bool pkgApplyStatus(pkgDepCache &Cache); +bool pkgFixBroken(pkgDepCache &Cache); +bool pkgAllUpgrade(pkgDepCache &Cache); +bool pkgMinimizeUpgrade(pkgDepCache &Cache); + +#endif diff --git a/apt/apt-pkg/cachefile.cc b/apt/apt-pkg/cachefile.cc new file mode 100644 index 0000000..af8831b --- /dev/null +++ b/apt/apt-pkg/cachefile.cc @@ -0,0 +1,123 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cachefile.cc,v 1.8 2001/07/12 21:47:32 kojima Exp $ +/* ###################################################################### + + CacheFile - Simple wrapper class for opening, generating and whatnot + + This class implements a simple 2 line mechanism to open various sorts + of caches. It can operate as root, as not root, show progress and so on, + it transparently handles everything necessary. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/cachefile.h" +#endif + + +#include +#include +#include +#include +#include +#include + +#include + + /*}}}*/ + +// CacheFile::CacheFile - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCacheFile::pkgCacheFile() : Map(0), Cache(0), +#if 0//akk +Lock(0), +#endif +RPM(0) +{ +} + /*}}}*/ +// CacheFile::~CacheFile - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCacheFile::~pkgCacheFile() +{ + delete Cache; + delete Map; +#if 0//akk + if (Lock) + delete Lock; +#endif + if (RPM) + delete RPM; +} + /*}}}*/ +// CacheFile::Open - Open the cache files, creating if necessary /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheFile::Open(OpProgress &Progress,bool WithLock) +{ + if (WithLock == true) + { +#if 0 //akk + if (0)//akk + { + Lock = new pkgDpkgLock; + } else + { + + } +#endif + } + if (1) { + RPM = new pkgRpmLock(WithLock); + } + + if (_error->PendingError() == true) + return false; + + // Read the source list + pkgSourceList List; + if (List.ReadMainList() == false) + return _error->Error(_("The list of sources could not be read.")); + + /* Build all of the caches, using the cache files if we are locking + (ie as root) */ + if (WithLock == true) + { + _system->makeStatusCache(List, Progress); + + Progress.Done(); + if (_error->PendingError() == true) + return _error->Error(_("The package lists or status file could not be parsed or opened.")); + if (_error->empty() == false) + _error->Warning(_("You may want to run apt-get update to correct these missing files")); + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + + Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + return false; + } + else + { + Map = _system->makeStatusCacheMem(List,Progress); + Progress.Done(); + if (Map == 0) + return false; + } + + // Create the dependency cache + Cache = new pkgDepCache(*Map,Progress); + Progress.Done(); + if (_error->PendingError() == true) + return false; + + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/cachefile.h b/apt/apt-pkg/cachefile.h new file mode 100644 index 0000000..158f5b3 --- /dev/null +++ b/apt/apt-pkg/cachefile.h @@ -0,0 +1,63 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cachefile.h,v 1.4 2001/07/12 21:47:32 kojima Exp $ +/* ###################################################################### + + CacheFile - Simple wrapper class for opening, generating and whatnot + + This class implements a simple 2 line mechanism to open various sorts + of caches. It can operate as root, as not root, show progress and so on, + it transparently handles everything necessary. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_CACHEFILE_H +#define PKGLIB_CACHEFILE_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/cachefile.h" +#endif + + +#include +#include +#include + +class pkgCacheFile +{ + protected: + + MMap *Map; + pkgDepCache *Cache; +#if 0//akk + pkgDpkgLock *Lock; +#endif + pkgRpmLock *RPM; + + public: + + // We look pretty much exactly like a pointer to a dep cache + inline operator pkgDepCache &() {return *Cache;}; + inline operator pkgDepCache *() {return Cache;}; + inline pkgDepCache *operator ->() {return Cache;}; + inline pkgDepCache &operator *() {return *Cache;}; + inline pkgDepCache::StateCache &operator [](pkgCache::PkgIterator const &I) {return (*Cache)[I];}; + inline unsigned char &operator [](pkgCache::DepIterator const &I) {return (*Cache)[I];}; + + // Release the dpkg status lock + inline void ReleaseLock() { +#if 0//akk + if (0) + Lock->Close(); + else +#endif + RPM->Close(); + };//akk + + bool Open(OpProgress &Progress,bool WithLock = true); + + pkgCacheFile(); + ~pkgCacheFile(); +}; + +#endif diff --git a/apt/apt-pkg/cacheiterators.h b/apt/apt-pkg/cacheiterators.h new file mode 100644 index 0000000..bb0ae84 --- /dev/null +++ b/apt/apt-pkg/cacheiterators.h @@ -0,0 +1,350 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cacheiterators.h,v 1.2 2000/09/20 15:20:06 kojima Exp $ +/* ###################################################################### + + Cache Iterators - Iterators for navigating the cache structure + + The iterators all provides ++,==,!=,->,* and end for their type. + The end function can be used to tell if the list has been fully + traversed. + + Unlike STL iterators these contain helper functions to access the data + that is being iterated over. This is because the data structures can't + be formed in a manner that is intuitive to use and also mmapable. + + For each variable in the target structure that would need a translation + to be accessed correctly a translating function of the same name is + present in the iterator. If applicable the translating function will + return an iterator. + + The DepIterator can iterate over two lists, a list of 'version depends' + or a list of 'package reverse depends'. The type is determined by the + structure passed to the constructor, which should be the structure + that has the depends pointer as a member. The provide iterator has the + same system. + + This header is not user includable, please use apt-pkg/pkgcache.h + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_CACHEITERATORS_H +#define PKGLIB_CACHEITERATORS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/cacheiterators.h" +#endif + +// Package Iterator +class pkgCache::PkgIterator +{ + Package *Pkg; + pkgCache *Owner; + long HashIndex; + + public: + + enum OkState {NeedsNothing,NeedsUnpack,NeedsConfigure}; + + // Iteration + void operator ++(int); + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == 0 || Pkg == Owner->PkgP?true:false;}; + + // Comparison + inline bool operator ==(const PkgIterator &B) const {return Pkg == B.Pkg;}; + inline bool operator !=(const PkgIterator &B) const {return Pkg != B.Pkg;}; + + // Accessors + inline Package *operator ->() {return Pkg;}; + inline Package const *operator ->() const {return Pkg;}; + inline Package const &operator *() const {return *Pkg;}; + inline operator Package *() {return Pkg == Owner->PkgP?0:Pkg;}; + inline operator Package const *() const {return Pkg == Owner->PkgP?0:Pkg;}; + + inline const char *Name() const {return Pkg->Name == 0?0:Owner->StrP + Pkg->Name;}; + inline const char *Section() const {return Pkg->Section == 0?0:Owner->StrP + Pkg->Section;}; + inline const char *TargetDist() const {return Pkg->TargetDist == 0?0:Owner->StrP + Pkg->TargetDist;}; + inline bool Purge() const {return Pkg->CurrentState == pkgCache::State::Purge || + (Pkg->CurrentVer == 0 && Pkg->CurrentState == pkgCache::State::NotInstalled);}; + inline VerIterator VersionList() const; + inline VerIterator TargetVer() const; + inline VerIterator CurrentVer() const; + inline DepIterator RevDependsList() const; + inline PrvIterator ProvidesList() const; + inline unsigned long Index() const {return Pkg - Owner->PkgP;}; + OkState State() const; + + // Constructors + inline PkgIterator(pkgCache &Owner) : Owner(&Owner), HashIndex(-1) + { + Pkg = Owner.PkgP; + operator ++(0); + }; + inline PkgIterator(pkgCache &Owner,Package *Trg) : Pkg(Trg), Owner(&Owner), + HashIndex(0) + { + if (Pkg == 0) + Pkg = Owner.PkgP; + }; + inline PkgIterator() : Pkg(0), Owner(0), HashIndex(0) {}; +}; + +// Version Iterator +class pkgCache::VerIterator +{ + Version *Ver; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Ver != Owner->VerP) Ver = Owner->VerP + Ver->NextVer;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Ver == Owner->VerP?true:false;}; + inline void operator =(const VerIterator &B) {Ver = B.Ver; Owner = B.Owner;}; + + // Comparison + inline bool operator ==(const VerIterator &B) const {return Ver == B.Ver;}; + inline bool operator !=(const VerIterator &B) const {return Ver != B.Ver;}; + int CompareVer(const VerIterator &B) const; + + // Accessors + inline Version *operator ->() {return Ver;}; + inline Version const *operator ->() const {return Ver;}; + inline Version &operator *() {return *Ver;}; + inline Version const &operator *() const {return *Ver;}; + inline operator Version *() {return Ver == Owner->VerP?0:Ver;}; + inline operator Version const *() const {return Ver == Owner->VerP?0:Ver;}; + + inline const char *VerStr() const {return Ver->VerStr == 0?0:Owner->StrP + Ver->VerStr;}; + inline const char *Section() const {return Ver->Section == 0?0:Owner->StrP + Ver->Section;}; + inline const char *Arch() const {return Ver->Arch == 0?0:Owner->StrP + Ver->Arch;}; + inline PkgIterator ParentPkg() const {return PkgIterator(*Owner,Owner->PkgP + Ver->ParentPkg);}; + inline DepIterator DependsList() const; + inline PrvIterator ProvidesList() const; + inline VerFileIterator FileList() const; + inline unsigned long Index() const {return Ver - Owner->VerP;}; + bool Downloadable() const; + const char *PriorityType(); + + bool Automatic() const; + VerFileIterator NewestFile() const; + + inline VerIterator() : Ver(0), Owner(0) {}; + inline VerIterator(pkgCache &Owner,Version *Trg = 0) : Ver(Trg), + Owner(&Owner) + { + if (Ver == 0) + Ver = Owner.VerP; + }; +}; + +// Dependency iterator +class pkgCache::DepIterator +{ + Dependency *Dep; + enum {DepVer, DepRev} Type; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Dep != Owner->DepP) Dep = Owner->DepP + + (Type == DepVer?Dep->NextDepends:Dep->NextRevDepends);}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Owner == 0 || Dep == Owner->DepP?true:false;}; + + // Comparison + inline bool operator ==(const DepIterator &B) const {return Dep == B.Dep;}; + inline bool operator !=(const DepIterator &B) const {return Dep != B.Dep;}; + + // Accessors + inline Dependency *operator ->() {return Dep;}; + inline Dependency const *operator ->() const {return Dep;}; + inline Dependency &operator *() {return *Dep;}; + inline Dependency const &operator *() const {return *Dep;}; + inline operator Dependency *() {return Dep == Owner->DepP?0:Dep;}; + inline operator Dependency const *() const {return Dep == Owner->DepP?0:Dep;}; + + inline const char *TargetVer() const {return Dep->Version == 0?0:Owner->StrP + Dep->Version;}; + inline PkgIterator TargetPkg() {return PkgIterator(*Owner,Owner->PkgP + Dep->Package);}; + inline PkgIterator SmartTargetPkg() {PkgIterator R(*Owner);SmartTargetPkg(R);return R;}; + inline VerIterator ParentVer() {return VerIterator(*Owner,Owner->VerP + Dep->ParentVer);}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Dep->ParentVer].ParentPkg);}; + inline bool Reverse() {return Type == DepRev;}; + inline unsigned long Index() const {return Dep - Owner->DepP;}; + bool IsCritical(); + void GlobOr(DepIterator &Start,DepIterator &End); + Version **AllTargets(); + bool SmartTargetPkg(PkgIterator &Result); + const char *CompType(); + const char *DepType(); + + inline DepIterator(pkgCache &Owner,Dependency *Trg,Version * = 0) : + Dep(Trg), Type(DepVer), Owner(&Owner) + { + if (Dep == 0) + Dep = Owner.DepP; + }; + inline DepIterator(pkgCache &Owner,Dependency *Trg,Package *) : + Dep(Trg), Type(DepRev), Owner(&Owner) + { + if (Dep == 0) + Dep = Owner.DepP; + }; + inline DepIterator() : Dep(0), Type(DepVer), Owner(0) {}; +}; + +// Provides iterator +class pkgCache::PrvIterator +{ + Provides *Prv; + enum {PrvVer, PrvPkg} Type; + pkgCache *Owner; + + void _dummy(); + + public: + + // Iteration + void operator ++(int) {if (Prv != Owner->ProvideP) Prv = Owner->ProvideP + + (Type == PrvVer?Prv->NextPkgProv:Prv->NextProvides);}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return Prv == Owner->ProvideP?true:false;}; + + // Comparison + inline bool operator ==(const PrvIterator &B) const {return Prv == B.Prv;}; + inline bool operator !=(const PrvIterator &B) const {return Prv != B.Prv;}; + + // Accessors + inline Provides *operator ->() {return Prv;}; + inline Provides const *operator ->() const {return Prv;}; + inline Provides &operator *() {return *Prv;}; + inline Provides const &operator *() const {return *Prv;}; + inline operator Provides *() {return Prv == Owner->ProvideP?0:Prv;}; + inline operator Provides const *() const {return Prv == Owner->ProvideP?0:Prv;}; + + inline const char *Name() const {return Owner->StrP + Owner->PkgP[Prv->ParentPkg].Name;}; + inline const char *ProvideVersion() const {return Prv->ProvideVersion == 0?0:Owner->StrP + Prv->ProvideVersion;}; + inline PkgIterator ParentPkg() {return PkgIterator(*Owner,Owner->PkgP + Prv->ParentPkg);}; + inline VerIterator OwnerVer() {return VerIterator(*Owner,Owner->VerP + Prv->Version);}; + inline PkgIterator OwnerPkg() {return PkgIterator(*Owner,Owner->PkgP + Owner->VerP[Prv->Version].ParentPkg);}; + inline unsigned long Index() const {return Prv - Owner->ProvideP;}; + + inline PrvIterator(pkgCache &Owner,Provides *Trg,Version *) : + Prv(Trg), Type(PrvVer), Owner(&Owner) + { + if (Prv == 0) + Prv = Owner.ProvideP; + }; + inline PrvIterator(pkgCache &Owner,Provides *Trg,Package *) : + Prv(Trg), Type(PrvPkg), Owner(&Owner) + { + if (Prv == 0) + Prv = Owner.ProvideP; + }; +}; + +// Package file +class pkgCache::PkgFileIterator +{ + pkgCache *Owner; + PackageFile *File; + + public: + + // Iteration + void operator ++(int) {if (File!= Owner->PkgFileP) File = Owner->PkgFileP + File->NextFile;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return File == Owner->PkgFileP?true:false;}; + + // Comparison + inline bool operator ==(const PkgFileIterator &B) const {return File == B.File;}; + inline bool operator !=(const PkgFileIterator &B) const {return File != B.File;}; + + // Accessors + inline PackageFile *operator ->() {return File;}; + inline PackageFile const *operator ->() const {return File;}; + inline PackageFile const &operator *() const {return *File;}; + inline operator PackageFile *() {return File == Owner->PkgFileP?0:File;}; + inline operator PackageFile const *() const {return File == Owner->PkgFileP?0:File;}; + + inline const char *FileName() const {return File->FileName == 0?0:Owner->StrP + File->FileName;}; + inline const char *Archive() const {return File->Archive == 0?0:Owner->StrP + File->Archive;}; + inline const char *Component() const {return File->Component == 0?0:Owner->StrP + File->Component;}; + inline const char *Version() const {return File->Version == 0?0:Owner->StrP + File->Version;}; + inline const char *Origin() const {return File->Origin == 0?0:Owner->StrP + File->Origin;}; + inline const char *Label() const {return File->Origin == 0?0:Owner->StrP + File->Label;}; + inline const char *Architecture() const {return File->Origin == 0?0:Owner->StrP + File->Architecture;}; + + inline unsigned long Index() const {return File - Owner->PkgFileP;}; + + bool IsOk(); + + // Constructors + inline PkgFileIterator(pkgCache &Owner) : Owner(&Owner), File(Owner.PkgFileP + Owner.Head().FileList) {}; + inline PkgFileIterator(pkgCache &Owner,PackageFile *Trg) : Owner(&Owner), File(Trg) {}; +}; + +// Version File +class pkgCache::VerFileIterator +{ + pkgCache *Owner; + VerFile *FileP; + + public: + + // Iteration + void operator ++(int) {if (FileP != Owner->VerFileP) FileP = Owner->VerFileP + FileP->NextFile;}; + inline void operator ++() {operator ++(0);}; + inline bool end() const {return FileP == Owner->VerFileP?true:false;}; + + // Comparison + inline bool operator ==(const VerFileIterator &B) const {return FileP == B.FileP;}; + inline bool operator !=(const VerFileIterator &B) const {return FileP != B.FileP;}; + + // Accessors + inline VerFile *operator ->() {return FileP;}; + inline VerFile const *operator ->() const {return FileP;}; + inline VerFile const &operator *() const {return *FileP;}; + inline operator VerFile *() {return FileP == Owner->VerFileP?0:FileP;}; + inline operator VerFile const *() const {return FileP == Owner->VerFileP?0:FileP;}; + + inline PkgFileIterator File() const {return PkgFileIterator(*Owner,FileP->File + Owner->PkgFileP);}; + inline unsigned long Index() const {return FileP - Owner->VerFileP;}; + + inline VerFileIterator(pkgCache &Owner,VerFile *Trg) : Owner(&Owner), FileP(Trg) {}; +}; + +// Inlined Begin functions cant be in the class because of order problems +inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const + {return VerIterator(*Owner,Owner->VerP + Pkg->VersionList);}; + +inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const + {return VerIterator(*Owner,Owner->VerP + Pkg->CurrentVer);}; + +inline pkgCache::VerIterator pkgCache::PkgIterator::TargetVer() const + {return VerIterator(*Owner,Owner->VerP + Pkg->TargetVer);}; + +inline pkgCache::DepIterator pkgCache::PkgIterator::RevDependsList() const + {return DepIterator(*Owner,Owner->DepP + Pkg->RevDepends,Pkg);}; + +inline pkgCache::PrvIterator pkgCache::PkgIterator::ProvidesList() const + {return PrvIterator(*Owner,Owner->ProvideP + Pkg->ProvidesList,Pkg);}; + +inline pkgCache::PrvIterator pkgCache::VerIterator::ProvidesList() const + {return PrvIterator(*Owner,Owner->ProvideP + Ver->ProvidesList,Ver);}; + +inline pkgCache::DepIterator pkgCache::VerIterator::DependsList() const + {return DepIterator(*Owner,Owner->DepP + Ver->DependsList,Ver);}; + +inline pkgCache::VerFileIterator pkgCache::VerIterator::FileList() const + {return VerFileIterator(*Owner,Owner->VerFileP + Ver->FileList);}; + +#endif diff --git a/apt/apt-pkg/clean.cc b/apt/apt-pkg/clean.cc new file mode 100644 index 0000000..2950810 --- /dev/null +++ b/apt/apt-pkg/clean.cc @@ -0,0 +1,117 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: clean.cc,v 1.2 2001/01/11 02:03:26 kojima Exp $ +/* ###################################################################### + + Clean - Clean out downloaded directories + + ##################################################################### */ + /*}}}*/ +// Includes /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/clean.h" +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#include + + /*}}}*/ + +// ArchiveCleaner::Go - Perform smart cleanup of the archive /*{{{*/ +// --------------------------------------------------------------------- +/* Scan the directory for files to erase, we check the version information + against our database to see if it is interesting */ +bool pkgArchiveCleaner::Go(string Dir,pkgCache &Cache) +{ + bool CleanInstalled = _config->FindB("APT::Clean-Installed",true); + + DIR *D = opendir(Dir.c_str()); + if (D == 0) + return _error->Errno("opendir",_("Unable to read %s"),Dir.c_str()); + + string StartDir = SafeGetCWD(); + if (chdir(Dir.c_str()) != 0) + { + closedir(D); + return _error->Errno("chdir",_("Unable to change to "),Dir.c_str()); + } + + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + // Skip some files.. + if (strcmp(Dir->d_name,"lock") == 0 || + strcmp(Dir->d_name,"partial") == 0 || + strcmp(Dir->d_name,".") == 0 || + strcmp(Dir->d_name,"..") == 0) + continue; + + struct stat St; + if (stat(Dir->d_name,&St) != 0) + return _error->Errno("stat",_("Unable to stat %s."),Dir->d_name); + + // Grab the package name + const char *I = Dir->d_name; + for (; *I != 0 && *I != '_';I++); + if (*I != '_') + continue; + string Pkg = DeQuoteString(string(Dir->d_name,I-Dir->d_name)); + + // Grab the version + const char *Start = I + 1; + for (I = Start; *I != 0 && *I != '_';I++); + if (*I != '_') + continue; + string Ver = DeQuoteString(string(Start,I-Start)); + + // Grab the arch + Start = I + 1; + for (I = Start; *I != 0 && *I != '.' ;I++); + if (*I != '.') + continue; + string Arch = DeQuoteString(string(Start,I-Start)); + + // Lookup the package + pkgCache::PkgIterator P = Cache.FindPkg(Pkg); + if (P.end() != true) + { + pkgCache::VerIterator V = P.VersionList(); + for (; V.end() == false; V++) + { + // See if we can fetch this version at all + bool IsFetchable = false; + for (pkgCache::VerFileIterator J = V.FileList(); + J.end() == false; J++) + { + if (CleanInstalled == true && + (J.File()->Flags & pkgCache::Flag::NotSource) != 0) + continue; + IsFetchable = true; + break; + } + + // See if this verison matches the file + if (IsFetchable == true && Ver == V.VerStr()) + break; + } + + // We found a match, keep the file + if (V.end() == false) + continue; + } + + Erase(Dir->d_name,Pkg,Ver,St); + }; + + chdir(StartDir.c_str()); + closedir(D); + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/clean.h b/apt/apt-pkg/clean.h new file mode 100644 index 0000000..807349a --- /dev/null +++ b/apt/apt-pkg/clean.h @@ -0,0 +1,30 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: clean.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Clean - Clean out downloaded directories + + ##################################################################### */ + /*}}}*/ +#ifndef APTPKG_CLEAN_H +#define APTPKG_CLEAN_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/clean.h" +#endif + +#include + +class pkgArchiveCleaner +{ + protected: + + virtual void Erase(const char * /*File*/,string /*Pkg*/,string /*Ver*/,struct stat & /*St*/) {}; + + public: + + bool Go(string Dir,pkgCache &Cache); +}; + +#endif diff --git a/apt/apt-pkg/cnc/CVS/Entries b/apt/apt-pkg/cnc/CVS/Entries new file mode 100644 index 0000000..1784810 --- /dev/null +++ b/apt/apt-pkg/cnc/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/apt/apt-pkg/cnc/CVS/Repository b/apt/apt-pkg/cnc/CVS/Repository new file mode 100644 index 0000000..95f956e --- /dev/null +++ b/apt/apt-pkg/cnc/CVS/Repository @@ -0,0 +1 @@ +rapt/apt-pkg/cnc diff --git a/apt/apt-pkg/cnc/CVS/Root b/apt/apt-pkg/cnc/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/apt-pkg/cnc/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/apt-pkg/contrib/CVS/Entries b/apt/apt-pkg/contrib/CVS/Entries new file mode 100644 index 0000000..845f523 --- /dev/null +++ b/apt/apt-pkg/contrib/CVS/Entries @@ -0,0 +1,24 @@ +/cdromutl.cc/1.1.1.1/Fri Aug 10 14:00:24 2001// +/cdromutl.h/1.1.1.1/Fri Aug 10 14:00:24 2001// +/cmndline.cc/1.1.1.1/Fri Aug 10 14:00:24 2001// +/cmndline.h/1.1.1.1/Fri Aug 10 14:00:28 2001// +/configuration.cc/1.2/Fri Aug 10 14:00:30 2001// +/configuration.h/1.2/Fri Aug 10 14:00:30 2001// +/crc-16.cc/1.1.1.1/Fri Aug 10 14:00:30 2001// +/crc-16.h/1.1.1.1/Fri Aug 10 14:00:30 2001// +/error.h/1.1.1.1/Fri Aug 10 14:00:30 2001// +/fileutl.cc/1.3/Fri Aug 10 14:00:30 2001// +/fileutl.h/1.2/Fri Aug 10 14:00:30 2001// +/md5.cc/1.1.1.1/Fri Aug 10 14:00:32 2001// +/md5.h/1.1.1.1/Fri Aug 10 14:00:32 2001// +/mmap.cc/1.1.1.1/Fri Aug 10 14:00:32 2001// +/mmap.h/1.1.1.1/Fri Aug 10 14:00:32 2001// +/progress.h/1.1.1.1/Fri Aug 10 14:00:32 2001// +/sptr.h/1.1/Fri Aug 10 14:00:34 2001// +/strutl.cc/1.3/Fri Aug 10 14:00:34 2001// +/strutl.h/1.3/Fri Aug 10 14:00:34 2001// +/system.h/1.1.1.1/Fri Aug 10 14:00:34 2001// +/error.cc/1.4/Tue Nov 13 14:24:16 2001// +/i18n.h/1.2/Fri Nov 16 01:13:06 2001// +/progress.cc/1.3/Fri Nov 16 01:13:06 2001// +D diff --git a/apt/apt-pkg/contrib/CVS/Repository b/apt/apt-pkg/contrib/CVS/Repository new file mode 100644 index 0000000..7939259 --- /dev/null +++ b/apt/apt-pkg/contrib/CVS/Repository @@ -0,0 +1 @@ +rapt/apt-pkg/contrib diff --git a/apt/apt-pkg/contrib/CVS/Root b/apt/apt-pkg/contrib/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/apt-pkg/contrib/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/apt-pkg/contrib/cdromutl.cc b/apt/apt-pkg/contrib/cdromutl.cc new file mode 100644 index 0000000..3ba7b13 --- /dev/null +++ b/apt/apt-pkg/contrib/cdromutl.cc @@ -0,0 +1,202 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cdromutl.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + CDROM Utilities - Some functions to manipulate CDROM mounts. + + These are here for the cdrom method and apt-cdrom. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/cdromutl.h" +#endif +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + /*}}}*/ + +// IsMounted - Returns true if the mount point is mounted /*{{{*/ +// --------------------------------------------------------------------- +/* This is a simple algorithm that should always work, we stat the mount point + and the '..' file in the mount point and see if they are on the same device. + By definition if they are the same then it is not mounted. This should + account for symlinked mount points as well. */ +bool IsMounted(string &Path) +{ + if (Path.empty() == true) + return false; + + // Need that trailing slash for directories + if (Path[Path.length() - 1] != '/') + Path += '/'; + + /* First we check if the path is actualy mounted, we do this by + stating the path and the previous directory (carefull of links!) + and comparing their device fields. */ + struct stat Buf,Buf2; + if (stat(Path.c_str(),&Buf) != 0 || + stat((Path + "../").c_str(),&Buf2) != 0) + return _error->Errno("stat","Unable to stat the mount point %s",Path.c_str()); + + if (Buf.st_dev == Buf2.st_dev) + return false; + return true; +} + /*}}}*/ +// UnmountCdrom - Unmount a cdrom /*{{{*/ +// --------------------------------------------------------------------- +/* Forking umount works much better than the umount syscall which can + leave /etc/mtab inconsitant. We drop all messages this produces. */ +bool UnmountCdrom(string Path) +{ + if (IsMounted(Path) == false) + return true; + + int Child = ExecFork(); + + // The child + if (Child == 0) + { + // Make all the fds /dev/null + for (int I = 0; I != 3; I++) + dup2(open("/dev/null",O_RDWR),I); + + if (_config->Exists("Acquire::cdrom::"+Path+"::UMount") == true) + { + if (system(_config->Find("Acquire::cdrom::"+Path+"::UMount").c_str()) != 0) + _exit(100); + _exit(0); + } + else + { + const char *Args[10]; + Args[0] = "umount"; + Args[1] = Path.c_str(); + Args[2] = 0; + execvp(Args[0],(char **)Args); + _exit(100); + } + } + + // Wait for mount + return ExecWait(Child,"mount",true); +} + /*}}}*/ +// MountCdrom - Mount a cdrom /*{{{*/ +// --------------------------------------------------------------------- +/* We fork mount and drop all messages */ +bool MountCdrom(string Path) +{ + if (IsMounted(Path) == true) + return true; + + int Child = ExecFork(); + + // The child + if (Child == 0) + { + // Make all the fds /dev/null + for (int I = 0; I != 3; I++) + dup2(open("/dev/null",O_RDWR),I); + + if (_config->Exists("Acquire::cdrom::"+Path+"::Mount") == true) + { + if (system(_config->Find("Acquire::cdrom::"+Path+"::Mount").c_str()) != 0) + _exit(100); + _exit(0); + } + else + { + const char *Args[10]; + Args[0] = "mount"; + Args[1] = Path.c_str(); + Args[2] = 0; + execvp(Args[0],(char **)Args); + _exit(100); + } + } + + // Wait for mount + return ExecWait(Child,"mount",true); +} + /*}}}*/ +// IdentCdrom - Generate a unique string for this CD /*{{{*/ +// --------------------------------------------------------------------- +/* We convert everything we hash into a string, this prevents byte size/order + from effecting the outcome. */ +bool IdentCdrom(string CD,string &Res,unsigned int Version) +{ + MD5Summation Hash; + + string StartDir = SafeGetCWD(); + if (chdir(CD.c_str()) != 0) + return _error->Errno("chdir","Unable to change to %s",CD.c_str()); + + DIR *D = opendir("."); + if (D == 0) + return _error->Errno("opendir","Unable to read %s",CD.c_str()); + + /* Run over the directory, we assume that the reader order will never + change as the media is read-only. In theory if the kernel did + some sort of wacked caching this might not be true.. */ + char S[300]; + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + // Skip some files.. + if (strcmp(Dir->d_name,".") == 0 || + strcmp(Dir->d_name,"..") == 0) + continue; + + if (Version <= 1) + { + sprintf(S,"%lu",(unsigned long)Dir->d_ino); + } + else + { + struct stat Buf; + if (stat(Dir->d_name,&Buf) != 0) + continue; + sprintf(S,"%lu",(unsigned long)Buf.st_mtime); + } + + Hash.Add(S); + Hash.Add(Dir->d_name); + }; + + chdir(StartDir.c_str()); + closedir(D); + + // Some stats from the fsys + if (_config->FindB("Debug::identcdrom",false) == false) + { + struct statvfs Buf; + if (statvfs(CD.c_str(),&Buf) != 0) + return _error->Errno("statfs","Failed to stat the cdrom"); + + // We use a kilobyte block size to advoid overflow + sprintf(S,"%lu %lu",(long)(Buf.f_blocks*(Buf.f_bsize/1024)), + (long)(Buf.f_bfree*(Buf.f_bsize/1024))); + Hash.Add(S); + sprintf(S,"-%u",Version); + } + else + sprintf(S,"-%u.debug",Version); + + Res = Hash.Result().Value() + S; + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/cdromutl.h b/apt/apt-pkg/contrib/cdromutl.h new file mode 100644 index 0000000..34a01ed --- /dev/null +++ b/apt/apt-pkg/contrib/cdromutl.h @@ -0,0 +1,23 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cdromutl.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + CDROM Utilities - Some functions to manipulate CDROM mounts. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_CDROMUTL_H +#define PKGLIB_ACQUIRE_METHOD_H + +#include + +#ifdef __GNUG__ +#pragma interface "apt-pkg/cdromutl.h" +#endif + +bool MountCdrom(string Path); +bool UnmountCdrom(string Path); +bool IdentCdrom(string CD,string &Res,unsigned int Version = 2); + +#endif diff --git a/apt/apt-pkg/contrib/cmndline.cc b/apt/apt-pkg/contrib/cmndline.cc new file mode 100644 index 0000000..8a5a29d --- /dev/null +++ b/apt/apt-pkg/contrib/cmndline.cc @@ -0,0 +1,347 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cmndline.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Command Line Class - Sophisticated command line parser + + ##################################################################### */ + /*}}}*/ +// Include files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/cmndline.h" +#endif +#include +#include +#include + /*}}}*/ + +// CommandLine::CommandLine - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +CommandLine::CommandLine(Args *AList,Configuration *Conf) : ArgList(AList), + Conf(Conf), FileList(0) +{ +} + /*}}}*/ +// CommandLine::~CommandLine - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +CommandLine::~CommandLine() +{ + delete [] FileList; +} + /*}}}*/ +// CommandLine::Parse - Main action member /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool CommandLine::Parse(int argc,const char **argv) +{ + delete [] FileList; + FileList = new const char *[argc]; + const char **Files = FileList; + int I; + for (I = 1; I != argc; I++) + { + const char *Opt = argv[I]; + + // It is not an option + if (*Opt != '-') + { + *Files++ = Opt; + continue; + } + + Opt++; + + // Double dash signifies the end of option processing + if (*Opt == '-' && Opt[1] == 0) + break; + + // Single dash is a short option + if (*Opt != '-') + { + // Iterate over each letter + while (*Opt != 0) + { + // Search for the option + Args *A; + for (A = ArgList; A->end() == false && A->ShortOpt != *Opt; A++); + if (A->end() == true) + return _error->Error("Command line option '%c' [from %s] is not known.",*Opt,argv[I]); + + if (HandleOpt(I,argc,argv,Opt,A) == false) + return false; + if (*Opt != 0) + Opt++; + } + continue; + } + + Opt++; + + // Match up to a = against the list + const char *OptEnd = Opt; + Args *A; + for (; *OptEnd != 0 && *OptEnd != '='; OptEnd++); + for (A = ArgList; A->end() == false && + stringcasecmp(Opt,OptEnd,A->LongOpt) != 0; A++); + + // Failed, look for a word after the first - (no-foo) + bool PreceedMatch = false; + if (A->end() == true) + { + for (; Opt != OptEnd && *Opt != '-'; Opt++); + + if (Opt == OptEnd) + return _error->Error("Command line option %s is not understood",argv[I]); + Opt++; + + for (A = ArgList; A->end() == false && + stringcasecmp(Opt,OptEnd,A->LongOpt) != 0; A++); + + // Failed again.. + if (A->end() == true && OptEnd - Opt != 1) + return _error->Error("Command line option %s is not understood",argv[I]); + + // The option could be a single letter option prefixed by a no-.. + if (A->end() == true) + { + for (A = ArgList; A->end() == false && A->ShortOpt != *Opt; A++); + + if (A->end() == true) + return _error->Error("Command line option %s is not understood",argv[I]); + } + + // The option is not boolean + if (A->IsBoolean() == false) + return _error->Error("Command line option %s is not boolean",argv[I]); + PreceedMatch = true; + } + + // Deal with it. + OptEnd--; + if (HandleOpt(I,argc,argv,OptEnd,A,PreceedMatch) == false) + return false; + } + + // Copy any remaining file names over + for (; I != argc; I++) + *Files++ = argv[I]; + *Files = 0; + + return true; +} + /*}}}*/ +// CommandLine::HandleOpt - Handle a single option including all flags /*{{{*/ +// --------------------------------------------------------------------- +/* This is a helper function for parser, it looks at a given argument + and looks for specific patterns in the string, it gets tokanized + -ruffly- like -*[yes|true|enable]-(o|longopt)[=][ ][argument] */ +bool CommandLine::HandleOpt(int &I,int argc,const char *argv[], + const char *&Opt,Args *A,bool PreceedMatch) +{ + const char *Argument = 0; + bool CertainArg = false; + int IncI = 0; + + /* Determine the possible location of an option or 0 if their is + no option */ + if (Opt[1] == 0 || (Opt[1] == '=' && Opt[2] == 0)) + { + if (I + 1 < argc && argv[I+1][0] != '-') + Argument = argv[I+1]; + + // Equals was specified but we fell off the end! + if (Opt[1] == '=' && Argument == 0) + return _error->Error("Option %s requires an argument.",argv[I]); + if (Opt[1] == '=') + CertainArg = true; + + IncI = 1; + } + else + { + if (Opt[1] == '=') + { + CertainArg = true; + Argument = Opt + 2; + } + else + Argument = Opt + 1; + } + + // Option is an argument set + if ((A->Flags & HasArg) == HasArg) + { + if (Argument == 0) + return _error->Error("Option %s requires an argument.",argv[I]); + Opt += strlen(Opt); + I += IncI; + + // Parse a configuration file + if ((A->Flags & ConfigFile) == ConfigFile) + return ReadConfigFile(*Conf,Argument); + + // Arbitary item specification + if ((A->Flags & ArbItem) == ArbItem) + { + const char *J; + for (J = Argument; *J != 0 && *J != '='; J++); + if (*J == 0) + return _error->Error("Option %s: Configuration item sepecification must have an =.",argv[I]); + + // = is trailing + if (J[1] == 0) + { + if (I+1 >= argc) + return _error->Error("Option %s: Configuration item sepecification must have an =.",argv[I]); + Conf->Set(string(Argument,J-Argument),string(argv[I++ +1])); + } + else + Conf->Set(string(Argument,J-Argument),string(J+1)); + + return true; + } + + const char *I = A->ConfName; + for (; *I != 0 && *I != ' '; I++); + if (*I == ' ') + Conf->Set(string(A->ConfName,0,I-A->ConfName),string(I+1) + Argument); + else + Conf->Set(A->ConfName,string(I) + Argument); + + return true; + } + + // Option is an integer level + if ((A->Flags & IntLevel) == IntLevel) + { + // There might be an argument + if (Argument != 0) + { + char *EndPtr; + unsigned long Value = strtol(Argument,&EndPtr,10); + + // Conversion failed and the argument was specified with an =s + if (EndPtr == Argument && CertainArg == true) + return _error->Error("Option %s requires an integer argument, not '%s'",argv[I],Argument); + + // Conversion was ok, set the value and return + if (EndPtr != 0 && EndPtr != Argument && *EndPtr == 0) + { + Conf->Set(A->ConfName,Value); + Opt += strlen(Opt); + I += IncI; + return true; + } + } + + // Increase the level + Conf->Set(A->ConfName,Conf->FindI(A->ConfName)+1); + return true; + } + + // Option is a boolean + int Sense = -1; // -1 is unspecified, 0 is yes 1 is no + + // Look for an argument. + while (1) + { + // Look at preceeding text + char Buffer[300]; + if (Argument == 0) + { + if (PreceedMatch == false) + break; + + if (strlen(argv[I]) >= sizeof(Buffer)) + return _error->Error("Option '%s' is too long",argv[I]); + + // Skip the leading dash + const char *J = argv[I]; + for (; *J != 0 && *J == '-'; J++); + + const char *JEnd = J; + for (; *JEnd != 0 && *JEnd != '-'; JEnd++); + if (*JEnd != 0) + { + strncpy(Buffer,J,JEnd - J); + Buffer[JEnd - J] = 0; + Argument = Buffer; + CertainArg = true; + } + else + break; + } + + // Check for boolean + Sense = StringToBool(Argument); + if (Sense >= 0) + { + // Eat the argument + if (Argument != Buffer) + { + Opt += strlen(Opt); + I += IncI; + } + break; + } + + if (CertainArg == true) + return _error->Error("Sense %s is not understood, try true or false.",Argument); + + Argument = 0; + } + + // Indeterminate sense depends on the flag + if (Sense == -1) + { + if ((A->Flags & InvBoolean) == InvBoolean) + Sense = 0; + else + Sense = 1; + } + + Conf->Set(A->ConfName,Sense); + return true; +} + /*}}}*/ +// CommandLine::FileSize - Count the number of filenames /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned int CommandLine::FileSize() const +{ + unsigned int Count = 0; + for (const char **I = FileList; I != 0 && *I != 0; I++) + Count++; + return Count; +} + /*}}}*/ +// CommandLine::DispatchArg - Do something with the first arg /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool CommandLine::DispatchArg(Dispatch *Map,bool NoMatch) +{ + int I; + for (I = 0; Map[I].Match != 0; I++) + { + if (strcmp(FileList[0],Map[I].Match) == 0) + { + bool Res = Map[I].Handler(*this); + if (Res == false && _error->PendingError() == false) + _error->Error("Handler silently failed"); + return Res; + } + } + + // No matching name + if (Map[I].Match == 0) + { + if (NoMatch == true) + _error->Error("Invalid operation %s",FileList[0]); + } + + return false; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/cmndline.h b/apt/apt-pkg/contrib/cmndline.h new file mode 100644 index 0000000..6684798 --- /dev/null +++ b/apt/apt-pkg/contrib/cmndline.h @@ -0,0 +1,106 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cmndline.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Command Line Class - Sophisticated command line parser + + This class provides a unified command line parser/option handliner/ + configuration mechanism. It allows the caller to specify the option + set and map the option set into the configuration class or other + special functioning. + + Filenames are stripped from the option stream and put into their + own array. + + The argument descriptor array can be initialized as: + + CommandLine::Args Args[] = + {{'q',"quiet","apt::get::quiet",CommandLine::IntLevel}, + {0,0,0,0}}; + + The flags mean, + HasArg - Means the argument has a value + IntLevel - Means the argument is an integer level indication, the + following -qqqq (+3) -q5 (=5) -q=5 (=5) are valid + Boolean - Means it is true/false or yes/no. + -d (true) --no-d (false) --yes-d (true) + --long (true) --no-long (false) --yes-long (true) + -d=yes (true) -d=no (false) Words like enable, disable, + true false, yes no and on off are recognized in logical + places. + InvBoolean - Same as boolean but the case with no specified sense + (first case) is set to false. + ConfigFile - Means this flag should be interprited as the name of + a config file to read in at this point in option processing. + Implies HasArg. + ArbItem - Means the item is an arbitary configuration string of + the form item=value, where item is passed directly + to the configuration class. + The default, if the flags are 0 is to use Boolean + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_CMNDLINE_H +#define PKGLIB_CMNDLINE_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/cmndline.h" +#endif + +#include + +class CommandLine +{ + public: + struct Args; + struct Dispatch; + + protected: + + Args *ArgList; + Configuration *Conf; + bool HandleOpt(int &I,int argc,const char *argv[], + const char *&Opt,Args *A,bool PreceedeMatch = false); + + public: + + enum AFlags + { + HasArg = (1 << 0), + IntLevel = (1 << 1), + Boolean = (1 << 2), + InvBoolean = (1 << 3), + ConfigFile = (1 << 4) | HasArg, + ArbItem = (1 << 5) | HasArg + }; + + const char **FileList; + + bool Parse(int argc,const char **argv); + void ShowHelp(); + unsigned int FileSize() const; + bool DispatchArg(Dispatch *List,bool NoMatch = true); + + CommandLine(Args *AList,Configuration *Conf); + ~CommandLine(); +}; + +struct CommandLine::Args +{ + char ShortOpt; + const char *LongOpt; + const char *ConfName; + unsigned long Flags; + + inline bool end() {return ShortOpt == 0 && LongOpt == 0;}; + inline bool IsBoolean() {return Flags == 0 || (Flags & (Boolean|InvBoolean)) != 0;}; +}; + +struct CommandLine::Dispatch +{ + const char *Match; + bool (*Handler)(CommandLine &); +}; + +#endif diff --git a/apt/apt-pkg/contrib/configuration.cc b/apt/apt-pkg/contrib/configuration.cc new file mode 100644 index 0000000..9aa98ea --- /dev/null +++ b/apt/apt-pkg/contrib/configuration.cc @@ -0,0 +1,665 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: configuration.cc,v 1.2 2000/10/30 18:49:49 kojima Exp $ +/* ###################################################################### + + Configuration Class + + This class provides a configuration file and command line parser + for a tree-oriented configuration environment. All runtime configuration + is stored in here. + + ##################################################################### */ + /*}}}*/ +// Include files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/configuration.h" +#endif +#include +#include +#include + +#include +#include + /*}}}*/ + +Configuration *_config = new Configuration; + +// Configuration::Configuration - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +Configuration::Configuration() : ToFree(true) +{ + Root = new Item; +} +Configuration::Configuration(const Item *Root) : Root((Item *)Root), ToFree(false) +{ +}; + + /*}}}*/ +// Configuration::~Configuration - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +Configuration::~Configuration() +{ + if (ToFree == false) + return; + + Item *Top = Root; + for (; Top != 0;) + { + if (Top->Child != 0) + { + Top = Top->Child; + continue; + } + + while (Top != 0 && Top->Next == 0) + { + Item *Parent = Top->Parent; + delete Top; + Top = Parent; + } + if (Top != 0) + { + Item *Next = Top->Next; + delete Top; + Top = Next; + } + } +} + /*}}}*/ +// Configuration::Lookup - Lookup a single item /*{{{*/ +// --------------------------------------------------------------------- +/* This will lookup a single item by name below another item. It is a + helper function for the main lookup function */ +Configuration::Item *Configuration::Lookup(Item *Head,const char *S, + unsigned long Len,bool Create) +{ + int Res = 1; + Item *I = Head->Child; + Item **Last = &Head->Child; + + // Empty strings match nothing. They are used for lists. + if (Len != 0) + { + for (; I != 0; Last = &I->Next, I = I->Next) + if ((Res = stringcasecmp(I->Tag.begin(),I->Tag.end(),S,S + Len)) == 0) + break; + } + else + for (; I != 0; Last = &I->Next, I = I->Next); + + if (Res == 0) + return I; + if (Create == false) + return 0; + + I = new Item; + I->Tag = string(S,Len); + I->Next = *Last; + I->Parent = Head; + *Last = I; + return I; +} + /*}}}*/ +// Configuration::Lookup - Lookup a fully scoped item /*{{{*/ +// --------------------------------------------------------------------- +/* This performs a fully scoped lookup of a given name, possibly creating + new items */ +Configuration::Item *Configuration::Lookup(const char *Name,bool Create) +{ + if (Name == 0) + return Root->Child; + + const char *Start = Name; + const char *End = Start + strlen(Name); + const char *TagEnd = Name; + Item *Itm = Root; + for (; End - TagEnd >= 2; TagEnd++) + { + if (TagEnd[0] == ':' && TagEnd[1] == ':') + { + Itm = Lookup(Itm,Start,TagEnd - Start,Create); + if (Itm == 0) + return 0; + TagEnd = Start = TagEnd + 2; + } + } + + // This must be a trailing ::, we create unique items in a list + if (End - Start == 0) + { + if (Create == false) + return 0; + } + + Itm = Lookup(Itm,Start,End - Start,Create); + return Itm; +} + /*}}}*/ +// Configuration::Find - Find a value /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string Configuration::Find(const char *Name,const char *Default) const +{ + const Item *Itm = Lookup(Name); + if (Itm == 0 || Itm->Value.empty() == true) + { + if (Default == 0) + return string(); + else + return Default; + } + + return Itm->Value; +} + /*}}}*/ +// Configuration::FindFile - Find a Filename /*{{{*/ +// --------------------------------------------------------------------- +/* Directories are stored as the base dir in the Parent node and the + sub directory in sub nodes with the final node being the end filename + */ +string Configuration::FindFile(const char *Name,const char *Default) const +{ + const Item *Itm = Lookup(Name); + if (Itm == 0 || Itm->Value.empty() == true) + { + if (Default == 0) + return string(); + else + return Default; + } + + string val = Itm->Value; + while (Itm->Parent != 0 && Itm->Parent->Value.empty() == false) + { + // Absolute + if (val[0] == '/') + break; + + // ~/foo or ./foo + if ((val[0] == '~' || val[0] == '.') && val[1] == '/') + break; + + // ../foo + if (val[0] == '.' && val[1] == '.' && val[2] == '/') + break; + + if (Itm->Parent->Value.end()[-1] != '/') + val.insert(0, "/"); + + val.insert(0, Itm->Parent->Value); + Itm = Itm->Parent; + } + + return val; +} + /*}}}*/ +// Configuration::FindDir - Find a directory name /*{{{*/ +// --------------------------------------------------------------------- +/* This is like findfile execept the result is terminated in a / */ +string Configuration::FindDir(const char *Name,const char *Default) const +{ + string Res = FindFile(Name,Default); + if (Res.end()[-1] != '/') + return Res + '/'; + return Res; +} + /*}}}*/ +// Configuration::FindI - Find an integer value /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int Configuration::FindI(const char *Name,int Default) const +{ + const Item *Itm = Lookup(Name); + if (Itm == 0 || Itm->Value.empty() == true) + return Default; + + char *End; + int Res = strtol(Itm->Value.c_str(),&End,0); + if (End == Itm->Value.c_str()) + return Default; + + return Res; +} + /*}}}*/ +// Configuration::FindB - Find a boolean type /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Configuration::FindB(const char *Name,bool Default) const +{ + const Item *Itm = Lookup(Name); + if (Itm == 0 || Itm->Value.empty() == true) + return Default; + + return StringToBool(Itm->Value,Default); +} + /*}}}*/ +// Configuration::FindAny - Find an arbitrary type /*{{{*/ +// --------------------------------------------------------------------- +/* a key suffix of /f, /d, /b or /i calls Find{File,Dir,B,I} */ +string Configuration::FindAny(const char *Name,const char *Default) const +{ + string key = Name; + char type = 0; + + if (key.size() > 2 && key.end()[-2] == '/') + { + type = key.end()[-1]; + key.resize(key.size() - 2); + } + + switch (type) + { + // file + case 'f': + return FindFile(key.c_str(), Default); + + // directory + case 'd': + return FindDir(key.c_str(), Default); + + // bool + case 'b': + return FindB(key, Default) ? "true" : "false"; + + // int + case 'i': + { + char buf[16]; + snprintf(buf, sizeof(buf)-1, "%d", FindI(key, Default)); + return buf; + } + } + + // fallback + return Find(Name, Default); +} + /*}}}*/ +// Configuration::CndSet - Conditinal Set a value /*{{{*/ +// --------------------------------------------------------------------- +/* This will not overwrite */ +void Configuration::CndSet(const char *Name,string Value) +{ + Item *Itm = Lookup(Name,true); + if (Itm == 0) + return; + if (Itm->Value.empty() == true) + Itm->Value = Value; +} + /*}}}*/ +// Configuration::Set - Set a value /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Configuration::Set(const char *Name,string Value) +{ + Item *Itm = Lookup(Name,true); + if (Itm == 0) + return; + Itm->Value = Value; +} + /*}}}*/ +// Configuration::Set - Set an integer value /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Configuration::Set(const char *Name,int Value) +{ + Item *Itm = Lookup(Name,true); + if (Itm == 0) + return; + char S[300]; + snprintf(S,sizeof(S),"%i",Value); + Itm->Value = S; +} + /*}}}*/ +// Configuration::Clear - Clear an entire tree /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Configuration::Clear(string Name) +{ + Item *Top = Lookup(Name.c_str(),false); + if (Top == 0) + return; + + Top->Value = string(); + Item *Stop = Top; + Top = Top->Child; + Stop->Child = 0; + for (; Top != 0;) + { + if (Top->Child != 0) + { + Top = Top->Child; + continue; + } + + while (Top != 0 && Top->Next == 0) + { + if (Top == Stop) + return; + Item *Tmp = Top; + Top = Top->Parent; + delete Tmp; + } + + Item *Tmp = Top; + if (Top != 0) + Top = Top->Next; + delete Tmp; + } +} + /*}}}*/ +// Configuration::Exists - Returns true if the Name exists /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Configuration::Exists(const char *Name) const +{ + const Item *Itm = Lookup(Name); + if (Itm == 0) + return false; + return true; +} + /*}}}*/ +// Configuration::ExistsAny - Returns true if the Name, possibly /*{{{*/ +// --------------------------------------------------------------------- +/* qualified by /[fdbi] exists */ +bool Configuration::ExistsAny(const char *Name) const +{ + string key = Name; + + if (key.size() > 2 && key.end()[-2] == '/' && + key.find_first_of("fdbi",key.size()-1) < key.size()) + { + key.resize(key.size() - 2); + if (Exists(key.c_str())) + return true; + } + + return Exists(Name); +} + /*}}}*/ +// Configuration::Dump - Dump the config /*{{{*/ +// --------------------------------------------------------------------- +/* Dump the entire configuration space */ +void Configuration::Dump() +{ + /* Write out all of the configuration directives by walking the + configuration tree */ + const Configuration::Item *Top = Tree(0); + for (; Top != 0;) + { + clog << Top->FullTag() << " \"" << Top->Value << "\";" << endl; + + if (Top->Child != 0) + { + Top = Top->Child; + continue; + } + + while (Top != 0 && Top->Next == 0) + Top = Top->Parent; + if (Top != 0) + Top = Top->Next; + } +} + /*}}}*/ + +// Configuration::Item::FullTag - Return the fully scoped tag /*{{{*/ +// --------------------------------------------------------------------- +/* Stop sets an optional max recursion depth if this item is being viewed as + part of a sub tree. */ +string Configuration::Item::FullTag(const Item *Stop) const +{ + if (Parent == 0 || Parent->Parent == 0 || Parent == Stop) + return Tag; + return Parent->FullTag(Stop) + "::" + Tag; +} + /*}}}*/ + +// ReadConfigFile - Read a configuration file /*{{{*/ +// --------------------------------------------------------------------- +/* The configuration format is very much like the named.conf format + used in bind8, in fact this routine can parse most named.conf files. + Sectional config files are like bind's named.conf where there are + sections like 'zone "foo.org" { .. };' This causes each section to be + added in with a tag like "zone::foo.org" instead of being split + tag/value. */ +bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional, + unsigned Depth) +{ + // Open the stream for reading + ifstream F(FName.c_str(),ios::in | ios::nocreate); + if (!F != 0) + return _error->Errno("ifstream::ifstream","Opening configuration file %s",FName.c_str()); + + char Buffer[300]; + string LineBuffer; + string Stack[100]; + unsigned int StackPos = 0; + + // Parser state + string ParentTag; + + int CurLine = 0; + bool InComment = false; + while (F.eof() == false) + { + F.getline(Buffer,sizeof(Buffer)); + CurLine++; + _strtabexpand(Buffer,sizeof(Buffer)); + _strstrip(Buffer); + + // Multi line comment + if (InComment == true) + { + for (const char *I = Buffer; *I != 0; I++) + { + if (*I == '*' && I[1] == '/') + { + memmove(Buffer,I+2,strlen(I+2) + 1); + InComment = false; + break; + } + } + if (InComment == true) + continue; + } + + // Discard single line comments + bool InQuote = false; + for (char *I = Buffer; *I != 0; I++) + { + if (*I == '"') + InQuote = !InQuote; + if (InQuote == true) + continue; + + if (*I == '/' && I[1] == '/') + { + *I = 0; + break; + } + } + + // Look for multi line comments + InQuote = false; + for (char *I = Buffer; *I != 0; I++) + { + if (*I == '"') + InQuote = !InQuote; + if (InQuote == true) + continue; + + if (*I == '/' && I[1] == '*') + { + InComment = true; + for (char *J = Buffer; *J != 0; J++) + { + if (*J == '*' && J[1] == '/') + { + memmove(I,J+2,strlen(J+2) + 1); + InComment = false; + break; + } + } + + if (InComment == true) + { + *I = 0; + break; + } + } + } + + // Blank + if (Buffer[0] == 0) + continue; + + // We now have a valid line fragment + InQuote = false; + for (char *I = Buffer; *I != 0;) + { + if (*I == '"') + InQuote = !InQuote; + + if (InQuote == false && (*I == '{' || *I == ';' || *I == '}')) + { + // Put the last fragment into the buffer + char *Start = Buffer; + char *Stop = I; + for (; Start != I && isspace(*Start) != 0; Start++); + for (; Stop != Start && isspace(Stop[-1]) != 0; Stop--); + if (LineBuffer.empty() == false && Stop - Start != 0) + LineBuffer += ' '; + LineBuffer += string(Start,Stop - Start); + + // Remove the fragment + char TermChar = *I; + memmove(Buffer,I + 1,strlen(I + 1) + 1); + I = Buffer; + + // Syntax Error + if (TermChar == '{' && LineBuffer.empty() == true) + return _error->Error("Syntax error %s:%u: Block starts with no name.",FName.c_str(),CurLine); + + // No string on this line + if (LineBuffer.empty() == true) + { + if (TermChar == '}') + { + if (StackPos == 0) + ParentTag = string(); + else + ParentTag = Stack[--StackPos]; + } + continue; + } + + // Parse off the tag + string Tag; + const char *Pos = LineBuffer.c_str(); + if (ParseQuoteWord(Pos,Tag) == false) + return _error->Error("Syntax error %s:%u: Malformed Tag",FName.c_str(),CurLine); + + // Parse off the word + string Word; + if (ParseCWord(Pos,Word) == false && + ParseQuoteWord(Pos,Word) == false) + { + if (TermChar != '{') + { + Word = Tag; + Tag = ""; + } + } + if (strlen(Pos) != 0) + return _error->Error("Syntax error %s:%u: Extra junk after value",FName.c_str(),CurLine); + + // Go down a level + if (TermChar == '{') + { + if (StackPos <= 100) + Stack[StackPos++] = ParentTag; + + /* Make sectional tags incorperate the section into the + tag string */ + if (AsSectional == true && Word.empty() == false) + { + Tag += "::" ; + Tag += Word; + Word = ""; + } + + if (ParentTag.empty() == true) + ParentTag = Tag; + else + ParentTag += string("::") + Tag; + Tag = string(); + } + + // Generate the item name + string Item; + if (ParentTag.empty() == true) + Item = Tag; + else + { + if (TermChar != '{' || Tag.empty() == false) + Item = ParentTag + "::" + Tag; + else + Item = ParentTag; + } + + // Specials + if (Tag[0] == '#') + { + if (ParentTag.empty() == false) + return _error->Error("Syntax error %s:%u: Directives can only be done at the top level",FName.c_str(),CurLine); + Tag.erase(Tag.begin()); + if (Tag == "clear") + Conf.Clear(Word); + else if (Tag == "include") + { + if (Depth > 10) + return _error->Error("Syntax error %s:%u: Too many nested includes",FName.c_str(),CurLine); + if (ReadConfigFile(Conf,Word,AsSectional,Depth+1) == false) + return _error->Error("Syntax error %s:%u: Included from here",FName.c_str(),CurLine); + } + else + return _error->Error("Syntax error %s:%u: Unsupported directive '%s'",FName.c_str(),CurLine,Tag.c_str()); + } + else + { + // Set the item in the configuration class + Conf.Set(Item,Word); + } + + // Empty the buffer + LineBuffer = string(); + + // Move up a tag, but only if there is no bit to parse + if (TermChar == '}') + { + if (StackPos == 0) + ParentTag = string(); + else + ParentTag = Stack[--StackPos]; + } + + } + else + I++; + } + + // Store the fragment + const char *Stripd = _strstrip(Buffer); + if (*Stripd != 0 && LineBuffer.empty() == false) + LineBuffer += " "; + LineBuffer += Stripd; + } + + if (LineBuffer.empty() == false) + return _error->Error("Syntax error %s:%u: Extra junk at end of file",FName.c_str(),CurLine); + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/configuration.h b/apt/apt-pkg/contrib/configuration.h new file mode 100644 index 0000000..9e0ab79 --- /dev/null +++ b/apt/apt-pkg/contrib/configuration.h @@ -0,0 +1,103 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: configuration.h,v 1.2 2000/10/30 18:49:49 kojima Exp $ +/* ###################################################################### + + Configuration Class + + This class provides a configuration file and command line parser + for a tree-oriented configuration environment. All runtime configuration + is stored in here. + + Each configuration name is given as a fully scoped string such as + Foo::Bar + And has associated with it a text string. The Configuration class only + provides storage and lookup for this tree, other classes provide + configuration file formats (and parsers/emitters if needed). + + Most things can get by quite happily with, + cout << _config->Find("Foo::Bar") << endl; + + A special extension, support for ordered lists is provided by using the + special syntax, "block::list::" the trailing :: designates the + item as a list. To access the list you must use the tree function on + "block::list". + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_CONFIGURATION_H +#define PKGLIB_CONFIGURATION_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/configuration.h" +#endif + +#include + +class Configuration +{ + public: + + struct Item + { + string Value; + string Tag; + Item *Parent; + Item *Child; + Item *Next; + + string FullTag(const Item *Stop = 0) const; + + Item() : Parent(0), Child(0), Next(0) {}; + }; + + private: + + Item *Root; + bool ToFree; + + Item *Lookup(Item *Head,const char *S,unsigned long Len,bool Create); + Item *Lookup(const char *Name,bool Create); + inline const Item *Lookup(const char *Name) const + { + return ((Configuration *)this)->Lookup(Name,false); + } + + public: + + string Find(const char *Name,const char *Default = 0) const; + string Find(string Name,const char *Default = 0) const {return Find(Name.c_str(),Default);}; + string FindFile(const char *Name,const char *Default = 0) const; + string FindDir(const char *Name,const char *Default = 0) const; + int FindI(const char *Name,int Default = 0) const; + int FindI(string Name,bool Default = 0) const {return FindI(Name.c_str(),Default);}; + bool FindB(const char *Name,bool Default = false) const; + bool FindB(string Name,bool Default = false) const {return FindB(Name.c_str(),Default);}; + string FindAny(const char *Name,const char *Default = 0) const; + + inline void Set(string Name,string Value) {Set(Name.c_str(),Value);}; + void CndSet(const char *Name,string Value); + void Set(const char *Name,string Value); + void Set(const char *Name,int Value); + + inline bool Exists(string Name) const {return Exists(Name.c_str());}; + bool Exists(const char *Name) const; + bool ExistsAny(const char *Name) const; + + void Clear(string Name); + + inline const Item *Tree(const char *Name) const {return Lookup(Name);}; + + void Dump(); + + Configuration(const Item *Root); + Configuration(); + ~Configuration(); +}; + +extern Configuration *_config; + +bool ReadConfigFile(Configuration &Conf,string FName,bool AsSectional = false, + unsigned Depth = 0); + +#endif diff --git a/apt/apt-pkg/contrib/crc-16.cc b/apt/apt-pkg/contrib/crc-16.cc new file mode 100644 index 0000000..e8bb7fd --- /dev/null +++ b/apt/apt-pkg/contrib/crc-16.cc @@ -0,0 +1,76 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: crc-16.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + CRC16 - Compute a 16bit crc very quickly + + This was ripped out of the linux 2.2 kernel source (irda/crc.c) and + is credited to ppp.c by Michael Callahan and + Al Longyear + + Modified by Jason Gunthorpe to fit the local coding + style, this code is belived to be in the Public Domain. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/crc-16.h" +#endif + +#include + /*}}}*/ + +/* + * This mysterious table is just the CRC of each possible byte. It can be + * computed using the standard bit-at-a-time methods. The polynomial can + * be seen in entry 128, 0x8408. This corresponds to x^0 + x^5 + x^12. + * Add the implicit x^16, and you have the standard CRC-CCITT. + */ +static unsigned short const crc16_table[256] = +{ + 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, + 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, + 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, + 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, + 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, + 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, + 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, + 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, + 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, + 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, + 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, + 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, + 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, + 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, + 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, + 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, + 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, + 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, + 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, + 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, + 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, + 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, + 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, + 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, + 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, + 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, + 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, + 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, + 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, + 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, + 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, + 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 +}; + +/* Recompute the FCS with one more character appended. */ +#define CalcFCS(fcs, c) (((fcs) >> 8) ^ crc16_table[((fcs) ^ (c)) & 0xff]) +unsigned short AddCRC16(unsigned short fcs, void const *Buf, + unsigned long len) +{ + unsigned char const *buf = (unsigned char const *)Buf; + while (len--) + fcs = CalcFCS(fcs, *buf++); + return fcs; +} diff --git a/apt/apt-pkg/contrib/crc-16.h b/apt/apt-pkg/contrib/crc-16.h new file mode 100644 index 0000000..3b9ca71 --- /dev/null +++ b/apt/apt-pkg/contrib/crc-16.h @@ -0,0 +1,21 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: crc-16.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + CRC16 - Compute a 16bit crc very quickly + + ##################################################################### */ + /*}}}*/ +#ifndef APTPKG_CRC16_H +#define APTPKG_CRC16_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/crc-16.h" +#endif + +#define INIT_FCS 0xffff +unsigned short AddCRC16(unsigned short fcs, void const *buf, + unsigned long len); + +#endif diff --git a/apt/apt-pkg/contrib/error.cc b/apt/apt-pkg/contrib/error.cc new file mode 100644 index 0000000..412daec --- /dev/null +++ b/apt/apt-pkg/contrib/error.cc @@ -0,0 +1,239 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: error.cc,v 1.4 2001/11/12 16:04:37 kojima Exp $ +/* ###################################################################### + + Global Erorr Class - Global error mechanism + + We use a simple STL vector to store each error record. A PendingFlag + is kept which indicates when the vector contains a Sever error. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/error.h" +#endif + +#include + +#include +#include +#include +#include +#include + +#include "config.h" + /*}}}*/ + +// Global Error Object /*{{{*/ +/* If the implementation supports posix threads then the accessor function + is compiled to be thread safe otherwise a non-safe version is used. A + Per-Thread error object is maintained in much the same manner as libc + manages errno */ +#if _POSIX_THREADS == 1 && defined(HAVE_PTHREAD) + #include + + static pthread_key_t ErrorKey; + static void ErrorDestroy(void *Obj) {delete (GlobalError *)Obj;}; + static void KeyAlloc() {pthread_key_create(&ErrorKey,ErrorDestroy);}; + + GlobalError *_GetErrorObj() + { + static pthread_once_t Once = PTHREAD_ONCE_INIT; + pthread_once(&Once,KeyAlloc); + + void *Res = pthread_getspecific(ErrorKey); + if (Res == 0) + pthread_setspecific(ErrorKey,Res = new GlobalError); + return (GlobalError *)Res; + } +#else + GlobalError *_GetErrorObj() + { + static GlobalError *Obj = new GlobalError; + return Obj; + } +#endif + /*}}}*/ + +// GlobalError::GlobalError - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +GlobalError::GlobalError() : List(0), PendingFlag(false) +{ +} + /*}}}*/ +// GlobalError::Errno - Get part of the error string from errno /*{{{*/ +// --------------------------------------------------------------------- +/* Function indicates the stdlib function that failed and Description is + a user string that leads the text. Form is: + Description - Function (errno: strerror) + Carefull of the buffer overrun, sprintf. + */ +bool GlobalError::Errno(const char *Function,const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsnprintf(S,sizeof(S),Description,args); + snprintf(S + strlen(S),sizeof(S) - strlen(S), + " - %s (%i %s)",Function,errno,strerror(errno)); + + // Put it on the list + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = true; + Insert(Itm); + + PendingFlag = true; + + return false; +} + /*}}}*/ +// GlobalError::WarningE - Get part of the warn string from errno /*{{{*/ +// --------------------------------------------------------------------- +/* Function indicates the stdlib function that failed and Description is + a user string that leads the text. Form is: + Description - Function (errno: strerror) + Carefull of the buffer overrun, sprintf. + */ +bool GlobalError::WarningE(const char *Function,const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsnprintf(S,sizeof(S),Description,args); + snprintf(S + strlen(S),sizeof(S) - strlen(S)," - %s (%i %s)",Function,errno,strerror(errno)); + + // Put it on the list + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = false; + Insert(Itm); + + return false; +} + /*}}}*/ +// GlobalError::Error - Add an error to the list /*{{{*/ +// --------------------------------------------------------------------- +/* Just vsprintfs and pushes */ +bool GlobalError::Error(const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsnprintf(S,sizeof(S),Description,args); + + // Put it on the list + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = true; + Insert(Itm); + + PendingFlag = true; + + return false; +} + /*}}}*/ +// GlobalError::Warning - Add a warning to the list /*{{{*/ +// --------------------------------------------------------------------- +/* This doesn't set the pending error flag */ +bool GlobalError::Warning(const char *Description,...) +{ + va_list args; + va_start(args,Description); + + // sprintf the description + char S[400]; + vsnprintf(S,sizeof(S),Description,args); + + // Put it on the list + Item *Itm = new Item; + Itm->Text = S; + Itm->Error = false; + Insert(Itm); + + return false; +} + /*}}}*/ +// GlobalError::PopMessage - Pulls a single message out /*{{{*/ +// --------------------------------------------------------------------- +/* This should be used in a loop checking empty() each cycle. It returns + true if the message is an error. */ +bool GlobalError::PopMessage(string &Text) +{ + if (List == 0) + return false; + + bool Ret = List->Error; + Text = List->Text; + Item *Old = List; + List = List->Next; + delete Old; + + // This really should check the list to see if only warnings are left.. + if (List == 0) + PendingFlag = false; + + return Ret; +} + /*}}}*/ +// GlobalError::DumpErrors - Dump all of the errors/warns to cerr /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GlobalError::DumpErrors() +{ + // Print any errors or warnings found + string Err; + while (empty() == false) + { + bool Type = PopMessage(Err); + if (Type == true) + cerr << "E: " << Err << endl; + else + cerr << "W: " << Err << endl; + } +} + /*}}}*/ +// GlobalError::Discard - Discard /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GlobalError::Discard() +{ + while (List != 0) + { + Item *Old = List; + List = List->Next; + delete Old; + } + + PendingFlag = false; +}; + /*}}}*/ +// GlobalError::Insert - Insert a new item at the end /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GlobalError::Insert(Item *Itm) +{ + if (0) {//akk don't leave this here or it will have evil side effects + // on acquire methods + cerr << Itm->Text.c_str() << endl; + return; + } + Item **End = &List; + for (Item *I = List; I != 0; I = I->Next) + End = &I->Next; + Itm->Next = *End; + *End = Itm; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/error.h b/apt/apt-pkg/contrib/error.h new file mode 100644 index 0000000..5ab802d --- /dev/null +++ b/apt/apt-pkg/contrib/error.h @@ -0,0 +1,89 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: error.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Global Erorr Class - Global error mechanism + + This class has a single global instance. When a function needs to + generate an error condition, such as a read error, it calls a member + in this class to add the error to a stack of errors. + + By using a stack the problem with a scheme like errno is removed and + it allows a very detailed account of what went wrong to be transmitted + to the UI for display. (Errno has problems because each function sets + errno to 0 if it didn't have an error thus eraseing erno in the process + of cleanup) + + Several predefined error generators are provided to handle common + things like errno. The general idea is that all methods return a bool. + If the bool is true then things are OK, if it is false then things + should start being undone and the stack should unwind under program + control. + + A Warning should not force the return of false. Things did not fail, but + they might have had unexpected problems. Errors are stored in a FIFO + so Pop will return the first item.. + + I have some thoughts about extending this into a more general UI<-> + Engine interface, ie allowing the Engine to say 'The disk is full' in + a dialog that says 'Panic' and 'Retry'.. The error generator functions + like errno, Warning and Error return false always so this is normal: + if (open(..)) + return _error->Errno(..); + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_ERROR_H +#define PKGLIB_ERROR_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/error.h" +#endif + +#include + +class GlobalError +{ + struct Item + { + string Text; + bool Error; + Item *Next; + }; + + Item *List; + bool PendingFlag; + void Insert(Item *I); + + public: + + // Call to generate an error from a library call. + bool Errno(const char *Function,const char *Description,...); + bool WarningE(const char *Function,const char *Description,...); + + /* A warning should be considered less severe than an error, and may be + ignored by the client. */ + bool Error(const char *Description,...); + bool Warning(const char *Description,...); + + // Simple accessors + inline bool PendingError() {return PendingFlag;}; + inline bool empty() {return List == 0;}; + bool PopMessage(string &Text); + void Discard(); + + // Usefull routine to dump to cerr + void DumpErrors(); + + GlobalError(); +}; + +// The 'extra-ansi' syntax is used to help with collisions. +GlobalError *_GetErrorObj(); +#define _error _GetErrorObj() + +#endif diff --git a/apt/apt-pkg/contrib/fileutl.cc b/apt/apt-pkg/contrib/fileutl.cc new file mode 100644 index 0000000..da09eb6 --- /dev/null +++ b/apt/apt-pkg/contrib/fileutl.cc @@ -0,0 +1,569 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: fileutl.cc,v 1.3 2000/09/26 14:22:14 kojima Exp $ +/* ###################################################################### + + File Utilities + + CopyFile - Buffered copy of a single file + GetLock - dpkg compatible lock file manipulation (fcntl) + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/fileutl.h" +#endif +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + /*}}}*/ + +// CopyFile - Buffered copy of a file /*{{{*/ +// --------------------------------------------------------------------- +/* The caller is expected to set things so that failure causes erasure */ +bool CopyFile(FileFd &From,FileFd &To) +{ + if (From.IsOpen() == false || To.IsOpen() == false) + return false; + + // Buffered copy between fds + unsigned char *Buf = new unsigned char[64000]; + unsigned long Size = From.Size(); + while (Size != 0) + { + unsigned long ToRead = Size; + if (Size > 64000) + ToRead = 64000; + + if (From.Read(Buf,ToRead) == false || + To.Write(Buf,ToRead) == false) + { + delete [] Buf; + return false; + } + + Size -= ToRead; + } + + delete [] Buf; + return true; +} + /*}}}*/ +// GetLock - Gets a lock file /*{{{*/ +// --------------------------------------------------------------------- +/* This will create an empty file of the given name and lock it. Once this + is done all other calls to GetLock in any other process will fail with + -1. The return result is the fd of the file, the call should call + close at some time. */ +int GetLock(string File,bool Errors) +{ + int FD = open(File.c_str(),O_RDWR | O_CREAT | O_TRUNC,0640); + if (FD < 0) + { + // Read only .. cant have locking problems there. + if (errno == EROFS) + { + _error->Warning("Not using locking for read only lock file %s",File.c_str()); + return dup(0); // Need something for the caller to close + } + + if (Errors == true) + _error->Errno("open","Could not open lock file %s",File.c_str()); + return -1; + } + SetCloseExec(FD,true); + + // Aquire a write lock + struct flock fl; + fl.l_type = F_WRLCK; + fl.l_whence = SEEK_SET; + fl.l_start = 0; + fl.l_len = 0; + if (fcntl(FD,F_SETLK,&fl) == -1) + { + if (errno == ENOLCK) + { + _error->Warning("Not using locking for nfs mounted lock file %s",File.c_str()); + return true; + } + if (Errors == true) + _error->Errno("open","Could not get lock %s",File.c_str()); + close(FD); + return -1; + } + + return FD; +} + /*}}}*/ +// FileExists - Check if a file exists /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileExists(string File) +{ + struct stat Buf; + if (stat(File.c_str(),&Buf) != 0) + return false; + return true; +} + /*}}}*/ +// SafeGetCWD - This is a safer getcwd that returns a dynamic string /*{{{*/ +// --------------------------------------------------------------------- +/* We return / on failure. */ +string SafeGetCWD() +{ + // Stash the current dir. + char S[300]; + S[0] = 0; + if (getcwd(S,sizeof(S)-2) == 0) + return "/"; + unsigned int Len = strlen(S); + S[Len] = '/'; + S[Len+1] = 0; + return S; +} + /*}}}*/ +// flNotDir - Strip the directory from the filename /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string flNotDir(string File) +{ + string::size_type Res = File.rfind('/'); + if (Res == string::npos) + return File; + Res++; + return string(File,Res,Res - File.length()); +} + /*}}}*/ +// flNotFile - Strip the file from the directory name /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string flNotFile(string File) +{ + string::size_type Res = File.rfind('/'); + if (Res == string::npos) + return File; + Res++; + return string(File,0,Res); +} + /*}}}*/ +// flExtension - Return the extension for the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string flExtension(string File) +{ + string::size_type Res = File.rfind('.'); + if (Res == string::npos) + return File; + Res++; + return string(File,Res,Res - File.length()); +} + /*}}}*/ +// flNoLink - If file is a symlink then deref it /*{{{*/ +// --------------------------------------------------------------------- +/* If the name is not a link then the returned path is the input. */ +string flNoLink(string File) +{ + struct stat St; + if (lstat(File.c_str(),&St) != 0 || S_ISLNK(St.st_mode) == 0) + return File; + if (stat(File.c_str(),&St) != 0) + return File; + + /* Loop resolving the link. There is no need to limit the number of + loops because the stat call above ensures that the symlink is not + circular */ + char Buffer[1024]; + string NFile = File; + while (1) + { + // Read the link + int Res; + if ((Res = readlink(NFile.c_str(),Buffer,sizeof(Buffer))) <= 0 || + (unsigned)Res >= sizeof(Buffer)) + return File; + + // Append or replace the previous path + Buffer[Res] = 0; + if (Buffer[0] == '/') + NFile = Buffer; + else + NFile = flNotFile(NFile) + Buffer; + + // See if we are done + if (lstat(NFile.c_str(),&St) != 0) + return File; + if (S_ISLNK(St.st_mode) == 0) + return NFile; + } +} + /*}}}*/ +// flCombine - Combine a file and a directory /*{{{*/ +// --------------------------------------------------------------------- +/* If the file is an absolute path then it is just returned, otherwise + the directory is pre-pended to it. */ +string flCombine(string Dir,string File) +{ + if (File.empty() == true) + return string(); + + if (File[0] == '/' || Dir.empty() == true) + return File; + if (File.length() >= 2 && File[0] == '.' && File[1] == '/') + return File; + if (Dir[Dir.length()-1] == '/') + return Dir + File; + return Dir + '/' + File; +} + /*}}}*/ +// SetCloseExec - Set the close on exec flag /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void SetCloseExec(int Fd,bool Close) +{ + if (fcntl(Fd,F_SETFD,(Close == false)?0:FD_CLOEXEC) != 0) + { + cerr << "FATAL -> Could not set close on exec " << strerror(errno) << endl; + exit(100); + } +} + /*}}}*/ +// SetNonBlock - Set the nonblocking flag /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void SetNonBlock(int Fd,bool Block) +{ + int Flags = fcntl(Fd,F_GETFL) & (~O_NONBLOCK); + if (fcntl(Fd,F_SETFL,Flags | ((Block == false)?0:O_NONBLOCK)) != 0) + { + cerr << "FATAL -> Could not set non-blocking flag " << strerror(errno) << endl; + exit(100); + } +} + /*}}}*/ +// WaitFd - Wait for a FD to become readable /*{{{*/ +// --------------------------------------------------------------------- +/* This waits for a FD to become readable using select. It is useful for + applications making use of non-blocking sockets. The timeout is + in seconds. */ +bool WaitFd(int Fd,bool write,unsigned long timeout) +{ + fd_set Set; + struct timeval tv; + FD_ZERO(&Set); + FD_SET(Fd,&Set); + tv.tv_sec = timeout; + tv.tv_usec = 0; + if (write == true) + { + int Res; + do + { + Res = select(Fd+1,0,&Set,0,(timeout != 0?&tv:0)); + } + while (Res < 0 && errno == EINTR); + + if (Res <= 0) + return false; + } + else + { + int Res; + do + { + Res = select(Fd+1,&Set,0,0,(timeout != 0?&tv:0)); + } + while (Res < 0 && errno == EINTR); + + if (Res <= 0) + return false; + } + + return true; +} + /*}}}*/ +// ExecFork - Magical fork that sanitizes the context before execing /*{{{*/ +// --------------------------------------------------------------------- +/* This is used if you want to cleanse the environment for the forked + child, it fixes up the important signals and nukes all of the fds, + otherwise acts like normal fork. */ +int ExecFork() +{ + // Fork off the process + pid_t Process = fork(); + if (Process < 0) + { + cerr << "FATAL -> Failed to fork." << endl; + exit(100); + } + + // Spawn the subprocess + if (Process == 0) + { + // Setup the signals + signal(SIGPIPE,SIG_DFL); + signal(SIGQUIT,SIG_DFL); + signal(SIGINT,SIG_DFL); + signal(SIGWINCH,SIG_DFL); + signal(SIGCONT,SIG_DFL); + signal(SIGTSTP,SIG_DFL); + + // Close all of our FDs - just in case + for (int K = 3; K != 40; K++) + fcntl(K,F_SETFD,FD_CLOEXEC); + } + + return Process; +} + /*}}}*/ +// ExecWait - Fancy waitpid /*{{{*/ +// --------------------------------------------------------------------- +/* Waits for the given sub process. If Reap is set the no errors are + generated. Otherwise a failed subprocess will generate a proper descriptive + message */ +bool ExecWait(int Pid,const char *Name,bool Reap) +{ + if (Pid <= 1) + return true; + + // Wait and collect the error code + int Status; + while (waitpid(Pid,&Status,0) != Pid) + { + if (errno == EINTR) + continue; + + if (Reap == true) + return false; + + return _error->Error("Waited, for %s but it wasn't there",Name); + } + + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + { + if (Reap == true) + return false; + if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) + return _error->Error("Sub-process %s recieved a segmentation fault.",Name); + + if (WIFEXITED(Status) != 0) + return _error->Error("Sub-process %s returned an error code (%u)",Name,WEXITSTATUS(Status)); + + return _error->Error("Sub-process %s exited unexpectedly",Name); + } + + return true; +} + /*}}}*/ + +// FileFd::Open - Open a file /*{{{*/ +// --------------------------------------------------------------------- +/* The most commonly used open mode combinations are given with Mode */ +bool FileFd::Open(string FileName,OpenMode Mode, unsigned long Perms) +{ + Close(); + Flags = AutoClose; + switch (Mode) + { + case ReadOnly: + iFd = open(FileName.c_str(),O_RDONLY); + break; + + case WriteEmpty: + { + struct stat Buf; + if (lstat(FileName.c_str(),&Buf) == 0 && S_ISLNK(Buf.st_mode)) + unlink(FileName.c_str()); + iFd = open(FileName.c_str(),O_RDWR | O_CREAT | O_TRUNC,Perms); + break; + } + + case WriteExists: + iFd = open(FileName.c_str(),O_RDWR); + break; + + case WriteAny: + iFd = open(FileName.c_str(),O_RDWR | O_CREAT,Perms); + break; + } + + if (iFd < 0) + return _error->Errno("open","Could not open file %s",FileName.c_str()); + + this->FileName = FileName; + SetCloseExec(iFd,true); + return true; +} + /*}}}*/ +// FileFd::~File - Closes the file /*{{{*/ +// --------------------------------------------------------------------- +/* If the proper modes are selected then we close the Fd and possibly + unlink the file on error. */ +FileFd::~FileFd() +{ + Close(); +} + /*}}}*/ +// FileFd::Read - Read a bit of the file /*{{{*/ +// --------------------------------------------------------------------- +/* We are carefull to handle interruption by a signal while reading + gracefully. */ +bool FileFd::Read(void *To,unsigned long Size,bool AllowEof) +{ + int Res; + errno = 0; + do + { + Res = read(iFd,To,Size); + if (Res < 0 && errno == EINTR) + continue; + if (Res < 0) + { + Flags |= Fail; + return _error->Errno("read","Read error"); + } + + To = (char *)To + Res; + Size -= Res; + } + while (Res > 0 && Size > 0); + + if (Size == 0) + return true; + + // Eof handling + if (AllowEof == true) + { + Flags |= HitEof; + return true; + } + + Flags |= Fail; + return _error->Error("read, still have %u to read but none left",Size); +} + /*}}}*/ +// FileFd::Write - Write to the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileFd::Write(const void *From,unsigned long Size) +{ + int Res; + errno = 0; + do + { + Res = write(iFd,From,Size); + if (Res < 0 && errno == EINTR) + continue; + if (Res < 0) + { + Flags |= Fail; + return _error->Errno("write","Write error"); + } + + From = (char *)From + Res; + Size -= Res; + } + while (Res > 0 && Size > 0); + + if (Size == 0) + return true; + + Flags |= Fail; + return _error->Error("write, still have %u to write but couldn't",Size); +} + /*}}}*/ +// FileFd::Seek - Seek in the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileFd::Seek(unsigned long To) +{ + if (lseek(iFd,To,SEEK_SET) != (signed)To) + { + Flags |= Fail; + return _error->Error("Unable to seek to %u",To); + } + + return true; +} + /*}}}*/ +// FileFd::Skip - Seek in the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileFd::Skip(unsigned long Over) +{ + if (lseek(iFd,Over,SEEK_CUR) < 0) + { + Flags |= Fail; + return _error->Error("Unable to seek ahead %u",Over); + } + + return true; +} + /*}}}*/ +// FileFd::Truncate - Truncate the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileFd::Truncate(unsigned long To) +{ + if (ftruncate(iFd,To) != 0) + { + Flags |= Fail; + return _error->Error("Unable to truncate to %u",To); + } + + return true; +} + /*}}}*/ +// FileFd::Tell - Current seek position /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long FileFd::Tell() +{ + off_t Res = lseek(iFd,0,SEEK_CUR); + if (Res == (off_t)-1) + _error->Errno("lseek","Failed to determine the current file position"); + return Res; +} + /*}}}*/ +// FileFd::Size - Return the size of the file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long FileFd::Size() +{ + struct stat Buf; + if (fstat(iFd,&Buf) != 0) + return _error->Errno("fstat","Unable to determine the file size"); + return Buf.st_size; +} + /*}}}*/ +// FileFd::Close - Close the file if the close flag is set /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileFd::Close() +{ + bool Res = true; + if ((Flags & AutoClose) == AutoClose) + if (iFd >= 0 && close(iFd) != 0) + Res &= _error->Errno("close","Problem closing the file"); + iFd = -1; + + if ((Flags & Fail) == Fail && (Flags & DelOnFail) == DelOnFail && + FileName.empty() == false) + if (unlink(FileName.c_str()) != 0) + Res &= _error->Warning("unlnk","Problem unlinking the file"); + return Res; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/fileutl.h b/apt/apt-pkg/contrib/fileutl.h new file mode 100644 index 0000000..e3b18a8 --- /dev/null +++ b/apt/apt-pkg/contrib/fileutl.h @@ -0,0 +1,90 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: fileutl.h,v 1.2 2000/09/26 14:22:14 kojima Exp $ +/* ###################################################################### + + File Utilities + + CopyFile - Buffered copy of a single file + GetLock - dpkg compatible lock file manipulation (fcntl) + FileExists - Returns true if the file exists + SafeGetCWD - Returns the CWD in a string with overrun protection + + The file class is a handy abstraction for various functions+classes + that need to accept filenames. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_FILEUTL_H +#define PKGLIB_FILEUTL_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/fileutl.h" +#endif + +#include + +class FileFd +{ + protected: + int iFd; + + enum LocalFlags {AutoClose = (1<<0),Fail = (1<<1),DelOnFail = (1<<2), + HitEof = (1<<3)}; + unsigned long Flags; + string FileName; + + public: + enum OpenMode {ReadOnly,WriteEmpty,WriteExists,WriteAny}; + + bool Read(void *To,unsigned long Size,bool AllowEof = false); + bool Write(const void *From,unsigned long Size); + bool Seek(unsigned long To); + bool Skip(unsigned long To); + bool Truncate(unsigned long To); + unsigned long Tell(); + unsigned long Size(); + bool Open(string FileName,OpenMode Mode,unsigned long Perms = 0666); + bool Close(); + + // Simple manipulators + inline int Fd() {return iFd;}; + inline void Fd(int fd) {iFd = fd;}; + inline bool IsOpen() {return iFd >= 0;}; + inline bool Failed() {return (Flags & Fail) == Fail;}; + inline void EraseOnFailure() {Flags |= DelOnFail;}; + inline void OpFail() {Flags |= Fail;}; + inline bool Eof() {return (Flags & HitEof) == HitEof;}; + inline string &Name() {return FileName;}; + + FileFd(string FileName,OpenMode Mode,unsigned long Perms = 0666) : iFd(-1), + Flags(0) + { + Open(FileName,Mode,Perms); + }; + FileFd(int Fd = -1) : iFd(Fd), Flags(AutoClose) {}; + FileFd(int Fd,bool) : iFd(Fd), Flags(0) {}; + virtual ~FileFd(); +}; + +bool CopyFile(FileFd &From,FileFd &To); +int GetLock(string File,bool Errors = true); +bool FileExists(string File); +string SafeGetCWD(); +void SetCloseExec(int Fd,bool Close); +void SetNonBlock(int Fd,bool Block); +bool WaitFd(int Fd,bool write = false,unsigned long timeout = 0); +int ExecFork(); +bool ExecWait(int Pid,const char *Name,bool Reap = false); + +// File string manipulators +string flNotDir(string File); +string flNotFile(string File); +string flNoLink(string File); +string flExtension(string File); +string flCombine(string Dir,string File); + +#endif diff --git a/apt/apt-pkg/contrib/i18n.h b/apt/apt-pkg/contrib/i18n.h new file mode 100644 index 0000000..f60e77b --- /dev/null +++ b/apt/apt-pkg/contrib/i18n.h @@ -0,0 +1,54 @@ +/* i18n.h -- Internationalization stuff (ripped from bash) + + Copyright (C) 1996 Free Software Foundation, Inc. + + This file is part of GNU Bash, the Bourne Again SHell. + + Modified 9/2000 by Alfredo K. Kojima for apt + + Bash is free software; you can redistribute it and/or modify it under + the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2, or (at your option) any later + version. + + Bash is distributed in the hope that it will be useful, but WITHOUT ANY + WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + for more details. + + You should have received a copy of the GNU General Public License along + with Bash; see the file COPYING. If not, write to the Free Software + Foundation, 59 Temple Place, Suite 330, Boston, MA 02111 USA. */ + +#if !defined (_I18N_H_) +#define _I18N_H_ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined (HAVE_LIBINTL_H) +# include +#endif + +#if defined (HAVE_LOCALE_H) +# include +#endif + +#if defined (HAVE_SETLOCALE) && !defined (LC_ALL) +# undef HAVE_SETLOCALE +#endif + +#if ENABLE_NLS +# define _(a) (const char*)gettext(a) +#else +# undef bindtextdomain +# define bindtextdomain(Domain, Directory) /* empty */ +# undef textdomain +# define textdomain(Domain) /* empty */ +# undef setlocale +# define setlocale(cat, log) +# define _(a) a +#endif + +#endif /* !_I18N_H_ */ diff --git a/apt/apt-pkg/contrib/md5.cc b/apt/apt-pkg/contrib/md5.cc new file mode 100644 index 0000000..1c042bf --- /dev/null +++ b/apt/apt-pkg/contrib/md5.cc @@ -0,0 +1,358 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: md5.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + MD5Sum - MD5 Message Digest Algorithm. + + This code implements the MD5 message-digest algorithm. The algorithm is + due to Ron Rivest. This code was written by Colin Plumb in 1993, no + copyright is claimed. This code is in the public domain; do with it what + you wish. + + Equivalent code is available from RSA Data Security, Inc. This code has + been tested against that, and is equivalent, except that you don't need to + include two pages of legalese with every copy. + + To compute the message digest of a chunk of bytes, instantiate the class, + and repeatedly call one of the Add() members. When finished the Result + method will return the Hash and finalize the value. + + Changed so as no longer to depend on Colin Plumb's `usual.h' header + definitions; now uses stuff from dpkg's config.h. + - Ian Jackson . + + Changed into a C++ interface and made work with APT's config.h. + - Jason Gunthorpe + + Still in the public domain. + + The classes use arrays of char that are a specific size. We cast those + arrays to uint8_t's and go from there. This allows us to advoid using + the uncommon inttypes.h in a public header or internally newing memory. + In theory if C9x becomes nicely accepted + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/md5.h" +#endif + +#include +#include + +#include +#include +#include // For htonl +#include +#include +#include + /*}}}*/ + +// byteSwap - Swap bytes in a buffer /*{{{*/ +// --------------------------------------------------------------------- +/* Swap n 32 bit longs in given buffer */ +#ifdef WORDS_BIGENDIAN +static void byteSwap(uint32_t *buf, unsigned words) +{ + uint8_t *p = (uint8_t *)buf; + + do + { + *buf++ = (uint32_t)((unsigned)p[3] << 8 | p[2]) << 16 | + ((unsigned)p[1] << 8 | p[0]); + p += 4; + } while (--words); +} +#else +#define byteSwap(buf,words) +#endif + /*}}}*/ +// MD5Transform - Alters an existing MD5 hash /*{{{*/ +// --------------------------------------------------------------------- +/* The core of the MD5 algorithm, this alters an existing MD5 hash to + reflect the addition of 16 longwords of new data. Add blocks + the data and converts bytes into longwords for this routine. */ + +// The four core functions - F1 is optimized somewhat +// #define F1(x, y, z) (x & y | ~x & z) +#define F1(x, y, z) (z ^ (x & (y ^ z))) +#define F2(x, y, z) F1(z, x, y) +#define F3(x, y, z) (x ^ y ^ z) +#define F4(x, y, z) (y ^ (x | ~z)) + +// This is the central step in the MD5 algorithm. +#define MD5STEP(f,w,x,y,z,in,s) \ + (w += f(x,y,z) + in, w = (w<>(32-s)) + x) + +static void MD5Transform(uint32_t buf[4], uint32_t const in[16]) +{ + register uint32_t a, b, c, d; + + a = buf[0]; + b = buf[1]; + c = buf[2]; + d = buf[3]; + + MD5STEP(F1, a, b, c, d, in[0] + 0xd76aa478, 7); + MD5STEP(F1, d, a, b, c, in[1] + 0xe8c7b756, 12); + MD5STEP(F1, c, d, a, b, in[2] + 0x242070db, 17); + MD5STEP(F1, b, c, d, a, in[3] + 0xc1bdceee, 22); + MD5STEP(F1, a, b, c, d, in[4] + 0xf57c0faf, 7); + MD5STEP(F1, d, a, b, c, in[5] + 0x4787c62a, 12); + MD5STEP(F1, c, d, a, b, in[6] + 0xa8304613, 17); + MD5STEP(F1, b, c, d, a, in[7] + 0xfd469501, 22); + MD5STEP(F1, a, b, c, d, in[8] + 0x698098d8, 7); + MD5STEP(F1, d, a, b, c, in[9] + 0x8b44f7af, 12); + MD5STEP(F1, c, d, a, b, in[10] + 0xffff5bb1, 17); + MD5STEP(F1, b, c, d, a, in[11] + 0x895cd7be, 22); + MD5STEP(F1, a, b, c, d, in[12] + 0x6b901122, 7); + MD5STEP(F1, d, a, b, c, in[13] + 0xfd987193, 12); + MD5STEP(F1, c, d, a, b, in[14] + 0xa679438e, 17); + MD5STEP(F1, b, c, d, a, in[15] + 0x49b40821, 22); + + MD5STEP(F2, a, b, c, d, in[1] + 0xf61e2562, 5); + MD5STEP(F2, d, a, b, c, in[6] + 0xc040b340, 9); + MD5STEP(F2, c, d, a, b, in[11] + 0x265e5a51, 14); + MD5STEP(F2, b, c, d, a, in[0] + 0xe9b6c7aa, 20); + MD5STEP(F2, a, b, c, d, in[5] + 0xd62f105d, 5); + MD5STEP(F2, d, a, b, c, in[10] + 0x02441453, 9); + MD5STEP(F2, c, d, a, b, in[15] + 0xd8a1e681, 14); + MD5STEP(F2, b, c, d, a, in[4] + 0xe7d3fbc8, 20); + MD5STEP(F2, a, b, c, d, in[9] + 0x21e1cde6, 5); + MD5STEP(F2, d, a, b, c, in[14] + 0xc33707d6, 9); + MD5STEP(F2, c, d, a, b, in[3] + 0xf4d50d87, 14); + MD5STEP(F2, b, c, d, a, in[8] + 0x455a14ed, 20); + MD5STEP(F2, a, b, c, d, in[13] + 0xa9e3e905, 5); + MD5STEP(F2, d, a, b, c, in[2] + 0xfcefa3f8, 9); + MD5STEP(F2, c, d, a, b, in[7] + 0x676f02d9, 14); + MD5STEP(F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20); + + MD5STEP(F3, a, b, c, d, in[5] + 0xfffa3942, 4); + MD5STEP(F3, d, a, b, c, in[8] + 0x8771f681, 11); + MD5STEP(F3, c, d, a, b, in[11] + 0x6d9d6122, 16); + MD5STEP(F3, b, c, d, a, in[14] + 0xfde5380c, 23); + MD5STEP(F3, a, b, c, d, in[1] + 0xa4beea44, 4); + MD5STEP(F3, d, a, b, c, in[4] + 0x4bdecfa9, 11); + MD5STEP(F3, c, d, a, b, in[7] + 0xf6bb4b60, 16); + MD5STEP(F3, b, c, d, a, in[10] + 0xbebfbc70, 23); + MD5STEP(F3, a, b, c, d, in[13] + 0x289b7ec6, 4); + MD5STEP(F3, d, a, b, c, in[0] + 0xeaa127fa, 11); + MD5STEP(F3, c, d, a, b, in[3] + 0xd4ef3085, 16); + MD5STEP(F3, b, c, d, a, in[6] + 0x04881d05, 23); + MD5STEP(F3, a, b, c, d, in[9] + 0xd9d4d039, 4); + MD5STEP(F3, d, a, b, c, in[12] + 0xe6db99e5, 11); + MD5STEP(F3, c, d, a, b, in[15] + 0x1fa27cf8, 16); + MD5STEP(F3, b, c, d, a, in[2] + 0xc4ac5665, 23); + + MD5STEP(F4, a, b, c, d, in[0] + 0xf4292244, 6); + MD5STEP(F4, d, a, b, c, in[7] + 0x432aff97, 10); + MD5STEP(F4, c, d, a, b, in[14] + 0xab9423a7, 15); + MD5STEP(F4, b, c, d, a, in[5] + 0xfc93a039, 21); + MD5STEP(F4, a, b, c, d, in[12] + 0x655b59c3, 6); + MD5STEP(F4, d, a, b, c, in[3] + 0x8f0ccc92, 10); + MD5STEP(F4, c, d, a, b, in[10] + 0xffeff47d, 15); + MD5STEP(F4, b, c, d, a, in[1] + 0x85845dd1, 21); + MD5STEP(F4, a, b, c, d, in[8] + 0x6fa87e4f, 6); + MD5STEP(F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10); + MD5STEP(F4, c, d, a, b, in[6] + 0xa3014314, 15); + MD5STEP(F4, b, c, d, a, in[13] + 0x4e0811a1, 21); + MD5STEP(F4, a, b, c, d, in[4] + 0xf7537e82, 6); + MD5STEP(F4, d, a, b, c, in[11] + 0xbd3af235, 10); + MD5STEP(F4, c, d, a, b, in[2] + 0x2ad7d2bb, 15); + MD5STEP(F4, b, c, d, a, in[9] + 0xeb86d391, 21); + + buf[0] += a; + buf[1] += b; + buf[2] += c; + buf[3] += d; +} + /*}}}*/ +// MD5SumValue::MD5SumValue - Constructs the summation from a string /*{{{*/ +// --------------------------------------------------------------------- +/* The string form of a MD5 is a 32 character hex number */ +MD5SumValue::MD5SumValue(string Str) +{ + memset(Sum,0,sizeof(Sum)); + Set(Str); +} + /*}}}*/ +// MD5SumValue::MD5SumValue - Default constructor /*{{{*/ +// --------------------------------------------------------------------- +/* Sets the value to 0 */ +MD5SumValue::MD5SumValue() +{ + memset(Sum,0,sizeof(Sum)); +} + /*}}}*/ +// MD5SumValue::Set - Set the sum from a string /*{{{*/ +// --------------------------------------------------------------------- +/* Converts the hex string into a set of chars */ +bool MD5SumValue::Set(string Str) +{ + return Hex2Num(Str.begin(),Str.end(),Sum,sizeof(Sum)); +} + /*}}}*/ +// MD5SumValue::Value - Convert the number into a string /*{{{*/ +// --------------------------------------------------------------------- +/* Converts the set of chars into a hex string in lower case */ +string MD5SumValue::Value() const +{ + char Conv[16] = {'0','1','2','3','4','5','6','7','8','9','a','b', + 'c','d','e','f'}; + char Result[33]; + Result[32] = 0; + + // Convert each char into two letters + int J = 0; + int I = 0; + for (; I != 32; J++, I += 2) + { + Result[I] = Conv[Sum[J] >> 4]; + Result[I + 1] = Conv[Sum[J] & 0xF]; + } + + return string(Result); +} + /*}}}*/ +// MD5SumValue::operator == - Comparitor /*{{{*/ +// --------------------------------------------------------------------- +/* Call memcmp on the buffer */ +bool MD5SumValue::operator ==(const MD5SumValue &rhs) const +{ + return memcmp(Sum,rhs.Sum,sizeof(Sum)) == 0; +} + /*}}}*/ +// MD5Summation::MD5Summation - Initialize the summer /*{{{*/ +// --------------------------------------------------------------------- +/* This assigns the deep magic initial values */ +MD5Summation::MD5Summation() +{ + uint32_t *buf = (uint32_t *)Buf; + uint32_t *bytes = (uint32_t *)Bytes; + + buf[0] = 0x67452301; + buf[1] = 0xefcdab89; + buf[2] = 0x98badcfe; + buf[3] = 0x10325476; + + bytes[0] = 0; + bytes[1] = 0; + Done = false; +} + /*}}}*/ +// MD5Summation::Add - 'Add' a data set to the hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MD5Summation::Add(const unsigned char *data,unsigned long len) +{ + if (Done == true) + return false; + + uint32_t *buf = (uint32_t *)Buf; + uint32_t *bytes = (uint32_t *)Bytes; + uint32_t *in = (uint32_t *)In; + + // Update byte count and carry (this could be done with a long long?) + uint32_t t = bytes[0]; + if ((bytes[0] = t + len) < t) + bytes[1]++; + + // Space available (at least 1) + t = 64 - (t & 0x3f); + if (t > len) + { + memcpy((unsigned char *)in + 64 - t,data,len); + return true; + } + + // First chunk is an odd size + memcpy((unsigned char *)in + 64 - t,data,t); + byteSwap(in, 16); + MD5Transform(buf,in); + data += t; + len -= t; + + // Process data in 64-byte chunks + while (len >= 64) + { + memcpy(in,data,64); + byteSwap(in,16); + MD5Transform(buf,in); + data += 64; + len -= 64; + } + + // Handle any remaining bytes of data. + memcpy(in,data,len); + + return true; +} + /*}}}*/ +// MD5Summation::AddFD - Add the contents of a FD to the hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MD5Summation::AddFD(int Fd,unsigned long Size) +{ + unsigned char Buf[64*64]; + int Res = 0; + while (Size != 0) + { + Res = read(Fd,Buf,MIN(Size,sizeof(Buf))); + if (Res < 0 || (unsigned)Res != MIN(Size,sizeof(Buf))) + return false; + Size -= Res; + Add(Buf,Res); + } + return true; +} + /*}}}*/ +// MD5Summation::Result - Returns the value of the sum /*{{{*/ +// --------------------------------------------------------------------- +/* Because this must add in the last bytes of the series it prevents anyone + from calling add after. */ +MD5SumValue MD5Summation::Result() +{ + uint32_t *buf = (uint32_t *)Buf; + uint32_t *bytes = (uint32_t *)Bytes; + uint32_t *in = (uint32_t *)In; + + if (Done == false) + { + // Number of bytes in In + int count = bytes[0] & 0x3f; + unsigned char *p = (unsigned char *)in + count; + + // Set the first char of padding to 0x80. There is always room. + *p++ = 0x80; + + // Bytes of padding needed to make 56 bytes (-8..55) + count = 56 - 1 - count; + + // Padding forces an extra block + if (count < 0) + { + memset(p,0,count + 8); + byteSwap(in, 16); + MD5Transform(buf,in); + p = (unsigned char *)in; + count = 56; + } + + memset(p, 0, count); + byteSwap(in, 14); + + // Append length in bits and transform + in[14] = bytes[0] << 3; + in[15] = bytes[1] << 3 | bytes[0] >> 29; + MD5Transform(buf,in); + byteSwap(buf,4); + Done = true; + } + + MD5SumValue V; + memcpy(V.Sum,buf,16); + return V; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/md5.h b/apt/apt-pkg/contrib/md5.h new file mode 100644 index 0000000..8503664 --- /dev/null +++ b/apt/apt-pkg/contrib/md5.h @@ -0,0 +1,74 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: md5.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + MD5SumValue - Storage for a MD5Sum + MD5Summation - MD5 Message Digest Algorithm. + + This is a C++ interface to a set of MD5Sum functions. The class can + store a MD5Sum in 16 bytes of memory. + + A MD5Sum is used to generate a (hopefully) unique 16 byte number for a + block of data. This can be used to gaurd against corruption of a file. + MD5 should not be used for tamper protection, use SHA or something more + secure. + + There are two classes because computing a MD5 is not a continual + operation unless 64 byte blocks are used. Also the summation requires an + extra 18*4 bytes to operate. + + ##################################################################### */ + /*}}}*/ +#ifndef APTPKG_MD5_H +#define APTPKG_MD5_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/md5.h" +#endif + +#include + +class MD5Summation; + +class MD5SumValue +{ + friend MD5Summation; + unsigned char Sum[4*4]; + + public: + + // Accessors + bool operator ==(const MD5SumValue &rhs) const; + string Value() const; + inline void Value(unsigned char S[16]) + {for (int I = 0; I != sizeof(Sum); I++) S[I] = Sum[I];}; + inline operator string() const {return Value();}; + bool Set(string Str); + inline void Set(unsigned char S[16]) + {for (int I = 0; I != sizeof(Sum); I++) Sum[I] = S[I];}; + + MD5SumValue(string Str); + MD5SumValue(); +}; + +class MD5Summation +{ + unsigned char Buf[4*4]; + unsigned char Bytes[2*4]; + unsigned char In[16*4]; + bool Done; + + public: + + bool Add(const unsigned char *Data,unsigned long Size); + inline bool Add(const char *Data) {return Add((unsigned char *)Data,strlen(Data));}; + bool AddFD(int Fd,unsigned long Size); + inline bool Add(const unsigned char *Beg,const unsigned char *End) + {return Add(Beg,End-Beg);}; + MD5SumValue Result(); + + MD5Summation(); +}; + +#endif diff --git a/apt/apt-pkg/contrib/mmap.cc b/apt/apt-pkg/contrib/mmap.cc new file mode 100644 index 0000000..e5359bf --- /dev/null +++ b/apt/apt-pkg/contrib/mmap.cc @@ -0,0 +1,279 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: mmap.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + MMap Class - Provides 'real' mmap or a faked mmap using read(). + + MMap cover class. + + Some broken versions of glibc2 (libc6) have a broken definition + of mmap that accepts a char * -- all other systems (and libc5) use + void *. We can't safely do anything here that would be portable, so + libc6 generates warnings -- which should be errors, g++ isn't properly + strict. + + The configure test notes that some OS's have broken private mmap's + so on those OS's we can't use mmap. This means we have to use + configure to test mmap and can't rely on the POSIX + _POSIX_MAPPED_FILES test. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/mmap.h" +#endif + +#define _BSD_SOURCE +#include +#include + +#include +#include +#include +#include + /*}}}*/ + +// MMap::MMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::MMap(FileFd &F,unsigned long Flags) : Flags(Flags), iSize(0), + Base(0) +{ + if ((Flags & NoImmMap) != NoImmMap) + Map(F); +} + /*}}}*/ +// MMap::MMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::MMap(unsigned long Flags) : Flags(Flags), iSize(0), + Base(0) +{ +} + /*}}}*/ +// MMap::~MMap - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MMap::~MMap() +{ + Close(); +} + /*}}}*/ +// MMap::Map - Perform the mapping /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Map(FileFd &Fd) +{ + iSize = Fd.Size(); + + // Set the permissions. + int Prot = PROT_READ; + int Map = MAP_SHARED; + if ((Flags & ReadOnly) != ReadOnly) + Prot |= PROT_WRITE; + if ((Flags & Public) != Public) + Map = MAP_PRIVATE; + + if (iSize == 0) + return _error->Error("Can't mmap an empty file"); + + // Map it. + Base = mmap(0,iSize,Prot,Map,Fd.Fd(),0); + if (Base == (void *)-1) + return _error->Errno("mmap","Couldn't make mmap of %u bytes",iSize); + + return true; +} + /*}}}*/ +// MMap::Close - Close the map /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Close(bool DoSync) +{ + if ((Flags & UnMapped) == UnMapped || Base == 0 || iSize == 0) + return true; + + if (DoSync == true) + Sync(); + + if (munmap((char *)Base,iSize) != 0) + _error->Warning("Unable to munmap"); + + iSize = 0; + return true; +} + /*}}}*/ +// MMap::Sync - Syncronize the map with the disk /*{{{*/ +// --------------------------------------------------------------------- +/* This is done in syncronous mode - the docs indicate that this will + not return till all IO is complete */ +bool MMap::Sync() +{ + if ((Flags & UnMapped) == UnMapped) + return true; + +#ifdef _POSIX_SYNCHRONIZED_IO + if ((Flags & ReadOnly) != ReadOnly) + if (msync((char *)Base,iSize,MS_SYNC) != 0) + return _error->Errno("msync","Unable to write mmap"); +#endif + return true; +} + /*}}}*/ +// MMap::Sync - Syncronize a section of the file to disk /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool MMap::Sync(unsigned long Start,unsigned long Stop) +{ + if ((Flags & UnMapped) == UnMapped) + return true; + +#ifdef _POSIX_SYNCHRONIZED_IO + unsigned long PSize = sysconf(_SC_PAGESIZE); + if ((Flags & ReadOnly) != ReadOnly) + if (msync((char *)Base+(int)(Start/PSize)*PSize,Stop - Start,MS_SYNC) != 0) + return _error->Errno("msync","Unable to write mmap"); +#endif + return true; +} + /*}}}*/ + +// DynamicMMap::DynamicMMap - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +DynamicMMap::DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace) : + MMap(F,Flags | NoImmMap), Fd(&F), WorkSpace(WorkSpace) +{ + if (_error->PendingError() == true) + return; + + unsigned long EndOfFile = Fd->Size(); + Fd->Seek(WorkSpace); + char C = 0; + Fd->Write(&C,sizeof(C)); + Map(F); + iSize = EndOfFile; +} + /*}}}*/ +// DynamicMMap::DynamicMMap - Constructor for a non-file backed map /*{{{*/ +// --------------------------------------------------------------------- +/* This is just a fancy malloc really.. */ +DynamicMMap::DynamicMMap(unsigned long Flags,unsigned long WorkSpace) : + MMap(Flags | NoImmMap | UnMapped), Fd(0), WorkSpace(WorkSpace) +{ + if (_error->PendingError() == true) + return; + + Base = new unsigned char[WorkSpace]; + iSize = 0; +} + /*}}}*/ +// DynamicMMap::~DynamicMMap - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* We truncate the file to the size of the memory data set */ +DynamicMMap::~DynamicMMap() +{ + if (Fd == 0) + { + delete [] (unsigned char *)Base; + return; + } + + unsigned long EndOfFile = iSize; + Sync(); + iSize = WorkSpace; + Close(false); + ftruncate(Fd->Fd(),EndOfFile); + Fd->Close(); +} + /*}}}*/ +// DynamicMMap::RawAllocate - Allocate a raw chunk of unaligned space /*{{{*/ +// --------------------------------------------------------------------- +/* This allocates a block of memory aligned to the given size */ +unsigned long DynamicMMap::RawAllocate(unsigned long Size,unsigned long Aln) +{ + unsigned long Result = iSize; + if (Aln != 0) + Result += Aln - (iSize%Aln); + + iSize = Result + Size; + + // Just in case error check + if (Result + Size > WorkSpace) + { + _error->Error("Dynamic MMap ran out of room"); + return 0; + } + + return Result; +} + /*}}}*/ +// DynamicMMap::Allocate - Pooled aligned allocation /*{{{*/ +// --------------------------------------------------------------------- +/* This allocates an Item of size ItemSize so that it is aligned to its + size in the file. */ +unsigned long DynamicMMap::Allocate(unsigned long ItemSize) +{ + // Look for a matching pool entry + Pool *I; + Pool *Empty = 0; + for (I = Pools; I != Pools + PoolCount; I++) + { + if (I->ItemSize == 0) + Empty = I; + if (I->ItemSize == ItemSize) + break; + } + + // No pool is allocated, use an unallocated one + if (I == Pools + PoolCount) + { + // Woops, we ran out, the calling code should allocate more. + if (Empty == 0) + { + _error->Error("Ran out of allocation pools"); + return 0; + } + + I = Empty; + I->ItemSize = ItemSize; + I->Count = 0; + } + + // Out of space, allocate some more + if (I->Count == 0) + { + I->Count = 20*1024/ItemSize; + I->Start = RawAllocate(I->Count*ItemSize,ItemSize); + } + + I->Count--; + unsigned long Result = I->Start; + I->Start += ItemSize; + return Result/ItemSize; +} + /*}}}*/ +// DynamicMMap::WriteString - Write a string to the file /*{{{*/ +// --------------------------------------------------------------------- +/* Strings are not aligned to anything */ +unsigned long DynamicMMap::WriteString(const char *String, + unsigned long Len) +{ + unsigned long Result = iSize; + // Just in case error check + if (Result + Len > WorkSpace) + { + _error->Error("Dynamic MMap ran out of room"); + return 0; + } + + if (Len == (unsigned long)-1) + Len = strlen(String); + iSize += Len + 1; + memcpy((char *)Base + Result,String,Len); + ((char *)Base)[Result + Len] = 0; + return Result; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/mmap.h b/apt/apt-pkg/contrib/mmap.h new file mode 100644 index 0000000..0f373a1 --- /dev/null +++ b/apt/apt-pkg/contrib/mmap.h @@ -0,0 +1,103 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: mmap.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + MMap Class - Provides 'real' mmap or a faked mmap using read(). + + The purpose of this code is to provide a generic way for clients to + access the mmap function. In enviroments that do not support mmap + from file fd's this function will use read and normal allocated + memory. + + Writing to a public mmap will always fully comit all changes when the + class is deleted. Ie it will rewrite the file, unless it is readonly + + The DynamicMMap class is used to help the on-disk data structure + generators. It provides a large allocated workspace and members + to allocate space from the workspace in an effecient fashion. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_MMAP_H +#define PKGLIB_MMAP_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/mmap.h" +#endif + +#include +#include + +/* This should be a 32 bit type, larger tyes use too much ram and smaller + types are too small. Where ever possible 'unsigned long' should be used + instead of this internal type */ +typedef unsigned int map_ptrloc; + +class MMap +{ + protected: + + unsigned long Flags; + unsigned long iSize; + void *Base; + + bool Map(FileFd &Fd); + bool Close(bool DoSync = true); + + public: + + enum OpenFlags {NoImmMap = (1<<0),Public = (1<<1),ReadOnly = (1<<2), + UnMapped = (1<<3)}; + + // Simple accessors + inline operator void *() {return Base;}; + inline void *Data() {return Base;}; + inline unsigned long Size() {return iSize;}; + + // File manipulators + bool Sync(); + bool Sync(unsigned long Start,unsigned long Stop); + + MMap(FileFd &F,unsigned long Flags); + MMap(unsigned long Flags); + virtual ~MMap(); +}; + +class DynamicMMap : public MMap +{ + public: + + // This is the allocation pool structure + struct Pool + { + unsigned long ItemSize; + unsigned long Start; + unsigned long Count; + }; + + protected: + + FileFd *Fd; + unsigned long WorkSpace; + Pool *Pools; + unsigned int PoolCount; + + public: + + // Allocation + unsigned long RawAllocate(unsigned long Size,unsigned long Aln = 0); + unsigned long Allocate(unsigned long ItemSize); + unsigned long WriteString(const char *String,unsigned long Len = (unsigned long)-1); + inline unsigned long WriteString(string S) {return WriteString(S.begin(),S.size());}; + void UsePools(Pool &P,unsigned int Count) {Pools = &P; PoolCount = Count;}; + + DynamicMMap(FileFd &F,unsigned long Flags,unsigned long WorkSpace = 2*1024*1024); + DynamicMMap(unsigned long Flags,unsigned long WorkSpace = 2*1024*1024); + virtual ~DynamicMMap(); +}; + +#endif diff --git a/apt/apt-pkg/contrib/progress.cc b/apt/apt-pkg/contrib/progress.cc new file mode 100644 index 0000000..97b3a71 --- /dev/null +++ b/apt/apt-pkg/contrib/progress.cc @@ -0,0 +1,200 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: progress.cc,v 1.3 2001/11/13 17:32:08 kojima Exp $ +/* ###################################################################### + + OpProgress - Operation Progress + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/progress.h" +#endif +#include +#include +#include +#include + /*}}}*/ +#include + +// OpProgress::OpProgress - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +OpProgress::OpProgress() : Current(0), Total(0), Size(0), SubTotal(1), + LastPercent(0), Percent(0) +{ + memset(&LastTime,0,sizeof(LastTime)); +} + /*}}}*/ +// OpProgress::Progress - Sub progress with no state change /*{{{*/ +// --------------------------------------------------------------------- +/* Current is the Base Overall progress in units of Total. Cur is the sub + progress in units of SubTotal. Size is a scaling factor that says what + percent of Total SubTotal is. */ +void OpProgress::Progress(unsigned long Cur) +{ + Percent = (Current + Cur/((float)SubTotal)*Size)*100.0/Total; + Update(); +} + /*}}}*/ +// OpProgress::OverallProgress - Set the overall progress /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void OpProgress::OverallProgress(unsigned long Current, unsigned long Total, + unsigned long Size,string Op) +{ + this->Current = Current; + this->Total = Total; + this->Size = Size; + this->Op = Op; + SubOp = string(); + Percent = Current*100.0/Total; + Update(); +} + /*}}}*/ +// OpProgress::SubProgress - Set the sub progress state /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void OpProgress::SubProgress(unsigned long SubTotal,string Op) +{ + this->SubTotal = SubTotal; + SubOp = Op; + Percent = Current*100.0/Total; + Update(); +} + /*}}}*/ +// OpProgress::SubProgress - Set the sub progress state /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void OpProgress::SubProgress(unsigned long SubTotal) +{ + this->SubTotal = SubTotal; + Percent = Current*100.0/Total; + Update(); +} + /*}}}*/ +// OpProgress::CheckChange - See if the display should be updated /*{{{*/ +// --------------------------------------------------------------------- +/* Progress calls are made so frequently that if every one resulted in + an update the display would be swamped and the system much slower. + This provides an upper bound on the update rate. */ +bool OpProgress::CheckChange(float Interval) +{ + // New major progress indication + if (Op != LastOp) + { + MajorChange = true; + LastOp = Op; + return true; + } + MajorChange = false; + + if (SubOp != LastSubOp) + { + LastSubOp = SubOp; + return true; + } + + if ((int)LastPercent == (int)Percent) + return false; + + // Check time delta + struct timeval Now; + gettimeofday(&Now,0); + double Diff = Now.tv_sec - LastTime.tv_sec + (Now.tv_usec - LastTime.tv_usec)/1000000.0; + if (Diff < Interval) + return false; + LastTime = Now; + LastPercent = Percent; + return true; +} + /*}}}*/ +// OpTextProgress::OpTextProgress - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +OpTextProgress::OpTextProgress(Configuration &Config) : + NoUpdate(false), NoDisplay(false), LastLen(0) +{ + if (Config.FindI("quiet",0) >= 1) + NoUpdate = true; + if (Config.FindI("quiet",0) >= 2) + NoDisplay = true; +}; + /*}}}*/ +// OpTextProgress::Done - Clean up the display /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void OpTextProgress::Done() +{ + if (NoUpdate == false && OldOp.empty() == false) + { + char S[300]; + if (_error->PendingError() == true) + snprintf(S,sizeof(S),"\r%s... %s",OldOp.c_str(),_("Error!")); + else + snprintf(S,sizeof(S),"\r%s... %s",OldOp.c_str(),_("Done")); + Write(S); + cout << endl; + OldOp = string(); + } + + if (NoUpdate == true && NoDisplay == false && OldOp.empty() == false) + { + OldOp = string(); + cout << endl; + } +} + /*}}}*/ +// OpTextProgress::Update - Simple text spinner /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void OpTextProgress::Update() +{ + if (CheckChange(0.1) == false) + return; + + // No percent spinner + if (NoUpdate == true) + { + if (MajorChange == false) + return; + if (NoDisplay == false) + { + if (OldOp.empty() == false) + cout << endl; + OldOp = "a"; + cout << Op << "..." << flush; + } + + return; + } + + // Erase the old text and 'log' the event + char S[300]; + if (MajorChange == true && OldOp.empty() == false) + { + snprintf(S,sizeof(S),"\r%s",OldOp.c_str()); + Write(S); + cout << endl; + } + + // Print the spinner + snprintf(S,sizeof(S),"\r%s... %u%%",Op.c_str(),(unsigned int)Percent); + Write(S); + + OldOp = Op; +} + /*}}}*/ +// OpTextProgress::Write - Write the progress string /*{{{*/ +// --------------------------------------------------------------------- +/* This space fills the end to overwrite the previous text */ +void OpTextProgress::Write(const char *S) +{ + cout << S; + for (unsigned int I = strlen(S); I < LastLen; I++) + cout << ' '; + cout << '\r' << flush; + LastLen = strlen(S); +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/progress.h b/apt/apt-pkg/contrib/progress.h new file mode 100644 index 0000000..c39a146 --- /dev/null +++ b/apt/apt-pkg/contrib/progress.h @@ -0,0 +1,90 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: progress.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + OpProgress - Operation Progress + + This class allows lengthy operations to communicate their progress + to the GUI. The progress model is simple and is not designed to handle + the complex case of the multi-activity aquire class. + + The model is based on the concept of an overall operation consisting + of a series of small sub operations. Each sub operation has it's own + completion status and the overall operation has it's completion status. + The units of the two are not mixed and are completely independent. + + The UI is expected to subclass this to provide the visuals to the user. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_PROGRESS_H +#define PKGLIB_PROGRESS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/progress.h" +#endif + +#include +#include + +class Configuration; +class OpProgress +{ + unsigned long Current; + unsigned long Total; + unsigned long Size; + unsigned long SubTotal; + float LastPercent; + + // Change reduction code + struct timeval LastTime; + string LastOp; + string LastSubOp; + + protected: + + string Op; + string SubOp; + float Percent; + + bool MajorChange; + + bool CheckChange(float Interval = 0.7); + virtual void Update() {}; + + public: + + void Progress(unsigned long Current); + void SubProgress(unsigned long SubTotal); + void SubProgress(unsigned long SubTotal,string Op); + void OverallProgress(unsigned long Current,unsigned long Total, + unsigned long Size,string Op); + virtual void Done() {}; + + OpProgress(); + virtual ~OpProgress() {}; +}; + +class OpTextProgress : public OpProgress +{ + protected: + + string OldOp; + bool NoUpdate; + bool NoDisplay; + unsigned long LastLen; + virtual void Update(); + void Write(const char *S); + + public: + + virtual void Done(); + + OpTextProgress(bool NoUpdate = false) : NoUpdate(NoUpdate), + NoDisplay(false), LastLen(0) {}; + OpTextProgress(Configuration &Config); + virtual ~OpTextProgress() {Done();}; +}; + +#endif diff --git a/apt/apt-pkg/contrib/sptr.h b/apt/apt-pkg/contrib/sptr.h new file mode 100644 index 0000000..3fd05c7 --- /dev/null +++ b/apt/apt-pkg/contrib/sptr.h @@ -0,0 +1,66 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: sptr.h,v 1.1 2001/03/27 21:18:18 kojima Exp $ +/* ###################################################################### + + Trivial non-ref counted 'smart pointer' + + This is really only good to eliminate + { + delete Foo; + return; + } + + Blocks from functions. + + I think G++ has become good enough that doing this won't have much + code size implications. + + ##################################################################### */ + /*}}}*/ +#ifndef SMART_POINTER_H +#define SMART_POINTER_H + +template +class SPtr +{ + public: + T *Ptr; + + inline T *operator ->() {return Ptr;}; + inline T &operator *() {return *Ptr;}; + inline operator T *() {return Ptr;}; + inline operator void *() {return Ptr;}; + inline T *UnGuard() {T *Tmp = Ptr; Ptr = 0; return Tmp;}; + inline void operator =(T *N) {Ptr = N;}; + inline bool operator ==(T *lhs) const {return Ptr == lhs;}; + inline bool operator !=(T *lhs) const {return Ptr != lhs;}; + inline T*Get() {return Ptr;}; + + inline SPtr(T *Ptr) : Ptr(Ptr) {}; + inline SPtr() : Ptr(0) {}; + inline ~SPtr() {delete Ptr;}; +}; + +template +class SPtrArray +{ + public: + T *Ptr; + + //inline T &operator *() {return *Ptr;}; + inline operator T *() {return Ptr;}; + inline operator void *() {return Ptr;}; + inline T *UnGuard() {T *Tmp = Ptr; Ptr = 0; return Tmp;}; + //inline T &operator [](signed long I) {return Ptr[I];}; + inline void operator =(T *N) {Ptr = N;}; + inline bool operator ==(T *lhs) const {return Ptr == lhs;}; + inline bool operator !=(T *lhs) const {return Ptr != lhs;}; + inline T *Get() {return Ptr;}; + + inline SPtrArray(T *Ptr) : Ptr(Ptr) {}; + inline SPtrArray() : Ptr(0) {}; + inline ~SPtrArray() {delete [] Ptr;}; +}; + +#endif diff --git a/apt/apt-pkg/contrib/strutl.cc b/apt/apt-pkg/contrib/strutl.cc new file mode 100644 index 0000000..b26963a --- /dev/null +++ b/apt/apt-pkg/contrib/strutl.cc @@ -0,0 +1,1039 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: strutl.cc,v 1.3 2000/10/30 18:49:49 kojima Exp $ +/* ###################################################################### + + String Util - Some useful string functions. + + These have been collected from here and there to do all sorts of useful + things to strings. They are useful in file parsers, URI handlers and + especially in APT methods. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe + + ##################################################################### */ + /*}}}*/ +// Includes /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/strutl.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + /*}}}*/ + +// strstrip - Remove white space from the front and back of a string /*{{{*/ +// --------------------------------------------------------------------- +/* This is handy to use when parsing a file. It also removes \n's left + over from fgets and company */ +char *_strstrip(char *String) +{ + for (;*String != 0 && (*String == ' ' || *String == '\t'); String++); + + if (*String == 0) + return String; + + char *End = String + strlen(String) - 1; + for (;End != String - 1 && (*End == ' ' || *End == '\t' || *End == '\n' || + *End == '\r'); End--); + End++; + *End = 0; + return String; +}; + /*}}}*/ +// strtabexpand - Converts tabs into 8 spaces /*{{{*/ +// --------------------------------------------------------------------- +/* */ +char *_strtabexpand(char *String,size_t Len) +{ + for (char *I = String; I != I + Len && *I != 0; I++) + { + if (*I != '\t') + continue; + if (I + 8 > String + Len) + { + *I = 0; + return String; + } + + /* Assume the start of the string is 0 and find the next 8 char + division */ + int Len; + if (String == I) + Len = 1; + else + Len = 8 - ((String - I) % 8); + Len -= 2; + if (Len <= 0) + { + *I = ' '; + continue; + } + + memmove(I + Len,I + 1,strlen(I) + 1); + for (char *J = I; J + Len != I; *I = ' ', I++); + } + return String; +} + /*}}}*/ +// ParseQuoteWord - Parse a single word out of a string /*{{{*/ +// --------------------------------------------------------------------- +/* This grabs a single word, converts any % escaped characters to their + proper values and advances the pointer. Double quotes are understood + and striped out as well. This is for URI/URL parsing. It also can + understand [] brackets.*/ +bool ParseQuoteWord(const char *&String,string &Res) +{ + // Skip leading whitespace + const char *C = String; + for (;*C != 0 && *C == ' '; C++); + if (*C == 0) + return false; + + // Jump to the next word + for (;*C != 0 && isspace(*C) == 0; C++) + { + if (*C == '"') + { + for (C++; *C != 0 && *C != '"'; C++); + if (*C == 0) + return false; + } + if (*C == '[') + { + for (C++; *C != 0 && *C != ']'; C++); + if (*C == 0) + return false; + } + } + + // Now de-quote characters + char Buffer[1024]; + char Tmp[3]; + const char *Start = String; + char *I; + for (I = Buffer; I < Buffer + sizeof(Buffer) && Start != C; I++) + { + if (*Start == '%' && Start + 2 < C) + { + Tmp[0] = Start[1]; + Tmp[1] = Start[2]; + Tmp[2] = 0; + *I = (char)strtol(Tmp,0,16); + Start += 3; + continue; + } + if (*Start != '"') + *I = *Start; + else + I--; + Start++; + } + *I = 0; + Res = Buffer; + + // Skip ending white space + for (;*C != 0 && isspace(*C) != 0; C++); + String = C; + return true; +} + /*}}}*/ +// ParseCWord - Parses a string like a C "" expression /*{{{*/ +// --------------------------------------------------------------------- +/* This expects a series of space separated strings enclosed in ""'s. + It concatenates the ""'s into a single string. */ +bool ParseCWord(const char *&String,string &Res) +{ + // Skip leading whitespace + const char *C = String; + for (;*C != 0 && *C == ' '; C++); + if (*C == 0) + return false; + + char Buffer[1024]; + char *Buf = Buffer; + if (strlen(String) >= sizeof(Buffer)) + return false; + + for (; *C != 0; C++) + { + if (*C == '"') + { + for (C++; *C != 0 && *C != '"'; C++) + *Buf++ = *C; + + if (*C == 0) + return false; + + continue; + } + + if (C != String && isspace(*C) != 0 && isspace(C[-1]) != 0) + continue; + if (isspace(*C) == 0) + return false; + *Buf++ = ' '; + } + *Buf = 0; + Res = Buffer; + String = C; + return true; +} + /*}}}*/ +// QuoteString - Convert a string into quoted from /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string QuoteString(string Str,const char *Bad) +{ + string Res; + for (string::iterator I = Str.begin(); I != Str.end(); I++) + { + if (strchr(Bad,*I) != 0 || isprint(*I) == 0 || + *I <= 0x20 || *I >= 0x7F) + { + char Buf[10]; + sprintf(Buf,"%%%02x",(int)*I); + Res += Buf; + } + else + Res += *I; + } + return Res; +} + /*}}}*/ +// DeQuoteString - Convert a string from quoted from /*{{{*/ +// --------------------------------------------------------------------- +/* This undoes QuoteString */ +string DeQuoteString(string Str) +{ + string Res; + for (string::iterator I = Str.begin(); I != Str.end(); I++) + { + if (*I == '%' && I + 2 < Str.end()) + { + char Tmp[3]; + Tmp[0] = I[1]; + Tmp[1] = I[2]; + Tmp[2] = 0; + Res += (char)strtol(Tmp,0,16); + I += 2; + continue; + } + else + Res += *I; + } + return Res; +} + + /*}}}*/ +// SizeToStr - Convert a long into a human readable size /*{{{*/ +// --------------------------------------------------------------------- +/* A max of 4 digits are shown before conversion to the next highest unit. + The max length of the string will be 5 chars unless the size is > 10 + YottaBytes (E24) */ +string SizeToStr(double Size) +{ + char S[300]; + double ASize; + if (Size >= 0) + ASize = Size; + else + ASize = -1*Size; + + /* bytes, KiloBytes, MegaBytes, GigaBytes, TeraBytes, PetaBytes, + ExaBytes, ZettaBytes, YottaBytes */ + char Ext[] = {'\0','k','M','G','T','P','E','Z','Y'}; + int I = 0; + while (I <= 8) + { + if (ASize < 100 && I != 0) + { + sprintf(S,"%.1f%c",ASize,Ext[I]); + break; + } + + if (ASize < 10000) + { + sprintf(S,"%.0f%c",ASize,Ext[I]); + break; + } + ASize /= 1000.0; + I++; + } + + return S; +} + /*}}}*/ +// TimeToStr - Convert the time into a string /*{{{*/ +// --------------------------------------------------------------------- +/* Converts a number of seconds to a hms format */ +string TimeToStr(unsigned long Sec) +{ + char S[300]; + + while (1) + { + if (Sec > 60*60*24) + { + sprintf(S,"%lid %lih%lim%lis",Sec/60/60/24,(Sec/60/60) % 24,(Sec/60) % 60,Sec % 60); + break; + } + + if (Sec > 60*60) + { + sprintf(S,"%lih%lim%lis",Sec/60/60,(Sec/60) % 60,Sec % 60); + break; + } + + if (Sec > 60) + { + sprintf(S,"%lim%lis",Sec/60,Sec % 60); + break; + } + + sprintf(S,"%lis",Sec); + break; + } + + return S; +} + /*}}}*/ +// SubstVar - Substitute a string for another string /*{{{*/ +// --------------------------------------------------------------------- +/* This replaces all occurances of Subst with Contents in Str. */ +string SubstVar(string Str,string Subst,string Contents) +{ + string::size_type Pos = 0; + string::size_type OldPos = 0; + string Temp; + + while (OldPos < Str.length() && + (Pos = Str.find(Subst,OldPos)) != string::npos) + { + Temp += string(Str,OldPos,Pos) + Contents; + OldPos = Pos + Subst.length(); + } + + if (OldPos == 0) + return Str; + + return Temp + string(Str,OldPos); +} + +string SubstVar(string Str,const struct SubstVar *Vars) +{ + for (; Vars->Subst != 0; Vars++) + Str = SubstVar(Str,Vars->Subst,*Vars->Contents); + return Str; +} + /*}}}*/ +// URItoFileName - Convert the uri into a unique file name /*{{{*/ +// --------------------------------------------------------------------- +/* This converts a URI into a safe filename. It quotes all unsafe characters + and converts / to _ and removes the scheme identifier. The resulting + file name should be unique and never occur again for a different file */ +string URItoFileName(string URI) +{ + // Nuke 'sensitive' items + ::URI U(URI); + U.User = string(); + U.Password = string(); + U.Access = ""; + + // "\x00-\x20{}|\\\\^\\[\\]<>\"\x7F-\xFF"; + URI = QuoteString(U,"\\|{}[]<>\"^~_=!@#$%^&*"); + string::iterator J = URI.begin(); + for (; J != URI.end(); J++) + if (*J == '/') + *J = '_'; + return URI; +} + /*}}}*/ +// Base64Encode - Base64 Encoding routine for short strings /*{{{*/ +// --------------------------------------------------------------------- +/* This routine performs a base64 transformation on a string. It was ripped + from wget and then patched and bug fixed. + + This spec can be found in rfc2045 */ +string Base64Encode(string S) +{ + // Conversion table. + static char tbl[64] = {'A','B','C','D','E','F','G','H', + 'I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X', + 'Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3', + '4','5','6','7','8','9','+','/'}; + + // Pre-allocate some space + string Final; + Final.reserve((4*S.length() + 2)/3 + 2); + + /* Transform the 3x8 bits to 4x6 bits, as required by + base64. */ + for (string::const_iterator I = S.begin(); I < S.end(); I += 3) + { + char Bits[3] = {0,0,0}; + Bits[0] = I[0]; + if (I + 1 < S.end()) + Bits[1] = I[1]; + if (I + 2 < S.end()) + Bits[2] = I[2]; + + Final += tbl[Bits[0] >> 2]; + Final += tbl[((Bits[0] & 3) << 4) + (Bits[1] >> 4)]; + + if (I + 1 >= S.end()) + break; + + Final += tbl[((Bits[1] & 0xf) << 2) + (Bits[2] >> 6)]; + + if (I + 2 >= S.end()) + break; + + Final += tbl[Bits[2] & 0x3f]; + } + + /* Apply the padding elements, this tells how many bytes the remote + end should discard */ + if (S.length() % 3 == 2) + Final += '='; + if (S.length() % 3 == 1) + Final += "=="; + + return Final; +} + /*}}}*/ +// stringcmp - Arbitary string compare /*{{{*/ +// --------------------------------------------------------------------- +/* This safely compares two non-null terminated strings of arbitary + length */ +int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd) +{ + for (; A != AEnd && B != BEnd; A++, B++) + if (*A != *B) + break; + + if (A == AEnd && B == BEnd) + return 0; + if (A == AEnd) + return 1; + if (B == BEnd) + return -1; + if (*A < *B) + return -1; + return 1; +} + /*}}}*/ +// stringcasecmp - Arbitary case insensitive string compare /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd) +{ + for (; A != AEnd && B != BEnd; A++, B++) + if (toupper(*A) != toupper(*B)) + break; + + if (A == AEnd && B == BEnd) + return 0; + if (A == AEnd) + return 1; + if (B == BEnd) + return -1; + if (toupper(*A) < toupper(*B)) + return -1; + return 1; +} + /*}}}*/ +// LookupTag - Lookup the value of a tag in a taged string /*{{{*/ +// --------------------------------------------------------------------- +/* The format is like those used in package files and the method + communication system */ +string LookupTag(string Message,const char *Tag,const char *Default) +{ + // Look for a matching tag. + int Length = strlen(Tag); + for (string::iterator I = Message.begin(); I + Length < Message.end(); I++) + { + // Found the tag + if (I[Length] == ':' && stringcasecmp(I,I+Length,Tag) == 0) + { + // Find the end of line and strip the leading/trailing spaces + string::iterator J; + I += Length + 1; + for (; isspace(*I) != 0 && I < Message.end(); I++); + for (J = I; *J != '\n' && J < Message.end(); J++); + for (; J > I && isspace(J[-1]) != 0; J--); + + return string(I,J-I); + } + + for (; *I != '\n' && I < Message.end(); I++); + } + + // Failed to find a match + if (Default == 0) + return string(); + return Default; +} + /*}}}*/ +// StringToBool - Converts a string into a boolean /*{{{*/ +// --------------------------------------------------------------------- +/* This inspects the string to see if it is true or if it is false and + then returns the result. Several varients on true/false are checked. */ +int StringToBool(string Text,int Default = -1) +{ + char *End; + int Res = strtol(Text.c_str(),&End,0); + if (End != Text.c_str() && Res >= 0 && Res <= 1) + return Res; + + // Check for positives + if (strcasecmp(Text.c_str(),"no") == 0 || + strcasecmp(Text.c_str(),"false") == 0 || + strcasecmp(Text.c_str(),"without") == 0 || + strcasecmp(Text.c_str(),"off") == 0 || + strcasecmp(Text.c_str(),"disable") == 0) + return 0; + + // Check for negatives + if (strcasecmp(Text.c_str(),"yes") == 0 || + strcasecmp(Text.c_str(),"true") == 0 || + strcasecmp(Text.c_str(),"with") == 0 || + strcasecmp(Text.c_str(),"on") == 0 || + strcasecmp(Text.c_str(),"enable") == 0) + return 1; + + return Default; +} + /*}}}*/ +// TimeRFC1123 - Convert a time_t into RFC1123 format /*{{{*/ +// --------------------------------------------------------------------- +/* This converts a time_t into a string time representation that is + year 2000 complient and timezone neutral */ +string TimeRFC1123(time_t Date) +{ + struct tm Conv = *gmtime(&Date); + char Buf[300]; + + const char *Day[] = {"Sun","Mon","Tue","Wed","Thu","Fri","Sat"}; + const char *Month[] = {"Jan","Feb","Mar","Apr","May","Jun","Jul", + "Aug","Sep","Oct","Nov","Dec"}; + + sprintf(Buf,"%s, %02i %s %i %02i:%02i:%02i GMT",Day[Conv.tm_wday], + Conv.tm_mday,Month[Conv.tm_mon],Conv.tm_year+1900,Conv.tm_hour, + Conv.tm_min,Conv.tm_sec); + return Buf; +} + /*}}}*/ +// ReadMessages - Read messages from the FD /*{{{*/ +// --------------------------------------------------------------------- +/* This pulls full messages from the input FD into the message buffer. + It assumes that messages will not pause during transit so no + fancy buffering is used. */ +bool ReadMessages(int Fd, vector &List) +{ + char Buffer[4000]; + char *End = Buffer; + + while (1) + { + int Res = read(Fd,End,sizeof(Buffer) - (End-Buffer)); + if (Res < 0 && errno == EINTR) + continue; + + // Process is dead, this is kind of bad.. + if (Res == 0) + return false; + + // No data + if (Res < 0 && errno == EAGAIN) + return true; + if (Res < 0) + return false; + + End += Res; + + // Look for the end of the message + for (char *I = Buffer; I + 1 < End; I++) + { + if (I[0] != '\n' || I[1] != '\n') + continue; + + // Pull the message out + string Message(Buffer,0,I-Buffer); + + // Fix up the buffer + for (; I < End && *I == '\n'; I++); + End -= I-Buffer; + memmove(Buffer,I,End-Buffer); + I = Buffer; + + List.push_back(Message); + } + if (End == Buffer) + return true; + + if (WaitFd(Fd) == false) + return false; + } +} + /*}}}*/ +// MonthConv - Converts a month string into a number /*{{{*/ +// --------------------------------------------------------------------- +/* This was lifted from the boa webserver which lifted it from 'wn-v1.07' + Made it a bit more robust with a few touppers though. */ +static int MonthConv(char *Month) +{ + switch (toupper(*Month)) + { + case 'A': + return toupper(Month[1]) == 'P'?3:7; + case 'D': + return 11; + case 'F': + return 1; + case 'J': + if (toupper(Month[1]) == 'A') + return 0; + return toupper(Month[2]) == 'N'?5:6; + case 'M': + return toupper(Month[2]) == 'R'?2:4; + case 'N': + return 10; + case 'O': + return 9; + case 'S': + return 8; + + // Pretend it is January.. + default: + return 0; + } +} + /*}}}*/ +// timegm - Internal timegm function if gnu is not available /*{{{*/ +// --------------------------------------------------------------------- +/* Ripped this evil little function from wget - I prefer the use of + GNU timegm if possible as this technique will have interesting problems + with leap seconds, timezones and other. + + Converts struct tm to time_t, assuming the data in tm is UTC rather + than local timezone (mktime assumes the latter). + + Contributed by Roger Beeman , with the help of + Mark Baushke and the rest of the Gurus at CISCO. */ +#ifndef __USE_MISC // glib sets this +static time_t timegm(struct tm *t) +{ + time_t tl, tb; + + tl = mktime (t); + if (tl == -1) + return -1; + tb = mktime (gmtime (&tl)); + return (tl <= tb ? (tl + (tl - tb)) : (tl - (tb - tl))); +} +#endif + /*}}}*/ +// StrToTime - Converts a string into a time_t /*{{{*/ +// --------------------------------------------------------------------- +/* This handles all 3 populare time formats including RFC 1123, RFC 1036 + and the C library asctime format. It requires the GNU library function + 'timegm' to convert a struct tm in UTC to a time_t. For some bizzar + reason the C library does not provide any such function :< This also + handles the weird, but unambiguous FTP time format*/ +bool StrToTime(string Val,time_t &Result) +{ + struct tm Tm; + char Month[10]; + const char *I = Val.c_str(); + + // Skip the day of the week + for (;*I != 0 && *I != ' '; I++); + + // Handle RFC 1123 time + Month[0] = 0; + if (sscanf(I," %d %3s %d %d:%d:%d GMT",&Tm.tm_mday,Month,&Tm.tm_year, + &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6) + { + // Handle RFC 1036 time + if (sscanf(I," %d-%3s-%d %d:%d:%d GMT",&Tm.tm_mday,Month, + &Tm.tm_year,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) == 6) + Tm.tm_year += 1900; + else + { + // asctime format + if (sscanf(I," %3s %d %d:%d:%d %d",Month,&Tm.tm_mday, + &Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec,&Tm.tm_year) != 6) + { + // 'ftp' time + if (sscanf(Val.c_str(),"%4d%2d%2d%2d%2d%2d",&Tm.tm_year,&Tm.tm_mon, + &Tm.tm_mday,&Tm.tm_hour,&Tm.tm_min,&Tm.tm_sec) != 6) + return false; + Tm.tm_mon--; + } + } + } + + Tm.tm_isdst = 0; + if (Month[0] != 0) + Tm.tm_mon = MonthConv(Month); + Tm.tm_year -= 1900; + + // Convert to local time and then to GMT + Result = timegm(&Tm); + return true; +} + /*}}}*/ +// StrToNum - Convert a fixed length string to a number /*{{{*/ +// --------------------------------------------------------------------- +/* This is used in decoding the crazy fixed length string headers in + tar and ar files. */ +bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base) +{ + char S[30]; + if (Len >= sizeof(S)) + return false; + memcpy(S,Str,Len); + S[Len] = 0; + + // All spaces is a zero + Res = 0; + unsigned I; + for (I = 0; S[I] == ' '; I++); + if (S[I] == 0) + return true; + + char *End; + Res = strtoul(S,&End,Base); + if (End == S) + return false; + + return true; +} + /*}}}*/ +// HexDigit - Convert a hex character into an integer /*{{{*/ +// --------------------------------------------------------------------- +/* Helper for Hex2Num */ +static int HexDigit(int c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + if (c >= 'a' && c <= 'f') + return c - 'a' + 10; + if (c >= 'A' && c <= 'F') + return c - 'A' + 10; + return 0; +} + /*}}}*/ +// Hex2Num - Convert a long hex number into a buffer /*{{{*/ +// --------------------------------------------------------------------- +/* The length of the buffer must be exactly 1/2 the length of the string. */ +bool Hex2Num(const char *Start,const char *End,unsigned char *Num, + unsigned int Length) +{ + if (End - Start != (signed)(Length*2)) + return false; + + // Convert each digit. We store it in the same order as the string + int J = 0; + for (const char *I = Start; I < End;J++, I += 2) + { + if (isxdigit(*I) == 0 || isxdigit(I[1]) == 0) + return false; + + Num[J] = HexDigit(I[0]) << 4; + Num[J] += HexDigit(I[1]); + } + + return true; +} + /*}}}*/ +// TokSplitString - Split a string up by a given token /*{{{*/ +// --------------------------------------------------------------------- +/* This is intended to be a faster splitter, it does not use dynamic + memories. Input is changed to insert nulls at each token location. */ +bool TokSplitString(char Tok,char *Input,char **List, + unsigned long ListMax) +{ + // Strip any leading spaces + char *Start = Input; + char *Stop = Start + strlen(Start); + for (; *Start != 0 && isspace(*Start) != 0; Start++); + + unsigned long Count = 0; + char *Pos = Start; + while (Pos != Stop) + { + // Skip to the next Token + for (; Pos != Stop && *Pos != Tok; Pos++); + + // Back remove spaces + char *End = Pos; + for (; End > Start && (End[-1] == Tok || isspace(End[-1]) != 0); End--); + *End = 0; + + List[Count++] = Start; + if (Count >= ListMax) + { + List[Count-1] = 0; + return false; + } + + // Advance pos + for (; Pos != Stop && (*Pos == Tok || isspace(*Pos) != 0 || *Pos == 0); Pos++); + Start = Pos; + } + + List[Count] = 0; + return true; +} + /*}}}*/ +// RegexChoice - Simple regex list/list matcher /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin, + const char **ListEnd) +{ + for (RxChoiceList *R = Rxs; R->Str != 0; R++) + R->Hit = false; + + unsigned long Hits = 0; + for (; ListBegin != ListEnd; ListBegin++) + { + // Check if the name is a regex + const char *I; + bool Regex = true; + for (I = *ListBegin; *I != 0; I++) + if (*I == '.' || *I == '?' || *I == '*' || *I == '|') + break; + if (*I == 0) + Regex = false; + + // Compile the regex pattern + regex_t Pattern; + if (Regex == true) + if (regcomp(&Pattern,*ListBegin,REG_EXTENDED | REG_ICASE | + REG_NOSUB) != 0) + Regex = false; + + // Search the list + bool Done = false; + for (RxChoiceList *R = Rxs; R->Str != 0; R++) + { + if (R->Str[0] == 0) + continue; + + if (strcasecmp(R->Str,*ListBegin) != 0) + { + if (Regex == false) + continue; + if (regexec(&Pattern,R->Str,0,0,0) != 0) + continue; + } + Done = true; + + if (R->Hit == false) + Hits++; + + R->Hit = true; + } + + if (Regex == true) + regfree(&Pattern); + + if (Done == false) + _error->Warning("Selection %s not found",*ListBegin); + } + + return Hits; +} + /*}}}*/ + +// URI::CopyFrom - Copy from an object /*{{{*/ +// --------------------------------------------------------------------- +/* This parses the URI into all of its components */ +void URI::CopyFrom(string U) +{ + string::const_iterator I = U.begin(); + + // Locate the first colon, this separates the scheme + for (; I < U.end() && *I != ':' ; I++); + string::const_iterator FirstColon = I; + + /* Determine if this is a host type URI with a leading double // + and then search for the first single / */ + string::const_iterator SingleSlash = I; + if (I + 3 < U.end() && I[1] == '/' && I[2] == '/') + SingleSlash += 3; + + /* Find the / indicating the end of the hostname, ignoring /'s in the + square brackets */ + bool InBracket = false; + for (; SingleSlash < U.end() && (*SingleSlash != '/' || InBracket == true); SingleSlash++) + { + if (*SingleSlash == '[') + InBracket = true; + if (InBracket == true && *SingleSlash == ']') + InBracket = false; + } + + if (SingleSlash > U.end()) + SingleSlash = U.end(); + + // We can now write the access and path specifiers + Access = string(U,0,FirstColon - U.begin()); + if (SingleSlash != U.end()) + Path = string(U,SingleSlash - U.begin()); + if (Path.empty() == true) + Path = "/"; + + // Now we attempt to locate a user:pass@host fragment + if (FirstColon[1] == '/' && FirstColon[2] == '/') + FirstColon += 3; + else + FirstColon += 1; + if (FirstColon >= U.end()) + return; + + if (FirstColon > SingleSlash) + FirstColon = SingleSlash; + + // Find the colon... + I = FirstColon + 1; + if (I > SingleSlash) + I = SingleSlash; + for (; I < SingleSlash && *I != ':'; I++); + string::const_iterator SecondColon = I; + + // Search for the @ after the colon + for (; I < SingleSlash && *I != '@'; I++); + string::const_iterator At = I; + + // Now write the host and user/pass + if (At == SingleSlash) + { + if (FirstColon < SingleSlash) + Host = string(U,FirstColon - U.begin(),SingleSlash - FirstColon); + } + else + { + Host = string(U,At - U.begin() + 1,SingleSlash - At - 1); + User = string(U,FirstColon - U.begin(),SecondColon - FirstColon); + if (SecondColon < At) + Password = string(U,SecondColon - U.begin() + 1,At - SecondColon - 1); + } + + // Now we parse the RFC 2732 [] hostnames. + unsigned long PortEnd = 0; + InBracket = false; + for (unsigned I = 0; I != Host.length();) + { + if (Host[I] == '[') + { + InBracket = true; + Host.erase(I,1); + continue; + } + + if (InBracket == true && Host[I] == ']') + { + InBracket = false; + Host.erase(I,1); + PortEnd = I; + continue; + } + I++; + } + + // Tsk, weird. + if (InBracket == true) + { + Host = string(); + return; + } + + // Now we parse off a port number from the hostname + Port = 0; + string::size_type Pos = Host.rfind(':'); + if (Pos == string::npos || Pos < PortEnd) + return; + + Port = atoi(string(Host,Pos+1).c_str()); + Host = string(Host,0,Pos); +} + /*}}}*/ +// URI::operator string - Convert the URI to a string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +URI::operator string() +{ + string Res; + + if (Access.empty() == false) + Res = Access + ':'; + + if (Host.empty() == false) + { + if (Access.empty() == false) + Res += "//"; + + if (User.empty() == false) + { + Res += User; + if (Password.empty() == false) + Res += ":" + Password; + Res += "@"; + } + + // Add RFC 2732 escaping characters + if (Access.empty() == false && + (Host.find('/') != string::npos || Host.find(':') != string::npos)) + Res += '[' + Host + ']'; + else + Res += Host; + + if (Port != 0) + { + char S[30]; + sprintf(S,":%u",Port); + Res += S; + } + } + + if (Path.empty() == false) + { + if (Path[0] != '/') + Res += "/" + Path; + else + Res += Path; + } + + return Res; +} + /*}}}*/ +// URI::SiteOnly - Return the schema and site for the URI /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string URI::SiteOnly(string URI) +{ + ::URI U(URI); + U.User = string(); + U.Password = string(); + U.Path = string(); + U.Port = 0; + return U; +} + /*}}}*/ diff --git a/apt/apt-pkg/contrib/strutl.h b/apt/apt-pkg/contrib/strutl.h new file mode 100644 index 0000000..f86be18 --- /dev/null +++ b/apt/apt-pkg/contrib/strutl.h @@ -0,0 +1,96 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: strutl.h,v 1.3 2000/10/30 18:49:49 kojima Exp $ +/* ###################################################################### + + String Util - These are some useful string functions + + _strstrip is a function to remove whitespace from the front and end + of a string. + + This source is placed in the Public Domain, do with it what you will + It was originally written by Jason Gunthorpe + + ##################################################################### */ + /*}}}*/ +#ifndef STRUTL_H +#define STRUTL_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/strutl.h" +#endif + +#include +#include +#include +#include + +char *_strstrip(char *String); +char *_strtabexpand(char *String,size_t Len); +bool ParseQuoteWord(const char *&String,string &Res); +bool ParseCWord(const char *&String,string &Res); +string QuoteString(string Str,const char *Bad); +string DeQuoteString(string Str); +string SizeToStr(double Bytes); +string TimeToStr(unsigned long Sec); +string Base64Encode(string Str); +string URItoFileName(string URI); +string TimeRFC1123(time_t Date); +bool StrToTime(string Val,time_t &Result); +string LookupTag(string Message,const char *Tag,const char *Default = 0); +int StringToBool(string Text,int Default = -1); +bool ReadMessages(int Fd, vector &List); +bool StrToNum(const char *Str,unsigned long &Res,unsigned Len,unsigned Base = 0); +bool Hex2Num(const char *Start,const char *End,unsigned char *Num, + unsigned int Length); +bool TokSplitString(char Tok,char *Input,char **List, + unsigned long ListMax); + +int stringcmp(const char *A,const char *AEnd,const char *B,const char *BEnd); +inline int stringcmp(const char *A,const char *AEnd,const char *B) {return stringcmp(A,AEnd,B,B+strlen(B));}; +inline int stringcmp(string A,const char *B) {return stringcmp(A.begin(),A.end(),B,B+strlen(B));}; +int stringcasecmp(const char *A,const char *AEnd,const char *B,const char *BEnd); +inline int stringcasecmp(const char *A,const char *AEnd,const char *B) {return stringcasecmp(A,AEnd,B,B+strlen(B));}; +inline int stringcasecmp(string A,const char *B) {return stringcasecmp(A.begin(),A.end(),B,B+strlen(B));}; +inline int stringcasecmp(string A,string B) {return stringcasecmp(A.begin(),A.end(),B.begin(),B.end());}; + +class URI +{ + void CopyFrom(string From); + + public: + + string Access; + string User; + string Password; + string Host; + string Path; + unsigned int Port; + + operator string(); + inline void operator =(string From) {CopyFrom(From);}; + inline bool empty() {return Access.empty();}; + static string SiteOnly(string URI); + + URI(string Path) {CopyFrom(Path);}; + URI() : Port(0) {}; +}; + +struct SubstVar +{ + const char *Subst; + const string *Contents; +}; +string SubstVar(string Str,const struct SubstVar *Vars); +string SubstVar(string Str,string Subst,string Contents); + +struct RxChoiceList +{ + void *UserData; + const char *Str; + bool Hit; +}; +unsigned long RegexChoice(RxChoiceList *Rxs,const char **ListBegin, + const char **ListEnd); + +#endif diff --git a/apt/apt-pkg/contrib/system.h b/apt/apt-pkg/contrib/system.h new file mode 100644 index 0000000..8e31828 --- /dev/null +++ b/apt/apt-pkg/contrib/system.h @@ -0,0 +1,58 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: system.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + System Header - Usefull private definitions + + This source is placed in the Public Domain, do with it what you will + It was originally written by Brian C. White. + + ##################################################################### */ + /*}}}*/ +// Private header +#ifndef SYSTEM_H +#define SYSTEM_H + +// MIN_VAL(SINT16) will return -0x8000 and MAX_VAL(SINT16) = 0x7FFF +#define MIN_VAL(t) (((t)(-1) > 0) ? (t)( 0) : (t)(((1L<<(sizeof(t)*8-1)) ))) +#define MAX_VAL(t) (((t)(-1) > 0) ? (t)(-1) : (t)(((1L<<(sizeof(t)*8-1))-1))) + +// Min/Max functions +#if !defined(MIN) +#if defined(__HIGHC__) +#define MIN(x,y) _min(x,y) +#define MAX(x,y) _max(x,y) +#endif + +// GNU C++ has a min/max operator +#if defined(__GNUG__) +#define MIN(A,B) ((A) ? (B)) +#endif + +/* Templates tend to mess up existing code that uses min/max because of the + strict matching requirements */ +#if !defined(MIN) +#define MIN(A,B) ((A) < (B)?(A):(B)) +#define MAX(A,B) ((A) > (B)?(A):(B)) +#endif +#endif + +/* Bound functions, bound will return the value b within the limits a-c + bounv will change b so that it is within the limits of a-c. */ +#define _bound(a,b,c) MIN(c,MAX(b,a)) +#define _boundv(a,b,c) b = _bound(a,b,c) +#define ABS(a) (((a) < (0)) ?-(a) : (a)) + +/* Usefull count macro, use on an array of things and it will return the + number of items in the array */ +#define _count(a) (sizeof(a)/sizeof(a[0])) + +// Flag Macros +#define FLAG(f) (1L << (f)) +#define SETFLAG(v,f) ((v) |= FLAG(f)) +#define CLRFLAG(v,f) ((v) &=~FLAG(f)) +#define CHKFLAG(v,f) ((v) & FLAG(f) ? true : false) + +#endif diff --git a/apt/apt-pkg/deb/CVS/Entries b/apt/apt-pkg/deb/CVS/Entries new file mode 100644 index 0000000..4a3a09e --- /dev/null +++ b/apt/apt-pkg/deb/CVS/Entries @@ -0,0 +1,13 @@ +/debfactory.cc/1.6/Fri Aug 10 14:00:34 2001// +/debfactory.h/1.6/Fri Aug 10 14:00:34 2001// +/deblistparser.cc/1.1.1.1/Fri Aug 10 14:00:36 2001// +/deblistparser.h/1.1.1.1/Fri Aug 10 14:00:36 2001// +/debrecords.cc/1.1.1.1/Fri Aug 10 14:00:36 2001// +/debrecords.h/1.1.1.1/Fri Aug 10 14:00:37 2001// +/debsrcrecords.cc/1.2/Fri Aug 10 14:00:37 2001// +/debsrcrecords.h/1.1.1.1/Fri Aug 10 14:00:37 2001// +/dpkginit.cc/1.1.1.1/Fri Aug 10 14:00:37 2001// +/dpkginit.h/1.1.1.1/Fri Aug 10 14:00:37 2001// +/dpkgpm.cc/1.1.1.1/Fri Aug 10 14:00:37 2001// +/dpkgpm.h/1.1.1.1/Fri Aug 10 14:00:37 2001// +D diff --git a/apt/apt-pkg/deb/CVS/Repository b/apt/apt-pkg/deb/CVS/Repository new file mode 100644 index 0000000..b73f528 --- /dev/null +++ b/apt/apt-pkg/deb/CVS/Repository @@ -0,0 +1 @@ +rapt/apt-pkg/deb diff --git a/apt/apt-pkg/deb/CVS/Root b/apt/apt-pkg/deb/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/apt-pkg/deb/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/apt-pkg/deb/debfactory.cc b/apt/apt-pkg/deb/debfactory.cc new file mode 100644 index 0000000..e5e2fa6 --- /dev/null +++ b/apt/apt-pkg/deb/debfactory.cc @@ -0,0 +1,197 @@ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + + + +pkgPackageManager *DebianFactory::CreatePackageManager(pkgDepCache &Cache) +{ + return new pkgDPkgPM(Cache); +} + + +pkgRecords::Parser *DebianFactory::CreateRecordParser(string File, pkgCache &Cache) +{ + FileFd f; + + f = FileFd(File, FileFd::ReadOnly); + if (_error->PendingError()) + return NULL; + + return new debRecordParser(f, Cache); +} + + +pkgSrcRecords::Parser *DebianFactory::CreateSrcRecordParser(string File, + pkgSourceList::const_iterator SrcItem) +{ + FileFd *f; + + f = new FileFd(File, FileFd::ReadOnly); + if (_error->PendingError()) { + delete f; + return NULL; + } + + return new debSrcRecordParser(f, SrcItem); +} + + +bool DebianFactory::checkSourceType(int type, bool binary) +{ + if (binary) + return (type == pkgSourceList::Deb); + else + return (type == pkgSourceList::DebSrc); +} + + +pkgCacheGenerator::ListParser *DebianFactory::CreateListParser(FileFd &File) +{ + return new debListParser(File); +} + + + /*}}}*/ +// PkgCacheCheck - Check if the package cache is uptodate /*{{{*/ +// --------------------------------------------------------------------- +/* This does a simple check of all files used to compose the cache */ +bool DebianFactory::packageCacheCheck(string CacheFile) +{ + if (_error->PendingError() == true) + return false; + + // Open the source package cache + if (FileExists(CacheFile) == false) + return false; + + FileFd CacheF(CacheFile,FileFd::ReadOnly); + if (_error->PendingError() == true) + { + _error->Discard(); + return false; + } + + MMap Map(CacheF,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true || Map.Size() == 0) + { + _error->Discard(); + return false; + } + + pkgCache Cache(Map); + if (_error->PendingError() == true) + { + _error->Discard(); + return false; + } + + // Status files that must be in the cache + string Status[3]; + Status[0] = _config->FindFile("Dir::State::xstatus"); + Status[1]= _config->FindFile("Dir::State::userstatus"); + Status[2] = _config->FindFile("Dir::State::status"); + + // Cheack each file + for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++) + { + if (F.IsOk() == false) + return false; + + // See if this is one of the status files + for (int I = 0; I != 3; I++) + if (F.FileName() == Status[I]) + Status[I] = string(); + } + + // Make sure all the status files are loaded. + for (int I = 0; I != 3; I++) + { + if (Status[I].empty() == false && FileExists(Status[I]) == true) + return false; + } + + return true; +} + /*}}}*/ +// AddStatusSize - Add the size of the status files /*{{{*/ +// --------------------------------------------------------------------- +/* This adds the size of all the status files to the size counter */ +bool DebianFactory::addStatusSize(unsigned long &TotalSize) +{ + // Grab the file names + string xstatus = _config->FindFile("Dir::State::xstatus"); + string userstatus = _config->FindFile("Dir::State::userstatus"); + string status = _config->FindFile("Dir::State::status"); + + // Grab the sizes + struct stat Buf; + if (stat(xstatus.c_str(),&Buf) == 0) + TotalSize += Buf.st_size; + if (stat(userstatus.c_str(),&Buf) == 0) + TotalSize += Buf.st_size; + if (stat(status.c_str(),&Buf) != 0) + return _error->Errno("stat","Couldn't stat the status file %s",status.c_str()); + TotalSize += Buf.st_size; + + return true; +} + /*}}}*/ +// MergeInstalledPackages (was MergeStatus) - Add the status files to the cache /*{{{*/ +// --------------------------------------------------------------------- +/* This adds the status files to the map */ +bool DebianFactory::mergeInstalledPackages(OpProgress &Progress, + pkgCacheGenerator &Gen, + unsigned long &CurrentSize, + unsigned long TotalSize) +{ + // Grab the file names + string Status[3]; + Status[0] = _config->FindFile("Dir::State::xstatus"); + Status[1]= _config->FindFile("Dir::State::userstatus"); + Status[2] = _config->FindFile("Dir::State::status"); + + for (int I = 0; I != 3; I++) + { + pkgCacheGenerator::ListParser *Parser; + + // Check if the file exists and it is not the primary status file. + string File = Status[I]; + if (I != 2 && FileExists(File) == false) + continue; + + FileFd Pkg(File,FileFd::ReadOnly); + Parser = new debListParser(Pkg); + + Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists"); + if (_error->PendingError() == true) + return _error->Error("Problem opening %s",File.c_str()); + CurrentSize += Pkg.Size(); + + Progress.SubProgress(0,"Local Package State - " + flNotDir(File)); + if (Gen.SelectFile(File,pkgCache::Flag::NotSource) == false) + return _error->Error("Problem with SelectFile %s",File.c_str()); + + if (Gen.MergeList(*Parser) == false) + return _error->Error("Problem with MergeList %s",File.c_str()); + Progress.Progress(Pkg.Size()); + + delete Parser; + } + + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/deb/debfactory.h b/apt/apt-pkg/deb/debfactory.h new file mode 100644 index 0000000..f25f965 --- /dev/null +++ b/apt/apt-pkg/deb/debfactory.h @@ -0,0 +1,31 @@ + +#ifndef _DEBIANFACTORY_H_ +#define _DEBIANFACTORY_H_ + +#include + + +class DebianFactory : public SystemFactory +{ +// for cache generation + protected: + bool addStatusSize(unsigned long &TotalSize); + + bool mergeInstalledPackages(OpProgress &Progress,pkgCacheGenerator &Gen, + unsigned long &CurrentSize, + unsigned long TotalSize); + + protected: + bool packageCacheCheck(string CacheFile); + + bool checkSourceType(int type, bool binary=true); + + public: +// other stuffs + pkgCacheGenerator::ListParser *CreateListParser(FileFd &File); + pkgRecords::Parser *CreateRecordParser(string File, pkgCache &Cache); + pkgSrcRecords::Parser *CreateSrcRecordParser(string File, pkgSourceList::const_iterator SrcItem); + pkgPackageManager *CreatePackageManager(pkgDepCache &Cache); +}; + +#endif diff --git a/apt/apt-pkg/deb/deblistparser.cc b/apt/apt-pkg/deb/deblistparser.cc new file mode 100644 index 0000000..710ff70 --- /dev/null +++ b/apt/apt-pkg/deb/deblistparser.cc @@ -0,0 +1,529 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: deblistparser.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Package Cache Generator - Generator for the cache structure. + + This builds the cache structure from the abstract package list parser. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include + +#include + /*}}}*/ + +// ListParser::debListParser - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +debListParser::debListParser(FileFd &File) : Tags(File) +{ + Arch = _config->Find("APT::architecture"); +} + /*}}}*/ +// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long debListParser::UniqFindTagWrite(const char *Tag) +{ + const char *Start; + const char *Stop; + if (Section.Find(Tag,Start,Stop) == false) + return 0; + return WriteUniqString(Start,Stop - Start); +} + /*}}}*/ +// ListParser::Package - Return the package name /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the name of the package this section describes */ +string debListParser::Package() +{ + string Result = Section.FindS("Package"); + if (Result.empty() == true) + _error->Error("Encountered a section with no Package: header"); + return Result; +} + /*}}}*/ +// ListParser::Version - Return the version string /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the string describing the version in debian form, + epoch:upstream-release. If this returns the blank string then the + entry is assumed to only describe package properties */ +string debListParser::Version() +{ + return Section.FindS("Version"); +} + /*}}}*/ +// ListParser::NewVersion - Fill in the version structure /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::NewVersion(pkgCache::VerIterator Ver) +{ + // Parse the section + Ver->Section = UniqFindTagWrite("Section"); + Ver->Arch = UniqFindTagWrite("Architecture"); + + // Archive Size + Ver->Size = (unsigned)Section.FindI("Size"); + + // Unpacked Size (in K) + Ver->InstalledSize = (unsigned)Section.FindI("Installed-Size"); + Ver->InstalledSize *= 1024; + + // Priority + const char *Start; + const char *Stop; + if (Section.Find("Priority",Start,Stop) == true) + { + WordList PrioList[] = {{"important",pkgCache::State::Important}, + {"required",pkgCache::State::Required}, + {"standard",pkgCache::State::Standard}, + {"optional",pkgCache::State::Optional}, + {"extra",pkgCache::State::Extra}}; + if (GrabWord(string(Start,Stop-Start),PrioList, + _count(PrioList),Ver->Priority) == false) + Ver->Priority = pkgCache::State::Extra; + } + + if (ParseDepends(Ver,"Depends",pkgCache::Dep::Depends) == false) + return false; + if (ParseDepends(Ver,"Pre-Depends",pkgCache::Dep::PreDepends) == false) + return false; + if (ParseDepends(Ver,"Suggests",pkgCache::Dep::Suggests) == false) + return false; + if (ParseDepends(Ver,"Recommends",pkgCache::Dep::Recommends) == false) + return false; + if (ParseDepends(Ver,"Conflicts",pkgCache::Dep::Conflicts) == false) + return false; + if (ParseDepends(Ver,"Replaces",pkgCache::Dep::Replaces) == false) + return false; + + if (ParseProvides(Ver) == false) + return false; + + return true; +} + /*}}}*/ +// ListParser::UsePackage - Update a package structure /*{{{*/ +// --------------------------------------------------------------------- +/* This is called to update the package with any new information + that might be found in the section */ +bool debListParser::UsePackage(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver) +{ + if (Pkg->Section == 0) + Pkg->Section = UniqFindTagWrite("Section"); + if (Section.FindFlag("Essential",Pkg->Flags,pkgCache::Flag::Essential) == false) + return false; + if (Section.FindFlag("Important",Pkg->Flags,pkgCache::Flag::Important) == false) + return false; + + if (strcmp(Pkg.Name(),"apt") == 0) + Pkg->Flags |= pkgCache::Flag::Important; + + if (ParseStatus(Pkg,Ver) == false) + return false; + return true; +} + /*}}}*/ +// ListParser::VersionHash - Compute a unique hash for this version /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned short debListParser::VersionHash() +{ + const char *Sections[] ={"Installed-Size", + "Depends", + "Pre-Depends", +// "Suggests", +// "Recommends", + "Conflicts", + "Replaces",0}; + unsigned long Result = INIT_FCS; + char S[300]; + for (const char **I = Sections; *I != 0; I++) + { + const char *Start; + const char *End; + if (Section.Find(*I,Start,End) == false || End - Start >= (signed)sizeof(S)) + continue; + + /* Strip out any spaces from the text, this undoes dpkgs reformatting + of certain fields. dpkg also has the rather interesting notion of + reformatting depends operators < -> <= */ + char *I = S; + for (; Start != End; Start++) + { + if (isspace(*Start) == 0) + *I++ = tolower(*Start); + if (*Start == '<' && Start[1] != '<' && Start[1] != '=') + *I++ = '='; + if (*Start == '>' && Start[1] != '>' && Start[1] != '=') + *I++ = '='; + } + + Result = AddCRC16(Result,S,I - S); + } + + return Result; +} + /*}}}*/ +// ListParser::ParseStatus - Parse the status field /*{{{*/ +// --------------------------------------------------------------------- +/* Status lines are of the form, + Status: want flag status + want = unknown, install, hold, deinstall, purge + flag = ok, reinstreq, hold, hold-reinstreq + status = not-installed, unpacked, half-configured, + half-installed, config-files, post-inst-failed, + removal-failed, installed + + Some of the above are obsolete (I think?) flag = hold-* and + status = post-inst-failed, removal-failed at least. + */ +bool debListParser::ParseStatus(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver) +{ + const char *Start; + const char *Stop; + if (Section.Find("Status",Start,Stop) == false) + return true; + + // Isolate the first word + const char *I = Start; + for(; I < Stop && *I != ' '; I++); + if (I >= Stop || *I != ' ') + return _error->Error("Malformed Status line"); + + // Process the want field + WordList WantList[] = {{"unknown",pkgCache::State::Unknown}, + {"install",pkgCache::State::Install}, + {"hold",pkgCache::State::Hold}, + {"deinstall",pkgCache::State::DeInstall}, + {"purge",pkgCache::State::Purge}}; + if (GrabWord(string(Start,I-Start),WantList, + _count(WantList),Pkg->SelectedState) == false) + return _error->Error("Malformed 1st word in the Status line"); + + // Isloate the next word + I++; + Start = I; + for(; I < Stop && *I != ' '; I++); + if (I >= Stop || *I != ' ') + return _error->Error("Malformed status line, no 2nd word"); + + // Process the flag field + WordList FlagList[] = {{"ok",pkgCache::State::Ok}, + {"reinstreq",pkgCache::State::ReInstReq}, + {"hold",pkgCache::State::HoldInst}, + {"hold-reinstreq",pkgCache::State::HoldReInstReq}}; + if (GrabWord(string(Start,I-Start),FlagList, + _count(FlagList),Pkg->InstState) == false) + return _error->Error("Malformed 2nd word in the Status line"); + + // Isloate the last word + I++; + Start = I; + for(; I < Stop && *I != ' '; I++); + if (I != Stop) + return _error->Error("Malformed Status line, no 3rd word"); + + // Process the flag field + WordList StatusList[] = {{"not-installed",pkgCache::State::NotInstalled}, + {"unpacked",pkgCache::State::UnPacked}, + {"half-configured",pkgCache::State::HalfConfigured}, + {"installed",pkgCache::State::Installed}, + {"half-installed",pkgCache::State::HalfInstalled}, + {"config-files",pkgCache::State::ConfigFiles}, + {"post-inst-failed",pkgCache::State::HalfConfigured}, + {"removal-failed",pkgCache::State::HalfInstalled}}; + if (GrabWord(string(Start,I-Start),StatusList, + _count(StatusList),Pkg->CurrentState) == false) + return _error->Error("Malformed 3rd word in the Status line"); + + /* A Status line marks the package as indicating the current + version as well. Only if it is actually installed.. Otherwise + the interesting dpkg handling of the status file creates bogus + entries. */ + if (!(Pkg->CurrentState == pkgCache::State::NotInstalled || + Pkg->CurrentState == pkgCache::State::ConfigFiles)) + { + if (Ver.end() == true) + _error->Warning("Encountered status field in a non-version description"); + else + Pkg->CurrentVer = Ver.Index(); + } + + return true; +} + /*}}}*/ +// ListParser::ParseDepends - Parse a dependency element /*{{{*/ +// --------------------------------------------------------------------- +/* This parses the dependency elements out of a standard string in place, + bit by bit. */ +const char *debListParser::ParseDepends(const char *Start,const char *Stop, + string &Package,string &Ver, + unsigned int &Op) +{ + // Strip off leading space + for (;Start != Stop && isspace(*Start) != 0; Start++); + + // Parse off the package name + const char *I = Start; + for (;I != Stop && isspace(*I) == 0 && *I != '(' && *I != ')' && + *I != ',' && *I != '|'; I++); + + // Malformed, no '(' + if (I != Stop && *I == ')') + return 0; + + if (I == Start) + return 0; + + // Stash the package name + Package.assign(Start,I - Start); + + // Skip white space to the '(' + for (;I != Stop && isspace(*I) != 0 ; I++); + + // Parse a version + if (I != Stop && *I == '(') + { + // Skip the '(' + for (I++; I != Stop && isspace(*I) != 0 ; I++); + if (I + 3 >= Stop) + return 0; + + // Determine the operator + switch (*I) + { + case '<': + I++; + if (*I == '=') + { + I++; + Op = pkgCache::Dep::LessEq; + break; + } + + if (*I == '<') + { + I++; + Op = pkgCache::Dep::Less; + break; + } + + // < is the same as <= and << is really Cs < for some reason + Op = pkgCache::Dep::LessEq; + break; + + case '>': + I++; + if (*I == '=') + { + I++; + Op = pkgCache::Dep::GreaterEq; + break; + } + + if (*I == '>') + { + I++; + Op = pkgCache::Dep::Greater; + break; + } + + // > is the same as >= and >> is really Cs > for some reason + Op = pkgCache::Dep::GreaterEq; + break; + + case '=': + Op = pkgCache::Dep::Equals; + I++; + break; + + // HACK around bad package definitions + default: + Op = pkgCache::Dep::Equals; + break; + } + + // Skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + Start = I; + for (;I != Stop && *I != ')'; I++); + if (I == Stop || Start == I) + return 0; + + // Skip trailing whitespace + const char *End = I; + for (; End > Start && isspace(End[-1]); End--); + + Ver = string(Start,End-Start); + I++; + } + else + { + Ver = string(); + Op = pkgCache::Dep::NoOp; + } + + // Skip whitespace + for (;I != Stop && isspace(*I) != 0; I++); + if (I != Stop && *I == '|') + Op |= pkgCache::Dep::Or; + + if (I == Stop || *I == ',' || *I == '|') + { + if (I != Stop) + for (I++; I != Stop && isspace(*I) != 0; I++); + return I; + } + + return 0; +} + /*}}}*/ +// ListParser::ParseDepends - Parse a dependency list /*{{{*/ +// --------------------------------------------------------------------- +/* This is the higher level depends parser. It takes a tag and generates + a complete depends tree for the given version. */ +bool debListParser::ParseDepends(pkgCache::VerIterator Ver, + const char *Tag,unsigned int Type) +{ + const char *Start; + const char *Stop; + if (Section.Find(Tag,Start,Stop) == false) + return true; + + string Package; + string Version; + unsigned int Op; + + while (1) + { + Start = ParseDepends(Start,Stop,Package,Version,Op); + if (Start == 0) + return _error->Error("Problem parsing dependency %s",Tag); + + if (NewDepends(Ver,Package,Version,Op,Type) == false) + return false; + if (Start == Stop) + break; + } + return true; +} + /*}}}*/ +// ListParser::ParseProvides - Parse the provides list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::ParseProvides(pkgCache::VerIterator Ver) +{ + const char *Start; + const char *Stop; + if (Section.Find("Provides",Start,Stop) == false) + return true; + + string Package; + string Version; + unsigned int Op; + + while (1) + { + Start = ParseDepends(Start,Stop,Package,Version,Op); + if (Start == 0) + return _error->Error("Problem parsing Provides line"); + if (Op != pkgCache::Dep::NoOp) + return _error->Error("Malformed provides line"); + + if (NewProvides(Ver,Package,Version) == false) + return false; + + if (Start == Stop) + break; + } + + return true; +} + /*}}}*/ +// ListParser::GrabWord - Matches a word and returns /*{{{*/ +// --------------------------------------------------------------------- +/* Looks for a word in a list of words - for ParseStatus */ +bool debListParser::GrabWord(string Word,WordList *List,int Count, + unsigned char &Out) +{ + for (int C = 0; C != Count; C++) + { + if (strcasecmp(Word.c_str(),List[C].Str) == 0) + { + Out = List[C].Val; + return true; + } + } + return false; +} + /*}}}*/ +// ListParser::Step - Move to the next section in the file /*{{{*/ +// --------------------------------------------------------------------- +/* This has to be carefull to only process the correct architecture */ +bool debListParser::Step() +{ + iOffset = Tags.Offset(); + while (Tags.Step(Section) == true) + { + /* See if this is the correct Architecture, if it isn't then we + drop the whole section. A missing arch tag only happens (in theory) + inside the Status file, so that is a positive return */ + const char *Start; + const char *Stop; + if (Section.Find("Architecture",Start,Stop) == false) + return true; + + if (stringcmp(Start,Stop,Arch.begin(),Arch.end()) == 0) + return true; + + if (stringcmp(Start,Stop,"all") == 0) + return true; + + iOffset = Tags.Offset(); + } + return false; +} + /*}}}*/ +// ListParser::LoadReleaseInfo - Load the release information /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, + FileFd &File) +{ + pkgTagFile Tags(File); + pkgTagSection Section; + if (Tags.Step(Section) == false) + return false; + + const char *Start; + const char *Stop; + if (Section.Find("Archive",Start,Stop) == true) + FileI->Archive = WriteUniqString(Start,Stop - Start); + if (Section.Find("Component",Start,Stop) == true) + FileI->Component = WriteUniqString(Start,Stop - Start); + if (Section.Find("Version",Start,Stop) == true) + FileI->Version = WriteUniqString(Start,Stop - Start); + if (Section.Find("Origin",Start,Stop) == true) + FileI->Origin = WriteUniqString(Start,Stop - Start); + if (Section.Find("Label",Start,Stop) == true) + FileI->Label = WriteUniqString(Start,Stop - Start); + if (Section.Find("Architecture",Start,Stop) == true) + FileI->Architecture = WriteUniqString(Start,Stop - Start); + + if (Section.FindFlag("NotAutomatic",FileI->Flags, + pkgCache::Flag::NotAutomatic) == false) + _error->Warning("Bad NotAutomatic flag"); + + return !_error->PendingError(); +} + /*}}}*/ diff --git a/apt/apt-pkg/deb/deblistparser.h b/apt/apt-pkg/deb/deblistparser.h new file mode 100644 index 0000000..9807458 --- /dev/null +++ b/apt/apt-pkg/deb/deblistparser.h @@ -0,0 +1,60 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: deblistparser.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Debian Package List Parser - This implements the abstract parser + interface for Debian package files + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_DEBLISTPARSER_H +#define PKGLIB_DEBLISTPARSER_H + +#include +#include + +class debListParser : public pkgCacheGenerator::ListParser +{ + pkgTagFile Tags; + pkgTagSection Section; + unsigned long iOffset; + string Arch; + + // Parser Helper + struct WordList + { + char *Str; + unsigned char Val; + }; + + unsigned long UniqFindTagWrite(const char *Tag); + bool ParseStatus(pkgCache::PkgIterator Pkg,pkgCache::VerIterator Ver); + const char *ParseDepends(const char *Start,const char *Stop, + string &Package,string &Ver,unsigned int &Op); + bool ParseDepends(pkgCache::VerIterator Ver,const char *Tag, + unsigned int Type); + bool ParseProvides(pkgCache::VerIterator Ver); + bool GrabWord(string Word,WordList *List,int Count,unsigned char &Out); + + public: + + // These all operate against the current section + virtual string Package(); + virtual string Version(); + virtual bool NewVersion(pkgCache::VerIterator Ver); + virtual unsigned short VersionHash(); + virtual bool UsePackage(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver); + virtual unsigned long Offset() {return iOffset;}; + virtual unsigned long Size() {return Section.size();}; + + virtual bool Step(); + + bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File); + + debListParser(FileFd &File); +}; + +#endif diff --git a/apt/apt-pkg/deb/debrecords.cc b/apt/apt-pkg/deb/debrecords.cc new file mode 100644 index 0000000..d818444 --- /dev/null +++ b/apt/apt-pkg/deb/debrecords.cc @@ -0,0 +1,89 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: debrecords.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Debian Package Records - Parser for debian package records + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/debrecords.h" +#endif +#include +#include + /*}}}*/ + +// RecordParser::debRecordParser - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +debRecordParser::debRecordParser(FileFd &File,pkgCache &Cache) : + Tags(File,Cache.Head().MaxVerFileSize + 20) +{ +} + /*}}}*/ +// RecordParser::Jump - Jump to a specific record /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool debRecordParser::Jump(pkgCache::VerFileIterator const &Ver) +{ + return Tags.Jump(Section,Ver->Offset); +} + /*}}}*/ +// RecordParser::FileName - Return the archive filename on the site /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::FileName() +{ + return Section.FindS("Filename"); +} + /*}}}*/ +// RecordParser::MD5Hash - Return the archive hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::MD5Hash() +{ + return Section.FindS("MD5sum"); +} + /*}}}*/ +// RecordParser::Maintainer - Return the maintainer email /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::Maintainer() +{ + return Section.FindS("Maintainer"); +} + /*}}}*/ +// RecordParser::ShortDesc - Return a 1 line description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::ShortDesc() +{ + string Res = Section.FindS("Description"); + string::size_type Pos = Res.find('\n'); + if (Pos == string::npos) + return Res; + return string(Res,0,Pos); +} + /*}}}*/ +// RecordParser::LongDesc - Return a longer description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::LongDesc() +{ + return Section.FindS("Description"); +} + /*}}}*/ +// RecordParser::SourcePkg - Return the source package name if any /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string debRecordParser::SourcePkg() +{ + string Res = Section.FindS("Source"); + string::size_type Pos = Res.find(' '); + if (Pos == string::npos) + return Res; + return string(Res,0,Pos); +} + /*}}}*/ diff --git a/apt/apt-pkg/deb/debrecords.h b/apt/apt-pkg/deb/debrecords.h new file mode 100644 index 0000000..914702e --- /dev/null +++ b/apt/apt-pkg/deb/debrecords.h @@ -0,0 +1,50 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: debrecords.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Debian Package Records - Parser for debian package records + + This provides display-type parsing for the Packages file. This is + different than the the list parser which provides cache generation + services. There should be no overlap between these two. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_DEBRECORDS_H +#define PKGLIB_DEBRECORDS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/debrecords.h" +#endif + +#include +#include + +class debRecordParser : public pkgRecords::Parser +{ + pkgTagFile Tags; + pkgTagSection Section; + + protected: + + virtual bool Jump(pkgCache::VerFileIterator const &Ver); + + public: + + // These refer to the archive file for the Version + virtual string FileName(); + virtual string MD5Hash(); + virtual string SourcePkg(); + + // These are some general stats about the package + virtual string Maintainer(); + virtual string ShortDesc(); + virtual string LongDesc(); + + debRecordParser(FileFd &File,pkgCache &Cache); +}; + + +#endif diff --git a/apt/apt-pkg/deb/debsrcrecords.cc b/apt/apt-pkg/deb/debsrcrecords.cc new file mode 100644 index 0000000..6b93a52 --- /dev/null +++ b/apt/apt-pkg/deb/debsrcrecords.cc @@ -0,0 +1,103 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: debsrcrecords.cc,v 1.2 2000/10/29 20:25:10 kojima Exp $ +/* ###################################################################### + + Debian Source Package Records - Parser implementation for Debian style + source indexes + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/debsrcrecords.h" +#endif + +#include +#include +#include + /*}}}*/ + +// SrcRecordParser::Binaries - Return the binaries field /*{{{*/ +// --------------------------------------------------------------------- +/* This member parses the binaries field into a pair of class arrays and + returns a list of strings representing all of the components of the + binaries field. The returned array need not be freed and will be + reused by the next Binaries function call. */ +const char **debSrcRecordParser::Binaries() +{ + string Bins = Sect.FindS("Binary"); + char *Buf = Buffer; + unsigned int Bin = 0; + if (Bins.empty() == true) + return 0; + // XXX no bounds check: exploitable? + // Strip any leading spaces + string::const_iterator Start = Bins.begin(); + for (; Start != Bins.end() && isspace(*Start) != 0; Start++); + + string::const_iterator Pos = Start; + while (Pos != Bins.end()) + { + // Skip to the next ',' + for (; Pos != Bins.end() && *Pos != ','; Pos++); + + // Back remove spaces + string::const_iterator End = Pos; + for (; End > Start && (End[-1] == ',' || isspace(End[-1]) != 0); End--); + + // Stash the string + memcpy(Buf,Start,End-Start); + StaticBinList[Bin] = Buf; + Bin++; + Buf += End-Start; + *Buf++ = 0; + + // Advance pos + for (; Pos != Bins.end() && (*Pos == ',' || isspace(*Pos) != 0); Pos++); + Start = Pos; + } + + StaticBinList[Bin] = 0; + return StaticBinList; +} + /*}}}*/ +// SrcRecordParser::Files - Return a list of files for this source /*{{{*/ +// --------------------------------------------------------------------- +/* This parses the list of files and returns it, each file is required to have + a complete source package */ +bool debSrcRecordParser::Files(vector &List) +{ + List.erase(List.begin(),List.end()); + + string Files = Sect.FindS("Files"); + if (Files.empty() == true) + return false; + + // Stash the / terminated directory prefix + string Base = Sect.FindS("Directory"); + if (Base.empty() == false && Base[Base.length()-1] != '/') + Base += '/'; + + // Iterate over the entire list grabbing each triplet + const char *C = Files.c_str(); + while (*C != 0) + { + pkgSrcRecords::File F; + string Size; + + // Parse each of the elements + if (ParseQuoteWord(C,F.MD5Hash) == false || + ParseQuoteWord(C,Size) == false || + ParseQuoteWord(C,F.Path) == false) + return _error->Error("Error parsing file record"); + + // Parse the size and append the directory + F.Size = atoi(Size.c_str()); + F.Path = Base + F.Path; + List.push_back(F); + } + + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/deb/debsrcrecords.h b/apt/apt-pkg/deb/debsrcrecords.h new file mode 100644 index 0000000..5316889 --- /dev/null +++ b/apt/apt-pkg/deb/debsrcrecords.h @@ -0,0 +1,54 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: debsrcrecords.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Debian Source Package Records - Parser implementation for Debian style + source indexes + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_DEBSRCRECORDS_H +#define PKGLIB_DEBSRCRECORDS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/debsrcrecords.h" +#endif + +#include +#include + +class debSrcRecordParser : public pkgSrcRecords::Parser +{ + pkgTagFile Tags; + pkgTagSection Sect; + char Buffer[10000]; + const char *StaticBinList[400]; + unsigned long iOffset; + + public: + + virtual bool Restart() {return Tags.Jump(Sect,0);}; + virtual bool Step() {iOffset = Tags.Offset(); return Tags.Step(Sect);}; + virtual bool Jump(unsigned long Off) {iOffset = Off; return Tags.Jump(Sect,Off);}; + + virtual string Package() {return Sect.FindS("Package");}; + virtual string Version() {return Sect.FindS("Version");}; + virtual string Maintainer() {return Sect.FindS("Maintainer");}; + virtual string Section() {return Sect.FindS("Section");}; + virtual const char **Binaries(); + virtual unsigned long Offset() {return iOffset;}; + virtual string AsStr() + { + const char *Start=0,*Stop=0; + Sect.GetSection(Start,Stop); + return string(Start,Stop); + }; + virtual bool Files(vector &F); + + debSrcRecordParser(FileFd *File,pkgSourceList::const_iterator SrcItem) : + Parser(File,SrcItem), + Tags(*File,sizeof(Buffer)) {}; +}; + +#endif diff --git a/apt/apt-pkg/deb/dpkginit.cc b/apt/apt-pkg/deb/dpkginit.cc new file mode 100644 index 0000000..1cb3866 --- /dev/null +++ b/apt/apt-pkg/deb/dpkginit.cc @@ -0,0 +1,119 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: dpkginit.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + DPKG init - Initialize the dpkg stuff + + This class provides the locking mechanism used by dpkg for its + database area. It does the proper consistency checks and acquires the + correct kind of lock. + + ##################################################################### */ + /*}}}*/ +// Includes /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/dpkginit.h" +#endif +#include +#include +#include +#include + +#include +#include +#include + /*}}}*/ + +// DpkgLock::pkgDpkgLock - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDpkgLock::pkgDpkgLock(bool WithUpdates) +{ + LockFD = -1; + GetLock(WithUpdates); +} + /*}}}*/ +// DpkgLock::~pkgDpkgLock - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDpkgLock::~pkgDpkgLock() +{ + Close(); +} + /*}}}*/ +// DpkgLock::GetLock - Get the lock /*{{{*/ +// --------------------------------------------------------------------- +/* This mirrors the operations dpkg does when it starts up. Note the + checking of the updates directory. */ +bool pkgDpkgLock::GetLock(bool WithUpdates) +{ + // Disable file locking + if (_config->FindB("Debug::NoLocking",false) == true) + return true; + + Close(); + + // Create the lockfile + string AdminDir = flNotFile(_config->Find("Dir::State::status")); + LockFD = ::GetLock(AdminDir + "lock"); + if (LockFD == -1) + return _error->Error("Unable to lock the administration directory, " + "are you root?"); + + // See if we need to abort with a dirty journal + if (WithUpdates == true && CheckUpdates() == true) + { + Close(); + return _error->Error("dpkg was interrupted, you must manually " + "run 'dpkg --configure -a' to correct the problem. "); + } + + return true; +} + /*}}}*/ +// DpkgLock::Close - Close the lock /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDpkgLock::Close() +{ + close(LockFD); + LockFD = -1; +} + /*}}}*/ +// DpkgLock::CheckUpdates - Check if the updates dir is dirty /*{{{*/ +// --------------------------------------------------------------------- +/* This does a check of the updates directory to see if it has any entries + in it. */ +bool pkgDpkgLock::CheckUpdates() +{ + // Check for updates.. (dirty) + string File = flNotFile(_config->Find("Dir::State::status")) + "updates/"; + DIR *DirP = opendir(File.c_str()); + if (DirP == 0) + return false; + + /* We ignore any files that are not all digits, this skips .,.. and + some tmp files dpkg will leave behind.. */ + bool Damaged = false; + for (struct dirent *Ent = readdir(DirP); Ent != 0; Ent = readdir(DirP)) + { + Damaged = true; + for (unsigned int I = 0; Ent->d_name[I] != 0; I++) + { + // Check if its not a digit.. + if (isdigit(Ent->d_name[I]) == 0) + { + Damaged = false; + break; + } + } + if (Damaged == true) + break; + } + closedir(DirP); + + return Damaged; +} + /*}}}*/ + diff --git a/apt/apt-pkg/deb/dpkginit.h b/apt/apt-pkg/deb/dpkginit.h new file mode 100644 index 0000000..8f72131 --- /dev/null +++ b/apt/apt-pkg/deb/dpkginit.h @@ -0,0 +1,34 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: dpkginit.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + DPKG init - Initialize the dpkg stuff + + This basically gets a lock in /var/lib/dpkg and checks the updates + directory + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_DPKGINIT_H +#define PKGLIB_DPKGINIT_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/dpkginit.h" +#endif + +class pkgDpkgLock +{ + int LockFD; + + public: + + bool CheckUpdates(); + bool GetLock(bool WithUpdates); + void Close(); + + pkgDpkgLock(bool WithUpdates = true); + ~pkgDpkgLock(); +}; + +#endif diff --git a/apt/apt-pkg/deb/dpkgpm.cc b/apt/apt-pkg/deb/dpkgpm.cc new file mode 100644 index 0000000..dc3c6c4 --- /dev/null +++ b/apt/apt-pkg/deb/dpkgpm.cc @@ -0,0 +1,408 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: dpkgpm.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + DPKG Package Manager - Provide an interface to dpkg + + ##################################################################### */ + /*}}}*/ +// Includes /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/dpkgpm.h" +#endif +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + /*}}}*/ + +// DPkgPM::pkgDPkgPM - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDPkgPM::pkgDPkgPM(pkgDepCache &Cache) : pkgPackageManager(Cache) +{ +} + /*}}}*/ +// DPkgPM::pkgDPkgPM - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDPkgPM::~pkgDPkgPM() +{ +} + /*}}}*/ +// DPkgPM::Install - Install a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add an install operation to the sequence list */ +bool pkgDPkgPM::Install(PkgIterator Pkg,string File) +{ + if (File.empty() == true || Pkg.end() == true) + return _error->Error("Internal Error, No file name for %s",Pkg.Name()); + + List.push_back(Item(Item::Install,Pkg,File)); + return true; +} + /*}}}*/ +// DPkgPM::Configure - Configure a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add a configure operation to the sequence list */ +bool pkgDPkgPM::Configure(PkgIterator Pkg) +{ + if (Pkg.end() == true) + return false; + + List.push_back(Item(Item::Configure,Pkg)); + return true; +} + /*}}}*/ +// DPkgPM::Remove - Remove a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add a remove operation to the sequence list */ +bool pkgDPkgPM::Remove(PkgIterator Pkg,bool Purge) +{ + if (Pkg.end() == true) + return false; + + if (Purge == true) + List.push_back(Item(Item::Purge,Pkg)); + else + List.push_back(Item(Item::Remove,Pkg)); + return true; +} + /*}}}*/ +// DPkgPM::RunScripts - Run a set of scripts /*{{{*/ +// --------------------------------------------------------------------- +/* This looks for a list of script sto run from the configuration file, + each one is run with system from a forked child. */ +bool pkgDPkgPM::RunScripts(const char *Cnf) +{ + Configuration::Item const *Opts = _config->Tree(Cnf); + if (Opts == 0 || Opts->Child == 0) + return true; + Opts = Opts->Child; + + // Fork for running the system calls + pid_t Child = ExecFork(); + + // This is the child + if (Child == 0) + { + if (chdir("/tmp/") != 0) + _exit(100); + + unsigned int Count = 1; + for (; Opts != 0; Opts = Opts->Next, Count++) + { + if (Opts->Value.empty() == true) + continue; + + if (system(Opts->Value.c_str()) != 0) + _exit(100+Count); + } + _exit(0); + } + + // Wait for the child + int Status = 0; + while (waitpid(Child,&Status,0) != Child) + { + if (errno == EINTR) + continue; + return _error->Errno("waitpid","Couldn't wait for subprocess"); + } + + // Restore sig int/quit + signal(SIGQUIT,SIG_DFL); + signal(SIGINT,SIG_DFL); + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + { + unsigned int Count = WEXITSTATUS(Status); + if (Count > 100) + { + Count -= 100; + for (; Opts != 0 && Count != 1; Opts = Opts->Next, Count--); + _error->Error("Problem executing scripts %s '%s'",Cnf,Opts->Value.c_str()); + } + + return _error->Error("Sub-process returned an error code"); + } + + return true; +} + + /*}}}*/ +// DPkgPM::RunScriptsWithPkgs - Run scripts with package names on stdin /*{{{*/ +// --------------------------------------------------------------------- +/* This looks for a list of scripts to run from the configuration file + each one is run and is fed on standard input a list of all .deb files + that are due to be installed. */ +bool pkgDPkgPM::RunScriptsWithPkgs(const char *Cnf) +{ + Configuration::Item const *Opts = _config->Tree(Cnf); + if (Opts == 0 || Opts->Child == 0) + return true; + Opts = Opts->Child; + + unsigned int Count = 1; + for (; Opts != 0; Opts = Opts->Next, Count++) + { + if (Opts->Value.empty() == true) + continue; + + // Create the pipes + int Pipes[2]; + if (pipe(Pipes) != 0) + return _error->Errno("pipe","Failed to create IPC pipe to subprocess"); + SetCloseExec(Pipes[0],true); + SetCloseExec(Pipes[1],true); + + // Purified Fork for running the script + pid_t Process = ExecFork(); + if (Process == 0) + { + // Setup the FDs + dup2(Pipes[0],STDIN_FILENO); + SetCloseExec(STDOUT_FILENO,false); + SetCloseExec(STDIN_FILENO,false); + SetCloseExec(STDERR_FILENO,false); + + const char *Args[4]; + Args[0] = "/bin/sh"; + Args[1] = "-c"; + Args[2] = Opts->Value.c_str(); + Args[3] = 0; + execv(Args[0],(char **)Args); + _exit(100); + } + close(Pipes[0]); + FileFd Fd(Pipes[1]); + + // Feed it the filenames. + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + // Only deal with packages to be installed from .deb + if (I->Op != Item::Install) + continue; + + // No errors here.. + if (I->File[0] != '/') + continue; + + /* Feed the filename of each package that is pending install + into the pipe. */ + if (Fd.Write(I->File.begin(),I->File.length()) == false || + Fd.Write("\n",1) == false) + { + kill(Process,SIGINT); + Fd.Close(); + ExecWait(Process,Opts->Value.c_str(),true); + return _error->Error("Failure running script %s",Opts->Value.c_str()); + } + } + Fd.Close(); + + // Clean up the sub process + if (ExecWait(Process,Opts->Value.c_str()) == false) + return _error->Error("Failure running script %s",Opts->Value.c_str()); + } + + return true; +} + + /*}}}*/ +// DPkgPM::Go - Run the sequence /*{{{*/ +// --------------------------------------------------------------------- +/* This globs the operations and calls dpkg */ +bool pkgDPkgPM::Go() +{ + if (RunScripts("DPkg::Pre-Invoke") == false) + return false; + + if (RunScriptsWithPkgs("DPkg::Pre-Install-Pkgs") == false) + return false; + + for (vector::iterator I = List.begin(); I != List.end();) + { + vector::iterator J = I; + for (; J != List.end() && J->Op == I->Op; J++); + + // Generate the argument list + const char *Args[400]; + if (J - I > 350) + J = I + 350; + + unsigned int n = 0; + unsigned long Size = 0; + Args[n++] = _config->Find("Dir::Bin::dpkg","dpkg").c_str(); + Size += strlen(Args[n-1]); + + // Stick in any custom dpkg options + Configuration::Item const *Opts = _config->Tree("DPkg::Options"); + if (Opts != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + Args[n++] = Opts->Value.c_str(); + Size += Opts->Value.length(); + } + } + + switch (I->Op) + { + case Item::Remove: + Args[n++] = "--force-depends"; + Size += strlen(Args[n-1]); + Args[n++] = "--force-remove-essential"; + Size += strlen(Args[n-1]); + Args[n++] = "--remove"; + Size += strlen(Args[n-1]); + break; + + case Item::Purge: + Args[n++] = "--force-depends"; + Size += strlen(Args[n-1]); + Args[n++] = "--force-remove-essential"; + Size += strlen(Args[n-1]); + Args[n++] = "--purge"; + Size += strlen(Args[n-1]); + break; + + case Item::Configure: + Args[n++] = "--configure"; + Size += strlen(Args[n-1]); + break; + + case Item::Install: + Args[n++] = "--unpack"; + Size += strlen(Args[n-1]); + break; + } + + // Write in the file or package names + if (I->Op == Item::Install) + { + for (;I != J && Size < 1024; I++) + { + if (I->File[0] != '/') + return _error->Error("Internal Error, Pathname to install is not absolute '%s'",I->File.c_str()); + Args[n++] = I->File.c_str(); + Size += strlen(Args[n-1]); + } + } + else + { + for (;I != J && Size < 1024; I++) + { + Args[n++] = I->Pkg.Name(); + Size += strlen(Args[n-1]); + } + } + Args[n] = 0; + J = I; + + if (_config->FindB("Debug::pkgDPkgPM",false) == true) + { + for (unsigned int k = 0; k != n; k++) + clog << Args[k] << ' '; + clog << endl; + continue; + } + + cout << flush; + clog << flush; + cerr << flush; + + /* Mask off sig int/quit. We do this because dpkg also does when + it forks scripts. What happens is that when you hit ctrl-c it sends + it to all processes in the group. Since dpkg ignores the signal + it doesn't die but we do! So we must also ignore it */ + signal(SIGQUIT,SIG_IGN); + signal(SIGINT,SIG_IGN); + + // Fork dpkg + pid_t Child = ExecFork(); + + // This is the child + if (Child == 0) + { + if (chdir(_config->FindDir("DPkg::Run-Directory","/").c_str()) != 0) + _exit(100); + + if (_config->FindB("DPkg::FlushSTDIN",true) == true) + { + int Flags,dummy; + if ((Flags = fcntl(STDIN_FILENO,F_GETFL,dummy)) < 0) + _exit(100); + + // Discard everything in stdin before forking dpkg + if (fcntl(STDIN_FILENO,F_SETFL,Flags | O_NONBLOCK) < 0) + _exit(100); + + while (read(STDIN_FILENO,&dummy,1) == 1); + + if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) + _exit(100); + } + + /* No Job Control Stop Env is a magic dpkg var that prevents it + from using sigstop */ + putenv("DPKG_NO_TSTP=yes"); + execvp(Args[0],(char **)Args); + cerr << "Could not exec dpkg!" << endl; + _exit(100); + } + + // Wait for dpkg + int Status = 0; + while (waitpid(Child,&Status,0) != Child) + { + if (errno == EINTR) + continue; + RunScripts("DPkg::Post-Invoke"); + return _error->Errno("waitpid","Couldn't wait for subprocess"); + } + + // Restore sig int/quit + signal(SIGQUIT,SIG_DFL); + signal(SIGINT,SIG_DFL); + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + { + RunScripts("DPkg::Post-Invoke"); + if (WIFSIGNALED(Status) != 0 && WTERMSIG(Status) == SIGSEGV) + return _error->Error("Sub-process %s recieved a segmentation fault.",Args[0]); + + if (WIFEXITED(Status) != 0) + return _error->Error("Sub-process %s returned an error code (%u)",Args[0],WEXITSTATUS(Status)); + + return _error->Error("Sub-process %s exited unexpectedly",Args[0]); + } + } + + if (RunScripts("DPkg::Post-Invoke") == false) + return false; + return true; +} + /*}}}*/ +// pkgDpkgPM::Reset - Dump the contents of the command list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDPkgPM::Reset() +{ + List.erase(List.begin(),List.end()); +} + /*}}}*/ diff --git a/apt/apt-pkg/deb/dpkgpm.h b/apt/apt-pkg/deb/dpkgpm.h new file mode 100644 index 0000000..ad822f7 --- /dev/null +++ b/apt/apt-pkg/deb/dpkgpm.h @@ -0,0 +1,53 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: dpkgpm.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + DPKG Package Manager - Provide an interface to dpkg + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_DPKGPM_H +#define PKGLIB_DPKGPM_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/dpkgpm.h" +#endif + +#include +#include + +class pkgDPkgPM : public pkgPackageManager +{ + protected: + + struct Item + { + enum Ops {Install, Configure, Remove, Purge} Op; + string File; + PkgIterator Pkg; + Item(Ops Op,PkgIterator Pkg,string File = "") : Op(Op), + File(File), Pkg(Pkg) {}; + Item() {}; + + }; + vector List; + + // Helpers + bool RunScripts(const char *Cnf); + bool RunScriptsWithPkgs(const char *Cnf); + + // The Actuall installation implementation + virtual bool Install(PkgIterator Pkg,string File); + virtual bool Configure(PkgIterator Pkg); + virtual bool Remove(PkgIterator Pkg,bool Purge = false); + virtual bool Go(); + virtual void Reset(); + + public: + + pkgDPkgPM(pkgDepCache &Cache); + virtual ~pkgDPkgPM(); +}; + +#endif diff --git a/apt/apt-pkg/depcache.cc b/apt/apt-pkg/depcache.cc new file mode 100644 index 0000000..c0f83e9 --- /dev/null +++ b/apt/apt-pkg/depcache.cc @@ -0,0 +1,941 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: depcache.cc,v 1.20 2001/11/13 17:32:07 kojima Exp $ +/* ###################################################################### + + Dependency Cache - Caches Dependency information. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/depcache.h" +#endif +#include +#include +#include +#include + +#include + /*}}}*/ + +// DepCache::pkgDepCache - Constructors /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDepCache::pkgDepCache(MMap &Map,OpProgress &Prog) : + pkgCache(Map), PkgState(0), DepState(0) +{ + if (_error->PendingError() == false) + Init(&Prog); +} +pkgDepCache::pkgDepCache(MMap &Map) : + pkgCache(Map), PkgState(0), DepState(0) +{ + if (_error->PendingError() == false) + Init(0); +} + /*}}}*/ +// DepCache::~pkgDepCache - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgDepCache::~pkgDepCache() +{ + delete [] PkgState; + delete [] DepState; +} + /*}}}*/ +// DepCache::Init - Generate the initial extra structures. /*{{{*/ +// --------------------------------------------------------------------- +/* This allocats the extension buffers and initializes them. */ +bool pkgDepCache::Init(OpProgress *Prog) +{ + delete [] PkgState; + delete [] DepState; + PkgState = new StateCache[Head().PackageCount]; + DepState = new unsigned char[Head().DependsCount]; + memset(PkgState,0,sizeof(*PkgState)*Head().PackageCount); + memset(DepState,0,sizeof(*DepState)*Head().DependsCount); + + if (Prog != 0) + { + Prog->OverallProgress(0,2*Head().PackageCount,Head().PackageCount, + _("Building Dependency Tree")); + Prog->SubProgress(Head().PackageCount,_("Candidate Versions")); + } + + /* Set the current state of everything. In this state all of the + packages are kept exactly as is. See AllUpgrade */ + int Done = 0; + for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++) + { + if (Prog != 0) + Prog->Progress(Done); + + // Find the proper cache slot + StateCache &State = PkgState[I->ID]; + State.iFlags = 0; + + // Figure out the install version + State.CandidateVer = GetCandidateVer(I); + State.InstallVer = I.CurrentVer(); + State.Mode = ModeKeep; + + State.Update(I,*this); + } + + if (Prog != 0) + { + + Prog->OverallProgress(Head().PackageCount,2*Head().PackageCount, + Head().PackageCount, + _("Building Dependency Tree")); + Prog->SubProgress(Head().PackageCount,_("Dependency Generation")); + } + + Update(Prog); + + return true; +} + /*}}}*/ +// DepCache::GetCandidateVer - Returns the Candidate install version /*{{{*/ +// --------------------------------------------------------------------- +/* The default just returns the target version if it exists or the + highest version. */ +pkgDepCache::VerIterator pkgDepCache::GetCandidateVer(PkgIterator Pkg, + bool AllowCurrent) +{ + // Try to use an explicit target + if (Pkg->TargetVer == 0 || + (AllowCurrent == false && Pkg.TargetVer() == Pkg.CurrentVer())) + return pkgCache::GetCandidateVer(Pkg,AllowCurrent); + else + return Pkg.TargetVer(); +} + /*}}}*/ +// DepCache::IsImportantDep - True if the dependency is important /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgDepCache::IsImportantDep(DepIterator Dep) +{ + return Dep.IsCritical(); +} + /*}}}*/ + +// DepCache::CheckDep - Checks a single dependency /*{{{*/ +// --------------------------------------------------------------------- +/* This first checks the dependency against the main target package and + then walks along the package provides list and checks if each provides + will be installed then checks the provides against the dep. Res will be + set to the package which was used to satisfy the dep. */ +bool pkgDepCache::CheckDep(DepIterator Dep,int Type,PkgIterator &Res) +{ + Res = Dep.TargetPkg(); + + /* Check simple depends. A depends -should- never self match but + we allow it anyhow because dpkg does. Technically it is a packaging + bug. Conflicts may never self match */ + if (Dep.TargetPkg() != Dep.ParentPkg() + || (Dep->Type != Dep::Conflicts + && Dep->Type != Dep::Obsoletes)) + { + PkgIterator Pkg = Dep.TargetPkg(); + + // Check the base package + if (Type == NowVersion && Pkg->CurrentVer != 0) + if (_system->checkDep(Dep.TargetVer(), + Pkg.CurrentVer().VerStr(),Dep->CompareOp) == true) + return true; + + if (Type == InstallVersion && PkgState[Pkg->ID].InstallVer != 0) + if (_system->checkDep(Dep.TargetVer(), + PkgState[Pkg->ID].InstVerIter(*this).VerStr(), + Dep->CompareOp) == true) + return true; + + if (Type == CandidateVersion && PkgState[Pkg->ID].CandidateVer != 0) + if (_system->checkDep(Dep.TargetVer(), + PkgState[Pkg->ID].CandidateVerIter(*this).VerStr(), + Dep->CompareOp) == true) + return true; + } + + if (Dep->Type == Dep::Obsoletes) + return false; + + // Check the providing packages + PrvIterator P = Dep.TargetPkg().ProvidesList(); + PkgIterator Pkg = Dep.ParentPkg(); + + for (; P.end() != true; P++) + { + /* Provides may never be applied against the same package if it is + a conflicts. See the comment above. */ + if (P.OwnerPkg() == Pkg && Dep->Type == Dep::Conflicts) + continue; + + // Check if the provides is a hit + if (Type == NowVersion) + { + if (P.OwnerPkg().CurrentVer() != P.OwnerVer()) + continue; + } + + if (Type == InstallVersion) + { + StateCache &State = PkgState[P.OwnerPkg()->ID]; + if (State.InstallVer != (Version *)P.OwnerVer()) + continue; + } + + if (Type == CandidateVersion) + { + StateCache &State = PkgState[P.OwnerPkg()->ID]; + if (State.CandidateVer != (Version *)P.OwnerVer()) + continue; + } + + // Compare the versions. + if (_system->checkDep(Dep.TargetVer(),P.ProvideVersion(),Dep->CompareOp) == true) + { + Res = P.OwnerPkg(); + /* + if (Dep->Type == Dep::Conflicts) + cout << "MATCH: " << Res.Name() << "::"<ID]; + + if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + P.Keep() == true) + return; + + // Compute the size data + if (P.NewInstall() == true) + { + iUsrSize += Mult*P.InstVerIter(*this)->InstalledSize; + iDownloadSize += Mult*P.InstVerIter(*this)->Size; + return; + } + + // Upgrading + if (Pkg->CurrentVer != 0 && + (P.InstallVer != (Version *)Pkg.CurrentVer() || + (P.iFlags & ReInstall) == ReInstall) && P.InstallVer != 0) + { + iUsrSize += Mult*((signed)P.InstVerIter(*this)->InstalledSize - + (signed)Pkg.CurrentVer()->InstalledSize); + iDownloadSize += Mult*P.InstVerIter(*this)->Size; + return; + } + + // Reinstall + if (Pkg.State() == pkgCache::PkgIterator::NeedsUnpack && + P.Delete() == false) + { + iDownloadSize += Mult*P.InstVerIter(*this)->Size; + return; + } + + // Removing + if (Pkg->CurrentVer != 0 && P.InstallVer == 0) + { + iUsrSize -= Mult*Pkg.CurrentVer()->InstalledSize; + return; + } +} + /*}}}*/ +// DepCache::AddStates - Add the package to the state counter /*{{{*/ +// --------------------------------------------------------------------- +/* This routine is tricky to use, you must make sure that it is never + called twice for the same package. This means the Remove/Add section + should be as short as possible and not encompass any code that will + calld Remove/Add itself. Remember, dependencies can be circular so + while processing a dep for Pkg it is possible that Add/Remove + will be called on Pkg */ +void pkgDepCache::AddStates(const PkgIterator &Pkg,int Add) +{ + StateCache &State = PkgState[Pkg->ID]; + + // The Package is broken + if ((State.DepState & DepInstMin) != DepInstMin) + iBrokenCount += Add; + + // Bad state + if (Pkg.State() != PkgIterator::NeedsNothing) + iBadCount += Add; + + // Not installed + if (Pkg->CurrentVer == 0) + { + if (State.Mode == ModeDelete && + (State.iFlags | Purge) == Purge && Pkg.Purge() == false) + iDelCount += Add; + + if (State.Mode == ModeInstall) + iInstCount += Add; + return; + } + + // Installed, no upgrade + if (State.Upgradable() == false) + { + if (State.Mode == ModeDelete) + iDelCount += Add; + else + if ((State.iFlags & ReInstall) == ReInstall) + iInstCount += Add; + + return; + } + + // Alll 3 are possible + if (State.Mode == ModeDelete) + iDelCount += Add; + if (State.Mode == ModeKeep) + iKeepCount += Add; + if (State.Mode == ModeInstall) + iInstCount += Add; +} + /*}}}*/ +// DepCache::BuildGroupOrs - Generate the Or group dep data /*{{{*/ +// --------------------------------------------------------------------- +/* The or group results are stored in the last item of the or group. This + allows easy detection of the state of a whole or'd group. */ +void pkgDepCache::BuildGroupOrs(VerIterator const &V) +{ + unsigned char Group = 0; + + for (DepIterator D = V.DependsList(); D.end() != true; D++) + { + // Build the dependency state. + unsigned char &State = DepState[D->ID]; + + /* Invert for Conflicts. We have to do this twice to get the + right sense for a conflicts group */ + if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + State = ~State; + + // Add to the group if we are within an or.. + State &= 0x7; + Group |= State; + State |= Group << 3; + if ((D->CompareOp & Dep::Or) != Dep::Or) + Group = 0; + + // Invert for Conflicts + if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + State = ~State; + } +} + /*}}}*/ +// DepCache::VersionState - Perform a pass over a dependency list /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to run over a dependency list and determine the dep + state of the list, filtering it through both a Min check and a Policy + check. The return result will have SetMin/SetPolicy low if a check + fails. It uses the DepState cache for it's computations. */ +unsigned char pkgDepCache::VersionState(DepIterator D,unsigned char Check, + unsigned char SetMin, + unsigned char SetPolicy) +{ + unsigned char Dep = 0xFF; + + while (D.end() != true) + { + // Compute a single dependency element (glob or) + DepIterator Start = D; + unsigned char State = 0; + for (bool LastOR = true; D.end() == false && LastOR == true; D++) + { + State |= DepState[D->ID]; + LastOR = (D->CompareOp & Dep::Or) == Dep::Or; + } + + // Minimum deps that must be satisfied to have a working package + if (Start.IsCritical() == true) + if ((State & Check) != Check) + Dep &= ~SetMin; + + // Policy deps that must be satisfied to install the package + if (IsImportantDep(Start) == true && + (State & Check) != Check) + Dep &= ~SetPolicy; + } + + return Dep; +} + /*}}}*/ +// DepCache::DependencyState - Compute the 3 results for a dep /*{{{*/ +// --------------------------------------------------------------------- +/* This is the main dependency computation bit. It computes the 3 main + results for a dependencys, Now, Install and Candidate. Callers must + invert the result if dealing with conflicts. */ +unsigned char pkgDepCache::DependencyState(DepIterator &D) +{ + unsigned char State = 0; + + if (CheckDep(D,NowVersion) == true) + State |= DepNow; + if (CheckDep(D,InstallVersion) == true) + State |= DepInstall; + if (CheckDep(D,CandidateVersion) == true) + State |= DepCVer; + + return State; +} + /*}}}*/ +// DepCache::UpdateVerState - Compute the Dep member of the state /*{{{*/ +// --------------------------------------------------------------------- +/* This determines the combined dependency representation of a package + for its two states now and install. This is done by using the pre-generated + dependency information. */ +void pkgDepCache::UpdateVerState(PkgIterator Pkg) +{ + // Empty deps are always true + StateCache &State = PkgState[Pkg->ID]; + State.DepState = 0xFF; + + // Check the Current state + if (Pkg->CurrentVer != 0) + { + DepIterator D = Pkg.CurrentVer().DependsList(); + State.DepState &= VersionState(D,DepNow,DepNowMin,DepNowPolicy); + } + + /* Check the candidate state. We do not compare against the whole as + a candidate state but check the candidate version against the + install states */ + if (State.CandidateVer != 0) + { + DepIterator D = State.CandidateVerIter(*this).DependsList(); + State.DepState &= VersionState(D,DepInstall,DepCandMin,DepCandPolicy); + } + + // Check target state which can only be current or installed + if (State.InstallVer != 0) + { + DepIterator D = State.InstVerIter(*this).DependsList(); + State.DepState &= VersionState(D,DepInstall,DepInstMin,DepInstPolicy); + } +} + /*}}}*/ +// DepCache::Update - Figure out all the state information /*{{{*/ +// --------------------------------------------------------------------- +/* This will figure out the state of all the packages and all the + dependencies based on the current policy. */ +void pkgDepCache::Update(OpProgress *Prog) +{ + iUsrSize = 0; + iDownloadSize = 0; + iDelCount = 0; + iInstCount = 0; + iKeepCount = 0; + iBrokenCount = 0; + iBadCount = 0; + + // Perform the depends pass + int Done = 0; + for (PkgIterator I = PkgBegin(); I.end() != true; I++,Done++) + { + if (Prog != 0 && Done%20 == 0) + Prog->Progress(Done); + for (VerIterator V = I.VersionList(); V.end() != true; V++) + { + unsigned char Group = 0; + + for (DepIterator D = V.DependsList(); D.end() != true; D++) + { + // Build the dependency state. + unsigned char &State = DepState[D->ID]; + State = DependencyState(D);; + + // Add to the group if we are within an or.. + Group |= State; + State |= Group << 3; + if ((D->CompareOp & Dep::Or) != Dep::Or) + Group = 0; + + // Invert for Conflicts + if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + State = ~State; + } + } + + // Compute the pacakge dependency state and size additions + AddSizes(I); + UpdateVerState(I); + AddStates(I); + } + + if (Prog != 0) + Prog->Progress(Done); +} + /*}}}*/ +// DepCache::Update - Update the deps list of a package /*{{{*/ +// --------------------------------------------------------------------- +/* This is a helper for update that only does the dep portion of the scan. + It is mainly ment to scan reverse dependencies. */ +void pkgDepCache::Update(DepIterator D) +{ + // Update the reverse deps + for (;D.end() != true; D++) + { + unsigned char &State = DepState[D->ID]; + State = DependencyState(D); + + // Invert for Conflicts + if (D->Type == Dep::Conflicts || D->Type == Dep::Obsoletes) + State = ~State; + + RemoveStates(D.ParentPkg()); + BuildGroupOrs(D.ParentVer()); + UpdateVerState(D.ParentPkg()); + AddStates(D.ParentPkg()); + } +} + /*}}}*/ +// DepCache::Update - Update the related deps of a package /*{{{*/ +// --------------------------------------------------------------------- +/* This is called whenever the state of a package changes. It updates + all cached dependencies related to this package. */ +void pkgDepCache::Update(PkgIterator const &Pkg) +{ + // Recompute the dep of the package + RemoveStates(Pkg); + UpdateVerState(Pkg); + AddStates(Pkg); + + // Update the reverse deps + Update(Pkg.RevDependsList()); + + // Update the provides map for the current ver + if (Pkg->CurrentVer != 0) + for (PrvIterator P = Pkg.CurrentVer().ProvidesList(); + P.end() != true; P++) + Update(P.ParentPkg().RevDependsList()); + + // Update the provides map for the candidate ver + if (PkgState[Pkg->ID].CandidateVer != 0) + for (PrvIterator P = PkgState[Pkg->ID].CandidateVerIter(*this).ProvidesList(); + P.end() != true; P++) + Update(P.ParentPkg().RevDependsList()); +} + + /*}}}*/ + +// DepCache::MarkKeep - Put the package in the keep state /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDepCache::MarkKeep(PkgIterator const &Pkg,bool Soft) +{ + // Simplifies other routines. + if (Pkg.end() == true) + return; + + /* Reject an attempt to keep a non-source broken installed package, those + must be upgraded */ + if (Pkg.State() == PkgIterator::NeedsUnpack && + Pkg.CurrentVer().Downloadable() == false) + return; + + /* We changed the soft state all the time so the UI is a bit nicer + to use */ + StateCache &P = PkgState[Pkg->ID]; + if (Soft == true) + P.iFlags |= AutoKept; + else + P.iFlags &= ~AutoKept; + + // Check that it is not already kept + if (P.Mode == ModeKeep) + return; + + // We dont even try to keep virtual packages.. + if (Pkg->VersionList == 0) + return; + + P.Flags &= ~Flag::Auto; + RemoveSizes(Pkg); + RemoveStates(Pkg); + + P.Mode = ModeKeep; + if (Pkg->CurrentVer == 0) + P.InstallVer = 0; + else + P.InstallVer = Pkg.CurrentVer(); + + AddStates(Pkg); + + Update(Pkg); + + AddSizes(Pkg); +} + /*}}}*/ +// DepCache::MarkDelete - Put the package in the delete state /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDepCache::MarkDelete(PkgIterator const &Pkg, bool fReplace, bool rPurge) +{ + // Simplifies other routines. + if (Pkg.end() == true) + return; + + // Check that it is not already marked for delete + StateCache &P = PkgState[Pkg->ID]; + P.iFlags &= ~(AutoKept | Purge); + if ( fReplace ) P.iFlags |= Replaced; + if (rPurge == true) + P.iFlags |= Purge; + + if ((P.Mode == ModeDelete || P.InstallVer == 0) && + (Pkg.Purge() == true || rPurge == false)) + return; + + // We dont even try to delete virtual packages.. + if (Pkg->VersionList == 0) + return; + + RemoveSizes(Pkg); + RemoveStates(Pkg); + + if (Pkg->CurrentVer == 0 && (Pkg.Purge() == true || rPurge == false)) + P.Mode = ModeKeep; + else + P.Mode = ModeDelete; + P.InstallVer = 0; + P.Flags &= Flag::Auto; + + AddStates(Pkg); + Update(Pkg); + AddSizes(Pkg); +} + /*}}}*/ +#if 1 +// DepCache::MarkInstall - Put the package in the install state /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst) +{ + // Simplifies other routines. + if (Pkg.end() == true) + return; + + /* Check that it is not already marked for install and that it can be + installed */ + StateCache &P = PkgState[Pkg->ID]; + P.iFlags &= ~AutoKept; + if (P.InstBroken() == false && (P.Mode == ModeInstall || + P.CandidateVer == (Version *)Pkg.CurrentVer())) + { + if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0) + MarkKeep(Pkg); + return; + } + + // We dont even try to install virtual packages.. + if (Pkg->VersionList == 0) + return; + + /* Target the candidate version and remove the autoflag. We reset the + autoflag below if this was called recursively. Otherwise the user + should have the ability to de-auto a package by changing its state */ + RemoveSizes(Pkg); + RemoveStates(Pkg); + + P.Mode = ModeInstall; + P.InstallVer = P.CandidateVer; + P.Flags &= ~Flag::Auto; + if (P.CandidateVer == (Version *)Pkg.CurrentVer()) + P.Mode = ModeKeep; + + AddStates(Pkg); + Update(Pkg); + AddSizes(Pkg); + + + if (AutoInst == false) + return; + + DepIterator Dep = P.InstVerIter(*this).DependsList(); + for (; Dep.end() != true;) + { + // Grok or groups + DepIterator Start = Dep; + bool Result = true; + for (bool LastOR = true; Dep.end() == false && LastOR == true; Dep++) + { + LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or; + + if ((DepState[Dep->ID] & DepInstall) == DepInstall) + Result = false; + } + + // Dep is satisfied okay. + if (Result == false) { + continue; + } + + /* Check if this dep should be consider for install. If it is a user + defined important dep and we are installed a new package then + it will be installed. Otherwise we only worry about critical deps */ + if (IsImportantDep(Start) == false) + continue; + if (Pkg->CurrentVer != 0 && Start.IsCritical() == false) + continue; + + // Now we have to take action... + PkgIterator P = Start.SmartTargetPkg(); + if ((DepState[Start->ID] & DepCVer) == DepCVer) + { + MarkInstall(P,true); + + // Set the autoflag, after MarkInstall because MarkInstall unsets it + if (P->CurrentVer == 0) + PkgState[P->ID].Flags |= Flag::Auto; + + continue; + } + + // For conflicts we just de-install the package and mark as auto + if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes) + { + Version **List = Start.AllTargets(); + for (Version **I = List; *I != 0; I++) + { + VerIterator Ver(*this,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + MarkDelete(Pkg, Start->Type == Dep::Obsoletes); + PkgState[Pkg->ID].Flags |= Flag::Auto; + } + delete [] List; + continue; + } + } +} + /*}}}*/ +#else +// DepCache::MarkInstall - Put the package in the install state /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDepCache::MarkInstall(PkgIterator const &Pkg,bool AutoInst, + unsigned long Depth) +{ + if (Depth > 100) + return; + + // Simplifies other routines. + if (Pkg.end() == true) + return; + + /* Check that it is not already marked for install and that it can be + installed */ + StateCache &P = PkgState[Pkg->ID]; + P.iFlags &= ~AutoKept; + if (P.InstBroken() == false && (P.Mode == ModeInstall || + P.CandidateVer == (Version *)Pkg.CurrentVer())) + { + if (P.CandidateVer == (Version *)Pkg.CurrentVer() && P.InstallVer == 0) + MarkKeep(Pkg); + return; + } + + // See if there is even any possible instalation candidate + if (P.CandidateVer == 0) + return; + + // We dont even try to install virtual packages.. + if (Pkg->VersionList == 0) + return; + + /* Target the candidate version and remove the autoflag. We reset the + autoflag below if this was called recursively. Otherwise the user + should have the ability to de-auto a package by changing its state */ + RemoveSizes(Pkg); + RemoveStates(Pkg); + + P.Mode = ModeInstall; + P.InstallVer = P.CandidateVer; + P.Flags &= ~Flag::Auto; + if (P.CandidateVer == (Version *)Pkg.CurrentVer()) + P.Mode = ModeKeep; + + AddStates(Pkg); + Update(Pkg); + AddSizes(Pkg); + + if (AutoInst == false) + return; + + DepIterator Dep = P.InstVerIter(*this).DependsList(); + for (; Dep.end() != true;) + { + // Grok or groups + DepIterator Start = Dep; + bool Result = true; + unsigned Ors = 0; + for (bool LastOR = true; Dep.end() == false && LastOR == true; Dep++,Ors++) + { + LastOR = (Dep->CompareOp & Dep::Or) == Dep::Or; + + if ((DepState[Dep->ID] & DepInstall) == DepInstall) + Result = false; + } + + // Dep is satisfied okay. + if (Result == false) + continue; + + /* Check if this dep should be consider for install. If it is a user + defined important dep and we are installed a new package then + it will be installed. Otherwise we only worry about critical deps */ + if (IsImportantDep(Start) == false) + continue; + if (Pkg->CurrentVer != 0 && Start.IsCritical() == false) + continue; + + /* If we are in an or group locate the first or that can + succeed. We have already cached this.. */ + for (; Ors > 1 && (DepState[Start->ID] & DepCVer) != DepCVer; Ors--) + Start++; + + /* This bit is for processing the possibilty of an install/upgrade + fixing the problem */ + SPtrArray List = Start.AllTargets(); + if ((DepState[Start->ID] & DepCVer) == DepCVer) + { + // Right, find the best version to install.. + Version **Cur = List; + PkgIterator P = Start.TargetPkg(); + PkgIterator InstPkg(*Cache,0); + + // See if there are direct matches (at the start of the list) + for (; *Cur != 0 && (*Cur)->ParentPkg == P.Index(); Cur++) + { + PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg); + if (PkgState[Pkg->ID].CandidateVer != *Cur) + continue; + InstPkg = Pkg; + break; + } + + // Select the highest priority providing package + if (InstPkg.end() == false) + { + pkgPrioSortList(*Cache,Cur); + for (; *Cur != 0; Cur++) + { + PkgIterator Pkg(*Cache,Cache->PkgP + (*Cur)->ParentPkg); + if (PkgState[Pkg->ID].CandidateVer != *Cur) + continue; + InstPkg = Pkg; + break; + } + } + + if (InstPkg.end() == false) + { + MarkInstall(InstPkg,true,Depth + 1); + + // Set the autoflag, after MarkInstall because MarkInstall unsets it + if (P->CurrentVer == 0) + PkgState[InstPkg->ID].Flags |= Flag::Auto; + } + + continue; + } + + /* For conflicts we just de-install the package and mark as auto, + Conflicts may not have or groups */ + if (Start->Type == Dep::Conflicts || Start->Type == Dep::Obsoletes) + { + for (Version **I = List; *I != 0; I++) + { + VerIterator Ver(*this,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + MarkDelete(Pkg, Start->Type == Dep::Obsoletes); + PkgState[Pkg->ID].Flags |= Flag::Auto; + } + continue; + } + } +} + /*}}}*/ +#endif +// DepCache::SetReInstall - Set the reinstallation flag /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgDepCache::SetReInstall(PkgIterator const &Pkg,bool To) +{ + RemoveSizes(Pkg); + RemoveStates(Pkg); + + StateCache &P = PkgState[Pkg->ID]; + if (To == true) + P.iFlags |= ReInstall; + else + P.iFlags &= ~ReInstall; + + AddStates(Pkg); + AddSizes(Pkg); +} + +// StateCache::Update - Compute the various static display things /*{{{*/ +// --------------------------------------------------------------------- +/* This is called whenever the Candidate version changes. */ +void pkgDepCache::StateCache::Update(PkgIterator Pkg,pkgCache &Cache) +{ + // Some info + VerIterator Ver = CandidateVerIter(Cache); + + // Use a null string or the version string + if (Ver.end() == true) + CandVersion = ""; + else + CandVersion = Ver.VerStr(); + + // Find the current version + CurVersion = ""; + if (Pkg->CurrentVer != 0) + CurVersion = Pkg.CurrentVer().VerStr(); + + // Strip off the epochs for display + CurVersion = StripEpoch(CurVersion); + CandVersion = StripEpoch(CandVersion); + + // Figure out if its up or down or equal + Status = Ver.CompareVer(Pkg.CurrentVer()); + + if (Pkg->CurrentVer == 0 || Pkg->VersionList == 0 || CandidateVer == 0) { + Status = 2; + } +} + /*}}}*/ +// StateCache::StripEpoch - Remove the epoch specifier from the version /*{{{*/ +// --------------------------------------------------------------------- +/* */ +const char *pkgDepCache::StateCache::StripEpoch(const char *Ver) +{ + if (Ver == 0) + return 0; + + // Strip any epoch + for (const char *I = Ver; *I != 0; I++) + if (*I == ':') + return I + 1; + return Ver; +} + /*}}}*/ diff --git a/apt/apt-pkg/depcache.h b/apt/apt-pkg/depcache.h new file mode 100644 index 0000000..627265a --- /dev/null +++ b/apt/apt-pkg/depcache.h @@ -0,0 +1,187 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: depcache.h,v 1.3 2001/11/13 17:32:07 kojima Exp $ +/* ###################################################################### + + DepCache - Dependency Extension data for the cache + + This class stores the cache data and a set of extension structures for + monitoring the current state of all the packages. It also generates and + caches the 'install' state of many things. This refers to the state of the + package after an install has been run. + + The StateCache::State field can be -1,0,1,2 which is <,=,>,no current. + StateCache::Mode is which of the 3 fields is active. + + This structure is important to support the readonly status of the cache + file. When the data is saved the cache will be refereshed from our + internal rep and written to disk. Then the actual persistant data + files will be put on the disk. + + Each dependency is compared against 3 target versions to produce to + 3 dependency results. + Now - Compared using the Currently install version + Install - Compared using the install version (final state) + CVer - (Candidate Verion) Compared using the Candidate Version + The candidate and now results are used to decide wheather a package + should be automatically installed or if it should be left alone. + + Remember, the Candidate Version is selected based on the distribution + settings for the Package. The Install Version is selected based on the + state (Delete, Keep, Install) field and can be either the Current Version + or the Candidate version. + + The Candidate version is what is shown the 'Install Version' field. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_DEPCACHE_H +#define PKGLIB_DEPCACHE_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/depcache.h" +#endif + +#include +#include + +class pkgDepCache : public pkgCache +{ + public: + + // These flags are used in DepState + enum DepFlags {DepNow = (1 << 0),DepInstall = (1 << 1),DepCVer = (1 << 2), + DepGNow = (1 << 3),DepGInstall = (1 << 4),DepGCVer = (1 << 5)}; + + // These flags are used in StateCache::DepState + enum DepStateFlags {DepNowPolicy = (1 << 0), DepNowMin = (1 << 1), + DepInstPolicy = (1 << 2), DepInstMin = (1 << 3), + DepCandPolicy = (1 << 4), DepCandMin = (1 << 5)}; + + // These flags are used in StateCache::iFlags + enum InternalFlags {AutoKept = (1 << 0), Purge = (1 << 1), ReInstall = (1 << 2), Replaced = (1 << 3)}; + + enum VersionTypes {NowVersion, InstallVersion, CandidateVersion}; + enum ModeList {ModeDelete = 0, ModeKeep, ModeInstall}; + struct StateCache + { + // Epoch stripped text versions of the two version fields + const char *CandVersion; + const char *CurVersion; + + // Pointer to the candidate install version. + Version *CandidateVer; + + // Pointer to the install version. + Version *InstallVer; + + // Various tree indicators + signed char Status; // -1,0,1,2 + unsigned char Mode; // ModeList + unsigned char DepState; // DepState Flags + + // Copy of Package::Flags + unsigned short Flags; + unsigned short iFlags; // Internal flags + + // Update of candidate version + const char *StripEpoch(const char *Ver); + void Update(PkgIterator Pkg,pkgCache &Cache); + + // Various test members for the current status of the package + inline bool NewInstall() const {return Status == 2 && Mode == ModeInstall;}; + inline bool Delete() const {return Mode == ModeDelete;}; + inline bool Replaced() const {return iFlags & pkgDepCache::Replaced;}; + inline bool Keep() const {return Mode == ModeKeep;}; + inline bool Upgrade() const {return Status > 0 && Mode == ModeInstall;}; + inline bool Upgradable() const {return Status >= 1;}; + inline bool Downgrade() const {return Status < 0;}; + inline bool Held() const {return Status != 0 && Keep();}; + inline bool NowBroken() const {return (DepState & DepNowMin) != DepNowMin;}; + inline bool InstBroken() const {return (DepState & DepInstMin) != DepInstMin;}; + inline bool Install() const {return Mode == ModeInstall;}; + inline VerIterator InstVerIter(pkgCache &Cache) + {return VerIterator(Cache,InstallVer);}; + inline VerIterator CandidateVerIter(pkgCache &Cache) + {return VerIterator(Cache,CandidateVer);}; + }; + + // Helper functions + void BuildGroupOrs(VerIterator const &V); + void UpdateVerState(PkgIterator Pkg); + + bool Init(OpProgress *Prog); + + protected: + + // State information + StateCache *PkgState; + unsigned char *DepState; + + signed long iUsrSize; + unsigned long iDownloadSize; + unsigned long iInstCount; + unsigned long iDelCount; + unsigned long iKeepCount; + unsigned long iBrokenCount; + unsigned long iBadCount; + + // Check for a matching provides + bool CheckDep(DepIterator Dep,int Type,PkgIterator &Res); + inline bool CheckDep(DepIterator Dep,int Type) + { + PkgIterator Res(*this); + return CheckDep(Dep,Type,Res); + } + + // Computes state information for deps and versions (w/o storing) + unsigned char DependencyState(DepIterator &D); + unsigned char VersionState(DepIterator D,unsigned char Check, + unsigned char SetMin, + unsigned char SetPolicy); + + // Recalculates various portions of the cache, call after changing something + void Update(DepIterator Dep); // Mostly internal + void Update(PkgIterator const &P); + + // Count manipulators + void AddSizes(const PkgIterator &Pkg,long Mult = 1); + inline void RemoveSizes(const PkgIterator &Pkg) {AddSizes(Pkg,-1);}; + void AddStates(const PkgIterator &Pkg,int Add = 1); + inline void RemoveStates(const PkgIterator &Pkg) {AddStates(Pkg,-1);}; + + public: + + // Policy implementation + virtual VerIterator GetCandidateVer(PkgIterator Pkg,bool AllowCurrent = true); + virtual bool IsImportantDep(DepIterator Dep); + + // Accessors + inline StateCache &operator [](PkgIterator const &I) {return PkgState[I->ID];}; + inline unsigned char &operator [](DepIterator const &I) {return DepState[I->ID];}; + + // Manipulators + void MarkKeep(PkgIterator const &Pkg,bool Soft = false); + void MarkDelete(PkgIterator const &Pkg, bool fReplace = false, bool Purge = false); + void MarkInstall(PkgIterator const &Pkg,bool AutoInst = true); + void SetReInstall(PkgIterator const &Pkg,bool To); + + // This is for debuging + void Update(OpProgress *Prog = 0); + + // Size queries + inline signed long UsrSize() {return iUsrSize;}; + inline unsigned long DebSize() {return iDownloadSize;}; + inline unsigned long DelCount() {return iDelCount;}; + inline unsigned long KeepCount() {return iKeepCount;}; + inline unsigned long InstCount() {return iInstCount;}; + inline unsigned long BrokenCount() {return iBrokenCount;}; + inline unsigned long BadCount() {return iBadCount;}; + + pkgDepCache(MMap &Map,OpProgress &Prog); + pkgDepCache(MMap &Map); + virtual ~pkgDepCache(); +}; + +#endif diff --git a/apt/apt-pkg/init.cc b/apt/apt-pkg/init.cc new file mode 100644 index 0000000..38678bf --- /dev/null +++ b/apt/apt-pkg/init.cc @@ -0,0 +1,94 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: init.cc,v 1.16 2001/08/01 21:35:12 kojima Exp $ +/* ###################################################################### + + Init - Initialize the package library + + ##################################################################### */ + /*}}}*/ +// Include files /*{{{*/ +#include +#include +#include +#include + /*}}}*/ + + +// pkgInitialize - Initialize the configuration class /*{{{*/ +// --------------------------------------------------------------------- +/* Directories are specified in such a way that the FindDir function will + understand them. That is, if they don't start with a / then their parent + is prepended, this allows a fair degree of flexability. */ +bool pkgInitialize(Configuration &Cnf) +{ + // General APT things + Cnf.Set("APT::Architecture",COMMON_CPU); + + // State + Cnf.Set("Dir::State","/var/state/apt/"); + Cnf.Set("Dir::State::lists","lists/"); + + /* These really should be jammed into a generic 'Local Database' engine + which is yet to be determined. The functions in pkgcachegen should + be the only users of these */ + Cnf.Set("Dir::State::xstatus","xstatus"); + Cnf.Set("Dir::State::userstatus","status.user"); + if (0) {//akk + Cnf.Set("Dir::State::status","/var/lib/dpkg/status"); + } else { + Cnf.Set("Acquire::cdrom::mount", "/mnt/cdrom"); + Cnf.Set("RPM::AllowedDupPkgs::","^kernel$"); + Cnf.Set("RPM::AllowedDupPkgs::", "kernel-smp"); + Cnf.Set("RPM::AllowedDupPkgs::", "kernel-enterprise"); + + Cnf.Set("RPM::HoldPkgs::", "kernel-source"); + Cnf.Set("RPM::HoldPkgs::", "kernel-headers"); + + Cnf.Set("Dir::State::status","/var/lib/rpm/status"); + } + Cnf.Set("Dir::State::cdroms","cdroms.list"); + + // Cache + Cnf.Set("Dir::Cache","/var/cache/apt/"); + Cnf.Set("Dir::Cache::archives","archives/"); + Cnf.Set("Dir::Cache::srcpkgcache","srcpkgcache.bin"); + Cnf.Set("Dir::Cache::pkgcache","pkgcache.bin"); + + // Configuration + Cnf.Set("Dir::Etc","/etc/apt/"); + Cnf.Set("Dir::Etc::sourcelist","sources.list"); + Cnf.Set("Dir::Etc::vendorlist","vendors.list"); + Cnf.Set("Dir::Etc::main","apt.conf"); + Cnf.Set("Dir::Bin::gpg","/usr/bin/gpg"); + Cnf.Set("Dir::Bin::methods","/usr/lib/apt/methods"); + if (0) {//akk + Cnf.Set("Dir::Bin::dpkg","/usr/bin/dpkg"); + Cnf.Set("Acquire::ComprExtension", ".gz"); + } else { + Cnf.Set("Dir::Etc::RpmPriorities", "rpmpriorities"); + Cnf.Set("Dir::bin::gzip","/usr/bin/bzip2"); + Cnf.Set("Dir::Bin::rpm","/bin/rpm"); + Cnf.Set("Acquire::ComprExtension", ".bz2"); + } + + // Read the main config file + string FName = Cnf.FindFile("Dir::Etc::main"); + bool Res = true; + if (FileExists(FName) == true) + Res &= ReadConfigFile(Cnf,FName); + + // Read an alternate config file + const char *Cfg = getenv("APT_CONFIG"); + if (Cfg != 0 && FileExists(Cfg) == true) + Res &= ReadConfigFile(Cnf,Cfg); + + if (Res == false) + return false; + + if (Cnf.FindB("Debug::pkgInitialize",false) == true) + Cnf.Dump(); + + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/init.h b/apt/apt-pkg/init.h new file mode 100644 index 0000000..4f76764 --- /dev/null +++ b/apt/apt-pkg/init.h @@ -0,0 +1,21 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: init.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Init - Initialize the package library + + This function must be called to configure the config class before + calling many APT library functions. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_INIT_H +#define PKGLIB_INIT_H + +#include + +bool pkgInitialize(Configuration &Cnf); + +#endif diff --git a/apt/apt-pkg/makefile b/apt/apt-pkg/makefile new file mode 100644 index 0000000..6ec3936 --- /dev/null +++ b/apt/apt-pkg/makefile @@ -0,0 +1,61 @@ +# -*- make -*- +BASE=.. +SUBDIR=apt-pkg + +# Header location +SUBDIRS = rpm deb contrib +HEADER_TARGETDIRS = apt-pkg + +# Bring in the default rules +include ../buildlib/defaults.mak + +# The library name +LIBRARY=apt-pkg +MAJOR=3.1 +MINOR=0 +SLIBS=$(PTHREADLIB) + +# Source code for the contributed non-core things +SOURCE = contrib/mmap.cc contrib/error.cc contrib/strutl.cc \ + contrib/configuration.cc contrib/progress.cc contrib/cmndline.cc \ + contrib/md5.cc contrib/cdromutl.cc contrib/crc-16.cc + +# Source code for the main library +SOURCE+= pkgcache.cc version.cc fileutl.cc pkgcachegen.cc depcache.cc \ + orderlist.cc tagfile.cc sourcelist.cc packagemanager.cc \ + pkgrecords.cc algorithms.cc acquire.cc acquire-item.cc \ + acquire-worker.cc acquire-method.cc init.cc clean.cc \ + srcrecords.cc cachefile.cc systemfactory.cc + +# Source code for the debian specific components +SOURCE+= deb/deblistparser.cc deb/debrecords.cc deb/dpkgpm.cc deb/dpkginit.cc \ + deb/debsrcrecords.cc \ + deb/debfactory.cc + +# Source code for the rpm specific components +SOURCE+= rpm/rpminit.cc rpm/rpmlistparser.cc rpm/rpmpm.cc\ + rpm/rpmrecords.cc rpm/rpmsrcrecords.cc + +SOURCE+= rpm/rpmfactory.cc rpm/rpmversion.cc rpm/rpmpackagedata.cc + +# Public apt-pkg header files +HEADERS = algorithms.h depcache.h mmap.h pkgcachegen.h cacheiterators.h \ + error.h orderlist.h sourcelist.h configuration.h fileutl.h \ + packagemanager.h tagfile.h deblistparser.h init.h pkgcache.h \ + progress.h pkgrecords.h debrecords.h cmndline.h \ + acquire.h acquire-worker.h acquire-item.h acquire-method.h md5.h \ + dpkgpm.h dpkginit.h cdromutl.h strutl.h clean.h srcrecords.h \ + debsrcrecords.h cachefile.h crc-16.h systemfactory.h sptr.h + +HEADERS+= rpmfactory.h debfactory.h + +HEADERS+= rpminit.h rpmlistparser.h rpmpm.h rpmrecords.h rpmpackagedata.h\ + rpmsrcrecords.h + + +HEADERS := $(addprefix apt-pkg/,$(HEADERS)) + +# Private header files +HEADERS+= system.h i18n.h + +include $(LIBRARY_H) diff --git a/apt/apt-pkg/orderlist.cc b/apt/apt-pkg/orderlist.cc new file mode 100644 index 0000000..cbd7ac3 --- /dev/null +++ b/apt/apt-pkg/orderlist.cc @@ -0,0 +1,960 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: orderlist.cc,v 1.4 2000/10/26 21:15:21 kojima Exp $ +/* ###################################################################### + + Order List - Represents and Manipulates an ordered list of packages. + + A list of packages can be ordered by a number of conflicting criteria + each given a specific priority. Each package also has a set of flags + indicating some usefull things about it that are derived in the + course of sorting. The pkgPackageManager class uses this class for + all of it's installation ordering needs. + + This is a modified version of Manoj's Routine B. It consists of four + independent ordering algorithms that can be applied at for different + points in the ordering. By appling progressivly fewer ordering + operations it is possible to give each consideration it's own + priority and create an order that satisfies the lowest applicable + consideration. + + The rules for unpacking ordering are: + 1) Unpacking ignores Depends: on all packages + 2) Unpacking requires Conflicts: on -ALL- packages to be satisfied + 3) Unpacking requires PreDepends: on this package only to be satisfied + 4) Removing requires that no packages depend on the package to be + removed. + + And the rule for configuration ordering is: + 1) Configuring requires that the Depends: of the package be satisfied + Conflicts+PreDepends are ignored because unpacking says they are + already correct [exageration, it does check but we need not be + concerned] + + And some features that are valuable for unpacking ordering. + f1) Unpacking a new package should advoid breaking dependencies of + configured packages + f2) Removal should not require a force, corrolory of f1 + f3) Unpacking should order by depends rather than fall back to random + ordering. + + Each of the features can be enabled in the sorting routine at an + arbitary priority to give quite abit of control over the final unpacking + order. + + The rules listed above may never be violated and are called Critical. + When a critical rule is violated then a loop condition is recorded + and will have to be delt with in the caller. + + The ordering keeps two lists, the main list and the 'After List'. The + purpose of the after list is to allow packages to be delayed. This is done + by setting the after flag on the package. Any package which requires this + package to be ordered before will inherit the after flag and so on. This + is used for CD swap ordering where all packages on a second CD have the + after flag set. This forces them and all their dependents to be ordered + toward the end. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/orderlist.h" +#endif +#include +#include +#include + /*}}}*/ + +pkgOrderList *pkgOrderList::Me = 0; + +// OrderList::pkgOrderList - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgOrderList::pkgOrderList(pkgDepCache &Cache) : Cache(Cache) +{ + FileList = 0; + Primary = 0; + Secondary = 0; + RevDepends = 0; + Remove = 0; + LoopCount = -1; + + /* Construct the arrays, egcs 1.0.1 bug requires the package count + hack */ + unsigned long Size = Cache.HeaderP->PackageCount; + Flags = new unsigned short[Size]; + End = List = new Package *[Size]; + memset(Flags,0,sizeof(*Flags)*Size); +} + /*}}}*/ +// OrderList::~pkgOrderList - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgOrderList::~pkgOrderList() +{ + delete [] List; + delete [] Flags; +} + /*}}}*/ +// OrderList::IsMissing - Check if a file is missing /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgOrderList::IsMissing(PkgIterator Pkg) +{ + // Skip packages to erase + if (Cache[Pkg].Delete() == true) + return false; + + // Skip Packages that need configure only. + if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + Cache[Pkg].Keep() == true) + return false; + + if (FileList != 0 && FileList[Pkg->ID].empty() == false) + return false; + return true; +} + /*}}}*/ + +// OrderList::DoRun - Does an order run /*{{{*/ +// --------------------------------------------------------------------- +/* The caller is expeted to have setup the desired probe state */ +bool pkgOrderList::DoRun() +{ + // Temp list + unsigned long Size = Cache.HeaderP->PackageCount; + Package **NList = new Package *[Size]; + AfterList = new Package *[Size]; + AfterEnd = AfterList; + + Depth = 0; + WipeFlags(Added | AddPending | Loop | InList); + + for (iterator I = List; I != End; I++) + Flag(*I,InList); + + // Rebuild the main list into the temp list. + iterator OldEnd = End; + End = NList; + for (iterator I = List; I != OldEnd; I++) + if (VisitNode(PkgIterator(Cache,*I)) == false) + { + End = OldEnd; + delete [] NList; + delete [] AfterList; + return false; + } + + // Copy the after list to the end of the main list + for (Package **I = AfterList; I != AfterEnd; I++) + *End++ = *I; + + // Swap the main list to the new list + delete [] List; + delete [] AfterList; + List = NList; + return true; +} + /*}}}*/ +// OrderList::OrderCritical - Perform critical unpacking ordering /*{{{*/ +// --------------------------------------------------------------------- +/* This performs predepends and immediate configuration ordering only. + This is termed critical unpacking ordering. Any loops that form are + fatal and indicate that the packages cannot be installed. */ +bool pkgOrderList::OrderCritical() +{ + FileList = 0; + + Primary = &pkgOrderList::DepUnPackPre; + Secondary = 0; + RevDepends = 0; + Remove = 0; + LoopCount = 0; + + // Sort + Me = this; + qsort(List,End - List,sizeof(*List),&OrderCompareB); + + if (DoRun() == false) + return false; + + if (LoopCount != 0) + return _error->Error("Fatal, predepends looping detected"); + return true; +} + /*}}}*/ +// OrderList::OrderUnpack - Perform complete unpacking ordering /*{{{*/ +// --------------------------------------------------------------------- +/* This performs complete unpacking ordering and creates an order that is + suitable for unpacking */ +bool pkgOrderList::OrderUnpack(string *FileList) +{ + this->FileList = FileList; + + // Setup the after flags + if (FileList != 0) + { + WipeFlags(After); + + // Set the inlist flag + for (iterator I = List; I != End; I++) + { + PkgIterator P(Cache,*I); + if (IsMissing(P) == true && IsNow(P) == true) + Flag(*I,After); + } + } + + Primary = &pkgOrderList::DepUnPackCrit; + Secondary = &pkgOrderList::DepConfigure; + RevDepends = &pkgOrderList::DepUnPackDep; + Remove = &pkgOrderList::DepRemove; + LoopCount = -1; + + // Sort + Me = this; + qsort(List,End - List,sizeof(*List),&OrderCompareA); + + if (DoRun() == false) + return false; + + Secondary = 0; + if (DoRun() == false) + return false; + + LoopCount = 0; + RevDepends = 0; + Remove = 0; // Otherwise the libreadline remove problem occures + if (DoRun() == false) + return false; + + LoopCount = 0; + Primary = &pkgOrderList::DepUnPackPre; + if (DoRun() == false) + return false; + +/* cout << "----------END" << endl; + + for (iterator I = List; I != End; I++) + { + PkgIterator P(Cache,*I); + if (IsNow(P) == true) + cout << P.Name() << ' ' << IsMissing(P) << ',' << IsFlag(P,After) << endl; + }*/ + + return true; +} + /*}}}*/ +// OrderList::OrderConfigure - Perform configuration ordering /*{{{*/ +// --------------------------------------------------------------------- +/* This orders by depends only and produces an order which is suitable + for configuration */ +bool pkgOrderList::OrderConfigure() +{ + FileList = 0; + Primary = &pkgOrderList::DepConfigure; + Secondary = 0; + RevDepends = 0; + Remove = 0; + LoopCount = -1; + return DoRun(); +} + /*}}}*/ + +// OrderList::Score - Score the package for sorting /*{{{*/ +// --------------------------------------------------------------------- +/* Higher scores order earlier */ +int pkgOrderList::Score(PkgIterator Pkg) +{ + // Removal is always done first + if (Cache[Pkg].Delete() == true) + return 200; + + // This should never happen.. + if (Cache[Pkg].InstVerIter(Cache).end() == true) + return -1; + + int Score = 0; + if ((Pkg->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential) + Score += 100; + + if (IsFlag(Pkg,Immediate) == true) + Score += 10; + + for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); + D.end() == false; D++) + if (D->Type == pkgCache::Dep::PreDepends) + { + Score += 50; + break; + } + + // Important Required Standard Optional Extra + signed short PrioMap[] = {0,5,4,3,1,0}; + if (Cache[Pkg].InstVerIter(Cache)->Priority <= 5) + Score += PrioMap[Cache[Pkg].InstVerIter(Cache)->Priority]; + return Score; +} + /*}}}*/ +// OrderList::FileCmp - Compare by package file /*{{{*/ +// --------------------------------------------------------------------- +/* This compares by the package file that the install version is in. */ +int pkgOrderList::FileCmp(PkgIterator A,PkgIterator B) +{ + if (Cache[A].Delete() == true && Cache[B].Delete() == true) + return 0; + if (Cache[A].Delete() == true) + return -1; + if (Cache[B].Delete() == true) + return 1; + + if (Cache[A].InstVerIter(Cache).FileList().end() == true) + return -1; + if (Cache[B].InstVerIter(Cache).FileList().end() == true) + return 1; + + pkgCache::PackageFile *FA = Cache[A].InstVerIter(Cache).FileList().File(); + pkgCache::PackageFile *FB = Cache[B].InstVerIter(Cache).FileList().File(); + if (FA < FB) + return -1; + if (FA > FB) + return 1; + return 0; +} + /*}}}*/ +// BoolCompare - Comparison function for two booleans /*{{{*/ +// --------------------------------------------------------------------- +/* */ +static int BoolCompare(bool A,bool B) +{ + if (A == B) + return 0; + if (A == false) + return -1; + return 1; +} + /*}}}*/ +// OrderList::OrderCompareA - Order the installation by op /*{{{*/ +// --------------------------------------------------------------------- +/* This provides a first-pass sort of the list and gives a decent starting + point for further complete ordering. It is used by OrderUnpack only */ +int pkgOrderList::OrderCompareA(const void *a, const void *b) +{ + PkgIterator A(Me->Cache,*(Package **)a); + PkgIterator B(Me->Cache,*(Package **)b); + + // We order packages with a set state toward the front + int Res; + if ((Res = BoolCompare(Me->IsNow(A),Me->IsNow(B))) != 0) + return -1*Res; + + // We order missing files to toward the end +/* if (Me->FileList != 0) + { + if ((Res = BoolCompare(Me->IsMissing(A), + Me->IsMissing(B))) != 0) + return Res; + }*/ + + if (A.State() != pkgCache::PkgIterator::NeedsNothing && + B.State() == pkgCache::PkgIterator::NeedsNothing) + return -1; + + if (A.State() == pkgCache::PkgIterator::NeedsNothing && + B.State() != pkgCache::PkgIterator::NeedsNothing) + return 1; + + int ScoreA = Me->Score(A); + int ScoreB = Me->Score(B); + if (ScoreA > ScoreB) + return -1; + + if (ScoreA < ScoreB) + return 1; + + return strcmp(A.Name(),B.Name()); +} + /*}}}*/ +// OrderList::OrderCompareB - Order the installation by source /*{{{*/ +// --------------------------------------------------------------------- +/* This orders by installation source. This is usefull to handle + inter-source breaks */ +int pkgOrderList::OrderCompareB(const void *a, const void *b) +{ + PkgIterator A(Me->Cache,*(Package **)a); + PkgIterator B(Me->Cache,*(Package **)b); + + if (A.State() != pkgCache::PkgIterator::NeedsNothing && + B.State() == pkgCache::PkgIterator::NeedsNothing) + return -1; + + if (A.State() == pkgCache::PkgIterator::NeedsNothing && + B.State() != pkgCache::PkgIterator::NeedsNothing) + return 1; + + int F = Me->FileCmp(A,B); + if (F != 0) + { + if (F > 0) + return -1; + return 1; + } + + int ScoreA = Me->Score(A); + int ScoreB = Me->Score(B); + if (ScoreA > ScoreB) + return -1; + + if (ScoreA < ScoreB) + return 1; + + return strcmp(A.Name(),B.Name()); +} + /*}}}*/ + +// OrderList::VisitDeps - Visit forward install dependencies /*{{{*/ +// --------------------------------------------------------------------- +/* This calls the dependency function for the normal forwards dependencies + of the package */ +bool pkgOrderList::VisitDeps(DepFunc F,PkgIterator Pkg) +{ + if (F == 0 || Pkg.end() == true || Cache[Pkg].InstallVer == 0) + return true; + + return (this->*F)(Cache[Pkg].InstVerIter(Cache).DependsList()); +} + /*}}}*/ +// OrderList::VisitRDeps - Visit reverse dependencies /*{{{*/ +// --------------------------------------------------------------------- +/* This calls the dependency function for all of the normal reverse depends + of the package */ +bool pkgOrderList::VisitRDeps(DepFunc F,PkgIterator Pkg) +{ + if (F == 0 || Pkg.end() == true) + return true; + + return (this->*F)(Pkg.RevDependsList()); +} + /*}}}*/ +// OrderList::VisitRProvides - Visit provides reverse dependencies /*{{{*/ +// --------------------------------------------------------------------- +/* This calls the dependency function for all reverse dependencies + generated by the provides line on the package. */ +bool pkgOrderList::VisitRProvides(DepFunc F,VerIterator Ver) +{ + if (F == 0 || Ver.end() == true) + return true; + + bool Res = true; + for (PrvIterator P = Ver.ProvidesList(); P.end() == false; P++) + Res &= (this->*F)(P.ParentPkg().RevDependsList()); + return true; +} + /*}}}*/ +// OrderList::VisitProvides - Visit all of the providing packages /*{{{*/ +// --------------------------------------------------------------------- +/* This routine calls visit on all providing packages. */ +bool pkgOrderList::VisitProvides(DepIterator D,bool Critical) +{ + Version **List = D.AllTargets(); + for (Version **I = List; *I != 0; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + if (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing) + continue; + + if (D->Type != pkgCache::Dep::Conflicts && D->Type != pkgCache::Dep::Obsoletes + && Cache[Pkg].InstallVer != *I) + continue; + + if ((D->Type == pkgCache::Dep::Conflicts || D->Type == pkgCache::Dep::Obsoletes) + && (Version *)Pkg.CurrentVer() != *I) + continue; + + // Skip over missing files + if (Critical == false && IsMissing(D.ParentPkg()) == true) + continue; + + if (VisitNode(Pkg) == false) + { + delete [] List; + return false; + } + } + delete [] List; + return true; +} + /*}}}*/ +// OrderList::VisitNode - Recursive ordering director /*{{{*/ +// --------------------------------------------------------------------- +/* This is the core ordering routine. It calls the set dependency + consideration functions which then potentialy call this again. Finite + depth is achived through the colouring mechinism. */ +bool pkgOrderList::VisitNode(PkgIterator Pkg) +{ + // Looping or irrelevent. + // This should probably trancend not installed packages + if (Pkg.end() == true || IsFlag(Pkg,Added) == true || + IsFlag(Pkg,AddPending) == true || IsFlag(Pkg,InList) == false) + return true; + +/* for (int j = 0; j != Depth; j++) cout << ' '; + cout << "Visit " << Pkg.Name() << endl;*/ + Depth++; + + // Color grey + Flag(Pkg,AddPending); + + DepFunc Old = Primary; + + // Perform immedate configuration of the package if so flagged. + if (IsFlag(Pkg,Immediate) == true && Primary != &pkgOrderList::DepUnPackPre) + Primary = &pkgOrderList::DepUnPackPreD; + + if (IsNow(Pkg) == true) + { + bool Res = true; + if (Cache[Pkg].Delete() == false) + { + // Primary + Res &= Res && VisitDeps(Primary,Pkg); + Res &= Res && VisitRDeps(Primary,Pkg); + Res &= Res && VisitRProvides(Primary,Pkg.CurrentVer()); + Res &= Res && VisitRProvides(Primary,Cache[Pkg].InstVerIter(Cache)); + + // RevDep + Res &= Res && VisitRDeps(RevDepends,Pkg); + Res &= Res && VisitRProvides(RevDepends,Pkg.CurrentVer()); + Res &= Res && VisitRProvides(RevDepends,Cache[Pkg].InstVerIter(Cache)); + + // Secondary + Res &= Res && VisitDeps(Secondary,Pkg); + Res &= Res && VisitRDeps(Secondary,Pkg); + Res &= Res && VisitRProvides(Secondary,Pkg.CurrentVer()); + Res &= Res && VisitRProvides(Secondary,Cache[Pkg].InstVerIter(Cache)); + } + else + { + // RevDep + Res &= Res && VisitRDeps(Remove,Pkg); + Res &= Res && VisitRProvides(Remove,Pkg.CurrentVer()); + } + } + + if (IsFlag(Pkg,Added) == false) + { + Flag(Pkg,Added,Added | AddPending); + if (IsFlag(Pkg,After) == true) + *AfterEnd++ = Pkg; + else + *End++ = Pkg; + } + + Primary = Old; + Depth--; + +/* for (int j = 0; j != Depth; j++) cout << ' '; + cout << "Leave " << Pkg.Name() << ' ' << IsFlag(Pkg,Added) << ',' << IsFlag(Pkg,AddPending) << endl;*/ + + return true; +} + /*}}}*/ + +// OrderList::DepUnPackCrit - Critical UnPacking ordering /*{{{*/ +// --------------------------------------------------------------------- +/* Critical unpacking ordering strives to satisfy Conflicts: and + PreDepends: only. When a prdepends is encountered the Primary + DepFunc is changed to be DepUnPackPreD. + + Loops are preprocessed and logged. */ +bool pkgOrderList::DepUnPackCrit(DepIterator D) +{ + for (; D.end() == false; D++) + { + if (D.Reverse() == true) + { + /* Reverse depenanices are only interested in conflicts, + predepend breakage is ignored here */ + if (D->Type != pkgCache::Dep::Conflicts && D->Type != pkgCache::Dep::Obsoletes) + continue; + + // Duplication elimination, consider only the current version + if (D.ParentPkg().CurrentVer() != D.ParentVer()) + continue; + + /* For reverse dependencies we wish to check if the + dependency is satisifed in the install state. The + target package (caller) is going to be in the installed + state. */ + if (CheckDep(D) == true) + continue; + + if (VisitNode(D.ParentPkg()) == false) + return false; + } + else + { + /* Forward critical dependencies MUST be correct before the + package can be unpacked. */ + if (D->Type != pkgCache::Dep::Conflicts && D->Type != pkgCache::Dep::Obsoletes && + D->Type != pkgCache::Dep::PreDepends) + continue; + + /* We wish to check if the dep is okay in the now state of the + target package against the install state of this package. */ + if (CheckDep(D) == true) + { + /* We want to catch predepends loops with the code below. + Conflicts loops that are Dep OK are ignored */ + if (IsFlag(D.TargetPkg(),AddPending) == false || + D->Type != pkgCache::Dep::PreDepends) + continue; + } + + // This is the loop detection + if (IsFlag(D.TargetPkg(),Added) == true || + IsFlag(D.TargetPkg(),AddPending) == true) + { + if (IsFlag(D.TargetPkg(),AddPending) == true) + AddLoop(D); + continue; + } + + /* Predepends require a special ordering stage, they must have + all dependents installed as well */ + DepFunc Old = Primary; + bool Res = false; + if (D->Type == pkgCache::Dep::PreDepends) + Primary = &pkgOrderList::DepUnPackPreD; + Res = VisitProvides(D,true); + Primary = Old; + if (Res == false) + return false; + } + } + return true; +} + /*}}}*/ +// OrderList::DepUnPackPreD - Critical UnPacking ordering with depends /*{{{*/ +// --------------------------------------------------------------------- +/* Critical PreDepends (also configure immediate and essential) strives to + ensure not only that all conflicts+predepends are met but that this + package will be immediately configurable when it is unpacked. + + Loops are preprocessed and logged. */ +bool pkgOrderList::DepUnPackPreD(DepIterator D) +{ + if (D.Reverse() == true) + return DepUnPackCrit(D); + + for (; D.end() == false; D++) + { + if (D.IsCritical() == false) + continue; + + /* We wish to check if the dep is okay in the now state of the + target package against the install state of this package. */ + if (CheckDep(D) == true) + { + /* We want to catch predepends loops with the code below. + Conflicts loops that are Dep OK are ignored */ + if (IsFlag(D.TargetPkg(),AddPending) == false || + D->Type != pkgCache::Dep::PreDepends) + continue; + } + + // This is the loop detection + if (IsFlag(D.TargetPkg(),Added) == true || + IsFlag(D.TargetPkg(),AddPending) == true) + { + if (IsFlag(D.TargetPkg(),AddPending) == true) + AddLoop(D); + continue; + } + + if (VisitProvides(D,true) == false) + return false; + } + return true; +} + /*}}}*/ +// OrderList::DepUnPackPre - Critical Predepends ordering /*{{{*/ +// --------------------------------------------------------------------- +/* Critical PreDepends (also configure immediate and essential) strives to + ensure not only that all conflicts+predepends are met but that this + package will be immediately configurable when it is unpacked. + + Loops are preprocessed and logged. All loops will be fatal. */ +bool pkgOrderList::DepUnPackPre(DepIterator D) +{ + if (D.Reverse() == true) + return true; + + for (; D.end() == false; D++) + { + /* Only consider the PreDepends or Depends. Depends are only + considered at the lowest depth or in the case of immediate + configure */ + if (D->Type != pkgCache::Dep::PreDepends) + { + if (D->Type == pkgCache::Dep::Depends) + { + if (Depth == 1 && IsFlag(D.ParentPkg(),Immediate) == false) + continue; + } + else + continue; + } + + /* We wish to check if the dep is okay in the now state of the + target package against the install state of this package. */ + if (CheckDep(D) == true) + { + /* We want to catch predepends loops with the code below. + Conflicts loops that are Dep OK are ignored */ + if (IsFlag(D.TargetPkg(),AddPending) == false) + continue; + } + + // This is the loop detection + if (IsFlag(D.TargetPkg(),Added) == true || + IsFlag(D.TargetPkg(),AddPending) == true) + { + if (IsFlag(D.TargetPkg(),AddPending) == true) + AddLoop(D); + continue; + } + + if (VisitProvides(D,true) == false) + return false; + } + return true; +} + /*}}}*/ +// OrderList::DepUnPackDep - Reverse dependency considerations /*{{{*/ +// --------------------------------------------------------------------- +/* Reverse dependencies are considered to determine if unpacking this + package will break any existing dependencies. If so then those + packages are ordered before this one so that they are in the + UnPacked state. + + The forwards depends loop is designed to bring the packages dependents + close to the package. This helps reduce deconfigure time. + + Loops are irrelevent to this. */ +bool pkgOrderList::DepUnPackDep(DepIterator D) +{ + + for (; D.end() == false; D++) + if (D.IsCritical() == true) + { + if (D.Reverse() == true) + { + /* Duplication prevention. We consider rev deps only on + the current version, a not installed package + cannot break */ + if (D.ParentPkg()->CurrentVer == 0 || + D.ParentPkg().CurrentVer() != D.ParentVer()) + continue; + + // The dep will not break so it is irrelevent. + if (CheckDep(D) == true) + continue; + + // Skip over missing files + if (IsMissing(D.ParentPkg()) == true) + continue; + + if (VisitNode(D.ParentPkg()) == false) + return false; + } + else + if (D->Type == pkgCache::Dep::Depends) + if (VisitProvides(D,false) == false) + return false; + } + return true; +} + /*}}}*/ +// OrderList::DepConfigure - Configuration ordering /*{{{*/ +// --------------------------------------------------------------------- +/* Configuration only ordering orders by the Depends: line only. It + orders configuration so that when a package comes to be configured it's + dependents are configured. + + Loops are ingored. Depends loop entry points are chaotic. */ +bool pkgOrderList::DepConfigure(DepIterator D) +{ + // Never consider reverse configuration dependencies. + if (D.Reverse() == true) + return true; + + for (; D.end() == false; D++) + if (D->Type == pkgCache::Dep::Depends) + if (VisitProvides(D,false) == false) + return false; + return true; +} + /*}}}*/ +// OrderList::DepRemove - Removal ordering /*{{{*/ +// --------------------------------------------------------------------- +/* Removal visits all reverse depends. It considers if the dependency + of the Now state version to see if it is okay with removing this + package. This check should always fail, but is provided for symetery + with the other critical handlers. + + Loops are preprocessed and logged. Removal loops can also be + detected in the critical handler. They are characterized by an + old version of A depending on B but the new version of A conflicting + with B, thus either A or B must break to install. */ +bool pkgOrderList::DepRemove(DepIterator D) +{ + if (D.Reverse() == false) + return true; + for (; D.end() == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + { + // Duplication elimination, consider the current version only + if (D.ParentPkg().CurrentVer() != D.ParentVer()) + continue; + + /* We wish to see if the dep on the parent package is okay + in the removed (install) state of the target pkg. */ + if (CheckDep(D) == true) + { + // We want to catch loops with the code below. + if (IsFlag(D.ParentPkg(),AddPending) == false) + continue; + } + + // This is the loop detection + if (IsFlag(D.ParentPkg(),Added) == true || + IsFlag(D.ParentPkg(),AddPending) == true) + { + if (IsFlag(D.ParentPkg(),AddPending) == true) + AddLoop(D); + continue; + } + + // Skip over missing files + if (IsMissing(D.ParentPkg()) == true) + continue; + + if (VisitNode(D.ParentPkg()) == false) + return false; + } + + return true; +} + /*}}}*/ + +// OrderList::AddLoop - Add a loop to the loop list /*{{{*/ +// --------------------------------------------------------------------- +/* We record the loops. This is a relic since loop breaking is done + genericaly as part of the safety routines. */ +bool pkgOrderList::AddLoop(DepIterator D) +{ + if (LoopCount < 0 || LoopCount >= 20) + return false; + + // Skip dups + if (LoopCount != 0) + { + if (Loops[LoopCount - 1].ParentPkg() == D.ParentPkg() || + Loops[LoopCount - 1].TargetPkg() == D.ParentPkg()) + return true; + } + + Loops[LoopCount++] = D; + + // Mark the packages as being part of a loop. + Flag(D.TargetPkg(),Loop); + Flag(D.ParentPkg(),Loop); + return true; +} + /*}}}*/ +// OrderList::WipeFlags - Unset the given flags from all packages /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgOrderList::WipeFlags(unsigned long F) +{ + unsigned long Size = Cache.HeaderP->PackageCount; + for (unsigned long I = 0; I != Size; I++) + Flags[I] &= ~F; +} + /*}}}*/ +// OrderList::CheckDep - Check a dependency for truth /*{{{*/ +// --------------------------------------------------------------------- +/* This performs a complete analysis of the dependency wrt to the + current add list. It returns true if after all events are + performed it is still true. This sort of routine can be approximated + by examining the DepCache, however in convoluted cases of provides + this fails to produce a suitable result. */ +bool pkgOrderList::CheckDep(DepIterator D) +{ + Version **List = D.AllTargets(); + bool Hit = false; + for (Version **I = List; *I != 0; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + /* The meaning of Added and AddPending is subtle. AddPending is + an indication that the package is looping. Because of the + way ordering works Added means the package will be unpacked + before this one and AddPending means after. It is therefore + correct to ignore AddPending in all cases, but that exposes + reverse-ordering loops which should be ignored. */ + if (IsFlag(Pkg,Added) == true || + (IsFlag(Pkg,AddPending) == true && D.Reverse() == true)) + { + if (Cache[Pkg].InstallVer != *I) + continue; + } + else + if ((Version *)Pkg.CurrentVer() != *I || + Pkg.State() != PkgIterator::NeedsNothing) + continue; + + /* Conflicts requires that all versions are not present, depends + just needs one */ + if (D->Type != pkgCache::Dep::Conflicts && D->Type != pkgCache::Dep::Obsoletes) + { + /* Try to find something that does not have the after flag set + if at all possible */ + if (IsFlag(Pkg,After) == true) + { + Hit = true; + continue; + } + + delete [] List; + return true; + } + else + { + if (IsFlag(Pkg,After) == true) + Flag(D.ParentPkg(),After); + + delete [] List; + return false; + } + } + delete [] List; + + // We found a hit, but it had the after flag set + if (Hit == true && D->Type == pkgCache::Dep::PreDepends) + { + Flag(D.ParentPkg(),After); + return true; + } + + /* Conflicts requires that all versions are not present, depends + just needs one */ + if (D->Type == pkgCache::Dep::Conflicts || D->Type == pkgCache::Dep::Obsoletes) + return true; + return false; +} + /*}}}*/ diff --git a/apt/apt-pkg/orderlist.h b/apt/apt-pkg/orderlist.h new file mode 100644 index 0000000..caca764 --- /dev/null +++ b/apt/apt-pkg/orderlist.h @@ -0,0 +1,129 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: orderlist.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Order List - Represents and Manipulates an ordered list of packages. + + A list of packages can be ordered by a number of conflicting criteria + each given a specific priority. Each package also has a set of flags + indicating some usefull things about it that are derived in the + course of sorting. The pkgPackageManager class uses this class for + all of it's installation ordering needs. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_ORDERLIST_H +#define PKGLIB_ORDERLIST_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/orderlist.h" +#endif + +#include + +class pkgDepCache; +class pkgOrderList +{ + protected: + + pkgDepCache &Cache; + + // Bring some usefull types into the local scope + typedef pkgCache::PkgIterator PkgIterator; + typedef pkgCache::VerIterator VerIterator; + typedef pkgCache::DepIterator DepIterator; + typedef pkgCache::PrvIterator PrvIterator; + typedef pkgCache::Package Package; + typedef pkgCache::Version Version; + typedef bool (pkgOrderList::*DepFunc)(DepIterator D); + + // These are the currently selected ordering functions + DepFunc Primary; + DepFunc Secondary; + DepFunc RevDepends; + DepFunc Remove; + + // State + Package **End; + Package **List; + Package **AfterList; + Package **AfterEnd; + string *FileList; + DepIterator Loops[20]; + int LoopCount; + int Depth; + unsigned short *Flags; + + // Main visit function + bool VisitNode(PkgIterator Pkg); + bool VisitDeps(DepFunc F,PkgIterator Pkg); + bool VisitRDeps(DepFunc F,PkgIterator Pkg); + bool VisitRProvides(DepFunc F,VerIterator Ver); + bool VisitProvides(DepIterator Pkg,bool Critical); + + // Dependency checking functions. + bool DepUnPackCrit(DepIterator D); + bool DepUnPackPreD(DepIterator D); + bool DepUnPackPre(DepIterator D); + bool DepUnPackDep(DepIterator D); + bool DepConfigure(DepIterator D); + bool DepRemove(DepIterator D); + + // Analysis helpers + bool AddLoop(DepIterator D); + bool CheckDep(DepIterator D); + bool DoRun(); + + // For pre sorting + static pkgOrderList *Me; + static int OrderCompareA(const void *a, const void *b); + static int OrderCompareB(const void *a, const void *b); + int FileCmp(PkgIterator A,PkgIterator B); + + public: + + typedef Package **iterator; + + // State flags + enum Flags {Added = (1 << 0), AddPending = (1 << 1), + Immediate = (1 << 2), Loop = (1 << 3), + UnPacked = (1 << 4), Configured = (1 << 5), + Removed = (1 << 6), // Early Remove + InList = (1 << 7), + After = (1 << 8), + States = (UnPacked | Configured | Removed)}; + + // Flag manipulators + inline bool IsFlag(PkgIterator Pkg,unsigned long F) {return (Flags[Pkg->ID] & F) == F;}; + inline bool IsFlag(Package *Pkg,unsigned long F) {return (Flags[Pkg->ID] & F) == F;}; + void Flag(PkgIterator Pkg,unsigned long State, unsigned long F) {Flags[Pkg->ID] = (Flags[Pkg->ID] & (~F)) | State;}; + inline void Flag(PkgIterator Pkg,unsigned long F) {Flags[Pkg->ID] |= F;}; + inline void Flag(Package *Pkg,unsigned long F) {Flags[Pkg->ID] |= F;}; + inline bool IsNow(PkgIterator Pkg) {return (Flags[Pkg->ID] & (States & (~Removed))) == 0;}; + bool IsMissing(PkgIterator Pkg); + void WipeFlags(unsigned long F); + void SetFileList(string *FileList) {this->FileList = FileList;}; + + // Accessors + inline iterator begin() {return List;}; + inline iterator end() {return End;}; + inline void push_back(Package *Pkg) {*(End++) = Pkg;}; + inline void push_back(PkgIterator Pkg) {*(End++) = Pkg;}; + inline void pop_back() {End--;}; + inline bool empty() {return End == List;}; + inline unsigned int size() {return End - List;}; + + // Ordering modes + bool OrderCritical(); + bool OrderUnpack(string *FileList = 0); + bool OrderConfigure(); + + int Score(PkgIterator Pkg); + + pkgOrderList(pkgDepCache &Cache); + ~pkgOrderList(); +}; + +#endif diff --git a/apt/apt-pkg/packagemanager.cc b/apt/apt-pkg/packagemanager.cc new file mode 100644 index 0000000..dd5972d --- /dev/null +++ b/apt/apt-pkg/packagemanager.cc @@ -0,0 +1,671 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: packagemanager.cc,v 1.15 2001/11/13 17:32:07 kojima Exp $ +/* ###################################################################### + + Package Manager - Abstacts the package manager + + More work is needed in the area of transitioning provides, ie exim + replacing smail. This can cause interesing side effects. + + Other cases involving conflicts+replaces should be tested. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/packagemanager.h" +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + /*}}}*/ + +// PM::PackageManager - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgPackageManager::pkgPackageManager(pkgDepCache &Cache) : Cache(Cache) +{ + FileNames = new string[Cache.Head().PackageCount]; + List = 0; + Debug = _config->FindB("Debug::pkgPackageManager",false); +} + /*}}}*/ +// PM::PackageManager - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgPackageManager::~pkgPackageManager() +{ + delete List; + delete [] FileNames; +} + /*}}}*/ +// PM::GetArchives - Queue the archives for download /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgPackageManager::GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, + pkgRecords *Recs) +{ + if (CreateOrderList() == false) + return false; + + if (List->OrderUnpack() == false) + return _error->Error("Internal ordering error"); + + for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + { + PkgIterator Pkg(Cache,*I); + FileNames[Pkg->ID] = string(); + + // Skip packages to erase + if (Cache[Pkg].Delete() == true) + continue; + + // Skip Packages that need configure only. + if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + Cache[Pkg].Keep() == true) + continue; + + // Skip already processed packages + if (List->IsNow(Pkg) == false) + continue; + + new pkgAcqArchive(Owner,Sources,Recs,Cache[Pkg].InstVerIter(Cache), + FileNames[Pkg->ID]); + } + + return true; +} + /*}}}*/ +// PM::FixMissing - Keep all missing packages /*{{{*/ +// --------------------------------------------------------------------- +/* This is called to correct the installation when packages could not + be downloaded. */ +bool pkgPackageManager::FixMissing() +{ + pkgProblemResolver Resolve(Cache); + List->SetFileList(FileNames); + + bool Bad = false; + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + if (List->IsMissing(I) == false) + continue; + + // Okay, this file is missing and we need it. Mark it for keep + Bad = true; + Cache.MarkKeep(I); + } + + // We have to empty the list otherwise it will not have the new changes + delete List; + List = 0; + + if (Bad == false) + return true; + + // Now downgrade everything that is broken + return Resolve.ResolveByKeep() == true && Cache.BrokenCount() == 0; +} + /*}}}*/ + +// PM::CreateOrderList - Create the ordering class /*{{{*/ +// --------------------------------------------------------------------- +/* This populates the ordering list with all the packages that are + going to change. */ +bool pkgPackageManager::CreateOrderList() +{ + if (List != 0) + return true; + + delete List; + List = new pkgOrderList(Cache); + + bool NoImmConfigure = _config->FindB("APT::Immediate-Configure",false); + + // Generate the list of affected packages and sort it + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + // Mark the package and its dependends for immediate configuration + if (((I->Flags & pkgCache::Flag::Essential) == pkgCache::Flag::Essential || + (I->Flags & pkgCache::Flag::Important) == pkgCache::Flag::Important) && + NoImmConfigure == false) + { + List->Flag(I,pkgOrderList::Immediate); + + // Look for other packages to make immediate configurea + if (Cache[I].InstallVer != 0) + for (DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); + D.end() == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + List->Flag(D.TargetPkg(),pkgOrderList::Immediate); + + // And again with the current version. + if (I->CurrentVer != 0) + for (DepIterator D = I.CurrentVer().DependsList(); + D.end() == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + List->Flag(D.TargetPkg(),pkgOrderList::Immediate); + } + + // Not interesting + if ((Cache[I].Keep() == true || + Cache[I].InstVerIter(Cache) == I.CurrentVer()) && + I.State() == pkgCache::PkgIterator::NeedsNothing && + (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall && + (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete || + (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge)) + continue; + + // Append it to the list + List->push_back(I); + } + + return true; +} + /*}}}*/ +// PM::DepAlwaysTrue - Returns true if this dep is irrelevent /*{{{*/ +// --------------------------------------------------------------------- +/* The restriction on provides is to eliminate the case when provides + are transitioning between valid states [ie exim to smail] */ +bool pkgPackageManager::DepAlwaysTrue(DepIterator D) +{ + if (D.TargetPkg()->ProvidesList != 0) + return false; + + if ((Cache[D] & pkgDepCache::DepInstall) != 0 && + (Cache[D] & pkgDepCache::DepNow) != 0) + return true; + return false; +} + /*}}}*/ +// PM::CheckRConflicts - Look for reverse conflicts /*{{{*/ +// --------------------------------------------------------------------- +/* This looks over the reverses for a conflicts line that needs early + removal. */ +bool pkgPackageManager::CheckRConflicts(PkgIterator Pkg,DepIterator D, + const char *Ver) +{ + for (;D.end() == false; D++) + { + if (D->Type != pkgCache::Dep::Conflicts && D->Type != pkgCache::Dep::Obsoletes) + continue; + + // The package hasnt been changed + if (List->IsNow(Pkg) == false) + continue; + + // Ignore self conflicts, ignore conflicts from irrelevent versions + if (D.ParentPkg() == Pkg || D.ParentVer() != D.ParentPkg().CurrentVer()) + continue; + + if (_system->checkDep(D.TargetVer(),Ver,D->CompareOp) == false) + continue; + + if (EarlyRemove(D.ParentPkg()) == false) + return _error->Error("Reverse conflicts early remove for package '%s' failed", + Pkg.Name()); + } + return true; +} + /*}}}*/ +// PM::ConfigureAll - Run the all out configuration /*{{{*/ +// --------------------------------------------------------------------- +/* This configures every package. It is assumed they are all unpacked and + that the final configuration is valid. */ +bool pkgPackageManager::ConfigureAll() +{ + pkgOrderList OList(Cache); + + // Populate the order list + for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + if (List->IsFlag(pkgCache::PkgIterator(Cache,*I), + pkgOrderList::UnPacked) == true) + OList.push_back(*I); + + if (OList.OrderConfigure() == false) + return false; + + // Perform the configuring + for (pkgOrderList::iterator I = OList.begin(); I != OList.end(); I++) + { + PkgIterator Pkg(Cache,*I); + + if (Configure(Pkg) == false) + return false; + + List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); + } + + return true; +} + /*}}}*/ +// PM::SmartConfigure - Perform immediate configuration of the pkg /*{{{*/ +// --------------------------------------------------------------------- +/* This routine scheduals the configuration of the given package and all + of it's dependents. */ +bool pkgPackageManager::SmartConfigure(PkgIterator Pkg) +{ + pkgOrderList OList(Cache); + + if (DepAdd(OList,Pkg) == false) { + cout<<"AAA"<Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); + } + + // Sanity Check + if (List->IsFlag(Pkg,pkgOrderList::Configured) == false) { + cout<<"DDD"<Error("Internal error, could not immediate configure %s",Pkg.Name()); + } + return true; +} + /*}}}*/ +// PM::DepAdd - Add all dependents to the oder list /*{{{*/ +// --------------------------------------------------------------------- +/* This recursively adds all dependents to the order list */ +bool pkgPackageManager::DepAdd(pkgOrderList &OList,PkgIterator Pkg,int Depth) +{ + if (OList.IsFlag(Pkg,pkgOrderList::Added) == true) + return true; + if (List->IsFlag(Pkg,pkgOrderList::Configured) == true) + return true; + if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == false) + return false; + + + // Put the package on the list + OList.push_back(Pkg); + OList.Flag(Pkg,pkgOrderList::Added); + Depth++; + + // Check the dependencies to see if they are all satisfied. + bool Bad = false; + for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); D.end() == false;) + { + if (D->Type != pkgCache::Dep::Depends && D->Type != pkgCache::Dep::PreDepends) + { + D++; + continue; + } + + // Grok or groups + Bad = true; + for (bool LastOR = true; D.end() == false && LastOR == true; D++) + { + LastOR = (D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + + if (Bad == false) + continue; + + Version **VList = D.AllTargets(); + for (Version **I = VList; *I != 0 && Bad == true; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + // See if the current version is ok + if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && + Pkg.State() == PkgIterator::NeedsNothing) + { + Bad = false; + continue; + } + + // Not the install version + if (Cache[Pkg].InstallVer != *I || + (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) + continue; + if (List->IsFlag(Pkg,pkgOrderList::UnPacked) == true) + Bad = !DepAdd(OList,Pkg,Depth); + if (List->IsFlag(Pkg,pkgOrderList::Configured) == true) + Bad = false; + } + delete [] VList; + } + + if (Bad == true) + { + OList.Flag(Pkg,0,pkgOrderList::Added); + OList.pop_back(); + Depth--; + return false; + } + } + + Depth--; + return true; +} + /*}}}*/ +// PM::EarlyRemove - Perform removal of packages before their time /*{{{*/ +// --------------------------------------------------------------------- +/* This is called to deal with conflicts arising from unpacking */ +bool pkgPackageManager::EarlyRemove(PkgIterator Pkg) +{ + if (List->IsNow(Pkg) == false) + return true; + + // Already removed it + if (List->IsFlag(Pkg,pkgOrderList::Removed) == true) + return true; + + // Woops, it will not be re-installed! + if (List->IsFlag(Pkg,pkgOrderList::InList) == false) + return false; + + // Essential packages get special treatment + bool IsEssential = false; + if ((Pkg->Flags & pkgCache::Flag::Essential) != 0) + IsEssential = true; + + /* Check for packages that are the dependents of essential packages and + promote them too */ + if (Pkg->CurrentVer != 0) + { + for (DepIterator D = Pkg.RevDependsList(); D.end() == false && + IsEssential == false; D++) + if (D->Type == pkgCache::Dep::Depends || D->Type == pkgCache::Dep::PreDepends) + if ((D.ParentPkg()->Flags & pkgCache::Flag::Essential) != 0) + IsEssential = true; + } + + if (IsEssential == true) + { + if (_config->FindB("APT::Force-LoopBreak",false) == false) + return _error->Error(_("This installation run will require temporarily " + "removing the essential package %s due to a " + "Conflicts/Pre-Depends loop. This is often bad, " + "but if you really want to do it, activate the " + "APT::Force-LoopBreak option."),Pkg.Name()); + } + + bool Res = SmartRemove(Pkg); + if (Cache[Pkg].Delete() == false) + List->Flag(Pkg,pkgOrderList::Removed,pkgOrderList::States); + + return Res; +} + /*}}}*/ +// PM::SmartRemove - Removal Helper /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgPackageManager::SmartRemove(PkgIterator Pkg) +{ + if (List->IsNow(Pkg) == false) + return true; + + List->Flag(Pkg,pkgOrderList::Configured,pkgOrderList::States); + if (Cache[Pkg].Replaced()) + return true; + return Remove(Pkg,(Cache[Pkg].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge); +} + /*}}}*/ +// PM::SmartUnPack - Install helper /*{{{*/ +// --------------------------------------------------------------------- +/* This performs the task of handling pre-depends. */ +bool pkgPackageManager::SmartUnPack(PkgIterator Pkg) +{ + // Check if it is already unpacked + if (Pkg.State() == pkgCache::PkgIterator::NeedsConfigure && + Cache[Pkg].Keep() == true) + { + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); + if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true) { + if (SmartConfigure(Pkg) == false) + return _error->Error("Internal Error, Could not perform immediate configuration: %s", + Pkg.Name()); + } + return true; + } + + /* See if this packages install version has any predependencies + that are not met by 'now' packages. */ + for (DepIterator D = Cache[Pkg].InstVerIter(Cache).DependsList(); + D.end() == false; ) + { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + + while (End->Type == pkgCache::Dep::PreDepends) + { + // Look for possible ok targets. + Version **VList = Start.AllTargets(); + bool Bad = true; + for (Version **I = VList; *I != 0 && Bad == true; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + // See if the current version is ok + if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && + Pkg.State() == PkgIterator::NeedsNothing) + { + Bad = false; + continue; + } + } + + // Look for something that could be configured. + for (Version **I = VList; *I != 0 && Bad == true; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + // Not the install version + if (Cache[Pkg].InstallVer != *I || + (Cache[Pkg].Keep() == true && Pkg.State() == PkgIterator::NeedsNothing)) + continue; + + Bad = !SmartConfigure(Pkg); + } + + delete [] VList; + + /* If this or element did not match then continue on to the + next or element until a matching element is found*/ + if (Bad == true) + { + if (Start == End) + return _error->Error("Internal Error, Couldn't configure a pre-depend: %s", + Pkg.Name()); + Start++; + } + else + break; + } + + if (End->Type == pkgCache::Dep::Conflicts || End->Type == pkgCache::Dep::Obsoletes) + { + /* Look for conflicts. Two packages that are both in the install + state cannot conflict so we don't check.. */ + Version **VList = End.AllTargets(); + for (Version **I = VList; *I != 0; I++) + { + VerIterator Ver(Cache,*I); + PkgIterator Pkg = Ver.ParentPkg(); + + // See if the current version is conflicting + // and that it's not obsoleting a virtual package + if (Pkg.CurrentVer() == Ver && List->IsNow(Pkg) == true && + !(Pkg->ProvidesList == 0 && End->Type == pkgCache::Dep::Obsoletes)) + { + if (EarlyRemove(Pkg) == false) + return _error->Error("Internal Error, Could not early remove %s",Pkg.Name()); + } + } + delete [] VList; + } + } + + // Check for reverse conflicts. + if (CheckRConflicts(Pkg,Pkg.RevDependsList(), + Cache[Pkg].InstVerIter(Cache).VerStr()) == false) + return false; + + for (PrvIterator P = Cache[Pkg].InstVerIter(Cache).ProvidesList(); + P.end() == false; P++) + CheckRConflicts(Pkg,P.ParentPkg().RevDependsList(),P.ProvideVersion()); + + if (Install(Pkg,FileNames[Pkg->ID]) == false) + return false; + + List->Flag(Pkg,pkgOrderList::UnPacked,pkgOrderList::States); + + // Perform immedate configuration of the package. + if (List->IsFlag(Pkg,pkgOrderList::Immediate) == true) { + if (SmartConfigure(Pkg) == false) + return _error->Error("Internal Error, Could not perform immediate configuration"); + } + return true; +} + /*}}}*/ +// PM::OrderInstall - Installation ordering routine /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgPackageManager::OrderResult pkgPackageManager::OrderInstall() +{ + for (PkgIterator I = Cache.PkgBegin(); I.end() == false; I++) + { + // Not interesting + if ((Cache[I].Keep() == true || + Cache[I].InstVerIter(Cache) == I.CurrentVer()) && + I.State() == pkgCache::PkgIterator::NeedsNothing && + (Cache[I].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall && + (I.Purge() != false || Cache[I].Mode != pkgDepCache::ModeDelete || + (Cache[I].iFlags & pkgDepCache::Purge) != pkgDepCache::Purge)) + continue; + + // Perform a delete or an install + if (Cache[I].Delete() == true) + { + if (!Cache[I].Replaced() && !Remove(I)) + return Failed; + } + else + if (Install(I, FileNames[I->ID]) == false) + return Failed; + } + return Completed; +#if 0 + if (CreateOrderList() == false) + return Failed; + + Reset(); + + if (Debug == true) + clog << "Begining to order" << endl; + + if (List->OrderUnpack(FileNames) == false) + { + _error->Error("Internal ordering error"); + return Failed; + } + + if (Debug == true) + clog << "Done ordering" << endl; + + bool DoneSomething = false; + for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + { + PkgIterator Pkg(Cache,*I); + + if (List->IsNow(Pkg) == false) + { + if (Debug == true) + clog << "Skipping already done " << Pkg.Name() << endl; + continue; + } + + if (List->IsMissing(Pkg) == true) + { + if (Debug == true) + clog << "Sequence completed at " << Pkg.Name() << endl; + if (DoneSomething == false) + { + _error->Error("Internal Error, ordering was unable to handle the media swap"); + return Failed; + } + return Incomplete; + } + + // Sanity check + if (Cache[Pkg].Keep() == true && + Pkg.State() == pkgCache::PkgIterator::NeedsNothing && + (Cache[Pkg].iFlags & pkgDepCache::ReInstall) != pkgDepCache::ReInstall) + { + _error->Error("Internal Error, trying to manipulate a kept package"); + return Failed; + } + + // Perform a delete or an install + if (Cache[Pkg].Delete() == true) + { + if (SmartRemove(Pkg) == false) + return Failed; + } + else + if (SmartUnPack(Pkg) == false) + return Failed; + DoneSomething = true; + } + + // Final run through the configure phase + if (ConfigureAll() == false) + return Failed; + + // Sanity check + for (pkgOrderList::iterator I = List->begin(); I != List->end(); I++) + { + if (List->IsFlag(*I,pkgOrderList::Configured) == false) + { + _error->Error("Internal error, packages left unconfigured. %s", + PkgIterator(Cache,*I).Name()); + return Failed; + } + } + + return Completed; +#endif +} + /*}}}*/ +// PM::DoInstall - Does the installation /*{{{*/ +// --------------------------------------------------------------------- +/* This uses the filenames in FileNames and the information in the + DepCache to perform the installation of packages.*/ +pkgPackageManager::OrderResult pkgPackageManager::DoInstall() +{ + OrderResult Res = OrderInstall(); + if (Res != Failed) + if (Go() == false) + return Failed; + return Res; +} + /*}}}*/ diff --git a/apt/apt-pkg/packagemanager.h b/apt/apt-pkg/packagemanager.h new file mode 100644 index 0000000..5347801 --- /dev/null +++ b/apt/apt-pkg/packagemanager.h @@ -0,0 +1,93 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: packagemanager.h,v 1.2 2000/09/26 14:22:14 kojima Exp $ +/* ###################################################################### + + Package Manager - Abstacts the package manager + + Three steps are + - Aquiration of archives (stores the list of final file names) + - Sorting of operations + - Invokation of package manager + + This is the final stage when the package cache entities get converted + into file names and the state stored in a DepCache is transformed + into a series of operations. + + In the final scheme of things this may serve as a director class to + access the actual install methods based on the file type being + installed. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_PACKAGEMANAGER_H +#define PKGLIB_PACKAGEMANAGER_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/packagemanager.h" +#endif + +#include +#include + +class pkgAcquire; +class pkgDepCache; +class pkgSourceList; +class pkgOrderList; +class pkgRecords; +class pkgPackageManager +{ + public: + + enum OrderResult {Completed,Failed,Incomplete}; + + protected: + string *FileNames; + pkgDepCache &Cache; + pkgOrderList *List; + bool Debug; + + // Bring some usefull types into the local scope + typedef pkgCache::PkgIterator PkgIterator; + typedef pkgCache::VerIterator VerIterator; + typedef pkgCache::DepIterator DepIterator; + typedef pkgCache::PrvIterator PrvIterator; + typedef pkgCache::Version Version; + typedef pkgCache::Package Package; + + bool DepAdd(pkgOrderList &Order,PkgIterator P,int Depth = 0); + OrderResult OrderInstall(); + bool CheckRConflicts(PkgIterator Pkg,DepIterator Dep,const char *Ver); + bool CreateOrderList(); + + // Analysis helpers + bool DepAlwaysTrue(DepIterator D); + + // Install helpers + bool ConfigureAll(); + bool SmartConfigure(PkgIterator Pkg); + bool SmartUnPack(PkgIterator Pkg); + bool SmartRemove(PkgIterator Pkg); + bool EarlyRemove(PkgIterator Pkg); + + // The Actuall installation implementation + virtual bool Install(PkgIterator /*Pkg*/,string /*File*/) {return false;}; + virtual bool Configure(PkgIterator /*Pkg*/) {return false;}; + virtual bool Remove(PkgIterator /*Pkg*/,bool /*Purge*/=false) {return false;}; + virtual bool Go() {return true;}; + virtual void Reset() {}; + + public: + + // Main action members + bool GetArchives(pkgAcquire *Owner,pkgSourceList *Sources, + pkgRecords *Recs); + OrderResult DoInstall(); + bool FixMissing(); + + pkgPackageManager(pkgDepCache &Cache); + virtual ~pkgPackageManager(); +}; + +#endif diff --git a/apt/apt-pkg/pkgcache.cc b/apt/apt-pkg/pkgcache.cc new file mode 100644 index 0000000..3297b8a --- /dev/null +++ b/apt/apt-pkg/pkgcache.cc @@ -0,0 +1,545 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcache.cc,v 1.11 2001/06/25 16:16:18 kojima Exp $ +/* ###################################################################### + + Package Cache - Accessor code for the cache + + Please see doc/apt-pkg/cache.sgml for a more detailed description of + this format. Also be sure to keep that file up-to-date!! + + This is the general utility functions for cache managment. They provide + a complete set of accessor functions for the cache. The cacheiterators + header contains the STL-like iterators that can be used to easially + navigate the cache as well as seemlessly dereference the mmap'd + indexes. Use these always. + + The main class provides for ways to get package indexes and some + general lookup functions to start the iterators. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/pkgcache.h" +#pragma implementation "apt-pkg/cacheiterators.h" +#endif +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include + + /*}}}*/ + +// Cache::Header::Header - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* Simply initialize the header */ +pkgCache::Header::Header() +{ + Signature = 0x98FE76DC; + + /* Whenever the structures change the major version should be bumped, + whenever the generator changes the minor version should be bumped. */ + MajorVersion = 3; + MinorVersion = 7; + Dirty = true; + + HeaderSz = sizeof(pkgCache::Header); + PackageSz = sizeof(pkgCache::Package); + PackageFileSz = sizeof(pkgCache::PackageFile); + VersionSz = sizeof(pkgCache::Version); + DependencySz = sizeof(pkgCache::Dependency); + ProvidesSz = sizeof(pkgCache::Provides); + VerFileSz = sizeof(pkgCache::VerFile); + + PackageCount = 0; + VersionCount = 0; + DependsCount = 0; + PackageFileCount = 0; + VerFileCount = 0; + ProvidesCount = 0; + MaxVerFileSize = 0; + + FileList = 0; + StringList = 0; + memset(HashTable,0,sizeof(HashTable)); + memset(Pools,0,sizeof(Pools)); +} + /*}}}*/ +// Cache::Header::CheckSizes - Check if the two headers have same *sz /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCache::Header::CheckSizes(Header &Against) const +{ + if (HeaderSz == Against.HeaderSz && + PackageSz == Against.PackageSz && + PackageFileSz == Against.PackageFileSz && + VersionSz == Against.VersionSz && + DependencySz == Against.DependencySz && + VerFileSz == Against.VerFileSz && + ProvidesSz == Against.ProvidesSz) + return true; + return false; +} + /*}}}*/ + +// Cache::pkgCache - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCache::pkgCache(MMap &Map) : Map(Map) +{ + ReMap(); +} + /*}}}*/ +// Cache::ReMap - Reopen the cache file /*{{{*/ +// --------------------------------------------------------------------- +/* If the file is already closed then this will open it open it. */ +bool pkgCache::ReMap() +{ + // Apply the typecasts. + HeaderP = (Header *)Map.Data(); + PkgP = (Package *)Map.Data(); + VerFileP = (VerFile *)Map.Data(); + PkgFileP = (PackageFile *)Map.Data(); + VerP = (Version *)Map.Data(); + ProvideP = (Provides *)Map.Data(); + DepP = (Dependency *)Map.Data(); + StringItemP = (StringItem *)Map.Data(); + StrP = (char *)Map.Data(); + + if (Map.Size() == 0) + return false; + + // Check the header + Header DefHeader; + if (HeaderP->Signature != DefHeader.Signature || + HeaderP->Dirty == true) + return _error->Error(_("The package cache file is corrupted")); + + if (HeaderP->MajorVersion != DefHeader.MajorVersion || + HeaderP->MinorVersion != DefHeader.MinorVersion || + HeaderP->CheckSizes(DefHeader) == false) + return _error->Error(_("The package cache file is an incompatible version")); + + return true; +} + /*}}}*/ +// Cache::Hash - Hash a string /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to generate the hash entries for the HashTable. With my + package list from bo this function gets 94% table usage on a 512 item + table (480 used items) */ +unsigned long pkgCache::sHash(string Str) const +{ + unsigned long Hash = 0; +#if 0 + for (const char *I = Str.begin(); I != Str.end(); I++) + Hash = 5*Hash + tolower(*I); +#else + for (const char *I = Str.begin(); I != Str.end(); I++) + Hash = 5*Hash + *I; +#endif + return Hash % _count(HeaderP->HashTable); +} + +unsigned long pkgCache::sHash(const char *Str) const +{ + unsigned long Hash = 0; +#if 0 + for (const char *I = Str; *I != 0; I++) + Hash = 5*Hash + tolower(*I); +#else + for (const char *I = Str; *I != 0; I++) + Hash = 5*Hash + *I; +#endif + return Hash % _count(HeaderP->HashTable); +} + + /*}}}*/ +// Cache::FindPkg - Locate a package by name /*{{{*/ +// --------------------------------------------------------------------- +/* Returns 0 on error, pointer to the package otherwise */ +pkgCache::PkgIterator pkgCache::FindPkg(string Name) +{ + // Look at the hash bucket + Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)]; + for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage) + { +#if 0 + if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] && + stringcasecmp(Name.begin(),Name.end(),StrP + Pkg->Name) == 0) + return PkgIterator(*this,Pkg); +#else + if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] && + stringcmp(Name.begin(),Name.end(),StrP + Pkg->Name) == 0) + return PkgIterator(*this,Pkg); +#endif + } + return PkgIterator(*this,0); +} + /*}}}*/ +// Cache::Priority - Convert a priority value to a string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +const char *pkgCache::Priority(unsigned char Prio) +{ + const char *Mapping[] = {0,"important","required","standard","optional","extra"}; + if (Prio < _count(Mapping)) + return Mapping[Prio]; + return 0; +} + /*}}}*/ +// Cache::GetCandidateVer - Returns the Candidate install version /*{{{*/ +// --------------------------------------------------------------------- +/* The default just returns the highest available version that is not + a source and automatic */ +pkgCache::VerIterator pkgCache::GetCandidateVer(PkgIterator Pkg, + bool AllowCurrent) +{ + /* Not source/not automatic versions cannot be a candidate version + unless they are already installed */ + VerIterator Last(*this,0); + + for (VerIterator I = Pkg.VersionList(); I.end() == false; I++) + { + if (Pkg.CurrentVer() == I && AllowCurrent == true) + return I; + + for (VerFileIterator J = I.FileList(); J.end() == false; J++) + { + if ((J.File()->Flags & Flag::NotSource) != 0) + continue; + + /* Stash the highest version of a not-automatic source, we use it + if there is nothing better */ + if ((J.File()->Flags & Flag::NotAutomatic) != 0) + { + if (Last.end() == true) + Last = I; + continue; + } + + return I; + } + } + + return Last; +} + /*}}}*/ + +// Bases for iterator classes /*{{{*/ +void pkgCache::VerIterator::_dummy() {} +void pkgCache::DepIterator::_dummy() {} +void pkgCache::PrvIterator::_dummy() {} + /*}}}*/ +// PkgIterator::operator ++ - Postfix incr /*{{{*/ +// --------------------------------------------------------------------- +/* This will advance to the next logical package in the hash table. */ +void pkgCache::PkgIterator::operator ++(int) +{ + // Follow the current links + if (Pkg != Owner->PkgP) + Pkg = Owner->PkgP + Pkg->NextPackage; + + // Follow the hash table + while (Pkg == Owner->PkgP && HashIndex < (signed)_count(Owner->HeaderP->HashTable)) + { + HashIndex++; + Pkg = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex]; + } +}; + /*}}}*/ +// PkgIterator::State - Check the State of the package /*{{{*/ +// --------------------------------------------------------------------- +/* By this we mean if it is either cleanly installed or cleanly removed. */ +pkgCache::PkgIterator::OkState pkgCache::PkgIterator::State() const +{ + if (Pkg->InstState == pkgCache::State::ReInstReq || + Pkg->InstState == pkgCache::State::HoldReInstReq) + return NeedsUnpack; + + if (Pkg->CurrentState == pkgCache::State::UnPacked || + Pkg->CurrentState == pkgCache::State::HalfConfigured) + return NeedsConfigure; + + if (Pkg->CurrentState == pkgCache::State::HalfInstalled || + Pkg->InstState != pkgCache::State::Ok) + return NeedsUnpack; + + return NeedsNothing; +} + /*}}}*/ +// DepIterator::IsCritical - Returns true if the dep is important /*{{{*/ +// --------------------------------------------------------------------- +/* Currently critical deps are defined as depends, predepends and + conflicts. */ +bool pkgCache::DepIterator::IsCritical() +{ + if (Dep->Type == pkgCache::Dep::Conflicts || + Dep->Type == pkgCache::Dep::Obsoletes || + Dep->Type == pkgCache::Dep::Depends || + Dep->Type == pkgCache::Dep::PreDepends) + return true; + return false; +} + /*}}}*/ +// DepIterator::SmartTargetPkg - Resolve dep target pointers w/provides /*{{{*/ +// --------------------------------------------------------------------- +/* This intellegently looks at dep target packages and tries to figure + out which package should be used. This is needed to nicely handle + provide mapping. If the target package has no other providing packages + then it returned. Otherwise the providing list is looked at to + see if there is one one unique providing package if so it is returned. + Otherwise true is returned and the target package is set. The return + result indicates whether the node should be expandable */ +bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) +{ + Result = TargetPkg(); + + // No provides at all + if (Result->ProvidesList == 0) + return false; + + // There is the Base package and the providing ones which is at least 2 + if (Result->VersionList != 0) + return true; + + /* We have to skip over indirect provisions of the package that + owns the dependency. For instance, if libc5-dev depends on the + virtual package libc-dev which is provided by libc5-dev and libc6-dev + we must ignore libc5-dev when considering the provides list. */ + PrvIterator PStart = Result.ProvidesList(); + for (; PStart.end() != true && PStart.OwnerPkg() == ParentPkg(); PStart++); + + // Nothing but indirect self provides + if (PStart.end() == true) + return false; + + // Check for single packages in the provides list + PrvIterator P = PStart; + for (; P.end() != true; P++) + { + // Skip over self provides + if (P.OwnerPkg() == ParentPkg()) + continue; + if (PStart.OwnerPkg() != P.OwnerPkg()) + break; + } + + Result = PStart.OwnerPkg(); + // Check for non dups + if (P.end() != true) + return true; + return false; +} + /*}}}*/ +// DepIterator::AllTargets - Returns the set of all possible targets /*{{{*/ +// --------------------------------------------------------------------- +/* This is a more usefull version of TargetPkg() that follows versioned + provides. It includes every possible package-version that could satisfy + the dependency. The last item in the list has a 0. The resulting pointer + must be delete [] 'd */ +pkgCache::Version **pkgCache::DepIterator::AllTargets() +{ + Version **Res = 0; + unsigned long Size =0; + while (1) + { + Version **End = Res; + PkgIterator DPkg = TargetPkg(); + + // Walk along the actual package providing versions + for (VerIterator I = DPkg.VersionList(); I.end() == false; I++) + { + if (_system->checkDep(TargetVer(),I.VerStr(),Dep->CompareOp) == false) + continue; + + if ((Dep->Type == pkgCache::Dep::Conflicts + || Dep->Type == pkgCache::Dep::Obsoletes) && + ParentPkg() == I.ParentPkg()) + continue; + + Size++; + if (Res != 0) + *End++ = I; + } + + // Follow all provides + for (PrvIterator I = DPkg.ProvidesList(); I.end() == false; I++) + { + if (_system->checkDep(TargetVer(),I.ProvideVersion(),Dep->CompareOp) == false) + continue; + + if ((Dep->Type == pkgCache::Dep::Conflicts + || Dep->Type == pkgCache::Dep::Obsoletes) && + ParentPkg() == I.OwnerPkg()) + continue; + + Size++; + if (Res != 0) + *End++ = I.OwnerVer(); + } + + // Do it again and write it into the array + if (Res == 0) + { + Res = new Version *[Size+1]; + Size = 0; + } + else + { + *End = 0; + break; + } + } + + return Res; +} + /*}}}*/ +// DepIterator::CompType - Return a string describing the compare type /*{{{*/ +// --------------------------------------------------------------------- +/* This returns a string representation of the dependency compare + type */ +const char *pkgCache::DepIterator::CompType() +{ + const char *Ops[] = {"","<=",">=","<",">","=","!="}; + if ((unsigned)(Dep->CompareOp & 0xF) < 7) + return Ops[Dep->CompareOp & 0xF]; + return ""; +} + /*}}}*/ +// DepIterator::DepType - Return a string describing the dep type /*{{{*/ +// --------------------------------------------------------------------- +/* */ +const char *pkgCache::DepIterator::DepType() +{ + const char *Types[] = {"","Depends","PreDepends","Suggests", + "Recommends","Conflicts","Replaces","Obsoletes"}; + if (Dep->Type < 8) + return Types[Dep->Type]; + return ""; +} + /*}}}*/ +// DepIterator::GlobOr - Compute an OR group /*{{{*/ +// --------------------------------------------------------------------- +/* This Takes an iterator, iterates past the current dependency grouping + and returns Start and End so that so End is the final element + in the group, if End == Start then D is End++ and End is the + dependency D was pointing to. Use in loops to iterate sensibly. */ +void pkgCache::DepIterator::GlobOr(DepIterator &Start,DepIterator &End) +{ + // Compute a single dependency element (glob or) + Start = *this; + End = *this; + for (bool LastOR = true; end() == false && LastOR == true;) + { + LastOR = (Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + (*this)++; + if (LastOR == true) + End = (*this); + } +} + /*}}}*/ +// VerIterator::CompareVer - Fast version compare for same pkgs /*{{{*/ +// --------------------------------------------------------------------- +/* This just looks over the version list to see if B is listed before A. In + most cases this will return in under 4 checks, ver lists are short. */ +int pkgCache::VerIterator::CompareVer(const VerIterator &B) const +{ + // Check if they are equal + if (*this == B) + return 0; + if (end() == true) + return -1; + if (B.end() == true) + return 1; + + /* Start at A and look for B. If B is found then A > B otherwise + B was before A so A < B */ + VerIterator I = *this; + for (;I.end() == false; I++) + if (I == B) + return 1; + return -1; +} + /*}}}*/ +// VerIterator::Downloadable - Checks if the version is downloadable /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCache::VerIterator::Downloadable() const +{ + VerFileIterator Files = FileList(); + for (; Files.end() == false; Files++) + if ((Files.File()->Flags & pkgCache::Flag::NotSource) != pkgCache::Flag::NotSource) + return true; + return false; +} + /*}}}*/ +// VerIterator::PriorityType - Return a string describing the priority /*{{{*/ +// --------------------------------------------------------------------- +/* */ +const char *pkgCache::VerIterator::PriorityType() +{ + const char *Types[] = {"","Important","Required","Standard", + "Optional","Extra"}; + if (Ver->Priority < 6) + return Types[Ver->Priority]; + return ""; +} + /*}}}*/ +// VerIterator::Automatic - Check if this version is 'automatic' /*{{{*/ +// --------------------------------------------------------------------- +/* This checks to see if any of the versions files are not NotAutomatic. + True if this version is selectable for automatic installation. */ +bool pkgCache::VerIterator::Automatic() const +{ + VerFileIterator Files = FileList(); + for (; Files.end() == false; Files++) + if ((Files.File()->Flags & pkgCache::Flag::NotAutomatic) != pkgCache::Flag::NotAutomatic) + return true; + return false; +} + /*}}}*/ +// VerIterator::NewestFile - Return the newest file version relation /*{{{*/ +// --------------------------------------------------------------------- +/* This looks at the version numbers associated with all of the sources + this version is in and returns the highest.*/ +pkgCache::VerFileIterator pkgCache::VerIterator::NewestFile() const +{ + VerFileIterator Files = FileList(); + VerFileIterator Highest = Files; + for (; Files.end() == false; Files++) + { + if (_system->versionCompare(Files.File().Version(),Highest.File().Version()) > 0) + Highest = Files; + } + + return Highest; +} + /*}}}*/ +// PkgFileIterator::IsOk - Checks if the cache is in sync with the file /*{{{*/ +// --------------------------------------------------------------------- +/* This stats the file and compares its stats with the ones that were + stored during generation. Date checks should probably also be + included here. */ +bool pkgCache::PkgFileIterator::IsOk() +{ + struct stat Buf; + + if (stat(FileName(),&Buf) != 0) + return false; + + if (Buf.st_size != (signed)File->Size || Buf.st_mtime != File->mtime) + return false; + + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/pkgcache.h b/apt/apt-pkg/pkgcache.h new file mode 100644 index 0000000..da911da --- /dev/null +++ b/apt/apt-pkg/pkgcache.h @@ -0,0 +1,281 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcache.h,v 1.2 2000/09/18 18:34:42 kojima Exp $ +/* ###################################################################### + + Cache - Structure definitions for the cache file + + Please see doc/apt-pkg/cache.sgml for a more detailed description of + this format. Also be sure to keep that file up-to-date!! + + Clients should always use the CacheIterators classes for access to the + cache. They provide a simple STL-like method for traversing the links + of the datastructure. + + See pkgcachegen.h for information about generating cache structures. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_PKGCACHE_H +#define PKGLIB_PKGCACHE_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/pkgcache.h" +#endif + +#include +#include +#include + +class pkgCache +{ + public: + // Cache element predeclarations + struct Header; + struct Package; + struct PackageFile; + struct Version; + struct Provides; + struct Dependency; + struct StringItem; + struct VerFile; + + // Iterators + class PkgIterator; + class VerIterator; + class DepIterator; + class PrvIterator; + class PkgFileIterator; + class VerFileIterator; + friend PkgIterator; + friend VerIterator; + friend DepIterator; + friend PrvIterator; + friend PkgFileIterator; + friend VerFileIterator; + + // These are all the constants used in the cache structures + struct Dep + { + enum DepType {Depends=1,PreDepends=2,Suggests=3,Recommends=4, + Conflicts=5,Replaces=6,Obsoletes=7}; + enum DepCompareOp {Or=0x10,NoOp=0,LessEq=0x1,GreaterEq=0x2,Less=0x3, + Greater=0x4,Equals=0x5,NotEquals=0x6}; + }; + + struct State + { + enum VerPriority {Important=1,Required=2,Standard=3,Optional=4,Extra=5}; + enum PkgSelectedState {Unknown=0,Install=1,Hold=2,DeInstall=3,Purge=4}; + enum PkgInstState {Ok=0,ReInstReq=1,HoldInst=2,HoldReInstReq=3}; + enum PkgCurrentState {NotInstalled=0,UnPacked=1,HalfConfigured=2, + HalfInstalled=4,ConfigFiles=5,Installed=6}; + }; + + struct Flag + { + enum PkgFlags {Auto=(1<<0),Essential=(1<<3),Important=(1<<4)}; + enum PkgFFlags {NotSource=(1<<0),NotAutomatic=(1<<1)}; + }; + + protected: + + // Memory mapped cache file + string CacheFile; + MMap ⤅ + + unsigned long sHash(string S) const; + unsigned long sHash(const char *S) const; + + public: + + // Pointers to the arrays of items + Header *HeaderP; + Package *PkgP; + VerFile *VerFileP; + PackageFile *PkgFileP; + Version *VerP; + Provides *ProvideP; + Dependency *DepP; + StringItem *StringItemP; + char *StrP; + + virtual bool ReMap(); + inline bool Sync() {return Map.Sync();}; + inline MMap &GetMap() {return Map;}; + + // String hashing function (512 range) + inline unsigned long Hash(string S) const {return sHash(S);}; + inline unsigned long Hash(const char *S) const {return sHash(S);}; + + // Usefull transformation things + const char *Priority(unsigned char Priority); + + // Accessors + PkgIterator FindPkg(string Name); + Header &Head() {return *HeaderP;}; + inline PkgIterator PkgBegin(); + inline PkgIterator PkgEnd(); + inline PkgFileIterator FileBegin(); + inline PkgFileIterator FileEnd(); + VerIterator GetCandidateVer(PkgIterator Pkg,bool AllowCurrent = true); + + pkgCache(MMap &Map); + virtual ~pkgCache() {}; +}; + +// Header structure +struct pkgCache::Header +{ + // Signature information + unsigned long Signature; + short MajorVersion; + short MinorVersion; + bool Dirty; + + // Size of structure values + unsigned short HeaderSz; + unsigned short PackageSz; + unsigned short PackageFileSz; + unsigned short VersionSz; + unsigned short DependencySz; + unsigned short ProvidesSz; + unsigned short VerFileSz; + + // Structure counts + unsigned long PackageCount; + unsigned long VersionCount; + unsigned long DependsCount; + unsigned long PackageFileCount; + unsigned long VerFileCount; + unsigned long ProvidesCount; + + // Offsets + map_ptrloc FileList; // struct PackageFile + map_ptrloc StringList; // struct StringItem + unsigned long MaxVerFileSize; + + /* Allocation pools, there should be one of these for each structure + excluding the header */ + DynamicMMap::Pool Pools[7]; + + // Rapid package name lookup + map_ptrloc HashTable[2*1048]; + + bool CheckSizes(Header &Against) const; + Header(); +}; + +struct pkgCache::Package +{ + // Pointers + map_ptrloc Name; // Stringtable + map_ptrloc VersionList; // Version + map_ptrloc TargetVer; // Version + map_ptrloc CurrentVer; // Version + map_ptrloc TargetDist; // StringTable (StringItem) + map_ptrloc Section; // StringTable (StringItem) + + // Linked list + map_ptrloc NextPackage; // Package + map_ptrloc RevDepends; // Dependency + map_ptrloc ProvidesList; // Provides + + // Install/Remove/Purge etc + unsigned char SelectedState; // What + unsigned char InstState; // Flags + unsigned char CurrentState; // State + + unsigned short ID; + unsigned long Flags; +}; + +struct pkgCache::PackageFile +{ + // Names + map_ptrloc FileName; // Stringtable + map_ptrloc Archive; // Stringtable + map_ptrloc Component; // Stringtable + map_ptrloc Version; // Stringtable + map_ptrloc Origin; // Stringtable + map_ptrloc Label; // Stringtable + map_ptrloc Architecture; // Stringtable + unsigned long Size; + unsigned long Flags; + + // Linked list + map_ptrloc NextFile; // PackageFile + unsigned short ID; + time_t mtime; // Modification time for the file +}; + +struct pkgCache::VerFile +{ + map_ptrloc File; // PackageFile + map_ptrloc NextFile; // PkgVerFile + map_ptrloc Offset; // File offset + unsigned short Size; +}; + +struct pkgCache::Version +{ + map_ptrloc VerStr; // Stringtable + map_ptrloc Section; // StringTable (StringItem) + map_ptrloc Arch; // StringTable + + // Lists + map_ptrloc FileList; // VerFile + map_ptrloc NextVer; // Version + map_ptrloc DependsList; // Dependency + map_ptrloc ParentPkg; // Package + map_ptrloc ProvidesList; // Provides + + map_ptrloc Size; // These are the .deb size + map_ptrloc InstalledSize; + unsigned short Hash; + unsigned short ID; + unsigned char Priority; +}; + +struct pkgCache::Dependency +{ + map_ptrloc Version; // Stringtable + map_ptrloc Package; // Package + map_ptrloc NextDepends; // Dependency + map_ptrloc NextRevDepends; // Dependency + map_ptrloc ParentVer; // Version + + // Specific types of depends + unsigned char Type; + unsigned char CompareOp; + unsigned short ID; +}; + +struct pkgCache::Provides +{ + map_ptrloc ParentPkg; // Pacakge + map_ptrloc Version; // Version + map_ptrloc ProvideVersion; // Stringtable + map_ptrloc NextProvides; // Provides + map_ptrloc NextPkgProv; // Provides +}; + +struct pkgCache::StringItem +{ + map_ptrloc String; // Stringtable + map_ptrloc NextItem; // StringItem +}; + +#include + +inline pkgCache::PkgIterator pkgCache::PkgBegin() + {return PkgIterator(*this);}; +inline pkgCache::PkgIterator pkgCache::PkgEnd() + {return PkgIterator(*this,PkgP);}; +inline pkgCache::PkgFileIterator pkgCache::FileBegin() + {return PkgFileIterator(*this);}; +inline pkgCache::PkgFileIterator pkgCache::FileEnd() + {return PkgFileIterator(*this,PkgFileP);}; + +#endif diff --git a/apt/apt-pkg/pkgcachegen.cc b/apt/apt-pkg/pkgcachegen.cc new file mode 100644 index 0000000..d6e6004 --- /dev/null +++ b/apt/apt-pkg/pkgcachegen.cc @@ -0,0 +1,468 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcachegen.cc,v 1.24 2001/12/11 20:50:12 kojima Exp $ +/* ###################################################################### + + Package Cache Generator - Generator for the cache structure. + + This builds the cache structure from the abstract package list parser. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/pkgcachegen.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + /*}}}*/ +// CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* We set the diry flag and make sure that is written to the disk */ +pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map,OpProgress &Prog) : Map(Map), Cache(Map), Progress(&Prog) +{ + CurrentFile = 0; + + if (_error->PendingError() == true) + return; + + if (Map.Size() == 0) + { + Map.RawAllocate(sizeof(pkgCache::Header)); + *Cache.HeaderP = pkgCache::Header(); + } + Cache.HeaderP->Dirty = true; + Map.Sync(0,sizeof(pkgCache::Header)); + Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0])); + memset(UniqHash,0,sizeof(UniqHash)); +} +/*}}}*/ +// CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* We sync the data then unset the dirty flag in two steps so as to + advoid a problem during a crash */ +pkgCacheGenerator::~pkgCacheGenerator() +{ + if (_error->PendingError() == true) + return; + if (Map.Sync() == false) + return; + + Cache.HeaderP->Dirty = false; + Map.Sync(0,sizeof(pkgCache::Header)); +} + /*}}}*/ +// CacheGenerator::MergeList - Merge the package list /*{{{*/ +// --------------------------------------------------------------------- +/* This provides the generation of the entries in the cache. Each loop + goes through a single package record from the underlying parse engine. */ +bool pkgCacheGenerator::MergeList(ListParser &List, + pkgCache::VerIterator *OutVer) +{ + List.Owner = this; + + unsigned int Counter = 0; + while (List.Step() == true) + { + // Get a pointer to the package structure + string PackageName = List.Package(); + + if (PackageName.empty() == true) + return false; + + pkgCache::PkgIterator Pkg; + if (NewPackage(Pkg,PackageName) == false) + return _error->Error(_("Error occured while processing %s (NewPackage)"),PackageName.c_str()); + Counter++; + if (Counter % 100 == 0 && Progress != 0) + Progress->Progress(List.Offset()); + + /* Get a pointer to the version structure. We know the list is sorted + so we use that fact in the search. Insertion of new versions is + done with correct sorting */ + string Version = List.Version(); + if (Version.empty() == true) + { + if (List.UsePackage(Pkg,pkgCache::VerIterator(Cache)) == false) + return _error->Error(_("Error occured while processing %s (UsePackage1)"),PackageName.c_str()); + continue; + } + + pkgCache::VerIterator Ver = Pkg.VersionList(); + map_ptrloc *Last = &Pkg->VersionList; + int Res = 1; + for (; Ver.end() == false; Last = &Ver->NextVer, Ver++) + { + Res = _system->versionCompare(Version.begin(),Version.end(),Ver.VerStr(), + Ver.VerStr() + strlen(Ver.VerStr())); + if (Res >= 0) { + break; + } + } + + /* We already have a version for this item, record that we saw it */ + unsigned long Hash = List.VersionHash(); + bool ToEnd = true; + + if (Res == 0 && Ver->Hash == Hash) + { + if (List.UsePackage(Pkg,Ver) == false) + return _error->Error(_("Error occured while processing %s (UsePackage2)"),PackageName.c_str()); + + if (NewFileVer(Ver,List) == false) + return _error->Error(_("Error occured while processing %s (NewFileVer1)"),PackageName.c_str()); + + // Read only a single record and return + if (OutVer != 0) + { + *OutVer = Ver; + return true; + } + continue; + } else if (Res == 0) { + cout << _("WARNING: '") << PackageName << _("' has 2 packages with same version but different dependencies. "); + cout << _("That usually means a packaging bug.") << endl; + + if (Pkg.CurrentVer() == Ver) { + // if this is the currently installed version, then + // keep it as the 1st in the same version set + ToEnd = false; + } else { + // if this one is not the currently installed version, + // just ignore it. and hope that this package doesn't + // have an extra dependency that would fix some + // situation... which would be severe a packaging bug anyway +// cout << "Skipping package"<NextVer, Ver++) + { + Res = _system->versionCompare(Version.begin(),Version.end(),Ver.VerStr(), + Ver.VerStr() + strlen(Ver.VerStr())); + if (Res != 0) + break; + } + } + + // Add a new version + *Last = NewVersion(Ver,Version,*Last); + Ver->ParentPkg = Pkg.Index(); + Ver->Hash = Hash; + if (List.NewVersion(Ver) == false) + return _error->Error(_("Error occured while processing %s (NewVersion1)"),PackageName.c_str()); + + if (List.UsePackage(Pkg,Ver) == false) + return _error->Error(_("Error occured while processing %s (UsePackage3)"),PackageName.c_str()); + + if (NewFileVer(Ver,List) == false) + return _error->Error(_("Error occured while processing %s (NewVersion2)"),PackageName.c_str()); + + // Read only a single record and return + if (OutVer != 0) + { + *OutVer = Ver; + return true; + } + } + + return true; +} + /*}}}*/ +// CacheGenerator::NewPackage - Add a new package /*{{{*/ +// --------------------------------------------------------------------- +/* This creates a new package structure and adds it to the hash table */ +bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,string Name) +{ + Pkg = Cache.FindPkg(Name); + if (Pkg.end() == false) + return true; + + // Get a structure + unsigned long Package = Map.Allocate(sizeof(pkgCache::Package)); + if (Package == 0) + return false; + + Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package); + + // Insert it into the hash table + unsigned long Hash = Cache.Hash(Name); + Pkg->NextPackage = Cache.HeaderP->HashTable[Hash]; + Cache.HeaderP->HashTable[Hash] = Package; + + // Set the name and the ID + Pkg->Name = Map.WriteString(Name); + if (Pkg->Name == 0) + return false; + Pkg->ID = Cache.HeaderP->PackageCount++; + + return true; +} +/*}}}*/ +// CacheGenerator::NewFileVer - Create a new File<->Version association /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver, + ListParser &List) +{ + if (CurrentFile == 0) + return true; + + // Get a structure + unsigned long VerFile = Map.Allocate(sizeof(pkgCache::VerFile)); + if (VerFile == 0) + return false; + + pkgCache::VerFileIterator VF(Cache,Cache.VerFileP + VerFile); + VF->File = CurrentFile - Cache.PkgFileP; + + // Link it to the end of the list + map_ptrloc *Last = &Ver->FileList; + for (pkgCache::VerFileIterator V = Ver.FileList(); V.end() == false; V++) + Last = &V->NextFile; + VF->NextFile = *Last; + *Last = VF.Index(); + + VF->Offset = List.Offset(); + VF->Size = List.Size(); + if (Cache.HeaderP->MaxVerFileSize < VF->Size) + Cache.HeaderP->MaxVerFileSize = VF->Size; + Cache.HeaderP->VerFileCount++; + + return true; +} +/*}}}*/ +// CacheGenerator::NewVersion - Create a new Version /*{{{*/ +// --------------------------------------------------------------------- +/* This puts a version structure in the linked list */ +unsigned long pkgCacheGenerator::NewVersion(pkgCache::VerIterator &Ver, + string VerStr, + unsigned long Next) +{ + // Get a structure + unsigned long Version = Map.Allocate(sizeof(pkgCache::Version)); + if (Version == 0) + return 0; + + // Fill it in + Ver = pkgCache::VerIterator(Cache,Cache.VerP + Version); + Ver->NextVer = Next; + Ver->ID = Cache.HeaderP->VersionCount++; + Ver->VerStr = Map.WriteString(VerStr); + if (Ver->VerStr == 0) + return 0; + + return Version; +} +/*}}}*/ +// ListParser::NewDepends - Create a dependency element /*{{{*/ + // --------------------------------------------------------------------- +/* This creates a dependency element in the tree. It is linked to the + version and to the package that it is pointing to. */ +bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, + string PackageName, + string Version, + unsigned int Op, + unsigned int Type) +{ + pkgCache &Cache = Owner->Cache; + + // Get a structure + unsigned long Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency)); + if (Dependency == 0) + return false; + + // Fill it in + pkgCache::DepIterator Dep(Cache,Cache.DepP + Dependency); + Dep->ParentVer = Ver.Index(); + Dep->Type = Type; + Dep->CompareOp = Op; + Dep->ID = Cache.HeaderP->DependsCount++; + + // Locate the target package + pkgCache::PkgIterator Pkg; + if (Owner->NewPackage(Pkg,PackageName) == false) + return false; + + // Probe the reverse dependency list for a version string that matches + if (Version.empty() == false) + { + /* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++, Hit++) + if (I->Version != 0 && I.TargetVer() == Version) + Dep->Version = I->Version;*/ + if (Dep->Version == 0) + if ((Dep->Version = WriteString(Version)) == 0) + return false; + } + + // Link it to the package + Dep->Package = Pkg.Index(); + Dep->NextRevDepends = Pkg->RevDepends; + Pkg->RevDepends = Dep.Index(); + + /* Link it to the version (at the end of the list) + Caching the old end point speeds up generation substantially */ + if (OldDepVer != Ver) + { + OldDepLast = &Ver->DependsList; + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) + OldDepLast = &D->NextDepends; + OldDepVer = Ver; + } + + + Dep->NextDepends = *OldDepLast; + *OldDepLast = Dep.Index(); + OldDepLast = &Dep->NextDepends; + + return true; +} +/*}}}*/ +// ListParser::NewProvides - Create a Provides element /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, + string PackageName, + string Version) +{ + pkgCache &Cache = Owner->Cache; + + // We do not add self referencing provides + if (Ver.ParentPkg().Name() == PackageName) + return true; + + // Get a structure + unsigned long Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides)); + if (Provides == 0) + return false; + Cache.HeaderP->ProvidesCount++; + + // Fill it in + pkgCache::PrvIterator Prv(Cache,Cache.ProvideP + Provides,Cache.PkgP); + Prv->Version = Ver.Index(); + Prv->NextPkgProv = Ver->ProvidesList; + Ver->ProvidesList = Prv.Index(); + + if (Version.empty() == false) + { + if (Prv->ProvideVersion == 0) + if ((Prv->ProvideVersion = WriteString(Version)) == 0) + return false; + } + + // Locate the target package + pkgCache::PkgIterator Pkg; + if (Owner->NewPackage(Pkg,PackageName) == false) + return false; + + // Link it to the package + Prv->ParentPkg = Pkg.Index(); + Prv->NextProvides = Pkg->ProvidesList; + Pkg->ProvidesList = Prv.Index(); + + return true; +} +/*}}}*/ +// CacheGenerator::SelectFile - Select the current file being parsed /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to select which file is to be associated with all newly + added versions. */ +bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags) +{ + struct stat Buf; + if (stat(File.c_str(),&Buf) == -1) + return _error->Errno("stat","Couldn't stat %s",File.c_str()); + + // Get some space for the structure + CurrentFile = Cache.PkgFileP + Map.Allocate(sizeof(*CurrentFile)); + if (CurrentFile == Cache.PkgFileP) + return false; + + // Fill it in + CurrentFile->FileName = Map.WriteString(File); + CurrentFile->Size = Buf.st_size; + CurrentFile->mtime = Buf.st_mtime; + CurrentFile->NextFile = Cache.HeaderP->FileList; + CurrentFile->Flags = Flags; + CurrentFile->ID = Cache.HeaderP->PackageFileCount; + PkgFileName = File; + Cache.HeaderP->FileList = CurrentFile - Cache.PkgFileP; + Cache.HeaderP->PackageFileCount++; + + if (CurrentFile->FileName == 0) + return false; + + if (Progress != 0) + Progress->SubProgress(Buf.st_size); + return true; +} +/*}}}*/ +// CacheGenerator::WriteUniqueString - Insert a unique string /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to create handles to strings. Given the same text it + always returns the same number */ +unsigned long pkgCacheGenerator::WriteUniqString(const char *S, + unsigned int Size) +{ + /* We use a very small transient hash table here, this speeds up generation + by a fair amount on slower machines */ + pkgCache::StringItem *&Bucket = UniqHash[(S[0]*5 + S[1]) % _count(UniqHash)]; + if (Bucket != 0 && + stringcmp(S,S+Size,Cache.StrP + Bucket->String) == 0) + return Bucket->String; + + // Search for an insertion point + pkgCache::StringItem *I = Cache.StringItemP + Cache.HeaderP->StringList; + int Res = 1; + map_ptrloc *Last = &Cache.HeaderP->StringList; + for (; I != Cache.StringItemP; Last = &I->NextItem, + I = Cache.StringItemP + I->NextItem) + { + Res = stringcmp(S,S+Size,Cache.StrP + I->String); + if (Res >= 0) + break; + } + + // Match + if (Res == 0) + { + Bucket = I; + return I->String; + } + + // Get a structure + unsigned long Item = Map.Allocate(sizeof(pkgCache::StringItem)); + if (Item == 0) + return 0; + + // Fill in the structure + pkgCache::StringItem *ItemP = Cache.StringItemP + Item; + ItemP->NextItem = I - Cache.StringItemP; + *Last = Item; + ItemP->String = Map.WriteString(S,Size); + if (ItemP->String == 0) + return 0; + + Bucket = ItemP; + return ItemP->String; +} diff --git a/apt/apt-pkg/pkgcachegen.h b/apt/apt-pkg/pkgcachegen.h new file mode 100644 index 0000000..8258ad0 --- /dev/null +++ b/apt/apt-pkg/pkgcachegen.h @@ -0,0 +1,115 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgcachegen.h,v 1.5 2000/12/02 18:02:53 kojima Exp $ +/* ###################################################################### + + Package Cache Generator - Generator for the cache structure. + + This builds the cache structure from the abstract package list parser. + Each archive source has it's own list parser that is instantiated by + the caller to provide data for the generator. + + Parts of the cache are created by this generator class while other + parts are created by the list parser. The list parser is responsible + for creating version, depends and provides structures, and some of + their contents + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_PKGCACHEGEN_H +#define PKGLIB_PKGCACHEGEN_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/pkgcachegen.h" +#endif + +#include + +class pkgSourceList; +class OpProgress; +class MMap; + +class pkgCacheGenerator +{ + private: + + pkgCache::StringItem *UniqHash[26]; + + public: + + class ListParser; + friend ListParser; + + protected: + + DynamicMMap ⤅ + pkgCache Cache; + OpProgress *Progress; + + string PkgFileName; + pkgCache::PackageFile *CurrentFile; + + bool NewPackage(pkgCache::PkgIterator &Pkg,string Pkg); + bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List); + unsigned long NewVersion(pkgCache::VerIterator &Ver,string VerStr,unsigned long Next); + + unsigned long WriteUniqString(const char *S,unsigned int Size); + inline unsigned long WriteUniqString(string S) {return WriteUniqString(S.c_str(),S.length());}; + + public: + + void DropProgress() {Progress = 0;}; + bool SelectFile(string File,unsigned long Flags = 0); + bool MergeList(ListParser &List,pkgCache::VerIterator *Ver = 0); + inline pkgCache &GetCache() {return Cache;}; + inline pkgCache::PkgFileIterator GetCurFile() + {return pkgCache::PkgFileIterator(Cache,CurrentFile);}; + + pkgCacheGenerator(DynamicMMap &Map,OpProgress &Progress); + ~pkgCacheGenerator(); +}; + +// This is the abstract package list parser class. +class pkgCacheGenerator::ListParser +{ + pkgCacheGenerator *Owner; + friend pkgCacheGenerator; + + // Some cache items + pkgCache::VerIterator OldDepVer; + map_ptrloc *OldDepLast; + + protected: + + inline unsigned long WriteUniqString(string S) {return Owner->WriteUniqString(S);}; + inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);}; + inline unsigned long WriteString(string S) {return Owner->Map.WriteString(S);}; + inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);}; + bool NewDepends(pkgCache::VerIterator Ver,string Package, + string Version,unsigned int Op, + unsigned int Type); + bool NewProvides(pkgCache::VerIterator Ver,string Package,string Version); + + public: + + // These all operate against the current section + virtual string Package() = 0; + virtual string Version() = 0; + inline virtual string Architecture() { return string(); } + virtual bool NewVersion(pkgCache::VerIterator Ver) = 0; + virtual unsigned short VersionHash() = 0; + virtual bool UsePackage(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver) = 0; + virtual unsigned long Offset() = 0; + virtual unsigned long Size() = 0; + + virtual bool Step() = 0; + + virtual bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File) = 0; + + virtual ~ListParser() {}; +}; + + +#endif diff --git a/apt/apt-pkg/pkgrecords.cc b/apt/apt-pkg/pkgrecords.cc new file mode 100644 index 0000000..f658ab0 --- /dev/null +++ b/apt/apt-pkg/pkgrecords.cc @@ -0,0 +1,79 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgrecords.cc,v 1.5 2001/01/11 02:03:27 kojima Exp $ +/* ###################################################################### + + Package Records - Allows access to complete package description records + directly from the file. + + ##################################################################### + */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/pkgrecords.h" +#endif +#include +#include +#include +#include + +#include + /*}}}*/ + +// Records::pkgRecords - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* This will create the necessary structures to access the status files */ +pkgRecords::pkgRecords(pkgCache &Cache) : Cache(Cache), Files(0) +{ + Files = new PkgFile[Cache.HeaderP->PackageFileCount]; + for (pkgCache::PkgFileIterator I = Cache.FileBegin(); + I.end() == false; I++) + { + // We can not initialize if the cache is out of sync. + if (I.IsOk() == false) + { + _error->Error(_("Package file %s is out of sync."),I.FileName()); + return; + } + + // Create the file + Files[I->ID].File = string(I.FileName()); + + // Create the parser + Files[I->ID].Parse = _system->CreateRecordParser(Files[I->ID].File,Cache); + if (_error->PendingError() == true) { + if (Files[I->ID].Parse) + delete Files[I->ID].Parse; + return; + } + } +} + /*}}}*/ +// Records::~pkgRecords - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgRecords::~pkgRecords() +{ + delete [] Files; +} + /*}}}*/ +// Records::Lookup - Get a parser for the package version file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgRecords::Parser &pkgRecords::Lookup(pkgCache::VerFileIterator const &Ver) +{ + PkgFile &File = Files[Ver.File()->ID]; + File.Parse->Jump(Ver); + + return *File.Parse; +} + /*}}}*/ +// Records::Pkgfile::~PkgFile - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgRecords::PkgFile::~PkgFile() +{ + delete Parse; +} + /*}}}*/ diff --git a/apt/apt-pkg/pkgrecords.h b/apt/apt-pkg/pkgrecords.h new file mode 100644 index 0000000..122e516 --- /dev/null +++ b/apt/apt-pkg/pkgrecords.h @@ -0,0 +1,80 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgrecords.h,v 1.3 2000/10/28 01:48:45 kojima Exp $ +/* ###################################################################### + + Package Records - Allows access to complete package description records + directly from the file. + + The package record system abstracts the actual parsing of the + package files. This is different than the generators parser in that + it is used to access information not generate information. No + information touched by the generator should be parable from here as + it can always be retreived directly from the cache. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_PKGRECORDS_H +#define PKGLIB_PKGRECORDS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/pkgrecords.h" +#endif + +#include +#include + +class pkgRecords +{ + public: + class Parser; + + private: + + pkgCache &Cache; + + // List of package files + struct PkgFile + { + string File; + Parser *Parse; + + PkgFile() : Parse(0) { File=""; }; + ~PkgFile(); + }; + PkgFile *Files; + + public: + + // Lookup function + Parser &Lookup(pkgCache::VerFileIterator const &Ver); + + // Construct destruct + pkgRecords(pkgCache &Cache); + ~pkgRecords(); +}; + +class pkgRecords::Parser +{ + protected: + + public: + friend pkgRecords; + + virtual bool Jump(pkgCache::VerFileIterator const &Ver) = 0; + + // These refer to the archive file for the Version + virtual string FileName() {return string();}; + virtual string MD5Hash() {return string();}; + virtual string SourcePkg() {return string();}; + + // These are some general stats about the package + virtual string Maintainer() {return string();}; + virtual string ShortDesc() {return string();}; + virtual string LongDesc() {return string();}; + + virtual ~Parser() {}; +}; + +#endif diff --git a/apt/apt-pkg/rpm/CVS/Entries b/apt/apt-pkg/rpm/CVS/Entries new file mode 100644 index 0000000..fad1da5 --- /dev/null +++ b/apt/apt-pkg/rpm/CVS/Entries @@ -0,0 +1,16 @@ +/rpmrecords.cc/1.20/Wed Aug 1 21:35:12 2001// +/rpmfactory.h/1.6/Fri Aug 10 14:00:38 2001// +/rpminit.h/1.14/Fri Aug 10 14:00:38 2001// +/rpmpackagedata.h/1.3/Fri Aug 10 14:00:39 2001// +/rpmrecords.h/1.3/Fri Aug 10 14:00:39 2001// +/rpmsrcrecords.h/1.1/Fri Aug 10 14:00:39 2001// +/rpmpm.h/1.6/Tue Nov 13 14:24:16 2001// +/rpmfactory.cc/1.27/Fri Nov 16 01:13:06 2001// +/rpminit.cc/1.32/Fri Nov 16 01:13:06 2001// +/rpmpackagedata.cc/1.5/Fri Nov 16 01:13:06 2001// +/rpmsrcrecords.cc/1.5/Fri Nov 16 01:13:06 2001// +/rpmlistparser.cc/1.60/Wed Mar 6 17:17:10 2002// +/rpmlistparser.h/1.15/Wed Mar 6 17:17:10 2002// +/rpmpm.cc/1.34/Wed Mar 6 17:17:13 2002// +/rpmversion.cc/1.4/Wed Mar 6 17:17:13 2002// +D diff --git a/apt/apt-pkg/rpm/CVS/Repository b/apt/apt-pkg/rpm/CVS/Repository new file mode 100644 index 0000000..50f634e --- /dev/null +++ b/apt/apt-pkg/rpm/CVS/Repository @@ -0,0 +1 @@ +rapt/apt-pkg/rpm diff --git a/apt/apt-pkg/rpm/CVS/Root b/apt/apt-pkg/rpm/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/apt-pkg/rpm/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/apt-pkg/rpm/rpmfactory.cc b/apt/apt-pkg/rpm/rpmfactory.cc new file mode 100644 index 0000000..1f52a2b --- /dev/null +++ b/apt/apt-pkg/rpm/rpmfactory.cc @@ -0,0 +1,385 @@ +/* + * $Id: rpmfactory.cc,v 1.27 2001/11/13 17:32:08 kojima Exp $ + */ + +#include + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +RPMFactory::RPMFactory() +{ + filedeps = new map(); + multiarchs = new map(); +} + + +pkgPackageManager *RPMFactory::CreatePackageManager(pkgDepCache &Cache) +{ + return new pkgRPMPM(Cache); +} + + +pkgRecords::Parser *RPMFactory::CreateRecordParser(string File, pkgCache &Cache) +{ + if (File == pkgRpmLock::RPMDBPath()) + return new rpmRecordParser("", Cache); + else + return new rpmRecordParser(File, Cache); +} + + +pkgSrcRecords::Parser *RPMFactory::CreateSrcRecordParser(string File, + pkgSourceList::const_iterator SrcItem) +{ + FileFd *Fd = new FileFd(File, FileFd::ReadOnly); + if (_error->PendingError()) + { + delete Fd; + return NULL; + } + + return new rpmSrcRecordParser(Fd, SrcItem); +} + + +bool RPMFactory::checkSourceType(int type, bool binary) +{ + if (binary) + return (type == pkgSourceList::Rpm); + else + return (type == pkgSourceList::RpmSrc); +} + + +bool RPMFactory::packageCacheCheck(string CacheFile) +{ + if (_error->PendingError()) + return false; + + // Open the source package cache + if (!FileExists(CacheFile)) { + return false; + } + + FileFd CacheF(CacheFile,FileFd::ReadOnly); + if (_error->PendingError()) + { + _error->Discard(); + return false; + } + + MMap Map(CacheF,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() || Map.Size() == 0) + { + _error->Discard(); + return false; + } + + pkgCache Cache(Map); + if (_error->PendingError()) + { + _error->Discard(); + return false; + } + + string blaa="packages.rpm"; +#ifdef HAVE_RPM4 + if (rpmExpandNumeric("%{_dbapi}") == 3) + blaa = "Packages"; +#endif + + string rpmdb_path = pkgRpmLock::RPMDBPath() + blaa; + + int bla = 0; + + // Check each file + for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++) + { + if (F.IsOk() == false) { + return false; + } + if (strcmp(rpmdb_path.c_str(), F.FileName()) != 0) { + continue; + } + bla++; + } + + // only one file + if (bla != 1) { + return false; + } + + return true; +} + + +pkgCacheGenerator::ListParser *RPMFactory::CreateListParser(FileFd &File) +{ + return new rpmListParser(File, filedeps, multiarchs); +} + + + /*}}}*/ +// AddStatusSize - Add the size of the status files /*{{{*/ +// --------------------------------------------------------------------- +bool RPMFactory::addStatusSize(unsigned long &TotalSize) +{ + //struct stat Buf; + unsigned size, bla; + + pkgRpmLock::SharedRPM()->Offset(size, bla); + + TotalSize += size; + + return true; +} + /*}}}*/ + +// MergeInstalledPackages (was MergeStatus) - Add the status files to the cache /*{{{*/ +// --------------------------------------------------------------------- +/* This adds the status files to the map */ +bool RPMFactory::mergeInstalledPackages(OpProgress &Progress, + pkgCacheGenerator &Gen, + unsigned long &CurrentSize, + unsigned long TotalSize) +{ + unsigned size, bla; + string suffix = "packages.rpm"; +#ifdef HAVE_RPM4 + if (rpmExpandNumeric("%{_dbapi}") == 3) + suffix = "Packages"; +#endif + + string tmp = string(pkgRpmLock::RPMDBPath()+suffix).c_str(); + + const char *dbpath = tmp.c_str(); + + pkgRpmLock::SharedRPM()->Rewind(); + // Check if the file exists and it is not the primary status file. + rpmListParser *Parser = new rpmListParser(filedeps, multiarchs); + + + pkgRpmLock::SharedRPM()->Offset(size, bla); + + Progress.OverallProgress(CurrentSize,TotalSize, size,_("Reading Package Lists")); + if (_error->PendingError() == true) + return _error->Error(_("Problem opening %s"), dbpath); + CurrentSize += size; + + Progress.SubProgress(0,_("Local Package State - ") + flNotDir(dbpath)); + if (Gen.SelectFile(dbpath,pkgCache::Flag::NotSource) == false) + return _error->Error(_("Problem with SelectFile %s"), dbpath); + + if (Gen.MergeList(*Parser) == false) + return _error->Error(_("Problem with MergeList %s"), dbpath); + Progress.Progress(size); + + return true; +} + + + + +void gatherFileDependencies(map*filedeps, Header header) +{ + int type, count; + char **namel; + char **verl; + int *flagl; + int res; + + res = headerGetEntry(header, RPMTAG_REQUIRENAME, &type, + (void **)&namel, &count); + res = headerGetEntry(header, RPMTAG_REQUIREVERSION, &type, + (void **)&verl, &count); + res = headerGetEntry(header, RPMTAG_REQUIREFLAGS, &type, + (void **)&flagl, &count); + + while (count--) { + if (*namel[count] == '/') { // ugh file dep! + (*filedeps)[string(namel[count])] = 1; + } + } +} + + +bool RPMFactory::preProcess(pkgSourceList &List, OpProgress &Progress) +{ + string ListDir = _config->FindDir("Dir::State::lists"); + unsigned total, complete; + struct stat stbuf; + const char *baseArch; + const char *thisArch; + struct utsname un; + map archmap; + + baseArch = _config->Find("APT::architecture").c_str(); + + if (uname(&un) < 0) { + thisArch = baseArch; + } else { + thisArch = un.machine; + } + + // calculate size of files + + pkgRpmLock::SharedRPM()->Offset(total, complete); + + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + // Only check relevant source types. + if (!checkSourceType(I->Type())) + continue; + + string File = ListDir + URItoFileName(I->PackagesURI()); + + if (FileExists(File) == false) + continue; + + if (stat(File.c_str(), &stbuf) == 0) + { + total += stbuf.st_size; + } + } + + + complete = 0; + Progress.OverallProgress(0, 100, 100, _("Processing File Dependencies")); + Progress.SubProgress(total, _("Looking for file dependencies")); + + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + // Only check relevant source types. + if (!checkSourceType(I->Type())) + continue; + + string File = ListDir + URItoFileName(I->PackagesURI()); + + if (FileExists(File) == false) + continue; + + FileFd F(File, FileFd::ReadOnly); + if (_error->PendingError() == true) + return _error->Error(_("Problem opening %s"),File.c_str()); + + FD_t fdt = fdDup(F.Fd()); + while (1) + { + Header hdr; + int type, count, res; + char *arch; + + hdr = headerRead(fdt, HEADER_MAGIC_YES); + if (!hdr) + break; + gatherFileDependencies(filedeps, hdr); + + + /* + * Make it so that for each version, we keep track of the best + * architecture. + */ + res = headerGetEntry(hdr, RPMTAG_ARCH, &type, + (void **)&arch, &count); + assert(type == RPM_STRING_TYPE); + if (res) { + char *name; + char *version; + char *release; + int_32 *epoch; + int res; + char buf[256]; + + headerGetEntry(hdr, RPMTAG_NAME, &type, + (void **)&name, &count); + headerGetEntry(hdr, RPMTAG_VERSION, &type, + (void **)&version, &count); + headerGetEntry(hdr, RPMTAG_RELEASE, &type, + (void **)&release, &count); + res = headerGetEntry(hdr, RPMTAG_EPOCH, &type, + (void **)&epoch, &count); + + if (res == 1) { + snprintf(buf, 255, "%i:%s-%s", *epoch, version, release); + } else { + snprintf(buf, 255, "%s-%s", version, release); + } + string n = string(name)+"#"+string(buf); + + if (archmap.find(n) != archmap.end()) + { + if (strcmp(archmap[n].c_str(), arch) != 0) { + int a = rpmMachineScore(RPM_MACHTABLE_INSTARCH, archmap[n].c_str()); + int b = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); + + if (b < a && b > 0) { + (*multiarchs)[n] = string(arch); + // this is a multiarch pkg + archmap[n] = (*multiarchs)[n]; + } else { + (*multiarchs)[n] = archmap[n]; + } + } + } + else + { + int a = rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch); + if (a > 0) + { + archmap[n] = string(arch); + (*multiarchs)[n] = string(arch); + } + } + } + headerFree(hdr); + + Progress.Progress(complete+F.Tell()); + } + fdClose(fdt); + complete += F.Size(); + } + + pkgRpmLock::SharedRPM()->Rewind(); + while (1) + { + Header hdr; + unsigned comp; + + hdr = pkgRpmLock::SharedRPM()->NextHeader(); + if (!hdr) + break; + gatherFileDependencies(filedeps, hdr); + headerFree(hdr); + pkgRpmLock::SharedRPM()->Offset(total, comp); + Progress.Progress(complete+comp); + } + Progress.Done(); + + return true; +} diff --git a/apt/apt-pkg/rpm/rpmfactory.h b/apt/apt-pkg/rpm/rpmfactory.h new file mode 100644 index 0000000..a79500b --- /dev/null +++ b/apt/apt-pkg/rpm/rpmfactory.h @@ -0,0 +1,45 @@ + +#ifndef _RPMFACTORY_H_ +#define _RPMFACTORY_H_ + +#include +#include +#include +#include + +class RPMFactory : public SystemFactory +{ + map *filedeps; + map *multiarchs; // pkgs with multiple architectures + + protected: + bool addStatusSize(unsigned long &TotalSize); + + bool mergeInstalledPackages(OpProgress &Progress,pkgCacheGenerator &Gen, + unsigned long &CurrentSize, + unsigned long TotalSize); + + virtual bool packageCacheCheck(string CacheFile); + + virtual bool checkSourceType(int type, bool binary=true); + + bool preProcess(pkgSourceList &List, OpProgress &Progress); + + public: + virtual int versionCompare(const char *A, const char *B); + virtual int versionCompare(const char *A, const char *AEnd, const char *B, + const char *BEnd); + virtual int versionCompare(string A,string B); + virtual bool checkDep(const char *DepVer,const char *PkgVer,int Op); + virtual string baseVersion(const char *Ver); + + public: + pkgCacheGenerator::ListParser *CreateListParser(FileFd &File); + pkgRecords::Parser *CreateRecordParser(string File, pkgCache &Cache); + pkgSrcRecords::Parser *CreateSrcRecordParser(string File, pkgSourceList::const_iterator SrcItem); + pkgPackageManager *CreatePackageManager(pkgDepCache &Cache); + + RPMFactory::RPMFactory(); +}; + +#endif diff --git a/apt/apt-pkg/rpm/rpminit.cc b/apt/apt-pkg/rpm/rpminit.cc new file mode 100644 index 0000000..526dfb7 --- /dev/null +++ b/apt/apt-pkg/rpm/rpminit.cc @@ -0,0 +1,179 @@ +/* + * $Id: rpminit.cc,v 1.32 2001/11/13 17:32:08 kojima Exp $ + * Copyright (c) 2000 Conectiva S/A + * + * Author: Alfredo K. Kojima + * Hacks: Gustavo Niemeyer + */ + +#include + +#include +#include + +#include + +#include +#include +#include + +#include + +static pkgRpmLock *global_me = NULL; + + +#define Rpmiter *(rpmdbMatchIterator*)rpmiter + + +pkgRpmLock::pkgRpmLock(bool exclusive) +{ + struct stat stbuf; + +#ifndef HAVE_RPM4 + string rpmdb_path = pkgRpmLock::RPMDBPath() + "packages.rpm"; + stat(rpmdb_path.c_str(), &stbuf); + size = stbuf.st_size; +#endif + + rpmiter = 0; + offset = 0; + global_me = this; + GetLock(exclusive); +} + +pkgRpmLock::~pkgRpmLock() +{ +#ifdef HAVE_RPM4 + if (rpmiter) + delete (rpmdbMatchIterator*)rpmiter; +#endif +} + + + +pkgRpmLock *pkgRpmLock::SharedRPM() +{ + return global_me; +} + +string pkgRpmLock::RPMDBPath() +{ + string root; + + root = _config->FindDir("RPM::DBPath", ""); + if (root.empty() || root == "/") { + root = _config->FindDir("RPM::RootDir", "/"); + + return string(root+"var/lib/rpm/"); + } else { + return root; + } +} + + +/* + * Well, this actually does more than just locking the rpm db. + */ +bool pkgRpmLock::GetLock(bool exclusive) +{ + rpmReadConfigFiles(NULL, NULL); + + string root = _config->Find("RPM::RootDir"); + const char *rootdir = NULL; + + if (!root.empty()) + rootdir = root.c_str(); + + // we use O_RDWR although we won't write anything on the DB, + // (the spawned rpm will) so that we effectively get an exclusive + // lock on it. That's needed to avoid anyone from running rpm + // at all while we're running. + if (rpmdbOpen(rootdir, &db, exclusive ? O_RDWR : O_RDONLY, 0644) != 0) { + _error->Error(_("could not open RPM database:%s"), rpmErrorString()); + if (getuid() != 0) + _error->Error(_("You need to run it as the root user.")); + return false; + } +#ifdef HAVE_RPM4 + rpmiter = new rpmdbMatchIterator; + + Rpmiter = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0); + if (!Rpmiter) { + _error->Error(_("could not create RPM database iterator:%s"), rpmErrorString()); + return false; + } + + while (rpmdbNextIterator(Rpmiter)); + size = rpmdbGetIteratorOffset(Rpmiter); + + rpmdbFreeIterator(Rpmiter); + Rpmiter = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0); + +#endif + return true; +} + + +void pkgRpmLock::Close() +{ +#ifdef HAVE_RPM4 + if (Rpmiter) + rpmdbFreeIterator(Rpmiter); +#endif + rpmdbClose(db); +} + + +void pkgRpmLock::Rewind() +{ + offset = 0; +#ifdef HAVE_RPM4 + rpmdbFreeIterator(Rpmiter); + Rpmiter = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0); +#endif +} + + +Header pkgRpmLock::NextHeader() +{ +#ifdef HAVE_RPM4 + Header h; + if ((h = rpmdbNextIterator(Rpmiter))) { + h = headerLink(h); + } + offset = rpmdbGetIteratorOffset(Rpmiter); + return h; +#else + if (offset == 0) { + offset = rpmdbFirstRecNum(db); + } else { + offset = rpmdbNextRecNum(db, offset); + } + if (offset==0) + return NULL; + + return rpmdbGetRecord(db, offset); +#endif +} + + + +Header pkgRpmLock::GetRecord(unsigned offset) +{ +#ifdef HAVE_RPM4 + Header h = NULL; + rpmdbMatchIterator i; + if (offset == 0) { + i = rpmdbInitIterator(db, RPMDBI_PACKAGES, NULL, 0); + } else { + i = rpmdbInitIterator(db, RPMDBI_PACKAGES, &offset, sizeof(offset)); + } + if ((h = rpmdbNextIterator(i))) { + h = headerLink(h); + } + rpmdbFreeIterator(i); + return h; +#else + return rpmdbGetRecord(db, offset); +#endif +} diff --git a/apt/apt-pkg/rpm/rpminit.h b/apt/apt-pkg/rpm/rpminit.h new file mode 100644 index 0000000..819a2b4 --- /dev/null +++ b/apt/apt-pkg/rpm/rpminit.h @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2000 Conectiva S/A + * + * Author: Alfredo K. Kojima + */ + +#ifndef _RPMINIT_H_ +#define _RPMINIT_H_ + +#include + +#include + +#include + + +class pkgRpmLock +{ + rpmdb db; + unsigned int size; + unsigned int offset; + + void *rpmiter; // only used in rpm4 + + public: + bool GetLock(bool exclusive); + void Close(); + + static pkgRpmLock *SharedRPM(); + + static string RPMDBPath(); + + void Rewind(); + Header NextHeader(); + Header GetRecord(unsigned offset); + inline void Offset(unsigned &total, unsigned ¤t) + { + total = size; + current = offset; + } + + pkgRpmLock(bool exclusive); + ~pkgRpmLock(); +}; + +#define CRPMTAG_FILENAME 1000000 +#define CRPMTAG_FILESIZE 1000001 +#define CRPMTAG_MD5 1000005 + +#define CRPMTAG_DIRECTORY 1000010 +#define CRPMTAG_BINARY 1000011 + +#define CRPMTAG_UPDATE_SUMMARY 1000020 +#define CRPMTAG_UPDATE_IMPORTANCE 1000021 +#define CRPMTAG_UPDATE_DATE 1000022 +#define CRPMTAG_UPDATE_URL 1000023 + + + +#endif diff --git a/apt/apt-pkg/rpm/rpmlistparser.cc b/apt/apt-pkg/rpm/rpmlistparser.cc new file mode 100644 index 0000000..ed12fa6 --- /dev/null +++ b/apt/apt-pkg/rpm/rpmlistparser.cc @@ -0,0 +1,853 @@ +// Description +// $Id: rpmlistparser.cc,v 1.60 2001/12/11 20:50:12 kojima Exp $ +// +/* ###################################################################### + * Package Cache Generator - Generator for the cache structure. + * This builds the cache structure from the abstract package list parser. + * + ##################################################################### + */ + +#include + +// Include Files +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#define DUPPACK + + +// ListParser::rpmListParser - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +rpmListParser::rpmListParser(FileFd &File, map *fdeps, + map *marchs) +{ + file = &File; + header = NULL; + filedeps = fdeps; + multiarchs = marchs; + + parsing_hdlist = true; + + DupPackages = NULL; + + GetConfig(); +} + +rpmListParser::rpmListParser(map *fdeps, map *marchs) +{ + file = 0; + header = NULL; + filedeps = fdeps; + multiarchs = marchs; + + parsing_hdlist = false; + + DupPackages = new map(); + + GetConfig(); +} + +rpmListParser::~rpmListParser() +{ +#ifndef HAVE_RPM4 + if (header) + headerFree(header); +#endif + delete AllowedDupPackages; + if (DupPackages) + delete DupPackages; +} +/*}}}*/ + + +bool rpmListParser::GetConfig() +{ + string str; + char *begin, *end; + char *p; + +#ifdef DUPPACK + AllowedDupPackages = new slist; + + const Configuration::Item *Top = _config->Tree("RPM::AllowedDupPkgs"); + + if (Top) { + for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next) + { + regex_t *ptrn = new regex_t; + + if (regcomp(ptrn,Top->Value.c_str(),REG_EXTENDED|REG_ICASE|REG_NOSUB) != 0) + { + _error->Warning(_("Bad regular expression '%s' in option RPM::AllowedDupPkgs."), + Top->Value.c_str()); + delete ptrn; + } + else + AllowedDupPackages->push_front(ptrn); + } + } else { + str = _config->Find("RPM::AllowedDupPackages"); + if (!str.empty()) { + return _error->Error(_("Option RPM::AllowedDupPackages was replaced with RPM::AllowedDupPkgs, which is a list of regular expressions (apt-config dump for an example). Please update.")); + } + } +#else + AllowedDupPackages = NULL;//akk +#endif + + HoldPackages = new slist; + + Top = _config->Tree("RPM::HoldPkgs"); + + for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next) + { + regex_t *ptrn = new regex_t; + + if (regcomp(ptrn,Top->Value.c_str(),REG_EXTENDED|REG_ICASE|REG_NOSUB) != 0) + { + _error->Warning(_("Bad regular expression '%s' in option RPM::HoldPackages."), + Top->Value.c_str()); + delete ptrn; + } + else + HoldPackages->push_front(ptrn); + } + + + str = _config->Find("APT::architecture"); + + BaseArch = strdup(str.c_str()); + + return true; +} + +// ListParser::UniqFindTagWrite - Find the tag and write a unq string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +unsigned long rpmListParser::UniqFindTagWrite(int Tag) +{ + char *str; + int type; + int count; + void *data; + + if (headerGetEntry(header, Tag, &type, &data, &count) != 1) { + return 0; + } + if (type == RPM_STRING_TYPE) { + str = (char*)data; + } else { + cout << _("oh shit, not handled for ")<Error(_("Corrupt pkglist: no RPMTAG_NAME in header entry")); + return string(); + } + else + { + bool dupok = false; + string name = string(str); + + if (AllowedDupPackages != NULL) + { + for (slist::iterator iter = AllowedDupPackages->begin(); + iter != AllowedDupPackages->end(); + iter++) + { + if (regexec(*iter,str,0,0,0) == 0) + { + dupok = true; + break; + } + } + } + +#ifdef DUPPACK + /* + * If this package can have multiple versions installed at + * the same time, then we make it so that the name of the + * package is NAME+"#"+VERSION and also adds a provides + * with the original name and version, to satisfy the + * dependencies. + */ + if (dupok) + { + string bla = name+"#"+Version(); + duplicated = true; + return bla; + } else if (DupPackages) { + string res = string(str); + + if (DupPackages->find(res) != DupPackages->end() + && (*DupPackages)[res] != offset) { + _error->Error(_("There are two or more versions of the package '%s' installed in your " + "system, which is a situation APT can't handle cleanly at the moment.\n" + "Please do one of the following:\n" + "1) Remove the older packages, leaving only one version installed; or\n" + "2) If you do want to have multiple versions of that package, add the " + "package names to the RPM::AllowedDupPkgs option.\n"), + str); + (*DupPackages)[res] = offset; + return string(); + } + (*DupPackages)[res] = offset; + } +#endif + return name; + } +} + /*}}}*/ +// ListParser::Arch - Return the architecture string /*{{{*/ +// --------------------------------------------------------------------- +string rpmListParser::Architecture() +{ + int type, count; + char *arch; + int res; + + res = headerGetEntry(header, RPMTAG_ARCH, &type, (void **)&arch, &count); + + assert(res); + + return string(arch); +} + /*}}}*/ +// ListParser::Version - Return the version string /*{{{*/ +// --------------------------------------------------------------------- +/* This is to return the string describing the version in RPM form, + version-release. If this returns the blank string then the + entry is assumed to only describe package properties */ +string rpmListParser::Version() +{ + char *ver, *rel; + int_32 *ser; + bool has_serial = false; + int type, count; + string str; + + if (headerGetEntry(header, RPMTAG_EPOCH, &type, (void **)&ser, &count)==1 + && count > 0) + { + has_serial = true; + } + + headerGetEntry(header, RPMTAG_VERSION, &type, (void **)&ver, &count); + + headerGetEntry(header, RPMTAG_RELEASE, &type, (void **)&rel, &count); + + if (has_serial) + { + char buf[32]; + snprintf(buf, sizeof(buf), "%i", *ser); + + str = string(buf)+":"+string(ver)+"-"+string(rel); + } + else + { + str = string(ver)+"-"+string(rel); + } + + return str; +} +/*}}}*/ +// ListParser::NewVersion - Fill in the version structure /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool rpmListParser::NewVersion(pkgCache::VerIterator Ver) +{ + int count, type; + int_32 *num; + + // Parse the section + Ver->Section = UniqFindTagWrite(RPMTAG_GROUP); + Ver->Arch = UniqFindTagWrite(RPMTAG_ARCH); + + // Archive Size + headerGetEntry(header, CRPMTAG_FILESIZE, &type, (void**)&num, &count); + if (count > 0) + Ver->Size = (unsigned)num[0]; + else + Ver->Size = 1; + + // Unpacked Size (in kbytes) + headerGetEntry(header, RPMTAG_SIZE, &type, (void**)&num, &count); + Ver->InstalledSize = (unsigned)num[0]; + +// Ver->InstalledSize /= 1024; + + if (ParseDepends(Ver,pkgCache::Dep::Depends) == false) + return false; + /* + * We consider both Requires and PreRequires as simple Depends, + * because that differentiation is only used for package ordering. + * Since we delegate package ordering to rpm, it won't be usefull + * in APT anyway. + if (ParseDepends(Ver,pkgCache::Dep::PreDepends) == false) + return false; + */ + if (ParseDepends(Ver,pkgCache::Dep::Conflicts) == false) + return false; + if (ParseDepends(Ver,pkgCache::Dep::Obsoletes) == false) + return false; + if (ProcessFileProvides(Ver) == false) + return false; + + if (ParseProvides(Ver) == false) + return false; + + return true; +} +/*}}}*/ +// ListParser::UsePackage - Update a package structure /*{{{*/ +// --------------------------------------------------------------------- +/* This is called to update the package with any new information + that might be found in the section */ +bool rpmListParser::UsePackage(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver) +{ + RPMPackageData *rpmdata; + + rpmdata = RPMPackageData::Singleton(); + if (_error->PendingError()) + return false; + if (Pkg->Section == 0) + Pkg->Section = UniqFindTagWrite(RPMTAG_GROUP); + + Ver->Priority = rpmdata->PackagePriority(string(Pkg.Name())); + + if (Ver->Priority == pkgCache::State::Important) + Pkg->Flags |= pkgCache::Flag::Essential; + + if (Ver->Priority == pkgCache::State::Required || + Ver->Priority == pkgCache::State::Important) + Pkg->Flags |= pkgCache::Flag::Important; + + if (ParseStatus(Pkg,Ver) == false) + return false; + + return true; +} +/*}}}*/ +// ListParser::VersionHash - Compute a unique hash for this version /*{{{*/ +// --------------------------------------------------------------------- +/* */ + +static int compare(const void *a, const void *b) +{ + return strcmp(*(char**)a, *(char**)b); +} + + +unsigned short rpmListParser::VersionHash() +{ + int Sections[] ={ + RPMTAG_REQUIRENAME, + RPMTAG_OBSOLETENAME, + RPMTAG_CONFLICTNAME, + 0 + // "Pre-Depends", + // "Conflicts", + }; + unsigned long Result = INIT_FCS; + char S[300]; + char *I; + + for (const int *sec = Sections; *sec != 0; sec++) + { + char *Start; + char *End; + int type, count; + int res; + char **strings; + + res = headerGetEntry(header, *sec, &type, (void **)&strings, &count); + if (res != 1 || count == 0) { + continue; + } + + qsort(strings, count, sizeof(char*), compare); + + switch (type) { + case RPM_STRING_ARRAY_TYPE: + while (count-- > 0) { + Start = strings[count]; + + End = Start+strlen(Start); + + if (End - Start >= (signed)sizeof(S)) + continue; + + /* Strip out any spaces from the text */ + I = S; + for (; Start != End; Start++) { + if (isspace(*Start) == 0) + *I++ = *Start; + } + + Result = AddCRC16(Result,S,I - S); + +// free(strings); + } + break; + + case RPM_STRING_TYPE: + Start = (char*)strings; + + End = Start+strlen(Start); + + if (End - Start >= (signed)sizeof(S)) + continue; + + /* Strip out any spaces from the text */ + I = S; + for (; Start != End; Start++) { + if (isspace(*Start) == 0) + *I++ = *Start; + } + Result = AddCRC16(Result,S,I - S); + + break; + } + } + + return Result; +} +/*}}}*/ +// ListParser::ParseStatus - Parse the status field /*{{{*/ +// --------------------------------------------------------------------- +bool rpmListParser::ParseStatus(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver) +{ + if (parsing_hdlist) { // this means we're parsing a hdlist, so it's not installed + return true; + } + + // if we're reading from the rpmdb, then it's installed + + bool hold = false; + + if (HoldPackages != NULL) + { + const char *str = Package().c_str(); + + for (slist::iterator iter = HoldPackages->begin(); + iter != HoldPackages->end(); + iter++) + { + if (regexec(*iter,str,0,0,0) == 0) + { + hold = true; + break; + } + } + } + + if (hold) { + Pkg->SelectedState = pkgCache::State::Hold; + } else { + Pkg->SelectedState = pkgCache::State::Install; + } + Pkg->InstState = pkgCache::State::Ok; + + + Pkg->CurrentState = pkgCache::State::Installed; + + /* A Status line marks the package as indicating the current + version as well. Only if it is actually installed.. Otherwise + the interesting dpkg handling of the status file creates bogus + entries. */ + if (!(Pkg->CurrentState == pkgCache::State::NotInstalled || + Pkg->CurrentState == pkgCache::State::ConfigFiles)) + { + if (Ver.end() == true) + _error->Warning(_("Encountered status field in a non-version description")); + else + Pkg->CurrentVer = Ver.Index(); + } + + return true; +} + + +bool rpmListParser::ParseDepends(pkgCache::VerIterator Ver, + char **namel, char **verl, int_32 *flagl, + int count, unsigned int Type) +{ + int i; + unsigned int Op = 0; + + for (i = 0; i < count; i++) { + + /* + if (Type == pkgCache::Dep::Depends) { + if (flagl[i] & RPMSENSE_PREREQ) + continue; + } else if (Type == pkgCache::Dep::PreDepends) { + if (!(flagl[i] & RPMSENSE_PREREQ)) + continue; + } + */ + + /* + * strip-off requires for rpmlib features.. + */ + if (strncmp(namel[i], "rpmlib", 6) == 0) { + if (_config->FindB("RPM::IgnoreRpmlibDeps", false) == false || + rpmCheckRpmlibProvides(namel[i], + verl ? verl[i] : NULL, + flagl[i])) { + continue; + } + } + + if (verl) { + if (!*verl[i]) { + Op = pkgCache::Dep::NoOp; + } else { + if (flagl[i] & RPMSENSE_LESS) { + if (flagl[i] & RPMSENSE_EQUAL) { + Op = pkgCache::Dep::LessEq; + } else { + Op = pkgCache::Dep::Less; + } + } else if (flagl[i] & RPMSENSE_GREATER) { + if (flagl[i] & RPMSENSE_EQUAL) { + Op = pkgCache::Dep::GreaterEq; + } else { + Op = pkgCache::Dep::Greater; + } + } else if (flagl[i] & RPMSENSE_EQUAL) { + Op = pkgCache::Dep::Equals; + } + } + + if (NewDepends(Ver,string(namel[i]),string(verl[i]),Op,Type) == false) + return false; + } else { + if (NewDepends(Ver,string(namel[i]),string(),pkgCache::Dep::NoOp, + Type) == false) + return false; + } + } + return true; +} +/*}}}*/ + + +// ListParser::ParseDepends - Parse a dependency list /*{{{*/ +// --------------------------------------------------------------------- +/* This is the higher level depends parser. It takes a tag and generates + a complete depends tree for the given version. */ +bool rpmListParser::ParseDepends(pkgCache::VerIterator Ver, + unsigned int Type) +{ + char **namel = NULL; + char **verl = NULL; + int *flagl = NULL; + int res, type, count; + + switch (Type) { + case pkgCache::Dep::Depends: + case pkgCache::Dep::PreDepends: + res = headerGetEntry(header, RPMTAG_REQUIRENAME, &type, + (void **)&namel, &count); + if (res != 1) + return true; + res = headerGetEntry(header, RPMTAG_REQUIREVERSION, &type, + (void **)&verl, &count); + res = headerGetEntry(header, RPMTAG_REQUIREFLAGS, &type, + (void **)&flagl, &count); + break; + + case pkgCache::Dep::Obsoletes: + res = headerGetEntry(header, RPMTAG_OBSOLETENAME, &type, + (void **)&namel, &count); + if (res != 1) + return true; + res = headerGetEntry(header, RPMTAG_OBSOLETEVERSION, &type, + (void **)&verl, &count); + res = headerGetEntry(header, RPMTAG_OBSOLETEFLAGS, &type, + (void **)&flagl, &count); + break; + + case pkgCache::Dep::Conflicts: + res = headerGetEntry(header, RPMTAG_CONFLICTNAME, &type, + (void **)&namel, &count); + if (res != 1) + return true; + res = headerGetEntry(header, RPMTAG_CONFLICTVERSION, &type, + (void **)&verl, &count); + res = headerGetEntry(header, RPMTAG_CONFLICTFLAGS, &type, + (void **)&flagl, &count); + break; + + default: + cout << "not implemented!!!\n"; + abort(); + } + + ParseDepends(Ver, namel, verl, flagl, count, Type); + +// free(namel); +// if (verl) free(verl); + + return true; +} +/*}}}*/ + + + +bool rpmListParser::ProcessFileProvides(pkgCache::VerIterator Ver) +{ + const char **names = NULL; + int count = 0; + + rpmBuildFileList(header, &names, &count); + +#if 1 + while (count--) { + /* if some pkg depends on the file, add it to the provides list */ + if (filedeps->find(string(names[count])) != filedeps->end()) { + if (!NewProvides(Ver, string(names[count]), string())) { +// free(names); + return false; + } + } + } +#else + for (map::iterator i = filedeps->begin(); + i!=filedeps->end(); + i++) { + const char *file = (*i).first.c_str(); + + if (bsearch(file, names, count, sizeof(char*), + (int (*)(const void *, const void *))strcmp)) { + if (!NewProvides(Ver, string(file), string())) + return false; + } + } +#endif + +// free(names); + + return true; +} + +// ListParser::ParseProvides - Parse the provides list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool rpmListParser::ParseProvides(pkgCache::VerIterator Ver) +{ + int type, count; + char **namel = NULL; + char **verl = NULL; + int res; + bool ok = true; + +#ifdef DUPPACK + if (duplicated) { + char *name; + headerGetEntry(header, RPMTAG_NAME, &type, (void **)&name, &count); + NewProvides(Ver, string(name), Version()); + } +#endif + + res = headerGetEntry(header, RPMTAG_PROVIDENAME, &type, + (void **)&namel, &count); + if (res != 1) + return true; + /* + res = headerGetEntry(header, RPMTAG_PROVIDEFLAGS, &type, + (void **)&flagl, &count); + if (res != 1) + return true; + */ + res = headerGetEntry(header, RPMTAG_PROVIDEVERSION, &type, + (void **)&verl, NULL); + if (res != 1) + verl = NULL; + + for (int i = 0; i < count; i++) { + if (verl && *verl[i]) { + if (NewProvides(Ver,string(namel[i]),string(verl[i])) == false) { + ok = false; + break; + } + } else { + if (NewProvides(Ver,string(namel[i]),string()) == false) { + ok = false; + break; + } + } + } + + return ok; +} +/*}}}*/ + +Header rpmListParser::NextHeader() +{ + Header h; + + if (parsing_hdlist) { + FD_t fdt = fdDup(file->Fd()); + offset = file->Tell(); + h = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + } else { + unsigned bla1, bla2; + h = pkgRpmLock::SharedRPM()->NextHeader(); + pkgRpmLock::SharedRPM()->Offset(bla1, bla2); + offset = bla2; + } + + return h; +} + + +bool rpmListParser::ShouldBeIgnored(string pkg) +{ + // check whether this package must be ignored + // usually because user installed it with --nodeps + // use with moderation + + const Configuration::Item *Top = _config->Tree("RPM::IgnorePkgs"); + + for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next) + { + if (Top->Value == pkg) + return true; + } + + return false; +} + +// ListParser::Step - Move to the next section in the file /*{{{*/ +// --------------------------------------------------------------------- +/* This has to be carefull to only process the correct architecture */ +bool rpmListParser::Step() +{ + Header tmp; + + while ((tmp = NextHeader()) != NULL) + { + /* See if this is the correct Architecture, if it isn't then we + drop the whole section. A missing arch tag can't happen to us */ + int type; + string arch; + int count; + bool res; + bool archOk = false; + + if (header) + headerFree(header); + header = tmp; + + arch = Architecture(); + + string pkg = Package(); + if (!duplicated) { + pkg = pkg+'#'+Version(); + } + + if (ShouldBeIgnored(string(pkg.c_str(),pkg.find('#'))) == true) + continue; + + if (multiarchs->find(pkg) != multiarchs->end()) { + if (arch == (*multiarchs)[pkg]) { + archOk = true; + } + } else { + if (rpmMachineScore(RPM_MACHTABLE_INSTARCH, arch.c_str()) > 0) + archOk = true; + else + archOk = false; + } + + if (!parsing_hdlist || archOk) { + return true; + } + } + + if (header) + headerFree(header); + header = NULL; + + return false; +} +/*}}}*/ +// ListParser::LoadReleaseInfo - Load the release information /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool rpmListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI, + FileFd &File) +{ + pkgTagFile Tags(File); + pkgTagSection Section; + if (!Tags.Step(Section)) + return false; + + const char *Start; + const char *Stop; + if (Section.Find("Archive",Start,Stop)) + FileI->Archive = WriteUniqString(Start,Stop - Start); + if (Section.Find("Component",Start,Stop)) + FileI->Component = WriteUniqString(Start,Stop - Start); + if (Section.Find("Version",Start,Stop)) + FileI->Version = WriteUniqString(Start,Stop - Start); + if (Section.Find("Origin",Start,Stop)) + FileI->Origin = WriteUniqString(Start,Stop - Start); + if (Section.Find("Label",Start,Stop)) + FileI->Label = WriteUniqString(Start,Stop - Start); + if (Section.Find("Architecture",Start,Stop)) + FileI->Architecture = WriteUniqString(Start,Stop - Start); + + if (Section.FindFlag("NotAutomatic",FileI->Flags, + pkgCache::Flag::NotAutomatic) == false) + _error->Warning("Bad NotAutomatic flag"); + + return !_error->PendingError(); +} +/*}}}*/ + + +unsigned long rpmListParser::Size() +{ + uint_32 *size; + int type, count; + + if (headerGetEntry(header, RPMTAG_SIZE, &type, (void **)&size, &count)!=1) + return 1; + + return size[0]/1024; +} diff --git a/apt/apt-pkg/rpm/rpmlistparser.h b/apt/apt-pkg/rpm/rpmlistparser.h new file mode 100644 index 0000000..43f125c --- /dev/null +++ b/apt/apt-pkg/rpm/rpmlistparser.h @@ -0,0 +1,93 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rpmlistparser.h,v 1.15 2001/11/30 20:34:13 kojima Exp $ +/* ###################################################################### + + Debian Package List Parser - This implements the abstract parser + interface for rpmian package files + + ##################################################################### + */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_RPMLISTPARSER_H +#define PKGLIB_RPMLISTPARSER_H + +#include +#include +#include +#include +#include +#include + +class rpmListParser : public pkgCacheGenerator::ListParser +{ + Header header; + FileFd *file; + unsigned long offset; + + vector Essentials; + vector Importants; + + map *filedeps; + map *multiarchs; + + map *DupPackages; + slist *AllowedDupPackages; + bool duplicated; + + slist *HoldPackages; + + bool parsing_hdlist; + + char *Arch; + char *BaseArch; + + // Parser Helper + struct WordList + { + char *Str; + unsigned char Val; + }; + + bool GetConfig(); + + bool IsMultiArch(string package); + + unsigned long UniqFindTagWrite(int Tag); + bool ParseStatus(pkgCache::PkgIterator Pkg,pkgCache::VerIterator Ver); + bool ParseDepends(pkgCache::VerIterator Ver, + char **namel, char **verl, int_32 *flagl, + int count, unsigned int Type); + bool ParseDepends(pkgCache::VerIterator Ver, unsigned int Type); + bool ParseProvides(pkgCache::VerIterator Ver); + + bool ProcessFileProvides(pkgCache::VerIterator Ver); + + Header NextHeader(); + + bool ShouldBeIgnored(string pkg); + + public: + + // These all operate against the current header + virtual string Package(); + virtual string Version(); + virtual string Architecture(); + virtual bool NewVersion(pkgCache::VerIterator Ver); + virtual unsigned short VersionHash(); + virtual bool UsePackage(pkgCache::PkgIterator Pkg, + pkgCache::VerIterator Ver); + virtual unsigned long Offset() {return offset;}; + virtual unsigned long Size(); + + virtual bool Step(); + + bool LoadReleaseInfo(pkgCache::PkgFileIterator FileI,FileFd &File); + + rpmListParser(FileFd &File, map *fdeps, map *marchs); + rpmListParser(map *fdeps, map *marchs); + ~rpmListParser(); +}; + +#endif diff --git a/apt/apt-pkg/rpm/rpmpackagedata.cc b/apt/apt-pkg/rpm/rpmpackagedata.cc new file mode 100644 index 0000000..0ebd481 --- /dev/null +++ b/apt/apt-pkg/rpm/rpmpackagedata.cc @@ -0,0 +1,70 @@ + +#include + +#include +#include +#include +#include +#include + +#include + + + +RPMPackageData::RPMPackageData() +{ + string path = _config->FindFile("Dir::Etc::RpmPriorities"); + FileFd F(path, FileFd::ReadOnly); + if (_error->PendingError()) + { + _error->Error(_("could not open package priority file %s"), path.c_str()); + return; + } + pkgTagFile Tags(F); + pkgTagSection Section; + + if (!Tags.Step(Section)) + { + _error->Error(_("no data in %s"), path.c_str()); + return; + } + + for (int i = 0; i < 5; i++) + { + static const char *priorities[] = + { + "Important", "Required", "Standard", "Optional", "Extra" + }; + static pkgCache::State::VerPriority states[] = { + pkgCache::State::Important, + pkgCache::State::Required, + pkgCache::State::Standard, + pkgCache::State::Optional, + pkgCache::State::Extra + }; + + string Packages = Section.FindS(priorities[i]); + if (Packages.empty()) + continue; + + const char *C = Packages.c_str(); + while (*C != 0) + { + string pkg; + + if (ParseQuoteWord(C,pkg)) + Priorities[pkg] = states[i]; + } + } +} + + +RPMPackageData *RPMPackageData::Singleton() +{ + static RPMPackageData *data = NULL; + + if (!data) + data = new RPMPackageData(); + + return data; +} diff --git a/apt/apt-pkg/rpm/rpmpackagedata.h b/apt/apt-pkg/rpm/rpmpackagedata.h new file mode 100644 index 0000000..640dbd6 --- /dev/null +++ b/apt/apt-pkg/rpm/rpmpackagedata.h @@ -0,0 +1,31 @@ + +#ifndef _RPMPACKAGEDATA_H_ +#define _RPMPACKAGEDATA_H_ + + +#include +#include + +#include + +class RPMPackageData +{ +protected: + map Priorities; + +public: + inline pkgCache::State::VerPriority PackagePriority(string Package) + { + if (Priorities.find(Package) == Priorities.end()) + return pkgCache::State::Standard; + else + return Priorities[Package]; + } + + static RPMPackageData *Singleton(); + + RPMPackageData(); +}; + + +#endif diff --git a/apt/apt-pkg/rpm/rpmpm.cc b/apt/apt-pkg/rpm/rpmpm.cc new file mode 100644 index 0000000..e37c739 --- /dev/null +++ b/apt/apt-pkg/rpm/rpmpm.cc @@ -0,0 +1,571 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + RPM Package Manager - Provide an interface to rpm + + ##################################################################### + */ + /*}}}*/ +// Includes /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/rpmpm.h" +#endif + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include + +#include + /*}}}*/ +// RPMPM::pkgRPMPM - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgRPMPM::pkgRPMPM(pkgDepCache &Cache) : pkgPackageManager(Cache) +{ + noninteractive = false; +} + /*}}}*/ +// RPMPM::pkgRPMPM - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgRPMPM::~pkgRPMPM() +{ +} + /*}}}*/ +// RPMPM::Install - Install a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add an install operation to the sequence list */ +bool pkgRPMPM::Install(PkgIterator Pkg,string File) +{ + if (File.empty() == true || Pkg.end() == true) + return _error->Error(_("Internal Error, No file name for %s"),Pkg.Name()); + + List.push_back(Item(Item::Install,Pkg,File)); + return true; +} + /*}}}*/ +// RPMPM::Configure - Configure a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add a configure operation to the sequence list */ +bool pkgRPMPM::Configure(PkgIterator Pkg) +{ + if (Pkg.end() == true) { + return false; + } + +// List.push_back(Item(Item::Configure,Pkg)); + return true; +} + /*}}}*/ +// RPMPM::Remove - Remove a package /*{{{*/ +// --------------------------------------------------------------------- +/* Add a remove operation to the sequence list */ +bool pkgRPMPM::Remove(PkgIterator Pkg,bool Purge) +{ + if (Pkg.end() == true) + return false; + +// if (Purge == true) +// List.push_back(Item(Item::Purge,Pkg)); +// else + List.push_back(Item(Item::Remove,Pkg)); + return true; +} + /*}}}*/ +// RPMPM::RunScripts - Run a set of scripts /*{{{*/ +// --------------------------------------------------------------------- +/* This looks for a list of script sto run from the configuration file, + each one is run with system from a forked child. */ +bool pkgRPMPM::RunScripts(const char *Cnf) +{ + Configuration::Item const *Opts = _config->Tree(Cnf); + if (Opts == 0 || Opts->Child == 0) + return true; + Opts = Opts->Child; + + // Fork for running the system calls + pid_t Child = ExecFork(); + + // This is the child + if (Child == 0) + { + if (chdir("/tmp/") != 0) + _exit(100); + + unsigned int Count = 1; + for (; Opts != 0; Opts = Opts->Next, Count++) + { + if (Opts->Value.empty() == true) + continue; + + if (system(Opts->Value.c_str()) != 0) + _exit(100+Count); + } + _exit(0); + } + + // Wait for the child + int Status = 0; + while (waitpid(Child,&Status,0) != Child) + { + if (errno == EINTR) + continue; + return _error->Errno("waitpid",_("Couldn't wait() for subprocess")); + } + + // Restore sig int/quit + signal(SIGQUIT,SIG_DFL); + signal(SIGINT,SIG_DFL); + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + { + unsigned int Count = WEXITSTATUS(Status); + if (Count > 100) + { + Count -= 100; + for (; Opts != 0 && Count != 1; Opts = Opts->Next, Count--); + _error->Error(_("Problem executing scripts %s '%s'"),Cnf,Opts->Value.c_str()); + } + + return _error->Error(_("Sub-process returned an error code")); + } + + return true; +} + + /*}}}*/ +// RPMPM::RunScriptsWithPkgs - Run scripts with package names on stdin /*{{{*/ +// --------------------------------------------------------------------- +/* This looks for a list of scripts to run from the configuration file + each one is run and is fed on standard input a list of all .deb files + that are due to be installed. */ +bool pkgRPMPM::RunScriptsWithPkgs(const char *Cnf) +{ + Configuration::Item const *Opts = _config->Tree(Cnf); + if (Opts == 0 || Opts->Child == 0) + return true; + Opts = Opts->Child; + + unsigned int Count = 1; + for (; Opts != 0; Opts = Opts->Next, Count++) + { + if (Opts->Value.empty() == true) + continue; + + // Create the pipes + int Pipes[2]; + if (pipe(Pipes) != 0) + return _error->Errno("pipe",_("Failed to create IPC pipe to subprocess")); + SetCloseExec(Pipes[0],true); + SetCloseExec(Pipes[1],true); + + // Purified Fork for running the script + pid_t Process = ExecFork(); + if (Process == 0) + { + // Setup the FDs + dup2(Pipes[0],STDIN_FILENO); + SetCloseExec(STDOUT_FILENO,false); + SetCloseExec(STDIN_FILENO,false); + SetCloseExec(STDERR_FILENO,false); + + const char *Args[4]; + Args[0] = "/bin/sh"; + Args[1] = "-c"; + Args[2] = Opts->Value.c_str(); + Args[3] = 0; + execv(Args[0],(char **)Args); + _exit(100); + } + close(Pipes[0]); + FileFd Fd(Pipes[1]); + + // Feed it the filenames. + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + // Only deal with packages to be installed from .rpm + if (I->Op != Item::Install) + continue; + + // No errors here.. + if (I->File[0] != '/') + continue; + + /* Feed the filename of each package that is pending install + into the pipe. */ + if (Fd.Write(I->File.begin(),I->File.length()) == false || + Fd.Write("\n",1) == false) + { + kill(Process,SIGINT); + Fd.Close(); + ExecWait(Process,Opts->Value.c_str(),true); + return _error->Error(_("Failure running script %s"),Opts->Value.c_str()); + } + } + Fd.Close(); + + // Clean up the sub process + if (ExecWait(Process,Opts->Value.c_str()) == false) + return _error->Error(_("Failure running script %s"),Opts->Value.c_str()); + } + + return true; +} + + /*}}}*/ + +bool pkgRPMPM::ExecRPM(Operation operation, slist *files, bool nodeps) +{ + // Generate the argument list + const char *Args[10000]; + unsigned int n = 0; + string options; + + Args[n++] = _config->Find("Dir::Bin::rpm","rpm").c_str(); + + // Stick in any custom rpm options + Configuration::Item const *Opts = _config->Tree("RPM::Options"); + if (Opts != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + Args[n++] = Opts->Value.c_str(); + } + } + + switch (operation) { + case OInstall: + case OUpgrade: + Opts = _config->Tree("RPM::UpgradeOptions"); + break; + + case ORemove: + Opts = _config->Tree("RPM::RemoveOptions"); + break; + + case OCheckSignature: + break; + } + + if (Opts != 0) + { + Opts = Opts->Child; + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + Args[n++] = Opts->Value.c_str(); + } + } + + string rootdir = _config->Find("RPM::RootDir", ""); + if (!rootdir.empty()) { + Args[n++] = "-r"; + Args[n++] = rootdir.c_str(); + } + + + switch (operation) { + case OInstall: + options = "-i"; + + Args[n++] = "-i"; + + Args[n++] = "--replacepkgs"; + + if (noninteractive) + Args[n++] = "--percent"; + else + Args[n++] = "-h"; + + if (_config->FindB("RPM::Force", false) == true) + Args[n++] = "--force"; + + break; + + case OUpgrade: + options = "-U"; + Args[n++] = "-Uv"; + + Args[n++] = "--replacepkgs"; + + if (noninteractive) + Args[n++] = "--percent"; + else + Args[n++] = "-h"; + + if (_config->FindB("RPM::Force", false) == true) + Args[n++] = "--force"; + break; + + case ORemove: + options = "-e"; + Args[n++] = "-e"; + break; + + case OCheckSignature: + options = "-K"; + Args[n++] = "-Kv"; + break; + } + + if (nodeps) + Args[n++] = "--nodeps"; + + + for (slist::iterator i = files->begin(); + i != files->end() && n < sizeof(Args); + i++) + { + Args[n++] = *i; + } + Args[n++] = 0; + + + // spit out command line for debugging + if (_config->FindB("Debug::pkgRPMPM",false) == true) + { + for (unsigned int k = 0; k < n; k++) + clog << Args[k] << ' '; + clog << endl; + return true; + } + + cout << _("Executing RPM (")<FindDir("RPM::Run-Directory","/").c_str()) != 0) + _exit(100); + + if (_config->FindB("RPM::FlushSTDIN",true) == true) + { + int Flags,dummy; + if ((Flags = fcntl(STDIN_FILENO,F_GETFL,dummy)) < 0) + _exit(100); + + // Discard everything in stdin before forking + if (fcntl(STDIN_FILENO,F_SETFL,Flags | O_NONBLOCK) < 0) + _exit(100); + + while (read(STDIN_FILENO,&dummy,1) == 1); + + if (fcntl(STDIN_FILENO,F_SETFL,Flags & (~(long)O_NONBLOCK)) < 0) + _exit(100); + } + + execvp(Args[0],(char **)Args); + cerr << _("Could not exec() ") << Args[0] << endl; + _exit(100); + } + + // Wait for rpm + int Status = 0; + while (waitpid(Child,&Status,0) != Child) + { + if (errno == EINTR) + continue; + return _error->Errno("waitpid",_("Couldn't wait for subprocess")); + } + + // Restore sig int/quit + signal(SIGQUIT,SIG_DFL); + signal(SIGINT,SIG_DFL); + + // Check for an error code. + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + { + if (WIFSIGNALED(Status) != 0) + return _error->Error(_("Sub-process %s terminated by signal (%i)") ,Args[0], WTERMSIG(Status) ); + + if (WIFEXITED(Status) != 0) + return _error->Error(_("Sub-process %s returned an error code (%u)"),Args[0], + WEXITSTATUS(Status)); + + return _error->Error(_("Sub-process %s exited unexpectedly"),Args[0]); + } + + return true; +} + + +bool pkgRPMPM::Process(slist *install, + slist *upgrade, + slist *uninstall) +{ + if (_config->FindB("RPM::Check-Signatures", false) == true) + { + cout << "Verifying signatures for individual packages..." << endl; + cout << "Package operations will not be performed." << endl; + + if (!install->empty()) + ExecRPM(OCheckSignature, install, false); + + if (!upgrade->empty()) + ExecRPM(OCheckSignature, upgrade, false); + + if (_error->PendingError() == true) + return _error->Error("Errors found while verifying individual package signatures."); + else + return true; + } + + if (!uninstall->empty()) + ExecRPM(ORemove, uninstall, true); + + if (!install->empty()) + ExecRPM(OInstall, install, true); + + if (!upgrade->empty()) + ExecRPM(OUpgrade, upgrade, false); + + return true; +} + + +// RPMPM::Go - Run the sequence /*{{{*/ +// --------------------------------------------------------------------- +/* This globs the operations and calls rpm */ +bool pkgRPMPM::Go() +{ + bool RPMUpgrade = false; + + if (RunScripts("RPM::Pre-Invoke") == false) + return false; + + if (RunScriptsWithPkgs("RPM::Pre-Install-Pkgs") == false) + return false; + + slist *install = new slist; + slist *upgrade = new slist; + slist *uninstall = new slist; + + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + switch (I->Op) + { + case Item::Purge: + case Item::Remove: + if (strchr(I->Pkg.Name(), '#')) + { + char *ptr = strdup(I->Pkg.Name()); + char *p1 = strchr(ptr, '#'); + char *p2 = strrchr(ptr, '#'); + if (p1 == p2) + { + *p1 = '-'; + uninstall->push_front(ptr); // akk: leak + } + else + { + p2 = strrchr(I->Pkg.Name(), '#'); + strcpy(p1, p2); + *p1 = '-'; + uninstall->push_front(ptr); + } + } + else + { + uninstall->push_front((char*)I->Pkg.Name()); + } + break; + + case Item::Configure: +// cout << __FUNCTION__ << ": ignoring request for configure\n"; + break; + + case Item::Install: + // eeek!! yuck!!! bleh!!! blame rpm + if (strcmp(I->Pkg.Name(), "rpm") == 0 + || strcmp(I->Pkg.Name(), "librpm") == 0) + RPMUpgrade = true; + + if (strchr(I->Pkg.Name(), '#')) + { + install->push_front((char*)I->File.c_str()); + } + else + { + upgrade->push_front((char*)I->File.c_str()); + } + break; + + default: + cout << __FUNCTION__ << "UNKNOWN OPERATION!!!!\n"; + break; + } + } + + if (RPMUpgrade == true && _config->FindB("RPM::AutoRebuildDB", true) == true) + { + int res; + + cerr << (_("Rebuilding RPM database (this may take a few minutes)...")) << endl; + + res = rpmdbRebuild(_config->FindDir("RPM::RootDir", "/").c_str()); + if (res != 0) + return _error->Error(_("could not rebuild RPM database for upgrade of RPM")); + } + + bool result = Process(install, upgrade, uninstall); + + delete install; + delete upgrade; + delete uninstall; + + if (!result) { + RunScripts("RPM::Post-Invoke"); + return false; + } + + if (RunScripts("RPM::Post-Invoke") == false) + return false; + + if (RunScriptsWithPkgs("RPM::Post-Invoke-Pkgs") == false) + return false; + + return true; +} + /*}}}*/ +// pkgRPMPM::Reset - Dump the contents of the command list /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void pkgRPMPM::Reset() +{ + List.erase(List.begin(),List.end()); +} + /*}}}*/ diff --git a/apt/apt-pkg/rpm/rpmpm.h b/apt/apt-pkg/rpm/rpmpm.h new file mode 100644 index 0000000..19d56aa --- /dev/null +++ b/apt/apt-pkg/rpm/rpmpm.h @@ -0,0 +1,73 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rpmpm.h,v 1.6 2001/11/12 16:04:38 kojima Exp $ +/* ###################################################################### + + rpm Package Manager - Provide an interface to rpm + + ##################################################################### + */ + /*}}}*/ +#ifndef PKGLIB_rpmPM_H +#define PKGLIB_rpmPM_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/rpmpm.h" +#endif + +#include +#include +#include + + +class pkgRPMPM : public pkgPackageManager +{ + bool noninteractive; + + protected: + + struct Item + { + enum Ops {Install, Configure, Remove, Purge} Op; + string File; + PkgIterator Pkg; + Item(Ops Op,PkgIterator Pkg,string File = "") : Op(Op), + File(File), Pkg(Pkg) {}; + Item() {}; + + }; + + enum Operation { OInstall, OUpgrade, ORemove, OCheckSignature }; + + vector List; + + // Helpers + bool RunScripts(const char *Cnf); + bool RunScriptsWithPkgs(const char *Cnf); + + // The Actuall installation implementation + virtual bool Install(PkgIterator Pkg,string File); + virtual bool Configure(PkgIterator Pkg); + virtual bool Remove(PkgIterator Pkg,bool Purge = false); + + bool ExecRPM(Operation operation, slist *files, bool nodeps); + bool Process(slist *install, + slist *upgrade, + slist *uninstall); + + virtual bool Go(); + virtual void Reset(); + + public: + + pkgRPMPM(pkgDepCache &Cache); + virtual ~pkgRPMPM(); + + void setNonInteractive() { noninteractive = true; }; +}; + + + + + +#endif diff --git a/apt/apt-pkg/rpm/rpmrecords.cc b/apt/apt-pkg/rpm/rpmrecords.cc new file mode 100644 index 0000000..bd4693b --- /dev/null +++ b/apt/apt-pkg/rpm/rpmrecords.cc @@ -0,0 +1,196 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +/* ###################################################################### + + RPM Package Records - Parser for RPM package records + + ##################################################################### + */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/rpmrecords.h" +#endif + +#include + +#include +#include +#include + +#include + +// RecordParser::rpmRecordParser - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +rpmRecordParser::rpmRecordParser(string File, pkgCache &Cache) +{ + string RPMFile = "packages.rpm"; +#ifdef HAVE_RPM4 + if (rpmExpandNumeric("%{_dbapi}") == 3) + RPMFile = "Packages"; +#endif + + if (File.find(RPMFile) != string::npos) { + // read from the rpm db + Fd = NULL; + pkgRpmLock::SharedRPM()->Rewind(); + } else { + Fd = new FileFd(File, FileFd::ReadOnly); + } + Offset = 0; + header = NULL; +} + /*}}}*/ +rpmRecordParser::~rpmRecordParser() +{ + if (Fd) { + delete Fd; + } + if (header) + headerFree(header); +} +// RecordParser::Jump - Jump to a specific record /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool rpmRecordParser::Jump(pkgCache::VerFileIterator const &Ver) +{ + if (header) + headerFree(header); + + if (Fd) { + Offset = Ver->Offset; + Fd->Seek(Offset); + FD_t fdt = fdDup(Fd->Fd()); + header = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + } else { + Offset = Ver->Offset; + header = pkgRpmLock::SharedRPM()->GetRecord(Offset); + } + + if (header != NULL) + return true; + else + return false; +} + /*}}}*/ +// RecordParser::FileName - Return the archive filename on the site /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string rpmRecordParser::FileName() +{ + char *str; + int_32 count, type; + + headerGetEntry(header, CRPMTAG_FILENAME, &type, (void**)&str, &count); + + string tmp = string(str); + + return tmp; +} + /*}}}*/ +// RecordParser::MD5Hash - Return the archive hash /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string rpmRecordParser::MD5Hash() +{ + char *str; + int_32 count, type; + + if (headerGetEntry(header, CRPMTAG_MD5, &type, (void**)&str, &count)!=1) { + return string(); + } else { + return string(str); + } +} + /*}}}*/ +// RecordParser::Maintainer - Return the maintainer email /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string rpmRecordParser::Maintainer() +{ + char *str = NULL; + int_32 count, type; + + headerGetEntry(header, RPMTAG_PACKAGER, &type, (void**)&str, &count); + + if (!str) + return ""; + + string tmp = string(str); + return tmp; +} + /*}}}*/ +// RecordParser::ShortDesc - Return a 1 line description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string rpmRecordParser::ShortDesc() +{ + string Res; + char *str = NULL; + int_32 count, type; + + headerGetEntry(header, RPMTAG_SUMMARY, &type, (void**)&str, &count); + + if (!str) + return ""; + + Res = string(str); + string::size_type Pos = Res.find('\n'); + if (Pos == string::npos) + return Res; + return string(Res,0,Pos); +} + /*}}}*/ +// RecordParser::LongDesc - Return a longer description /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string rpmRecordParser::LongDesc() +{ + char *str = NULL, *str2, *x, *y; + int_32 count, type; + int n, s; + + headerGetEntry(header, RPMTAG_DESCRIPTION, &type, (void**)&str, &count); + + if (!str) + return ""; + + // Ouch! + for (x = str, s = n = 0; *x; x++, s++) { + if (*x == '\n') + n++; + } + str2 = (char *)malloc (s + n + 4); + for (x = str, y = str2; *x; x++, y++) { + *y = *x; + if (*x == '\n') + *++y = ' '; + } + *y = 0; + for (y--; (*y == ' ' || *y == '\n') && y > str2; y--) + *y = 0; + + string tmp = string(str2); + + free(str2); + + return tmp; +} + /*}}}*/ +// RecordParser::SourcePkg - Return the source package name if any /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string rpmRecordParser::SourcePkg() +{ + char *str; + int_32 count, type; + + if (headerGetEntry(header, RPMTAG_SOURCERPM, &type, (void**)&str, &count)==0) { + string tmp = string(str); + return tmp; + } else + return string(); +} + /*}}}*/ diff --git a/apt/apt-pkg/rpm/rpmrecords.h b/apt/apt-pkg/rpm/rpmrecords.h new file mode 100644 index 0000000..049ca4b --- /dev/null +++ b/apt/apt-pkg/rpm/rpmrecords.h @@ -0,0 +1,57 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rpmrecords.h,v 1.3 2001/06/05 17:14:24 kojima Exp $ +/* ###################################################################### + + RPM Package Records - Parser for RPM hdlist/rpmdb files + + This provides display-type parsing for the Packages file. This is + different than the the list parser which provides cache generation + services. There should be no overlap between these two. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_RPMRECORDS_H +#define PKGLIB_RPMRECORDS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/rpmrecords.h" +#endif + + +#include +#include +#include + +class rpmRecordParser : public pkgRecords::Parser +{ + FileFd *Fd; + unsigned Offset; + + Header header; + + protected: + + virtual bool Jump(pkgCache::VerFileIterator const &Ver); + + public: + + // These refer to the archive file for the Version + virtual string FileName(); + virtual string MD5Hash(); + virtual string SourcePkg(); + + // These are some general stats about the package + virtual string Maintainer(); + virtual string ShortDesc(); + virtual string LongDesc(); + + inline Header GetRecord() { return header; }; + + rpmRecordParser(string File,pkgCache &Cache); + ~rpmRecordParser(); +}; + + +#endif diff --git a/apt/apt-pkg/rpm/rpmsrcrecords.cc b/apt/apt-pkg/rpm/rpmsrcrecords.cc new file mode 100644 index 0000000..fbe4108 --- /dev/null +++ b/apt/apt-pkg/rpm/rpmsrcrecords.cc @@ -0,0 +1,225 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rpmsrcrecords.cc,v 1.5 2001/11/13 17:32:08 kojima Exp $ +/* ###################################################################### + + SRPM Records - Parser implementation for RPM style source indexes + + ##################################################################### + */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/rpmsrcrecords.h" +#endif + +#include +#include +#include +#include /*}}}*/ + +#include + +rpmSrcRecordParser::rpmSrcRecordParser(FileFd *F, pkgSourceList::const_iterator SrcItem) + : Parser(F, SrcItem) +{ +} + + + + + +// SrcRecordParser::Binaries - Return the binaries field /*{{{*/ +// --------------------------------------------------------------------- +/* This member parses the binaries field into a pair of class arrays and + returns a list of strings representing all of the components of the + binaries field. The returned array need not be freed and will be + reused by the next Binaries function call. */ +const char **rpmSrcRecordParser::Binaries() +{ + int i = 0; + char **bins; + int type, count; + + if (headerGetEntry(header, CRPMTAG_BINARY, &type, (void**)&bins, &count)!=1) + return NULL; + for (i = 0; (unsigned)i < sizeof(StaticBinList)/sizeof(char*) && i < count; i++) + { + StaticBinList[i] = bins[i]; + } + StaticBinList[i] = 0; +// free(bins); + + return StaticBinList; +} + /*}}}*/ +// SrcRecordParser::Files - Return a list of files for this source /*{{{*/ +// --------------------------------------------------------------------- +/* This parses the list of files and returns it, each file is required to have + a complete source package */ +bool rpmSrcRecordParser::Files(vector &List) +{ + char *srpm, *md5; + char *dir; + int type, count; + int_32 *size; + + List.erase(List.begin(),List.end()); + + if (headerGetEntry(header, CRPMTAG_FILENAME, &type, (void**)&srpm, &count)==0) + return false; + + if (headerGetEntry(header, CRPMTAG_MD5, &type, (void**)&md5, &count)==0) + { + return _error->Error(_("error parsing file record")); + return false; + } + + if (headerGetEntry(header, CRPMTAG_FILESIZE, &type, (void**)&size, &count)==0) + { + return _error->Error(_("error parsing file record")); + return false; + } + + if (headerGetEntry(header, CRPMTAG_DIRECTORY, &type, (void**)&dir, &count)==0) + { + return _error->Error(_("error parsing file record")); + return false; + } + + pkgSrcRecords::File F; + + F.MD5Hash = string(md5); + F.Size = size[0]; + F.Path = string(dir)+"/"+string(srpm); + + List.push_back(F); + + return true; +} + /*}}}*/ + + +bool rpmSrcRecordParser::Restart() +{ + iOffset = 0; + return true; +} + + +bool rpmSrcRecordParser::Step() +{ + FD_t fdt = fdDup(File->Fd()); + iOffset = File->Tell(); + header = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + + if (header != NULL) + return true; + else + return false; +} + + +bool rpmSrcRecordParser::Jump(unsigned long Off) +{ + iOffset = Off; + + File->Seek(iOffset); + FD_t fdt = fdDup(File->Fd()); + header = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + + if (header != NULL) + return true; + else + return false; +} + +string rpmSrcRecordParser::Package() +{ + char *str; + int_32 count, type; + + headerGetEntry(header, RPMTAG_NAME, &type, (void**)&str, &count); + + string tmp = string(str); +// free(str); + + return tmp; +} + + +string rpmSrcRecordParser::Version() +{ + char *ver, *rel; + int_32 *ser; + bool has_serial = false; + int type, count; + string str; + + if (headerGetEntry(header, RPMTAG_EPOCH, &type, (void **)&ser, &count)==1 + && count > 0) + { + has_serial = true; + } + + headerGetEntry(header, RPMTAG_VERSION, &type, (void **)&ver, &count); + + headerGetEntry(header, RPMTAG_RELEASE, &type, (void **)&rel, &count); + + if (has_serial) + { + char buf[32]; + snprintf(buf, sizeof(buf), "%i", *ser); + + str = string(buf)+":"+string(ver)+"-"+string(rel); + } + else + { + str = string(ver)+"-"+string(rel); + } + + return str; +} + + +// RecordParser::Maintainer - Return the maintainer email /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string rpmSrcRecordParser::Maintainer() +{ + char *str; + int_32 count, type; + + headerGetEntry(header, RPMTAG_PACKAGER, &type, (void**)&str, &count); + + string tmp = string(str); + + return tmp; +} + /*}}}*/ + + +string rpmSrcRecordParser::Section() +{ + char *str; + int_32 count, type; + + headerGetEntry(header, RPMTAG_GROUP, &type, (void**)&str, &count); + + string tmp = string(str); + + return tmp; +} + +unsigned long rpmSrcRecordParser::Offset() +{ + return iOffset; +} + +string rpmSrcRecordParser::AsStr() +{ + return "NOT IMPLEMENTED!!!\n\n"; +} + diff --git a/apt/apt-pkg/rpm/rpmsrcrecords.h b/apt/apt-pkg/rpm/rpmsrcrecords.h new file mode 100644 index 0000000..f467c43 --- /dev/null +++ b/apt/apt-pkg/rpm/rpmsrcrecords.h @@ -0,0 +1,44 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rpmsrcrecords.h,v 1.1 2000/10/29 20:25:46 kojima Exp $ +/* ###################################################################### + + SRPM Records - Parser implementation for RPM style source indexes + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_RPMSRCRECORDS_H +#define PKGLIB_RPMSRCRECORDS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/rpmsrcrecords.h" +#endif + +#include +#include +#include + +class rpmSrcRecordParser : public pkgSrcRecords::Parser +{ + long iOffset; + Header header; + const char *StaticBinList[400]; + +public: + virtual bool Restart(); + virtual bool Step(); + virtual bool Jump(unsigned long Off); + + virtual string Package(); + virtual string Version(); + virtual string Maintainer(); + virtual string Section(); + virtual const char **Binaries(); + virtual unsigned long Offset(); + virtual string AsStr(); + virtual bool Files(vector &F); + + rpmSrcRecordParser(FileFd *F,pkgSourceList::const_iterator SrcItem); +}; + +#endif diff --git a/apt/apt-pkg/rpm/rpmversion.cc b/apt/apt-pkg/rpm/rpmversion.cc new file mode 100644 index 0000000..29179e9 --- /dev/null +++ b/apt/apt-pkg/rpm/rpmversion.cc @@ -0,0 +1,284 @@ +// $Id: rpmversion.cc,v 1.4 2002/01/14 16:53:12 kojima Exp $ + +#ifdef __GNUG__ +#pragma implementation "apt-pkg/rpmversion.h" +#endif + +#include + +#include +#include + +#include +#include + +// VersionCompare (op) - Greater than comparison for versions +// --------------------------------------------------------------------- +/* */ +int RPMFactory::versionCompare(const char *A, const char *B) +{ + return versionCompare(A,A + strlen(A),B,B + strlen(B)); +} + +int RPMFactory::versionCompare(string A,string B) +{ + return versionCompare(A.begin(),A.end(),B.begin(),B.end()); +} + + + +/* Code ripped from rpmlib */ +static void ParseVersion(const char *V, const char *VEnd, + char **Epoch, + char **Version, + char **Release) +{ + string tmp = string(V, VEnd); + const char *evr = tmp.c_str(); + const char *epoch, *epoend; + const char *version, *verend; /* assume only version is present */ + const char *release, *relend; + char *s, *se; + + s = (char*)evr; + while (*evr && isdigit(*s)) s++; /* s points to epoch terminator */ + se = strrchr(s, '-'); /* se points to version terminator */ + + if (*s == ':') { + epoch = evr; + *s++ = '\0'; + version = s; + if (*epoch == '\0') epoch = "0"; + } else { + epoch = NULL; /* XXX disable epoch compare if missing */ + version = evr; + } + if (se) { + *se++ = '\0'; + release = se; + } else { + release = NULL; + } + +#define Xstrdup(a) (a) ? strdup(a) : NULL + *Epoch = Xstrdup(epoch); + *Version = Xstrdup(version); + *Release = Xstrdup(release); +#undef Xstrdup +} + +/* This fragments the version into E:V-R triples and compares each + portion seperately. */ +int RPMFactory::versionCompare(const char *A, const char *AEnd, + const char *B, const char *BEnd) +{ +#if 0 + char *AE, *AV, *AS; + char *BE, *BV, *BS; + int rc; + +#define FREE(x) if (x) free(x) + + ParseVersion(A, AEnd, &AE, &AV, &AS); + ParseVersion(B, BEnd, &BE, &BV, &BS); + + if (AE && !BE) { + FREE(AE); FREE(AV); FREE(AS); + FREE(BE); FREE(BV); FREE(BS); + return 1; + } else if (!AE && BE) { + FREE(AE); FREE(AV); FREE(AS); + FREE(BE); FREE(BV); FREE(BS); + return -1; + } else if (AE && BE) + { + int Aep, Bep; + + Aep = atoi(AE); + Bep = atoi(BE); + + FREE(AE); FREE(AV); FREE(AS); + FREE(BE); FREE(BV); FREE(BS); + + if (Aep < Bep) + return -1; + else + return 1; + } + + rc = rpmvercmp(AV, BV); + + if (rc) { + FREE(AE); FREE(AV); FREE(AS); + FREE(BE); FREE(BV); FREE(BS); + + return rc; + } + + rc = rpmvercmp(AS, BS); + FREE(AE); FREE(AV); FREE(AS); + FREE(BE); FREE(BV); FREE(BS); + + return rc; +#else + char *bufA; + char *bufB; + char *p; + bool okA, okB; + char *verA, *verB; + char *relA, *relB; + int res; + + bufA = (char*)alloca(AEnd-A+4); + bufB = (char*)alloca(BEnd-B+4); + + bufA = strncpy(bufA, A, AEnd-A); + bufA[AEnd-A] = 0; + + bufB = strncpy(bufB, B, BEnd-B); + bufB[BEnd-B] = 0; + + // compare epoch + p = strchr(bufA, ':'); + okA = (p != NULL); + + p = strchr(bufB, ':'); + okB = (p != NULL); + + if (okA && !okB) + return 2; + else if (!okA && okB) + return -2; + else if (okA && okB) { + int epoA, epoB; + + p = strchr(bufA, ':'); + *p = 0; + epoA = atoi(bufA); + verA = p+1; + + p = strchr(bufB, ':'); + *p = 0; + verB = p+1; + + epoB = atoi(bufB); + if (epoA < epoB) + return -1; + else if (epoA > epoB) + return 1; + } else { + verA = bufA; + verB = bufB; + } + + // compare version + p = strchr(verA, '-'); + if (p) { + *p = 0; + relA = p+1; + } else { + relA = NULL; + } + + p = strchr(verB, '-'); + if (p) { + *p = 0; + relB = p+1; + } else { + relB = NULL; + } + + res = rpmvercmp(verA, verB); + if (res) + return res; + + // compare release + if (!relA) + return 0; + + if (!relB) + return 0; + + res = rpmvercmp(relA, relB); + + return res; +#endif +} + + +// CheckDep - Check a single dependency /*{{{*/ +// --------------------------------------------------------------------- +/* This simply preforms the version comparison and switch based on + operator. */ +bool RPMFactory::checkDep(const char *DepVer,const char *PkgVer,int Op) +{ + int rc; + int PkgFlags; + int DepFlags; + bool invert = false; + + DepFlags = 0; + PkgFlags = RPMSENSE_EQUAL; + switch (Op & 0x0F) + { + case pkgCache::Dep::LessEq: + DepFlags = RPMSENSE_LESS|RPMSENSE_EQUAL; + break; + + case pkgCache::Dep::GreaterEq: + DepFlags = RPMSENSE_GREATER|RPMSENSE_EQUAL; + break; + + case pkgCache::Dep::Less: + DepFlags = RPMSENSE_LESS; + break; + + case pkgCache::Dep::Greater: + DepFlags = RPMSENSE_GREATER; + break; + + case pkgCache::Dep::Equals: + DepFlags = RPMSENSE_EQUAL; + break; + + case pkgCache::Dep::NotEquals: + DepFlags = RPMSENSE_EQUAL; + invert = true; + break; + + default: + DepFlags = RPMSENSE_ANY; // any version is ok + break; + } + + rc = rpmRangesOverlap("", PkgVer, PkgFlags, // provide + "", DepVer, DepFlags); // request + + if (invert) + return !(rc == 1); + else + return (rc == 1); +} + + /*}}}*/ +// BaseVersion - Return the upstream version string /*{{{*/ +// --------------------------------------------------------------------- +/* This strips all the debian specific information from the version number */ +string RPMFactory::baseVersion(const char *Ver) +{ + // Strip off the bit before the first colon + const char *I = Ver; + for (; *I != 0 && *I != ':'; I++); + if (*I == ':') + Ver = I + 1; + + // Chop off the trailing - + I = Ver; + unsigned Last = strlen(Ver); + for (; *I != 0; I++) + if (*I == '-') + Last = I - Ver; + + return string(Ver,Last); +} + /*}}}*/ diff --git a/apt/apt-pkg/sourcelist.cc b/apt/apt-pkg/sourcelist.cc new file mode 100644 index 0000000..270356a --- /dev/null +++ b/apt/apt-pkg/sourcelist.cc @@ -0,0 +1,723 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: sourcelist.cc,v 1.25 2001/11/12 16:34:00 kojima Exp $ +/* ###################################################################### + + List of Sources and Vendors + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/sourcelist.h" +#endif + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + /*}}}*/ + +// SourceList::pkgSourceList - Constructors /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgSourceList::pkgSourceList() +{ +} +/* +pkgSourceList::pkgSourceList(string File) +{ + ReadVendors(_config->FindFile("Dir::Etc::vendorlist")); + + Read(File); +} +*/ /*}}}*/ +// SourceList::ReadMainList - Read the main source list from etc /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSourceList::ReadMainList() +{ + ReadVendors(_config->FindFile("Dir::Etc::vendorlist")); + + return Read(_config->FindFile("Dir::Etc::sourcelist")); +} + /*}}}*/ + +bool pkgSourceList::ReadVendors(string File) +{ + Configuration Cnf; + + ReadConfigFile(Cnf, File, true); + + // Process 'simple-key' type sections + const Configuration::Item *Top = Cnf.Tree("simple-key"); + for (Top = (Top == 0?0:Top->Child); Top != 0; Top = Top->Next) + { + Configuration Block(Top); + VendorItem *vendor; + + vendor = new VendorItem; + + vendor->VendorID = Top->Tag; + vendor->Fingerprint = Block.Find("Fingerprint"); + vendor->Name = Block.Find("Name"); // Description? + + if (vendor->Fingerprint.empty() == true || vendor->Name.empty() == true) + _error->Error(_("Block %s is invalid"), vendor->VendorID.c_str()); + + Vendors.push_back(vendor); + } + + if (_error->PendingError()) + return false; + + return true; +} + +// SourceList::Read - Parse the sourcelist file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSourceList::Read(string File) +{ + // Open the stream for reading + ifstream F(File.c_str(),ios::in | ios::nocreate); + if (!F != 0) + return _error->Errno("ifstream::ifstream","Opening %s",File.c_str()); + + List.erase(List.begin(),List.end()); + char Buffer[300]; + + int CurLine = 0; + while (F.eof() == false) + { + F.getline(Buffer,sizeof(Buffer)); + CurLine++; + _strtabexpand(Buffer,sizeof(Buffer)); + _strstrip(Buffer); + + // Comment or blank + if (Buffer[0] == '#' || Buffer[0] == 0) + continue; + + // Grok it + string Type; + string URI; + string VendorID; + + RepositoryItem *Rep = new RepositoryItem; + + const char *C = Buffer; + if (ParseQuoteWord(C,Type) == false) + return _error->Error(_("Malformed line %u in source list %s (type)"),CurLine,File.c_str()); + if (ParseQuoteWord(C,URI) == false) + return _error->Error(_("Malformed line %u in source list %s (URI)"),CurLine,File.c_str()); + + if (URI[0] == '[') { + const char *begin = URI.c_str()+1; + const char *end = strchr(begin, ']'); + + if (!end) + return _error->Error(_("Malformed line %u in source list %s (vendor ID)"),CurLine,File.c_str()); + + VendorID = string(begin, end); + + if (ParseQuoteWord(C,URI) == false) + return _error->Error(_("Malformed line %u in source list %s (URI)"),CurLine,File.c_str()); + } else { + VendorID = ""; + Rep->Vendor = NULL; + } + if (ParseQuoteWord(C,Rep->Dist) == false) + return _error->Error(_("Malformed line %u in source list %s (dist)"),CurLine,File.c_str()); + + if (!VendorID.empty()) { + if (Rep->SetVendor(Vendors, VendorID) == false) + return _error->Error(_("Malformed line %u in source list %s (bad vendor ID)"),CurLine,File.c_str()); + } + if (Rep->SetType(Type) == false) + return _error->Error(_("Malformed line %u in source list %s (bad type)"),CurLine,File.c_str()); + + if (Rep->SetURI(URI) == false) + return _error->Error(_("Malformed line %u in source list %s (bad URI)"),CurLine,File.c_str()); + + // Check for an absolute dists specification. + if (Rep->Dist.empty() == false && Rep->Dist[Rep->Dist.size() - 1] == '/') + { + Item Itm; + Itm.Dist = Rep->Dist; + Itm.Repository = Rep; + + if (ParseQuoteWord(C,Itm.Section) == true) + return _error->Error(_("Malformed line %u in source list %s (Absolute dist)"),CurLine,File.c_str()); + Rep->Dist = SubstVar(Rep->Dist,"$(ARCH)",_config->Find("APT::Architecture")); + + List.push_back(Itm); + + Repositories.push_back(Rep); + continue; + } + + string Section; + + // Grab the rest of the dists + if (ParseQuoteWord(C,Section) == false) + return _error->Error(_("Malformed line %u in source list %s (dist parse)"),CurLine,File.c_str()); + + do + { + Item Itm; + + Itm.Section = Section; + Itm.Dist = SubstVar(Rep->Dist,"$(ARCH)",_config->Find("APT::Architecture")); + Itm.Repository = Rep; + List.push_back(Itm); + } + while (ParseQuoteWord(C, Section) == true); + + Repositories.push_back(Rep); + + + } + return true; +} + /*}}}*/ +// SourceList::Item << - Writes the item to a stream /*{{{*/ +// --------------------------------------------------------------------- +/* This is not suitable for rebuilding the sourcelist file but it good for + debugging. */ +ostream &operator <<(ostream &O,pkgSourceList::Item &Itm) +{ + O << (int)Itm.Type() << ' ' << Itm.URI() << ' ' << Itm.Dist << ' ' << Itm.Section; + return O; +} + /*}}}*/ +// SourceList::Repository::SetType - Sets the distribution type /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool pkgSourceList::RepositoryItem::SetType(string S) +{ + if (S == "deb") + { + Type = Deb; + return true; + } + + if (S == "deb-src") + { + Type = DebSrc; + return true; + } + + //akk + if (S == "rpm") + { + Type = Rpm; + return true; + } + + if (S == "rpm-src") + { + Type = RpmSrc; + return true; + } + + return false; +} + /*}}}*/ + +bool pkgSourceList::RepositoryItem::SetVendor(vector vendors, + string S) +{ + vector::const_iterator iter; + + if (S.empty()) + { + Vendor = NULL; + return false; + } + + for (iter = vendors.begin(); + iter != vendors.end(); + iter++) + { + Vendor = *iter; + + if (Vendor->VendorID == S) + { + return true; + } + } + + Vendor = NULL; + + return false; +} + + +// SourceList::RepositoryItem::SetURI - Set the URI /*{{{*/ +// --------------------------------------------------------------------- +/* For simplicity we strip the scheme off the uri */ +bool pkgSourceList::RepositoryItem::SetURI(string S) +{ + if (S.empty() == true) + return false; + + if (S.find(':') == string::npos) + return false; + + S = SubstVar(S,"$(ARCH)",_config->Find("APT::Architecture")); + + // Make sure that the URN is / postfixed + URI = S; + if (URI[URI.size() - 1] != '/') + URI += '/'; + + return true; +} + /*}}}*/ +// SourceList::Item::SiteOnly - Strip off the path part of a URI /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string pkgSourceList::RepositoryItem::SiteOnly(string URI) +{ + ::URI U(URI); + U.User = string(); + U.Password = string(); + U.Path = string(); + U.Port = 0; + return U; +} + /*}}}*/ + + +string pkgSourceList::RepositoryItem::HashesURI() +{ + string Res; + switch (Type) + { + case Deb: + break; + + case DebSrc: + break; + + case Rpm: + Res = URI + Dist + "/base/hashfile"; + break; + + case RpmSrc: + Res = URI + Dist + "/base/hashfile"; + break; + }; + return Res; +} + + +string pkgSourceList::RepositoryItem::HashesInfo() +{ + string Res; + switch (Type) + { + case Deb: + break; + + case DebSrc: + break; + + case Rpm: + case RpmSrc: + Res = SiteOnly(URI) + ' '; + Res += Dist + "/"; + Res += "base/hashfile"; + break; + }; + return Res; +} + + +bool pkgSourceList::RepositoryItem::UpdateHashes(string File) +{ + // Open the stream for reading + FileFd F(File, FileFd::ReadOnly); + if (_error->PendingError()) + return _error->Error(_("could not open hash index"),File.c_str()); + + pkgTagFile Tags(F); + pkgTagSection Section; + + if (!Tags.Step(Section)) + return false; + + string Files = Section.FindS("MD5SUM"); + if (Files.empty()) { + return _error->Error(_("No MD5SUM data in hashfile")); + } + // Iterate over the entire list grabbing each triplet + const char *C = Files.c_str(); + while (*C != 0) + { + string Size; + string Hash; + string Path; + + // Parse each of the elements + if (ParseQuoteWord(C,Hash) == false || + ParseQuoteWord(C,Size) == false || + ParseQuoteWord(C,Path) == false) + return _error->Error(_("Error parsing MD5 hash record")); + + // Parse the size and append the directory + HashIndex[Path].size = atoi(Size.c_str()); + HashIndex[Path].md5_hash = Hash; + } + + return true; +} + + + +bool pkgSourceList::RepositoryItem::MD5HashForFile(string file, + string &hash, + unsigned int &size) +{ + + if (Vendor == NULL) { + // means authentication is disabled + size = 0; + hash = ""; + return true; + } + if (HashIndex.count(file) == 0) { + return _error->Error(_("Repository entry in sources.list contains extra components that are not listed in the signed hash file: %s"), + file.c_str()); + } + if (HashIndex[file].md5_hash.empty()) + return false; + hash = HashIndex[file].md5_hash; + size = HashIndex[file].size; + return true; +} + + +// SourceList::Item::PackagesURI - Returns a URI to the packages file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string pkgSourceList::Item::PackagesURI(bool PathOnly) const +{ + string Res; + string Prefix; + + if (PathOnly) + Prefix = ""; + else + Prefix = URI(); + + switch (Type()) + { + case Deb: + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res = Prefix + Dist; + else + Res = Prefix; + } + else + Res = Prefix + "dists/" + Dist + '/' + Section + + "/binary-" + _config->Find("APT::Architecture") + '/'; + + Res += "Packages"; + break; + + case DebSrc: + if (Dist[Dist.size() - 1] == '/') + Res = Prefix + Dist; + else + Res = Prefix + "dists/" + Dist + '/' + Section + + "/source/"; + + Res += "Sources"; + break; + + case Rpm: + if (Dist[Dist.size()-1] == '/') + Res = Prefix + (Dist != "/" ? Dist : "") + "pkglist"; + else + Res = Prefix + Dist + "/base/pkglist."+Section; + break; + + case RpmSrc: + if (Dist[Dist.size()-1] == '/') + Res = Prefix + (Dist != "/" ? Dist : "") + "srclist"; + else + Res = Prefix + Dist + "/base/srclist."+Section; + break; + + default: + cout << "SHIT!!!"<SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res += Dist; + } + else + Res += Dist + '/' + Section; + + Res += " Packages"; + break; + + case DebSrc: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + Res += Dist; + else + Res += Dist + '/' + Section; + + Res += " Sources"; + break; + + case Rpm: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + Res += (Dist != "/" ? Dist : "") + "pkglist"; + else + Res += Dist + "/base/pkglist." + Section; + break; + + case RpmSrc: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + Res += (Dist != "/" ? Dist : "") + "srclist"; + else + Res += Dist + "/base/srclist." + Section; + break; + }; + return Res; +} +/*}}}*/ + +// SourceList::Item::ReleaseURI - Returns a URI to the release file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string pkgSourceList::Item::ReleaseURI(bool PathOnly) const +{ + string Res; + string Prefix; + + if (PathOnly) + Prefix = ""; + else + Prefix = URI(); + + switch (Type()) + { + case Deb: + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res = Prefix + Dist; + else + Res = Prefix; + } + else + Res = Prefix + "dists/" + Dist + '/' + Section + + "/binary-" + _config->Find("APT::Architecture") + '/'; + + Res += "Release"; + break; + + case DebSrc: + if (Dist[Dist.size() - 1] == '/') + Res = Prefix + Dist; + else + Res = Prefix + "dists/" + Dist + '/' + Section + + "/source/"; + + Res += "Release"; + break; + + case Rpm: + case RpmSrc: + if (Dist[Dist.size() - 1] == '/') + Res = Prefix + (Dist != "/" ? Dist : "") + "release"; + else + Res = Prefix + Dist + "/base/release."+Section; + break; + }; + return Res; +} + /*}}}*/ +// SourceList::Item::ReleaseInfo - Shorter version of the URI /*{{{*/ +// --------------------------------------------------------------------- +/* This is a shorter version that is designed to be < 60 chars or so */ +string pkgSourceList::Item::ReleaseInfo() const +{ + string Res; + + switch (Type()) + { + case Deb: + case DebSrc: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res += Dist; + } + else + Res += Dist + '/' + Section; + + Res += " Release"; + break; + + case Rpm: + case RpmSrc: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res += Dist; + Res += " release"; + } else { + Res += Dist; + + Res += " release."+Section; + } + break; + }; + return Res; +} + /*}}}*/ + +// SourceList::Item::ArchiveInfo - Shorter version of the archive spec /*{{{*/ +// --------------------------------------------------------------------- +/* This is a shorter version that is designed to be < 60 chars or so */ +string pkgSourceList::Item::ArchiveInfo(pkgCache::VerIterator Ver) const +{ + string Res; + + switch (Type()) + { + case DebSrc: + case Deb: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res += Dist; + } + else + Res += Dist + '/' + Section; + + Res += " "; + Res += Ver.ParentPkg().Name(); + Res += " "; + Res += Ver.VerStr(); + + break; + + case Rpm: + case RpmSrc: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res += Dist; + } + else + Res += Dist + '/' + Section; + + Res += " "; + Res += Ver.ParentPkg().Name(); + Res += " "; + Res += Ver.VerStr(); + break; + }; + return Res; +} + /*}}}*/ +// SourceList::Item::ArchiveURI - Returns a URI to the given archive /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string pkgSourceList::Item::ArchiveURI(string File) const +{ + string Res; + switch (Type()) + { + case Deb: + case DebSrc: + Res = URI() + File; + break; + case Rpm: + if (Dist[Dist.size()-1] == '/') + Res = URI()+(Dist != "/" ? Dist : "")+File; + else + Res = URI() + Dist + "/RPMS." + Section + "/" + File; + break; + case RpmSrc: + if (Dist[Dist.size()-1] == '/') + Res = URI()+(Dist != "/" ? Dist : "")+File; + else + Res = URI() + Dist + "/../" + File; + break; + }; + return Res; +} + /*}}}*/ +// SourceList::Item::SourceInfo - Returns an info line for a source /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string pkgSourceList::Item::SourceInfo(string Pkg,string Ver,string Comp) const +{ + string Res; + + switch (Type()) + { + case DebSrc: + case Deb: + case RpmSrc: + case Rpm: + Res += Repository->SiteOnly(URI()) + ' '; + if (Dist[Dist.size() - 1] == '/') + { + if (Dist != "/") + Res += Dist; + } + else + Res += Dist + '/' + Section; + + Res += " "; + Res += Pkg; + Res += " "; + Res += Ver; + if (Comp.empty() == false) + Res += " (" + Comp + ")"; + break; + }; + return Res; +} diff --git a/apt/apt-pkg/sourcelist.h b/apt/apt-pkg/sourcelist.h new file mode 100644 index 0000000..80dc270 --- /dev/null +++ b/apt/apt-pkg/sourcelist.h @@ -0,0 +1,140 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: sourcelist.h,v 1.9 2001/11/12 16:34:00 kojima Exp $ +/* ###################################################################### + + SourceList - Manage a list of sources + + The Source List class provides access to a list of sources. It + can read them from a file and generate a list of all the distinct + sources. + + All sources have a type associated with them that defines the layout + of the archive. The exact format of the file is documented in + files.sgml. + + ##################################################################### + */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_SOURCELIST_H +#define PKGLIB_SOURCELIST_H + +#include +#include +#include +#include +#include + +#ifdef __GNUG__ +#pragma interface "apt-pkg/sourcelist.h" +#endif + +class pkgAquire; +class pkgSourceList +{ + public: + + struct Item; + + struct VendorItem + { + string VendorID; + string Fingerprint; + string Name; + }; + + enum RepositoryType {Deb, DebSrc, Rpm, RpmSrc}; + + struct FileData + { + string md5_hash; + unsigned int size; + }; + + struct RepositoryItem + { + RepositoryType Type; + map HashIndex; // filename -> filedata + + VendorItem *Vendor; + + string URI; + string Dist; + + bool SetType(string S); + bool SetURI(string S); + bool SetVendor(vector vendors, string S); + + bool AuthSucceeded() { HashIndex.size() > 0; }; + + bool MD5HashForFile(string file, string &hash, unsigned int &size); + + string SiteOnly(string URI); + + string HashesURI(); + string HashesInfo(); + + bool UpdateHashes(string File); + + bool ParseHashData(string str, string &hash, unsigned long &size, + string &file); + }; + typedef vector::iterator rep_iterator; + + + /* Each item in the source list, each line can have more than one + item */ + struct Item + { + RepositoryItem *Repository; + string Section; + + inline RepositoryType Type() const { return Repository->Type; }; + inline string URI() const { return Repository->URI; }; + string Dist; + + string PackagesURI(bool PathOnly = false) const; + string PackagesInfo() const; + + string ReleaseURI(bool PathOnly = false) const; + string ReleaseInfo() const; + + string SourceInfo(string Pkg,string Ver,string Comp) const; + + string ArchiveInfo(pkgCache::VerIterator Ver) const; + string ArchiveURI(string File) const; + }; + typedef vector::const_iterator const_iterator; + + + protected: + + vector Repositories; + vector Vendors; + vector List; + + public: + + bool ReadMainList(); + bool Read(string File); + + bool ReadVendors(string File); + + // Repository accessors + inline rep_iterator rep_begin() {return Repositories.begin();}; + inline rep_iterator rep_end() {return Repositories.end();}; + + // List accessors + inline const_iterator begin() const {return List.begin();}; + inline const_iterator end() const {return List.end();}; + inline unsigned int size() const {return List.size();}; + inline bool empty() const {return List.empty();}; + + pkgSourceList(); +// pkgSourceList(string File); +}; + +ostream &operator <<(ostream &O,pkgSourceList::Item &Itm); + +#endif diff --git a/apt/apt-pkg/srcrecords.cc b/apt/apt-pkg/srcrecords.cc new file mode 100644 index 0000000..77d8ac8 --- /dev/null +++ b/apt/apt-pkg/srcrecords.cc @@ -0,0 +1,147 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: srcrecords.cc,v 1.4 2001/01/11 02:03:27 kojima Exp $ +/* ###################################################################### + + Source Package Records - Allows access to source package records + + Parses and allows access to the list of source records and searching by + source name on that list. + + ##################################################################### + */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/srcrecords.h" +#endif + +#include +#include +#include +#include +#include + /*}}}*/ + +#include + +#include + + +// SrcRecords::pkgSrcRecords - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* Open all the source index files */ +pkgSrcRecords::pkgSrcRecords(pkgSourceList &List) : Files(0), Current(0) +{ + pkgSourceList::const_iterator I = List.begin(); + + // Count how many items we will need + unsigned int Count = 0; + for (; I != List.end(); I++) + if (_system->checkSourceType(I->Type(), false)) + Count++; + + // Doesnt work without any source index files + if (Count == 0) + { + _error->Error(_("Sorry, you must put some 'source' uris" + " in your sources.list")); + return; + } + + Files = new Parser *[Count+1]; + memset(Files,0,sizeof(*Files)*(Count+1)); + + // Create the parser objects + Count = 0; + string Dir = _config->FindDir("Dir::State::lists"); + for (I = List.begin(); I != List.end(); I++) + { + if (!_system->checkSourceType(I->Type(), false)) + continue; + + string path = Dir + URItoFileName(I->PackagesURI()); + + Files[Count] = _system->CreateSrcRecordParser(path,I); + + if (Files[Count] == NULL || _error->PendingError() == true) + { + if (Files[Count]) + delete Files[Count]; + return; + } + Count++; + } + + Restart(); +} + /*}}}*/ +// SrcRecords::~pkgSrcRecords - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgSrcRecords::~pkgSrcRecords() +{ + if (Files == 0) + return; + + // Blow away all the parser objects + for (unsigned int Count = 0; Files[Count] != 0; Count++) + delete Files[Count]; +} + /*}}}*/ +// SrcRecords::Restart - Restart the search /*{{{*/ +// --------------------------------------------------------------------- +/* Return all of the parsers to their starting position */ +bool pkgSrcRecords::Restart() +{ + Current = Files; + for (Parser **I = Files; *I != 0; I++) + (*I)->Restart(); + + return true; +} + /*}}}*/ +// SrcRecords::Find - Find the first source package with the given name /*{{{*/ +// --------------------------------------------------------------------- +/* This searches on both source package names and output binary names and + returns the first found. A 'cursor' like system is used to allow this + function to be called multiple times to get successive entries */ +pkgSrcRecords::Parser *pkgSrcRecords::Find(const char *Package,bool SrcOnly) +{ + if (*Current == 0) + return 0; + + while (true) + { + // Step to the next record, possibly switching files + while ((*Current)->Step() == false) + { + if (_error->PendingError() == true) + return 0; + Current++; + if (*Current == 0) + return 0; + } + + // IO error somehow + if (_error->PendingError() == true) + return 0; + + // Source name hit + if ((*Current)->Package() == Package) + return *Current; + + if (SrcOnly == true) + continue; + + // Check for a binary hit + const char **I = (*Current)->Binaries(); + if (I) { + for (; I != 0 && *I != 0; I++) + if (strcmp(Package,*I) == 0) + return *Current; + } + } +} + /*}}}*/ + diff --git a/apt/apt-pkg/srcrecords.h b/apt/apt-pkg/srcrecords.h new file mode 100644 index 0000000..dba1b10 --- /dev/null +++ b/apt/apt-pkg/srcrecords.h @@ -0,0 +1,83 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: srcrecords.h,v 1.2 2000/10/29 20:25:10 kojima Exp $ +/* ###################################################################### + + Source Package Records - Allows access to source package records + + Parses and allows access to the list of source records and searching by + source name on that list. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGLIB_SRCRECORDS_H +#define PKGLIB_SRCRECORDS_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/srcrecords.h" +#endif + +#include +#include + +class pkgSrcRecords +{ + public: + + // Describes a single file + struct File + { + string MD5Hash; + unsigned long Size; + string Path; + }; + + // Abstract parser for each source record + class Parser + { + protected: + FileFd *File; + pkgSourceList::const_iterator SrcItem; + + public: + + inline pkgSourceList::const_iterator Source() const {return SrcItem;}; + + virtual bool Restart() = 0; + virtual bool Step() = 0; + virtual bool Jump(unsigned long Off) = 0; + virtual unsigned long Offset() = 0; + virtual string AsStr() = 0; + + virtual string Package() = 0; + virtual string Version() = 0; + virtual string Maintainer() = 0; + virtual string Section() = 0; + virtual const char **Binaries() = 0; + virtual bool Files(vector &F) = 0; + + Parser(FileFd *File,pkgSourceList::const_iterator SrcItem) : File(File), + SrcItem(SrcItem) {}; + virtual ~Parser() { if (File) delete File;}; + }; + + private: + + // The list of files and the current parser pointer + Parser **Files; + Parser **Current; + + public: + + // Reset the search + bool Restart(); + + // Locate a package by name + Parser *Find(const char *Package,bool SrcOnly = false); + + pkgSrcRecords(pkgSourceList &List); + ~pkgSrcRecords(); +}; + + +#endif diff --git a/apt/apt-pkg/systemfactory.cc b/apt/apt-pkg/systemfactory.cc new file mode 100644 index 0000000..1a2adb8 --- /dev/null +++ b/apt/apt-pkg/systemfactory.cc @@ -0,0 +1,439 @@ + + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include + + +SystemFactory *_system = NULL; + + + +SystemFactory::SystemFactory() +{ + assert(_system == NULL); + _system = this; +} + + +pkgPackageManager *SystemFactory::CreatePackageManager(pkgDepCache &Cache) +{ + return NULL; +} + + +// SrcCacheCheck - Check if the source package cache is uptodate /*{{{*/ +// --------------------------------------------------------------------- +/* The source cache is checked against the source list and the files + on disk, any difference results in a false. */ +bool SystemFactory::sourceCacheCheck(pkgSourceList &List) +{ + if (_error->PendingError() == true) { + return false; + } + + string CacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); + string ListDir = _config->FindDir("Dir::State::lists"); + + // Count the number of missing files + int Missing = 0; + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + // Only cache our source types. + if (!checkSourceType(I->Type())) + { + Missing++; + continue; + } + + string File = ListDir + URItoFileName(I->PackagesURI()); + struct stat Buf; + if (stat(File.c_str(),&Buf) != 0) + { + // Old format file name.. rename it + if (File[0] == '_' && stat(File.c_str()+1,&Buf) == 0) + { + if (rename(File.c_str()+1,File.c_str()) != 0) + return _error->Errno("rename",_("Failed to rename %s to %s"), + File.c_str()+1,File.c_str()); + continue; + } + + _error->WarningE("stat",_("Couldn't stat source package list '%s' (%s)"), + I->PackagesInfo().c_str(),File.c_str()); + Missing++; + } + } + + // Open the source package cache + if (FileExists(CacheFile) == false) + return false; + + FileFd CacheF(CacheFile,FileFd::ReadOnly); + if (_error->PendingError() == true) + { + _error->Discard(); + return false; + } + + MMap Map(CacheF,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true || Map.Size() == 0) + { + _error->Discard(); + return false; + } + + pkgCache Cache(Map); + if (_error->PendingError() == true) + { + _error->Discard(); + return false; + } + + // They are certianly out of sync + if (Cache.Head().PackageFileCount != List.size() - Missing) + return false; + + for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++) + { + // Search for a match in the source list + bool Bad = true; + for (pkgSourceList::const_iterator I = List.begin(); + I != List.end(); I++) + { + // Only cache deb source types. + if (!checkSourceType(I->Type())) + continue; + + string File = ListDir + URItoFileName(I->PackagesURI()); + if (F.FileName() == File) + { + Bad = false; + break; + } + } + + // Check if the file matches what was cached + Bad |= !F.IsOk(); + if (Bad == true) + return false; + } + + return true; +} + +/*}}}*/ +// GenerateSrcCache - Write the source package lists to the map /*{{{*/ +// --------------------------------------------------------------------- +/* This puts the source package cache into the given generator. */ +bool SystemFactory::generateSrcCache(pkgSourceList &List,OpProgress &Progress, + pkgCacheGenerator &Gen, + unsigned long &CurrentSize,unsigned long &TotalSize) +{ + string ListDir = _config->FindDir("Dir::State::lists"); + + // Prepare the progress indicator + TotalSize = 0; + struct stat Buf; + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + string File = ListDir + URItoFileName(I->PackagesURI()); + if (stat(File.c_str(),&Buf) != 0) + continue; + TotalSize += Buf.st_size; + } + + if (addStatusSize(TotalSize) == false) + return false; + + // Generate the pkg source cache + CurrentSize = 0; + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + pkgCacheGenerator::ListParser *Parser; + + // Only cache relevant source types. + if (!checkSourceType(I->Type())) + continue; + + string File = ListDir + URItoFileName(I->PackagesURI()); + + if (FileExists(File) == false) + continue; + + FileFd Pkg(File,FileFd::ReadOnly); + + Parser = CreateListParser(Pkg); + + Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),_("Reading Package Lists")); + + if (_error->PendingError() == true) { + delete Parser; + return _error->Error(_("Problem opening %s"),File.c_str()); + } + + CurrentSize += Pkg.Size(); + + Progress.SubProgress(0,I->PackagesInfo()); + if (Gen.SelectFile(File) == false) { + delete Parser; + return _error->Error(_("Problem with SelectFile %s"),File.c_str()); + } + + if (Gen.MergeList(*Parser) == false) { + delete Parser; + return _error->Error(_("Problem with MergeList %s"),File.c_str()); + } + + // Check the release file + string RFile = ListDir + URItoFileName(I->ReleaseURI()); + if (FileExists(RFile) == true) + { + FileFd Rel(RFile,FileFd::ReadOnly); + if (_error->PendingError() == true) { + return false; + } + Parser->LoadReleaseInfo(Gen.GetCurFile(),Rel); + } + } + + return true; +} + + + +// MakeStatusCache - Generates a cache that includes the status files /*{{{*/ +// --------------------------------------------------------------------- +/* This copies the package source cache and then merges the status and + xstatus files into it. */ +bool SystemFactory::makeStatusCache(pkgSourceList &List,OpProgress &Progress) +{ + unsigned long MapSize = _config->FindI("APT::Cache-Limit",4*1024*1024); + + string CacheFile = _config->FindFile("Dir::Cache::pkgcache"); + bool SrcOk = sourceCacheCheck(List); + + bool PkgOk = SrcOk && packageCacheCheck(CacheFile); + + // Rebuild the source and package caches + if (SrcOk == false) + { + if (!preProcess(List, Progress)) + return false; + + Progress.OverallProgress(0,1,1,_("Reading Package Lists")); + + string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); + FileFd SCacheF(SCacheFile,FileFd::WriteEmpty); + + /* Open the pkgcache, we want a new inode here so we do no corrupt + existing mmaps */ + unlink(CacheFile.c_str()); + FileFd CacheF(CacheFile,FileFd::WriteEmpty); + DynamicMMap Map(CacheF,MMap::Public,MapSize); + if (_error->PendingError() == true) + return false; + + pkgCacheGenerator Gen(Map,Progress); + unsigned long CurrentSize = 0; + unsigned long TotalSize = 0; + + if (generateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false) + return false; + + // Write the src cache + Gen.GetCache().HeaderP->Dirty = false; + if (SCacheF.Write(Map.Data(),Map.Size()) == false) + return _error->Error(_("IO Error saving source cache")); + Gen.GetCache().HeaderP->Dirty = true; + + // Merge in the source caches + return mergeInstalledPackages(Progress,Gen,CurrentSize,TotalSize); + } + + if (PkgOk == true) + { + Progress.OverallProgress(0,1,1,_("Reading Package Lists")); + Progress.OverallProgress(1,1,1,_("Reading Package Lists")); + return true; + } + else + { + if (!preProcess(List, Progress)) + return false; + Progress.OverallProgress(0,1,1,_("Reading Package Lists")); + } + + // We use the source cache to generate the package cache + string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); + FileFd SCacheF(SCacheFile,FileFd::ReadOnly); + + /* Open the pkgcache, we want a new inode here so we do no corrupt + existing mmaps */ + unlink(CacheFile.c_str()); + FileFd CacheF(CacheFile,FileFd::WriteEmpty); + DynamicMMap Map(CacheF,MMap::Public,MapSize); + if (_error->PendingError() == true) + return false; + + // Preload the map with the source cache + if (SCacheF.Read((unsigned char *)Map.Data() + Map.RawAllocate(SCacheF.Size()), + SCacheF.Size()) == false) + return false; + + pkgCacheGenerator Gen(Map,Progress); + + // Compute the progress + unsigned long TotalSize = 0; + if (addStatusSize(TotalSize) == false) + return false; + + unsigned long CurrentSize = 0; + return mergeInstalledPackages(Progress,Gen,CurrentSize,TotalSize); +} +/*}}}*/ +// MakeStatusCacheMem - Returns a map for the status cache /*{{{*/ +// --------------------------------------------------------------------- +/* This creates a map object for the status cache. If the process has write + access to the caches then it is the same as MakeStatusCache, otherwise it + creates a memory block and puts the cache in there. */ +MMap *SystemFactory::makeStatusCacheMem(pkgSourceList &List,OpProgress &Progress) +{ + unsigned long MapSize = _config->FindI("APT::Cache-Limit",4*1024*1024); + + if (!preProcess(List, Progress)) { + return 0; + } + + /* If the cache file is writeable this is just a wrapper for + MakeStatusCache */ + string CacheFile = _config->FindFile("Dir::Cache::pkgcache"); + bool Writeable = (access(CacheFile.c_str(),W_OK) == 0) || + (errno == ENOENT); + + if (Writeable == true) + { + if (makeStatusCache(List,Progress) == false) + return 0; + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return 0; + + MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + return Map; + } + + // Mostly from MakeStatusCache.. + Progress.OverallProgress(0,1,1,_("Reading Package Lists")); + + bool SrcOk = sourceCacheCheck(List); + bool PkgOk = SrcOk && packageCacheCheck(CacheFile); + + // Rebuild the source and package caches + if (SrcOk == false) + { + DynamicMMap *Map = new DynamicMMap(MMap::Public,MapSize); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + + pkgCacheGenerator Gen(*Map,Progress); + unsigned long CurrentSize = 0; + unsigned long TotalSize = 0; + if (generateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + // Merge in the source caches + if (mergeInstalledPackages(Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + return Map; + } + + if (PkgOk == true) + { + Progress.OverallProgress(1,1,1,_("Reading Package Lists")); + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return 0; + + MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + return Map; + } + + // We use the source cache to generate the package cache + string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); + FileFd SCacheF(SCacheFile,FileFd::ReadOnly); + DynamicMMap *Map = new DynamicMMap(MMap::Public,MapSize); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + + // Preload the map with the source cache + if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()), + SCacheF.Size()) == false) + { + delete Map; + return 0; + } + + pkgCacheGenerator Gen(*Map,Progress); + + // Compute the progress + unsigned long TotalSize = 0; + if (addStatusSize(TotalSize) == false) + { + delete Map; + return 0; + } + + unsigned long CurrentSize = 0; + if (mergeInstalledPackages(Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + return Map; +} +/*}}}*/ + diff --git a/apt/apt-pkg/systemfactory.h b/apt/apt-pkg/systemfactory.h new file mode 100644 index 0000000..a7d661b --- /dev/null +++ b/apt/apt-pkg/systemfactory.h @@ -0,0 +1,65 @@ + + +#ifndef _SYSTEMFACTORY_H_ +#define _SYSTEMFACTORY_H_ + +#include +#include +#include + +class FileFd; +class pkgPackageManager; +class pkgDepCache; +class pkgCache; +class OpProgress; +class pkgSourceList; +class MMap; + +class SystemFactory { +// for cache generation + protected: + inline virtual bool addStatusSize(unsigned long &TotalSize) {return false;}; + + virtual bool sourceCacheCheck(pkgSourceList &List); + inline virtual bool packageCacheCheck(string CacheFile) = 0; + + bool generateSrcCache(pkgSourceList &List,OpProgress &Progress, + pkgCacheGenerator &Gen, + unsigned long &CurrentSize,unsigned long &TotalSize); + + inline virtual bool mergeInstalledPackages(OpProgress &Progress, + pkgCacheGenerator &Gen, + unsigned long &CurrentSize, + unsigned long TotalSize) { + return false; + }; + + inline virtual bool preProcess(pkgSourceList &List, OpProgress &Progress) {return true;} + + public: + inline virtual bool checkSourceType(int type, bool binary=true) {return false;} + + bool makeStatusCache(pkgSourceList &List,OpProgress &Progress); + MMap *makeStatusCacheMem(pkgSourceList &List,OpProgress &Progress); + + virtual int versionCompare(const char *A, const char *B); + virtual int versionCompare(const char *A, const char *AEnd, const char *B, + const char *BEnd); + virtual int versionCompare(string A,string B); + virtual bool checkDep(const char *DepVer,const char *PkgVer,int Op); + virtual string baseVersion(const char *Ver); + + // for other stuffs + public: + SystemFactory::SystemFactory(); + + virtual pkgCacheGenerator::ListParser *CreateListParser(FileFd &File) = 0; + virtual pkgRecords::Parser *CreateRecordParser(string File, pkgCache &Cache) = 0; + virtual pkgSrcRecords::Parser *CreateSrcRecordParser(string File, pkgSourceList::const_iterator SrcItem) = 0; + virtual pkgPackageManager *CreatePackageManager(pkgDepCache &Cache); + +}; + +extern SystemFactory *_system; + +#endif diff --git a/apt/apt-pkg/tagfile.cc b/apt/apt-pkg/tagfile.cc new file mode 100644 index 0000000..f753459 --- /dev/null +++ b/apt/apt-pkg/tagfile.cc @@ -0,0 +1,304 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: tagfile.cc,v 1.2 2001/01/11 02:03:27 kojima Exp $ +/* ###################################################################### + + Fast scanner for RFC-822 type header information + + This uses a rotating buffer to load the package information into. + The scanner runs over it and isolates and indexes a single section. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/tagfile.h" +#endif + +#include +#include +#include + +#include + +#include +#include + /*}}}*/ + +// TagFile::pkgTagFile - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgTagFile::pkgTagFile(FileFd &Fd,unsigned long Size) : Fd(Fd), Size(Size) +{ + Buffer = new char[Size]; + Start = End = Buffer; + Left = Fd.Size(); + iOffset = 0; + Fill(); +} + /*}}}*/ +// pkgTagFile::~pkgTagFile - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgTagFile::~pkgTagFile() +{ + delete [] Buffer; +} + /*}}}*/ +// TagFile::Step - Advance to the next section /*{{{*/ +// --------------------------------------------------------------------- +/* If the Section Scanner fails we refill the buffer and try again. */ +bool pkgTagFile::Step(pkgTagSection &Tag) +{ + if (Tag.Scan(Start,End - Start) == false) + { + if (Fill() == false) + return false; + + if (Tag.Scan(Start,End - Start) == false) + return _error->Error(_("Unable to parse package file %s (1)"),Fd.Name().c_str()); + } + Start += Tag.size(); + iOffset += Tag.size(); + + return true; +} + /*}}}*/ +// TagFile::Fill - Top up the buffer /*{{{*/ +// --------------------------------------------------------------------- +/* This takes the bit at the end of the buffer and puts it at the start + then fills the rest from the file */ +bool pkgTagFile::Fill() +{ + unsigned long EndSize = End - Start; + + memmove(Buffer,Start,EndSize); + Start = Buffer; + End = Buffer + EndSize; + + if (Left == 0) + { + if (EndSize <= 3) + return false; + if (Size - (End - Buffer) < 4) + return true; + + // Append a double new line if one does not exist + unsigned int LineCount = 0; + for (const char *E = End - 1; E - End < 6 && (*E == '\n' || *E == '\r'); E--) + if (*E == '\n') + LineCount++; + for (; LineCount < 2; LineCount++) + *End++ = '\n'; + + return true; + } + + // See if only a bit of the file is left + if (Left < Size - (End - Buffer)) + { + if (Fd.Read(End,Left) == false) + return false; + + End += Left; + Left = 0; + } + else + { + if (Fd.Read(End,Size - (End - Buffer)) == false) + return false; + + Left -= Size - (End - Buffer); + End = Buffer + Size; + } + return true; +} + /*}}}*/ +// TagFile::Jump - Jump to a pre-recorded location in the file /*{{{*/ +// --------------------------------------------------------------------- +/* This jumps to a pre-recorded file location and reads the record + that is there */ +bool pkgTagFile::Jump(pkgTagSection &Tag,unsigned long Offset) +{ + iOffset = Offset; + Left = Fd.Size() - Offset; + if (Fd.Seek(Offset) == false) + return false; + End = Start = Buffer; + + if (Fill() == false) + return false; + + if (Tag.Scan(Start,End - Start) == true) + return true; + + // This appends a double new line (for the real eof handling) + if (Fill() == false) + return false; + + if (Tag.Scan(Start,End - Start) == false) + { + cout << string(Start,End) << endl; + return _error->Error(_("Unable to parse package file %s (2)"),Fd.Name().c_str()); + } + + return true; +} + /*}}}*/ +// TagSection::Scan - Scan for the end of the header information /*{{{*/ +// --------------------------------------------------------------------- +/* This looks for the first double new line in the data stream. It also + indexes the tags in the section. This very simple hash function for the + first 3 letters gives very good performance on the debian package files */ +bool pkgTagSection::Scan(const char *Start,unsigned long MaxLength) +{ + const char *End = Start + MaxLength; + Stop = Section = Start; + memset(AlphaIndexes,0,sizeof(AlphaIndexes)); + + if (Stop == 0) + return false; + + TagCount = 0; + while (TagCount < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End) + { + // Start a new index and add it to the hash + if (isspace(Stop[0]) == 0) + { + Indexes[TagCount++] = Stop - Section; + unsigned char A = tolower(Stop[0]) - 'a'; + unsigned char B = tolower(Stop[1]) - 'a'; + unsigned char C = tolower(Stop[3]) - 'a'; + AlphaIndexes[((A + C/3)%26) + 26*((B + C/2)%26)] = TagCount; + } + + Stop = (const char *)memchr(Stop,'\n',End - Stop); + + if (Stop == 0) + return false; + + for (; Stop[1] == '\r' && Stop+1 < End; Stop++); + + // Double newline marks the end of the record + if (Stop+1 < End && Stop[1] == '\n') + { + Indexes[TagCount] = Stop - Section; + for (; (Stop[0] == '\n' || Stop[0] == '\r') && Stop < End; Stop++); + return true; + } + + Stop++; + } + + return false; +} + /*}}}*/ +// TagSection::Find - Locate a tag /*{{{*/ +// --------------------------------------------------------------------- +/* This searches the section for a tag that matches the given string. */ +bool pkgTagSection::Find(const char *Tag,const char *&Start, + const char *&End) +{ + unsigned int Length = strlen(Tag); + unsigned char A = tolower(Tag[0]) - 'a'; + unsigned char B = tolower(Tag[1]) - 'a'; + unsigned char C = tolower(Tag[3]) - 'a'; + unsigned int I = AlphaIndexes[((A + C/3)%26) + 26*((B + C/2)%26)]; + if (I == 0) + return false; + I--; + + for (unsigned int Counter = 0; Counter != TagCount; Counter++, + I = (I+1)%TagCount) + { + const char *St; + St = Section + Indexes[I]; + if (strncasecmp(Tag,St,Length) != 0) + continue; + + // Make sure the colon is in the right place + const char *C = St + Length; + for (; isspace(*C) != 0; C++); + if (*C != ':') + continue; + + // Strip off the gunk from the start end + Start = C; + End = Section + Indexes[I+1]; + if (Start >= End) + return _error->Error("Internal parsing error"); + + for (; (isspace(*Start) != 0 || *Start == ':') && Start < End; Start++); + for (; isspace(End[-1]) != 0 && End > Start; End--); + + return true; + } + + Start = End = 0; + return false; +} + /*}}}*/ +// TagSection::FindS - Find a string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string pkgTagSection::FindS(const char *Tag) +{ + const char *Start; + const char *End; + if (Find(Tag,Start,End) == false) + return string(); + return string(Start,End); +} + /*}}}*/ +// TagSection::FindI - Find an integer /*{{{*/ +// --------------------------------------------------------------------- +/* */ +signed int pkgTagSection::FindI(const char *Tag,signed long Default) +{ + const char *Start; + const char *Stop; + if (Find(Tag,Start,Stop) == false) + return Default; + + // Copy it into a temp buffer so we can use strtol + char S[300]; + if ((unsigned)(Stop - Start) >= sizeof(S)) + return Default; + strncpy(S,Start,Stop-Start); + S[Stop - Start] = 0; + + char *End; + signed long Result = strtol(S,&End,10); + if (S == End) + return Default; + return Result; +} + /*}}}*/ +// TagSection::FindFlag - Locate a yes/no type flag /*{{{*/ +// --------------------------------------------------------------------- +/* The bits marked in Flag are masked on/off in Flags */ +bool pkgTagSection::FindFlag(const char *Tag,unsigned long &Flags, + unsigned long Flag) +{ + const char *Start; + const char *Stop; + if (Find(Tag,Start,Stop) == false) + return true; + + switch (StringToBool(string(Start,Stop))) + { + case 0: + Flags &= ~Flag; + return true; + + case 1: + Flags |= Flag; + return true; + + default: + _error->Warning("Unknown flag value"); + return true; + } + return true; +} + /*}}}*/ diff --git a/apt/apt-pkg/tagfile.h b/apt/apt-pkg/tagfile.h new file mode 100644 index 0000000..58cb642 --- /dev/null +++ b/apt/apt-pkg/tagfile.h @@ -0,0 +1,89 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: tagfile.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Fast scanner for RFC-822 type header information + + This parser handles Debian package files (and others). Their form is + RFC-822 type header fields in groups seperated by a blank line. + + The parser reads the file and provides methods to step linearly + over it or to jump to a pre-recorded start point and read that record. + + A second class is used to perform pre-parsing of the record. It works + by indexing the start of each header field and providing lookup + functions for header fields. + + ##################################################################### */ + /*}}}*/ +// Header section: pkglib +#ifndef PKGLIB_TAGFILE_H +#define PKGLIB_TAGFILE_H + +#ifdef __GNUG__ +#pragma interface "apt-pkg/tagfile.h" +#endif + +#include + +class pkgTagSection +{ + const char *Section; + const char *Stop; + + // We have a limit of 256 tags per section. + unsigned short Indexes[256]; + unsigned short AlphaIndexes[26 + 26*26]; + + unsigned int TagCount; + + public: + + inline bool operator ==(const pkgTagSection &rhs) {return Section == rhs.Section;}; + inline bool operator !=(const pkgTagSection &rhs) {return Section != rhs.Section;}; + + bool Find(const char *Tag,const char *&Start, const char *&End); + string FindS(const char *Tag); + signed int FindI(const char *Tag,signed long Default = 0); + bool pkgTagSection::FindFlag(const char *Tag,unsigned long &Flags, + unsigned long Flag); + bool Scan(const char *Start,unsigned long MaxLength); + inline unsigned long size() {return Stop - Section;}; + + inline unsigned int Count() {return TagCount;}; + inline void Get(const char *&Start,const char *&Stop,unsigned int I) + {Start = Section + Indexes[I]; Stop = Section + Indexes[I+1];} + + inline void GetSection(const char *&Start,const char *&Stop) + { + Start = Section; + Stop = this->Stop; + }; + + pkgTagSection() : Section(0), Stop(0) {}; +}; + +class pkgTagFile +{ + FileFd &Fd; + char *Buffer; + char *Start; + char *End; + unsigned long Left; + unsigned long iOffset; + unsigned long Size; + + bool Fill(); + + public: + + bool Step(pkgTagSection &Section); + inline unsigned long Offset() {return iOffset;}; + bool Jump(pkgTagSection &Tag,unsigned long Offset); + + pkgTagFile(FileFd &F,unsigned long Size = 32*1024); + ~pkgTagFile(); +}; + +#endif diff --git a/apt/apt-pkg/version.cc b/apt/apt-pkg/version.cc new file mode 100644 index 0000000..b7af1e7 --- /dev/null +++ b/apt/apt-pkg/version.cc @@ -0,0 +1,276 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: version.cc,v 1.4 2000/09/04 15:55:08 kojima Exp $ +/* ###################################################################### + + Version - Version string + + Version comparing is done using the == and < operators. STL's + function.h provides the remaining set of comparitors. A directly + callable non-string class version is provided for functions manipulating + the cache file (esp the sort function). + + A version is defined to be equal if a case sensitive compare returns + that the two strings are the same. For compatibility with the QSort + function this version returns -1,0,1. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#ifdef __GNUG__ +#pragma implementation "apt-pkg/systemfactory.h" +#endif + +#include +#include + +#include + /*}}}*/ + +// StrToLong - Convert the string between two iterators to a long /*{{{*/ +// --------------------------------------------------------------------- +/* */ +static unsigned long StrToLong(const char *begin,const char *end) +{ + char S[40]; + char *I = S; + for (; begin != end && I < S + 40;) + *I++ = *begin++; + *I = 0; + return strtoul(S,0,10); +} + /*}}}*/ +// VersionCompare (op) - Greater than comparison for versions /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int SystemFactory::versionCompare(const char *A, const char *B) +{ + return versionCompare(A,A + strlen(A),B,B + strlen(B)); +} + +int SystemFactory::versionCompare(string A,string B) +{ + return versionCompare(A.begin(),A.end(),B.begin(),B.end()); +} + + /*}}}*/ +// iVersionCompare - Compare versions /*{{{*/ +// --------------------------------------------------------------------- +/* This compares a fragment of the version. */ +static int iVersionCompare(const char *A, const char *AEnd, const char *B, + const char *BEnd) +{ + if (A >= AEnd && B >= BEnd) + return 0; + if (A >= AEnd) + return -1; + if (B >= BEnd) + return 1; + + /* Iterate over the whole string + What this does is to spilt the whole string into groups of + numeric and non numeric portions. For instance: + a67bhgs89 + Has 4 portions 'a', '67', 'bhgs', '89'. A more normal: + 2.7.2-linux-1 + Has '2', '.', '7', '.' ,'-linux-','1' */ + const char *lhs = A; + const char *rhs = B; + while (lhs != AEnd && rhs != BEnd) + { + // Starting points + const char *Slhs = lhs; + const char *Srhs = rhs; + + // Compute ending points were we have passed over the portion + bool Digit = (isdigit(*lhs) > 0?true:false); + for (;lhs != AEnd && (isdigit(*lhs) > 0?true:false) == Digit; lhs++); + for (;rhs != BEnd && (isdigit(*rhs) > 0?true:false) == Digit; rhs++); + + if (Digit == true) + { + // If the lhs has a digit and the rhs does not then < + if (rhs - Srhs == 0) + return -1; + + // Generate integers from the strings. + unsigned long Ilhs = StrToLong(Slhs,lhs); + unsigned long Irhs = StrToLong(Srhs,rhs); + if (Ilhs != Irhs) + { + if (Ilhs > Irhs) + return 1; + return -1; + } + } + else + { + // They are equal length so do a straight text compare + for (;Slhs != lhs && Srhs != rhs; Slhs++, Srhs++) + { + if (*Slhs != *Srhs) + { + /* We need to compare non alpha chars as higher than alpha + chars (a < !) */ + int lc = *Slhs; + int rc = *Srhs; + if (isalpha(lc) == 0) lc += 256; + if (isalpha(rc) == 0) rc += 256; + if (lc > rc) + return 1; + return -1; + } + } + + // If the lhs is shorter than the right it is 'less' + if (lhs - Slhs < rhs - Srhs) + return -1; + + // If the lhs is longer than the right it is 'more' + if (lhs - Slhs > rhs - Srhs) + return 1; + } + } + + // The strings must be equal + if (lhs == AEnd && rhs == BEnd) + return 0; + + // lhs is shorter + if (lhs == AEnd) + return -1; + + // rhs is shorter + if (rhs == BEnd) + return 1; + + // Shouldnt happen + return 1; +} + + /*}}}*/ +// VersionCompare - Comparison for versions /*{{{*/ +// --------------------------------------------------------------------- +/* This fragments the version into E:V-R triples and compares each + portion seperately. */ +int SystemFactory::versionCompare(const char *A, const char *AEnd, const char *B, + const char *BEnd) +{ + // Strip off the epoch and compare it + const char *lhs = A; + const char *rhs = B; + for (;lhs != AEnd && *lhs != ':'; lhs++); + for (;rhs != BEnd && *rhs != ':'; rhs++); + if (lhs == AEnd) + lhs = A; + if (rhs == BEnd) + rhs = B; + + // Compare the epoch + int Res = iVersionCompare(A,lhs,B,rhs); + if (Res != 0) { + return Res; + } + + // Skip the : + if (lhs != A) + lhs++; + if (rhs != B) + rhs++; + + // Find the last - + const char *dlhs = AEnd-1; + const char *drhs = BEnd-1; + for (;dlhs > lhs && *dlhs != '-'; dlhs--); + for (;drhs > rhs && *drhs != '-'; drhs--); + + if (dlhs == lhs) + dlhs = AEnd; + if (drhs == rhs) + drhs = BEnd; + + // Compare the main version + Res = iVersionCompare(lhs,dlhs,rhs,drhs); + if (Res != 0) + return Res; + + // Skip the - + if (dlhs != lhs) + dlhs++; + if (drhs != rhs) + drhs++; + Res = iVersionCompare(dlhs,AEnd,drhs,BEnd); + + return Res; +} + /*}}}*/ +// CheckDep - Check a single dependency /*{{{*/ +// --------------------------------------------------------------------- +/* This simply preforms the version comparison and switch based on + operator. */ +bool SystemFactory::checkDep(const char *DepVer,const char *PkgVer,int Op) +{ + if (DepVer == 0) + return true; + if (PkgVer == 0) + return false; + + // Perform the actuall comparision. + int Res = versionCompare(PkgVer,DepVer); + switch (Op & 0x0F) + { + case pkgCache::Dep::LessEq: + if (Res <= 0) + return true; + break; + + case pkgCache::Dep::GreaterEq: + if (Res >= 0) + return true; + break; + + case pkgCache::Dep::Less: + if (Res < 0) + return true; + break; + + case pkgCache::Dep::Greater: + if (Res > 0) + return true; + break; + + case pkgCache::Dep::Equals: + if (Res == 0) + return true; + break; + + case pkgCache::Dep::NotEquals: + if (Res != 0) + return true; + break; + } + + return false; +} + /*}}}*/ +// BaseVersion - Return the upstream version string /*{{{*/ +// --------------------------------------------------------------------- +/* This strips all the debian specific information from the version number */ +string SystemFactory::baseVersion(const char *Ver) +{ + // Strip off the bit before the first colon + const char *I = Ver; + for (; *I != 0 && *I != ':'; I++); + if (*I == ':') + Ver = I + 1; + + // Chop off the trailing - + I = Ver; + unsigned Last = strlen(Ver); + for (; *I != 0; I++) + if (*I == '-') + Last = I - Ver; + + return string(Ver,Last); +} + /*}}}*/ diff --git a/apt/apt.dia b/apt/apt.dia new file mode 100644 index 0000000..631d864 Binary files /dev/null and b/apt/apt.dia differ diff --git a/apt/buildlib/CVS/Entries b/apt/buildlib/CVS/Entries new file mode 100644 index 0000000..4c65de6 --- /dev/null +++ b/apt/buildlib/CVS/Entries @@ -0,0 +1,26 @@ +/config.guess/1.3/Wed Aug 1 21:31:58 2001// +/config.h.in/1.4/Wed Aug 1 21:31:58 2001// +/config.sub/1.2/Wed Aug 1 21:31:58 2001// +/configure.mak/1.2/Thu Aug 2 14:30:39 2001// +/copy.mak/1.2/Wed Aug 1 21:31:58 2001// +/debiandoc.mak/1.2/Wed Aug 1 21:31:58 2001// +/defaults.mak/1.2/Wed Aug 1 21:31:58 2001// +/environment.mak.in/1.7/Wed Aug 1 21:31:58 2001// +/fail.mak/1.1/Thu Aug 2 14:15:15 2001// +/library.mak/1.2/Wed Aug 1 21:31:58 2001// +/makefile.in/1.3/Wed Aug 1 21:31:58 2001// +/manpage.mak/1.2/Wed Aug 1 21:31:58 2001// +/mkChangeLog/1.2/Wed Aug 1 21:31:58 2001// +/ostable/1.1/Wed Aug 1 21:31:58 2001// +/program.mak/1.2/Wed Aug 1 21:31:58 2001// +/sizetable/1.3/Wed Aug 1 21:31:58 2001// +/staticlibrary.mak/1.2/Wed Aug 1 21:31:58 2001// +/tools.m4/1.2/Wed Aug 1 21:31:58 2001// +/acconfig.h/1.1/Fri Aug 10 14:00:39 2001// +/install-sh/1.1.1.1/Fri Aug 10 14:00:40 2001// +/inttypes.h.in/1.1.1.1/Fri Aug 10 14:00:40 2001// +/netdb.h.in/1.1.1.1/Fri Aug 10 14:00:40 2001// +/statvfs.h.in/1.1.1.1/Fri Aug 10 14:00:40 2001// +/yodl_manpage.mak/1.1.1.1/Fri Aug 10 14:00:40 2001// +/archtable/1.3/Tue Nov 13 14:24:16 2001// +D diff --git a/apt/buildlib/CVS/Repository b/apt/buildlib/CVS/Repository new file mode 100644 index 0000000..c9cb46d --- /dev/null +++ b/apt/buildlib/CVS/Repository @@ -0,0 +1 @@ +rapt/buildlib diff --git a/apt/buildlib/CVS/Root b/apt/buildlib/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/buildlib/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/buildlib/acconfig.h b/apt/buildlib/acconfig.h new file mode 100644 index 0000000..9647d71 --- /dev/null +++ b/apt/buildlib/acconfig.h @@ -0,0 +1,19 @@ +#undef ARCHITECTURE + +#undef HAVE_LIBGPM + +#undef HAVE_LIBSLANG + +#undef HAVE_LIBXPM + +#undef HAVE_MOUNT_H + +#undef HAVE_VFS_H + +#undef HAVE_X11 + +#undef NEED_SOCKLEN_T_DEFINE + +#undef PACKAGE + +#undef VERSION diff --git a/apt/buildlib/archtable b/apt/buildlib/archtable new file mode 100644 index 0000000..252f39d --- /dev/null +++ b/apt/buildlib/archtable @@ -0,0 +1,25 @@ +# This file contains a table of known architecture strings, with +# things to map them to. `configure' will take the output of the +# autoconf cannon macros and look in here. This only deals with architecture +# (CPU) names. + +# The left side is a regex for awk + +i.86 i386 +pentium i386 +sparc sparc +sparc64 sparc +alpha.* alpha +m68k m68k +arm.* arm +powerpc powerpc +ppc powerpc +mipsel mipsel +mipseb mips +mips mips +sheb sheb +shel sh +sh sh +hppa.* hppa +ia64 ia64 +s390 s390 diff --git a/apt/buildlib/config.guess b/apt/buildlib/config.guess new file mode 100755 index 0000000..bf5a9b3 --- /dev/null +++ b/apt/buildlib/config.guess @@ -0,0 +1,1371 @@ +#! /bin/sh +# Attempt to guess a canonical system name. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-02-23' + +# This file is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Written by Per Bothner . +# Please send patches to . +# +# This script attempts to guess a canonical system name similar to +# config.sub. If it succeeds, it prints the system name on stdout, and +# exits with 0. Otherwise, it exits with 1. +# +# The plan is that this can be called by configure scripts if you +# don't specify an explicit build system type. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] + +Output the configuration name of the system \`$me' is run on. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.guess ($timestamp) + +Originally written by Per Bothner. +Copyright (C) 1992, 93, 94, 95, 96, 97, 98, 99, 2000 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" >&2 + exit 1 ;; + * ) + break ;; + esac +done + +if test $# != 0; then + echo "$me: too many arguments$help" >&2 + exit 1 +fi + + +dummy=dummy-$$ +trap 'rm -f $dummy.c $dummy.o $dummy.rel $dummy; exit 1' 1 2 15 + +# CC_FOR_BUILD -- compiler used by this script. +# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still +# use `HOST_CC' if defined, but it is deprecated. + +case $CC_FOR_BUILD,$HOST_CC,$CC in + ,,) echo "int dummy(){}" > $dummy.c + for c in cc gcc c89 ; do + ($c $dummy.c -c -o $dummy.o) >/dev/null 2>&1 + if test $? = 0 ; then + CC_FOR_BUILD="$c"; break + fi + done + rm -f $dummy.c $dummy.o $dummy.rel + if test x"$CC_FOR_BUILD" = x ; then + CC_FOR_BUILD=no_compiler_found + fi + ;; + ,,*) CC_FOR_BUILD=$CC ;; + ,*,*) CC_FOR_BUILD=$HOST_CC ;; +esac + +# This is needed to find uname on a Pyramid OSx when run in the BSD universe. +# (ghazi@noc.rutgers.edu 8/24/94.) +if (test -f /.attbin/uname) >/dev/null 2>&1 ; then + PATH=$PATH:/.attbin ; export PATH +fi + +UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown +UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown +UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown +UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown + +# Note: order is significant - the case branches are not exclusive. + +case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in + *:NetBSD:*:*) + # Netbsd (nbsd) targets should (where applicable) match one or + # more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*, + # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently + # switched to ELF, *-*-netbsd* would select the old + # object file format. This provides both forward + # compatibility and a consistent mechanism for selecting the + # object file format. + # Determine the machine/vendor (is the vendor relevant). + case "${UNAME_MACHINE}" in + amiga) machine=m68k-unknown ;; + arm32) machine=arm-unknown ;; + atari*) machine=m68k-atari ;; + sun3*) machine=m68k-sun ;; + mac68k) machine=m68k-apple ;; + macppc) machine=powerpc-apple ;; + hp3[0-9][05]) machine=m68k-hp ;; + ibmrt|romp-ibm) machine=romp-ibm ;; + *) machine=${UNAME_MACHINE}-unknown ;; + esac + # The Operating System including object format, if it has switched + # to ELF recently, or will in the future. + case "${UNAME_MACHINE}" in + i386|sparc|amiga|arm*|hp300|mvme68k|vax|atari|luna68k|mac68k|news68k|next68k|pc532|sun3*|x68k) + if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \ + | grep __ELF__ >/dev/null + then + # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout). + # Return netbsd for either. FIX? + os=netbsd + else + os=netbsdelf + fi + ;; + *) + os=netbsd + ;; + esac + # The OS release + release=`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM: + # contains redundant information, the shorter form: + # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used. + echo "${machine}-${os}${release}" + exit 0 ;; + alpha:OSF1:*:*) + if test $UNAME_RELEASE = "V4.0"; then + UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'` + fi + # A Vn.n version is a released version. + # A Tn.n version is a released field test version. + # A Xn.n version is an unreleased experimental baselevel. + # 1.2 uses "1.2" for uname -r. + cat <$dummy.s + .data +\$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + + .text + .globl main + .align 4 + .ent main +main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) + UNAME_MACHINE="alpha" + ;; + 1-0) + UNAME_MACHINE="alphaev5" + ;; + 1-1) + UNAME_MACHINE="alphaev56" + ;; + 1-101) + UNAME_MACHINE="alphapca56" + ;; + 2-303) + UNAME_MACHINE="alphaev6" + ;; + 2-307) + UNAME_MACHINE="alphaev67" + ;; + esac + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + exit 0 ;; + Alpha\ *:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # Should we change UNAME_MACHINE based on the output of uname instead + # of the specific Alpha model? + echo alpha-pc-interix + exit 0 ;; + 21064:Windows_NT:50:3) + echo alpha-dec-winnt3.5 + exit 0 ;; + Amiga*:UNIX_System_V:4.0:*) + echo m68k-unknown-sysv4 + exit 0;; + amiga:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:[Aa]miga[Oo][Ss]:*:*) + echo ${UNAME_MACHINE}-unknown-amigaos + exit 0 ;; + arc64:OpenBSD:*:*) + echo mips64el-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + arc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + hkmips:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + pmax:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + sgi:OpenBSD:*:*) + echo mips-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + wgrisc:OpenBSD:*:*) + echo mipsel-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + *:OS/390:*:*) + echo i370-ibm-openedition + exit 0 ;; + arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) + echo arm-acorn-riscix${UNAME_RELEASE} + exit 0;; + SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*) + echo hppa1.1-hitachi-hiuxmpp + exit 0;; + Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*) + # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE. + if test "`(/bin/universe) 2>/dev/null`" = att ; then + echo pyramid-pyramid-sysv3 + else + echo pyramid-pyramid-bsd + fi + exit 0 ;; + NILE*:*:*:dcosx) + echo pyramid-pyramid-svr4 + exit 0 ;; + sun4H:SunOS:5.*:*) + echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*) + echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + i86pc:SunOS:5.*:*) + echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:6*:*) + # According to config.sub, this is the proper way to canonicalize + # SunOS6. Hard to guess exactly what SunOS6 will be like, but + # it's likely to be more like Solaris than SunOS4. + echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + sun4*:SunOS:*:*) + case "`/usr/bin/arch -k`" in + Series*|S4*) + UNAME_RELEASE=`uname -v` + ;; + esac + # Japanese Language versions have a version number like `4.1.3-JL'. + echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'` + exit 0 ;; + sun3*:SunOS:*:*) + echo m68k-sun-sunos${UNAME_RELEASE} + exit 0 ;; + sun*:*:4.2BSD:*) + UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null` + test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3 + case "`/bin/arch`" in + sun3) + echo m68k-sun-sunos${UNAME_RELEASE} + ;; + sun4) + echo sparc-sun-sunos${UNAME_RELEASE} + ;; + esac + exit 0 ;; + aushp:SunOS:*:*) + echo sparc-auspex-sunos${UNAME_RELEASE} + exit 0 ;; + atari*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + # The situation for MiNT is a little confusing. The machine name + # can be virtually everything (everything which is not + # "atarist" or "atariste" at least should have a processor + # > m68000). The system name ranges from "MiNT" over "FreeMiNT" + # to the lowercase version "mint" (or "freemint"). Finally + # the system name "TOS" denotes a system which is actually not + # MiNT. But MiNT is downward compatible to TOS, so this should + # be no problem. + atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*) + echo m68k-atari-mint${UNAME_RELEASE} + exit 0 ;; + milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*) + echo m68k-milan-mint${UNAME_RELEASE} + exit 0 ;; + hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*) + echo m68k-hades-mint${UNAME_RELEASE} + exit 0 ;; + *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*) + echo m68k-unknown-mint${UNAME_RELEASE} + exit 0 ;; + sun3*:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mac68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme68k:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + mvme88k:OpenBSD:*:*) + echo m88k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + powerpc:machten:*:*) + echo powerpc-apple-machten${UNAME_RELEASE} + exit 0 ;; + RISC*:Mach:*:*) + echo mips-dec-mach_bsd4.3 + exit 0 ;; + RISC*:ULTRIX:*:*) + echo mips-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + VAX*:ULTRIX*:*:*) + echo vax-dec-ultrix${UNAME_RELEASE} + exit 0 ;; + 2020:CLIX:*:* | 2430:CLIX:*:*) + echo clipper-intergraph-clix${UNAME_RELEASE} + exit 0 ;; + mips:*:*:UMIPS | mips:*:*:RISCos) + sed 's/^ //' << EOF >$dummy.c +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif + #if defined (host_mips) && defined (MIPSEB) + #if defined (SYSTYPE_SYSV) + printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_SVR4) + printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0); + #endif + #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD) + printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0); + #endif + #endif + exit (-1); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy \ + && ./$dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \ + && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo mips-mips-riscos${UNAME_RELEASE} + exit 0 ;; + Night_Hawk:Power_UNIX:*:*) + echo powerpc-harris-powerunix + exit 0 ;; + m88k:CX/UX:7*:*) + echo m88k-harris-cxux7 + exit 0 ;; + m88k:*:4*:R4*) + echo m88k-motorola-sysv4 + exit 0 ;; + m88k:*:3*:R3*) + echo m88k-motorola-sysv3 + exit 0 ;; + AViiON:dgux:*:*) + # DG/UX returns AViiON for all architectures + UNAME_PROCESSOR=`/usr/bin/uname -p` + if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ] + then + if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \ + [ ${TARGET_BINARY_INTERFACE}x = x ] + then + echo m88k-dg-dgux${UNAME_RELEASE} + else + echo m88k-dg-dguxbcs${UNAME_RELEASE} + fi + else + echo i586-dg-dgux${UNAME_RELEASE} + fi + exit 0 ;; + M88*:DolphinOS:*:*) # DolphinOS (SVR3) + echo m88k-dolphin-sysv3 + exit 0 ;; + M88*:*:R3*:*) + # Delta 88k system running SVR3 + echo m88k-motorola-sysv3 + exit 0 ;; + XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3) + echo m88k-tektronix-sysv3 + exit 0 ;; + Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD) + echo m68k-tektronix-bsd + exit 0 ;; + *:IRIX*:*:*) + echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` + exit 0 ;; + ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. + echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id + exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' + i?86:AIX:*:*) + echo i386-ibm-aix + exit 0 ;; + ia64:AIX:*:*) + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${UNAME_MACHINE}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:2:3) + if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then + sed 's/^ //' << EOF >$dummy.c + #include + + main() + { + if (!__power_pc()) + exit(1); + puts("powerpc-ibm-aix3.2.5"); + exit(0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo rs6000-ibm-aix3.2.5 + elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then + echo rs6000-ibm-aix3.2.4 + else + echo rs6000-ibm-aix3.2 + fi + exit 0 ;; + *:AIX:*:[45]) + IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'` + if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then + IBM_ARCH=rs6000 + else + IBM_ARCH=powerpc + fi + if [ -x /usr/bin/oslevel ] ; then + IBM_REV=`/usr/bin/oslevel` + else + IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE} + fi + echo ${IBM_ARCH}-ibm-aix${IBM_REV} + exit 0 ;; + *:AIX:*:*) + echo rs6000-ibm-aix + exit 0 ;; + ibmrt:4.4BSD:*|romp-ibm:BSD:*) + echo romp-ibm-bsd4.4 + exit 0 ;; + ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and + echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to + exit 0 ;; # report: romp-ibm BSD 4.3 + *:BOSX:*:*) + echo rs6000-bull-bosx + exit 0 ;; + DPX/2?00:B.O.S.:*:*) + echo m68k-bull-sysv3 + exit 0 ;; + 9000/[34]??:4.3bsd:1.*:*) + echo m68k-hp-bsd + exit 0 ;; + hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) + echo m68k-hp-bsd4.4 + exit 0 ;; + 9000/[34678]??:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + case "${UNAME_MACHINE}" in + 9000/31? ) HP_ARCH=m68000 ;; + 9000/[34]?? ) HP_ARCH=m68k ;; + 9000/[678][0-9][0-9]) + case "${HPUX_REV}" in + 11.[0-9][0-9]) + if [ -x /usr/bin/getconf ]; then + sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null` + sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null` + case "${sc_cpu_version}" in + 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0 + 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1 + 532) # CPU_PA_RISC2_0 + case "${sc_kernel_bits}" in + 32) HP_ARCH="hppa2.0n" ;; + 64) HP_ARCH="hppa2.0w" ;; + esac ;; + esac + fi ;; + esac + if [ "${HP_ARCH}" = "" ]; then + sed 's/^ //' << EOF >$dummy.c + + #define _HPUX_SOURCE + #include + #include + + int main () + { + #if defined(_SC_KERNEL_BITS) + long bits = sysconf(_SC_KERNEL_BITS); + #endif + long cpu = sysconf (_SC_CPU_VERSION); + + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1"); break; + case CPU_PA_RISC2_0: + #if defined(_SC_KERNEL_BITS) + switch (bits) + { + case 64: puts ("hppa2.0w"); break; + case 32: puts ("hppa2.0n"); break; + default: puts ("hppa2.0"); break; + } break; + #else /* !defined(_SC_KERNEL_BITS) */ + puts ("hppa2.0"); break; + #endif + default: puts ("hppa1.0"); break; + } + exit (0); + } +EOF + (CCOPTS= $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null ) && HP_ARCH=`./$dummy` + if test -z "$HP_ARCH"; then HP_ARCH=hppa; fi + rm -f $dummy.c $dummy + fi ;; + esac + echo ${HP_ARCH}-hp-hpux${HPUX_REV} + exit 0 ;; + ia64:HP-UX:*:*) + HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` + echo ia64-hp-hpux${HPUX_REV} + exit 0 ;; + 3050*:HI-UX:*:*) + sed 's/^ //' << EOF >$dummy.c + #include + int + main () + { + long cpu = sysconf (_SC_CPU_VERSION); + /* The order matters, because CPU_IS_HP_MC68K erroneously returns + true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct + results, however. */ + if (CPU_IS_PA_RISC (cpu)) + { + switch (cpu) + { + case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break; + case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break; + case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break; + default: puts ("hppa-hitachi-hiuxwe2"); break; + } + } + else if (CPU_IS_HP_MC68K (cpu)) + puts ("m68k-hitachi-hiuxwe2"); + else puts ("unknown-hitachi-hiuxwe2"); + exit (0); + } +EOF + $CC_FOR_BUILD $dummy.c -o $dummy && ./$dummy && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + echo unknown-hitachi-hiuxwe2 + exit 0 ;; + 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* ) + echo hppa1.1-hp-bsd + exit 0 ;; + 9000/8??:4.3bsd:*:*) + echo hppa1.0-hp-bsd + exit 0 ;; + *9??*:MPE/iX:*:*) + echo hppa1.0-hp-mpeix + exit 0 ;; + hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* ) + echo hppa1.1-hp-osf + exit 0 ;; + hp8??:OSF1:*:*) + echo hppa1.0-hp-osf + exit 0 ;; + i?86:OSF1:*:*) + if [ -x /usr/sbin/sysversion ] ; then + echo ${UNAME_MACHINE}-unknown-osf1mk + else + echo ${UNAME_MACHINE}-unknown-osf1 + fi + exit 0 ;; + parisc*:Lites*:*:*) + echo hppa1.1-hp-lites + exit 0 ;; + hppa*:OpenBSD:*:*) + echo hppa-unknown-openbsd + exit 0 ;; + C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*) + echo c1-convex-bsd + exit 0 ;; + C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*) + echo c34-convex-bsd + exit 0 ;; + C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*) + echo c38-convex-bsd + exit 0 ;; + C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*) + echo c4-convex-bsd + exit 0 ;; + CRAY*X-MP:*:*:*) + echo xmp-cray-unicos + exit 0 ;; + CRAY*Y-MP:*:*:*) + echo ymp-cray-unicos${UNAME_RELEASE} + exit 0 ;; + CRAY*[A-Z]90:*:*:*) + echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \ + | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \ + -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ + exit 0 ;; + CRAY*TS:*:*:*) + echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3D:*:*:*) + echo alpha-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*T3E:*:*:*) + echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY*SV1:*:*:*) + echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/' + exit 0 ;; + CRAY-2:*:*:*) + echo cray2-cray-unicos + exit 0 ;; + F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*) + FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'` + FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'` + FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'` + echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}" + exit 0 ;; + hp300:OpenBSD:*:*) + echo m68k-unknown-openbsd${UNAME_RELEASE} + exit 0 ;; + i?86:BSD/386:*:* | i?86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*) + echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} + exit 0 ;; + sparc*:BSD/OS:*:*) + echo sparc-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:BSD/OS:*:*) + echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE} + exit 0 ;; + *:FreeBSD:*:*) + echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` + exit 0 ;; + *:OpenBSD:*:*) + echo ${UNAME_MACHINE}-unknown-openbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'` + exit 0 ;; + i*:CYGWIN*:*) + echo ${UNAME_MACHINE}-pc-cygwin + exit 0 ;; + i*:MINGW*:*) + echo ${UNAME_MACHINE}-pc-mingw32 + exit 0 ;; + i*:PW*:*) + echo ${UNAME_MACHINE}-pc-pw32 + exit 0 ;; + i*:Windows_NT*:* | Pentium*:Windows_NT*:*) + # How do we know it's Interix rather than the generic POSIX subsystem? + # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we + # UNAME_MACHINE based on the output of uname instead of i386? + echo i386-pc-interix + exit 0 ;; + i*:UWIN*:*) + echo ${UNAME_MACHINE}-pc-uwin + exit 0 ;; + p*:CYGWIN*:*) + echo powerpcle-unknown-cygwin + exit 0 ;; + prep*:SunOS:5.*:*) + echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` + exit 0 ;; + *:GNU:*:*) + echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` + exit 0 ;; + i*86:Minix:*:*) + echo ${UNAME_MACHINE}-pc-minix + exit 0 ;; + arm*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + ia64:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux + exit 0 ;; + m68*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + mips:Linux:*:*) + cat >$dummy.c < /* for printf() prototype */ +int main (int argc, char *argv[]) { +#else +int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __MIPSEB__ + printf ("%s-unknown-linux-gnu\n", argv[1]); +#endif +#ifdef __MIPSEL__ + printf ("%sel-unknown-linux-gnu\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + ;; + ppc:Linux:*:*) + # Determine Lib Version + cat >$dummy.c < +#if defined(__GLIBC__) +extern char __libc_version[]; +extern char __libc_release[]; +#endif +main(argc, argv) + int argc; + char *argv[]; +{ +#if defined(__GLIBC__) + printf("%s %s\n", __libc_version, __libc_release); +#else + printf("unknown\n"); +#endif + return 0; +} +EOF + LIBC="" + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null + if test "$?" = 0 ; then + ./$dummy | grep 1\.99 > /dev/null + if test "$?" = 0 ; then LIBC="libc1" ; fi + fi + rm -f $dummy.c $dummy + echo powerpc-unknown-linux-gnu${LIBC} + exit 0 ;; + alpha:Linux:*:*) + cat <$dummy.s + .data + \$Lformat: + .byte 37,100,45,37,120,10,0 # "%d-%x\n" + .text + .globl main + .align 4 + .ent main + main: + .frame \$30,16,\$26,0 + ldgp \$29,0(\$27) + .prologue 1 + .long 0x47e03d80 # implver \$0 + lda \$2,-1 + .long 0x47e20c21 # amask \$2,\$1 + lda \$16,\$Lformat + mov \$0,\$17 + not \$1,\$18 + jsr \$26,printf + ldgp \$29,0(\$26) + mov 0,\$16 + jsr \$26,exit + .end main +EOF + LIBC="" + $CC_FOR_BUILD $dummy.s -o $dummy 2>/dev/null + if test "$?" = 0 ; then + case `./$dummy` in + 0-0) UNAME_MACHINE="alpha" ;; + 1-0) UNAME_MACHINE="alphaev5" ;; + 1-1) UNAME_MACHINE="alphaev56" ;; + 1-101) UNAME_MACHINE="alphapca56" ;; + 2-303) UNAME_MACHINE="alphaev6" ;; + 2-307) UNAME_MACHINE="alphaev67" ;; + esac + objdump --private-headers $dummy | \ + grep ld.so.1 > /dev/null + if test "$?" = 0 ; then + LIBC="libc1" + fi + fi + rm -f $dummy.s $dummy + echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} + exit 0 ;; + parisc:Linux:*:* | hppa:Linux:*:*) + # Look for CPU level + case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in + PA7*) echo hppa1.1-unknown-linux-gnu ;; + PA8*) echo hppa2.0-unknown-linux-gnu ;; + *) echo hppa-unknown-linux-gnu ;; + esac + exit 0 ;; + parisc64:Linux:*:* | hppa64:Linux:*:*) + echo hppa64-unknown-linux-gnu + exit 0 ;; + s390:Linux:*:* | s390x:Linux:*:*) + echo ${UNAME_MACHINE}-ibm-linux + exit 0 ;; + sh*:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + sparc:Linux:*:*) + echo ${UNAME_MACHINE}-unknown-linux-gnu + exit 0 ;; + x86_64:Linux:*:*) + echo x86_64-unknown-linux-gnu + exit 0 ;; + *:Linux:*:*) + # The BFD linker knows what the default object file format is, so + # first see if it will tell us. cd to the root directory to prevent + # problems with other programs or directories called `ld' in the path. + ld_supported_emulations=`cd /; ld --help 2>&1 \ + | sed -ne '/supported emulations:/!d + s/[ ][ ]*/ /g + s/.*supported emulations: *// + s/ .*// + p'` + case "$ld_supported_emulations" in + i?86linux) + echo "${UNAME_MACHINE}-pc-linux-gnuaout" + exit 0 + ;; + elf_i?86) + TENTATIVE="${UNAME_MACHINE}-pc-linux-gnu" + ;; + i?86coff) + echo "${UNAME_MACHINE}-pc-linux-gnucoff" + exit 0 + ;; + esac + + # Either a pre-BFD a.out linker (linux-gnuoldld) + # or one that does not give us useful --help. + # GCC wants to distinguish between linux-gnuoldld and linux-gnuaout. + # If ld does not provide *any* "supported emulations:" + # that means it is gnuoldld. + test -z "$ld_supported_emulations" \ + && echo "${UNAME_MACHINE}-pc-linux-gnuoldld" && exit 0 + + case "${UNAME_MACHINE}" in + i?86) + VENDOR=pc; + ;; + *) + VENDOR=unknown; + ;; + esac + # Determine whether the default compiler is a.out or elf + cat >$dummy.c < +#ifdef __cplusplus +#include /* for printf() prototype */ + int main (int argc, char *argv[]) { +#else + int main (argc, argv) int argc; char *argv[]; { +#endif +#ifdef __ELF__ +# ifdef __GLIBC__ +# if __GLIBC__ >= 2 + printf ("%s-${VENDOR}-linux-gnu\n", argv[1]); +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +# else + printf ("%s-${VENDOR}-linux-gnulibc1\n", argv[1]); +# endif +#else + printf ("%s-${VENDOR}-linux-gnuaout\n", argv[1]); +#endif + return 0; +} +EOF + $CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy "${UNAME_MACHINE}" && rm $dummy.c $dummy && exit 0 + rm -f $dummy.c $dummy + test x"${TENTATIVE}" != x && echo "${TENTATIVE}" && exit 0 + ;; +# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions +# are messed up and put the nodename in both sysname and nodename. + i?86:DYNIX/ptx:4*:*) + echo i386-sequent-sysv4 + exit 0 ;; + i?86:UNIX_SV:4.2MP:2.*) + # Unixware is an offshoot of SVR4, but it has its own version + # number series starting with 2... + # I am not positive that other SVR4 systems won't match this, + # I just have to hope. -- rms. + # Use sysv4.2uw... so that sysv4* matches it. + echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION} + exit 0 ;; + i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*) + UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'` + if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then + echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL} + fi + exit 0 ;; + i?86:*:5:7*) + # Fixed at (any) Pentium or better + UNAME_MACHINE=i586 + if [ ${UNAME_SYSTEM} = "UnixWare" ] ; then + echo ${UNAME_MACHINE}-sco-sysv${UNAME_RELEASE}uw${UNAME_VERSION} + else + echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} + fi + exit 0 ;; + i?86:*:3.2:*) + if test -f /usr/options/cb.name; then + UNAME_REL=`sed -n 's/.*Version //p' /dev/null >/dev/null ; then + UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')` + (/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486 + (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \ + && UNAME_MACHINE=i586 + (/bin/uname -X|egrep '^Machine.*Pent ?II' >/dev/null) \ + && UNAME_MACHINE=i686 + (/bin/uname -X|egrep '^Machine.*Pentium Pro' >/dev/null) \ + && UNAME_MACHINE=i686 + echo ${UNAME_MACHINE}-pc-sco$UNAME_REL + else + echo ${UNAME_MACHINE}-pc-sysv32 + fi + exit 0 ;; + i?86:*DOS:*:*) + echo ${UNAME_MACHINE}-pc-msdosdjgpp + exit 0 ;; + pc:*:*:*) + # Left here for compatibility: + # uname -m prints for DJGPP always 'pc', but it prints nothing about + # the processor, so we play safe by assuming i386. + echo i386-pc-msdosdjgpp + exit 0 ;; + Intel:Mach:3*:*) + echo i386-pc-mach3 + exit 0 ;; + paragon:*:*:*) + echo i860-intel-osf1 + exit 0 ;; + i860:*:4.*:*) # i860-SVR4 + if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then + echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4 + else # Add other i860-SVR4 vendors below as they are discovered. + echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4 + fi + exit 0 ;; + mini*:CTIX:SYS*5:*) + # "miniframe" + echo m68010-convergent-sysv + exit 0 ;; + M68*:*:R3V[567]*:*) + test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; + 3[34]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0) + OS_REL='' + test -r /etc/.relid \ + && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid` + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4.3${OS_REL} && exit 0 + /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \ + && echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;; + 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) + /bin/uname -p 2>/dev/null | grep 86 >/dev/null \ + && echo i486-ncr-sysv4 && exit 0 ;; + m68*:LynxOS:2.*:*) + echo m68k-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + mc68030:UNIX_System_V:4.*:*) + echo m68k-atari-sysv4 + exit 0 ;; + i?86:LynxOS:2.*:* | i?86:LynxOS:3.[01]*:*) + echo i386-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + TSUNAMI:LynxOS:2.*:*) + echo sparc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + rs6000:LynxOS:2.*:*) + echo rs6000-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:*) + echo powerpc-unknown-lynxos${UNAME_RELEASE} + exit 0 ;; + SM[BE]S:UNIX_SV:*:*) + echo mips-dde-sysv${UNAME_RELEASE} + exit 0 ;; + RM*:ReliantUNIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + RM*:SINIX-*:*:*) + echo mips-sni-sysv4 + exit 0 ;; + *:SINIX-*:*:*) + if uname -p 2>/dev/null >/dev/null ; then + UNAME_MACHINE=`(uname -p) 2>/dev/null` + echo ${UNAME_MACHINE}-sni-sysv4 + else + echo ns32k-sni-sysv + fi + exit 0 ;; + PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort + # says + echo i586-unisys-sysv4 + exit 0 ;; + *:UNIX_System_V:4*:FTX*) + # From Gerald Hewes . + # How about differentiating between stratus architectures? -djm + echo hppa1.1-stratus-sysv4 + exit 0 ;; + *:*:*:FTX*) + # From seanf@swdc.stratus.com. + echo i860-stratus-sysv4 + exit 0 ;; + mc68*:A/UX:*:*) + echo m68k-apple-aux${UNAME_RELEASE} + exit 0 ;; + news*:NEWS-OS:6*:*) + echo mips-sony-newsos6 + exit 0 ;; + R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*) + if [ -d /usr/nec ]; then + echo mips-nec-sysv${UNAME_RELEASE} + else + echo mips-unknown-sysv${UNAME_RELEASE} + fi + exit 0 ;; + BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only. + echo powerpc-be-beos + exit 0 ;; + BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only. + echo powerpc-apple-beos + exit 0 ;; + BePC:BeOS:*:*) # BeOS running on Intel PC compatible. + echo i586-pc-beos + exit 0 ;; + SX-4:SUPER-UX:*:*) + echo sx4-nec-superux${UNAME_RELEASE} + exit 0 ;; + SX-5:SUPER-UX:*:*) + echo sx5-nec-superux${UNAME_RELEASE} + exit 0 ;; + Power*:Rhapsody:*:*) + echo powerpc-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Rhapsody:*:*) + echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE} + exit 0 ;; + *:Darwin:*:*) + echo `uname -p`-apple-darwin${UNAME_RELEASE} + exit 0 ;; + *:procnto*:*:* | *:QNX:[0123456789]*:*) + if test "${UNAME_MACHINE}" = "x86pc"; then + UNAME_MACHINE=pc + fi + echo `uname -p`-${UNAME_MACHINE}-nto-qnx + exit 0 ;; + *:QNX:*:4*) + echo i386-pc-qnx + exit 0 ;; + NSR-[KW]:NONSTOP_KERNEL:*:*) + echo nsr-tandem-nsk${UNAME_RELEASE} + exit 0 ;; + *:NonStop-UX:*:*) + echo mips-compaq-nonstopux + exit 0 ;; + BS2000:POSIX*:*:*) + echo bs2000-siemens-sysv + exit 0 ;; + DS/*:UNIX_System_V:*:*) + echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE} + exit 0 ;; + *:Plan9:*:*) + # "uname -m" is not consistent, so use $cputype instead. 386 + # is converted to i386 for consistency with other x86 + # operating systems. + if test "$cputype" = "386"; then + UNAME_MACHINE=i386 + else + UNAME_MACHINE="$cputype" + fi + echo ${UNAME_MACHINE}-unknown-plan9 + exit 0 ;; + i?86:OS/2:*:*) + # If we were able to find `uname', then EMX Unix compatibility + # is probably installed. + echo ${UNAME_MACHINE}-pc-os2-emx + exit 0 ;; + *:TOPS-10:*:*) + echo pdp10-unknown-tops10 + exit 0 ;; + *:TENEX:*:*) + echo pdp10-unknown-tenex + exit 0 ;; + KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*) + echo pdp10-dec-tops20 + exit 0 ;; + XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*) + echo pdp10-xkl-tops20 + exit 0 ;; + *:TOPS-20:*:*) + echo pdp10-unknown-tops20 + exit 0 ;; + *:ITS:*:*) + echo pdp10-unknown-its + exit 0 ;; +esac + +#echo '(No uname command or uname output not recognized.)' 1>&2 +#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2 + +cat >$dummy.c < +# include +#endif +main () +{ +#if defined (sony) +#if defined (MIPSEB) + /* BFD wants "bsd" instead of "newsos". Perhaps BFD should be changed, + I don't know.... */ + printf ("mips-sony-bsd\n"); exit (0); +#else +#include + printf ("m68k-sony-newsos%s\n", +#ifdef NEWSOS4 + "4" +#else + "" +#endif + ); exit (0); +#endif +#endif + +#if defined (__arm) && defined (__acorn) && defined (__unix) + printf ("arm-acorn-riscix"); exit (0); +#endif + +#if defined (hp300) && !defined (hpux) + printf ("m68k-hp-bsd\n"); exit (0); +#endif + +#if defined (NeXT) +#if !defined (__ARCHITECTURE__) +#define __ARCHITECTURE__ "m68k" +#endif + int version; + version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; + if (version < 4) + printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version); + else + printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version); + exit (0); +#endif + +#if defined (MULTIMAX) || defined (n16) +#if defined (UMAXV) + printf ("ns32k-encore-sysv\n"); exit (0); +#else +#if defined (CMU) + printf ("ns32k-encore-mach\n"); exit (0); +#else + printf ("ns32k-encore-bsd\n"); exit (0); +#endif +#endif +#endif + +#if defined (__386BSD__) + printf ("i386-pc-bsd\n"); exit (0); +#endif + +#if defined (sequent) +#if defined (i386) + printf ("i386-sequent-dynix\n"); exit (0); +#endif +#if defined (ns32000) + printf ("ns32k-sequent-dynix\n"); exit (0); +#endif +#endif + +#if defined (_SEQUENT_) + struct utsname un; + + uname(&un); + + if (strncmp(un.version, "V2", 2) == 0) { + printf ("i386-sequent-ptx2\n"); exit (0); + } + if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */ + printf ("i386-sequent-ptx1\n"); exit (0); + } + printf ("i386-sequent-ptx\n"); exit (0); + +#endif + +#if defined (vax) +# if !defined (ultrix) +# include +# if defined (BSD) +# if BSD == 43 + printf ("vax-dec-bsd4.3\n"); exit (0); +# else +# if BSD == 199006 + printf ("vax-dec-bsd4.3reno\n"); exit (0); +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# endif +# else + printf ("vax-dec-bsd\n"); exit (0); +# endif +# else + printf ("vax-dec-ultrix\n"); exit (0); +# endif +#endif + +#if defined (alliant) && defined (i860) + printf ("i860-alliant-bsd\n"); exit (0); +#endif + + exit (1); +} +EOF + +$CC_FOR_BUILD $dummy.c -o $dummy 2>/dev/null && ./$dummy && rm $dummy.c $dummy && exit 0 +rm -f $dummy.c $dummy + +# Apollos put the system type in the environment. + +test -d /usr/apollo && { echo ${ISP}-apollo-${SYSTYPE}; exit 0; } + +# Convex versions that predate uname can use getsysinfo(1) + +if [ -x /usr/convex/getsysinfo ] +then + case `getsysinfo -f cpu_type` in + c1*) + echo c1-convex-bsd + exit 0 ;; + c2*) + if getsysinfo -f scalar_acc + then echo c32-convex-bsd + else echo c2-convex-bsd + fi + exit 0 ;; + c34*) + echo c34-convex-bsd + exit 0 ;; + c38*) + echo c38-convex-bsd + exit 0 ;; + c4*) + echo c4-convex-bsd + exit 0 ;; + esac +fi + +cat >&2 < in order to provide the needed +information to handle your system. + +config.guess timestamp = $timestamp + +uname -m = `(uname -m) 2>/dev/null || echo unknown` +uname -r = `(uname -r) 2>/dev/null || echo unknown` +uname -s = `(uname -s) 2>/dev/null || echo unknown` +uname -v = `(uname -v) 2>/dev/null || echo unknown` + +/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null` +/bin/uname -X = `(/bin/uname -X) 2>/dev/null` + +hostinfo = `(hostinfo) 2>/dev/null` +/bin/universe = `(/bin/universe) 2>/dev/null` +/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null` +/bin/arch = `(/bin/arch) 2>/dev/null` +/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null` +/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null` + +UNAME_MACHINE = ${UNAME_MACHINE} +UNAME_RELEASE = ${UNAME_RELEASE} +UNAME_SYSTEM = ${UNAME_SYSTEM} +UNAME_VERSION = ${UNAME_VERSION} +EOF + +exit 1 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/apt/buildlib/config.h.in b/apt/buildlib/config.h.in new file mode 100644 index 0000000..ca560b7 --- /dev/null +++ b/apt/buildlib/config.h.in @@ -0,0 +1,51 @@ +/* Define if your processor stores words with the most significant + byte first (like Motorola and SPARC, unlike Intel and VAX). */ +#undef WORDS_BIGENDIAN + +/* The following 4 are only used by inttypes.h shim if the system lacks + inttypes.h */ +/* The number of bytes in a usigned char. */ +#undef SIZEOF_CHAR + +/* The number of bytes in a unsigned int. */ +#undef SIZEOF_INT + +/* The number of bytes in a unsigned long. */ +#undef SIZEOF_LONG + +/* The number of bytes in a unsigned short. */ +#undef SIZEOF_SHORT + +/* These two are used by the statvfs shim for glibc2.0 and bsd */ +/* Define if we have sys/vfs.h */ +#undef HAVE_VFS_H + +/* Define if we have sys/mount.h */ +#undef HAVE_MOUNT_H + +/* Define if we have enabled pthread support */ +#undef HAVE_PTHREAD + +/* I hate this */ +#undef HAVE_DB1_DB_H + +/* The system has rpm installed */ +#undef HAVE_RPM + +/* This system uses RPM 4 */ +#undef HAVE_RPM4 + +/* If there is no socklen_t, define this for the netdb shim */ +#undef NEED_SOCKLEN_T_DEFINE + +/* Define the cpu name string */ +#undef COMMON_CPU + +/* Define the on name string */ +#undef COMMON_OS + +/* The version number string */ +#undef VERSION + +/* The package name string */ +#undef PACKAGE diff --git a/apt/buildlib/config.sub b/apt/buildlib/config.sub new file mode 100755 index 0000000..ddbbfe5 --- /dev/null +++ b/apt/buildlib/config.sub @@ -0,0 +1,1356 @@ +#! /bin/sh +# Configuration validation subroutine script. +# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +# Free Software Foundation, Inc. + +timestamp='2001-02-16' + +# This file is (in principle) common to ALL GNU software. +# The presence of a machine in this file suggests that SOME GNU software +# can handle that machine. It does not imply ALL GNU software can. +# +# This file is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, +# Boston, MA 02111-1307, USA. + +# As a special exception to the GNU General Public License, if you +# distribute this file as part of a program that contains a +# configuration script generated by Autoconf, you may include it under +# the same distribution terms that you use for the rest of that program. + +# Please send patches to . +# +# Configuration subroutine to validate and canonicalize a configuration type. +# Supply the specified configuration type as an argument. +# If it is invalid, we print an error message on stderr and exit with code 1. +# Otherwise, we print the canonical config type on stdout and succeed. + +# This file is supposed to be the same for all GNU packages +# and recognize all the CPU types, system types and aliases +# that are meaningful with *any* GNU software. +# Each package is responsible for reporting which valid configurations +# it does not support. The user should be able to distinguish +# a failure to support a valid configuration from a meaningless +# configuration. + +# The goal of this file is to map all the various variations of a given +# machine specification into a single specification in the form: +# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM +# or in some cases, the newer four-part form: +# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM +# It is wrong to echo any other type of specification. + +me=`echo "$0" | sed -e 's,.*/,,'` + +usage="\ +Usage: $0 [OPTION] CPU-MFR-OPSYS + $0 [OPTION] ALIAS + +Canonicalize a configuration name. + +Operation modes: + -h, --help print this help, then exit + -t, --time-stamp print date of last modification, then exit + -v, --version print version number, then exit + +Report bugs and patches to ." + +version="\ +GNU config.sub ($timestamp) + +Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001 +Free Software Foundation, Inc. + +This is free software; see the source for copying conditions. There is NO +warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." + +help=" +Try \`$me --help' for more information." + +# Parse command line +while test $# -gt 0 ; do + case $1 in + --time-stamp | --time* | -t ) + echo "$timestamp" ; exit 0 ;; + --version | -v ) + echo "$version" ; exit 0 ;; + --help | --h* | -h ) + echo "$usage"; exit 0 ;; + -- ) # Stop option processing + shift; break ;; + - ) # Use stdin as input. + break ;; + -* ) + echo "$me: invalid option $1$help" + exit 1 ;; + + *local*) + # First pass through any local machine types. + echo $1 + exit 0;; + + * ) + break ;; + esac +done + +case $# in + 0) echo "$me: missing argument$help" >&2 + exit 1;; + 1) ;; + *) echo "$me: too many arguments$help" >&2 + exit 1;; +esac + +# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any). +# Here we must recognize all the valid KERNEL-OS combinations. +maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'` +case $maybe_os in + nto-qnx* | linux-gnu* | storm-chaos* | os2-emx*) + os=-$maybe_os + basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'` + ;; + *) + basic_machine=`echo $1 | sed 's/-[^-]*$//'` + if [ $basic_machine != $1 ] + then os=`echo $1 | sed 's/.*-/-/'` + else os=; fi + ;; +esac + +### Let's recognize common machines as not being operating systems so +### that things like config.sub decstation-3100 work. We also +### recognize some manufacturers as not being operating systems, so we +### can provide default operating systems below. +case $os in + -sun*os*) + # Prevent following clause from handling this invalid input. + ;; + -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \ + -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \ + -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \ + -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\ + -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \ + -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \ + -apple | -axis) + os= + basic_machine=$1 + ;; + -sim | -cisco | -oki | -wec | -winbond) + os= + basic_machine=$1 + ;; + -scout) + ;; + -wrs) + os=-vxworks + basic_machine=$1 + ;; + -hiux*) + os=-hiuxwe2 + ;; + -sco5) + os=-sco3.2v5 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco4) + os=-sco3.2v4 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2.[4-9]*) + os=`echo $os | sed -e 's/sco3.2./sco3.2v/'` + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco3.2v[4-9]*) + # Don't forget version if it is 3.2v4 or newer. + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -sco*) + os=-sco3.2v2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -udk*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -isc) + os=-isc2.2 + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -clix*) + basic_machine=clipper-intergraph + ;; + -isc*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'` + ;; + -lynx*) + os=-lynxos + ;; + -ptx*) + basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'` + ;; + -windowsnt*) + os=`echo $os | sed -e 's/windowsnt/winnt/'` + ;; + -psos*) + os=-psos + ;; + -mint | -mint[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; +esac + +# Decode aliases for certain CPU-COMPANY combinations. +case $basic_machine in + # Recognize the basic CPU types without company name. + # Some are omitted here because they have special meanings below. + tahoe | i860 | ia64 | m32r | m68k | m68000 | m88k | ns32k | arc \ + | arm | arme[lb] | arm[bl]e | armv[2345] | armv[345][lb] | strongarm | xscale \ + | pyramid | mn10200 | mn10300 | tron | a29k \ + | 580 | i960 | h8300 \ + | x86 | ppcbe | mipsbe | mipsle | shbe | shle \ + | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w | hppa2.0n \ + | hppa64 \ + | alpha | alphaev[4-8] | alphaev56 | alphapca5[67] \ + | alphaev6[78] \ + | we32k | ns16k | clipper | i370 | sh | sh[34] \ + | powerpc | powerpcle \ + | 1750a | dsp16xx | pdp10 | pdp11 \ + | mips16 | mips64 | mipsel | mips64el \ + | mips64orion | mips64orionel | mipstx39 | mipstx39el \ + | mips64vr4300 | mips64vr4300el | mips64vr4100 | mips64vr4100el \ + | mips64vr5000 | miprs64vr5000el | mcore \ + | sparc | sparclet | sparclite | sparc64 | sparcv9 | v850 | c4x \ + | thumb | d10v | d30v | fr30 | avr | openrisc) + basic_machine=$basic_machine-unknown + ;; + m6811 | m68hc11 | m6812 | m68hc12) + # Motorola 68HC11/12. + basic_machine=$basic_machine-unknown + os=-none + ;; + m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | z8k | v70 | h8500 | w65 | pj | pjl) + ;; + + # We use `pc' rather than `unknown' + # because (1) that's what they normally are, and + # (2) the word "unknown" tends to confuse beginning users. + i[234567]86 | x86_64) + basic_machine=$basic_machine-pc + ;; + # Object if more than one company name word. + *-*-*) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; + # Recognize the basic CPU types with company name. + # FIXME: clean up the formatting here. + vax-* | tahoe-* | i[234567]86-* | i860-* | ia64-* | m32r-* | m68k-* | m68000-* \ + | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | c[123]* \ + | arm-* | armbe-* | armle-* | armv*-* | strongarm-* | xscale-* \ + | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \ + | power-* | none-* | 580-* | cray2-* | h8300-* | h8500-* | i960-* \ + | xmp-* | ymp-* \ + | x86-* | ppcbe-* | mipsbe-* | mipsle-* | shbe-* | shle-* \ + | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \ + | hppa2.0n-* | hppa64-* \ + | alpha-* | alphaev[4-8]-* | alphaev56-* | alphapca5[67]-* \ + | alphaev6[78]-* \ + | we32k-* | cydra-* | ns16k-* | pn-* | np1-* | xps100-* \ + | clipper-* | orion-* \ + | sparclite-* | pdp10-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \ + | sparc64-* | sparcv9-* | sparc86x-* | mips16-* | mips64-* | mipsel-* \ + | mips64el-* | mips64orion-* | mips64orionel-* \ + | mips64vr4100-* | mips64vr4100el-* | mips64vr4300-* | mips64vr4300el-* \ + | mipstx39-* | mipstx39el-* | mcore-* \ + | f30[01]-* | f700-* | s390-* | s390x-* | sv1-* | t3e-* \ + | [cjt]90-* \ + | m88110-* | m680[01234]0-* | m683?2-* | m68360-* | z8k-* | d10v-* \ + | thumb-* | v850-* | d30v-* | tic30-* | c30-* | fr30-* \ + | bs2000-* | tic54x-* | c54x-* | x86_64-*) + ;; + # Recognize the various machine names and aliases which stand + # for a CPU type and a company and sometimes even an OS. + 386bsd) + basic_machine=i386-unknown + os=-bsd + ;; + 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc) + basic_machine=m68000-att + ;; + 3b*) + basic_machine=we32k-att + ;; + a29khif) + basic_machine=a29k-amd + os=-udi + ;; + adobe68k) + basic_machine=m68010-adobe + os=-scout + ;; + alliant | fx80) + basic_machine=fx80-alliant + ;; + altos | altos3068) + basic_machine=m68k-altos + ;; + am29k) + basic_machine=a29k-none + os=-bsd + ;; + amdahl) + basic_machine=580-amdahl + os=-sysv + ;; + amiga | amiga-*) + basic_machine=m68k-unknown + ;; + amigaos | amigados) + basic_machine=m68k-unknown + os=-amigaos + ;; + amigaunix | amix) + basic_machine=m68k-unknown + os=-sysv4 + ;; + apollo68) + basic_machine=m68k-apollo + os=-sysv + ;; + apollo68bsd) + basic_machine=m68k-apollo + os=-bsd + ;; + aux) + basic_machine=m68k-apple + os=-aux + ;; + balance) + basic_machine=ns32k-sequent + os=-dynix + ;; + convex-c1) + basic_machine=c1-convex + os=-bsd + ;; + convex-c2) + basic_machine=c2-convex + os=-bsd + ;; + convex-c32) + basic_machine=c32-convex + os=-bsd + ;; + convex-c34) + basic_machine=c34-convex + os=-bsd + ;; + convex-c38) + basic_machine=c38-convex + os=-bsd + ;; + cray | ymp) + basic_machine=ymp-cray + os=-unicos + ;; + cray2) + basic_machine=cray2-cray + os=-unicos + ;; + [cjt]90) + basic_machine=${basic_machine}-cray + os=-unicos + ;; + crds | unos) + basic_machine=m68k-crds + ;; + cris | cris-* | etrax*) + basic_machine=cris-axis + ;; + da30 | da30-*) + basic_machine=m68k-da30 + ;; + decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn) + basic_machine=mips-dec + ;; + delta | 3300 | motorola-3300 | motorola-delta \ + | 3300-motorola | delta-motorola) + basic_machine=m68k-motorola + ;; + delta88) + basic_machine=m88k-motorola + os=-sysv3 + ;; + dpx20 | dpx20-*) + basic_machine=rs6000-bull + os=-bosx + ;; + dpx2* | dpx2*-bull) + basic_machine=m68k-bull + os=-sysv3 + ;; + ebmon29k) + basic_machine=a29k-amd + os=-ebmon + ;; + elxsi) + basic_machine=elxsi-elxsi + os=-bsd + ;; + encore | umax | mmax) + basic_machine=ns32k-encore + ;; + es1800 | OSE68k | ose68k | ose | OSE) + basic_machine=m68k-ericsson + os=-ose + ;; + fx2800) + basic_machine=i860-alliant + ;; + genix) + basic_machine=ns32k-ns + ;; + gmicro) + basic_machine=tron-gmicro + os=-sysv + ;; + go32) + basic_machine=i386-pc + os=-go32 + ;; + h3050r* | hiux*) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + h8300hms) + basic_machine=h8300-hitachi + os=-hms + ;; + h8300xray) + basic_machine=h8300-hitachi + os=-xray + ;; + h8500hms) + basic_machine=h8500-hitachi + os=-hms + ;; + harris) + basic_machine=m88k-harris + os=-sysv3 + ;; + hp300-*) + basic_machine=m68k-hp + ;; + hp300bsd) + basic_machine=m68k-hp + os=-bsd + ;; + hp300hpux) + basic_machine=m68k-hp + os=-hpux + ;; + hp3k9[0-9][0-9] | hp9[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k2[0-9][0-9] | hp9k31[0-9]) + basic_machine=m68000-hp + ;; + hp9k3[2-9][0-9]) + basic_machine=m68k-hp + ;; + hp9k6[0-9][0-9] | hp6[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hp9k7[0-79][0-9] | hp7[0-79][0-9]) + basic_machine=hppa1.1-hp + ;; + hp9k78[0-9] | hp78[0-9]) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893) + # FIXME: really hppa2.0-hp + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][13679] | hp8[0-9][13679]) + basic_machine=hppa1.1-hp + ;; + hp9k8[0-9][0-9] | hp8[0-9][0-9]) + basic_machine=hppa1.0-hp + ;; + hppa-next) + os=-nextstep3 + ;; + hppaosf) + basic_machine=hppa1.1-hp + os=-osf + ;; + hppro) + basic_machine=hppa1.1-hp + os=-proelf + ;; + i370-ibm* | ibm*) + basic_machine=i370-ibm + ;; +# I'm not sure what "Sysv32" means. Should this be sysv3.2? + i[34567]86v32) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv32 + ;; + i[34567]86v4*) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv4 + ;; + i[34567]86v) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-sysv + ;; + i[34567]86sol2) + basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` + os=-solaris2 + ;; + i386mach) + basic_machine=i386-mach + os=-mach + ;; + i386-vsta | vsta) + basic_machine=i386-unknown + os=-vsta + ;; + iris | iris4d) + basic_machine=mips-sgi + case $os in + -irix*) + ;; + *) + os=-irix4 + ;; + esac + ;; + isi68 | isi) + basic_machine=m68k-isi + os=-sysv + ;; + m88k-omron*) + basic_machine=m88k-omron + ;; + magnum | m3230) + basic_machine=mips-mips + os=-sysv + ;; + merlin) + basic_machine=ns32k-utek + os=-sysv + ;; + mingw32) + basic_machine=i386-pc + os=-mingw32 + ;; + miniframe) + basic_machine=m68000-convergent + ;; + *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*) + basic_machine=m68k-atari + os=-mint + ;; + mipsel*-linux*) + basic_machine=mipsel-unknown + os=-linux-gnu + ;; + mips*-linux*) + basic_machine=mips-unknown + os=-linux-gnu + ;; + mips3*-*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` + ;; + mips3*) + basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown + ;; + mmix*) + basic_machine=mmix-knuth + os=-mmixware + ;; + monitor) + basic_machine=m68k-rom68k + os=-coff + ;; + msdos) + basic_machine=i386-pc + os=-msdos + ;; + mvs) + basic_machine=i370-ibm + os=-mvs + ;; + ncr3000) + basic_machine=i486-ncr + os=-sysv4 + ;; + netbsd386) + basic_machine=i386-unknown + os=-netbsd + ;; + netwinder) + basic_machine=armv4l-rebel + os=-linux + ;; + news | news700 | news800 | news900) + basic_machine=m68k-sony + os=-newsos + ;; + news1000) + basic_machine=m68030-sony + os=-newsos + ;; + news-3600 | risc-news) + basic_machine=mips-sony + os=-newsos + ;; + necv70) + basic_machine=v70-nec + os=-sysv + ;; + next | m*-next ) + basic_machine=m68k-next + case $os in + -nextstep* ) + ;; + -ns2*) + os=-nextstep2 + ;; + *) + os=-nextstep3 + ;; + esac + ;; + nh3000) + basic_machine=m68k-harris + os=-cxux + ;; + nh[45]000) + basic_machine=m88k-harris + os=-cxux + ;; + nindy960) + basic_machine=i960-intel + os=-nindy + ;; + mon960) + basic_machine=i960-intel + os=-mon960 + ;; + nonstopux) + basic_machine=mips-compaq + os=-nonstopux + ;; + np1) + basic_machine=np1-gould + ;; + nsr-tandem) + basic_machine=nsr-tandem + ;; + op50n-* | op60c-*) + basic_machine=hppa1.1-oki + os=-proelf + ;; + OSE68000 | ose68000) + basic_machine=m68000-ericsson + os=-ose + ;; + os68k) + basic_machine=m68k-none + os=-os68k + ;; + pa-hitachi) + basic_machine=hppa1.1-hitachi + os=-hiuxwe2 + ;; + paragon) + basic_machine=i860-intel + os=-osf + ;; + pbd) + basic_machine=sparc-tti + ;; + pbb) + basic_machine=m68k-tti + ;; + pc532 | pc532-*) + basic_machine=ns32k-pc532 + ;; + pentium | p5 | k5 | k6 | nexgen) + basic_machine=i586-pc + ;; + pentiumpro | p6 | 6x86 | athlon) + basic_machine=i686-pc + ;; + pentiumii | pentium2) + basic_machine=i686-pc + ;; + pentium-* | p5-* | k5-* | k6-* | nexgen-*) + basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumpro-* | p6-* | 6x86-* | athlon-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pentiumii-* | pentium2-*) + basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + pn) + basic_machine=pn-gould + ;; + power) basic_machine=power-ibm + ;; + ppc) basic_machine=powerpc-unknown + ;; + ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ppcle | powerpclittle | ppc-le | powerpc-little) + basic_machine=powerpcle-unknown + ;; + ppcle-* | powerpclittle-*) + basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'` + ;; + ps2) + basic_machine=i386-ibm + ;; + pw32) + basic_machine=i586-unknown + os=-pw32 + ;; + rom68k) + basic_machine=m68k-rom68k + os=-coff + ;; + rm[46]00) + basic_machine=mips-siemens + ;; + rtpc | rtpc-*) + basic_machine=romp-ibm + ;; + sa29200) + basic_machine=a29k-amd + os=-udi + ;; + sequent) + basic_machine=i386-sequent + ;; + sh) + basic_machine=sh-hitachi + os=-hms + ;; + sparclite-wrs) + basic_machine=sparclite-wrs + os=-vxworks + ;; + sps7) + basic_machine=m68k-bull + os=-sysv2 + ;; + spur) + basic_machine=spur-unknown + ;; + st2000) + basic_machine=m68k-tandem + ;; + stratus) + basic_machine=i860-stratus + os=-sysv4 + ;; + sun2) + basic_machine=m68000-sun + ;; + sun2os3) + basic_machine=m68000-sun + os=-sunos3 + ;; + sun2os4) + basic_machine=m68000-sun + os=-sunos4 + ;; + sun3os3) + basic_machine=m68k-sun + os=-sunos3 + ;; + sun3os4) + basic_machine=m68k-sun + os=-sunos4 + ;; + sun4os3) + basic_machine=sparc-sun + os=-sunos3 + ;; + sun4os4) + basic_machine=sparc-sun + os=-sunos4 + ;; + sun4sol2) + basic_machine=sparc-sun + os=-solaris2 + ;; + sun3 | sun3-*) + basic_machine=m68k-sun + ;; + sun4) + basic_machine=sparc-sun + ;; + sun386 | sun386i | roadrunner) + basic_machine=i386-sun + ;; + sv1) + basic_machine=sv1-cray + os=-unicos + ;; + symmetry) + basic_machine=i386-sequent + os=-dynix + ;; + t3e) + basic_machine=t3e-cray + os=-unicos + ;; + tic54x | c54x*) + basic_machine=tic54x-unknown + os=-coff + ;; + tx39) + basic_machine=mipstx39-unknown + ;; + tx39el) + basic_machine=mipstx39el-unknown + ;; + tower | tower-32) + basic_machine=m68k-ncr + ;; + udi29k) + basic_machine=a29k-amd + os=-udi + ;; + ultra3) + basic_machine=a29k-nyu + os=-sym1 + ;; + v810 | necv810) + basic_machine=v810-nec + os=-none + ;; + vaxv) + basic_machine=vax-dec + os=-sysv + ;; + vms) + basic_machine=vax-dec + os=-vms + ;; + vpp*|vx|vx-*) + basic_machine=f301-fujitsu + ;; + vxworks960) + basic_machine=i960-wrs + os=-vxworks + ;; + vxworks68) + basic_machine=m68k-wrs + os=-vxworks + ;; + vxworks29k) + basic_machine=a29k-wrs + os=-vxworks + ;; + w65*) + basic_machine=w65-wdc + os=-none + ;; + w89k-*) + basic_machine=hppa1.1-winbond + os=-proelf + ;; + xmp) + basic_machine=xmp-cray + os=-unicos + ;; + xps | xps100) + basic_machine=xps100-honeywell + ;; + z8k-*-coff) + basic_machine=z8k-unknown + os=-sim + ;; + none) + basic_machine=none-none + os=-none + ;; + +# Here we handle the default manufacturer of certain CPU types. It is in +# some cases the only manufacturer, in others, it is the most popular. + w89k) + basic_machine=hppa1.1-winbond + ;; + op50n) + basic_machine=hppa1.1-oki + ;; + op60c) + basic_machine=hppa1.1-oki + ;; + mips) + if [ x$os = x-linux-gnu ]; then + basic_machine=mips-unknown + else + basic_machine=mips-mips + fi + ;; + romp) + basic_machine=romp-ibm + ;; + rs6000) + basic_machine=rs6000-ibm + ;; + vax) + basic_machine=vax-dec + ;; + pdp10) + # there are many clones, so DEC is not a safe bet + basic_machine=pdp10-unknown + ;; + pdp11) + basic_machine=pdp11-dec + ;; + we32k) + basic_machine=we32k-att + ;; + sh3 | sh4) + basic_machine=sh-unknown + ;; + sparc | sparcv9) + basic_machine=sparc-sun + ;; + cydra) + basic_machine=cydra-cydrome + ;; + orion) + basic_machine=orion-highlevel + ;; + orion105) + basic_machine=clipper-highlevel + ;; + mac | mpw | mac-mpw) + basic_machine=m68k-apple + ;; + pmac | pmac-mpw) + basic_machine=powerpc-apple + ;; + c4x*) + basic_machine=c4x-none + os=-coff + ;; + *) + echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 + exit 1 + ;; +esac + +# Here we canonicalize certain aliases for manufacturers. +case $basic_machine in + *-digital*) + basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'` + ;; + *-commodore*) + basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` + ;; + *) + ;; +esac + +# Decode manufacturer-specific aliases for certain operating systems. + +if [ x"$os" != x"" ] +then +case $os in + # First match some system type aliases + # that might get confused with valid system types. + # -solaris* is a basic system type, with this one exception. + -solaris1 | -solaris1.*) + os=`echo $os | sed -e 's|solaris1|sunos4|'` + ;; + -solaris) + os=-solaris2 + ;; + -svr4*) + os=-sysv4 + ;; + -unixware*) + os=-sysv4.2uw + ;; + -gnu/linux*) + os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` + ;; + # First accept the basic system types. + # The portable systems comes first. + # Each alternative MUST END IN A *, to match a version number. + # -sysv* is not here because it comes later, after sysvr4. + -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ + | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ + | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ + | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \ + | -aos* \ + | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \ + | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ + | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ + | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \ + | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ + | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ + | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \ + | -mingw32* | -linux-gnu* | -uxpv* | -beos* | -mpeix* | -udk* \ + | -interix* | -uwin* | -rhapsody* | -darwin* | -opened* \ + | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \ + | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* | -os2*) + # Remember, each alternative MUST END IN *, to match a version number. + ;; + -qnx*) + case $basic_machine in + x86-* | i[34567]86-*) + ;; + *) + os=-nto$os + ;; + esac + ;; + -nto*) + os=-nto-qnx + ;; + -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \ + | -windows* | -osx | -abug | -netware* | -os9* | -beos* \ + | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*) + ;; + -mac*) + os=`echo $os | sed -e 's|mac|macos|'` + ;; + -linux*) + os=`echo $os | sed -e 's|linux|linux-gnu|'` + ;; + -sunos5*) + os=`echo $os | sed -e 's|sunos5|solaris2|'` + ;; + -sunos6*) + os=`echo $os | sed -e 's|sunos6|solaris3|'` + ;; + -opened*) + os=-openedition + ;; + -wince*) + os=-wince + ;; + -osfrose*) + os=-osfrose + ;; + -osf*) + os=-osf + ;; + -utek*) + os=-bsd + ;; + -dynix*) + os=-bsd + ;; + -acis*) + os=-aos + ;; + -386bsd) + os=-bsd + ;; + -ctix* | -uts*) + os=-sysv + ;; + -ns2 ) + os=-nextstep2 + ;; + -nsk*) + os=-nsk + ;; + # Preserve the version number of sinix5. + -sinix5.*) + os=`echo $os | sed -e 's|sinix|sysv|'` + ;; + -sinix*) + os=-sysv4 + ;; + -triton*) + os=-sysv3 + ;; + -oss*) + os=-sysv3 + ;; + -svr4) + os=-sysv4 + ;; + -svr3) + os=-sysv3 + ;; + -sysvr4) + os=-sysv4 + ;; + # This must come after -sysvr4. + -sysv*) + ;; + -ose*) + os=-ose + ;; + -es1800*) + os=-ose + ;; + -xenix) + os=-xenix + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + os=-mint + ;; + -none) + ;; + *) + # Get rid of the `-' at the beginning of $os. + os=`echo $os | sed 's/[^-]*-//'` + echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2 + exit 1 + ;; +esac +else + +# Here we handle the default operating systems that come with various machines. +# The value should be what the vendor currently ships out the door with their +# machine or put another way, the most popular os provided with the machine. + +# Note that if you're going to try to match "-MANUFACTURER" here (say, +# "-sun"), then you have to tell the case statement up towards the top +# that MANUFACTURER isn't an operating system. Otherwise, code above +# will signal an error saying that MANUFACTURER isn't an operating +# system, and we'll never get to this point. + +case $basic_machine in + *-acorn) + os=-riscix1.2 + ;; + arm*-rebel) + os=-linux + ;; + arm*-semi) + os=-aout + ;; + pdp10-*) + os=-tops20 + ;; + pdp11-*) + os=-none + ;; + *-dec | vax-*) + os=-ultrix4.2 + ;; + m68*-apollo) + os=-domain + ;; + i386-sun) + os=-sunos4.0.2 + ;; + m68000-sun) + os=-sunos3 + # This also exists in the configure program, but was not the + # default. + # os=-sunos4 + ;; + m68*-cisco) + os=-aout + ;; + mips*-cisco) + os=-elf + ;; + mips*-*) + os=-elf + ;; + *-tti) # must be before sparc entry or we get the wrong os. + os=-sysv3 + ;; + sparc-* | *-sun) + os=-sunos4.1.1 + ;; + *-be) + os=-beos + ;; + *-ibm) + os=-aix + ;; + *-wec) + os=-proelf + ;; + *-winbond) + os=-proelf + ;; + *-oki) + os=-proelf + ;; + *-hp) + os=-hpux + ;; + *-hitachi) + os=-hiux + ;; + i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent) + os=-sysv + ;; + *-cbm) + os=-amigaos + ;; + *-dg) + os=-dgux + ;; + *-dolphin) + os=-sysv3 + ;; + m68k-ccur) + os=-rtu + ;; + m88k-omron*) + os=-luna + ;; + *-next ) + os=-nextstep + ;; + *-sequent) + os=-ptx + ;; + *-crds) + os=-unos + ;; + *-ns) + os=-genix + ;; + i370-*) + os=-mvs + ;; + *-next) + os=-nextstep3 + ;; + *-gould) + os=-sysv + ;; + *-highlevel) + os=-bsd + ;; + *-encore) + os=-bsd + ;; + *-sgi) + os=-irix + ;; + *-siemens) + os=-sysv4 + ;; + *-masscomp) + os=-rtu + ;; + f30[01]-fujitsu | f700-fujitsu) + os=-uxpv + ;; + *-rom68k) + os=-coff + ;; + *-*bug) + os=-coff + ;; + *-apple) + os=-macos + ;; + *-atari*) + os=-mint + ;; + *) + os=-none + ;; +esac +fi + +# Here we handle the case where we know the os, and the CPU type, but not the +# manufacturer. We pick the logical manufacturer. +vendor=unknown +case $basic_machine in + *-unknown) + case $os in + -riscix*) + vendor=acorn + ;; + -sunos*) + vendor=sun + ;; + -aix*) + vendor=ibm + ;; + -beos*) + vendor=be + ;; + -hpux*) + vendor=hp + ;; + -mpeix*) + vendor=hp + ;; + -hiux*) + vendor=hitachi + ;; + -unos*) + vendor=crds + ;; + -dgux*) + vendor=dg + ;; + -luna*) + vendor=omron + ;; + -genix*) + vendor=ns + ;; + -mvs* | -opened*) + vendor=ibm + ;; + -ptx*) + vendor=sequent + ;; + -vxsim* | -vxworks*) + vendor=wrs + ;; + -aux*) + vendor=apple + ;; + -hms*) + vendor=hitachi + ;; + -mpw* | -macos*) + vendor=apple + ;; + -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*) + vendor=atari + ;; + esac + basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"` + ;; +esac + +echo $basic_machine$os +exit 0 + +# Local variables: +# eval: (add-hook 'write-file-hooks 'time-stamp) +# time-stamp-start: "timestamp='" +# time-stamp-format: "%:y-%02m-%02d" +# time-stamp-end: "'" +# End: diff --git a/apt/buildlib/configure.mak b/apt/buildlib/configure.mak new file mode 100644 index 0000000..c6eca19 --- /dev/null +++ b/apt/buildlib/configure.mak @@ -0,0 +1,29 @@ +# -*- make -*- + +# This make fragment is included by the toplevel make to handle configure +# and setup. It defines a target called startup that when run will init +# the build directory, generate configure from configure.in, create aclocal +# and has rules to run config.status should one of the .in files change. + +# Input +# BUILDDIR - The build directory +# CONVERTED - List of files output by configure $(BUILD) is prepended +# The caller must provide depends for these files +# It would be a fairly good idea to run this after a cvs checkout. +BUILDDIR=. + +.PHONY: startup +startup: configure $(BUILDDIR)/config.status $(addprefix $(BUILDDIR)/,$(CONVERTED)) + +configure: aclocal.m4 configure.in + autoconf + +aclocal.m4: $(wildcard buildlib/*.m4) + aclocal -I buildlib + +$(BUILDDIR)/config.status: configure + /usr/bin/test -e $(BUILDDIR) || mkdir $(BUILDDIR) + (HERE=`pwd`; cd $(BUILDDIR) && $$HERE/configure) + +$(addprefix $(BUILDDIR)/,$(CONVERTED)): + (cd $(BUILDDIR) && ./config.status) diff --git a/apt/buildlib/copy.mak b/apt/buildlib/copy.mak new file mode 100644 index 0000000..892b74b --- /dev/null +++ b/apt/buildlib/copy.mak @@ -0,0 +1,29 @@ +# -*- make -*- + +# This installs arbitary files into a directory + +# Input +# $(SOURCE) - The documents to use +# $(TO) - The directory to put them in +# All output is writtin to files in the build/$(TO) directory + +# See defaults.mak for information about LOCAL + +# Some local definitions +LOCAL := copy-$(firstword $(SOURCE)) +$(LOCAL)-LIST := $(addprefix $(TO)/,$(SOURCE)) + +# Install generation hooks +doc: $($(LOCAL)-LIST) +veryclean: veryclean/$(LOCAL) + +MKDIRS += $(dir $($(LOCAL)-LIST)) + +$($(LOCAL)-LIST) : $(TO)/% : % + echo Installing $< to $(@D) + cp $< $(@D) + +# Clean rule +.PHONY: veryclean/$(LOCAL) +veryclean/$(LOCAL): + -rm -rf $($(@F)-LIST) diff --git a/apt/buildlib/debiandoc.mak b/apt/buildlib/debiandoc.mak new file mode 100644 index 0000000..0c20dc9 --- /dev/null +++ b/apt/buildlib/debiandoc.mak @@ -0,0 +1,58 @@ +# -*- make -*- + +# This processes debian-doc sgml to produce html and plain text output + +# Input +# $(SOURCE) - The documents to use + +# All output is writtin to files in the build doc directory + +# See defaults.mak for information about LOCAL + +# Some local definitions +LOCAL := debiandoc-$(firstword $(SOURCE)) +$(LOCAL)-HTML := $(addsuffix .html,$(addprefix $(DOC)/,$(basename $(SOURCE)))) +$(LOCAL)-TEXT := $(addsuffix .text,$(addprefix $(DOC)/,$(basename $(SOURCE)))) + +#--------- + +# Rules to build HTML documentations +ifdef DEBIANDOC_HTML + +# Install generation hooks +doc: $($(LOCAL)-HTML) +veryclean: veryclean/html/$(LOCAL) + +vpath %.sgml $(SUBDIRS) +$(DOC)/%.html: %.sgml + echo Creating html for $< to $@ + -rm -rf $@ + (HERE=`pwd`; cd $(@D) && $(DEBIANDOC_HTML) $$HERE/$<) + +# Clean rule +.PHONY: veryclean/html/$(LOCAL) +veryclean/html/$(LOCAL): + -rm -rf $($(@F)-HTML) + +endif + +#--------- + +# Rules to build Text documentations +ifdef DEBIANDOC_TEXT + +# Install generation hooks +doc: $($(LOCAL)-TEXT) +veryclean: veryclean/text/$(LOCAL) + +vpath %.sgml $(SUBDIRS) +$(DOC)/%.text: %.sgml + echo Creating text for $< to $@ + $(DEBIANDOC_TEXT) -O $< > $@ + +# Clean rule +.PHONY: veryclean/text/$(LOCAL) +veryclean/text/$(LOCAL): + -rm -rf $($(@F)-TEXT) + +endif diff --git a/apt/buildlib/defaults.mak b/apt/buildlib/defaults.mak new file mode 100644 index 0000000..3ecf4ba --- /dev/null +++ b/apt/buildlib/defaults.mak @@ -0,0 +1,179 @@ +# -*- make -*- + +# This file configures the default environment for the make system +# The way it works is fairly simple, each module is defined in it's +# own *.mak file. It expects a set of variables to be set to values +# for it to operate as expected. When included the module generates +# the requested rules based on the contents of its control variables. + +# This works out very well and allows a good degree of flexability. +# To accomidate some of the features we introduce the concept of +# local variables. To do this we use the 'Computed Names' feature of +# gmake. Each module declares a LOCAL scope and access it with, +# $($(LOCAL)-VAR) +# This works very well but it is important to rembember that within +# a rule the LOCAL var is unavailble, it will have to be constructed +# from the information in the rule invokation. For stock rules like +# clean this is simple, we use a local clean rule called clean/$(LOCAL) +# and then within the rule $(@F) gets back $(LOCAL)! Other rules will +# have to use some other mechanism (filter perhaps?) The reason such +# lengths are used is so that each directory can contain several 'instances' +# of any given module. I notice that the very latest gmake has the concept +# of local variables for rules. It is possible this feature in conjunction +# with the generated names will provide a very powerfull solution indeed! + +# A build directory is used by default, all generated items get put into +# there. However unlike automake this is not done with a VPATH build +# (vpath builds break the distinction between #include "" and #include <>) +# but by explicly setting the BUILD variable. Make is invoked from +# within the source itself which is much more compatible with compilation +# environments. +ifndef NOISY +.SILENT: +endif + +# Search for the build directory +ifdef BUILD +BUILD_POSSIBLE := $(BUILD) $(BASE)/$(BUILD) +else +BUILD_POSSIBLE := $(BASE) $(BASE)/build-$(shell uname -m) $(BASE)/build +endif + +BUILDX:= $(foreach i,$(BUILD_POSSIBLE),$(wildcard $(i)/environment.mak*)) + +ifeq ($(words $(BUILDX)),0) + +# Check for a busted wildcard function. We use this function in several +# places, it must work. +ifeq ($(words $(wildcard *)),0) +error-all/environment.mak: + echo You have a broken version of GNU Make - upgrade. + error-out-and-die +else +error-all/environment.mak: + echo Can not find the build directory in $(BUILD_POSSIBLE) -- use BUILD= + error-out-and-die +endif + +# Force include below to come to the error target +BUILDX := error-all +else +BUILDX:= $(patsubst %/,%,$(firstword $(dir $(BUILDX)))) +endif + +override BUILD := $(BUILDX) + +# Base definitions +INCLUDE := $(BUILD)/include +BIN := $(BUILD)/bin +LIB := $(BIN) +OBJ := $(BUILD)/obj/$(SUBDIR) +DEP := $(OBJ) +DOC := $(BUILD)/docs + +# Module types +LIBRARY_H = $(BASE)/buildlib/library.mak +DEBIANDOC_H = $(BASE)/buildlib/debiandoc.mak +MANPAGE_H = $(BASE)/buildlib/manpage.mak +PROGRAM_H = $(BASE)/buildlib/program.mak +PYTHON_H = $(BASE)/buildlib/python.mak +COPY_H = $(BASE)/buildlib/copy.mak +YODL_MANPAGE_H = $(BASE)/buildlib/yodl_manpage.mak +SGML_MANPAGE_H = $(BASE)/buildlib/sgml_manpage.mak +FAIL_H = $(BASE)/buildlib/fail.mak + +include $(BUILD)/environment.mak + +ifdef STATICLIBS +LIBRARY_H += $(BASE)/buildlib/staticlibrary.mak +endif + +ifdef ONLYSTATICLIBS +LIBRARY_H = $(BASE)/buildlib/staticlibrary.mak +endif + +# Source location control +# SUBDIRS specifies sub components of the module that +# may be located in subdrictories of the source dir. +# This should be declared before including this file +SUBDIRS+= + +# Header file control. +# TARGETDIRS indicitates all of the locations that public headers +# will be published to. +# This should be declared before including this file +HEADER_TARGETDIRS+= + +# Options +CPPFLAGS+= -I$(INCLUDE) +LDFLAGS+= -L$(LIB) + +# Directors to create +MKDIRS := $(BIN) + +# Phony rules. Other things hook these by appending to the dependency +# list +.PHONY: headers library clean veryclean all binary program doc dirs +.PHONY: maintainer-clean dist-clean distclean pristine sanity +all: binary doc +binary: library program +maintainer-clean dist-clean distclean pristine sanity: veryclean +headers library clean veryclean program: + +veryclean: + echo Very Clean done for $(SUBDIR) +clean: + echo Clean done for $(SUBDIR) +dirs: + mkdir -p $(patsubst %/,%,$(sort $(MKDIRS))) + +# Header file control. We want all published interface headers to go +# into the build directory from thier source dirs. We setup some +# search paths here +vpath %.h $(SUBDIRS) +$(INCLUDE)/%.h $(addprefix $(INCLUDE)/,$(addsuffix /%.h,$(HEADER_TARGETDIRS))) : %.h + cp $< $@ + +# Dependency generation. We want to generate a .d file using gnu cpp. +# For GNU systems the compiler can spit out a .d file while it is compiling, +# this is specified with the INLINEDEPFLAG. Other systems might have a +# makedep program that can be called after compiling, that's illistrated +# by the DEPFLAG case. +# Compile rules are expected to call this macro after calling the compiler +ifdef GCC3DEP +DFILE = $(DEP)/$(basename $(@F)).d +else +DFILE = $(basename $(@F)).d +endif +ifdef INLINEDEPFLAG + define DoDep + sed -e "1s/.*:/$(subst /,\\/,$@):/" $(DFILE) > $(DEP)/$(@F).d + #sed -e "1s/.*:/$(subst /,\\/,$@):/" $(DEP)/$(basename $(@F)).d > $(DEP)/$(@F).d + -rm -f $(basename $(@F)).d + endef +else + ifdef DEPFLAG + define DoDep + $(CXX) $(DEPFLAG) $(CPPFLAGS) -o $@ $< + sed -e "1s/.*:/$(subst /,\\/,$@):/" $(basename $(@F)).d > $(DEP)/$(@F).d + -rm -f $(basename $(@F)).d + endef + else + define DoDep + endef + endif +endif + +# Automatic -j support +ifeq ($(NUM_PROCS),1) + PARALLEL_RUN=no +endif + +ifndef PARALLEL_RUN + PARALLEL_RUN=yes + .EXPORT: PARALLEL_RUN + # handle recursion + ifneq ($(NUM_PROCS),) + MAKEFLAGS += -j $(NUM_PROCS) + endif +endif diff --git a/apt/buildlib/environment.mak.in b/apt/buildlib/environment.mak.in new file mode 100644 index 0000000..af595a9 --- /dev/null +++ b/apt/buildlib/environment.mak.in @@ -0,0 +1,59 @@ +# This file contains everything that autoconf guessed for your system. +# if you want you can edit it, just don't re-run configure. + +# C++ compiler options +CC = @CC@ +CPPFLAGS+= @CPPFLAGS@ @DEFS@ -D_REENTRANT +CXX = @CXX@ +CXXFLAGS+= @CXXFLAGS@ +NUM_PROCS = @NUM_PROCS@ +GLIBC_VER = @GLIBC_VER@ +LIBSTDCPP_VER = @LIBSTDCPP_VER@ + +# Linker stuff +PICFLAGS+= -fPIC -DPIC +LFLAGS+= @LDFLAGS@ +LEFLAGS+= +SOCKETLIBS:= @SOCKETLIBS@ +AR:=@AR@ +RANLIB:=@RANLIB@ + +RPMLIBS:=@RPMLIBS@ + +# Dep generation - this only works for gnu stuff +GCC3DEP = @GCC3DEP@ +INLINEDEPFLAG = -MD + +# Debian doc stuff +DEBIANDOC_HTML = @DEBIANDOC_HTML@ +DEBIANDOC_TEXT = @DEBIANDOC_TEXT@ + +# SGML for the man pages +NSGMLS = @NSGMLS@ +SGMLSPL = @SGMLSPL@ +DOCBOOK2MAN := $(wildcard /usr/lib/perl5/sgmlspl-specs/docbook2man-spec.pl) + +# Various library checks +PTHREADLIB = @PTHREADLIB@ +PYTHONLIB = @PYTHONLIB@ +PYTHONVER = @PYTHONVER@ +PYTHONPREFIX = @PYTHONPREFIX@ +PYTHONEXECPREFIX = @PYTHONEXECPREFIX@ +PYTHONINCLUDE = @PYTHONINCLUDE@ +DB2LIB = @DB2LIB@ + +# Shim Headerfile control +HAVE_C9X = @HAVE_C9X@ +HAVE_STATVFS = @HAVE_STATVFS@ +NEED_SOCKLEN_T_DEFINE = @NEED_SOCKLEN_T_DEFINE@ + +# Shared library things +HOST_OS = @host_os@ +ifneq ($(words $(filter linux-gnu gnu%,$(HOST_OS))),0) + SONAME_MAGIC=-Wl,-soname -Wl, + LFLAGS_SO= +else + # Do not know how to create shared libraries here. + ONLYSTATICLIBS = yes +endif + diff --git a/apt/buildlib/fail.mak b/apt/buildlib/fail.mak new file mode 100644 index 0000000..dfc194e --- /dev/null +++ b/apt/buildlib/fail.mak @@ -0,0 +1,20 @@ +# -*- make -*- + +# This prints a failure message but does not abort the make + +# Input +# $(MESSAGE) - The message to show +# $(PROGRAM) - The program/libary/whatever. + +# See defaults.mak for information about LOCAL + +LOCAL := $(PROGRAM) +$(LOCAL)-MSG := $(MESSAGE) + +# Install hooks +program: $(PROGRAM) + +.PHONY: $(PROGRAM) +$(PROGRAM) : + echo $($@-MSG) + diff --git a/apt/buildlib/install-sh b/apt/buildlib/install-sh new file mode 100644 index 0000000..ebc6691 --- /dev/null +++ b/apt/buildlib/install-sh @@ -0,0 +1,250 @@ +#! /bin/sh +# +# install - install a program, script, or datafile +# This comes from X11R5 (mit/util/scripts/install.sh). +# +# Copyright 1991 by the Massachusetts Institute of Technology +# +# Permission to use, copy, modify, distribute, and sell this software and its +# documentation for any purpose is hereby granted without fee, provided that +# the above copyright notice appear in all copies and that both that +# copyright notice and this permission notice appear in 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. +# +# Calling this script install-sh is preferred over install.sh, to prevent +# `make' implicit rules from creating a file called install from it +# when there is no Makefile. +# +# This script is compatible with the BSD install script, but was written +# from scratch. It can only install one file at a time, a restriction +# shared with many OS's install programs. + + +# set DOITPROG to echo to test this script + +# Don't use :- since 4.3BSD and earlier shells don't like it. +doit="${DOITPROG-}" + + +# put in absolute paths if you don't have them in your path; or use env. vars. + +mvprog="${MVPROG-mv}" +cpprog="${CPPROG-cp}" +chmodprog="${CHMODPROG-chmod}" +chownprog="${CHOWNPROG-chown}" +chgrpprog="${CHGRPPROG-chgrp}" +stripprog="${STRIPPROG-strip}" +rmprog="${RMPROG-rm}" +mkdirprog="${MKDIRPROG-mkdir}" + +transformbasename="" +transform_arg="" +instcmd="$mvprog" +chmodcmd="$chmodprog 0755" +chowncmd="" +chgrpcmd="" +stripcmd="" +rmcmd="$rmprog -f" +mvcmd="$mvprog" +src="" +dst="" +dir_arg="" + +while [ x"$1" != x ]; do + case $1 in + -c) instcmd="$cpprog" + shift + continue;; + + -d) dir_arg=true + shift + continue;; + + -m) chmodcmd="$chmodprog $2" + shift + shift + continue;; + + -o) chowncmd="$chownprog $2" + shift + shift + continue;; + + -g) chgrpcmd="$chgrpprog $2" + shift + shift + continue;; + + -s) stripcmd="$stripprog" + shift + continue;; + + -t=*) transformarg=`echo $1 | sed 's/-t=//'` + shift + continue;; + + -b=*) transformbasename=`echo $1 | sed 's/-b=//'` + shift + continue;; + + *) if [ x"$src" = x ] + then + src=$1 + else + # this colon is to work around a 386BSD /bin/sh bug + : + dst=$1 + fi + shift + continue;; + esac +done + +if [ x"$src" = x ] +then + echo "install: no input file specified" + exit 1 +else + true +fi + +if [ x"$dir_arg" != x ]; then + dst=$src + src="" + + if [ -d $dst ]; then + instcmd=: + else + instcmd=mkdir + fi +else + +# Waiting for this to be detected by the "$instcmd $src $dsttmp" command +# might cause directories to be created, which would be especially bad +# if $src (and thus $dsttmp) contains '*'. + + if [ -f $src -o -d $src ] + then + true + else + echo "install: $src does not exist" + exit 1 + fi + + if [ x"$dst" = x ] + then + echo "install: no destination specified" + exit 1 + else + true + fi + +# If destination is a directory, append the input filename; if your system +# does not like double slashes in filenames, you may need to add some logic + + if [ -d $dst ] + then + dst="$dst"/`basename $src` + else + true + fi +fi + +## this sed command emulates the dirname command +dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` + +# Make sure that the destination directory exists. +# this part is taken from Noah Friedman's mkinstalldirs script + +# Skip lots of stat calls in the usual case. +if [ ! -d "$dstdir" ]; then +defaultIFS=' +' +IFS="${IFS-${defaultIFS}}" + +oIFS="${IFS}" +# Some sh's can't handle IFS=/ for some reason. +IFS='%' +set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` +IFS="${oIFS}" + +pathcomp='' + +while [ $# -ne 0 ] ; do + pathcomp="${pathcomp}${1}" + shift + + if [ ! -d "${pathcomp}" ] ; + then + $mkdirprog "${pathcomp}" + else + true + fi + + pathcomp="${pathcomp}/" +done +fi + +if [ x"$dir_arg" != x ] +then + $doit $instcmd $dst && + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else true ; fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else true ; fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else true ; fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else true ; fi +else + +# If we're going to rename the final executable, determine the name now. + + if [ x"$transformarg" = x ] + then + dstfile=`basename $dst` + else + dstfile=`basename $dst $transformbasename | + sed $transformarg`$transformbasename + fi + +# don't allow the sed command to completely eliminate the filename + + if [ x"$dstfile" = x ] + then + dstfile=`basename $dst` + else + true + fi + +# Make a temp file name in the proper directory. + + dsttmp=$dstdir/#inst.$$# + +# Move or copy the file name to the temp name + + $doit $instcmd $src $dsttmp && + + trap "rm -f ${dsttmp}" 0 && + +# and set any options; do chmod last to preserve setuid bits + +# If any of these fail, we abort the whole thing. If we want to +# ignore errors from any of these, just make sure not to ignore +# errors from the above "$doit $instcmd $src $dsttmp" command. + + if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else true;fi && + if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else true;fi && + if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else true;fi && + if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else true;fi && + +# Now rename the file to the real destination. + + $doit $rmcmd -f $dstdir/$dstfile && + $doit $mvcmd $dsttmp $dstdir/$dstfile + +fi && + + +exit 0 diff --git a/apt/buildlib/inttypes.h.in b/apt/buildlib/inttypes.h.in new file mode 100644 index 0000000..3be7207 --- /dev/null +++ b/apt/buildlib/inttypes.h.in @@ -0,0 +1,43 @@ +/* This is an ISO C 9X header file. We omit this copy to the include + directory if the local platform does not have inttypes.h, it contains + [u]int[8,16,32]_t fixed width types */ + +#include + +/* Generate the fixed bit size types */ +#if SIZEOF_INT == 4 + typedef int int32_t; + typedef unsigned int uint32_t; +#else +# if SIZEOF_LONG == 4 + typedef long int32_t; + typedef unsigned long uint32_t; +# else +# if SIZEOF_SHORT == 4 + typedef short int32_t; + typedef unsigned short uint32_t; +# else +# error Must have a form of 32-bit integer +# endif +# endif +#endif + +#if SIZEOF_INT == 2 + typedef int int16_t; + typedef unsigned int uint16_t; +#else +# if SIZEOF_LONG == 2 + typedef long int16_t; + typedef unsigned long uint16_t; +# else +# if SIZEOF_SHORT == 2 + typedef short int16_t; + typedef unsigned short uint16_t; +# else +# error Must have a form of 16-bit integer +# endif +# endif +#endif + +typedef signed char int8_t; +typedef unsigned char uint8_t; diff --git a/apt/buildlib/library.mak b/apt/buildlib/library.mak new file mode 100644 index 0000000..fb944cf --- /dev/null +++ b/apt/buildlib/library.mak @@ -0,0 +1,69 @@ +# -*- make -*- + +# This creates a shared library. + +# Input +# $(SOURCE) - The source code to use +# $(HEADERS) - Exported header files and private header files +# $(LIBRARY) - The name of the library without lib or .so +# $(MAJOR) - The major version number of this library +# $(MINOR) - The minor version number of this library + +# All output is writtin to .opic files in the build directory to +# signify the PIC output. + +# See defaults.mak for information about LOCAL + +# Some local definitions +LOCAL := lib$(LIBRARY)$(LIBEXT).so.$(MAJOR).$(MINOR) +$(LOCAL)-OBJS := $(addprefix $(OBJ)/,$(addsuffix .opic,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-DEP := $(addprefix $(DEP)/,$(addsuffix .opic.d,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-HEADERS := $(addprefix $(INCLUDE)/,$(HEADERS)) +$(LOCAL)-SONAME := lib$(LIBRARY)$(LIBEXT).so.$(MAJOR) +$(LOCAL)-SLIBS := $(SLIBS) +$(LOCAL)-LIBRARY := $(LIBRARY) + +# Install the command hooks +headers: $($(LOCAL)-HEADERS) +library: $(LIB)/lib$(LIBRARY).so $(LIB)/lib$(LIBRARY)$(LIBEXT).so.$(MAJOR) +clean: clean/$(LOCAL) +veryclean: veryclean/$(LOCAL) + +# Make Directories +MKDIRS += $(OBJ) $(DEP) $(LIB) $(dir $($(LOCAL)-HEADERS)) + +# The clean rules +.PHONY: clean/$(LOCAL) veryclean/$(LOCAL) +clean/$(LOCAL): + -rm -f $($(@F)-OBJS) $($(@F)-DEP) +veryclean/$(LOCAL): clean/$(LOCAL) + -rm -f $($(@F)-HEADERS) $(LIB)/lib$($(@F)-LIBRARY)*.so* + +# Build rules for the two symlinks +.PHONY: $(LIB)/lib$(LIBRARY)$(LIBEXT).so.$(MAJOR) $(LIB)/lib$(LIBRARY).so +$(LIB)/lib$(LIBRARY)$(LIBEXT).so.$(MAJOR): $(LIB)/lib$(LIBRARY)$(LIBEXT).so.$(MAJOR).$(MINOR) + ln -sf $( /dev/null + echo Building shared library $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(PICFLAGS) $(LFLAGS) $(LFLAGS_SO)\ + -o $@ $(SONAME_MAGIC)$($(@F)-SONAME) -shared \ + $(filter %.opic,$^) \ + $($(@F)-SLIBS) + +# Compilation rules +vpath %.cc $(SUBDIRS) +$(OBJ)/%.opic: %.cc + echo Compiling $< to $@ + $(CXX) -c $(INLINEDEPFLAG) $(CPPFLAGS) $(CXXFLAGS) $(PICFLAGS) -o $@ $< + $(DoDep) + +# Include the dependencies that are available +The_DFiles = $(wildcard $($(LOCAL)-DEP)) +ifneq ($(words $(The_DFiles)),0) +include $(The_DFiles) +endif diff --git a/apt/buildlib/makefile.in b/apt/buildlib/makefile.in new file mode 100644 index 0000000..756565f --- /dev/null +++ b/apt/buildlib/makefile.in @@ -0,0 +1,51 @@ +# -*- make -*- + +# This is the build directory make file, it sets the build directory +# and runs the src makefile. +ifndef NOISY +.SILENT: +endif +include environment.mak + +SRCDIR=@top_srcdir@ +BUILD:=$(shell pwd) +export BUILD + +# Chain to the parent make to do the actual building +.PHONY: headers library clean veryclean all binary program doc \ + veryclean/local +all headers library clean veryclean binary program doc: + $(MAKE) -C $(SRCDIR) -f Makefile $@ + +# Purge everything. +.PHONY: maintainer-clean dist-clean pristine sanity distclean +maintainer-clean dist-clean pristine sanity distclean: + -rm -rf $(DIRS) + -rm -f config.cache config.log config.status environment.mak makefile + +# Create the required directories and build the shims +# The configure script fills in below, and then we do the right things.. +# This cannot go in the configure script since the directories have not yet +# been created.. In any event I like the idea that you can change environment.mak +# and run make dirs and have the shims updated. +.PHONY: dirs +dirs: + $(MAKE) -C $(SRCDIR) -f Makefile $@ +ifeq ($(HAVE_C9X),yes) + @rm -f include/inttypes.h > /dev/null 2>&1 +else + @cp -p $(SRCDIR)/buildlib/inttypes.h.in include/inttypes.h +endif +ifeq ($(HAVE_STATVFS),yes) + @rm -f include/statvfs.h > /dev/null 2>&1 +else + @cp -p $(SRCDIR)/buildlib/statvfs.h.in include/statvfs.h + ln -sf . include/sys +endif +ifeq ($(NEED_SOCKLEN_T_DEFINE),yes) + @cp -p $(SRCDIR)/buildlib/netdb.h.in include/netdb.h +else + @rm -f include/netdb.h > /dev/null 2>&1 +endif + rm -f include/python + ln -sf $(PYTHONINCLUDE) include/python diff --git a/apt/buildlib/manpage.mak b/apt/buildlib/manpage.mak new file mode 100644 index 0000000..1f2644c --- /dev/null +++ b/apt/buildlib/manpage.mak @@ -0,0 +1,29 @@ +# -*- make -*- + +# This installs man pages into the doc directory + +# Input +# $(SOURCE) - The documents to use + +# All output is writtin to files in the build doc directory + +# See defaults.mak for information about LOCAL + +# Some local definitions +LOCAL := manpage-$(firstword $(SOURCE)) +$(LOCAL)-LIST := $(addprefix $(DOC)/,$(SOURCE)) + +# Install generation hooks +doc: $($(LOCAL)-LIST) +veryclean: veryclean/$(LOCAL) + +MKDIRS += $(DOC) + +$($(LOCAL)-LIST) : $(DOC)/% : % + echo Installing man page $< to $(@D) + cp $< $(@D) + +# Clean rule +.PHONY: veryclean/$(LOCAL) +veryclean/$(LOCAL): + -rm -rf $($(@F)-LIST) diff --git a/apt/buildlib/mkChangeLog b/apt/buildlib/mkChangeLog new file mode 100755 index 0000000..4164ec9 --- /dev/null +++ b/apt/buildlib/mkChangeLog @@ -0,0 +1,14 @@ +#!/bin/sh + +NAMES="`sed -ne 's/'\''/'\''\\\\'\'''\''/g; + s/^.*CVS:\([^ ]\+\) \([^<]\+\) <\([^>]*\)>/\ + -u '\''\1:\2:\3'\''/gp' AUTHORS`" +OPTIONS="-l 78" + +# Generate the standard ChangeLog +echo CVSIGNORE=po rcs2log $OPTIONS $NAMES +eval CVSIGNORE=po rcs2log $OPTIONS $NAMES >> ChangeLog + +# Generate the po ChangeLog +#echo rcs2log $OPTIONS $NAMES po +#eval rcs2log $OPTIONS $NAMES po >> po/ChangeLog diff --git a/apt/buildlib/netdb.h.in b/apt/buildlib/netdb.h.in new file mode 100644 index 0000000..0fa60e1 --- /dev/null +++ b/apt/buildlib/netdb.h.in @@ -0,0 +1,6 @@ +/* Fix broken unixen. */ +#include +#ifdef NEED_SOCKLEN_T_DEFINE + #define socklen_t size_t +#endif +#include_next diff --git a/apt/buildlib/ostable b/apt/buildlib/ostable new file mode 100644 index 0000000..433efea --- /dev/null +++ b/apt/buildlib/ostable @@ -0,0 +1,19 @@ +# This file contains a table of known vendor-os strings, with +# things to map them to. `configure' will take the output of the +# autoconf cannon macros and look in here. This only deals with +# OS names. The right should be a common name like the arch table +# generates +# The final bit to build the Debian Architecture is done in init.cc +# The left side is a regex for awk, and the first match is used. + +# These are used by Debian +[^-]*-linux-.* linux +[^-]*-gnu[^-]* hurd + +# These are samples. +hp-hpux[^-]* hp-ux +sun-solaris[^-]* solaris +[^-]*-openbsd[^-]* openbsd + +# Catch all +.* unknown diff --git a/apt/buildlib/program.mak b/apt/buildlib/program.mak new file mode 100644 index 0000000..a89dc5e --- /dev/null +++ b/apt/buildlib/program.mak @@ -0,0 +1,57 @@ +# -*- make -*- + +# This creates a program + +# Input +# $(SOURCE) - The source code to use +# $(PROGRAM) - The name of the program +# $(SLIBS) - Shared libs to link against +# $(LIB_MAKES) - Shared libary make files to depend on - to ensure we get +# remade when the shared library version increases. + +# See defaults.mak for information about LOCAL + +# Some local definitions +LOCAL := $(PROGRAM) +$(LOCAL)-OBJS := $(addprefix $(OBJ)/,$(addsuffix .o,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-DEP := $(addprefix $(DEP)/,$(addsuffix .o.d,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-BIN := $(BIN)/$(PROGRAM) +$(LOCAL)-SLIBS := $(SLIBS) +$(LOCAL)-MKS := $(addprefix $(BASE)/,$(LIB_MAKES)) + +# Install the command hooks +program: $(BIN)/$(PROGRAM) +clean: clean/$(LOCAL) +veryclean: veryclean/$(LOCAL) + +# Make Directories +MKDIRS += $(OBJ) $(DEP) $(BIN) + +# The clean rules +.PHONY: clean/$(LOCAL) veryclean/$(LOCAL) +clean/$(LOCAL): + -rm -f $($(@F)-OBJS) $($(@F)-DEP) +veryclean/$(LOCAL): clean/$(LOCAL) + -rm -f $($(@F)-BIN) + +# The convience binary build rule +.PHONY: $(PROGRAM) +$(PROGRAM): $($(LOCAL)-BIN) + +# The binary build rule +$($(LOCAL)-BIN): $($(LOCAL)-OBJS) $($(LOCAL)-MKS) + echo Building program $@ + $(CXX) $(CXXFLAGS) $(LDFLAGS) $(LFLAGS) -o $@ $(filter %.o,$^) $($(@F)-SLIBS) $(LEFLAGS) + +# Compilation rules +vpath %.cc $(SUBDIRS) +$(OBJ)/%.o: %.cc + echo Compiling $< to $@ + $(CXX) -c $(INLINEDEPFLAG) $(CPPFLAGS) $(CXXFLAGS) -o $@ $< + $(DoDep) + +# Include the dependencies that are available +The_DFiles = $(wildcard $($(LOCAL)-DEP)) +ifneq ($(words $(The_DFiles)),0) +include $(The_DFiles) +endif diff --git a/apt/buildlib/sizetable b/apt/buildlib/sizetable new file mode 100644 index 0000000..9111801 --- /dev/null +++ b/apt/buildlib/sizetable @@ -0,0 +1,22 @@ +# +# This file lists common architectures for cross-compilation (CPUs, not +# OSs), and the endian-ness and relative type sizes. It is not needed for +# native compilation. +# +# If you wish to cross-compile APT, and your architecture is not listed +# here, you should add it, and submit it by email to the APT team at +# . +# +# This is used primarily for the MD5 algorithm. +# The format is:- +# CPU endian sizeof: char, int, short, long +i386 little 1 4 2 4 +arm little 1 4 2 4 +alpha little 1 4 2 8 +mipsel little 1 4 2 4 +sparc big 1 4 2 4 +sparc64 big 1 4 2 8 +m68k big 1 4 2 4 +powerpc big 1 4 2 4 +mips big 1 4 2 4 +hppa big 1 4 2 4 diff --git a/apt/buildlib/staticlibrary.mak b/apt/buildlib/staticlibrary.mak new file mode 100644 index 0000000..ce9259d --- /dev/null +++ b/apt/buildlib/staticlibrary.mak @@ -0,0 +1,60 @@ +# -*- make -*- + +# This creates a static library. + +# Input +# $(SOURCE) - The source code to use +# $(HEADERS) - Exported header files and private header files +# $(LIBRARY) - The name of the library without lib or .so + +# All output is writtin to .o files in the build directory + +# See defaults.mak for information about LOCAL + +# Some local definitions +LOCAL := lib$(LIBRARY).a +$(LOCAL)-OBJS := $(addprefix $(OBJ)/,$(addsuffix .o,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-DEP := $(addprefix $(DEP)/,$(addsuffix .o.d,$(notdir $(basename $(SOURCE))))) +$(LOCAL)-HEADERS := $(addprefix $(INCLUDE)/,$(HEADERS)) +$(LOCAL)-LIB := $(LIB)/lib$(LIBRARY).a + +# Install the command hooks +headers: $($(LOCAL)-HEADERS) +library: $($(LOCAL)-LIB) +clean: clean/$(LOCAL) +veryclean: veryclean/$(LOCAL) + +# Make Directories +MKDIRS += $(OBJ) $(DEP) $(LIB) $(dir $($(LOCAL)-HEADERS)) + +# The clean rules +.PHONY: clean/$(LOCAL) veryclean/$(LOCAL) +clean/$(LOCAL): + -rm -f $($(@F)-OBJS) $($(@F)-DEP) +veryclean/$(LOCAL): clean/$(LOCAL) + -rm -f $($(@F)-HEADERS) $($(@F)-LIB) + +# Build rules for the two symlinks +.PHONY: $($(LOCAL)-LIB) + +# The binary build rule +$($(LOCAL)-LIB): $($(LOCAL)-HEADERS) $($(LOCAL)-OBJS) + echo Building library $@ + -rm $@ > /dev/null 2>&1 + $(AR) cq $@ $(filter %.o,$^) +ifneq ($(words $(RANLIB)),0) + $(RANLIB) $@ +endif + +# Compilation rules +vpath %.cc $(SUBDIRS) +$(OBJ)/%.o: %.cc + echo Compiling $< to $@ + $(CXX) -c $(INLINEDEPFLAG) $(CPPFLAGS) $(CXXFLAGS) -o $@ $< + $(DoDep) + +# Include the dependencies that are available +The_DFiles = $(wildcard $($(LOCAL)-DEP)) +ifneq ($(words $(The_DFiles)),0) +include $(The_DFiles) +endif diff --git a/apt/buildlib/statvfs.h.in b/apt/buildlib/statvfs.h.in new file mode 100644 index 0000000..d0ec238 --- /dev/null +++ b/apt/buildlib/statvfs.h.in @@ -0,0 +1,13 @@ +/* Compatibility for systems with out Single Unix Spec statvfs */ +#include + +#ifdef HAVE_VFS_H +#include +#endif + +#ifdef HAVE_MOUNT_H +#include +#include +#endif + +#define statvfs statfs diff --git a/apt/buildlib/tools.m4 b/apt/buildlib/tools.m4 new file mode 100644 index 0000000..442c0b6 --- /dev/null +++ b/apt/buildlib/tools.m4 @@ -0,0 +1,157 @@ +AC_DEFUN(ah_HAVE_GETCONF, + [AC_ARG_WITH(getconf, + [ --with-getconf Enable automagical buildtime configuration], + [if test "$withval" = "yes"; then + AC_PATH_PROG(GETCONF, getconf) + elif test ! "$withval" = "no";then + AC_MSG_CHECKING([getconf]) + AC_MSG_RESULT([$withval]) + GETCONF=$withval + fi], + [AC_PATH_PROG(GETCONF, getconf)] + ) + AC_SUBST(GETCONF) +]) + +dnl ah_GET_CONF(variable, value ..., [default]) +AC_DEFUN(ah_GET_GETCONF, + [AC_REQUIRE([ah_HAVE_GETCONF]) + if test ! -z "$GETCONF";then + old_args="[$]@" + set -- $2 + while eval test -z \"\$$1\" -a ! -z \"[$]1\";do + eval $1=`$GETCONF "[$]1" 2>/dev/null` + shift + done + fi + if eval test -z \"\$$1\" -o \"\$$1\" = "-1";then + eval $1="$3" + fi +]) +AC_DEFUN(ah_NUM_CPUS, + [AC_MSG_CHECKING([number of cpus]) + AC_ARG_WITH(cpus, + [ --with-cpus The number of cpus to be used for building(see --with-procs, default 1)], + [ + if test "$withval" = "yes"; then + ah_GET_GETCONF(NUM_CPUS, SC_NPROCESSORS_ONLN _NPROCESSORS_ONLN, 1) + elif test ! "$withval" = "no";then + NUM_CPUS=$withval + elif test "$withval" = "no";then + NUM_CPUS=1 + fi], + [ah_GET_GETCONF(NUM_CPUS, SC_NPROCESSORS_ONLN _NPROCESSORS_ONLN, 1)] + ) + ah_NUM_CPUS_msg="$NUM_CPUS" + if test "$NUM_CPUS" = "0"; then + # broken getconf, time to bitch. + ah_NUM_CPUS_msg="found 0 cpus. Has someone done a lobotomy?" + NUM_CPUS=1 + fi + if test $NUM_CPUS = 1 ;then + default_PROC_MULTIPLY=1 + else + default_PROC_MULTIPLY=2 + fi + AC_MSG_RESULT([$ah_NUM_CPUS_msg]) + AC_SUBST(NUM_CPUS) +]) +AC_DEFUN(ah_PROC_MULTIPLY, + [AC_REQUIRE([ah_NUM_CPUS]) + AC_MSG_CHECKING([processor multiplier]) + AC_ARG_WITH(proc-multiply, + [ --with-proc-multiply Multiply this * number of cpus for parallel making(default 2).], + [if test "$withval" = "yes"; then + PROC_MULTIPLY=$default_PROC_MULTIPLY + elif test ! "$withval" = "no";then + PROC_MULTIPLY=$withval + fi], + [PROC_MULTIPLY=$default_PROC_MULTIPLY] + ) + AC_MSG_RESULT([$PROC_MULTIPLY]) + AC_SUBST(PROC_MULTIPLY) +]) + +AC_DEFUN(ah_NUM_PROCS, + [AC_REQUIRE([ah_PROC_MULTIPLY]) + AC_REQUIRE([ah_NUM_CPUS]) + AC_MSG_CHECKING([number of processes to run during make]) + AC_ARG_WITH(procs, + [ --with-procs The number of processes to run in parallel during make(num_cpus * multiplier).], + [if test "$withval" = "yes"; then + NUM_PROCS=`expr $NUM_CPUS \* $PROC_MULTIPLY` + elif test ! "$withval" = "no";then + NUM_PROCS=$withval + fi], + [NUM_PROCS=`expr $NUM_CPUS \* $PROC_MULTIPLY`] + ) + AC_MSG_RESULT([$NUM_PROCS]) + AC_SUBST(NUM_PROCS) +]) + +AC_DEFUN(rc_GLIBC_VER, + [AC_MSG_CHECKING([glibc version]) + dummy=if$$ + cat <<_GLIBC_>$dummy.c +#include +#include +#include +int main(int argc, char **argv) { printf("libc6.%d",__GLIBC_MINOR__); exit(0); } +_GLIBC_ + ${CC-cc} $dummy.c -o $dummy > /dev/null 2>&1 + if test "$?" = 0; then + GLIBC_VER=`./$dummy` + AC_MSG_RESULT([$GLIBC_VER]) + GLIBC_VER="-$GLIBC_VER" + else + AC_MSG_WARN([cannot determine GNU C library minor version number]) + fi + rm -f $dummy $dummy.c + AC_SUBST(GLIBC_VER) +]) + +AC_DEFUN(rc_LIBSTDCPP_VER, + [AC_MSG_CHECKING([libstdc++ version]) + dummy=if$$ + cat <<_LIBSTDCPP_>$dummy.cc +#include +#include +#include +int main(int argc, char **argv) { exit(0); } +_LIBSTDCPP_ + ${CXX-c++} $dummy.cc -o $dummy > /dev/null 2>&1 + + if test "$?" = 0; then + soname=`objdump -p ./$dummy |grep NEEDED|grep libstd` + LIBSTDCPP_VER=`echo $soname | sed -e 's/.*NEEDED.*libstdc++\(-libc.*\(-.*\)\)\?.so.\(.*\)/\3\2/'` + fi + rm -f $dummy $dummy.cc + + if test -z "$LIBSTDCPP_VER"; then + AC_MSG_WARN([cannot determine standard C++ library version number]) + else + AC_MSG_RESULT([$LIBSTDCPP_VER]) + LIBSTDCPP_VER="-$LIBSTDCPP_VER" + fi + AC_SUBST(LIBSTDCPP_VER) +]) + +AC_DEFUN(ah_GCC3DEP,[ + AC_MSG_CHECKING(if $CXX -MD works) + touch gcc3dep.cc + ${CXX-c++} -MD -o gcc3dep_test.o -c gcc3dep.cc + rm -f gcc3dep.cc gcc3dep_test.o + if test -e gcc3dep.d; then + rm -f gcc3dep.d + GCC_MD=input + GCC3DEP= + elif test -e gcc3dep_test.d; then + rm -f gcc3dep_test.d + GCC_MD=output + GCC3DEP=yes + else + AC_MSG_ERROR(no) + fi + AC_MSG_RESULT([yes, for $GCC_MD]) + AC_SUBST(GCC3DEP) +]) diff --git a/apt/buildlib/yodl_manpage.mak b/apt/buildlib/yodl_manpage.mak new file mode 100644 index 0000000..a5f436f --- /dev/null +++ b/apt/buildlib/yodl_manpage.mak @@ -0,0 +1,42 @@ +# -*- make -*- + +# This handles man pages in YODL format. We convert to the respective +# output in the source directory then copy over to the final dest. This +# means yodl is only needed if compiling from CVS + +# Input +# $(SOURCE) - The documents to use, in the form foo.sect, ie apt-cache.8 +# the yodl files are called apt-cache.8.yo + +# See defaults.mak for information about LOCAL + +# Some local definitions +ifdef YODL_MAN + +LOCAL := yodl-manpage-$(firstword $(SOURCE)) +$(LOCAL)-LIST := $(SOURCE) + +# Install generation hooks +doc: $($(LOCAL)-LIST) +veryclean: veryclean/$(LOCAL) + +$($(LOCAL)-LIST) :: % : %.yo + echo Creating man page $@ + yodl2man -o $@ $< + +# Clean rule +.PHONY: veryclean/$(LOCAL) +veryclean/$(LOCAL): + -rm -rf $($(@F)-LIST) + +else + +# Strip from the source list any man pages we dont have compiled already +SOURCE := $(wildcard $(SOURCE)) + +endif + +# Chain to the manpage rule +ifneq ($(words $(SOURCE)),0) +include $(MANPAGE_H) +endif diff --git a/apt/cmdline/CVS/Entries b/apt/cmdline/CVS/Entries new file mode 100644 index 0000000..e84551a --- /dev/null +++ b/apt/cmdline/CVS/Entries @@ -0,0 +1,12 @@ +/apt-cache.cc/1.20/Wed Aug 1 21:57:04 2001// +/apt-config.cc/1.3/Wed Aug 1 21:57:05 2001// +/acqprogress.cc/1.2/Fri Aug 10 14:00:40 2001// +/acqprogress.h/1.1.1.1/Fri Aug 10 14:00:40 2001// +/indexcopy.cc/1.1.1.1/Fri Aug 10 14:00:44 2001// +/indexcopy.h/1.1.1.1/Fri Aug 10 14:00:44 2001// +/makefile/1.23/Fri Aug 10 14:00:44 2001// +/rpmindexcopy.cc/1.2/Fri Aug 10 14:00:44 2001// +/rpmindexcopy.h/1.1/Fri Aug 10 14:00:44 2001// +/apt-cdrom.cc/1.10/Fri Nov 16 01:13:06 2001// +/apt-get.cc/1.45/Fri Nov 16 01:13:06 2001// +D diff --git a/apt/cmdline/CVS/Repository b/apt/cmdline/CVS/Repository new file mode 100644 index 0000000..7290bfb --- /dev/null +++ b/apt/cmdline/CVS/Repository @@ -0,0 +1 @@ +rapt/cmdline diff --git a/apt/cmdline/CVS/Root b/apt/cmdline/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/cmdline/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/cmdline/acqprogress.cc b/apt/cmdline/acqprogress.cc new file mode 100644 index 0000000..a2aa952 --- /dev/null +++ b/apt/cmdline/acqprogress.cc @@ -0,0 +1,275 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acqprogress.cc,v 1.2 2000/09/28 21:51:57 kojima Exp $ +/* ###################################################################### + + Acquire Progress - Command line progress meter + + ##################################################################### */ + /*}}}*/ +// Include files /*{{{*/ +#include "acqprogress.h" +#include +#include +#include +#include + +#include +#include + /*}}}*/ + +// AcqTextStatus::AcqTextStatus - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +AcqTextStatus::AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet) : + ScreenWidth(ScreenWidth), Quiet(Quiet) +{ +} + /*}}}*/ +// AcqTextStatus::Start - Downloading has started /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void AcqTextStatus::Start() +{ + pkgAcquireStatus::Start(); + BlankLine[0] = 0; + ID = 1; +}; + /*}}}*/ +// AcqTextStatus::IMSHit - Called when an item got a HIT response /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void AcqTextStatus::IMSHit(pkgAcquire::ItemDesc &Itm) +{ + if (Quiet > 1) + return; + + if (Quiet <= 0) + cout << '\r' << BlankLine << '\r'; + + cout << "Hit " << Itm.Description; + if (Itm.Owner->FileSize != 0) + cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]"; + cout << endl; + Update = true; +}; + /*}}}*/ +// AcqTextStatus::Fetch - An item has started to download /*{{{*/ +// --------------------------------------------------------------------- +/* This prints out the short description and the expected size */ +void AcqTextStatus::Fetch(pkgAcquire::ItemDesc &Itm) +{ + Update = true; + if (Itm.Owner->Complete == true) + return; + + Itm.Owner->ID = ID++; + + if (Quiet > 1) + return; + + if (Quiet <= 0) + cout << '\r' << BlankLine << '\r'; + + cout << "Get:" << Itm.Owner->ID << ' ' << Itm.Description; + if (Itm.Owner->FileSize != 0) + cout << " [" << SizeToStr(Itm.Owner->FileSize) << "B]"; + cout << endl; +}; + /*}}}*/ +// AcqTextStatus::Done - Completed a download /*{{{*/ +// --------------------------------------------------------------------- +/* We don't display anything... */ +void AcqTextStatus::Done(pkgAcquire::ItemDesc &Itm) +{ + Update = true; +}; + /*}}}*/ +// AcqTextStatus::Fail - Called when an item fails to download /*{{{*/ +// --------------------------------------------------------------------- +/* We print out the error text */ +void AcqTextStatus::Fail(pkgAcquire::ItemDesc &Itm) +{ + if (Quiet > 1) + return; + + // Ignore certain kinds of transient failures (bad code) + if (Itm.Owner->Status == pkgAcquire::Item::StatIdle) + return; + + if (Quiet <= 0) + cout << '\r' << BlankLine << '\r'; + + if (Itm.Owner->Status == pkgAcquire::Item::StatDone) + { + cout << "Ign " << Itm.Description << endl; + } + else + { + cout << "Err " << Itm.Description << endl; + cout << " " << Itm.Owner->ErrorText << endl; + } + + Update = true; +}; + /*}}}*/ +// AcqTextStatus::Stop - Finished downloading /*{{{*/ +// --------------------------------------------------------------------- +/* This prints out the bytes downloaded and the overall average line + speed */ +void AcqTextStatus::Stop() +{ + pkgAcquireStatus::Stop(); + if (Quiet > 1) + return; + + if (Quiet <= 0) + cout << '\r' << BlankLine << '\r' << flush; + + if (FetchedBytes != 0 && _error->PendingError() == false) + cout << "Fetched " << SizeToStr(FetchedBytes) << "B in " << + TimeToStr(ElapsedTime) << " (" << SizeToStr(CurrentCPS) << + "B/s)" << endl; +} + /*}}}*/ +// AcqTextStatus::Pulse - Regular event pulse /*{{{*/ +// --------------------------------------------------------------------- +/* This draws the current progress. Each line has an overall percent + meter and a per active item status meter along with an overall + bandwidth and ETA indicator. */ +bool AcqTextStatus::Pulse(pkgAcquire *Owner) +{ + if (Quiet > 0) + return true; + + pkgAcquireStatus::Pulse(Owner); + + enum {Long = 0,Medium,Short} Mode = Long; + + char Buffer[1024]; + char *End = Buffer + sizeof(Buffer); + char *S = Buffer; + if (ScreenWidth >= sizeof(Buffer)) + ScreenWidth = sizeof(Buffer)-1; + + // Put in the percent done + sprintf(S,"%ld%%",long(double((CurrentBytes + CurrentItems)*100.0)/double(TotalBytes+TotalItems))); + + bool Shown = false; + for (pkgAcquire::Worker *I = Owner->WorkersBegin(); I != 0; + I = Owner->WorkerStep(I)) + { + S += strlen(S); + + // There is no item running + if (I->CurrentItem == 0) + { + if (I->Status.empty() == false) + { + snprintf(S,End-S," [%s]",I->Status.c_str()); + Shown = true; + } + + continue; + } + + Shown = true; + + // Add in the short description + if (I->CurrentItem->Owner->ID != 0) + snprintf(S,End-S," [%lu %s",I->CurrentItem->Owner->ID, + I->CurrentItem->ShortDesc.c_str()); + else + snprintf(S,End-S," [%s",I->CurrentItem->ShortDesc.c_str()); + S += strlen(S); + + // Show the short mode string + if (I->CurrentItem->Owner->Mode != 0) + { + snprintf(S,End-S," %s",I->CurrentItem->Owner->Mode); + S += strlen(S); + } + + // Add the current progress + if (Mode == Long) + snprintf(S,End-S," %lu",I->CurrentSize); + else + { + if (Mode == Medium || I->TotalSize == 0) + snprintf(S,End-S," %luB",I->CurrentSize); + } + S += strlen(S); + + // Add the total size and percent + if (I->TotalSize > 0 && I->CurrentItem->Owner->Complete == false) + { + if (Mode == Short) + snprintf(S,End-S," %lu%%", + long(double(I->CurrentSize*100.0)/double(I->TotalSize))); + else + snprintf(S,End-S,"/%luB %lu%%", I->TotalSize, + long(double(I->CurrentSize*100.0)/double(I->TotalSize))); + } + S += strlen(S); + snprintf(S,End-S,"]"); + } + + // Show something.. + if (Shown == false) + snprintf(S,End-S," [Working]"); + + /* Put in the ETA and cps meter, block off signals to prevent strangeness + during resizing */ + sigset_t Sigs,OldSigs; + sigemptyset(&Sigs); + sigaddset(&Sigs,SIGWINCH); + sigprocmask(SIG_BLOCK,&Sigs,&OldSigs); + + if (CurrentCPS != 0) + { + char Tmp[300]; + unsigned long ETA = (unsigned long)((TotalBytes - CurrentBytes)/CurrentCPS); + sprintf(Tmp," %sB/s %s",SizeToStr(CurrentCPS).c_str(),TimeToStr(ETA).c_str()); + unsigned int Len = strlen(Buffer); + unsigned int LenT = strlen(Tmp); + if (Len + LenT < ScreenWidth) + { + memset(Buffer + Len,' ',ScreenWidth - Len); + strcpy(Buffer + ScreenWidth - LenT,Tmp); + } + } + Buffer[ScreenWidth] = 0; + BlankLine[ScreenWidth] = 0; + sigprocmask(SIG_UNBLOCK,&OldSigs,0); + + // Draw the current status + if (strlen(Buffer) == strlen(BlankLine)) + cout << '\r' << Buffer << flush; + else + cout << '\r' << BlankLine << '\r' << Buffer << flush; + memset(BlankLine,' ',strlen(Buffer)); + BlankLine[strlen(Buffer)] = 0; + + Update = false; + + return true; +} + /*}}}*/ +// AcqTextStatus::MediaChange - Media need to be swapped /*{{{*/ +// --------------------------------------------------------------------- +/* Prompt for a media swap */ +bool AcqTextStatus::MediaChange(string Media,string Drive) +{ + if (Quiet <= 0) + cout << '\r' << BlankLine << '\r'; + cout << "Media Change: Please insert the disc labeled '" << Media << "' in "\ + "the drive '" << Drive << "' and press enter" << endl; + + char C = 0; + while (C != '\n' && C != '\r') + read(STDIN_FILENO,&C,1); + + Update = true; + return true; +} + /*}}}*/ diff --git a/apt/cmdline/acqprogress.h b/apt/cmdline/acqprogress.h new file mode 100644 index 0000000..10189e9 --- /dev/null +++ b/apt/cmdline/acqprogress.h @@ -0,0 +1,37 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: acqprogress.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Acquire Progress - Command line progress meter + + ##################################################################### */ + /*}}}*/ +#ifndef ACQPROGRESS_H +#define ACQPROGRESS_H + +#include + +class AcqTextStatus : public pkgAcquireStatus +{ + unsigned int &ScreenWidth; + char BlankLine[300]; + unsigned long ID; + unsigned long Quiet; + + public: + + virtual bool MediaChange(string Media,string Drive); + virtual void IMSHit(pkgAcquire::ItemDesc &Itm); + virtual void Fetch(pkgAcquire::ItemDesc &Itm); + virtual void Done(pkgAcquire::ItemDesc &Itm); + virtual void Fail(pkgAcquire::ItemDesc &Itm); + virtual void Start(); + virtual void Stop(); + + bool Pulse(pkgAcquire *Owner); + + AcqTextStatus(unsigned int &ScreenWidth,unsigned int Quiet); +}; + +#endif diff --git a/apt/cmdline/apt-cache.cc b/apt/cmdline/apt-cache.cc new file mode 100644 index 0000000..95002b5 --- /dev/null +++ b/apt/cmdline/apt-cache.cc @@ -0,0 +1,1352 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt-cache.cc,v 1.20 2001/08/01 21:57:04 kojima Exp $ + +/* ###################################################################### + + apt-cache - Manages the cache files + + apt-cache provides some functions fo manipulating the cache files. + It uses the command line interface common to all the APT tools. The + only really usefull function right now is dumpavail which is used + by the dselect method. Everything else is meant as a debug aide. + + Returns 100 on failure, 0 on success. + + ##################################################################### + */ + + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include //akk + +//akk#include +#include +#include + +#include + +#include + +#include +#include +#include +#include +#include + +#include //akk + + /*}}}*/ + +pkgCache *GCache = 0; + +// UnMet - Show unmet dependencies /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool UnMet(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + bool Important = _config->FindB("APT::Cache::Important",false); + + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + { + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++) + { + bool Header = false; + for (pkgCache::DepIterator D = V.DependsList(); D.end() == false;) + { + // Collect or groups + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + +/* cout << "s: Check " << Start.TargetPkg().Name() << ',' << + End.TargetPkg().Name() << endl;*/ + + // Skip conflicts and replaces + if (End->Type != pkgCache::Dep::PreDepends && + End->Type != pkgCache::Dep::Depends && + End->Type != pkgCache::Dep::Suggests && + End->Type != pkgCache::Dep::Recommends) + continue; + + // Important deps only + if (Important == true) + if (End->Type != pkgCache::Dep::PreDepends && + End->Type != pkgCache::Dep::Depends) + continue; + + // Verify the or group + bool OK = false; + pkgCache::DepIterator RealStart = Start; + do + { + // See if this dep is Ok + pkgCache::Version **VList = Start.AllTargets(); + if (*VList != 0) + { + OK = true; + delete [] VList; + break; + } + delete [] VList; + + if (Start == End) + break; + Start++; + } + while (1); + + // The group is OK + if (OK == true) + continue; + + // Oops, it failed.. + if (Header == false) + cout << _("Package ") << P.Name() << _(" version ") << + V.VerStr() << _(" has an unmet dep:") << endl; + Header = true; + + // Print out the dep type + cout << " " << End.DepType() << ": "; + + // Show the group + Start = RealStart; + do + { + cout << Start.TargetPkg().Name(); + if (Start.TargetVer() != 0) + cout << " (" << Start.CompType() << " " << Start.TargetVer() << + ")"; + if (Start == End) + break; + cout << " | "; + Start++; + } + while (1); + + cout << endl; + } + } + } + return true; +} + /*}}}*/ +// DumpPackage - Show a dump of a package record /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DumpPackage(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); + if (Pkg.end() == true) + { + _error->Warning(_("Unable to locate package %s"),*I); + continue; + } + + cout << _("Package: ") << Pkg.Name() << endl; + cout << _("Versions: "); + for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) + { + cout << Cur.VerStr(); + for (pkgCache::VerFileIterator Vf = Cur.FileList(); Vf.end() == false; Vf++) + cout << "(" << Vf.File().FileName() << ")"; + cout << ','; + } + + cout << endl; + + cout << _("Reverse Depends: ") << endl; + for (pkgCache::DepIterator D = Pkg.RevDependsList(); D.end() != true; D++) + cout << " " << D.ParentPkg().Name() << ',' << D.TargetPkg().Name() << endl; + + cout << _("Dependencies: ") << endl; + for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) + { + cout << Cur.VerStr() << " - "; + for (pkgCache::DepIterator Dep = Cur.DependsList(); Dep.end() != true; Dep++) + cout << Dep.TargetPkg().Name() << " (" << (int)Dep->CompareOp << " " << Dep.TargetVer() << ") "; + cout << endl; + } + + cout << _("Provides: ") << endl; + for (pkgCache::VerIterator Cur = Pkg.VersionList(); Cur.end() != true; Cur++) + { + cout << Cur.VerStr() << " - "; + for (pkgCache::PrvIterator Prv = Cur.ProvidesList(); Prv.end() != true; Prv++) + cout << Prv.ParentPkg().Name() << " "; + cout << endl; + } + cout << _("Reverse Provides: ") << endl; + for (pkgCache::PrvIterator Prv = Pkg.ProvidesList(); Prv.end() != true; Prv++) + cout << Prv.OwnerPkg().Name() << " " << Prv.OwnerVer().VerStr() << endl; + } + + return true; +} + /*}}}*/ +// Stats - Dump some nice statistics /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Stats(CommandLine &Cmd) +{ + pkgCache &Cache = *GCache; + cout << _("Total Package Names : ") << Cache.Head().PackageCount << " (" << + SizeToStr(Cache.Head().PackageCount*Cache.Head().PackageSz) << ')' << endl; + pkgCache::PkgIterator I = Cache.PkgBegin(); + + int Normal = 0; + int Virtual = 0; + int NVirt = 0; + int DVirt = 0; + int Missing = 0; + for (;I.end() != true; I++) + { + if (I->VersionList != 0 && I->ProvidesList == 0) + { + Normal++; + continue; + } + + if (I->VersionList != 0 && I->ProvidesList != 0) + { + NVirt++; + continue; + } + + if (I->VersionList == 0 && I->ProvidesList != 0) + { + // Only 1 provides + if (I.ProvidesList()->NextProvides == 0) + { + DVirt++; + } + else + Virtual++; + continue; + } + if (I->VersionList == 0 && I->ProvidesList == 0) + { + Missing++; + continue; + } + } + cout << _(" Normal Packages: ") << Normal << endl; + cout << _(" Pure Virtual Packages: ") << Virtual << endl; + cout << _(" Single Virtual Packages: ") << DVirt << endl; + cout << _(" Mixed Virtual Packages: ") << NVirt << endl; + cout << _(" Missing: ") << Missing << endl; + + cout << _("Total Distinct Versions: ") << Cache.Head().VersionCount << " (" << + SizeToStr(Cache.Head().VersionCount*Cache.Head().VersionSz) << ')' << endl; + cout << _("Total Dependencies: ") << Cache.Head().DependsCount << " (" << + SizeToStr(Cache.Head().DependsCount*Cache.Head().DependencySz) << ')' << endl; + + cout << _("Total Ver/File relations: ") << Cache.Head().VerFileCount << " (" << + SizeToStr(Cache.Head().VerFileCount*Cache.Head().VerFileSz) << ')' << endl; + cout << _("Total Provides Mappings: ") << Cache.Head().ProvidesCount << " (" << + SizeToStr(Cache.Head().ProvidesCount*Cache.Head().ProvidesSz) << ')' << endl; + + // String list stats + unsigned long Size = 0; + unsigned long Count = 0; + for (pkgCache::StringItem *I = Cache.StringItemP + Cache.Head().StringList; + I!= Cache.StringItemP; I = Cache.StringItemP + I->NextItem) + { + Count++; + Size += strlen(Cache.StrP + I->String); + } + cout << _("Total Globbed Strings: ") << Count << " (" << SizeToStr(Size) << ')' << endl; + + unsigned long Slack = 0; + for (int I = 0; I != 7; I++) + Slack += Cache.Head().Pools[I].ItemSize*Cache.Head().Pools[I].Count; + cout << _("Total Slack space: ") << SizeToStr(Slack) << endl; + + unsigned long Total = 0; + Total = Slack + Size + Cache.Head().DependsCount*Cache.Head().DependencySz + + Cache.Head().VersionCount*Cache.Head().VersionSz + + Cache.Head().PackageCount*Cache.Head().PackageSz + + Cache.Head().VerFileCount*Cache.Head().VerFileSz + + Cache.Head().ProvidesCount*Cache.Head().ProvidesSz; + cout << _("Total Space Accounted for: ") << SizeToStr(Total) << endl; + + return true; +} + /*}}}*/ +// Check - Check some things about the cache /*{{{*/ +// --------------------------------------------------------------------- +/* Debug aide mostly */ +bool Check(CommandLine &Cmd) +{ + pkgCache &Cache = *GCache; + pkgCache::PkgIterator Pkg = Cache.PkgBegin(); + for (;Pkg.end() != true; Pkg++) + { + if (Pkg.Section() == 0 && Pkg->VersionList != 0) + cout << _("Bad section ") << Pkg.Name() << endl; + + for (pkgCache::VerIterator Cur = Pkg.VersionList(); + Cur.end() != true; Cur++) + { + if (Cur->Priority < 1 || Cur->Priority > 5) + cout << _("Bad prio ") << Pkg.Name() << ',' << Cur.VerStr() << " == " << (int)Cur->Priority << endl; + } + } + return true; +} + /*}}}*/ +// Dump - show everything /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Dump(CommandLine &Cmd) +{ + pkgCache &Cache = *GCache; + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + { + cout << _("Package: ") << P.Name() << endl; + for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; V++) + { + cout << _(" Version: ") << V.VerStr() << endl; + cout << _(" File: ") << V.FileList().File().FileName() << endl; + for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; D++) + cout << _(" Depends: ") << D.TargetPkg().Name() << ' ' << D.TargetVer() << endl; + } + } + + for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++) + { + cout << _("File: ") << F.FileName() << endl; + cout << _(" Size: ") << F->Size << endl; + cout << _(" ID: ") << F->ID << endl; + cout << _(" Flags: ") << F->Flags << endl; + cout << _(" Time: ") << TimeRFC1123(F->mtime) << endl; + cout << _(" Archive: ") << F.Archive() << endl; + cout << _(" Component: ") << F.Component() << endl; + cout << _(" Version: ") << F.Version() << endl; + cout << _(" Origin: ") << F.Origin() << endl; + cout << _(" Label: ") << F.Label() << endl; + cout << _(" Architecture: ") << F.Architecture() << endl; + } + + return true; +} + /*}}}*/ +// DumpAvail - Print out the available list /*{{{*/ +// --------------------------------------------------------------------- +/* This is needed to make dpkg --merge happy */ +bool DumpAvail(CommandLine &Cmd) +{ + pkgCache &Cache = *GCache; + unsigned char *Buffer = new unsigned char[Cache.HeaderP->MaxVerFileSize]; + + for (pkgCache::PkgFileIterator I = Cache.FileBegin(); I.end() == false; I++) + { + if ((I->Flags & pkgCache::Flag::NotSource) != 0) + continue; + + if (I.IsOk() == false) + { + delete [] Buffer; + return _error->Error(_("Package file %s is out of sync."),I.FileName()); + } + + FileFd PkgF(I.FileName(),FileFd::ReadOnly); + if (_error->PendingError() == true) + { + delete [] Buffer; + return false; + } + + /* Write all of the records from this package file, we search the entire + structure to find them */ + for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++) + { + // Find the proper version to use. We should probably use the DepCache. + pkgCache::VerIterator V = Cache.GetCandidateVer(P,false); + + if (V.end() == true || V.FileList().File() != I) + continue; + + // Read the record and then write it out again. + if (PkgF.Seek(V.FileList()->Offset) == false || + PkgF.Read(Buffer,V.FileList()->Size) == false || + write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size) + { + delete [] Buffer; + return false; + } + } + } + + return true; +} + /*}}}*/ +// Depends - Print out a dependency tree /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool Depends(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); + if (Pkg.end() == true) + { + _error->Warning(_("Unable to locate package %s"),*I); + continue; + } + + pkgCache::VerIterator Ver = Pkg.VersionList(); + if (Ver.end() == true) + { + cout << '<' << Pkg.Name() << '>' << endl; + continue; + } + + cout << Pkg.Name() << endl; + + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) + { + if ((D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or) + cout << " |"; + else + cout << " "; + + // Show the package + pkgCache::PkgIterator Trg = D.TargetPkg(); + if (Trg->VersionList == 0) + cout << D.DepType() << ": <" << Trg.Name() << ">" << endl; + else + cout << D.DepType() << ": " << Trg.Name() << endl; + + // Display all solutions + pkgCache::Version **List = D.AllTargets(); + for (pkgCache::Version **I = List; *I != 0; I++) + { + pkgCache::VerIterator V(Cache,*I); + if (V != Cache.VerP + V.ParentPkg()->VersionList || + V->ParentPkg == D->Package) + continue; + cout << " " << V.ParentPkg().Name() << endl; + } + delete [] List; + } + } + + return true; +} + /*}}}*/ +// Dotty - Generate a graph for Dotty /*{{{*/ +// --------------------------------------------------------------------- +/* Dotty is the graphvis program for generating graphs. It is a fairly + simple queuing algorithm that just writes dependencies and nodes. + http://www.research.att.com/sw/tools/graphviz/ */ +bool Dotty(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + bool GivenOnly = _config->FindB("APT::Cache::GivenOnly",false); + + /* Normal packages are boxes + Pure Provides are triangles + Mixed are diamonds + Hexagons are missing packages*/ + const char *Shapes[] = {"hexagon","triangle","box","diamond"}; + + /* Initialize the list of packages to show. + 1 = To Show + 2 = To Show no recurse + 3 = Emitted no recurse + 4 = Emitted + 0 = None */ + enum States {None=0, ToShow, ToShowNR, DoneNR, Done}; + enum TheFlags {ForceNR=(1<<0)}; + unsigned char *Show = new unsigned char[Cache.Head().PackageCount]; + unsigned char *Flags = new unsigned char[Cache.Head().PackageCount]; + unsigned char *ShapeMap = new unsigned char[Cache.Head().PackageCount]; + + // Show everything if no arguments given + if (CmdL.FileList[1] == 0) + for (unsigned long I = 0; I != Cache.Head().PackageCount; I++) + Show[I] = ToShow; + else + for (unsigned long I = 0; I != Cache.Head().PackageCount; I++) + Show[I] = None; + memset(Flags,0,sizeof(*Flags)*Cache.Head().PackageCount); + + // Map the shapes + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + { + if (Pkg->VersionList == 0) + { + // Missing + if (Pkg->ProvidesList == 0) + ShapeMap[Pkg->ID] = 0; + else + ShapeMap[Pkg->ID] = 1; + } + else + { + // Normal + if (Pkg->ProvidesList == 0) + ShapeMap[Pkg->ID] = 2; + else + ShapeMap[Pkg->ID] = 3; + } + } + + // Load the list of packages from the command line into the show list + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + // Process per-package flags + string P = *I; + bool Force = false; + if (P.length() > 3) + { + if (P.end()[-1] == '^') + { + Force = true; + P.erase(P.end()-1); + } + + if (P.end()[-1] == ',') + P.erase(P.end()-1); + } + + // Locate the package + pkgCache::PkgIterator Pkg = Cache.FindPkg(P); + if (Pkg.end() == true) + { + _error->Warning(_("Unable to locate package %s"),*I); + continue; + } + Show[Pkg->ID] = ToShow; + + if (Force == true) + Flags[Pkg->ID] |= ForceNR; + } + + // Little header + printf("digraph packages {\n"); + printf("concentrate=true;\n"); + printf("size=\"30,40\";\n"); + + bool Act = true; + while (Act == true) + { + Act = false; + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + { + // See we need to show this package + if (Show[Pkg->ID] == None || Show[Pkg->ID] >= DoneNR) + continue; + + // Colour as done + if (Show[Pkg->ID] == ToShowNR || (Flags[Pkg->ID] & ForceNR) == ForceNR) + { + // Pure Provides and missing packages have no deps! + if (ShapeMap[Pkg->ID] == 0 || ShapeMap[Pkg->ID] == 1) + Show[Pkg->ID] = Done; + else + Show[Pkg->ID] = DoneNR; + } + else + Show[Pkg->ID] = Done; + Act = true; + + // No deps to map out + if (Pkg->VersionList == 0 || Show[Pkg->ID] == DoneNR) + continue; + + pkgCache::VerIterator Ver = Pkg.VersionList(); + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) + { + // See if anything can meet this dep + // Walk along the actual package providing versions + bool Hit = false; + pkgCache::PkgIterator DPkg = D.TargetPkg(); + for (pkgCache::VerIterator I = DPkg.VersionList(); + I.end() == false && Hit == false; I++) + { + if (_system->checkDep(D.TargetVer(),I.VerStr(),D->CompareOp) == true) + Hit = true; + } + + // Follow all provides + for (pkgCache::PrvIterator I = DPkg.ProvidesList(); + I.end() == false && Hit == false; I++) + { + if (_system->checkDep(D.TargetVer(),I.ProvideVersion(),D->CompareOp) == false) + Hit = true; + } + + // Only graph critical deps + if (D.IsCritical() == true) + { + printf("\"%s\" -> \"%s\"",Pkg.Name(),D.TargetPkg().Name()); + + // Colour the node for recursion + if (Show[D.TargetPkg()->ID] <= DoneNR) + { + /* If a conflicts does not meet anything in the database + then show the relation but do not recurse */ + if (Hit == false && D->Type == pkgCache::Dep::Conflicts) + { + if (Show[D.TargetPkg()->ID] == None && + Show[D.TargetPkg()->ID] != ToShow) + Show[D.TargetPkg()->ID] = ToShowNR; + } + else + { + if (GivenOnly == true && Show[D.TargetPkg()->ID] != ToShow) + Show[D.TargetPkg()->ID] = ToShowNR; + else + Show[D.TargetPkg()->ID] = ToShow; + } + } + + // Edge colour + switch(D->Type) + { + case pkgCache::Dep::Conflicts: + printf("[color=springgreen];\n"); + break; + + case pkgCache::Dep::PreDepends: + printf("[color=blue];\n"); + break; + + default: + printf(";\n"); + break; + } + } + } + } + } + + /* Draw the box colours after the fact since we can not tell what colour + they should be until everything is finished drawing */ + for (pkgCache::PkgIterator Pkg = Cache.PkgBegin(); Pkg.end() == false; Pkg++) + { + if (Show[Pkg->ID] < DoneNR) + continue; + + // Orange box for early recursion stoppage + if (Show[Pkg->ID] == DoneNR) + printf("\"%s\" [color=orange,shape=%s];\n",Pkg.Name(), + Shapes[ShapeMap[Pkg->ID]]); + else + printf("\"%s\" [shape=%s];\n",Pkg.Name(), + Shapes[ShapeMap[Pkg->ID]]); + } + + printf("}\n"); + return true; +} + /*}}}*/ +// DoAdd - Perform an adding operation /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DoAdd(CommandLine &CmdL) +{ + // Make sure there is at least one argument + if (CmdL.FileSize() <= 1) + return _error->Error(_("You must give at least one file name")); + + // Open the cache + FileFd CacheF(_config->FindFile("Dir::Cache::pkgcache"),FileFd::WriteAny); + if (_error->PendingError() == true) + return false; + + DynamicMMap Map(CacheF,MMap::Public); + if (_error->PendingError() == true) + return false; + + OpTextProgress Progress(*_config); + pkgCacheGenerator Gen(Map,Progress); + if (_error->PendingError() == true) + return false; + + unsigned long Length = CmdL.FileSize() - 1; + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + Progress.OverallProgress(I - CmdL.FileList,Length,1,_("Generating cache")); + Progress.SubProgress(Length); + + // Do the merge + FileFd TagF(*I,FileFd::ReadOnly); + pkgCacheGenerator::ListParser *Parser = _system->CreateListParser(TagF); + + if (_error->PendingError() == true) + return _error->Error(_("Problem opening %s"),*I); + + if (Gen.SelectFile(*I) == false) + return _error->Error(_("Problem with SelectFile")); + + if (Gen.MergeList(*Parser, 0) == false) + return _error->Error(_("Problem with MergeList")); + } + + Progress.Done(); + GCache = &Gen.GetCache(); + Stats(CmdL); + + return true; +} + /*}}}*/ +// DisplayRecord - Displays the complete record for the package /*{{{*/ +// --------------------------------------------------------------------- +/* This displays the package record from the proper package index file. + It is not used by DumpAvail for performance reasons. */ +#if 1 +#define CRPMTAG_FILENAME 1000000 +#define CRPMTAG_FILESIZE 1000001 +#define CRPMTAG_ESSENTIAL 1000002 +#define CRPMTAG_MD5 1000005 + + + + +void pstrarray(FILE *f, char **str, int count) +{ + if (!count) + return; + + fprintf(f, "%s", *str++); + count--; + while (count--) { + fprintf(f, ", %s", *str++); + } + fprintf(f, "\n"); +} + +void pstr(FILE *f, char **data, int count, int type) +{ + if (type == RPM_STRING_TYPE) { + fprintf(f, "%s\n", (char*)data); + } else if (type == RPM_STRING_ARRAY_TYPE) { + pstrarray(f, data, count); + } else { + puts("Oh shit!"); + abort(); + } +} + + +void pitem(FILE *f, char *file, char *version, int flags) +{ + fputs(file, f); + if (*version) { + int c = 0; + fputs(" (", f); + /* + * For some reason, debian ppl decided that: + * > and < are the same as >=, <= + * >> and << is the same as >, < + */ + if (flags & RPMSENSE_LESS) { + fputc('<', f); + c = '<'; + } + if (flags & RPMSENSE_GREATER) { + fputc('>', f); + c = '>'; + } + if (flags & RPMSENSE_EQUAL) { + fputc('=', f); + } else { + if (c) + fputc(c, f); + } + fprintf(f, " %s)", version); + } +} + + +void ptuplearray(FILE *f, char **str1, char **str2, int *flags, int count) +{ + int first = 1; + if (!count) + return; + + while (count--) { + if (!first) + fputs(", ", f); + first = 0; + pitem(f, *str1, *str2, *flags); + str1++; str2++; flags++; + } + fputc('\n', f); +} + +void pdepend(FILE *f, char **data1, char **data2, int *flags, int count, + int type) +{ + if (type == RPM_STRING_TYPE) { + pitem(f, (char*)data1, (char*)data2, *flags); + fprintf(f, "\n"); + } else if (type == RPM_STRING_ARRAY_TYPE) { + ptuplearray(f, data1, data2, flags, count); + } else { + puts(_("Oh shit!")); + abort(); + } +} + + +void dumpDescription(FILE *f, char *descr) +{ + int nl; + + nl = 1; + while (*descr) { + if (nl) { + fputc(' ', f); + nl = 0; + } + if (*descr=='\n') { + nl = 1; + } + fputc(*descr++, f); + } + fputc('\n', f); +} + + +void showHeader(FILE *f, Header hdr) +{ + int type, type2, type3, count; + char *str; + char **strv; + char **strv2; + int num; + int_32 *numv; + + headerGetEntry(hdr, RPMTAG_NAME, &type, (void **)&str, &count); + fprintf(f, _("Package: %s\n"), str); + + headerGetEntry(hdr, RPMTAG_GROUP, &type, (void **)&str, &count); + fprintf(f, _("Section: %s\n"), str); + + headerGetEntry(hdr, RPMTAG_SIZE, &type, (void **)&numv, &count); + fprintf(f, _("Installed Size: %i\n"), numv[0] / 1000); + + // Another kludge, --claudio + str = NULL; + headerGetEntry(hdr, RPMTAG_PACKAGER, &type, (void **)&str, &count); + if (!str) + headerGetEntry(hdr, RPMTAG_VENDOR, &type, (void **)&str, &count); + fprintf(f, _("Maintainer: %s\n"), str); + + headerGetEntry(hdr, RPMTAG_VERSION, &type, (void **)&str, &count); + if (headerGetEntry(hdr, RPMTAG_EPOCH, &type, (void **)&numv, &count)==1) + fprintf(f, _("Version: %i:%s"), numv[0], str); + else + fprintf(f, _("Version: %s"), str); + + headerGetEntry(hdr, RPMTAG_RELEASE, &type, (void **)&str, &count); + fprintf(f, "-%s\n", str); + +// headerGetEntry(hdr, RPMTAG_DISTRIBUTION, &type, (void **)&str, &count); +// fprintf(f, "Distribution: %s\n", str); + + headerGetEntry(hdr, RPMTAG_REQUIRENAME, &type, (void **)&strv, &count); + headerGetEntry(hdr, RPMTAG_REQUIREVERSION, &type2, (void **)&strv2, &count); + headerGetEntry(hdr, RPMTAG_REQUIREFLAGS, &type3, (void **)&numv, &count); + if (count > 0) { + char **dn, **dv; + int *df; + int i, j; + + dn = (char**)malloc(sizeof(char*)*count); + dv = (char**)malloc(sizeof(char*)*count); + df = (int*)malloc(sizeof(int)*count); + + if (!dn || !dv || !df) { + puts("could not malloc"); + exit(1); + } + + for (j = i = 0; i < count; i++) { + if ((numv[i] & RPMSENSE_PREREQ) && *strv[i]!='/') {//XXX + dn[j] = strv[i]; + dv[j] = strv2[i]; + df[j] = numv[i]; + j++; + } + } + if (j > 0) { + fprintf(f, _("Pre-Depends: ")); + pdepend(f, dn, dv, df, j, type); + } + + for (j = i = 0; i < count; i++) { + if (!(numv[i] & RPMSENSE_PREREQ) && *strv[i]!='/') {//XXX + dn[j] = strv[i]; + dv[j] = strv2[i]; + df[j] = numv[i]; + j++; + } + } + if (j > 0) { + fprintf(f, _("Depends: ")); + pdepend(f, dn, dv, df, j, type); + } + + free(dn); + free(dv); + free(df); + } + + headerGetEntry(hdr, RPMTAG_CONFLICTNAME, &type, (void **)&strv, &count); + headerGetEntry(hdr, RPMTAG_CONFLICTVERSION, &type2, (void **)&strv2, &count); + headerGetEntry(hdr, RPMTAG_CONFLICTFLAGS, &type3, (void **)&numv, &count); + if (count > 0) { + fprintf(f, _("Conflicts: ")); + pdepend(f, strv, strv2, numv, count, type); + } + + headerGetEntry(hdr, RPMTAG_PROVIDENAME, &type, (void **)&strv, &count); + if (count > 0) { + fprintf(f, _("Provides: ")); + pstr(f, strv, count, type); + } + + headerGetEntry(hdr, RPMTAG_OBSOLETENAME, &type, (void **)&strv, &count); + if (count > 0) { + fprintf(f, _("Obsoletes: ")); + pstr(f, strv, count, type); + } + + headerGetEntry(hdr, RPMTAG_ARCH, &type, (void **)&str, &count); + fprintf(f, _("Architecture: %s\n"), str); + + headerGetEntry(hdr, CRPMTAG_FILESIZE, &type, (void **)&num, &count); + fprintf(f, _("Size: %d\n"), num); + + if (headerGetEntry(hdr, CRPMTAG_MD5, &type, (void **)&str, &count)==1) + printf(_("MD5sum: %s\n"), str); + + headerGetEntry(hdr, CRPMTAG_FILENAME, &type, (void **)&str, &count); + fprintf(f, _("Filename: %s\n"), str); + + headerGetEntry(hdr, RPMTAG_SUMMARY, &type, (void **)&str, &count); + fprintf(f, _("Description: %s\n"), str); + + headerGetEntry(hdr, RPMTAG_DESCRIPTION, &type, (void **)&str, &count); + dumpDescription(f, str); + + fputc('\n', f); +} + +bool DisplayRecord(pkgCache &Cache, pkgCache::VerIterator V) +{ + // Find an appropriate file + pkgCache::VerFileIterator Vf = V.FileList(); + for (; Vf.end() == false; Vf++) + if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0) + break; + if (Vf.end() == true) + Vf = V.FileList(); + + // Check and load the package list file + pkgCache::PkgFileIterator I = Vf.File(); + if (I.IsOk() == false) + return _error->Error(_("Package file %s is out of sync."),I.FileName()); + + pkgRecords::Parser *Parser = _system->CreateRecordParser(I.FileName(), Cache); + if (_error->PendingError() == true) + return false; + + // Read the record and then write it out again. + if (Parser->Jump(V.FileList()) == false) + return false; + + Header h = ((rpmRecordParser*)Parser)->GetRecord(); + + if (!h) { + return false; + } + + showHeader(stdout, h); + + + return true; +} +#else +bool DisplayRecord(pkgCachepkgCache::VerIterator V) +{ + // Find an appropriate file + pkgCache::VerFileIterator Vf = V.FileList(); + for (; Vf.end() == false; Vf++) + if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0) + break; + if (Vf.end() == true) + Vf = V.FileList(); + + // Check and load the package list file + pkgCache::PkgFileIterator I = Vf.File(); + if (I.IsOk() == false) + return _error->Error(_("Package file %s is out of sync."),I.FileName()); + + FileFd PkgF(I.FileName(),FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + + // Read the record and then write it out again. + unsigned char *Buffer = new unsigned char[GCache->HeaderP->MaxVerFileSize]; + if (PkgF.Seek(V.FileList()->Offset) == false || + PkgF.Read(Buffer,V.FileList()->Size) == false || + write(STDOUT_FILENO,Buffer,V.FileList()->Size) != V.FileList()->Size) + { + delete [] Buffer; + return false; + } + + delete [] Buffer; + + return true; +} +#endif + /*}}}*/ +// Search - Perform a search /*{{{*/ +// --------------------------------------------------------------------- +/* This searches the package names and pacakge descriptions for a pattern */ +bool Search(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + bool ShowFull = _config->FindB("APT::Cache::ShowFull",false); + bool NamesOnly = _config->FindB("APT::Cache::NamesOnly",false); + + // Make sure there is at least one argument + if (CmdL.FileSize() != 2) + return _error->Error(_("You must give exactly one pattern")); + + // Compile the regex pattern + regex_t Pattern; + if (regcomp(&Pattern,CmdL.FileList[1],REG_EXTENDED | REG_ICASE | + REG_NOSUB) != 0) + return _error->Error(_("Regex compilation error")); + + // Create the text record parser + pkgRecords Recs(Cache); + if (_error->PendingError() == true) + return false; + + // Search package names + pkgCache::PkgIterator I = Cache.PkgBegin(); + for (;I.end() != true; I++) + { + // We search against the install version as that makes the most sense.. + pkgCache::VerIterator V = Cache.GetCandidateVer(I); + if (V.end() == true) + continue; + + pkgRecords::Parser &P = Recs.Lookup(V.FileList()); + + if (regexec(&Pattern,I.Name(),0,0,0) == 0 || + (NamesOnly == false && + regexec(&Pattern,P.LongDesc().c_str(),0,0,0) == 0)) + { + if (ShowFull == true) + DisplayRecord(Cache, V); + else + cout << I.Name() << " - " << P.ShortDesc() << endl; + } + } + + regfree(&Pattern); + + return true; +} + /*}}}*/ +// ShowPackage - Dump the package record to the screen /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ShowPackage(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + pkgCache::PkgIterator Pkg = Cache.FindPkg(*I); + if (Pkg.end() == true) + { + _error->Warning(_("Unable to locate package %s"),*I); + continue; + } + + // Find the proper version to use. We should probably use the DepCache. + if (_config->FindB("APT::Cache::AllVersions","true") == true) + { + pkgCache::VerIterator V; + for (V = Pkg.VersionList(); V.end() == false; V++) + { + if (DisplayRecord(Cache, V) == false) + return false; + } + } + else + { + pkgCache::VerIterator V = Cache.GetCandidateVer(Pkg); + if (V.end() == true || V.FileList().end() == true) + continue; + if (DisplayRecord(Cache, V) == false) + return false; + } + } + return true; +} + /*}}}*/ +// ShowPkgNames - Show package names /*{{{*/ +// --------------------------------------------------------------------- +/* This does a prefix match on the first argument */ +bool ShowPkgNames(CommandLine &CmdL) +{ + pkgCache &Cache = *GCache; + pkgCache::PkgIterator I = Cache.PkgBegin(); + bool All = _config->FindB("APT::Cache::AllNames","false"); + + if (CmdL.FileList[1] != 0) + { + for (;I.end() != true; I++) + { + if (All == false && I->VersionList == 0) + continue; + + if (strncmp(I.Name(),CmdL.FileList[1],strlen(CmdL.FileList[1])) == 0) + cout << I.Name() << endl; + } + + return true; + } + + // Show all pkgs + for (;I.end() != true; I++) + { + if (All == false && I->VersionList == 0) + continue; + cout << I.Name() << endl; + } + + return true; +} + /*}}}*/ +// ShowSrcPackage - Show source package records /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ShowSrcPackage(CommandLine &CmdL) +{ + pkgSourceList List; + List.ReadMainList(); + + // Create the text record parsers + pkgSrcRecords SrcRecs(List); + if (_error->PendingError() == true) + return false; + + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + SrcRecs.Restart(); + + pkgSrcRecords::Parser *Parse; + while ((Parse = SrcRecs.Find(*I,false)) != 0) + cout << Parse->AsStr(); + } + return true; +} + /*}}}*/ +// GenCaches - Call the main cache generator /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool GenCaches(CommandLine &Cmd) +{ + OpTextProgress Progress(*_config); + + pkgSourceList List; + List.ReadMainList(); + return _system->makeStatusCache(List,Progress); +} + /*}}}*/ +// ShowHelp - Show a help screen /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ShowHelp(CommandLine &Cmd) +{ + cout << PACKAGE << ' ' << VERSION << " for " << COMMON_CPU << + " compiled on " << __DATE__ << " " << __TIME__ << endl; + if (_config->FindB("version") == true) + return 100; + + cout << _("Usage: apt-cache [options] command") << endl; + cout << _(" apt-cache [options] add file1 [file1 ...]") << endl; + cout << _(" apt-cache [options] showpkg pkg1 [pkg2 ...]") << endl; + cout << endl; + cout << _("apt-cache is a low-level tool used to manipulate APT's binary") << endl; + cout << _("cache files stored in ") << _config->FindFile("Dir::Cache") << endl; + cout << _("It is not meant for ordinary use only as a debug aide.") << endl; + cout << endl; + cout << _("Commands:") << endl; + cout << _(" add - Add an package file to the source cache") << endl; + cout << _(" gencaches - Build both the package and source cache") << endl; + cout << _(" showpkg - Show some general information for a single package") << endl; + cout << _(" stats - Show some basic statistics") << endl; + cout << _(" dump - Show the entire file in a terse form") << endl; + cout << _(" dumpavail - Print an available file to stdout") << endl; + cout << _(" unmet - Show unmet dependencies") << endl; + cout << _(" check - Check the cache a bit") << endl; + cout << _(" search - Search the package list for a regex pattern") << endl; + cout << _(" show - Show a readable record for the package") << endl; + cout << _(" depends - Show raw dependency information for a package") << endl; + cout << _(" pkgnames - List the names of all packages") << endl; + cout << _(" dotty - Generate package graphs for GraphVis") << endl; + cout << endl; + cout << _("Options:") << endl; + cout << _(" -h This help text.") << endl; + cout << _(" -p=? The package cache. [") << _config->FindFile("Dir::Cache::pkgcache") << ']' << endl; + cout << _(" -s=? The source cache. [") << _config->FindFile("Dir::Cache::srcpkgcache") << ']' << endl; + cout << _(" -q Disable progress indicator.") << endl; + cout << _(" -i Show only important deps for the unmet command.") << endl; + cout << _(" -c=? Read this configuration file") << endl; + cout << _(" -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp") << endl; + cout << _("See the apt-cache(8) and apt.conf(5) manual pages for more information.") << endl; + return 100; +} + /*}}}*/ +// CacheInitialize - Initialize things for apt-cache /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void CacheInitialize() +{ + _config->Set("quiet",0); + _config->Set("help",false); +} + /*}}}*/ + +int main(int argc,const char *argv[]) +{ + CommandLine::Args Args[] = { + {'h',"help","help",0}, + {'v',"version","version",0}, + {'p',"pkg-cache","Dir::Cache::pkgcache",CommandLine::HasArg}, + {'s',"src-cache","Dir::Cache::srcpkgcache",CommandLine::HasArg}, + {'q',"quiet","quiet",CommandLine::IntLevel}, + {'i',"important","APT::Cache::Important",0}, + {'f',"full","APT::Cache::ShowFull",0}, + {'g',"no-generate","APT::Cache::NoGenerate",0}, + {'a',"all-versions","APT::Cache::AllVersions",0}, + {0,"names-only","APT::Cache::NamesOnly",0}, + {0,"all-names","APT::Cache::AllNames",0}, + {'c',"config-file",0,CommandLine::ConfigFile}, + {'o',"option",0,CommandLine::ArbItem}, + {0,0,0,0}}; + CommandLine::Dispatch CmdsA[] = {{"help",&ShowHelp}, + {"add",&DoAdd}, + {"gencaches",&GenCaches}, + {"showsrc",&ShowSrcPackage}, + {0,0}}; + CommandLine::Dispatch CmdsB[] = {{"showpkg",&DumpPackage}, + {"stats",&Stats}, + {"dump",&Dump}, + {"dumpavail",&DumpAvail}, + {"unmet",&UnMet}, + {"check",&Check}, + {"search",&Search}, + {"depends",&Depends}, + {"dotty",&Dotty}, + {"show",&ShowPackage}, + {"pkgnames",&ShowPkgNames}, + {0,0}}; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + if (1) { + RPMFactory *factory = new RPMFactory; + + pkgRpmLock *rpm = new pkgRpmLock(false); + void *shutup_gcc = NULL; + shutup_gcc = rpm; + shutup_gcc = factory; + } +#if 0//akk + else { + DebianFactory *factory = new DebianFactory; + void *shutup_gcc = NULL; + shutup_gcc = factory; + } +#endif + CacheInitialize(); + + // Parse the command line and initialize the package library + CommandLine CmdL(Args,_config); + if (pkgInitialize(*_config) == false || + CmdL.Parse(argc,argv) == false) + { + _error->DumpErrors(); + return 100; + } + + // See if the help should be shown + if (_config->FindB("help") == true || + CmdL.FileSize() == 0) + return ShowHelp(CmdL); + + // Deal with stdout not being a tty + if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1) + _config->Set("quiet","1"); + + if (CmdL.DispatchArg(CmdsA,false) == false && _error->PendingError() == false) + { + MMap *Map; + if (_config->FindB("APT::Cache::NoGenerate",false) == true) + { + Map = new MMap(*new FileFd(_config->FindFile("Dir::Cache::pkgcache"), + FileFd::ReadOnly),MMap::Public|MMap::ReadOnly); + } + else + { + // Open the cache file + pkgSourceList List; + List.ReadMainList(); + + // Generate it and map it + OpProgress Prog; + Map = _system->makeStatusCacheMem(List,Prog); + } + + if (_error->PendingError() == false) + { + pkgCache Cache(*Map); + GCache = &Cache; + if (_error->PendingError() == false) + CmdL.DispatchArg(CmdsB); + } + delete Map; + } + + // Print any errors or warnings found during parsing + if (_error->empty() == false) + { + bool Errors = _error->PendingError(); + _error->DumpErrors(); + return Errors == true?100:0; + } + + return 0; +} diff --git a/apt/cmdline/apt-cdrom.cc b/apt/cmdline/apt-cdrom.cc new file mode 100644 index 0000000..7fab58e --- /dev/null +++ b/apt/cmdline/apt-cdrom.cc @@ -0,0 +1,946 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt-cdrom.cc,v 1.10 2001/11/13 17:32:08 kojima Exp $ +/* ###################################################################### + + APT CDROM - Tool for handling APT's CDROM database. + + Currently the only option is 'add' which will take the current CD + in the drive and add it into the database. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "rpmindexcopy.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + /*}}}*/ + +#define PACKAGES "pkglist" +#define SOURCES "srclist" + + + +// FindPackages - Find the package files on the CDROM /*{{{*/ +// --------------------------------------------------------------------- +/* We look over the cdrom for package files. This is a recursive + search that short circuits when it his a package file in the dir. + This speeds it up greatly as the majority of the size is in the + binary-* sub dirs. */ +#if 1 +static int strrcmp_(const char *a, const char *b) +{ + int la = strlen(a); + int lb = strlen(b); + + if (la == 0 || lb == 0) + return 0; + + if (la > lb) + return strcmp(&a[la-lb], b); + else + return strcmp(&b[lb-la], a); +} + + +bool FindPackages(string CD,vector &List,vector &SList, + string &InfoDir,unsigned int Depth = 0) +{ + static ino_t Inodes[9]; + if (Depth >= 7) + return true; + + if (CD[CD.length()-1] != '/') + CD += '/'; + + if (chdir(CD.c_str()) != 0) + return _error->Errno("chdir",_("Unable to change to %s"),CD.c_str()); + + // Look for a .disk subdirectory + struct stat Buf; + if (stat(".disk",&Buf) == 0) + { + if (InfoDir.empty() == true) + InfoDir = CD + ".disk/"; + } + + DIR *D = opendir("."); + if (D == 0) + return _error->Errno("opendir",_("Unable to read %s"),CD.c_str()); + + bool found = false; + // Run over the directory + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + // We go through a list of several cases of what this directory entry can be: + // (0) an entry that we skip, (1) a pkglist file, (2) a srclist file, + // (3) another entry that is not a subdirectory. The final case (4) + // is a subdirecory. + // + // When we finish dealing with one of the cases, we 'continue;'. + // Note that if "Thorough" option is set to "false" + // and a list was found in this directory, then case (4) is not a + // special case for us: we skip it just like in case (3) for any other entries + // because we do not have to recurse deeper into subdirectories. + + // case 0 + // Skip some files.. + if (strcmp(Dir->d_name,".") == 0 || + strcmp(Dir->d_name,"..") == 0 || + //strcmp(Dir->d_name,"source") == 0 || + strcmp(Dir->d_name,".disk") == 0 || + strncmp(Dir->d_name,"RPMS", 4) == 0 || + strstr(Dir->d_name,"image") != NULL) + continue; + + // case 1 + if (strncmp(Dir->d_name, "pkglist", sizeof("pkglist")-1) == 0 && + strrcmp_(Dir->d_name, _config->Find("Acquire::ComprExtension").c_str())==0) + { + List.push_back(CD + string(Dir->d_name)); + found = true; + continue; + } + // case 2 + if (strncmp(Dir->d_name, "srclist", sizeof("srclist")-1) == 0 && + strrcmp_(Dir->d_name, _config->Find("Acquire::ComprExtension").c_str())==0) + { + SList.push_back(CD + string(Dir->d_name)); + found = true; + continue; + } + + //choosing between cases 3 and 4 + + // Continue down if thorough is given + if ((_config->FindB("APT::CDROM::Thorough",false) == false) && (found == true)) + continue; + + + // See if the name is a sub directory + struct stat Buf; + if (stat(Dir->d_name,&Buf) != 0) + continue; + + // case 3 + if (S_ISDIR(Buf.st_mode) == 0) + continue; + + // case 4 + unsigned int I; + for (I = 0; I != Depth; I++) + if (Inodes[I] == Buf.st_ino) + break; + if (I != Depth) + continue; + + // Store the inodes weve seen + Inodes[Depth] = Buf.st_ino; + + // Descend + if (FindPackages(CD + Dir->d_name,List,SList,InfoDir,Depth+1) == false) + break; + + if (chdir(CD.c_str()) != 0) + return _error->Errno("chdir",_("Unable to change to %s"),CD.c_str()); + }; + + closedir(D); + + return !_error->PendingError(); +} + +// DropBinaryArch - Dump dirs that contain a file like / /*{{{*/ +// --------------------------------------------------------------------- +/* Here we drop everything that is not this machines arch */ +bool DropBinaryArch(vector &List) +{ + const string arch = _config->Find("Apt::Architecture"); + struct stat buf; + + for (unsigned int I = 0; I < List.size(); I++) + { + const char *Str = List[I].c_str(); + + string prefix = string(List[I], 0, strstr(Str, "base")-Str); + + if (stat(string(prefix+arch).c_str(), &buf) == 0) + continue; + + // Erase it + List.erase(List.begin() + I); + I--; + } + + return true; +} +#else //4 debian +bool FindPackages(string CD,vector &List,vector &SList, + string &InfoDir,unsigned int Depth = 0) +{ + static ino_t Inodes[9]; + if (Depth >= 7) + return true; + + if (CD[CD.length()-1] != '/') + CD += '/'; + + if (chdir(CD.c_str()) != 0) + return _error->Errno("chdir",_("Unable to change to %s"),CD.c_str()); + + // Look for a .disk subdirectory + struct stat Buf; + if (stat(".disk",&Buf) == 0) + { + if (InfoDir.empty() == true) + InfoDir = CD + ".disk/"; + } + + /* Aha! We found some package files. We assume that everything under + this dir is controlled by those package files so we don't look down + anymore */ + if (stat("Packages",&Buf) == 0 || stat("Packages.gz",&Buf) == 0) + { + List.push_back(CD); + + // Continue down if thorough is given + if (_config->FindB("APT::CDROM::Thorough",false) == false) + return true; + } + if (stat("Sources",&Buf) == 0 || stat("Sources.gz",&Buf) == 0) + { + SList.push_back(CD); + + // Continue down if thorough is given + if (_config->FindB("APT::CDROM::Thorough",false) == false) + return true; + } + + DIR *D = opendir("."); + if (D == 0) + return _error->Errno("opendir",_("Unable to read %s"),CD.c_str()); + + // Run over the directory + for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D)) + { + // Skip some files.. + if (strcmp(Dir->d_name,".") == 0 || + strcmp(Dir->d_name,"..") == 0 || + //strcmp(Dir->d_name,"source") == 0 || + strcmp(Dir->d_name,".disk") == 0 || + strcmp(Dir->d_name,"experimental") == 0 || + strcmp(Dir->d_name,"binary-all") == 0) + continue; + + // See if the name is a sub directory + struct stat Buf; + if (stat(Dir->d_name,&Buf) != 0) + continue; + + if (S_ISDIR(Buf.st_mode) == 0) + continue; + + unsigned int I; + for (I = 0; I != Depth; I++) + if (Inodes[I] == Buf.st_ino) + break; + if (I != Depth) + continue; + + // Store the inodes weve seen + Inodes[Depth] = Buf.st_ino; + + // Descend + if (FindPackages(CD + Dir->d_name,List,SList,InfoDir,Depth+1) == false) + break; + + if (chdir(CD.c_str()) != 0) + return _error->Errno("chdir",_("Unable to change to %s"),CD.c_str()); + }; + + closedir(D); + + return !_error->PendingError(); +} + +// DropBinaryArch - Dump dirs with a string like /binary-/ /*{{{*/ +// --------------------------------------------------------------------- +/* Here we drop everything that is not this machines arch */ +bool DropBinaryArch(vector &List) +{ + char S[300]; + sprintf(S,"/binary-%s/",_config->Find("Apt::Architecture").c_str()); + + for (unsigned int I = 0; I < List.size(); I++) + { + const char *Str = List[I].c_str(); + + const char *Res; + if ((Res = strstr(Str,"/binary-")) == 0) + continue; + + // Weird, remove it. + if (strlen(Res) < strlen(S)) + { + List.erase(List.begin() + I); + I--; + continue; + } + + // See if it is our arch + if (stringcmp(Res,Res + strlen(S),S) == 0) + continue; + + // Erase it + List.erase(List.begin() + I); + I--; + } + + return true; +} + /*}}}*/ +// Score - We compute a 'score' for a path /*{{{*/ +// --------------------------------------------------------------------- +/* Paths are scored based on how close they come to what I consider + normal. That is ones that have 'dist' 'stable' 'frozen' will score + higher than ones without. */ +int Score(string Path) +{ + int Res = 0; + if (Path.find("stable/") != string::npos) + Res += 29; + if (Path.find("/binary-") != string::npos) + Res += 20; + if (Path.find("frozen/") != string::npos) + Res += 28; + if (Path.find("unstable/") != string::npos) + Res += 27; + if (Path.find("/dists/") != string::npos) + Res += 40; + if (Path.find("/main/") != string::npos) + Res += 20; + if (Path.find("/contrib/") != string::npos) + Res += 20; + if (Path.find("/non-free/") != string::npos) + Res += 20; + if (Path.find("/non-US/") != string::npos) + Res += 20; + if (Path.find("/source/") != string::npos) + Res += 10; + if (Path.find("/debian/") != string::npos) + Res -= 10; + return Res; +} + /*}}}*/ +// DropRepeats - Drop repeated files resulting from symlinks /*{{{*/ +// --------------------------------------------------------------------- +/* Here we go and stat every file that we found and strip dup inodes. */ +bool DropRepeats(vector &List,const char *Name) +{ + // Get a list of all the inodes + ino_t *Inodes = new ino_t[List.size()]; + for (unsigned int I = 0; I != List.size(); I++) + { + struct stat Buf; + if (stat((List[I] + Name).c_str(),&Buf) != 0 && + stat((List[I] + Name + ".gz").c_str(),&Buf) != 0) + _error->Errno("stat","Failed to stat %s%s",List[I].c_str(), + Name); + Inodes[I] = Buf.st_ino; + } + + if (_error->PendingError() == true) + return false; + + // Look for dups + for (unsigned int I = 0; I != List.size(); I++) + { + for (unsigned int J = I+1; J < List.size(); J++) + { + // No match + if (Inodes[J] != Inodes[I]) + continue; + + // We score the two paths.. and erase one + int ScoreA = Score(List[I]); + int ScoreB = Score(List[J]); + if (ScoreA < ScoreB) + { + List[I] = string(); + break; + } + + List[J] = string(); + } + } + + // Wipe erased entries + for (unsigned int I = 0; I < List.size();) + { + if (List[I].empty() == false) + I++; + else + List.erase(List.begin()+I); + } + + return true; +} +#endif /*}}}*/ /*}}}*/ + +// ReduceSourceList - Takes the path list and reduces it /*{{{*/ +// --------------------------------------------------------------------- +/* This takes the list of source list expressed entires and collects + similar ones to form a single entry for each dist */ +bool ReduceSourcelist(string CD,vector &List) +{ + sort(List.begin(),List.end()); + + // Collect similar entries + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + // Find a space.. + string::size_type Space = (*I).find(' '); + if (Space == string::npos) + continue; + string::size_type SSpace = (*I).find(' ',Space + 1); + if (SSpace == string::npos) + continue; + + string Word1 = string(*I,Space,SSpace-Space); + for (vector::iterator J = List.begin(); J != I; J++) + { + // Find a space.. + string::size_type Space2 = (*J).find(' '); + if (Space2 == string::npos) + continue; + string::size_type SSpace2 = (*J).find(' ',Space2 + 1); + if (SSpace2 == string::npos) + continue; + + if (string(*J,Space2,SSpace2-Space2) != Word1) + continue; + + *J += string(*I,SSpace); + *I = string(); + } + } + + // Wipe erased entries + for (unsigned int I = 0; I < List.size();) + { + if (List[I].empty() == false) + I++; + else + List.erase(List.begin()+I); + } + return true; +} + /*}}}*/ +// WriteDatabase - Write the CDROM Database file /*{{{*/ +// --------------------------------------------------------------------- +/* We rewrite the configuration class associated with the cdrom database. */ +bool WriteDatabase(Configuration &Cnf) +{ + string DFile = _config->FindFile("Dir::State::cdroms"); + string NewFile = DFile + ".new"; + + unlink(NewFile.c_str()); + ofstream Out(NewFile.c_str()); + if (!Out) + return _error->Errno("ofstream::ofstream", + _("Failed to open %s.new"),DFile.c_str()); + + /* Write out all of the configuration directives by walking the + configuration tree */ + const Configuration::Item *Top = Cnf.Tree(0); + for (; Top != 0;) + { + // Print the config entry + if (Top->Value.empty() == false) + Out << Top->FullTag() + " \"" << Top->Value << "\";" << endl; + + if (Top->Child != 0) + { + Top = Top->Child; + continue; + } + + while (Top != 0 && Top->Next == 0) + Top = Top->Parent; + if (Top != 0) + Top = Top->Next; + } + + Out.close(); + + rename(DFile.c_str(),string(DFile + '~').c_str()); + if (rename(NewFile.c_str(),DFile.c_str()) != 0) + return _error->Errno("rename",_("Failed to rename %s.new to %s"), + DFile.c_str(),DFile.c_str()); + + return true; +} + /*}}}*/ +// WriteSourceList - Write an updated sourcelist /*{{{*/ +// --------------------------------------------------------------------- +/* This reads the old source list and copies it into the new one. It + appends the new CDROM entires just after the first block of comments. + This places them first in the file. It also removes any old entries + that were the same. */ +bool WriteSourceList(string Name,vector &List,bool Source) +{ + if (List.size() == 0) + return true; + + string File = _config->FindFile("Dir::Etc::sourcelist"); + + // Open the stream for reading + ifstream F(File.c_str(),ios::in | ios::nocreate); + if (!F != 0) + return _error->Errno("ifstream::ifstream","Opening %s",File.c_str()); + + string NewFile = File + ".new"; + unlink(NewFile.c_str()); + ofstream Out(NewFile.c_str()); + if (!Out) + return _error->Errno("ofstream::ofstream", + _("Failed to open %s.new"),File.c_str()); + + // Create a short uri without the path + string ShortURI = "cdrom:[" + Name + "]/"; + string ShortURI2 = "cdrom:" + Name + "/"; // For Compatibility + + const char *Type; + if (0) + {//akk + if (Source == true) + Type = "deb-src"; + else + Type = "deb"; + } + else + { + if (Source == true) + Type = "rpm-src"; + else + Type = "rpm"; + } + + char Buffer[300]; + int CurLine = 0; + bool First = true; + while (F.eof() == false) + { + F.getline(Buffer,sizeof(Buffer)); + CurLine++; + _strtabexpand(Buffer,sizeof(Buffer)); + _strstrip(Buffer); + + // Comment or blank + if (Buffer[0] == '#' || Buffer[0] == 0) + { + Out << Buffer << endl; + continue; + } + + if (First == true) + { + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + string::size_type Space = (*I).find(' '); + if (Space == string::npos) + return _error->Error(_("Internal error")); + Out << Type << " cdrom:[" << Name << "]/" << string(*I,0,Space) << + " " << string(*I,Space+1) << endl; + } + } + First = false; + + // Grok it + string cType; + string URI; + const char *C = Buffer; + if (ParseQuoteWord(C,cType) == false || + ParseQuoteWord(C,URI) == false) + { + Out << Buffer << endl; + continue; + } + + // Emit lines like this one + if (cType != Type || (string(URI,0,ShortURI.length()) != ShortURI && + string(URI,0,ShortURI.length()) != ShortURI2)) + { + Out << Buffer << endl; + continue; + } + } + + // Just in case the file was empty + if (First == true) + { + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + string::size_type Space = (*I).find(' '); + if (Space == string::npos) + return _error->Error(_("Internal error")); + + Out << Type << " cdrom:[" << Name << "]/" << string(*I,0,Space) << + " " << string(*I,Space+1) << endl; + } + } + + Out.close(); + + rename(File.c_str(),string(File + '~').c_str()); + if (rename(NewFile.c_str(),File.c_str()) != 0) + return _error->Errno("rename",_("Failed to rename %s.new to %s"), + File.c_str(),File.c_str()); + + return true; +} + /*}}}*/ + +// Prompt - Simple prompt /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Prompt(const char *Text) +{ + char C; + cout << Text << ' ' << flush; + read(STDIN_FILENO,&C,1); + if (C != '\n') + cout << endl; +} + /*}}}*/ +// PromptLine - Prompt for an input line /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string PromptLine(const char *Text) +{ + cout << Text << ':' << endl; + + string Res; + getline(cin,Res); + return Res; +} + /*}}}*/ + +// DoAdd - Add a new CDROM /*{{{*/ +// --------------------------------------------------------------------- +/* This does the main add bit.. We show some status and things. The + sequence is to mount/umount the CD, Ident it then scan it for package + files and reduce that list. Then we copy over the package files and + verify them. Then rewrite the database files */ +bool DoAdd(CommandLine &) +{ + // Startup + string CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); + if (CDROM[0] == '.') + CDROM= SafeGetCWD() + '/' + CDROM; + + cout << _("Using CD-ROM mount point ") << CDROM << endl; + + // Read the database + Configuration Database; + string DFile = _config->FindFile("Dir::State::cdroms"); + if (FileExists(DFile) == true) + { + if (ReadConfigFile(Database,DFile) == false) + return _error->Error(_("Unable to read the cdrom database %s"), + DFile.c_str()); + } + + // Unmount the CD and get the user to put in the one they want + if (_config->FindB("APT::CDROM::NoMount",false) == false) + { + cout << _("Unmounting CD-ROM") << endl; + UnmountCdrom(CDROM); + + // Mount the new CDROM + Prompt(_("Please insert a Disc in the drive and press enter")); + cout << _("Mounting CD-ROM") << endl; + if (MountCdrom(CDROM) == false) + return _error->Error(_("Failed to mount the cdrom.")); + } + + // Hash the CD to get an ID + cout << _("Identifying.. ") << flush; + string ID; + if (IdentCdrom(CDROM,ID) == false) + { + cout << endl; + return false; + } + + cout << '[' << ID << ']' << endl; + + cout << _("Scanning Disc for index files.. ") << flush; + // Get the CD structure + vector List; + vector sList; + string StartDir = SafeGetCWD(); + string InfoDir; + if (FindPackages(CDROM,List,sList,InfoDir) == false) + { + cout << endl; + return false; + } + + chdir(StartDir.c_str()); + + if (_config->FindB("Debug::aptcdrom",false) == true) + { + cout << _("I found (binary):") << endl; + for (vector::iterator I = List.begin(); I != List.end(); I++) + cout << *I << endl; + cout << _("I found (source):") << endl; + for (vector::iterator I = sList.begin(); I != sList.end(); I++) + cout << *I << endl; + } + + // Fix up the list +// DropBinaryArch(List); + +#if 0 + //akk + DropRepeats(List,"Packages"); + DropRepeats(sList,"Sources"); +#endif + cout << _("Found ") << List.size() << _(" package indexes and ") << sList.size() << + _(" source indexes.") << endl; + + if (List.size() == 0 && sList.size() == 0) + { + if (0) + return _error->Error(_("Unable to locate any package files, perhaps this is not a Debian Disc")); + else + return _error->Error(_("Unable to locate any package files, perhaps this is not a Conectiva Disc")); + } + // Check if the CD is in the database + string Name; + if (Database.Exists("CD::" + ID) == false || + _config->FindB("APT::CDROM::Rename",false) == true) + { + // Try to use the CDs label if at all possible + if (InfoDir.empty() == false && + FileExists(InfoDir + "/info") == true) + { + ifstream F(string(InfoDir + "/info").c_str()); + if (!F == 0) + getline(F,Name); + + if (Name.empty() == false) + { + cout << _("Found label '") << Name << "'" << endl; + Database.Set("CD::" + ID + "::Label",Name); + } + } + + if (_config->FindB("APT::CDROM::Rename",false) == true || + Name.empty() == true) + { + cout << _("Please provide a name for this Disc, such as 'MyDistro 6.0 Disk 1'"); + + while (1) + { + Name = PromptLine(""); + if (Name.empty() == false && + Name.find('"') == string::npos && + Name.find('[') == string::npos && + Name.find(']') == string::npos) + break; + cout << _("That is not a valid name, try again ") << endl; + } + } + } + else + Name = Database.Find("CD::" + ID); + + // Escape special characters + string::iterator J = Name.begin(); + for (; J != Name.end(); J++) + if (*J == '"' || *J == ']' || *J == '[') + *J = '_'; + + Database.Set("CD::" + ID,Name); + cout << _("This Disc is called:") << endl << " '" << Name << "'" << endl; + + // Copy the package files to the state directory + RPMPackageCopy Copy; + RPMSourceCopy SrcCopy; + + if (Copy.CopyPackages(CDROM,Name,List) == false || + SrcCopy.CopyPackages(CDROM,Name,sList) == false) + return false; + + ReduceSourcelist(CDROM,List); + ReduceSourcelist(CDROM,sList); + + // Write the database and sourcelist + if (_config->FindB("APT::cdrom::NoAct",false) == false) + { + if (WriteDatabase(Database) == false) + return false; + + cout << _("Writing new source list") << endl; + if (WriteSourceList(Name,List,false) == false || + WriteSourceList(Name,sList,true) == false) + return false; + } + + // Print the sourcelist entries + cout << _("Source List entries for this Disc are:") << endl; + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + string::size_type Space = (*I).find(' '); + if (Space == string::npos) + return _error->Error(_("Internal error")); + + if (0) + {//akk + cout << "deb cdrom:[" << Name << "]/" << string(*I,0,Space) << + " " << string(*I,Space+1) << endl; + } + else + { + cout << "rpm cdrom:[" << Name << "]/" << string(*I,0,Space) << + " " << string(*I,Space+1) << endl; + } + } + + for (vector::iterator I = sList.begin(); I != sList.end(); I++) + { + string::size_type Space = (*I).find(' '); + if (Space == string::npos) + return _error->Error(_("Internal error")); + + if (0) + {//akk + cout << "deb-src cdrom:[" << Name << "]/" << string(*I,0,Space) << + " " << string(*I,Space+1) << endl; + } + else + { + cout << "rpm-src cdrom:[" << Name << "]/" << string(*I,0,Space) << + " " << string(*I,Space+1) << endl; + } + } + + cout << _("Repeat this process for the rest of the CDs in your set.") << endl; + + // Unmount and finish + if (_config->FindB("APT::CDROM::NoMount",false) == false) + UnmountCdrom(CDROM); + + return true; +} + /*}}}*/ + +// ShowHelp - Show the help screen /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int ShowHelp() +{ + cout << PACKAGE << ' ' << VERSION << " for " << COMMON_CPU << + " compiled on " << __DATE__ << " " << __TIME__ << endl; + if (_config->FindB("version") == true) + return 100; + + cout << _("Usage: apt-cdrom [options] command") << endl; + cout << endl; + cout << _("apt-cdrom is a tool to add CDROM's to APT's source list. The ") << endl; + cout << _("CDROM mount point and device information is taken from apt.conf") << endl; + cout << _("and /etc/fstab.") << endl; + cout << endl; + cout << _("Commands:") << endl; + cout << _(" add - Add a CDROM") << endl; + cout << endl; + cout << _("Options:") << endl; + cout << _(" -h This help text") << endl; + cout << _(" -d CD-ROM mount point") << endl; + cout << _(" -r Rename a recognized CD-ROM") << endl; + cout << _(" -m No mounting") << endl; + cout << _(" -f Fast mode, don't check package files") << endl; + cout << _(" -a Thorough scan mode") << endl; + cout << _(" -c=? Read this configuration file") << endl; + cout << _(" -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp") << endl; + cout << _("See fstab(5)") << endl; + return 100; +} + /*}}}*/ + +int main(int argc,const char *argv[]) +{ + CommandLine::Args Args[] = { + {'h',"help","help",0}, + {'v',"version","version",0}, + {'d',"cdrom","Acquire::cdrom::mount",CommandLine::HasArg}, + {'r',"rename","APT::CDROM::Rename",0}, + {'m',"no-mount","APT::CDROM::NoMount",0}, + {'f',"fast","APT::CDROM::Fast",0}, + {'n',"just-print","APT::CDROM::NoAct",0}, + {'n',"recon","APT::CDROM::NoAct",0}, + {'n',"no-act","APT::CDROM::NoAct",0}, + {'a',"thorough","APT::CDROM::Thorough",0}, + {'c',"config-file",0,CommandLine::ConfigFile}, + {'o',"option",0,CommandLine::ArbItem}, + {0,0,0,0}}; + CommandLine::Dispatch Cmds[] = { + {"add",&DoAdd}, + {0,0}}; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + // Parse the command line and initialize the package library + CommandLine CmdL(Args,_config); + if (pkgInitialize(*_config) == false || + CmdL.Parse(argc,argv) == false) + { + _error->DumpErrors(); + return 100; + } + + // See if the help should be shown + if (_config->FindB("help") == true || _config->FindB("version") == true || + CmdL.FileSize() == 0) + return ShowHelp(); + + // Deal with stdout not being a tty + if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1) + _config->Set("quiet","1"); + + // Match the operation + CmdL.DispatchArg(Cmds); + + // Print any errors or warnings found during parsing + if (_error->empty() == false) + { + bool Errors = _error->PendingError(); + _error->DumpErrors(); + return Errors == true?100:0; + } + + return 0; +} diff --git a/apt/cmdline/apt-config.cc b/apt/cmdline/apt-config.cc new file mode 100644 index 0000000..23f7476 --- /dev/null +++ b/apt/cmdline/apt-config.cc @@ -0,0 +1,133 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt-config.cc,v 1.3 2001/08/01 21:57:05 kojima Exp $ +/* ###################################################################### + + APT Config - Program to manipulate APT configuration files + + This program will parse a config file and then do something with it. + + Commands: + shell - Shell mode. After this a series of word pairs should occure. + The first is the environment var to set and the second is + the key to set it from. Use like: + eval `apt-config shell QMode apt::QMode` + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include "config.h" + +#include + +#include + /*}}}*/ + +// DoShell - Handle the shell command /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DoShell(CommandLine &CmdL) +{ + for (const char **I = CmdL.FileList + 1; *I != 0; I += 2) + { + if (I[1] == 0 || strlen(I[1]) == 0) + return _error->Error(_("Arguments not in pairs")); + + // Check if the caller has requested a directory path + if (I[1][strlen(I[1])-1] == '/') + { + char S[300]; + strcpy(S,I[1]); + S[strlen(S)-1] = 0; + if (_config->Exists(S) == true) + cout << *I << "=\"" << _config->FindDir(S) << '"' << endl; + } + + if (_config->Exists(I[1]) == true) + cout << *I << "=\"" << _config->Find(I[1]) << '"' << endl; + } + + return true; +} + /*}}}*/ +// DoDump - Dump the configuration space /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DoDump(CommandLine &CmdL) +{ + _config->Dump(); + return true; +} + /*}}}*/ +// ShowHelp - Show the help screen /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int ShowHelp() +{ + cout << PACKAGE << ' ' << VERSION << " for " << COMMON_CPU << + " compiled on " << __DATE__ << " " << __TIME__ << endl; + if (_config->FindB("version") == true) + return 100; + + cout << _("Usage: apt-config [options] command") << endl; + cout << endl; + cout << _("apt-config is a simple tool to read the APT config file") << endl; + cout << endl; + cout << _("Commands:") << endl; + cout << _(" shell - Shell mode") << endl; + cout << _(" dump - Show the configuration") << endl; + cout << endl; + cout << _("Options:") << endl; + cout << _(" -h This help text.") << endl; + cout << _(" -c=? Read this configuration file") << endl; + cout << _(" -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp") << endl; + return 100; +} + /*}}}*/ + +int main(int argc,const char *argv[]) +{ + CommandLine::Args Args[] = { + {'h',"help","help",0}, + {'v',"version","version",0}, + {'c',"config-file",0,CommandLine::ConfigFile}, + {'o',"option",0,CommandLine::ArbItem}, + {0,0,0,0}}; + CommandLine::Dispatch Cmds[] = {{"shell",&DoShell}, + {"dump",&DoDump}, + {0,0}}; + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + // Parse the command line and initialize the package library + CommandLine CmdL(Args,_config); + if (pkgInitialize(*_config) == false || + CmdL.Parse(argc,argv) == false) + { + _error->DumpErrors(); + return 100; + } + + // See if the help should be shown + if (_config->FindB("help") == true || + CmdL.FileSize() == 0) + return ShowHelp(); + + // Match the operation + CmdL.DispatchArg(Cmds); + + // Print any errors or warnings found during parsing + if (_error->empty() == false) + { + bool Errors = _error->PendingError(); + _error->DumpErrors(); + return Errors == true?100:0; + } + + return 0; +} diff --git a/apt/cmdline/apt-get.cc b/apt/cmdline/apt-get.cc new file mode 100644 index 0000000..670bccd --- /dev/null +++ b/apt/cmdline/apt-get.cc @@ -0,0 +1,2115 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: apt-get.cc,v 1.45 2001/11/13 18:00:07 kojima Exp $ +/* ###################################################################### + + apt-get - Cover for dpkg and rpm + + This is an allout cover for dpkg implementing a safer front end. It is + based largely on libapt-pkg. + + The syntax is different, + apt-get [opt] command [things] + Where command is: + update - Resyncronize the package files from their sources + upgrade - Smart-Download the newest versions of all packages + dselect-upgrade - Follows dselect's changes to the Status: field + and installes new and removes old packages + dist-upgrade - Powerfull upgrader designed to handle the issues with + a new distribution. + install - Download and install a given package (by name, not by .deb) + check - Update the package cache and check for broken packages + clean - Erase the .debs downloaded to /var/cache/apt/archives and + the partial dir too + + ##################################################################### + */ + +//#define DEBUG + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + + +#ifdef DEBUG +#include +#endif + +#include + +#include + +#include "acqprogress.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + /*}}}*/ + + +ostream c0out; +ostream c1out; +ostream c2out; +ofstream devnull("/dev/null"); +unsigned int ScreenWidth = 80; + +// class CacheFile - Cover class for some dependency cache functions /*{{{*/ +// --------------------------------------------------------------------- +/* */ +class CacheFile : public pkgCacheFile +{ + static pkgCache *SortCache; + static int NameComp(const void *a,const void *b); + + public: + pkgCache::Package **List; + + void Sort(); + bool CheckDeps(bool AllowBroken = false); + bool Open(bool WithLock = true) + { + OpTextProgress Prog(*_config); + + if (pkgCacheFile::Open(Prog,WithLock) == false) + return false; + Sort(); + return true; + }; + +#if 1 + Header header; +#endif + bool LoadRecord(pkgCache::VerIterator V); + const char *GetPriority(); + const char *GetSummary(); + const char *GetDate(); + + CacheFile() : List(0), header(0) {}; +}; + /*}}}*/ + +// YnPrompt - Yes No Prompt. /*{{{*/ +// --------------------------------------------------------------------- +/* Returns true on a Yes.*/ +bool YnPrompt() +{ + if (_config->FindB("APT::Get::Assume-Yes",false) == true) + { + c1out << 'Y' << endl; + return true; + } + + char C = 0; + char Jnk = 0; + read(STDIN_FILENO,&C,1); + while (C != '\n' && Jnk != '\n') read(STDIN_FILENO,&Jnk,1); + + /* Yes/No */ + if (!(C == *_("Y") || C == *_("y") || C == '\n' || C == '\r')) + return false; + return true; +} + /*}}}*/ +// AnalPrompt - Annoying Yes No Prompt. /*{{{*/ +// --------------------------------------------------------------------- +/* Returns true on a Yes.*/ +bool AnalPrompt(const char *Text) +{ + char Buf[1024]; + cin.getline(Buf,sizeof(Buf)); + if (strcmp(Buf,Text) == 0) + return true; + return false; +} + /*}}}*/ +// ShowList - Show a list /*{{{*/ +// --------------------------------------------------------------------- +/* This prints out a string of space seperated words with a title and + a two space indent line wraped to the current screen width. */ +bool ShowList(ostream &out,string Title,string List) +{ + if (List.empty() == true) + return true; + + // Acount for the leading space + int ScreenWidth = ::ScreenWidth - 3; + + out << Title << endl; + string::size_type Start = 0; + while (Start < List.size()) + { + string::size_type End; + if (Start + ScreenWidth >= List.size()) + End = List.size(); + else + End = List.rfind(' ',Start+ScreenWidth); + + if (End == string::npos || End < Start) + End = Start + ScreenWidth; + out << " " << string(List,Start,End - Start) << endl; + Start = End + 1; + } + return false; +} + /*}}}*/ + + +void ShowText(ostream &out, const char *text) +{ + const char *begin = text; + const char *end = text; + + while (*begin) + { + const char *p; + + p = begin; + while (1) + { + p++; + if (*p == '\n') + { + end = p+1; + break; + } + else if (*p == '\0') + { + end = p; + break; + } + } + out << " " << string(begin, end); + begin = end; + } + out << endl; +} + +// ShowBroken - Debugging aide /*{{{*/ +// --------------------------------------------------------------------- +/* This prints out the names of all the packages that are broken along + with the name of each each broken dependency and a quite version + description. */ +void ShowBroken(ostream &out,CacheFile &Cache,bool Now) +{ + out << _("Sorry, but the following packages have unmet dependencies:") << endl; + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + + if (Cache[I].InstBroken() == false) + continue; + + // Print out each package and the failed dependencies + out <<" " << I.Name() << ":"; + unsigned Indent = strlen(I.Name()) + 3; + bool First = true; + if (Cache[I].InstVerIter(Cache).end() == true) + { + cout << endl; + continue; + } + + for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); D.end() == false;) + { + // Compute a single dependency element (glob or) + pkgCache::DepIterator Start; + pkgCache::DepIterator End; + D.GlobOr(Start,End); + + if (Cache->IsImportantDep(End) == false || + (Cache[End] & pkgDepCache::DepGInstall) == pkgDepCache::DepGInstall) + { + continue; + } + + bool FirstOr = true; + while (1) + { + if (First == false) + for (unsigned J = 0; J != Indent; J++) + out << ' '; + First = false; + + if (FirstOr == false) + { + for (unsigned J = 0; J != strlen(End.DepType()) + 3; J++) + out << ' '; + } + else + out << ' ' << End.DepType() << ": "; + FirstOr = false; + + out << Start.TargetPkg().Name(); + + // Show a quick summary of the version requirements + if (Start.TargetVer() != 0) + out << " (" << Start.CompType() << " " << Start.TargetVer() << + ")"; + + /* Show a summary of the target package if possible. In the case + of virtual packages we show nothing */ + pkgCache::PkgIterator Targ = Start.TargetPkg(); + if (Targ->ProvidesList == 0) + { + out << _(" but "); + pkgCache::VerIterator Ver = Cache[Targ].InstVerIter(Cache); + if (Ver.end() == false) + out << Ver.VerStr() << (Now?_(" is installed"):_(" is to be installed")); + else + { + if (Cache[Targ].CandidateVerIter(Cache).end() == true) + { + if (Targ->ProvidesList == 0) + out << _("it is not installable"); + else + out << _("it is a virtual package"); + } + else + out << (Now?_("it is not installed"):_("it is not going to be installed")); + } + } + + if (Start != End) + cout << _(" or"); + out << endl; + + if (Start == End) + break; + Start++; + } + } + } +} + /*}}}*/ +// ShowNew - Show packages to newly install /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ShowNew(ostream &out,CacheFile &Cache) +{ + /* Print out a list of packages that are going to be removed extra + to what the user asked */ + string List; + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + if (Cache[I].NewInstall() == true) + List += string(I.Name()) + " "; + } + + ShowList(out,_("The following NEW packages will be installed:"),List); +} + /*}}}*/ +// ShowDel - Show packages to delete /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ShowDel(ostream &out,CacheFile &Cache) +{ + /* Print out a list of packages that are going to be removed extra + to what the user asked */ + string ListReplaced, ListRemoved; + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + if (Cache[I].Delete() == true) + { + const char *suffix; + if ((Cache[I].iFlags & pkgDepCache::Purge) == pkgDepCache::Purge) + suffix = "* "; + else + suffix = " "; + if (Cache[I].Replaced()) + ListReplaced += string(I.Name()) + suffix; + else + ListRemoved += string(I.Name()) + suffix; + } + } + + ShowList( out, _("The following packages will be REPLACED:"), ListReplaced ); + ShowList( out, _("The following packages will be REMOVED:"), ListRemoved ); +} + /*}}}*/ +// ShowKept - Show kept packages /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ShowKept(ostream &out,CacheFile &Cache) +{ + string List; + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + + // Not interesting + if (Cache[I].Upgrade() == true || Cache[I].Upgradable() == false || + I->CurrentVer == 0 || Cache[I].Delete() == true) + continue; + + List += string(I.Name()) + " "; + } + ShowList(out,_("The following packages have been kept back"),List); +} + /*}}}*/ +// ShowUpgraded - Show upgraded packages /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ShowUpgraded(ostream &out,CacheFile &Cache) +{ + string List; + + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + + // Not interesting + if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) + continue; + + List += string(I.Name()) + " "; + } + ShowList(out,_("The following packages will be upgraded"),List); +} + /*}}}*/ +// ShowUpgradeSummary - Show upgraded packages with detailed summary /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ShowUpgradeSummary(ostream &out,CacheFile &Cache) +{ + string List; + bool first = true; + + + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + const char *prio = NULL; + const char *summ = NULL; + const char *date = NULL; + + // Not interesting + if (Cache[I].Upgrade() == false || Cache[I].NewInstall() == true) + continue; + + if (Cache.LoadRecord(Cache[I].InstVerIter(Cache))) + { + prio = Cache.GetPriority(); + summ = Cache.GetSummary(); + date = Cache.GetDate(); + } + + if (first) + { + out << _("The following packages can be upgraded:") << endl; + first = false; + } + + if (!prio) + prio = "?"; + if (!date) + date = "?"; + + out << endl << I.Name(); + if (I.CurrentVer() != 0) + out << _(" from ") << I.CurrentVer().VerStr(); + out << _(" to ") << Cache[I].InstVerIter(Cache).VerStr() << endl; + + out << _(" Importance: ") << prio << " "; + out << _(" Date: ") << date << endl; + if (summ) + ShowText(out, summ); + } +} + /*}}}*/ +// ShowHold - Show held but changed packages /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ShowHold(ostream &out,CacheFile &Cache) +{ + string List; + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + if (Cache[I].InstallVer != (pkgCache::Version *)I.CurrentVer() && + I->SelectedState == pkgCache::State::Hold) + List += string(I.Name()) + " "; + } + + return ShowList(out,_("The following held packages will be changed:"),List); +} + /*}}}*/ +// ShowEssential - Show an essential package warning /*{{{*/ +// --------------------------------------------------------------------- +/* This prints out a warning message that is not to be ignored. It shows + all essential packages and their dependents that are to be removed. + It is insanely risky to remove the dependents of an essential package! */ +bool ShowEssential(ostream &out,CacheFile &Cache) +{ + string List; + bool *Added = new bool[Cache->HeaderP->PackageCount]; + for (unsigned int I = 0; I != Cache->HeaderP->PackageCount; I++) + Added[I] = false; + + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + if ((I->Flags & pkgCache::Flag::Essential) != pkgCache::Flag::Essential) + continue; + + // The essential package is being removed + if (Cache[I].Delete() == true) + { + if (Added[I->ID] == false) + { + Added[I->ID] = true; + List += string(I.Name()) + " "; + } + } + + if (I->CurrentVer == 0) + continue; + + // Print out any essential package depenendents that are to be removed + // and won't be replaced by something new + for (pkgDepCache::DepIterator D = I.CurrentVer().DependsList(); D.end() == false; D++) + { + // Skip everything but depends + if (D->Type != pkgCache::Dep::PreDepends && + D->Type != pkgCache::Dep::Depends) + continue; + + pkgCache::Version **Targets = D.AllTargets(); + + bool Broke = true; + + while (Targets != 0 && *Targets != 0) + { + pkgCache::PkgIterator P = pkgCache::VerIterator(*Cache,*Targets).ParentPkg(); + + if (Cache[P].Install() == true || + (P->CurrentVer != 0 && Cache[P].Delete() == false)) + { + Broke = false; + break; + } + Targets++; + } + if (Broke == true) + { + pkgCache::PkgIterator P = D.SmartTargetPkg(); + if (Added[P->ID] == true) + continue; + Added[P->ID] = true; + + char S[300]; + sprintf(S,_("%s (due to %s) "),P.Name(),I.Name()); + List += S; + } + } + } + + delete [] Added; + if (List.empty() == false) + out << _("WARNING: The following essential packages will be removed") << endl; + return ShowList(out,_("This should NOT be done unless you know exactly what you are doing!"),List); +} + /*}}}*/ +// Stats - Show some statistics /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void Stats(ostream &out,pkgDepCache &Dep) +{ + unsigned long Upgrade = 0; + unsigned long Install = 0; + unsigned long ReInstall = 0; + for (pkgCache::PkgIterator I = Dep.PkgBegin(); I.end() == false; I++) + { + if (Dep[I].NewInstall() == true) + Install++; + else + if (Dep[I].Upgrade() == true) + Upgrade++; + if (Dep[I].Delete() == false && (Dep[I].iFlags & pkgDepCache::ReInstall) == pkgDepCache::ReInstall) + ReInstall++; + } + + out << Upgrade << _(" packages upgraded, ") << + Install << _(" newly installed, "); + if (ReInstall != 0) + out << ReInstall << _(" reinstalled, "); + out << Dep.DelCount() << _(" to remove(replace) and ") << + Dep.KeepCount() << _(" not upgraded.") << endl; + + if (Dep.BadCount() != 0) + out << Dep.BadCount() << _(" packages not fully installed or removed.") << endl; +} + /*}}}*/ + +bool CacheFile::LoadRecord(pkgCache::VerIterator V) +{ + pkgCache::VerFileIterator Vf = V.FileList(); + for (; Vf.end() == false; Vf++) + if ((Vf.File()->Flags & pkgCache::Flag::NotSource) == 0) + break; + if (Vf.end() == true) + Vf = V.FileList(); + + // Check and load the package list file + pkgCache::PkgFileIterator I = Vf.File(); + if (I.IsOk() == false) + return _error->Error(_("Package file %s is out of sync."),I.FileName()); + + FileFd PkgF(I.FileName(),FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + + // Read the record and then write it out again. + if (PkgF.Seek(V.FileList()->Offset) == false) + return false; + + if (header) + headerFree(header); + + FD_t fdt = fdDup(PkgF.Fd()); + header = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + + return true; +} + + +const char *CacheFile::GetDate() +{ + const char *s = NULL; + + if (header) + { + int type, count; + + headerGetEntry(header, CRPMTAG_UPDATE_DATE, &type, (void **)&s, &count); + } + return s; +} + + +const char *CacheFile::GetPriority() +{ + const char *s = NULL; + + if (header) + { + int type, count; + + headerGetEntry(header, CRPMTAG_UPDATE_IMPORTANCE, &type, (void **)&s, &count); + } + return s; +} + + +const char *CacheFile::GetSummary() +{ + const char *s = NULL; + + if (header) + { + int type, count; + + headerGetEntry(header, CRPMTAG_UPDATE_SUMMARY, &type, (void **)&s, &count); + } + return s; +} + +// CacheFile::NameComp - QSort compare by name /*{{{*/ +// --------------------------------------------------------------------- +/* */ +pkgCache *CacheFile::SortCache = 0; +int CacheFile::NameComp(const void *a,const void *b) +{ + if (*(pkgCache::Package **)a == 0 || *(pkgCache::Package **)b == 0) + return *(pkgCache::Package **)a - *(pkgCache::Package **)b; + + const pkgCache::Package &A = **(pkgCache::Package **)a; + const pkgCache::Package &B = **(pkgCache::Package **)b; + + return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name); +} + /*}}}*/ +// CacheFile::Sort - Sort by name /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void CacheFile::Sort() +{ + delete [] List; + List = new pkgCache::Package *[Cache->Head().PackageCount]; + memset(List,0,sizeof(*List)*Cache->Head().PackageCount); + pkgCache::PkgIterator I = Cache->PkgBegin(); + for (;I.end() != true; I++) + List[I->ID] = I; + + SortCache = *this; + qsort(List,Cache->Head().PackageCount,sizeof(*List),NameComp); +} + /*}}}*/ +// CacheFile::Open - Open the cache file /*{{{*/ +// --------------------------------------------------------------------- +/* This routine generates the caches and then opens the dependency cache + and verifies that the system is OK. */ +bool CacheFile::CheckDeps(bool AllowBroken) +{ + if (_error->PendingError() == true) + return false; + + // Check that the system is OK + if (Cache->DelCount() != 0 || Cache->InstCount() != 0) + return _error->Error("Internal Error, non-zero counts"); + + // Apply corrections for half-installed packages + if (pkgApplyStatus(*Cache) == false) + return false; + + // Nothing is broken + if (Cache->BrokenCount() == 0 || AllowBroken == true) + return true; + + // Attempt to fix broken things + if (_config->FindB("APT::Get::Fix-Broken",false) == true) + { + c1out << _("Correcting dependencies...") << flush; + if (pkgFixBroken(*Cache) == false || Cache->BrokenCount() != 0) + { + c1out << _(" failed.") << endl; + ShowBroken(c1out,*this,true); + + return _error->Error(_("Unable to correct dependencies")); + } + if (pkgMinimizeUpgrade(*Cache) == false) + return _error->Error(_("Unable to minimize the upgrade set")); + + c1out << _(" Done") << endl; + } + else + { + c1out << _("You might want to run `apt-get -f install' to correct these.") << endl; + ShowBroken(c1out,*this,true); + + return _error->Error(_("Unmet dependencies. Try using -f.")); + } + + return true; +} + /*}}}*/ + +// InstallPackages - Actually download and install the packages /*{{{*/ +// --------------------------------------------------------------------- +/* This displays the informative messages describing what is going to + happen and then calls the download routines */ +bool InstallPackages(CacheFile &Cache,bool ShwKept,bool Ask = true, + bool Saftey = true) +{ + pkgPackageManager *PM; + + if (_config->FindB("APT::Get::Purge",false) == true) + { + pkgCache::PkgIterator I = Cache->PkgBegin(); + for (; I.end() == false; I++) + { + if (I.Purge() == false && Cache[I].Delete()) + Cache->MarkDelete( I, Cache[I].Replaced(), true ); + } + } + + bool Fail = false; + bool Essential = false; + + // Show all the various warning indicators + ShowDel(c1out,Cache); + ShowNew(c1out,Cache); + if (ShwKept == true) + ShowKept(c1out,Cache); + Fail |= !ShowHold(c1out,Cache); + + if (_config->FindB("APT::Get::Show-Upgrade-Summary",false) == true) { + ShowUpgradeSummary(c1out,Cache); + } else if (_config->FindB("APT::Get::Show-Upgraded",false) == true) { + ShowUpgraded(c1out,Cache); + } + Essential = !ShowEssential(c1out,Cache); + Fail |= Essential; + Stats(c1out,Cache); + + if (_config->FindB("APT::Get::Show-Upgrade-Summary",false) == true) { + return true; + } + + // Sanity check + if (Cache->BrokenCount() != 0) + { + ShowBroken(c1out,Cache,false); + return _error->Error(_("Internal Error, InstallPackages was called with broken packages!")); + } + + if (Cache->DelCount() == 0 && Cache->InstCount() == 0 && + Cache->BadCount() == 0) + return true; + + // No remove flag + if (Cache->DelCount() != 0 && _config->FindB("APT::Get::No-Remove",false) == true) + return _error->Error(_("Packages need to be removed but No Remove was specified.")); + + // Run the simulator .. + if (_config->FindB("APT::Get::Simulate") == true) + { + pkgSimulate PM(Cache); + pkgPackageManager::OrderResult Res = PM.DoInstall(); + if (Res == pkgPackageManager::Failed) + return false; + if (Res != pkgPackageManager::Completed) + return _error->Error(_("Internal Error, Ordering didn't finish")); + return true; + } + + // Create the text record parser + pkgRecords Recs(Cache); + if (_error->PendingError() == true) + return false; + + // Lock the archive directory + FileFd Lock; + if (_config->FindB("Debug::NoLocking",false) == false) + { + Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); + if (_error->PendingError() == true) + return _error->Error(_("Unable to lock the download directory")); + } + + // Create the download object + AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); + pkgAcquire Fetcher(&Stat); + + // Read the source list + pkgSourceList List; + if (List.ReadMainList() == false) + return _error->Error(_("The list of sources could not be read.")); + + // Create the package manager and prepare to download + + PM = _system->CreatePackageManager(Cache); + + if (PM->GetArchives(&Fetcher,&List,&Recs) == false || + _error->PendingError() == true) + return false; + + // Display statistics + unsigned long FetchBytes = Fetcher.FetchNeeded(); + unsigned long FetchPBytes = Fetcher.PartialPresent(); + unsigned long DebBytes = Fetcher.TotalNeeded(); + if (DebBytes != Cache->DebSize()) + { + c0out << DebBytes << ',' << Cache->DebSize() << endl; + c0out << _("How odd.. The sizes didn't match, email apt@packages.debian.org") << endl; + } + + // Number of bytes + c1out << _("Need to get "); + if (DebBytes != FetchBytes) + c1out << SizeToStr(FetchBytes) << "B/" << SizeToStr(DebBytes) << 'B'; + else + c1out << SizeToStr(DebBytes) << 'B'; + + c1out << _(" of archives. After unpacking "); + + // Size delta + if (Cache->UsrSize() > 0) + c1out << SizeToStr(Cache->UsrSize()) << _("B will be used."); + else if (Cache->UsrSize() < 0) + c1out << SizeToStr(-1*Cache->UsrSize()) << _("B will be freed."); + else /* if (Cache->UsrSize() == 0) */ + c1out << _("used disk space will remain the same."); + c1out << endl; + + if (_error->PendingError() == true) + return false; + + /* Check for enough free space, but only if we are actually going to + download */ + if (_config->FindB("APT::Get::Print-URIs") == false) + { + struct statvfs Buf; + string OutputDir = _config->FindDir("Dir::Cache::Archives"); + if (statvfs(OutputDir.c_str(),&Buf) != 0) + return _error->Errno("statvfs",_("Couldn't determine free space in %s"), + OutputDir.c_str()); + if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) + return _error->Error(_("Sorry, you don't have enough free space in %s to hold all packages."), + OutputDir.c_str()); + } + + // Fail safe check + if (_config->FindI("quiet",0) >= 2 || + _config->FindB("APT::Get::Assume-Yes",false) == true) + { + if (Fail == true && _config->FindB("APT::Get::Force-Yes",false) == false) + return _error->Error(_("There are problems and -y was used without --force-yes")); + } + + if (Essential == true && Saftey == true) + { + if (_config->FindB("APT::Get::Trivial-Only",false) == true) + return _error->Error(_("Trivial Only specified but this is not a trivial operation.")); + + c2out << _("You are about to do something potentially harmful") << endl; + c2out << _("To continue type in the phrase 'Yes, I understand this may be bad'") << endl; + c2out << _(" ?] ") << flush; + if (AnalPrompt(_("Yes, I understand this may be bad")) == false) + { + c2out << _("Aborted.") << endl; + exit(1); + } + } + else + { + // Prompt to continue + if (Ask == true || Fail == true) + { + if (_config->FindB("APT::Get::Trivial-Only",false) == true) + return _error->Error(_("Trivial Only specified but this is not a trivial operation.")); + + if (_config->FindI("quiet",0) < 2 && + _config->FindB("APT::Get::Assume-Yes",false) == false) + { + c2out << _("Do you want to continue? [Y/n] ") << flush; + + if (YnPrompt() == false) + { + c2out << _("Aborted.") << endl; + exit(1); + } + } + } + } + + // Just print out the uris an exit if the --print-uris flag was used + if (_config->FindB("APT::Get::Print-URIs") == true) + { + pkgAcquire::UriIterator I = Fetcher.UriBegin(); + for (; I != Fetcher.UriEnd(); I++) + cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl; + return true; + } + + // Run it + while (1) + { + bool Transient = false; + if (_config->FindB("APT::Get::No-Download",false) == true) + { + for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I < Fetcher.ItemsEnd();) + { + if ((*I)->Local == true) + { + I++; + continue; + } + + // Close the item and check if it was found in cache + (*I)->Finished(); + if ((*I)->Complete == false) + Transient = true; + + // Clear it out of the fetch list + delete *I; + I = Fetcher.ItemsBegin(); + } + } + + if (Fetcher.Run() == pkgAcquire::Failed) + return false; + // Print out errors + bool Failed = false; + for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) + { + if ((*I)->Status == pkgAcquire::Item::StatDone && + (*I)->Complete == true) + continue; + + if ((*I)->Status == pkgAcquire::Item::StatIdle) + { + Transient = true; + // Failed = true; + continue; + } + + cerr << _("Failed to fetch ") << (*I)->DescURI() << endl; + cerr << " " << (*I)->ErrorText << endl; + Failed = true; + } + + /* If we are in no download mode and missing files and there were + 'failures' then the user must specify -m. Furthermore, there + is no such thing as a transient error in no-download mode! */ + if (Transient == true && + _config->FindB("APT::Get::No-Download",false) == true) + { + Transient = false; + Failed = true; + } + + if (_config->FindB("APT::Get::Download-Only",false) == true) + { + if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false) + return _error->Error(_("Some files failed to download")); + return true; + } + + if (Failed == true && _config->FindB("APT::Get::Fix-Missing",false) == false) + { + return _error->Error(_("Unable to fetch some archives, maybe try with --fix-missing?")); + } + + if (Transient == true && Failed == true) + return _error->Error(_("--fix-missing and media swapping is not currently supported")); + + // Try to deal with missing package files + if (Failed == true && PM->FixMissing() == false) + { + cerr << _("Unable to correct missing packages.") << endl; + return _error->Error(_("Aborting Install.")); + } + + // need this so that we first fetch everything and then install (for CDs) + if (Transient == false || _config->FindB("Acquire::cdrom::copy", false) == false) { + Cache.ReleaseLock(); + pkgPackageManager::OrderResult Res = PM->DoInstall(); + if (Res == pkgPackageManager::Failed || _error->PendingError() == true) + return false; + if (Res == pkgPackageManager::Completed) + return true; + } + // Reload the fetcher object and loop again for media swapping + Fetcher.Shutdown(); + if (PM->GetArchives(&Fetcher,&List,&Recs) == false) + return false; + } + + if (_config->FindB("APT::Get::No-Download",false) == true) + cout << _("Run apt-get clean to remove downloaded packages.") << endl; +} + /*}}}*/ +// TryToInstall - Try to install a single package /*{{{*/ +// --------------------------------------------------------------------- +/* This used to be inlined in DoInstall, but with the advent of regex package + name matching it was split out.. */ +bool TryToInstall(pkgCache::PkgIterator Pkg,pkgDepCache &Cache, + pkgProblemResolver &Fix,bool Remove,bool BrokenFix, + unsigned int &ExpectedInst,bool AllowFail = true) +{ + /* This is a pure virtual package and there is a single available + provides */ + if (Cache[Pkg].CandidateVer == 0 && Pkg->ProvidesList != 0 && + Pkg.ProvidesList()->NextProvides == 0) + { + pkgCache::PkgIterator Tmp = Pkg.ProvidesList().OwnerPkg(); + c1out << _("Note, selecting ") << Tmp.Name() << _(" instead of ") << Pkg.Name() << endl; + Pkg = Tmp; + } + + // Handle the no-upgrade case + if (_config->FindB("APT::Get::no-upgrade",false) == true && + Pkg->CurrentVer != 0) + { + if (AllowFail == true) + c1out << _("Skipping ") << Pkg.Name() << _(", it is already installed and no-upgrade is set.") << endl; + return true; + } + + // Check if there is something at all to install + pkgDepCache::StateCache &State = Cache[Pkg]; + if (Remove == true && Pkg->CurrentVer == 0) + { + if (AllowFail == false) + return false; + return _error->Error(_("Package %s is not installed"),Pkg.Name()); + } + + if (State.CandidateVer == 0 && Remove == false) + { + if (AllowFail == false) + return false; + + if (Pkg->ProvidesList != 0) + { + c1out << _("Package ") << Pkg.Name() << _(" is a virtual package provided by:") << endl; + + pkgCache::PrvIterator I = Pkg.ProvidesList(); + for (; I.end() == false; I++) + { + pkgCache::PkgIterator Pkg = I.OwnerPkg(); + + if (Cache[Pkg].CandidateVerIter(Cache) == I.OwnerVer()) + { + if (Cache[Pkg].Install() == true && Cache[Pkg].NewInstall() == false) + c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << + _(" [Installed]")<< endl; + else + c1out << " " << Pkg.Name() << " " << I.OwnerVer().VerStr() << endl; + } + } + c1out << _("You should explicitly select one to install.") << endl; + } + else + { + c1out << _("Package ") << Pkg.Name() << _(" has no available version, but exists in the database.") << endl; + c1out << _("This typically means that the package was mentioned in a dependency and ") << endl; + c1out << _("never uploaded, has been obsoleted or is not available with the contents ") << endl; + c1out << _("of sources.list") << endl; + + string List; + pkgCache::DepIterator Dep = Pkg.RevDependsList(); + for (; Dep.end() == false; Dep++) + { + if (Dep->Type != pkgCache::Dep::Replaces + && Dep->Type != pkgCache::Dep::Obsoletes) + continue; + List += string(Dep.ParentPkg().Name()) + " "; + } + ShowList(c1out,_("However the following packages replace it:"),List); + } + + _error->Error(_("Package %s has no installation candidate"),Pkg.Name()); + return false; + } + + Fix.Clear(Pkg); + Fix.Protect(Pkg); + if (Remove == true) + { + Fix.Remove(Pkg); + Cache.MarkDelete(Pkg,false,_config->FindB("APT::Get::Purge",false)); + return true; + } + + // Install it + Cache.MarkInstall(Pkg,false); + if (State.Install() == false) + { + if (_config->FindB("APT::Get::ReInstall",false) == true) + { + if (Pkg->CurrentVer == 0 || Pkg.CurrentVer().Downloadable() == false) + c1out << _("Sorry, re-installation of ") << Pkg.Name() << _(" is not possible, it cannot be downloaded") << endl; + else + Cache.SetReInstall(Pkg,true); + } + else + { + if (AllowFail == true) + c1out << _("Sorry, ") << Pkg.Name() << _(" is already the newest version") << endl; + } + } + else + ExpectedInst++; + + // Install it with autoinstalling enabled. + if (State.InstBroken() == true && BrokenFix == false) + Cache.MarkInstall(Pkg,true); + return true; +} + /*}}}*/ + +// DoUpdate - Update the package lists /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DoUpdate(CommandLine &) +{ + // Get the source list + pkgSourceList List; + if (List.ReadMainList() == false) + return false; + + // Lock the list directory + FileFd Lock; + if (_config->FindB("Debug::NoLocking",false) == false) + { + Lock.Fd(GetLock(_config->FindDir("Dir::State::Lists") + "lock")); + if (_error->PendingError() == true) + return _error->Error(_("Unable to lock the list directory")); + } + + // Create the download object + AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); + pkgAcquire Fetcher(&Stat); + + + bool hasIndex = false; + + // Download the signed index hashfiles + pkgSourceList::rep_iterator R; + for (R = List.rep_begin(); R != List.rep_end(); R++) + { + if ((*R)->Vendor == NULL) { + continue; + } + new pkgAcqHashes(&Fetcher,*R); + if (_error->PendingError() == true) + return false; + hasIndex = true; + } + + // Run it + if (hasIndex && Fetcher.Run() == pkgAcquire::Failed) + return _error->Error(_("Could not retrieve digitally signed hash file")); + + + bool Failed = false; + for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) + { + if ((*I)->Status == pkgAcquire::Item::StatDone) { + continue; + } + + (*I)->Finished(); + + cerr << _("Failed to fetch hash file: ") + << (*I)->DescURI() << endl; + cerr << " " << (*I)->ErrorText << endl; + Failed = true; + } + + if (Failed) + { + return _error->Error(_("Some of the signed hash files could not be retrieved. Aborting operation.")); + } + + pkgSourceList::const_iterator I; + // Populate it with the source selection + for (I = List.begin(); I != List.end(); I++) + { + new pkgAcqIndex(&Fetcher,I); + if (_error->PendingError() == true) + return false; + } + + // Run it + if (Fetcher.Run() == pkgAcquire::Failed) + return false; + + bool AuthFailed = false; + Failed = false; + for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) + { + if ((*I)->Status == pkgAcquire::Item::StatDone) + continue; + + if ((*I)->Status == pkgAcquire::Item::StatAuthError) + AuthFailed = true; + + (*I)->Finished(); + + cerr << _("Failed to fetch ") << (*I)->DescURI() << endl; + cerr << " " << (*I)->ErrorText << endl; + Failed = true; + } + + // Clean out any old list files + if (_config->FindB("APT::Get::List-Cleanup",true) == true) + { + if (Fetcher.Clean(_config->FindDir("Dir::State::lists")) == false || + Fetcher.Clean(_config->FindDir("Dir::State::lists") + "partial/") == false) + return false; + } + + if (AuthFailed == true) + return _error->Error(_("Some of the index files had mismatching MD5 sums!")); + + // Prepare the cache. + CacheFile Cache; + if (Cache.Open() == false) + return false; + + if (Failed == true) + return _error->Error(_("Some index files failed to download, they have been ignored, or old ones used instead.")); + + for (R = List.rep_begin(); R != List.rep_end(); R++) + { + if ((*R)->Vendor == NULL) { + string msg = (*R)->URI + _(" will not be authenticated."); + _error->Warning(msg.c_str()); + } + } + return true; +} + /*}}}*/ +// DoUpgrade - Upgrade all packages /*{{{*/ +// --------------------------------------------------------------------- +/* Upgrade all packages without installing new packages or erasing old + packages */ +bool DoUpgrade(CommandLine &CmdL) +{ + CacheFile Cache; + if (Cache.Open() == false || Cache.CheckDeps() == false) + return false; + + // Do the upgrade + if (pkgAllUpgrade(Cache) == false) + { + ShowBroken(c1out,Cache,false); + return _error->Error(_("Internal Error, AllUpgrade broke stuff")); + } + + return InstallPackages(Cache,true); +} + /*}}}*/ +// DoInstall - Install packages from the command line /*{{{*/ +// --------------------------------------------------------------------- +/* Install named packages */ +bool DoInstall(CommandLine &CmdL) +{ + CacheFile Cache; + if (Cache.Open() == false || Cache.CheckDeps(CmdL.FileSize() != 1) == false) + return false; + + // Enter the special broken fixing mode if the user specified arguments + bool BrokenFix = false; + if (Cache->BrokenCount() != 0) + BrokenFix = true; + + unsigned int ExpectedInst = 0; + unsigned int Packages = 0; + pkgProblemResolver Fix(Cache); + + bool DefRemove = false; + if (strcasecmp(CmdL.FileList[0],"remove") == 0) + DefRemove = true; + + for (const char **I = CmdL.FileList + 1; *I != 0; I++) + { + // Duplicate the string + unsigned int Length = strlen(*I); + char S[300]; + if (Length >= sizeof(S)) + continue; + strcpy(S,*I); + + // See if we are removing the package + bool Remove = DefRemove; + while (Cache->FindPkg(S).end() == true) + { + // Handle an optional end tag indicating what to do + if (S[Length - 1] == '-') + { + Remove = true; + S[--Length] = 0; + continue; + } + + if (S[Length - 1] == '+') + { + Remove = false; + S[--Length] = 0; + continue; + } + break; + } + + // Locate the package + pkgCache::PkgIterator Pkg = Cache->FindPkg(S); + Packages++; + if (Pkg.end() == true) + { + // Check if the name is a regex + const char *I; + for (I = S; *I != 0; I++) + if (*I == '.' || *I == '?' || *I == '*') + break; + if (*I == 0) + return _error->Error(_("Couldn't find package %s"),S); + + // Regexs must always be confirmed + ExpectedInst += 1000; + + // Compile the regex pattern + regex_t Pattern; + int ercode; + ercode = regcomp(&Pattern,S,REG_EXTENDED | REG_ICASE | REG_NOSUB); + if (ercode != 0) { + char buffer[256]; + int l; + + strcpy(buffer, _("Regex compilation error:")); + l = strlen(buffer); + + regerror(ercode, &Pattern, buffer+l, sizeof(buffer)-l); + + return _error->Error(buffer); + } + // Run over the matches + bool Hit = false; + for (Pkg = Cache->PkgBegin(); Pkg.end() == false; Pkg++) + { + if (regexec(&Pattern,Pkg.Name(),0,0,0) != 0) + continue; + + Hit |= TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix, + ExpectedInst,false); + } + regfree(&Pattern); + + if (Hit == false) + return _error->Error(_("Couldn't find package %s"),S); + } + else + { + if (TryToInstall(Pkg,Cache,Fix,Remove,BrokenFix,ExpectedInst) == false) + return false; + } + } + + /* If we are in the Broken fixing mode we do not attempt to fix the + problems. This is if the user invoked install without -f and gave + packages */ + if (BrokenFix == true && Cache->BrokenCount() != 0) + { + c1out << _("You might want to run `apt-get -f install' to correct these:") << endl; + ShowBroken(c1out,Cache,false); + + return _error->Error(_("Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a solution).")); + } + + // Call the scored problem resolver + Fix.InstallProtect(); + if (Fix.Resolve(true) == false) + _error->Discard(); + + // Now we check the state of the packages, + if (Cache->BrokenCount() != 0) + { + c1out << _("Some packages could not be installed. This may mean that you have") << endl; + c1out << _("requested an impossible situation or if you are using the unstable") << endl; + c1out << _("distribution that some required packages have not yet been created") << endl; + c1out << _("or been moved out of Incoming.") << endl; + if (Packages == 1) + { + c1out << endl; + c1out << _("Since you only requested a single operation it is extremely likely that") << endl; + c1out << _("the package is simply not installable and a bug report against") << endl; + c1out << _("that package should be filed.") << endl; + } + + c1out << _("The following information may help to resolve the situation:") << endl; + c1out << endl; + ShowBroken(c1out,Cache,false); + return _error->Error(_("Sorry, broken packages")); + } + + /* Print out a list of packages that are going to be installed extra + to what the user asked */ + if (Cache->InstCount() != ExpectedInst) + { + string List; + for (unsigned J = 0; J < Cache->Head().PackageCount; J++) + { + pkgCache::PkgIterator I(Cache,Cache.List[J]); + if ((*Cache)[I].Install() == false) + continue; + + const char **J; + for (J = CmdL.FileList + 1; *J != 0; J++) + if (strcmp(*J,I.Name()) == 0) + break; + + if (*J == 0) + List += string(I.Name()) + " "; + } + + ShowList(c1out,_("The following extra packages will be installed:"),List); + } + + // See if we need to prompt + if (Cache->InstCount() == ExpectedInst && Cache->DelCount() == 0) + return InstallPackages(Cache,false,false); + + return InstallPackages(Cache,false); +} + /*}}}*/ +// DoDistUpgrade - Automatic smart upgrader /*{{{*/ +// --------------------------------------------------------------------- +/* Intelligent upgrader that will install and remove packages at will */ +bool DoDistUpgrade(CommandLine &CmdL) +{ + CacheFile Cache; + if (Cache.Open() == false || Cache.CheckDeps() == false) + return false; + + c0out << _("Calculating Upgrade... ") << flush; + if (pkgDistUpgrade(*Cache) == false) + { + c0out << _("Failed") << endl; + ShowBroken(c1out,Cache,false); + return false; + } + + c0out << _("Done") << endl; + + return InstallPackages(Cache,true); +} + /*}}}*/ +// DoDSelectUpgrade - Do an upgrade by following dselects selections /*{{{*/ +// --------------------------------------------------------------------- +/* Follows dselect's selections */ +bool DoDSelectUpgrade(CommandLine &CmdL) +{ + CacheFile Cache; + if (Cache.Open() == false || Cache.CheckDeps() == false) + return false; + + // Install everything with the install flag set + pkgCache::PkgIterator I = Cache->PkgBegin(); + for (;I.end() != true; I++) + { + /* Install the package only if it is a new install, the autoupgrader + will deal with the rest */ + if (I->SelectedState == pkgCache::State::Install) + Cache->MarkInstall(I,false); + } + + /* Now install their deps too, if we do this above then order of + the status file is significant for | groups */ + for (I = Cache->PkgBegin();I.end() != true; I++) + { + /* Install the package only if it is a new install, the autoupgrader + will deal with the rest */ + if (I->SelectedState == pkgCache::State::Install) + Cache->MarkInstall(I,true); + } + + // Apply erasures now, they override everything else. + for (I = Cache->PkgBegin();I.end() != true; I++) + { + // Remove packages + if (I->SelectedState == pkgCache::State::DeInstall || + I->SelectedState == pkgCache::State::Purge) + Cache->MarkDelete(I,false,I->SelectedState == pkgCache::State::Purge); + } + + /* Resolve any problems that dselect created, allupgrade cannot handle + such things. We do so quite agressively too.. */ + if (Cache->BrokenCount() != 0) + { + pkgProblemResolver Fix(Cache); + + // Hold back held packages. + if (_config->FindB("APT::Ignore-Hold",false) == false) + { + for (pkgCache::PkgIterator I = Cache->PkgBegin(); I.end() == false; I++) + { + if (I->SelectedState == pkgCache::State::Hold) + { + Fix.Protect(I); + Cache->MarkKeep(I); + } + } + } + + if (Fix.Resolve() == false) + { + ShowBroken(c1out,Cache,false); + return _error->Error(_("Internal Error, problem resolver broke stuff")); + } + } + + // Now upgrade everything + if (pkgAllUpgrade(Cache) == false) + { + ShowBroken(c1out,Cache,false); + return _error->Error(_("Internal Error, problem resolver broke stuff")); + } + + return InstallPackages(Cache,false); +} + /*}}}*/ +// DoClean - Remove download archives /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool DoClean(CommandLine &CmdL) +{ + if (_config->FindB("APT::Get::Simulate") == true) + { + cout << "Del " << _config->FindDir("Dir::Cache::archives") << "* " << + _config->FindDir("Dir::Cache::archives") << "partial/*" << endl; + return true; + } + + // Lock the archive directory + FileFd Lock; + if (_config->FindB("Debug::NoLocking",false) == false) + { + Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); + if (_error->PendingError() == true) + return _error->Error(_("Unable to lock the download directory")); + } + + pkgAcquire Fetcher; + Fetcher.Clean(_config->FindDir("Dir::Cache::archives")); + Fetcher.Clean(_config->FindDir("Dir::Cache::archives") + "partial/"); + return true; +} + /*}}}*/ +// DoAutoClean - Smartly remove downloaded archives /*{{{*/ +// --------------------------------------------------------------------- +/* This is similar to clean but it only purges things that cannot be + downloaded, that is old versions of cached packages. */ +class LogCleaner : public pkgArchiveCleaner +{ + protected: + virtual void Erase(const char *File,string Pkg,string Ver,struct stat &St) + { + c1out << "Del " << Pkg << " " << Ver << " [" << SizeToStr(St.st_size) << "B]" << endl; + + if (_config->FindB("APT::Get::Simulate") == false) + unlink(File); + }; +}; + +bool DoAutoClean(CommandLine &CmdL) +{ + // Lock the archive directory + FileFd Lock; + if (_config->FindB("Debug::NoLocking",false) == false) + { + Lock.Fd(GetLock(_config->FindDir("Dir::Cache::Archives") + "lock")); + if (_error->PendingError() == true) + return _error->Error(_("Unable to lock the download directory")); + } + + CacheFile Cache; + if (Cache.Open() == false) + return false; + + LogCleaner Cleaner; + + return Cleaner.Go(_config->FindDir("Dir::Cache::archives"),*Cache) && + Cleaner.Go(_config->FindDir("Dir::Cache::archives") + "partial/",*Cache); +} + /*}}}*/ +// DoCheck - Perform the check operation /*{{{*/ +// --------------------------------------------------------------------- +/* Opening automatically checks the system, this command is mostly used + for debugging */ +bool DoCheck(CommandLine &CmdL) +{ + CacheFile Cache; + Cache.Open(); + Cache.CheckDeps(); + + return true; +} + /*}}}*/ +// DoSource - Fetch a source archive /*{{{*/ +// --------------------------------------------------------------------- +/* Fetch souce packages */ +struct DscFile +{ + string Package; + string Version; + string Dsc; +}; + +bool DoSource(CommandLine &CmdL) +{ + CacheFile Cache; + + + if (Cache.Open(false) == false) + return false; + + if (CmdL.FileSize() <= 1) + return _error->Error(_("Must specify at least one package to fetch source for")); + + // Read the source list + pkgSourceList List; + if (List.ReadMainList() == false) + return _error->Error(_("The list of sources could not be read.")); + + // Create the text record parsers + pkgRecords Recs(Cache); + pkgSrcRecords SrcRecs(List); + if (_error->PendingError() == true) + return false; + + // Create the download object + AcqTextStatus Stat(ScreenWidth,_config->FindI("quiet",0)); + pkgAcquire Fetcher(&Stat); + + DscFile *Dsc = new DscFile[CmdL.FileSize()]; + + // Load the requestd sources into the fetcher + unsigned J = 0; + for (const char **I = CmdL.FileList + 1; *I != 0; I++, J++) + { + string Src; + + /* Lookup the version of the package we would install if we were to + install a version and determine the source package name, then look + in the archive for a source package of the same name. In theory + we could stash the version string as well and match that too but + today there aren't multi source versions in the archive. */ + pkgCache::PkgIterator Pkg = Cache->FindPkg(*I); + if (Pkg.end() == false) + { + pkgCache::VerIterator Ver = Cache->GetCandidateVer(Pkg); + if (Ver.end() == false) + { + pkgRecords::Parser &Parse = Recs.Lookup(Ver.FileList()); + Src = Parse.SourcePkg(); + } + } + + // No source package name.. + if (Src.empty() == true) + Src = *I; + + // The best hit + pkgSrcRecords::Parser *Last = 0; + unsigned long Offset = 0; + string Version; + bool IsMatch = false; + + // Iterate over all of the hits + pkgSrcRecords::Parser *Parse; + SrcRecs.Restart(); + while ((Parse = SrcRecs.Find(Src.c_str(),false)) != 0) + { + string Ver = Parse->Version(); + + // Skip name mismatches + if (IsMatch == true && Parse->Package() != Src) + continue; + + // Newer version or an exact match + if (Last == 0 || _system->versionCompare(Version,Ver) < 0 || + (Parse->Package() == Src && IsMatch == false)) + { + IsMatch = Parse->Package() == Src; + Last = Parse; + Offset = Parse->Offset(); + Version = Ver; + } + } + + if (Last == 0) + return _error->Error(_("Unable to find a source package for %s"),Src.c_str()); + + + // Back track + vector Lst; + if (Last->Jump(Offset) == false || Last->Files(Lst) == false) + return false; + + // Load them into the fetcher + for (vector::const_iterator I = Lst.begin(); + I != Lst.end(); I++) + { + string Comp; +#if 1 + Comp = "srpm"; + Dsc[J].Package = flNotDir(I->Path); +#else + // Try to guess what sort of file it is we are getting. + if (I->Path.find(".dsc") != string::npos) + { + Comp = "dsc"; + Dsc[J].Package = Last->Package(); + Dsc[J].Version = Last->Version(); + Dsc[J].Dsc = flNotDir(I->Path); + } + + if (I->Path.find(".tar.gz") != string::npos) + Comp = "tar"; + if (I->Path.find(".diff.gz") != string::npos) + Comp = "diff"; + + // Diff only mode only fetches .diff files + if (_config->FindB("APT::Get::Diff-Only",false) == true && + Comp != "diff") + continue; + + // Tar only mode only fetches .tar files + if (_config->FindB("APT::Get::Tar-Only",false) == true && + Comp != "tar") + continue; +#endif + new pkgAcqFile(&Fetcher,Last->Source()->ArchiveURI(I->Path), + I->MD5Hash,I->Size, + Last->Source()->SourceInfo(Src,Last->Version(),Comp), + Src); + } + } + + // Display statistics + unsigned long FetchBytes = Fetcher.FetchNeeded(); + unsigned long FetchPBytes = Fetcher.PartialPresent(); + unsigned long DebBytes = Fetcher.TotalNeeded(); + + // Check for enough free space + struct statvfs Buf; + string OutputDir = "."; + if (statvfs(OutputDir.c_str(),&Buf) != 0) + return _error->Errno("statvfs",_("Couldn't determine free space in %s"), + OutputDir.c_str()); + if (unsigned(Buf.f_bfree) < (FetchBytes - FetchPBytes)/Buf.f_bsize) + return _error->Error(_("Sorry, you don't have enough free space in %s"), + OutputDir.c_str()); + + // Number of bytes + c1out << _("Need to get "); + if (DebBytes != FetchBytes) + c1out << SizeToStr(FetchBytes) << "B/" << SizeToStr(DebBytes) << 'B'; + else + c1out << SizeToStr(DebBytes) << 'B'; + c1out << _(" of source archives.") << endl; + + if (_config->FindB("APT::Get::Simulate",false) == true) + { + for (unsigned I = 0; I != J; I++) + cout << _("Fetch Source ") << Dsc[I].Package << endl; + return true; + } + + // Just print out the uris an exit if the --print-uris flag was used + if (_config->FindB("APT::Get::Print-URIs") == true) + { + pkgAcquire::UriIterator I = Fetcher.UriBegin(); + for (; I != Fetcher.UriEnd(); I++) + cout << '\'' << I->URI << "' " << flNotDir(I->Owner->DestFile) << ' ' << + I->Owner->FileSize << ' ' << I->Owner->MD5Sum() << endl; + return true; + } + + // Run it + if (Fetcher.Run() == pkgAcquire::Failed) + return false; + + // Print error messages + bool Failed = false; + for (pkgAcquire::Item **I = Fetcher.ItemsBegin(); I != Fetcher.ItemsEnd(); I++) + { + if ((*I)->Status == pkgAcquire::Item::StatDone && + (*I)->Complete == true) + continue; + + cerr << _("Failed to fetch ") << (*I)->DescURI() << endl; + cerr << " " << (*I)->ErrorText << endl; + Failed = true; + } + if (Failed == true) + return _error->Error(_("Failed to fetch some archives.")); + + if (_config->FindB("APT::Get::Download-only",false) == true) + return true; + + // Unpack the sources + pid_t Process = ExecFork(); + + if (Process == 0) + { + for (unsigned I = 0; I != J; I++) + { +#if 1 + char S[400]; + + if (_config->FindB("APT::Get::Compile",false) == true) + { + snprintf(S,sizeof(S),"rpm --rebuild %s", Dsc[I].Package.c_str()); + if (system(S) != 0) + { + cerr << _("Build command '") << S << _("' failed.") << endl; + _exit(1); + } + } +#else + string Dir = Dsc[I].Package + '-' + _system->baseVersion(Dsc[I].Version.c_str()); + + // Diff only mode only fetches .diff files + if (_config->FindB("APT::Get::Diff-Only",false) == true || + _config->FindB("APT::Get::Tar-Only",false) == true || + Dsc[I].Dsc.empty() == true) + continue; + + // See if the package is already unpacked + struct stat Stat; + if (stat(Dir.c_str(),&Stat) == 0 && + S_ISDIR(Stat.st_mode) != 0) + { + c0out << _("Skipping unpack of already unpacked source in ") << Dir << endl; + } + else + { + // Call dpkg-source + char S[500]; + snprintf(S,sizeof(S),"%s -x %s", + _config->Find("Dir::Bin::dpkg-source","dpkg-source").c_str(), + Dsc[I].Dsc.c_str()); + if (system(S) != 0) + { + cerr << _("Unpack command '") << S << _("' failed.") << endl; + _exit(1); + } + } + + // Try to compile it with dpkg-buildpackage + if (_config->FindB("APT::Get::Compile",false) == true) + { + char S[500]; + // Call dpkg-buildpackage + snprintf(S,sizeof(S),"cd %s && %s %s", + Dir.c_str(), + _config->Find("Dir::Bin::dpkg-buildpackage","dpkg-buildpackage").c_str(), + _config->Find("DPkg::Build-Options","-b -uc").c_str()); + + if (system(S) != 0) + { + cerr << _("Build command '") << S << _("' failed.") << endl; + _exit(1); + } + } +#endif + } + + _exit(0); + } + + // Wait for the subprocess + int Status = 0; + while (waitpid(Process,&Status,0) != Process) + { + if (errno == EINTR) + continue; + return _error->Errno("waitpid",_("Couldn't wait for subprocess")); + } + + if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0) + return _error->Error(_("Child process failed")); + + return true; +} + /*}}}*/ + +// ShowHelp - Show a help screen /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ShowHelp(CommandLine &CmdL) +{ + cout << PACKAGE << ' ' << VERSION << " for " << COMMON_CPU << + " compiled on " << __DATE__ << " " << __TIME__ << endl; + if (_config->FindB("version") == true) + return 100; + + cout << _("Usage: apt-get [options] command") << endl; + cout << _(" apt-get [options] install pkg1 [pkg2 ...]") << endl; + cout << endl; + cout << _("apt-get is a simple command line interface for downloading and") << endl; + cout << _("installing packages. The most frequently used commands are update") << endl; + cout << _("and install.") << endl; + cout << endl; + cout << _("Commands:") << endl; + cout << _(" update - Retrieve new lists of packages") << endl; + cout << _(" upgrade - Perform an upgrade") << endl; + cout << _(" install - Install new packages") << endl; + cout << _(" remove - Remove packages") << endl; + cout << _(" source - Download source archives") << endl; + cout << _(" dist-upgrade - Distribution upgrade, see apt-get(8)") << endl; +// cout << " dselect-upgrade - Follow dselect selections" << endl; + cout << _(" clean - Erase downloaded archive files") << endl; + cout << _(" autoclean - Erase old downloaded archive files") << endl; + cout << _(" check - Verify that there are no broken dependencies") << endl; + cout << endl; + cout << _("Options:") << endl; + cout << _(" -h This help text.") << endl; + cout << _(" -q Loggable output - no progress indicator") << endl; + cout << _(" -qq No output except for errors") << endl; + cout << _(" -S Show summary for upgrade operation and quit") << endl; + cout << _(" -d Download only - do NOT install or unpack archives") << endl; + cout << _(" -s No-act. Perform ordering simulation") << endl; + cout << _(" -y Assume Yes to all queries and do not prompt") << endl; + cout << _(" -f Attempt to continue if the integrity check fails") << endl; + cout << _(" -m Attempt to continue if archives are unlocatable") << endl; + cout << _(" -u Show a list of upgraded packages as well") << endl; + cout << _(" -b Build the source package after fetching it") << endl; + cout << _(" -K Verify signatures in individual packages and quit") << endl; + cout << _(" -c=? Read this configuration file") << endl; + cout << _(" -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp") << endl; + cout << _("See the apt-get(8), sources.list(5) and apt.conf(5) manual") << endl; + cout << _("pages for more information and options.") << endl; + return 100; +} + /*}}}*/ +// GetInitialize - Initialize things for apt-get /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void GetInitialize() +{ + _config->Set("quiet",0); + _config->Set("help",false); + _config->Set("APT::Get::Download-Only",false); + _config->Set("APT::Get::Simulate",false); + _config->Set("APT::Get::Assume-Yes",false); + _config->Set("APT::Get::Fix-Broken",false); + _config->Set("APT::Get::Force-Yes",false); + _config->Set("APT::Get::APT::Get::No-List-Cleanup",true); +} + /*}}}*/ +// SigWinch - Window size change signal handler /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void SigWinch(int) +{ + // Riped from GNU ls +#ifdef TIOCGWINSZ + struct winsize ws; + + if (ioctl(1, TIOCGWINSZ, &ws) != -1 && ws.ws_col >= 5) + ScreenWidth = ws.ws_col - 1; +#endif +} + /*}}}*/ + +int main(int argc,const char *argv[]) +{ + CommandLine::Args Args[] = { + {'h',"help","help",0}, + {'v',"version","version",0}, + {'q',"quiet","quiet",CommandLine::IntLevel}, + {'q',"silent","quiet",CommandLine::IntLevel}, + {'d',"download-only","APT::Get::Download-Only",0}, + {'b',"compile","APT::Get::Compile",0}, + {'b',"build","APT::Get::Compile",0}, + {'s',"simulate","APT::Get::Simulate",0}, + {'s',"just-print","APT::Get::Simulate",0}, + {'s',"recon","APT::Get::Simulate",0}, + {'s',"no-act","APT::Get::Simulate",0}, + {'S',"summary","APT::Get::Show-Upgrade-Summary",0}, + {'y',"yes","APT::Get::Assume-Yes",0}, + {'y',"assume-yes","APT::Get::Assume-Yes",0}, + {'f',"fix-broken","APT::Get::Fix-Broken",0}, + {'u',"show-upgraded","APT::Get::Show-Upgraded",0}, + {'m',"ignore-missing","APT::Get::Fix-Missing",0}, + {0,"no-download","APT::Get::No-Download",0}, + {0,"fix-missing","APT::Get::Fix-Missing",0}, + {0,"ignore-hold","APT::Ingore-Hold",0}, + {0,"no-upgrade","APT::Get::no-upgrade",0}, + {0,"force-yes","APT::Get::force-yes",0}, + {0,"print-uris","APT::Get::Print-URIs",0}, + {0,"diff-only","APT::Get::Diff-Only",0}, + {0,"tar-only","APT::Get::tar-Only",0}, + {0,"purge","APT::Get::Purge",0}, + {0,"list-cleanup","APT::Get::List-Cleanup",0}, + {0,"reinstall","APT::Get::ReInstall",0}, + {0,"trivial-only","APT::Get::Trivial-Only",0}, + {0,"no-remove","APT::Get::No-Remove",0}, + {'c',"config-file",0,CommandLine::ConfigFile}, + {'o',"option",0,CommandLine::ArbItem}, + {'K',"check-signatures","RPM::Check-Signatures",0}, + {0,0,0,0}}; + CommandLine::Dispatch Cmds[] = {{"update",&DoUpdate}, + {"upgrade",&DoUpgrade}, + {"install",&DoInstall}, + {"remove",&DoInstall}, + {"dist-upgrade",&DoDistUpgrade}, +// {"dselect-upgrade",&DoDSelectUpgrade}, + {"clean",&DoClean}, + {"autoclean",&DoAutoClean}, + {"check",&DoCheck}, + {"source",&DoSource}, + {"help",&ShowHelp}, + {0,0}}; + + + setlocale(LC_ALL, ""); + bindtextdomain(PACKAGE, LOCALEDIR); + textdomain(PACKAGE); + + // Parse the command line and initialize the package library + CommandLine CmdL(Args,_config); + if (pkgInitialize(*_config) == false || + CmdL.Parse(argc,argv) == false) + { + _error->DumpErrors(); + return 100; + } + + if (1) { + RPMFactory *factory = new RPMFactory; // uses a config option, so must come after + void *shutup_gcc = NULL; + shutup_gcc = factory; + } +#if 0 //akk + else { + DebianFactory *factory = new DebianFactory; + void *shutup_gcc = NULL; + shutup_gcc = factory; + } +#endif + // See if the help should be shown + if (_config->FindB("help") == true || + _config->FindB("version") == true || + CmdL.FileSize() == 0) + return ShowHelp(CmdL); + + // Deal with stdout not being a tty + if (ttyname(STDOUT_FILENO) == 0 && _config->FindI("quiet",0) < 1) + _config->Set("quiet","1"); + + // Setup the output streams + c0out.rdbuf(cout.rdbuf()); + c1out.rdbuf(cout.rdbuf()); + c2out.rdbuf(cout.rdbuf()); + if (_config->FindI("quiet",0) > 0) + c0out.rdbuf(devnull.rdbuf()); + if (_config->FindI("quiet",0) > 1) + c1out.rdbuf(devnull.rdbuf()); + + // Setup the signals + signal(SIGPIPE,SIG_IGN); + signal(SIGWINCH,SigWinch); + SigWinch(0); + + // Match the operation + CmdL.DispatchArg(Cmds); + +#ifdef DEBUG + { + struct mallinfo ma = mallinfo(); + printf("Total allocated memory: %i kB. Total memory in use: %i kB.\n", + (ma.arena+ma.hblkhd)/1024, (ma.uordblks+ma.hblkhd)/1024); + + } +#endif + + // Print any errors or warnings found during parsing + if (_error->empty() == false) + { + bool Errors = _error->PendingError(); + _error->DumpErrors(); + return Errors == true?100:0; + } + + return 0; +} diff --git a/apt/cmdline/indexcopy.cc b/apt/cmdline/indexcopy.cc new file mode 100644 index 0000000..4429363 --- /dev/null +++ b/apt/cmdline/indexcopy.cc @@ -0,0 +1,548 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: indexcopy.cc,v 1.1.1.1 2000/08/10 12:42:38 kojima Exp $ +/* ###################################################################### + + Index Copying - Aid for copying and verifying the index files + + This class helps apt-cache reconstruct a damaged index files. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "indexcopy.h" + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + /*}}}*/ + +// IndexCopy::CopyPackages - Copy the package files from the CD /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool IndexCopy::CopyPackages(string CDROM,string Name,vector &List) +{ + if (List.size() == 0) + return true; + + OpTextProgress Progress; + + bool NoStat = _config->FindB("APT::CDROM::Fast",false); + bool Debug = _config->FindB("Debug::aptcdrom",false); + + // Prepare the progress indicator + unsigned long TotalSize = 0; + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + struct stat Buf; + if (stat(string(*I + GetFileName()).c_str(),&Buf) != 0 && + stat(string(*I + GetFileName() + ".gz").c_str(),&Buf) != 0) + return _error->Errno("stat","Stat failed for %s", + string(*I + GetFileName()).c_str()); + TotalSize += Buf.st_size; + } + + unsigned long CurrentSize = 0; + unsigned int NotFound = 0; + unsigned int WrongSize = 0; + unsigned int Packages = 0; + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + string OrigPath = string(*I,CDROM.length()); + unsigned long FileSize = 0; + + // Open the package file + FileFd Pkg; + if (FileExists(*I + GetFileName()) == true) + { + Pkg.Open(*I + GetFileName(),FileFd::ReadOnly); + FileSize = Pkg.Size(); + } + else + { + FileFd From(*I + GetFileName() + ".gz",FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + FileSize = From.Size(); + + // Get a temp file + FILE *tmp = tmpfile(); + if (tmp == 0) + return _error->Errno("tmpfile","Unable to create a tmp file"); + Pkg.Fd(dup(fileno(tmp))); + fclose(tmp); + + // Fork gzip + int Process = fork(); + if (Process < 0) + return _error->Errno("fork","Couldn't fork gzip"); + + // The child + if (Process == 0) + { + dup2(From.Fd(),STDIN_FILENO); + dup2(Pkg.Fd(),STDOUT_FILENO); + SetCloseExec(STDIN_FILENO,false); + SetCloseExec(STDOUT_FILENO,false); + + const char *Args[3]; + Args[0] = _config->Find("Dir::bin::gzip","gzip").c_str(); + Args[1] = "-d"; + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for gzip to finish + if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false) + return _error->Error("gzip failed, perhaps the disk is full."); + + Pkg.Seek(0); + } + pkgTagFile Parser(Pkg); + if (_error->PendingError() == true) + return false; + + // Open the output file + char S[400]; + sprintf(S,"cdrom:[%s]/%s%s",Name.c_str(),(*I).c_str() + CDROM.length(), + GetFileName()); + string TargetF = _config->FindDir("Dir::State::lists") + "partial/"; + TargetF += URItoFileName(S); + if (_config->FindB("APT::CDROM::NoAct",false) == true) + TargetF = "/dev/null"; + FileFd Target(TargetF,FileFd::WriteEmpty); + if (_error->PendingError() == true) + return false; + + // Setup the progress meter + Progress.OverallProgress(CurrentSize,TotalSize,FileSize, + string("Reading ") + Type() + " Indexes"); + + // Parse + Progress.SubProgress(Pkg.Size()); + pkgTagSection Section; + this->Section = &Section; + string Prefix; + unsigned long Hits = 0; + unsigned long Chop = 0; + while (Parser.Step(Section) == true) + { + Progress.Progress(Parser.Offset()); + string File; + unsigned long Size; + if (GetFile(File,Size) == false) + return false; + + if (Chop != 0) + File = OrigPath + ChopDirs(File,Chop); + + // See if the file exists + bool Mangled = false; + if (NoStat == false || Hits < 10) + { + // Attempt to fix broken structure + if (Hits == 0) + { + if (ReconstructPrefix(Prefix,OrigPath,CDROM,File) == false && + ReconstructChop(Chop,*I,File) == false) + { + if (Debug == true) + clog << "Missed: " << File << endl; + NotFound++; + continue; + } + if (Chop != 0) + File = OrigPath + ChopDirs(File,Chop); + } + + // Get the size + struct stat Buf; + if (stat(string(CDROM + Prefix + File).c_str(),&Buf) != 0 || + Buf.st_size == 0) + { + // Attempt to fix busted symlink support for one instance + string OrigFile = File; + string::size_type Start = File.find("binary-"); + string::size_type End = File.find("/",Start+3); + if (Start != string::npos && End != string::npos) + { + File.replace(Start,End-Start,"binary-all"); + Mangled = true; + } + + if (Mangled == false || + stat(string(CDROM + Prefix + File).c_str(),&Buf) != 0) + { + if (Debug == true) + clog << "Missed(2): " << OrigFile << endl; + NotFound++; + continue; + } + } + + // Size match + if ((unsigned)Buf.st_size != Size) + { + if (Debug == true) + clog << "Wrong Size: " << File << endl; + WrongSize++; + continue; + } + } + + Packages++; + Hits++; + + // Copy it to the target package file + if (Chop != 0 || Mangled == true) + { + if (RewriteEntry(Target,File) == false) + continue; + } + else + { + const char *Start; + const char *Stop; + Section.GetSection(Start,Stop); + if (Target.Write(Start,Stop-Start) == false) + return false; + } + } + + if (Debug == true) + cout << " Processed by using Prefix '" << Prefix << "' and chop " << Chop << endl; + + if (_config->FindB("APT::CDROM::NoAct",false) == false) + { + // Move out of the partial directory + Target.Close(); + string FinalF = _config->FindDir("Dir::State::lists"); + FinalF += URItoFileName(S); + if (rename(TargetF.c_str(),FinalF.c_str()) != 0) + return _error->Errno("rename","Failed to rename"); + + // Copy the release file + sprintf(S,"cdrom:[%s]/%sRelease",Name.c_str(),(*I).c_str() + CDROM.length()); + string TargetF = _config->FindDir("Dir::State::lists") + "partial/"; + TargetF += URItoFileName(S); + if (FileExists(*I + "Release") == true) + { + FileFd Target(TargetF,FileFd::WriteEmpty); + FileFd Rel(*I + "Release",FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + + if (CopyFile(Rel,Target) == false) + return false; + } + else + { + // Empty release file + FileFd Target(TargetF,FileFd::WriteEmpty); + } + + // Rename the release file + FinalF = _config->FindDir("Dir::State::lists"); + FinalF += URItoFileName(S); + if (rename(TargetF.c_str(),FinalF.c_str()) != 0) + return _error->Errno("rename","Failed to rename"); + } + + /* Mangle the source to be in the proper notation with + prefix dist [component] */ + *I = string(*I,Prefix.length()); + ConvertToSourceList(CDROM,*I); + *I = Prefix + ' ' + *I; + + CurrentSize += FileSize; + } + Progress.Done(); + + // Some stats + cout << "Wrote " << Packages << " records" ; + if (NotFound != 0) + cout << " with " << NotFound << " missing files"; + if (NotFound != 0 && WrongSize != 0) + cout << " and"; + if (WrongSize != 0) + cout << " with " << WrongSize << " mismatched files"; + cout << '.' << endl; + + if (Packages == 0) + return _error->Warning("No valid records were found."); + + if (NotFound + WrongSize > 10) + cout << "Alot of entries were discarded, something may be wrong." << endl; + + return true; +} + /*}}}*/ +// IndexCopy::ChopDirs - Chop off the leading directory components /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string IndexCopy::ChopDirs(string Path,unsigned int Depth) +{ + string::size_type I = 0; + do + { + I = Path.find('/',I+1); + Depth--; + } + while (I != string::npos && Depth != 0); + + if (I == string::npos) + return string(); + + return string(Path,I+1); +} + /*}}}*/ +// IndexCopy::ReconstructPrefix - Fix strange prefixing /*{{{*/ +// --------------------------------------------------------------------- +/* This prepends dir components from the path to the package files to + the path to the deb until it is found */ +bool IndexCopy::ReconstructPrefix(string &Prefix,string OrigPath,string CD, + string File) +{ + bool Debug = _config->FindB("Debug::aptcdrom",false); + unsigned int Depth = 1; + string MyPrefix = Prefix; + while (1) + { + struct stat Buf; + if (stat(string(CD + MyPrefix + File).c_str(),&Buf) != 0) + { + if (Debug == true) + cout << "Failed, " << CD + MyPrefix + File << endl; + if (GrabFirst(OrigPath,MyPrefix,Depth++) == true) + continue; + + return false; + } + else + { + Prefix = MyPrefix; + return true; + } + } + return false; +} + /*}}}*/ +// IndexCopy::ReconstructChop - Fixes bad source paths /*{{{*/ +// --------------------------------------------------------------------- +/* This removes path components from the filename and prepends the location + of the package files until a file is found */ +bool IndexCopy::ReconstructChop(unsigned long &Chop,string Dir,string File) +{ + // Attempt to reconstruct the filename + unsigned long Depth = 0; + while (1) + { + struct stat Buf; + if (stat(string(Dir + File).c_str(),&Buf) != 0) + { + File = ChopDirs(File,1); + Depth++; + if (File.empty() == false) + continue; + return false; + } + else + { + Chop = Depth; + return true; + } + } + return false; +} + /*}}}*/ +// IndexCopy::ConvertToSourceList - Convert a Path to a sourcelist /*{{{*/ +// --------------------------------------------------------------------- +/* We look for things in dists/ notation and convert them to + form otherwise it is left alone. This also strips + the CD path. + + This implements a regex sort of like: + (.*)/dists/([^/]*)/(.*)/binary-* + ^ ^ ^- Component + | |-------- Distribution + |------------------- Path + + It was deciced to use only a single word for dist (rather than say + unstable/non-us) to increase the chance that each CD gets a single + line in sources.list. + */ +void IndexCopy::ConvertToSourceList(string CD,string &Path) +{ + char S[300]; + sprintf(S,"binary-%s",_config->Find("Apt::Architecture").c_str()); + + // Strip the cdrom base path + Path = string(Path,CD.length()); + if (Path.empty() == true) + Path = "/"; + + // Too short to be a dists/ type + if (Path.length() < strlen("dists/")) + return; + + // Not a dists type. + if (stringcmp(Path.begin(),Path.begin()+strlen("dists/"),"dists/") != 0) + return; + + // Isolate the dist + string::size_type Slash = strlen("dists/"); + string::size_type Slash2 = Path.find('/',Slash + 1); + if (Slash2 == string::npos || Slash2 + 2 >= Path.length()) + return; + string Dist = string(Path,Slash,Slash2 - Slash); + + // Isolate the component + Slash = Slash2; + for (unsigned I = 0; I != 10; I++) + { + Slash = Path.find('/',Slash+1); + if (Slash == string::npos || Slash + 2 >= Path.length()) + return; + string Comp = string(Path,Slash2+1,Slash - Slash2-1); + + // Verify the trailing binary- bit + string::size_type BinSlash = Path.find('/',Slash + 1); + if (Slash == string::npos) + return; + string Binary = string(Path,Slash+1,BinSlash - Slash-1); + + if (Binary != S && Binary != "source") + continue; + + Path = Dist + ' ' + Comp; + return; + } +} + /*}}}*/ +// IndexCopy::GrabFirst - Return the first Depth path components /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool IndexCopy::GrabFirst(string Path,string &To,unsigned int Depth) +{ + string::size_type I = 0; + do + { + I = Path.find('/',I+1); + Depth--; + } + while (I != string::npos && Depth != 0); + + if (I == string::npos) + return false; + + To = string(Path,0,I+1); + return true; +} + /*}}}*/ +// IndexCopy::CopyWithReplace - Copy a section and replace text /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool IndexCopy::CopyWithReplace(FileFd &Target,const char *Tag,string New) +{ + // Mangle the output filename + const char *Start; + const char *Stop; + const char *Filename; + Section->Find(Tag,Filename,Stop); + + /* We need to rewrite the filename field so we emit + all fields except the filename file and rewrite that one */ + for (unsigned int I = 0; I != Section->Count(); I++) + { + Section->Get(Start,Stop,I); + if (Start <= Filename && Stop > Filename) + { + char S[500]; + sprintf(S,"%s: %s\n",Tag,New.c_str()); + if (I + 1 == Section->Count()) + strcat(S,"\n"); + if (Target.Write(S,strlen(S)) == false) + return false; + } + else + { + if (Target.Write(Start,Stop-Start) == false) + return false; + if (Stop[-1] != '\n') + if (Target.Write("\n",1) == false) + return false; + } + } + if (Target.Write("\n",1) == false) + return false; +} + /*}}}*/ +// PackageCopy::GetFile - Get the file information from the section /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool PackageCopy::GetFile(string &File,unsigned long &Size) +{ + File = Section->FindS("Filename"); + Size = Section->FindI("Size"); + if (File.empty() || Size == 0) + return _error->Error("Cannot find filename or size tag"); + return true; +} + /*}}}*/ +// PackageCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool PackageCopy::RewriteEntry(FileFd &Target,string File) +{ + return CopyWithReplace(Target,"Filename",File); +} + /*}}}*/ +// SourceCopy::GetFile - Get the file information from the section /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool SourceCopy::GetFile(string &File,unsigned long &Size) +{ + string Files = Section->FindS("Files"); + if (Files.empty() == true) + return false; + + // Stash the / terminated directory prefix + string Base = Section->FindS("Directory"); + if (Base.empty() == false && Base[Base.length()-1] != '/') + Base += '/'; + + // Iterate over the entire list grabbing each triplet + const char *C = Files.c_str(); + string sSize; + string MD5Hash; + + // Parse each of the elements + if (ParseQuoteWord(C,MD5Hash) == false || + ParseQuoteWord(C,sSize) == false || + ParseQuoteWord(C,File) == false) + return _error->Error("Error parsing file record"); + + // Parse the size and append the directory + Size = atoi(sSize.c_str()); + File = Base + File; + return true; +} + /*}}}*/ +// SourceCopy::RewriteEntry - Rewrite the entry with a new filename /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool SourceCopy::RewriteEntry(FileFd &Target,string File) +{ + return CopyWithReplace(Target,"Directory", + string(File,0,File.rfind('/'))); +} + /*}}}*/ diff --git a/apt/cmdline/indexcopy.h b/apt/cmdline/indexcopy.h new file mode 100644 index 0000000..43f8f47 --- /dev/null +++ b/apt/cmdline/indexcopy.h @@ -0,0 +1,65 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: indexcopy.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Index Copying - Aid for copying and verifying the index files + + ##################################################################### */ + /*}}}*/ +#ifndef INDEXCOPY_H +#define INDEXCOPY_H + +#include +#include + +class pkgTagSection; +class FileFd; + +class IndexCopy +{ + protected: + + pkgTagSection *Section; + + string ChopDirs(string Path,unsigned int Depth); + bool ReconstructPrefix(string &Prefix,string OrigPath,string CD, + string File); + bool ReconstructChop(unsigned long &Chop,string Dir,string File); + void ConvertToSourceList(string CD,string &Path); + bool GrabFirst(string Path,string &To,unsigned int Depth); + bool CopyWithReplace(FileFd &Target,const char *Tag,string New); + virtual bool GetFile(string &Filename,unsigned long &Size) = 0; + virtual bool RewriteEntry(FileFd &Target,string File) = 0; + virtual const char *GetFileName() = 0; + virtual const char *Type() = 0; + public: + + bool CopyPackages(string CDROM,string Name,vector &List); +}; + +class PackageCopy : public IndexCopy +{ + protected: + + virtual bool GetFile(string &Filename,unsigned long &Size); + virtual bool RewriteEntry(FileFd &Target,string File); + virtual const char *GetFileName() {return "Packages";}; + virtual const char *Type() {return "Package";}; + + public: +}; + +class SourceCopy : public IndexCopy +{ + protected: + + virtual bool GetFile(string &Filename,unsigned long &Size); + virtual bool RewriteEntry(FileFd &Target,string File); + virtual const char *GetFileName() {return "Sources";}; + virtual const char *Type() {return "Source";}; + + public: +}; + +#endif diff --git a/apt/cmdline/makefile b/apt/cmdline/makefile new file mode 100644 index 0000000..f1221ba --- /dev/null +++ b/apt/cmdline/makefile @@ -0,0 +1,34 @@ +# -*- make -*- +BASE=.. +SUBDIR=cmdline + +# Bring in the default rules +include ../buildlib/defaults.mak + +# The apt-cache program +PROGRAM=apt-cache +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = apt-cache.cc +include $(PROGRAM_H) + +# The apt-get program +PROGRAM=apt-get +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = apt-get.cc acqprogress.cc +include $(PROGRAM_H) + +# The apt-config program +PROGRAM=apt-config +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = apt-config.cc +include $(PROGRAM_H) + +# The apt-cdrom program +PROGRAM=apt-cdrom +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = apt-cdrom.cc rpmindexcopy.cc +include $(PROGRAM_H) diff --git a/apt/cmdline/rpmindexcopy.cc b/apt/cmdline/rpmindexcopy.cc new file mode 100644 index 0000000..01ebffd --- /dev/null +++ b/apt/cmdline/rpmindexcopy.cc @@ -0,0 +1,233 @@ + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include + + +#include "rpmindexcopy.h" + + + +string RPMIndexCopy::RipComponent(string Path) +{ + const char *begin; + const char *end; + + end = strrchr(Path.c_str(), '.'); + begin = strchr(strrchr(Path.c_str(), '/'), '.') + 1; + if (begin < strrchr(end, '/')) + return string(end + 1); + + return string(begin, end); +} + + +string RPMIndexCopy::RipDistro(string Path) +{ + return string(Path, 0, Path.find("base")-1); +} + + +string RPMIndexCopy::RipDirectory(string Path) +{ + return string(Path, 0, Path.rfind('/')); +} + + +static int strrcmp_(const char *a, const char *b) +{ + int la = strlen(a); + int lb = strlen(b); + + if (la == 0 || lb == 0) + return 0; + + if (la > lb) + return strcmp(&a[la-lb], b); + else + return strcmp(&b[lb-la], a); +} + + +bool RPMIndexCopy::CopyPackages(string CDROM,string Name,vector &List) +{ + OpTextProgress Progress; + + if (List.size() == 0) + return true; + + // Prepare the progress indicator + unsigned long TotalSize = 0; + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + struct stat Buf; + if (stat((*I).c_str(),&Buf) != 0) + return _error->Errno("stat","Stat failed for %s", + (*I).c_str()); + TotalSize += Buf.st_size; + } + + unsigned long CurrentSize = 0; + + for (vector::iterator I = List.begin(); I != List.end(); I++) + { + string OrigPath = string(*I,CDROM.length()); + unsigned long FileSize = 0; + + // Open the package file + FileFd Pkg; + string File = *I; + + + if (strrcmp_(File.c_str(), + _config->Find("Acquire::ComprExtension").c_str()) == 0) + { + File = string(File, 0, + File.length() - _config->Find("Acquire::ComprExtension").length()); + } + + + if (FileExists(File) == true) + { + Pkg.Open(File,FileFd::ReadOnly); + FileSize = Pkg.Size(); + } + else + { + FileFd From(*I, FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + FileSize = From.Size(); + + // Get a temp file + FILE *tmp = tmpfile(); + if (tmp == 0) + return _error->Errno("tmpfile","Unable to create a tmp file"); + Pkg.Fd(dup(fileno(tmp))); + fclose(tmp); + + // Fork gzip + int Process = fork(); + if (Process < 0) + return _error->Errno("fork","Couldn't fork gzip"); + + // The child + if (Process == 0) + { + dup2(From.Fd(),STDIN_FILENO); + dup2(Pkg.Fd(),STDOUT_FILENO); + SetCloseExec(STDIN_FILENO,false); + SetCloseExec(STDOUT_FILENO,false); + + const char *Args[3]; + Args[0] = _config->Find("Dir::bin::gzip","gzip").c_str(); + Args[1] = "-d"; + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + // Wait for gzip to finish + if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false) + return _error->Error("gzip failed, perhaps the disk is full."); + + Pkg.Seek(0); + } + if (_error->PendingError() == true) + return false; + + // Open the output file + char S[400]; + sprintf(S,"cdrom:[%s]/%s",Name.c_str(), + File.c_str() + CDROM.length()); + string TargetF = _config->FindDir("Dir::State::lists") + "partial/"; + TargetF += URItoFileName(S); + if (_config->FindB("APT::CDROM::NoAct",false) == true) + TargetF = "/dev/null"; + FileFd Target(TargetF,FileFd::WriteEmpty); + if (_error->PendingError() == true) + return false; + + // Setup the progress meter + Progress.OverallProgress(CurrentSize,TotalSize,FileSize, + string("Reading Indexes")); + + // Parse + Progress.SubProgress(Pkg.Size()); + + if (!CopyFile(Pkg, Target)) + return false; + + if (_config->FindB("APT::CDROM::NoAct",false) == false) + { + // Move out of the partial directory + Target.Close(); + string FinalF = _config->FindDir("Dir::State::lists"); + FinalF += URItoFileName(S); + if (rename(TargetF.c_str(),FinalF.c_str()) != 0) + return _error->Errno("rename","Failed to rename"); + + string release = "release." + RipComponent(*I); + + // Copy the release file + sprintf(S,"cdrom:[%s]/%s%s",Name.c_str(), + RipDirectory(*I).c_str() + CDROM.length(), + release.c_str()); + string TargetF = _config->FindDir("Dir::State::lists") + "partial/"; + TargetF += URItoFileName(S); + if (FileExists(RipDirectory(*I) + release.c_str()) == true) + { + FileFd Target(TargetF,FileFd::WriteEmpty); + FileFd Rel(RipDirectory(*I) + release.c_str(),FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + + if (CopyFile(Rel,Target) == false) + return false; + } + else + { + // Empty release file + FileFd Target(TargetF,FileFd::WriteEmpty); + } + + // Rename the release file + FinalF = _config->FindDir("Dir::State::lists"); + FinalF += URItoFileName(S); + if (rename(TargetF.c_str(),FinalF.c_str()) != 0) + return _error->Errno("rename","Failed to rename"); + } + + string Prefix = ""; + /* Mangle the source to be in the proper notation with + prefix dist [component] */ +// *I = string(*I,Prefix.length()); + ConvertToSourceList(CDROM,*I); + *I = Prefix + ' ' + *I; + + CurrentSize += FileSize; + } + Progress.Done(); + + return true; +} + + + + +void RPMIndexCopy::ConvertToSourceList(string CD, string &Path) +{ + Path = string(Path, CD.length()); + + Path = RipDistro(Path) + " " + RipComponent(Path); +} + diff --git a/apt/cmdline/rpmindexcopy.h b/apt/cmdline/rpmindexcopy.h new file mode 100644 index 0000000..e0f0aad --- /dev/null +++ b/apt/cmdline/rpmindexcopy.h @@ -0,0 +1,50 @@ + +/* ###################################################################### + + Index Copying - Aid for copying and verifying the index files + + ##################################################################### + */ + +#ifndef RPMINDEXCOPY_H +#define RPMINDEXCOPY_H + +#include +#include + +class pkgTagSection; +class FileFd; + +class RPMIndexCopy +{ + protected: + + string RipComponent(string Path); + string RipDirectory(string Path); + string RipDistro(string Path); + + void ConvertToSourceList(string CD, string &Path); + + public: + bool CopyPackages(string CDROM,string Name,vector &List); +}; + + +class RPMPackageCopy : public RPMIndexCopy +{ + protected: + + + public: +}; + + +class RPMSourceCopy : public RPMIndexCopy +{ + protected: + + + public: +}; + +#endif diff --git a/apt/configure.in b/apt/configure.in new file mode 100644 index 0000000..840606b --- /dev/null +++ b/apt/configure.in @@ -0,0 +1,221 @@ +dnl Process this file with autoconf to produce a configure script. +dnl The ONLY thing this is used for is to configure for different +dnl linux architectures and configurations, it is not used to make the +dnl code more portable + +dnl You MUST have an environment that has all the POSIX functions and +dnl some of the more populare bsd/sysv ones (like select). You'll also +dnl need a C++ compiler that is semi-standard conformant, exceptions are +dnl not used but STL is. + +dnl 'make -f Makefile startup' will generate the configure file from +dnl configure.in correctly and can be run at any time + +AC_INIT(configure.in) +AC_CONFIG_AUX_DIR(buildlib) +AC_CONFIG_HEADER(include/config.h:buildlib/config.h.in) + +dnl -- SET THIS TO THE RELEASE VERSION -- +AC_DEFINE_UNQUOTED(VERSION,"0.3.19cnc55") +PACKAGE="apt" +AC_DEFINE_UNQUOTED(PACKAGE,"$PACKAGE") +AC_SUBST(PACKAGE) +AC_SUBST(VERSION) + +dnl Check the archs, we want the target type. +AC_CANONICAL_SYSTEM + +dnl Check our C compiler +AC_CHECK_TOOL_PREFIX +AC_PROG_CC +AC_ISC_POSIX + +dnl Check for other programs +AC_PROG_CXX +AC_PROG_CPP +AC_PROG_RANLIB +AC_PROG_INSTALL +AC_CHECK_TOOL(AR,ar,"ar") + + +ALL_LINGUAS="pt_BR es_ES it_IT ru" + +dnl Check for i18n stuff through gettext +AM_GNU_GETTEXT +AC_CHECK_HEADERS(libintl.h) + +LOCALEDIR="/usr/share/locale" +AC_DEFINE_UNQUOTED(LOCALEDIR, "$LOCALEDIR") +AC_SUBST(LOCALEDIR) + +dnl Checks for sockets +SAVE_LIBS="$LIBS" +LIBS="" +AC_SEARCH_LIBS(gethostbyname,nsl) +AC_SEARCH_LIBS(connect,socket) +SOCKETLIBS="$LIBS" +AC_SUBST(SOCKETLIBS) +LIBS="$SAVE_LIBS" + +dnl Checks for pthread -- disabled due to glibc bugs jgg +dnl AC_CHECK_LIB(pthread, pthread_create,[AC_DEFINE(HAVE_PTHREAD) PTHREADLIB="-lpthread"]) +AC_SUBST(PTHREADLIB) +dnl if test "$PTHREADLIB" != "-lpthread"; then +dnl AC_MSG_ERROR(failed: I need posix threads, pthread) +dnl fi + +dnl Check for DB2 +AC_CHECK_HEADER(db2/db.h, + [AC_CHECK_LIB(db2,db_open, + [AC_DEFINE(HAVE_DB2) DB2LIB="-ldb2"])]) +AC_SUBST(DB2LIB) + + +dnl Check for rpm version --akk +rpm_version="none" +SAVE_LIBS="$LIBS" +SAVE_CPPFLAGS="$CPPFLAGS" + +CPPFLAGS="$SAVE_CPPFLAGS -I/usr/include/rpm" +AC_CHECK_HEADERS(db1/db.h) +AC_CHECK_HEADER(rpm/rpmlib.h, rpm_header_ok=1, rpm_header_ok=0) + +if test $rpm_header_ok = 1; then + + LIBS="$SAVE_LIBS -lrpm -lrpmio -lz -lbz2 -lpopt" + AC_CHECK_LIB(rpmdb,rpmdbOpen, + [RPMDBLIBS="-lrpmdb"], + [RPMDBLIBS="-ldb-3.1"]) + + LIBS="$SAVE_LIBS $RPMDBLIBS -lrpmio -lz -lbz2 -lpopt" + AC_CHECK_LIB(rpm,rpmdbGetIteratorOffset, + [AC_DEFINE_UNQUOTED(HAVE_RPM, 1) AC_DEFINE_UNQUOTED(HAVE_RPM4, 1) + RPMLIBS="-lrpm $RPMDBLIBS -lrpmio -lz -lbz2 -lpopt" + SAVE_CPPFLAGS="$SAVE_CPPFLAGS -I/usr/include/rpm" + rpm_version="4"]) + + if test $rpm_version = "none"; then + LIBS="$SAVE_LIBS -ldb1 -lz -lbz2 -lpopt" + AC_CHECK_LIB(rpm,rpmdbFirstRecNum, + [AC_DEFINE_UNQUOTED(HAVE_RPM, 1) + RPMLIBS="-lrpm -ldb1 -lz -lbz2 -lpopt" + SAVE_CPPFLAGS="$SAVE_CPPFLAGS -I/usr/include/rpm" + rpm_version="3"]) + fi +fi +AC_MSG_CHECKING(for RPM version) +AC_MSG_RESULT($rpm_version) + +AC_SUBST(RPMLIBS) +CPPFLAGS="$SAVE_CPPFLAGS" +LIBS="$SAVE_LIBS" + + +dnl Converts the ARCH to be something singular for this general CPU family +dnl This is often the dpkg architecture string. +AC_MSG_CHECKING(system architecture) +archset="`awk \" ! /^#|^\\\$/ { if(match(\\\"$target_cpu\\\",\\\"^\\\"\\\$1\\\"\\\$\\\")) {print \\\$2; exit}}\" $srcdir/buildlib/archtable`" +if test "x$archset" = "x"; then + AC_MSG_ERROR(failed: use --host=) +fi +AC_MSG_RESULT($archset) +AC_DEFINE_UNQUOTED(COMMON_CPU,"$archset") + +dnl Get a common name for the host OS - this is primarily only for HURD and is +dnl non fatal if it fails +AC_MSG_CHECKING(system OS) +osset="`awk \" ! /^#|^\\\$/ {if (match(\\\"$target_vendor-$target_os\\\",\\\$1)) {print \\\$2; exit}}\" $srcdir/buildlib/ostable`" +AC_MSG_RESULT($osset) +AC_DEFINE_UNQUOTED(COMMON_OS,"$osset") + +dnl We use C99 types if at all possible +AC_CACHE_CHECK([for C99 integer types],c9x_ints,[ + AC_TRY_COMPILE([#include ], + [uint8_t Foo1;uint16_t Foo2;uint32_t Foo3;], + c9x_ints=yes,c9x_ints=no)]) + +dnl Single Unix Spec statvfs +AC_CHECK_FUNC(statvfs,[HAVE_STATVFS=yes]) +AC_SUBST(HAVE_STATVFS) + +dnl Arg, linux and bsd put their statfs function in different places +if test x"$HAVE_STATVFS" != x"yes"; then + AC_EGREP_HEADER(statfs,sys/vfs.h,[AC_DEFINE(HAVE_VFS_H)],[ + AC_EGREP_HEADER(statfs,sys/mount.h,[AC_DEFINE(HAVE_MOUNT_H)],[AC_MSG_ERROR(failed: Need statvfs)]) + ]) +fi + +dnl Check the sizes etc. of the architecture +dnl This is stupid, it should just use the AC macros like it does below +dnl Cross compilers can either get a real C library or preload the cache +dnl with their size values. +changequote(,) +archline="`awk \" ! /^#|^\\\$/ {if (match(\\\"$archset\\\",\\\$1)) {print; exit}}\" $srcdir/buildlib/sizetable | cut -f 2- -d ' '`" +if test "x$archline" != "x"; then + changequote([,]) + set $archline + if test "$1" = "little"; then + ac_cv_c_bigendian=no + else + ac_cv_c_bigendian=yes + fi + size_char=$2 + size_int=$3 + size_short=$4 + size_long=$5 +fi + +dnl I wonder what AC_C_BIGENDIAN does if you cross compile... +dnl This is probably bogus, as above we only care if we have to build our own +dnl C9x types. +if test "$cross_compiling" = "yes" -a "x$archline" = "x"; then + AC_MSG_ERROR(When cross compiling, architecture must be present in sizetable) +fi +AC_C_BIGENDIAN + +dnl We do not need this if we have inttypes! +HAVE_C9X=yes +if test x"$c9x_ints" = x"no"; then + AC_CHECK_SIZEOF(char,$size_char) + AC_CHECK_SIZEOF(int,$size_int) + AC_CHECK_SIZEOF(short,$size_short) + AC_CHECK_SIZEOF(long,$size_long) + + HAVE_C9X= + AC_SUBST(HAVE_C9X) +fi + +dnl HP-UX sux.. +AC_MSG_CHECKING(for missing socklen_t) +AC_EGREP_HEADER(socklen_t, sys/socket.h,[AC_MSG_RESULT(no)],[ + AC_DEFINE(NEED_SOCKLEN_T_DEFINE) + NEED_SOCKLEN_T_DEFINE=yes + AC_MSG_RESULT(missing.)]) +AC_SUBST(NEED_SOCKLEN_T_DEFINE) + +dnl HP-UX needs -d_XOPEN_SOURCE_EXTENDED for h_errno +AC_MSG_CHECKING(for h_errno) +AC_EGREP_HEADER(h_errno, netdb.h, [AC_MSG_RESULT(normal)], + [CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED" + AC_EGREP_HEADER(h_errno, netdb.h, + [AC_MSG_RESULT(needs _XOPEN_SOURCE_EXTENDED)], + [AC_MSG_ERROR("not found.")]) + ]) + +dnl Check for debiandoc +AC_PATH_PROG(DEBIANDOC_HTML,debiandoc2html) +AC_PATH_PROG(DEBIANDOC_TEXT,debiandoc2text) + +dnl Check for the SGML tools needed to build man pages +AC_PATH_PROG(NSGMLS,nsgmls) +AC_PATH_PROG(SGMLSPL,sgmlspl) + +dnl Check for YODL +dnl AC_CHECK_PROG(YODL_MAN,yodl2man,"yes","") + +ah_NUM_PROCS +rc_GLIBC_VER +rc_LIBSTDCPP_VER +ah_GCC3DEP + +AC_OUTPUT(po/Makefile.in intl/Makefile environment.mak:buildlib/environment.mak.in makefile:buildlib/makefile.in,make -s dirs) diff --git a/apt/debian/CVS/Entries b/apt/debian/CVS/Entries new file mode 100644 index 0000000..dfe51fe --- /dev/null +++ b/apt/debian/CVS/Entries @@ -0,0 +1,15 @@ +/changelog/1.1.1.1/Fri Aug 10 14:00:44 2001// +/control/1.1.1.1/Fri Aug 10 14:00:44 2001// +/copyright/1.1.1.1/Fri Aug 10 14:00:44 2001// +/dhelp/1.1.1.1/Fri Aug 10 14:00:44 2001// +/dirs/1.1.1.1/Fri Aug 10 14:00:44 2001// +/examples/1.1.1.1/Fri Aug 10 14:00:44 2001// +/libapt-pkg-dev.dirs/1.1.1.1/Fri Aug 10 14:00:44 2001// +/libapt-pkg-doc.dhelp/1.1.1.1/Fri Aug 10 14:00:44 2001// +/libapt-pkg-doc.postinst/1.1.1.1/Fri Aug 10 14:00:44 2001// +/libapt-pkg-doc.prerm/1.1.1.1/Fri Aug 10 14:00:44 2001// +/postinst/1.1.1.1/Fri Aug 10 14:00:45 2001// +/postrm/1.1.1.1/Fri Aug 10 14:00:45 2001// +/rules/1.1.1.1/Fri Aug 10 14:00:45 2001// +/shlibs.local/1.1.1.1/Fri Aug 10 14:00:45 2001// +D diff --git a/apt/debian/CVS/Repository b/apt/debian/CVS/Repository new file mode 100644 index 0000000..525781f --- /dev/null +++ b/apt/debian/CVS/Repository @@ -0,0 +1 @@ +rapt/debian diff --git a/apt/debian/CVS/Root b/apt/debian/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/debian/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/debian/changelog b/apt/debian/changelog new file mode 100644 index 0000000..aa047bc --- /dev/null +++ b/apt/debian/changelog @@ -0,0 +1,505 @@ +apt (0.3.19) frozen unstable; urgency=low + + * Updates to apt-cdrom to support integrated non-us nicely, thanks to + Paul Wade. + * Fixed that apt-get/cdrom deadlock thing. Closes: #59853, #62945, #61976 + * Fixed hardcoded path. Closes: #59743 + * Fixed Jay's relative path bug + * Allowed source only CDs. Closes: #58952 + * Space check is supressed if --print-uris is given. Closes: #58965 + * Clarified the documenation examples for non-us. Closes: #58646 + * Typo in the package description. Closes: #60230 + * Man Page typo. Closes: #60347 + * Typo in Algorithms.cc. Closes: #63577 + * Evil dotty function in apt-cache for generating dependency graphs + with the as-yet-unpackaged GraphVis. + * Appears to have been fixed in Janurary.. Closes: #57981 + * New config.guess/sub for the new archs. Closes: #60874 + * Fixed error reporting for certain kinds of resolution failures. + Closes: #61327 + * Made autoclean respect 'q' settings. Closes: #63023 + * Fixed up the example sources.list. Closes: #63676 + * Added DPkg::FlushSTDIN to control the flushing of stdin before + forking dpkg. Closes: #63991 + + -- Ben Gertzfield Fri, 12 May 2000 21:10:54 -0700 + +apt (0.3.18) frozen unstable; urgency=low + + * Changes in the postinst script. Closes: #56855, #57237 + * Fixed bashism. Closes: #57216, #57335 + * Doc updates. Closes: #57772, #57069, #57331, #57833, #57896 + + -- Ben Gertzfield Sun, 13 Feb 2000 01:52:31 -0800 + +apt (0.3.17) unstable; urgency=low + + * RFC 2732 usage for CDROM URIs and fixes to apt-cdrom + * Fixed the configuration parser to not blow up if ; is in the config + string + * Applied visual patch to dselect install script . Closes #55214 + * Included the configure-index example + * Minimal CD swaps + * Library soname has increased + * Fixed default sources.list to have correct URLs for potato when it + becomes stable + * Added a message about erasing sources.list to dselect setup script + Closes: #55755 + * No remove prompt if the archives dir has not changed. Closes: #55709 + * Fixed inclusion of 2nd sample config file. Closes: #55374 + * Made file mtimes of 0 not confuse the methods If-Modifed-Since check. + Closes: #55991 + + -- Ben Gertzfield Mon, 31 Jan 2000 12:12:40 -0800 + +apt (0.3.16) unstable; urgency=low + + * Made --no-download work. Closes: #52993 + * Now compiles on OpenBSD, Solaris and HP-UX + * Clarify segfault errors + * More debhelper fixes. Closes: #52662, #54566, #52090, #53531, #54769 + * Fix for Joel's discovery of glibc removal behavoir. + * Fix for Ben Collins file: uri from slink upgrade. + * Fixed resume code in FTP. Closes: #54323 + * Take more precautions to prevent the corruption Joey Hess saw. + * Fixed --no-list-cleanup + * RFC 2732 URI parsing ([] for hostnames). + * Typo in apt-cache man page. Closes: #54949 + + -- Ben Gertzfield Fri, 14 Jan 2000 08:04:15 -0800 + +apt (0.3.15) unstable; urgency=low + + * Added DSelect::WaitAfterDownload Closes: #49549 + * Fixed cast error in byteswap macro and supporting code. Closes: #50093 + * Fixed buffer overflow for wide terminal sizes. Closes: #50295 + * Made -s and clean not do anything. Closes: #50238 + * Problem with Protected packages and the new OR code. + * /usr/share/doc stuff. Closes: #51017, #50228, #51141 + * Remove doesn't require a package to be installable. Closes: #51175 + * FTP proxy touch ups in the mabn page. Closes: #51315, #51314 + + -- Ben Gertzfield Sat, 4 Dec 1999 21:17:24 -0800 + +apt (0.3.14) unstable; urgency=low + + * Fix Perl or group pre-depends thing Closes: #46091, #46096, #46233, #45901 + * Fix handling of dpkg's conversions from < -> <= Closes: #46094, #47088 + * Make unparsable priorities non-fatal Closes: #46266, #46267, #46293, #46298 + * Fix handling of '/' for the dist name. Closes: #43830, #45640, #45692 + * Fixed 'Method gave a blank filename' error from IMS queries onto CDs. + Closes: #45034, #45695, #46537 + * Made OR group handling in the problem resolver more elaborate. Closes: #45646 + * Added APT::Clean-Installed option. Closes: #45973 + * Moves the free space check to after the calculated size is printed. + Closes: #46639, #47498 + * mipsel arch Closes: #47614 + * Beautified URI printing to not include passwords Closes: #46857 + * Fixed little problem with --no-download Closes: #47557 + * Tweaked Dselect 'update' script to re-gen the avail file even in the + event of a failure Closes: #47112 + * Retries for source archives too Closes: #47529 + * Unmounts CDROMs iff it mounted them Closes: #45299 + * Checks for the partial directories before doing downloads Closes: #47392 + * no_proxy environment variable (http only!) Closes: #43476 + * apt-cache showsrc Closes: #45799 + * De-Refs Single Pure virtual packages. Closes: #42437, #43555 + * Regexs for install. Closes: #35304, #38835 + * Dependency reports now show OR group relations + * Re-Install feature. Cloes: #46961, #37393, #38919 + * Locks archive directory on clean (woops) + * Remove is not 'sticky'. Closes: #48392 + * Slightly more accurate 'can not find package' message. Closes: #48311 + * --trivial-only and --no-remove. Closes: #48518 + * Increased the cache size. Closes: #47648 + * Comment woopsie. Closes: #48789 + * Removes existing links when linking sources. Closes: #48775 + * Problem resolver does not install all virtual packages. Closes: #48591, #49252 + * Clearer usage message about 'source' Closes: #48858 + * Immediate configure internal error Closes: #49062, #48884 + + -- Ben Gertzfield Sun, 7 Nov 1999 20:21:25 -0800 + +apt (0.3.13) unstable; urgency=low + + * Fix timestamp miss in FTP. Closes: #44363 + * Fix sorting of Kept packages. Closes: #44377 + * Fix Segfault for dselect-upgrade. Closes: #44436 + * Fix handling of '/' for the dist name. Closes #43830 + * Added APT::Get::Diff-Only and Tar-Only options. Closes #44384 + * Add commented-out deb-src URI to default sources.list file. + + -- Ben Gertzfield Sun, 19 Sep 1999 18:54:20 -0700 + +apt (0.3.12) unstable; urgency=low + + * Fix for typo in the dhelp index. Closes: #40377 + * Multiple media swap support + * Purge support. Closes: #33291, #40694 + * Better handling of - remove notation. Closes: #41024 + * Purge support. Closes: #33291, #40694 + * Error code on failed update. Closes: #41053 + * apt-cdrom adds entries for source directories. Closes: #41231 + * Sorts the output of any list. Closes: #41107 + * Fixes the looping problem. Closes: #41784, #42414, #44022 + * Fixes the CRC mechanism to lowercase all strings. Closes: #41839 + * More checks to keep the display sane. Particularly when fail-over is + used with local mirrors and CD-Roms. Closes: #42127, #43130, #43668 + * PThread lockup problem on certain sparc/m68k. Closes: #40628 + * apt-cdrom understands .gz Package files too. Closes: #42779 + * Spelling error in dselect method description. Closes: #43251 + * Added security to the default source list. Closes: #43356 + + -- Ben Gertzfield Fri, 3 Sep 1999 09:04:28 -0700 + +apt (0.3.11) unstable; urgency=low + + * Fix for mis-parsed file: URIs. Closes: #40373, #40366, #40230 + * Fix for properly upgrading the system from perl 5.004 to 5.005 + + -- Ben Gertzfield Mon, 28 Jun 1999 21:06:44 -0700 + +apt (0.3.9) unstable; urgency=low + + * Spelling error in cachefile.cc. Closes: #39885 + * Trailing slash in dselect install if you try to use the + default config file. Closes: #40011 + * Simulate works for autoclean. Closes: #39141 + * Fixed spelling errors. Closes: #39673 + * Changed url parsing a bit. Closes: #40070, #40069 + * Version 0.3.8 will be for slink/hamm (GNU libc 2). + + -- Ben Gertzfield Thu, 24 Jun 1999 18:02:52 -0700 + +apt (0.3.7) unstable; urgency=low + + * Fixed missing text in the apt-get(8) page. Closes: #37596 + * Made --simulate and friends work with apt-get source. Closes: #37597, #37656 + * Fixed inclusion of man pages in the -doc/-dev package. Closes: #37633, #38651 + * Fixed handling of the -q option with not-entirely integer arguments + Closes: #37499 + * Man page typo Closes: #37762 + * Fixed parsing of the Source: line. Closes: #37679 + * Dpkg/dpkg-hurd source bug. Closes: #38004, #38032 + * Added a check for an empty cache directory. Closes: #37963 + * Return a failure code if -d is given and packages fail to download. + Closes: #38127 + * Arranged for an ftp proxy specifing an http server to work. See the + important note in the sources.list man page. + * Accounted for resumed files in the cps calculation. Closes: #36787 + * Deal with duplicate same version different packages. Closes: #30237 + * Added --no-download. Closes: #38095 + * Order of apt-cdrom dist detection. Closes: #38139 + * Fix apt-cdrom chop handling and missing lines. Closes: #37276 + * IPv6 http support + * Suggests dpkg-dev for apt-get source. Closes: #38158 + * Fixed typo in apt-get help. Closes: #38712 + * Improved the error message in the case of broken held package. Closes: #38777 + * Fixed handling of MD5 failures + * Documented list notation Closes: #39008 + * Change the 'b' to 'B'. Closes: #39007 + + -- Ben Gertzfield Sun, 20 Jun 1999 18:36:20 -0700 + +apt (0.3.6) unstable; urgency=low + + * Note that 0.3.5 never made it out the door.. + * Fix for apt-cdrom and unusual disk label locations. Closes: #35571 + * Made APT print numbers in decimal. Closes: #35617, #37319 + * Buffer munching fix for FTP. Closes: #35868 + * Typo in sample config file. Closes: #35907 + * Fixed whitespace in version compares. Closes: #35968, #36283, #37051 + * Changed installed size counter to only count unpacked packages. + Closes: #36201 + * apt-get source support. Closes: #23934, #27190 + * Renames .debs that fail MD5 checking, provides automatic corruption + recovery. Closes: #35931 + * Fixed autoconf verison. Closes: #37305 + * Random Segfaulting. Closes: #37312, #37530 + * Fixed apt-cache man page. Closes: #36904 + * Added a newline to apt-cache showpkg. Closes: #36903 + + -- Ben Gertzfield Wed, 12 May 1999 09:18:49 -0700 + +apt (0.3.4) unstable; urgency=low + + * Release for Ben while he is out of town. + * Checked the size of partial files. Closes: #33705 + * apt-get should not print progress on non-tty. Closes: #34944 + * s/guide.text.gz/users-guide.txt.gz/ debian/control: Closes: #35207 + * Applied cdrom patches from Torsten. Closes: #35140, #35141 + * smbmounted cdrom fix. Closes: #35470 + * Changed ie to eg. Closes: #35196 + + -- Adam Heath Sun, 4 Apr 1999 18:26:44 -0500 + +apt (0.3.3) unstable; urgency=low + + * Fixes bug with file:/ URIs and multi-CD handling. Closes: #34923 + + -- Ben Gertzfield Tue, 23 Mar 1999 12:15:44 -0800 + +apt (0.3.2) unstable; urgency=low + + * Major release into unstable of v3 + * These bugs have been fixed, explanations are in the bug system, read + the man pages as well.. + Closes: #21113, #22507, #22675, #22836, #22892, #32883, #33006, #34121, + #23984, #24685, #24799, #25001, #25019, #34223, #34296, #34355, + #24021, #25022, #25026, #25104, #25176, #31557, #31691, #31853, + #25458, #26019, #26433, #26592, #26670, #27100, #27100, #27601, + #28184, #28391, #28778, #29293, #29351, #27841, #28172, #30260, + #29382, #29441, #29903, #29920, #29983, #30027, #30076, #30112, + #31009, #31155, #31381, #31883, #32140, #32395, #32584. #34465, + #30383, #30441, #30472, #30643, #30827, #30324, #36425, #34596 + + -- Ben Gertzfield Mon, 15 Mar 1999 19:14:25 -0800 + +apt (0.3.1) experimental; urgency=low + + * Minor release of cvs version. + * Added virtual package libapt-pkgx.x + + -- Mitch Blevins Wed, 10 Mar 1999 07:52:44 -0500 + +apt (0.3.0) experimental; urgency=low + + * New experimental version. + + -- Ben Gertzfield Tue, 15 Dec 1998 12:53:21 -0800 + +apt (0.1.9) frozen unstable; urgency=low + + * Return to the wacky numbering for when we build 0.1.8 for hamm + * Important bug related to APT on the Alpha fixed + * apt-get dist-upgrade problems fixed + * tiny patch for http method to fix an endless loop + * nice fix from /usr/doc/lintian/ to remove rpath nastiness from + libtool and add proper shared lib dependancies + * now dh_shlibdeps is called with LD_LIBRARY_PATH=debian/tmp/usr/lib + in case an old libpkg is installed while building APT to prevent + spurious dependancies + + -- Ben Gertzfield Thu, 5 Nov 1998 17:43:25 -0800 + +apt (0.1.7) unstable; urgency=low + + * New build with libstdc++2.9. + * Various fixes; read the Changelog. + + -- Ben Gertzfield Thu, 15 Oct 1998 18:29:18 -0700 + +apt (0.1.6) unstable; urgency=low + + * Various fixes in the FTP method for error checking. Fixes: #26188. + * Spelling corrections in dselect method. Fixes: #25884 + * Fixes for compilation on alpha/ppc. Fixes: #25313, #26108. + * No more bo releases: we're using a normal numbering system now. + + -- Ben Gertzfield Tue, 8 Sep 1998 19:27:13 -0700 + +apt (0.1.5) unstable; urgency=low + + * Changed sources.list to point to 'unstable' by default, as + 'frozen' no longer exists! + + -- Ben Gertzfield Thu, 23 Jul 1998 22:00:18 -0700 + +apt (0.1.3) unstable; urgency=low + + * New upstreamish version. + * ftp method rewritten in C. Removes dependancies on all perl/perl + related modules. This fixes many of the ftp method bugs. + + -- Ben Gertzfield Thu, 16 Jul 1998 22:19:00 -0700 + +apt (0.1.1) unstable; urgency=low + + * Release for unstable. + + -- Ben Gertzfield Tue, 30 Jun 1998 20:48:30 -0700 + +apt (0.1) unstable; urgency=low + + * Kludge to fix problem in libnet-perl with illegal anonymous + FTP passwords. + * Moved to unstable; apt is in a useable state now. + * Fixed version numbering. From now on, numbering will be: + 0.1 (no actual release) -> 0.1.0bo (release for libc5) -> + 0.1.1 (release for unstable). Thanks, Manoj. + + -- Ben Gertzfield Tue, 30 Jun 1998 20:40:58 -0700 + +apt (0.0.17-1) experimental; urgency=low + + * Fixed problem with libc6 version compare + * Scott's away for a while, so I'll be packaging apt for the time + being. + + -- Ben Gertzfield Thu, 25 Jun 1998 19:02:03 -0700 + +apt (0.0.16-1) experimental; urgency=low + + * Modifications to make apt-get more friendly when backgrounded. + * Updated documentation. + * Updates to graphic widgets + + -- Scott K. Ellis Mon, 8 Jun 1998 11:22:02 -0400 + +apt (0.0.15-0.2bo) experimental; urgency=low + + * Bo compilation + * Bob Hilliards crash + + -- Jason Gunthorpe Sun, 31 May 1998 20:18:35 -0600 + +apt (0.0.15-0.1bo) experimental; urgency=low + + * Bo compilation + * libstdc++272 patch + + -- Jason Gunthorpe Sun, 31 May 1998 20:18:35 -0600 + +apt (0.0.15) experimental; urgency=low + + * Clean up source tarball (no user-visible changes) + + -- Scott K. Ellis Tue, 26 May 1998 12:23:53 -0400 + +apt (0.0.14) experimental; urgency=low + + * Updates in ordering code to make sure certain upgrades work correctly. + * Made dselect/setup understand ftp as well as http + + -- Scott K. Ellis Wed, 20 May 1998 13:33:32 -0400 + +apt (0.0.13-bo1) experimental; urgency=low + + * Bo compilation + + -- Jason Gunthorpe Mon, 18 May 1998 15:10:49 -0600 + +apt (0.0.13) experimental; urgency=low + + * Remove hardcoded egcc from debian/rules (#21575) + * Fixes for ordering logic when system has a number of unpacked + but unconfigured packages installed. + * Spelling fix in dselect install method (#22556) + + -- Scott K. Ellis Sun, 17 May 1998 20:08:33 -0400 + +apt (0.0.12) experimental; urgency=low + + * Fixed problems with package cache corruption. + * Made to depend on libc6 >= 2.0.7pre1 due to timezone problems with + earlier versions. + * Interface and documentation improvements. + + -- Scott K. Ellis Sat, 16 May 1998 23:17:32 -0400 + +apt (0.0.11) experimental; urgency=low + + * Change dependancies to pre-depends since breaking your packaging tools + in the middle of an installation isn't very good. + * Bug fixes to ftp method and general apt-get code + + -- Scott K. Ellis Fri, 15 May 1998 08:57:38 -0400 + +apt (0.0.10) experimental; urgency=low + + * Run "dpkg --configure -a" after an aborted dselect install + * Fixed problem with install looping + * Support for authenticating proxys: (note this isn't terribly secure) + http_proxy="http://user:pass@firewall:port/" + * Substitute $ARCH in sources.list + * Fixes in the resumption code for ftp + + -- Scott K. Ellis Tue, 12 May 1998 09:14:41 -0400 + +apt (0.0.9) experimental; urgency=low + + * Added ftp support. + * Various other less visible bug fixes. + * Fixed problem with segfault when apt-get invoked in a non-existant + directory (Bug #21863) + * Bumped policy to 2.4.1 + + -- Scott K. Ellis Fri, 1 May 1998 09:18:19 -0400 + +apt (0.0.8) experimental; urgency=low + + * Fixed generated available file (Bug #21836) + * Added download ETA (Bug #21774). + * Fixed hardcoded ARCH (Bug #21751). + * Fixed check on http_proxy (Bug #21795). + * Added download speed indicator. + + -- Scott K. Ellis Mon, 27 Apr 1998 10:58:32 -0400 + +apt (0.0.7) experimental; urgency=low + + * Remove libdeity and apt from package for now, since only apt-get and + apt-cache are actually useful right now. + * Clean up handling of package installation errors. + * Added timeout to http transfers (#21269) + * Updated setup for dselect/apt method. + * Updated man pages + * Long options (added in 0.0.6) + + -- Scott K. Ellis Tue, 21 Apr 1998 09:06:49 -0400 + +apt (0.0.6) experimental; urgency=low + + * Spelling changes. + * Revamped download status display. + * Call apt-get clean after successful install in dselect. + * Added "apt-get clean" which deletes package files from /var/cache/apt + + -- Scott K. Ellis Thu, 9 Apr 1998 15:13:59 -0400 + +apt (0.0.5) experimental; urgency=low + + * Ignore signals while dpkg is running so we don't leave dpkg running in + the background (#20804) + * Check Packages as well as Packages.gz for file URIs (#20784) + * Spelling cleanup (#20800) + * Added -m option to permit upgrade to go on in the case of a bad mirror. + This option may result in incomplete upgrades when used with -f. + + -- Scott K. Ellis Tue, 7 Apr 1998 12:40:29 -0400 + +apt (0.0.4) experimental; urgency=low + + * New usage guide. + * Various documentation updates and cleanup. + * Added '-f' option to apt-get attempt to fix broken dependancies. + + -- Scott K. Ellis Sat, 4 Apr 1998 14:36:00 -0500 + +apt (0.0.3) experimental; urgency=low + + * Added a shlibs.local file to prevent apt from depending on itself. + * Updates to how apt-get handles bad states in installed packages. + * Updated rules to make sure build works from a freshly checked out source + archive. Building from CVS needs libtool/automake/autoconf, builds from + the distributed source package should have no such dependancy. + + -- Scott K. Ellis Fri, 3 Apr 1998 11:49:47 -0500 + +apt (0.0.2) unstable; urgency=low + + * Updates to apt-get and http binding for dselect method (apt). + * Updating version number from 0.0.1, which was released only on IRC. + + -- Scott K. Ellis Fri, 3 Apr 1998 00:35:18 -0500 + +apt (0.0.1) unstable; urgency=low + + * Initial Release. + + -- Scott K. Ellis Tue, 31 Mar 1998 12:49:28 -0500 + +Local variables: +mode: debian-changelog +add-log-mailing-address: "che@debian.org" +End: diff --git a/apt/debian/control b/apt/debian/control new file mode 100644 index 0000000..e462692 --- /dev/null +++ b/apt/debian/control @@ -0,0 +1,39 @@ +Source: apt +Section: admin +Priority: standard +Maintainer: APT Development Team +Standards-Version: 2.4.1 +Build-Depends: debhelper, debiandoc-sgml + +Package: apt +Architecture: any +Depends: ${shlibs:Depends} +Priority: standard +Conflicts: deity +Replaces: deity, libapt-pkg-doc (<< 0.3.7), libapt-pkg-dev (<< 0.3.7) +Provides: libapt-pkg${libapt-pkg:major} +Suggests: dpkg-dev +Description: Advanced front-end for dpkg + This is Debian's next generation front-end for the dpkg package manager. + It provides the apt-get utility and APT dselect method that provides a + simpler, safer way to install and upgrade packages. + . + APT features complete installation ordering, multiple source capability + and several other unique features, see the Users Guide in + /usr/doc/apt/guide.text.gz + +Package: libapt-pkg-dev +Architecture: any +Priority: optional +Depends: libapt-pkg${libapt-pkg:major} +Description: Development files for APT's libapt-pkg + This package contains the header files and static libraries for + developing with APT's libapt-pkg Debian package manipulation + library. + +Package: libapt-pkg-doc +Architecture: all +Priority: optional +Description: Documentation for APT development + This package contains documentation for development of the APT + Debian package manipulation program and its libraries. diff --git a/apt/debian/copyright b/apt/debian/copyright new file mode 100644 index 0000000..16f8cac --- /dev/null +++ b/apt/debian/copyright @@ -0,0 +1,4 @@ +APT is free software; you can redistribute them and/or modify them under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. diff --git a/apt/debian/dhelp b/apt/debian/dhelp new file mode 100644 index 0000000..e24a7c0 --- /dev/null +++ b/apt/debian/dhelp @@ -0,0 +1,21 @@ + +debian +Debian Utilities +APT User's Guide +guide.html/index.html + +The APT User's Guide provides an overview of how to use the the APT package +manager, and provides a detailed look at the apt-get tool. + + + + +debian +Debian Utilities +APT Offline Usage Guide +offline.html/index.html + +The APT Offline Usage Guide provides detailed instructions and examples +of how to use APT on an unconnected computer. + + diff --git a/apt/debian/dirs b/apt/debian/dirs new file mode 100644 index 0000000..1551a20 --- /dev/null +++ b/apt/debian/dirs @@ -0,0 +1,6 @@ +usr/bin +usr/lib/apt/methods +usr/lib/dpkg/methods/apt +etc/apt +var/cache/apt/archives/partial +var/state/apt/lists/partial diff --git a/apt/debian/examples b/apt/debian/examples new file mode 100644 index 0000000..e69de29 diff --git a/apt/debian/libapt-pkg-dev.dirs b/apt/debian/libapt-pkg-dev.dirs new file mode 100644 index 0000000..844642a --- /dev/null +++ b/apt/debian/libapt-pkg-dev.dirs @@ -0,0 +1,2 @@ +usr/lib +usr/include/apt-pkg diff --git a/apt/debian/libapt-pkg-doc.dhelp b/apt/debian/libapt-pkg-doc.dhelp new file mode 100644 index 0000000..7458cd0 --- /dev/null +++ b/apt/debian/libapt-pkg-doc.dhelp @@ -0,0 +1,61 @@ + +devel +Development Tools +APT Cache Specification +../apt/cache.html/index.html + +The APT Cache Specification describes the complete implementation and +format of the APT Cache file. The APT Cache file is a way for APT to parse +and store a large number of package files for display in the UI. It's primary +design goal is to make display of a single package in the tree very +fast by pre-linking important things like dependencies and provides. +The specification doubles as documentation for one of the in-memory +structures used by the package library and the APT GUI. + + + + +devel +Development Tools +APT Design Document +../apt/design.html/index.html + +The APT Design Document is an overview of the specifications and design goals +of the APT project. It also attempts to give a broad description of the +implementation as well. + + + + +devel +Development Tools +DPkg Technical Manual +../apt/design.html/index.html + +The DPkg Technical Manual gives an overview of dpkg's external functions +and describes how it views the world. + + + + +devel +Development Tools +APT Files +../apt/files.html/index.html + +The APT Files document describes the complete implementation and format of +the installed APT directory structure. It also serves as guide to how +APT views the Debian archive. + + + + +devel +Development Tools +APT Method Interface +../apt/method.html/index.html + +The APT Method Interface document describes the interface that APT uses to +the archive access methods. + + diff --git a/apt/debian/libapt-pkg-doc.postinst b/apt/debian/libapt-pkg-doc.postinst new file mode 100755 index 0000000..aa8aac4 --- /dev/null +++ b/apt/debian/libapt-pkg-doc.postinst @@ -0,0 +1,11 @@ +#! /bin/sh + +case "$1" in + configure) + if [ -f /usr/sbin/dhelp_parse ]; then + /usr/sbin/dhelp_parse -a /usr/doc/libapt-pkg-doc + fi + ;; +esac + +#DEBHELPER# diff --git a/apt/debian/libapt-pkg-doc.prerm b/apt/debian/libapt-pkg-doc.prerm new file mode 100755 index 0000000..6d28b6b --- /dev/null +++ b/apt/debian/libapt-pkg-doc.prerm @@ -0,0 +1,13 @@ +#! /bin/sh + +case "$1" in + remove|upgrade|remove-in-favour|deconfigure-in-favour) + if [ -f /usr/sbin/dhelp_parse ]; then + /usr/sbin/dhelp_parse -d /usr/doc/libapt-pkg-doc + fi + ;; + failed-upgrade) + ;; +esac + +#DEBHELPER# diff --git a/apt/debian/postinst b/apt/debian/postinst new file mode 100755 index 0000000..9f0a3d5 --- /dev/null +++ b/apt/debian/postinst @@ -0,0 +1,45 @@ +#! /bin/sh + +# apt postinst, based liberally on James Troup's gpm postinst +# Copyright (C) 1998, Ben Gertzfield + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +set -e + +create_apt_conf () +{ + echo "/etc/apt/sources.list does not exist; creating a default setup." + + cp /usr/doc/apt/examples/sources.list /etc/apt/sources.list +} + +check_apt_conf () +{ + true + # this is for future expansion +} + +#DEBHELPER# + +case "$1" in + configure) + ldconfig + # + # If there is no /etc/apt/sources.list then create a default + # + if [ ! -f /etc/apt/sources.list ]; then + create_apt_conf + echo + echo "If you wish to change the default sites from which APT fetches Debian" + echo "packages, please edit the file /etc/apt/sources.list." + else + check_apt_conf + fi + if [ -f /usr/sbin/dhelp_parse ]; then + /usr/sbin/dhelp_parse -a /usr/doc/apt + fi +esac diff --git a/apt/debian/postrm b/apt/debian/postrm new file mode 100755 index 0000000..6252800 --- /dev/null +++ b/apt/debian/postrm @@ -0,0 +1,20 @@ +#! /bin/sh + +# apt postrm +# Copyright (C) 1998, Ben Gertzfield + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. + +case "$1" in + purge) + echo -n "Removing APT cache and state files... " + echo -n "/var/cache/apt" + rm -rf /var/cache/apt + echo -n ", /var/state/apt" + rm -rf /var/state/apt + echo ". Done." +esac + diff --git a/apt/debian/rules b/apt/debian/rules new file mode 100755 index 0000000..f3567e9 --- /dev/null +++ b/apt/debian/rules @@ -0,0 +1,231 @@ +#!/usr/bin/make -f +# Made with the aid of dh_make, by Craig Small +# Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess. +# Some lines taken from debmake, by Christoph Lameter. +# $Id: rules,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + +# For the deb builder, you can run 'debian/rules cvs-build', which does all +# steps nescessary to produce a proper source tarball with the CVS/ removed. +# It builds in debian/cvs-build/apt-/, and places files in +# debian/cvs-build/. Optionally, you can run 'debian/rules cvs-mkul' to +# create ../upload-, with all the files needed to be uploaded placed +# in it. + +DEB_BUILD_PROG:=debuild -us -uc +APT_DEBVER=$(shell dpkg-parsechangelog |sed -n -e '/^Version:/s/^Version: //p') +APT_CONFVER=$(shell sed -n -e 's/^AC_DEFINE_UNQUOTED(VERSION,"\(.*\)")/\1/p' configure.in) + +# Determine the build directory to use +BASE=. +ifdef BUILD +BUILD_POSSIBLE := $(BUILD) $(BASE)/$(BUILD) +else +BUILD_POSSIBLE := $(BASE) $(BASE)/build-$(shell uname -m) $(BASE)/build +endif +BUILDX:= $(foreach i,$(BUILD_POSSIBLE),$(wildcard $(i)/environment.mak*)) +BUILDX:= $(patsubst %/,%,$(firstword $(dir $(BUILDX)))) +override BLD := $(BUILDX) + +ifeq ($(words $(BLD)),0) +override BLD := ./build +endif + +ifneq ($(APT_DEBVER),$(APT_CONFVER)) +.PHONY: configure.in +configure.in: + sed -e 's/$(APT_CONFVER)/$(APT_DEBVER)/' $@ > $@.$$$$;mv $@.$$$$ $@ +else +configure.in: +endif + +# Uncomment this to turn on verbose mode. +#export DH_VERBOSE=1 + +# Find the libapt-pkg major version for use in other control files +export LIBAPT_MAJOR:=$(shell egrep '^MAJOR=' apt-pkg/makefile |cut -d '=' -f 2) +#debian/shlibs.local: +# rm -f $@ +# echo "libapt-pkg $(LIBAPT_MAJOR) libapt-pkg$(LIBAPT_MAJOR)" >> $@ +# echo "libapt-pkg $(LIBAPT_MAJOR) apt $(APT_DEBVER)" >> $@ + +build: build-stamp +build-stamp: configure + dh_testdir + -mkdir build + (cd build; ../configure) +# cd build && CXXFLAGS="-g -Wall -D_POSIX_C_SOURCE=199309" ../configure --disable-nls --disable-static --prefix=/usr +# cd build && make all-hdr +# cd build && make -s + + # Add here commands to compile the package. + make + touch build-stamp + +clean: + dh_testdir +# dh_testroot + rm -f build-stamp + rm -rf build + + # Add here commands to clean up after the build process. + -$(MAKE) clean + -$(MAKE) distclean + dh_clean + +binary-indep: libapt-pkg-doc +# Build architecture-independent files here. +libapt-pkg-doc: build debian/shlibs.local + dh_testdir -p$@ + dh_testroot -p$@ + dh_clean -p$@ -k + dh_installdirs -p$@ +# +# libapt-pkg-doc install +# + dh_installdocs -p$@ $(BLD)/docs/cache* $(BLD)/docs/design* $(BLD)/docs/dpkg-tech* \ + $(BLD)/docs/files* $(BLD)/docs/method* + + -cp -a debian/libapt-pkg-doc.dhelp debian/libapt-pkg-doc/usr/doc/libapt-pkg-doc/.dhelp + -cp -a debian/libapt-pkg-doc.dhelp debian/libapt-pkg-doc/usr/share/doc/libapt-pkg-doc/.dhelp + + dh_installexamples -p$@ +# dh_installmenu -p$@ +# dh_installinit -p$@ +# dh_installcron -p$@ +# dh_installmanpages -p$@ + +# dh_undocumented -p$@ + dh_installchangelogs -p$@ + dh_strip -p$@ + dh_compress -p$@ + dh_fixperms -p$@ +# dh_suidregister -p$@ + dh_installdeb -p$@ + dh_gencontrol -p$@ -u -Vlibapt-pkg:major=${LIBAPT_MAJOR} + dh_md5sums -p$@ + dh_builddeb -p$@ + + +# Build architecture-dependent files here. + +binary-arch: apt libapt-pkg-dev +apt: build debian/shlibs.local + dh_testdir -p$@ + dh_testroot -p$@ + dh_clean -p$@ -k + dh_installdirs -p$@ +# +# apt install +# + cp $(BLD)/bin/apt-* debian/tmp/usr/bin/ + + # install the shared libs + find $(BLD)/bin/ -type f -name "libapt-pkg.so.*" -exec cp -a "{}" debian/tmp/usr/lib/ \; + find $(BLD)/bin/ -type l -name "libapt-pkg.so.*" -exec cp -a "{}" debian/tmp/usr/lib/ \; + + cp $(BLD)/bin/methods/* debian/tmp/usr/lib/apt/methods/ + + cp $(BLD)/scripts/dselect/* debian/tmp/usr/lib/dpkg/methods/apt/ + + # Copy the guides + dh_installdocs -p$@ $(BLD)/docs/guide.text $(BLD)/docs/guide.html \ + $(BLD)/docs/offline.text $(BLD)/docs/offline.html + + # One or the other.. + -cp -a debian/dhelp debian/tmp/usr/doc/apt/.dhelp + -cp -a debian/dhelp debian/tmp/usr/share/doc/apt/.dhelp + +# head -n 500 ChangeLog > debian/ChangeLog + + dh_installexamples -papt $(BLD)/docs/examples/* + dh_installmanpages -p$@ + + dh_installchangelogs -p$@ + dh_strip -p$@ + dh_compress -p$@ + dh_fixperms -p$@ + dh_installdeb -p$@ + LD_LIBRARY_PATH=`pwd`/debian/tmp/usr/lib dh_shlibdeps -papt + dh_gencontrol -p$@ -u -Vlibapt-pkg:major=${LIBAPT_MAJOR} + dh_makeshlibs -m${LIBAPT_MAJOR} -Vlibapt-pkg${LIBAPT_MAJOR} -papt + dh_md5sums -p$@ + dh_builddeb -p$@ + +libapt-pkg-dev: build debian/shlibs.local + dh_testdir -p$@ + dh_testroot -p$@ + dh_clean -p$@ -k + dh_installdirs -p$@ +# +# libapt-pkg-dev install +# + cp -a $(BLD)/bin/libapt-pkg.so debian/libapt-pkg-dev/usr/lib/ + #ln -s libapt-pkg.so.${LIBAPT_MAJOR} debian/libapt-pkg-dev/usr/lib/libapt-pkg.so + cp $(BLD)/include/apt-pkg/*.h debian/libapt-pkg-dev/usr/include/apt-pkg/ + + dh_installdocs -p$@ +# dh_installmenu -papt +# dh_installinit -papt +# dh_installcron -papt +# dh_installmanpages -p$@ + + dh_installchangelogs -p$@ + dh_strip -p$@ + dh_compress -p$@ + dh_fixperms -p$@ +# dh_suidregister -p$@ + dh_installdeb -p$@ + dh_gencontrol -p$@ -u -Vlibapt-pkg:major=${LIBAPT_MAJOR} + dh_md5sums -p$@ + dh_builddeb -p$@ + +source diff: + @echo >&2 'source and diff are obsolete - use dpkg-source -b'; false + +# Update from CVS +l33ch: really-clean + cvs update + buildlib/mkChangeLog + +# Update from CVS and then configure for build +super-l33ch: l33ch Makefile.in + +configure: + make configure + +l33ch-stamp: super-l33ch + touch l33ch-stamp + +really-clean: clean + -find -name Makefile.in -print0 | xargs -0r rm -f + find -name ChangeLog | xargs rm -f + rm -f l33ch-stamp + +binary: binary-indep binary-arch +.PHONY: build clean binary-indep binary-arch binary debian/shlibs.local + + +# Done by the uploader. +#cvs update.. +#edit debian/changelog +# configure.in has the version automatically updated now. +# edit configure.in +# debian/rules cvs-build + +cvs-build: + rm -rf debian/cvs-build + cvs update + buildlib/mkChangeLog + make startup + make doc + tar c --exclude CVS --exclude debian/cvs-build . |\ + (mkdir -p debian/cvs-build/apt-$(APT_DEBVER);cd debian/cvs-build/apt-$(APT_DEBVER);tar x) +# The next line isn't needed, as debuild will make the .tar.gz for us. +# (cd debian/cvs-build;tar zcf apt_$(APT_DEBVER).tar.gz apt-$(APT_DEBVER)) + (cd debian/cvs-build/apt-$(APT_DEBVER);$(DEB_BUILD_PROG)) + rm ChangeLog + +cvs-mkul: + -mkdir -p ../upload-$(APT_DEBVER) + cp `find debian/cvs-build -maxdepth 1 -type f` ../upload-$(APT_DEBVER) diff --git a/apt/debian/shlibs.local b/apt/debian/shlibs.local new file mode 100644 index 0000000..ab3c9c3 --- /dev/null +++ b/apt/debian/shlibs.local @@ -0,0 +1,2 @@ +libpkg 0 +libdeity 0 diff --git a/apt/deity/CVS/Entries b/apt/deity/CVS/Entries new file mode 100644 index 0000000..1784810 --- /dev/null +++ b/apt/deity/CVS/Entries @@ -0,0 +1 @@ +D diff --git a/apt/deity/CVS/Repository b/apt/deity/CVS/Repository new file mode 100644 index 0000000..21b3851 --- /dev/null +++ b/apt/deity/CVS/Repository @@ -0,0 +1 @@ +rapt/deity diff --git a/apt/deity/CVS/Root b/apt/deity/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/deity/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/doc/Bugs b/apt/doc/Bugs new file mode 100644 index 0000000..332abc5 --- /dev/null +++ b/apt/doc/Bugs @@ -0,0 +1,174 @@ +-- Real Problems +#24000: Bug in apt Version: 0.0.17-1bo0 + Summary: Couldn't locate an archive source for a package + Status: Require Status file. +#24717: apt dies early if one postinst/preinst dies + Status: Requires dpkg modifications +#25104: APT should retry failed downloads + Summary: FTP method has problems with busy servers + Status: The 0.3.0 ftp method should probably use the configuration mechanism + to control this desired behavoir. +#25176: Problem with FTP/firewall +#25458: Problem with FTP/firewall + Summary: FTP method has no controls for firewalls + Status: The 0.3.0 ftp method should probably use the configuration mechanism + to control this desired behavoir. + +-- Fixed but unclosed things +#25026: apt: Why do you list the packages you're _not_ doing anything to instead of the ones you are? +#22507: apt: apt-get - listing packages to be upgraded (wishlist) + Summary: Feature request + Status: Fixed in 0.3.0 via the -u option +#21113: [Apt] In dselect, update dies and exits if the packages file is not found. + Status: Fixed in 0.3.0 +#22675: APT does not honor the --admin-dir option +#22836: Disk/Zip-Method for apt? + Summary: APT does not provide a way to download packages onto a + removable media for another computer + Status: 0.3.0 has substantially better support for this to the point + that it is doable by using a seperate configuration file and + the -c option +#27601: srange errors from dselect + Summary: Couldn't locate an archive source + Status: Require status file + Believed to be fixed in 0.1.9, was not reproducable w/ given + status file +#27841: apt: apt depends on a missing library + Status: New versions of APT in slink have been compiled with libstdc++2.9 +#23984: apt: support for "no_proxy" would be nice + Status: Planed to be integrated into the new methods via the configuration + file + Done - Use Acquire::http::proxy::host.com="DIRECT" +#25021: apt: Need some control over multiple connections + Status: Probable that 0.3.x will have support for configuing some + parameters + Done - Use Acquire::Queue-Mode="access" +#25019: apt: Confusing progress report + Summary: Gripes about the progress meter + Status: I do not intend to implement very many of these ideas in apt-get. + The GUI will naturally be better + I think the new progress meter address basically everyone's + concerns. +#25022: apt: Lack of feedback on date checking + Summary: Wants to know what package files were not updated + Status: There is no place for this in the current apt-get design, + probably won't make the GUI either. + Wee, the new acquire code allows this, it now prints out 'Hit' +#26019: apt may report wrong line speed +#26433: apt: claims to fetch things it doesn't actually fetch (wishlist) +#28778: apt: apt's fetched message is wrong for update of packages files + Summary: APT includes the fetch time from the local cache in its + calculations + Status: Probably will be fixed with new acquire code + And it actually was fixed with the new acquire code +#26670: apt: apt-get dumps core after checking integrity + Summary: Some terminal environments cause APT to crash + Win95 telnet and emacs term-in-a-buffer are two at least + Status: I have no idea why. + Seems to be gone in .3, whatever it was... +#25001: apt: cleaned out archive even though not all files were installed + Status: Apparently in some cases APT can return a success code even + though it failed. I'm paying very close attention to this in + 0.3.x. Not to mention that the clean behavior will be + configurable.. +#28391: apt-get install without upgrading + Summary: Make install leave the package in the keep state if it is already + installed + Status: Will be implemented in 0.3.0 + Try the --no-upgrade options +#28373: apt package is missing information on ftp.conf +#29293: apt: Docs reference apt(8) but apt(8) not provided. + Summary: The man pages have references to several non-existent items, + ftp.conf is only one of them. + Status: Fix the man pages. This certainly will be done in 0.3.0 +#24799: Some suggestions for the apt method in dselect + Summary: Wants to be able to specifiy -d from dselect + Status: Likely a APT_OPTIONS enviornment variable will be created, -d can + be put there. + There is already an APT_CONFIG in 0.3, APT_OPTIONS may also + appear.. + Use Dselect::Options "-d" and others +#29920: Wish for more verbosity on "has no installation candidate" + Summary: More reports + Status: Already fixed in .3 +#29382: apt: apt deletes packages after installation without any question + Summary: Obvois. + Status: Fixed in .3, use Dselect::Clean "prompt" +#30027: apt: version comparison bug + Summary: Version compare differs from dpkg + Status: Fixed in all CVS versions. +#30260: apt: wishlist: do not return to main menu without prompting for return + Summary: Wants to prompt after dselect update + Status: Fixed in v3, use dselect::promptafterupdate "true"; +#29441: documenting the codes for -s + Summary: Apparently the simulation output is not immediately obvois + Status: Someone should update the man page. +#24685: HTTP Proxy cache refresh + Summary: Some caches hold onto the package index file for too long + Status: It may be possible to insert the proper header to disable + caching but I can't think how to do this while allowing + the cache to return cached objects - in effect it would + completely disable the cache which may not be desired. + APT now sends a max age header. See the apt.conf(5) +#28172: HTTP Proxy cache refresh should be forced for corrupted packages + Summary: Some problem resulted in a corrupted package + Status: I belive this reflects a deeper problem and the suggested solution + is only a band-aide patch. I intend to close this bug when #24685 + is fixed with a configuration directive. + Use -o acquire::http::no-cache=true +#29351: poor error message after conffile update + Summary: APT errors when the package file is not found + Status: The new APT warns better and the error is not fatal +#30112: apt: internal error in apt + Summary: APT gives an unclear error when it cannot correct dependencies + Status: Error is clearer +#30324: apt-get lying about file dates in /var/state/apt/lists + Summary: Doesn't copy the file dates right with file URIs + Status: Fixed in v3 +#30383: apt: dist-upgrade msg "E: Internal error, ScoredFix generated breaks." + Summary: libc6 maddness causes bizzar problems + Status: Fixed in v3 +#29983: apt: Wrong diagnostic, could be better + Summary: It doesn't explicy say you should be root + Status: Fixed in v3 +#22892: Apt improvements + Summary: Bails if an index file can't be found + Status: Fixed in v3 +#28184: apt could be smarter regarding mirrors + Summary: Make use of redundant sources + Status: 0.3.0 will likely do this, already the information for it is stored. +#27646: Apt: dpkg --merge-avail + Summary: Suggestion to call merge avail after each update operation + Status: Unlikely. The dpkg --print-avail functions should be obsoleted + by the apt-query program which should be written. + Use the dselect script, alias or something. +#26663: rsync file access + Status: Unlikely, rsync does not provide the necessary support to be + a terribly good method. I do not intend any 'split mode' + support (ie a way to get Package files via rsync and .debs + via http) +#27100: apt: Better support for project/experimental + Status: GUI Feature - Version selection and pinning + Honors the NotAutomatic flag +#30643: base: apt-get update problems with http-/ftp-caches (i.e. squid) + Status: Fixed as best I can. Try the Acquire::http::No-Cache option. + +-- Silly things +#26592: apt: Problems with ftpd in SunOS 5.6 +#29903: apt-get insists onto sending a SIZE command + Summary: SunOS ftpd does not support the SIZE command + Status: Probably not worth fixing +#20723: Apt suggestion + Summary: Package Grouping Mechanism + Status: Who knows +#22550: apt-get upgrade could configure packages earlier + Status: Who knows +#23934: apt-get source +#27190: apt: installing source packages (wishlist) + Status: Impossible to do without an index file for all source archives. +#22551: apt: wish: use dist X iff pkg does not exist in dist Y + Status: GUI Feature - Version selection and pinning +#30237: apt: 0.1.9 checks dependencies against packages.gz + Summary: For packages with identical version numbers APT prefers + to use the archive index files + Status: Yes it is sorta bad, but there is no reasonable solution. diff --git a/apt/doc/CVS/Entries b/apt/doc/CVS/Entries new file mode 100644 index 0000000..7a9b909 --- /dev/null +++ b/apt/doc/CVS/Entries @@ -0,0 +1,25 @@ +D/examples//// +D/pt_BR//// +/Bugs/1.1.1.1/Fri Aug 10 14:01:10 2001// +/apt-cache.8/1.5/Fri Aug 10 14:01:10 2001// +/apt-cache.8.yo/1.1.1.1/Fri Aug 10 14:01:10 2001// +/apt-cdrom.8/1.2/Fri Aug 10 14:01:10 2001// +/apt-cdrom.8.yo/1.1.1.1/Fri Aug 10 14:01:10 2001// +/apt-config.8/1.2/Fri Aug 10 14:01:10 2001// +/apt-config.8.yo/1.1.1.1/Fri Aug 10 14:01:10 2001// +/apt-get.8/1.3/Fri Aug 10 14:01:10 2001// +/apt-get.8.yo/1.1.1.1/Fri Aug 10 14:01:10 2001// +/apt.8/1.2/Fri Aug 10 14:01:12 2001// +/apt.conf.5/1.3/Fri Aug 10 14:01:12 2001// +/apt.conf.5.yo/1.1.1.1/Fri Aug 10 14:01:12 2001// +/cache.sgml/1.1.1.1/Fri Aug 10 14:01:31 2001// +/design.sgml/1.1.1.1/Fri Aug 10 14:01:32 2001// +/dpkg-tech.sgml/1.1.1.1/Fri Aug 10 14:01:36 2001// +/files.sgml/1.1.1.1/Fri Aug 10 14:01:36 2001// +/guide.sgml/1.1.1.1/Fri Aug 10 14:01:38 2001// +/makefile/1.4/Fri Aug 10 14:01:39 2001// +/method.sgml/1.1.1.1/Fri Aug 10 14:01:39 2001// +/offline.sgml/1.1.1.1/Fri Aug 10 14:01:40 2001// +/sources.list.5/1.4/Fri Aug 10 14:01:40 2001// +/sources.list.5.yo/1.1.1.1/Fri Aug 10 14:01:41 2001// +/vendors.list.5/1.3/Fri Aug 10 14:01:41 2001// diff --git a/apt/doc/CVS/Repository b/apt/doc/CVS/Repository new file mode 100644 index 0000000..f820167 --- /dev/null +++ b/apt/doc/CVS/Repository @@ -0,0 +1 @@ +rapt/doc diff --git a/apt/doc/CVS/Root b/apt/doc/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/doc/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/doc/apt-cache.8 b/apt/doc/apt-cache.8 new file mode 100644 index 0000000..f14e8c0 --- /dev/null +++ b/apt/doc/apt-cache.8 @@ -0,0 +1,311 @@ +.TH "apt-cache" "8" "25 Oct 2000" "apt" "" +.SH "NAME" +apt-cache \- APT package handling utility -- cache manipulator +.PP +.SH "SYNOPSIS" +apt-cache command [argument \&.\&.\&.] +.PP +.SH "DESCRIPTION" +\fBapt-cache\fP performs a variety of operations on APT\'s package cache\&. +\fBapt-cache\fP is seldom called directly; instead its operations are +performed automatically by the other \fBapt\fP utilities\&. +.PP +\fIcommand\fP is one of: +.IP o +add file1 [file2] [\&.\&.\&.] +.IP o +gencaches +.IP o +showpkg package1 [package2] [\&.\&.\&.] +.IP o +stats +.IP o +dump +.IP o +dumpavail +.IP o +unmet +.IP o +check +.IP o +search +.IP o +show +.IP o +showpkg +.IP o +depends +.IP o +pkgnames +.IP o +dotty +.PP +Unless the -h, or --help option is given one of the above commands +must be present\&. +.PP +.IP "\fBadd\fP" +\fBadd\fP adds the names package index files to the package cache\&. +.IP +.IP "\fBgencaches\fP" +\fBgencaches\fP performs the same opration as \fBapt-get check\fP\&. It builds +the source and package caches from thes sources in \fB/etc/apt/sources\&.list\fP +and from \fB/var/lib/dpkg/status\fP (or the RPM database)\&. +.IP +.IP "\fBshowpkg\fP" +\fBshowpkg\fP displays information about the packages listed on the +command line\&. Remaining arguments are package names\&. The available versions +and reverse dependencies of each package listed are listed, as well as +forward dependencies for each version\&. Forward (normal) dependencies +are those packages upon which the package in question depends; reverse +dependencies are those packages that depend upon the package in +question\&. Thus, forward dependencies must be satisfied for a package, +but reverse dependencies need not be\&. +For instance, \fBapt-cache showpkg libreadline2\fP would produce output similar +to the following: +.IP + +.nf + + +Package: libreadline2 + +Versions: + +2\&.1-12(/var/state/apt/lists/debian\&.midco\&.net_debian_dists_slink_main_binary-i386_Packages), + +Reverse Depends: + + libreadlineg2,libreadline2 + + libreadline2-altdev,libreadline2 +Dependencies: + +2\&.1-12 - libc5 (2 5\&.4\&.0-0) ncurses3\&.0 (0 (null)) ldso (2 1\&.9\&.0-1) + +Provides: + +2\&.1-12 - + +Reverse Provides: + +.fi + + +.IP +Thus it may be seen that libreadline2, version 2\&.1-8, depends on libc5, +ncurses3\&.0, and ldso, which must be installed for libreadline2 to work\&. In +turn, libreadlineg2 and libreadline2-altdev depend on libreadline2\&. If +libreadline2 is installed, libc5, ncurses3\&.0, and ldso must also be +installed; libreadlineg2 and libreadline2-altdev do not have to be +installed\&. For the specific meaning of the remainder of the output it +is best to consult the apt source code\&. +.IP +.IP "\fBstats\fP" +\fBstats\fP displays some statistics about \fBcache\fP\&. +No further arguments are expected\&. Statistics reported are: +.IP o +\fBTotal package names\fP is the number of package names found in the cache\&. +.IP +.IP o +\fBNormal packages\fP is the number of regular, ordinary package names; these +are packages that bear a one-to-one correspondence between their names and +the names used by other packages for them in dependencies\&. The majority of +packages fall into this category\&. +.IP +.IP o +\fBPure virtual packages\fP is the number of packages that exist only as +a virtual package name; that is, packages only "provide" the virtual +package name, and no package actually uses the name\&. For instance, +"mail-transport-agent" in the Debian GNU/Linux system is a pure virtual +package; several packages provide "mail-transport-agent", but there is no +package named "mail-transport-agent"\&. +.IP +.IP o +\fBSingle virtual packages\fP is the number of packages with only one +package providing a particular virtual package\&. For example, in the +Debian GNU/Linux system, "X11-text-viewer" is a virtual package, but only +one package, xless, provides "X11-text-viewer"\&. +.IP +.IP o +\fBMixed virtual packages\fP is the number of packages that either provide +a particular virtual package or have the virtual package name as the +package name\&. For instance, in the Debian GNU/Linux system, e2fsprogs is +both an actual package, and provided by the e2compr package\&. +.IP +.IP o +\fBMissing\fP is the number of package names that were referenced in a +dependency but were not provided by any package\&. Missing packages may be +in evidence if a full distribution is not accesssed, or if a package +(real or virtual) has been dropped from the distribution\&. +.IP +.IP o +\fBTotal distinct\fP versions is the number of package versions found in +the cache; this value is therefore at least equal to the number of total +package names\&. If more than one distribution (both "stable" and "unstable", +for instance), is being accessed, this value can be considerably larger +than the number of total package names\&. +.IP +.IP o +\fBTotal dependencies\fP is the number of dependency relationships claimed +by all of the packages in the cache\&. +.IP +.IP "\fBdump\fP" +\fBdump\fP shows a short listing of every package in the cache\&. It is primarily +for debugging\&. +.IP +.IP "\fBdumpavail\fP" +\fBdumpavail\fP prints out an available list to stdout\&. This is suitable for use +with \fBdpkg\fP and is used by the \fBdselect\fP method\&. +.IP +.IP "\fBunmet\fP" +\fBunmet\fP displays a summary of all unmet dependencies in the package cache\&. +.IP +.IP "\fBcheck\fP" +\fBcheck\fP is a random function for testing certain aspects of the cache\&. +Do not use it\&. +.IP +.IP "\fBshowpkg\fP" +\fBshowpkg\fP displays a listing of the given package cache structure and some +related information about it\&. The list is meant primarily for debugging\&. +.IP +.IP "\fBshow\fP" +\fBshow\fP performs a function similar to dpkg --print-avail or rpm -qi, +it displays the package records for the named packages\&. +.IP +.IP "\fBsearch\fP" +\fBsearch\fP performs a full text search on all available package files for +the pattern given\&. It searchs the package names and the descriptions for +an occurance of the string and prints out the package name and the short +description\&. If --full is given then output identical to \fBshow\fP is produced +for each matched package and if --names-only is given then the long +description is not searched, only the package name is\&. +.IP +.IP "\fBdepends\fP" +\fBdepends\fP shows a listing of each dependency a package has and all +the possible other packages that can fullfill that dependency\&. +.IP +.IP "\fBpkgnames\fP" +This command prints the name of each package in the system\&. The optional +argument is a prefix match to filter the name list\&. The output is suitable +for use in a shell tab complete function and the output is generated extremly +quickly\&. This command is best used with the \fB--no-generate\fP option\&. +.IP +.IP "\fBdotty\fP" +\fBdotty\fP Takes a list of packages on the command line and gernerates output +suitable for use by dotty from the GraphVis +(http://www\&.research\&.att\&.com/sw/tools/graphviz/) package\&. The result will be +a set of nodes and edges representing the relationships between the +packages\&. By default the given packages will trace out all dependent packages +which can produce a very large graph\&. This can be turned off by setting the +APT::Cache::GivenOnly option\&. +.IP +The resulting nodes will have several shapse, normal packages are boxes, +pure provides are triangles, mixed provides are diamonds, +hexagons are missing packages\&. Orange boxes mean recursion was stopped +[leaf packages], blue lines are prre-depends, green lines are conflicts\&. +.IP +Caution, dotty cannot graph larger sets of packages\&. +.IP +.PP +.SH "OPTIONS" +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set\&. For boolean +options you can override the config file by using something like \fB-f-\fP, +\fB--no-f\fP, \fB-f=no\fP or several other variations\&. +.PP +.IP "\fB-h, --help\fP" +Show a short usage summary\&. +.IP +.IP "\fB-v, --version\fP" +Show the program verison\&. +.IP +.IP "\fB-p --pkg-cache\fP" +Select the file to store the package cache\&. The package cache is the primary +cache used by all operations\&. +Configuration Item: \fBDir::Cache::pkgcache\fP\&. +.IP +.IP "\fB-s --src-cache\fP" +Select the file to store the source cache\&. The source is used only by +\fBgencaches\fP and it stores a parsed version of the package information from +remote sources\&. When building the package cache the source cache is used +to advoid reparsing all of the package files\&. +Configuration Item: \fBDir::Cache::srcpkgcache\fP\&. +.IP +.IP "\fB-q, --quiet\fP" +Quiet; produces output suitable for logging, omitting progress indicators\&. +More qs will produce more quite up to a maximum of 2\&. You can also use +\fB-q=#\fP to set the quiet level, overriding the configuration file\&. +Configuration Item: \fBquiet\fP\&. +.IP +.IP "\fB-i --important\fP" +Print only important deps; for use with unmet causes only \fIDepends\fP and +\fIPre-Depends\fP relations to be printed\&. +Configuration Item: \fBAPT::Cache::Important\fP\&. +.IP +.IP "\fB-f --full\fP" +Print full package records when searching\&. Configuration Item: \fBAPT::Cache::ShowFull\fP\&. +.IP +.IP "\fB-a --all-versions\fP" +Print full records for all available versions, this is only applicable to the +show command\&. Configuration Item: \fBAPT::Cache::AllVersions\fP +.IP +.IP "\fB-g --no-generate\fP" +Do not perform automatic package cache regeneration, use the cache as it is\&. +Configuration Item: \fBAPT::Cache::NoGenerate\fP\&. +.IP +.IP "\fB--names-only\fP" +Only search on the package names, not the long description\&. +Configuration Item: \fBAPT::Cache::NamesOnly\fP\&. +.IP +.IP "\fB--all-names\fP" +Make \fBpkgnames\fP print all names, including virtual packages and missing +dependencies\&. Configuration Item: \fBAPT::Cache::AllNames\fP\&. +.IP +.IP "\fB-c, --config-file\fP" +Configuration File; Specify a configuration file to use\&. \fBapt-get\fP will +read the default configuration file and then this configuration file\&. See +\fBapt\&.conf(5)\fP for syntax information\&. +.IP +.IP "\fB-o, --option\fP" +Set a Configuration Option; This will set an arbitary configuration option\&. +The syntax is + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "FILES" +.IP o +/etc/apt/sources\&.list +locations to fetch packages from +.IP +.IP o +/var/state/apt/lists/ +storage area for state information for each package resource specified in +.IP +.IP o +/var/state/apt/lists/partial/ +storage area for state information in transit +.PP +.SH "SEE ALSO" +apt-get(8), +sources\&.list(5), +apt\&.conf(5) +.PP +.SH "DIAGNOSTICS" +apt-cache returns zero on normal operation, decimal 100 on error\&. +.PP +.SH "BUGS" +See http://bugs\&.debian\&.org/apt\&. If you wish to report a +bug in \fBapt-cache\fP, please see \fB/usr/doc/debian/bug-reporting\&.txt\fP +or the \fBbug(1)\fP command\&. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt-get was written by the APT team +and ported to RPM based systems by +Alfredo K. Kojima, Conectiva S.A. \&. + diff --git a/apt/doc/apt-cache.8.yo b/apt/doc/apt-cache.8.yo new file mode 100644 index 0000000..5ce5c48 --- /dev/null +++ b/apt/doc/apt-cache.8.yo @@ -0,0 +1,280 @@ +mailto(apt@packages.debian.org) +manpage(apt-cache)(8)(4 Dec 1998)(apt)() +manpagename(apt-cache)(APT package handling utility -- cache manipulator) + +manpagesynopsis() +apt-cache command [argument ...] + +manpagedescription() +bf(apt-cache) performs a variety of operations on APT's package cache. +bf(apt-cache) is seldom called directly; instead its operations are +performed automatically by the other bf(apt) utilities. + +em(command) is one of: +itemize( + it() add file1 [file2] [...] + it() gencaches + it() showpkg package1 [package2] [...] + it() stats + it() dump + it() dumpavail + it() unmet + it() check + it() search + it() show + it() showpkg + it() depends + it() pkgnames + it() dotty +) + +Unless the -h, or --help option is given one of the above commands +must be present. + +startdit() +dit(bf(add)) +bf(add) adds the names package index files to the package cache. + +dit(bf(gencaches)) +bf(gencaches) performs the same opration as bf(apt-get check). It builds +the source and package caches from thes sources in bf(/etc/apt/sources.list) +and from bf(/var/lib/dpkg/status). + +dit(bf(showpkg)) +bf(showpkg) displays information about the packages listed on the +command line. Remaining arguments are package names. The available versions +and reverse dependencies of each package listed are listed, as well as +forward dependencies for each version. Forward (normal) dependencies +are those packages upon which the package in question depends; reverse +dependencies are those packages that depend upon the package in +question. Thus, forward dependencies must be satisfied for a package, +but reverse dependencies need not be. +For instance, bf(apt-cache showpkg libreadline2) would produce output similar +to the following: + +verb( +Package: libreadline2 + +Versions: + +2.1-12(/var/state/apt/lists/debian.midco.net_debian_dists_slink_main_binary-i386_Packages), + +Reverse Depends: + + libreadlineg2,libreadline2 + + libreadline2-altdev,libreadline2 +Dependencies: + +2.1-12 - libc5 (2 5.4.0-0) ncurses3.0 (0 (null)) ldso (2 1.9.0-1) + +Provides: + +2.1-12 - + +Reverse Provides: +) + +Thus it may be seen that libreadline2, version 2.1-8, depends on libc5, +ncurses3.0, and ldso, which must be installed for libreadline2 to work. In +turn, libreadlineg2 and libreadline2-altdev depend on libreadline2. If +libreadline2 is installed, libc5, ncurses3.0, and ldso must also be +installed; libreadlineg2 and libreadline2-altdev do not have to be +installed. For the specific meaning of the remainder of the output it +is best to consult the apt source code. + +dit(bf(stats)) +bf(stats) displays some statistics about bf(cache). +No further arguments are expected. Statistics reported are: +itemize( + it() bf(Total package names) is the number of package names found in the cache. + + it() bf(Normal packages) is the number of regular, ordinary package names; these + are packages that bear a one-to-one correspondence between their names and + the names used by other packages for them in dependencies. The majority of + packages fall into this category. + + it() bf(Pure virtual packages) is the number of packages that exist only as + a virtual package name; that is, packages only "provide" the virtual + package name, and no package actually uses the name. For instance, + "mail-transport-agent" in the Debian GNU/Linux system is a pure virtual + package; several packages provide "mail-transport-agent", but there is no + package named "mail-transport-agent". + + it() bf(Single virtual packages) is the number of packages with only one + package providing a particular virtual package. For example, in the + Debian GNU/Linux system, "X11-text-viewer" is a virtual package, but only + one package, xless, provides "X11-text-viewer". + + it() bf(Mixed virtual packages) is the number of packages that either provide + a particular virtual package or have the virtual package name as the + package name. For instance, in the Debian GNU/Linux system, e2fsprogs is + both an actual package, and provided by the e2compr package. + + it() bf(Missing) is the number of package names that were referenced in a + dependency but were not provided by any package. Missing packages may be + in evidence if a full distribution is not accesssed, or if a package + (real or virtual) has been dropped from the distribution. + + it() bf(Total distinct) versions is the number of package versions found in + the cache; this value is therefore at least equal to the number of total + package names. If more than one distribution (both "stable" and "unstable", + for instance), is being accessed, this value can be considerably larger + than the number of total package names. + + it() bf(Total dependencies) is the number of dependency relationships claimed + by all of the packages in the cache. +) + +dit(bf(dump)) +bf(dump) shows a short listing of every package in the cache. It is primarily +for debugging. + +dit(bf(dumpavail)) +bf(dumpavail) prints out an available list to stdout. This is suitable for use +with bf(dpkg) and is used by the bf(dselect) method. + +dit(bf(unmet)) +bf(unmet) displays a summary of all unmet dependencies in the package cache. + +dit(bf(check)) +bf(check) is a random function for testing certain aspects of the cache. +Do not use it. + +dit(bf(showpkg)) +bf(showpkg) displays a listing of the given package cache structure and some +related information about it. The list is meant primarily for debugging. + +dit(bf(show)) +bf(show) performs a function similar to dpkg --print-avail, it displays +the package records for the named packages. + +dit(bf(search)) +bf(search) performs a full text search on all available package files for +the pattern given. It searchs the package names and the descriptions for +an occurance of the string and prints out the package name and the short +description. If --full is given then output identical to bf(show) is produced +for each matched package and if --names-only is given then the long +description is not searched, only the package name is. + +dit(bf(depends)) +bf(depends) shows a listing of each dependency a package has and all +the possible other packages that can fullfill that dependency. + +dit(bf(pkgnames)) +This command prints the name of each package in the system. The optional +argument is a prefix match to filter the name list. The output is suitable +for use in a shell tab complete function and the output is generated extremly +quickly. This command is best used with the bf(--no-generate) option. + +dit(bf(dotty)) +bf(dotty) Takes a list of packages on the command line and gernerates output +suitable for use by dotty from the GraphVis +(http://www.research.att.com/sw/tools/graphviz/) package. The result will be +a set of nodes and edges representing the relationships between the +packages. By default the given packages will trace out all dependent packages +which can produce a very large graph. This can be turned off by setting the +APT::Cache::GivenOnly option. + +The resulting nodes will have several shapse, normal packages are boxes, +pure provides are triangles, mixed provides are diamonds, +hexagons are missing packages. Orange boxes mean recursion was stopped +[leaf packages], blue lines are prre-depends, green lines are conflicts. + +Caution, dotty cannot graph larger sets of packages. + +enddit() + +manpageoptions() +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set. For boolean +options you can override the config file by using something like bf(-f-), +bf(--no-f), bf(-f=no) or several other variations. + +startdit() +dit(bf(-h, --help)) +Show a short usage summary. + +dit(bf(-v, --version)) +Show the program verison. + +dit(bf(-p --pkg-cache)) +Select the file to store the package cache. The package cache is the primary +cache used by all operations. +Configuration Item: bf(Dir::Cache::pkgcache). + +dit(bf(-s --src-cache)) +Select the file to store the source cache. The source is used only by +bf(gencaches) and it stores a parsed version of the package information from +remote sources. When building the package cache the source cache is used +to advoid reparsing all of the package files. +Configuration Item: bf(Dir::Cache::srcpkgcache). + +dit(bf(-q, --quiet)) +Quiet; produces output suitable for logging, omitting progress indicators. +More qs will produce more quite up to a maximum of 2. You can also use +bf(-q=#) to set the quiet level, overriding the configuration file. +Configuration Item: bf(quiet). + +dit(bf(-i --important)) +Print only important deps; for use with unmet causes only em(Depends) and +em(Pre-Depends) relations to be printed. +Configuration Item: bf(APT::Cache::Important). + +dit(bf(-f --full)) +Print full package records when searching. Configuration Item: bf(APT::Cache::ShowFull). + +dit(bf(-a --all-versions)) +Print full records for all available versions, this is only applicable to the +show command. Configuration Item: bf(APT::Cache::AllVersions) + +dit(bf(-g --no-generate)) +Do not perform automatic package cache regeneration, use the cache as it is. +Configuration Item: bf(APT::Cache::NoGenerate). + +dit(bf(--names-only)) +Only search on the package names, not the long description. +Configuration Item: bf(APT::Cache::NamesOnly). + +dit(bf(--all-names)) +Make bf(pkgnames) print all names, including virtual packages and missing +dependencies. Configuration Item: bf(APT::Cache::AllNames). + +dit(bf(-c, --config-file)) +Configuration File; Specify a configuration file to use. bf(apt-get) will +read the default configuration file and then this configuration file. See +bf(apt.conf(5)) for syntax information. + +dit(bf(-o, --option)) +Set a Configuration Option; This will set an arbitary configuration option. +The syntax is +verb(-o Foo::Bar=bar) +enddit() + +manpagefiles() +itemize( + it() /etc/apt/sources.list + locations to fetch packages from + + it() /var/state/apt/lists/ + storage area for state information for each package resource specified in + + it() /var/state/apt/lists/partial/ + storage area for state information in transit +) + +manpageseealso() +apt-get(8), +sources.list(5), +apt.conf(5) + +manpagediagnostics() +apt-cache returns zero on normal operation, decimal 100 on error. + +manpagebugs() +See http://bugs.debian.org/apt. If you wish to report a +bug in bf(apt-cache), please see bf(/usr/doc/debian/bug-reporting.txt) +or the bf(bug(1)) command. + +manpageauthor() +apt-get was written by the APT team . diff --git a/apt/doc/apt-cdrom.8 b/apt/doc/apt-cdrom.8 new file mode 100644 index 0000000..c4abeba --- /dev/null +++ b/apt/doc/apt-cdrom.8 @@ -0,0 +1,127 @@ +.TH "apt-cdrom" "8" "25 Oct 2000" "apt" "" +.SH "NAME" +apt-cdrom \- APT CDROM managment utility +.PP +.SH "SYNOPSIS" +apt-cdrom command +.PP +.SH "DESCRIPTION" +\fBapt-cdrom\fP is used to add a new CDROM to APTs list of available sources\&. +\fBapt-cdrom\fP takes care of determining the structure of the disc as well +as correcting for several possible mis-burns and verifying the index files\&. +It is necessary to use \fBapt-cdrom\fP to add CDs to the APT system, it cannot +be done by hand\&. Furthermore each disk in a multi-cd set must be inserted +and scanned seperately to account for possible mis-burns\&. +.PP +\fIcommand\fP is one of: +.IP o +add +.PP +Unless the -h, or --help option is given one of the above commands +must be present\&. +.PP +.IP "\fBadd\fP" +\fBadd\fP is used to add a new disc to the source list\&. It will unmount the +CDROM device, prompt for a disk to be inserted and then procceed to scan it +and copy the index files\&. If the disc does not have a proper \fB\&.disk/\fP +directory you will be prompted for a descriptive title\&. +.IP +APT uses a CDROM ID to track which disc is currently in the drive and +maintains a database of these IDs in \fB/var/state/apt/cdroms\&.list\fP +.IP +.PP +.SH "OPTIONS" +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set\&. For boolean +options you can override the config file by using something like \fB-f-\fP, +\fB--no-f\fP, \fB-f=no\fP or several other variations\&. +.PP +.IP "\fB-h, --help\fP" +Show a short usage summary\&. +.IP +.IP "\fB-v, --version\fP" +Show the program verison\&. +.IP +.IP "\fB-d --cdrom\fP" +Mount point; specify the location to mount the cdrom\&. This mount point must +be listed in \fB/etc/fstab\fP and propely configured\&. +Configuration Item: \fBAcquire::cdrom::mount\fP\&. +.IP +.IP "\fB-r --rename\fP" +Rename a disc; change the label of a disk or override the disks given label\&. +This option will cause \fBapt-cdrom\fP to prompt for a new label +Configuration Item: \fBAPT::CDROM::Rename\fP\&. +.IP +.IP "\fB-m, --no-mount\fP" +No mounting; prevent \fBapt-cdrom\fP from mounting and unmounting the mount +point\&. +Configuration Item: \fBAPT::CDROM::NoMount\fP\&. +.IP +.IP "\fB-f, --fast\fP" +Fast Copy; Assume the package files are valid and do not check every package\&. +This option should be used only if \fBapt-cdrom\fP has been run on this disc +before and did not detect any errors\&. +Configuration Item: \fBAPT::CDROM::Fast\fP\&. +.IP +.IP "\fB-a, --thorough\fP" +Thorough Package Scan; This option may be needed with some old Debian 1\&.1/1\&.2 +burns that have Package files in strange places\&. It takes much longer to +scan the CD but will pick them all up\&. +.IP +.IP "\fB-n --just-print, --recon, --no-act\fP" +No Changes; Do not change the sources\&.list and do not write package files\&. +Everything is still checked however\&. +Configuration Item: \fBAPT::CDROM::NoAct\fP\&. +.IP +.IP "\fB-c, --config-file\fP" +Configuration File; Specify a configuration file to use\&. \fBapt-get\fP will +read the default configuration file and then this configuration file\&. See +\fBapt\&.conf(5)\fP for syntax information\&. +.IP +.IP "\fB-o, --option\fP" +Set a Configuration Option; This will set an arbitary configuration option\&. +The syntax is + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "FILES" +.IP o +/etc/apt/sources\&.list +locations to fetch packages from +.IP +.IP o +/var/state/apt/lists/ +storage area for state information for each package resource specified in +.IP +.IP o +/var/state/apt/lists/partial/ +storage area for state information in transit +.IP +.IP o +/var/state/apt/cdroms\&.list +list of cdrom IDs and names\&. +.PP +.SH "SEE ALSO" +apt-get(8), +sources\&.list(5), +apt\&.conf(5) +.PP +.SH "DIAGNOSTICS" +apt-cdrom returns zero on normal operation, decimal 100 on error\&. +.PP +.SH "BUGS" +See http://bugs\&.debian\&.org/apt\&. If you wish to report a +bug in \fBapt-cache\fP, please see \fB/usr/doc/debian/bug-reporting\&.txt\fP +or the \fBbug(1)\fP command\&. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt-get was written by the APT team +and ported to RPM based systems by Conectiva S.A. +\&. + diff --git a/apt/doc/apt-cdrom.8.yo b/apt/doc/apt-cdrom.8.yo new file mode 100644 index 0000000..9d5b598 --- /dev/null +++ b/apt/doc/apt-cdrom.8.yo @@ -0,0 +1,120 @@ +mailto(apt@packages.debian.org) +manpage(apt-cdrom)(8)(4 Dec 1998)(apt)() +manpagename(apt-cdrom)(APT CDROM managment utility) + +manpagesynopsis() +apt-cdrom command + +manpagedescription() +bf(apt-cdrom) is used to add a new CDROM to APTs list of available sources. +bf(apt-cdrom) takes care of determining the structure of the disc as well +as correcting for several possible mis-burns and verifying the index files. +It is necessary to use bf(apt-cdrom) to add CDs to the APT system, it cannot +be done by hand. Furthermore each disk in a multi-cd set must be inserted +and scanned seperately to account for possible mis-burns. + +em(command) is one of: +itemize( + it() add +) + +Unless the -h, or --help option is given one of the above commands +must be present. + +startdit() +dit(bf(add)) +bf(add) is used to add a new disc to the source list. It will unmount the +CDROM device, prompt for a disk to be inserted and then procceed to scan it +and copy the index files. If the disc does not have a proper bf(.disk/) +directory you will be prompted for a descriptive title. + +APT uses a CDROM ID to track which disc is currently in the drive and +maintains a database of these IDs in bf(/var/state/apt/cdroms.list) + +enddit() + +manpageoptions() +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set. For boolean +options you can override the config file by using something like bf(-f-), +bf(--no-f), bf(-f=no) or several other variations. + +startdit() +dit(bf(-h, --help)) +Show a short usage summary. + +dit(bf(-v, --version)) +Show the program verison. + +dit(bf(-d --cdrom)) +Mount point; specify the location to mount the cdrom. This mount point must +be listed in bf(/etc/fstab) and propely configured. +Configuration Item: bf(Acquire::cdrom::mount). + +dit(bf(-r --rename)) +Rename a disc; change the label of a disk or override the disks given label. +This option will cause bf(apt-cdrom) to prompt for a new label +Configuration Item: bf(APT::CDROM::Rename). + +dit(bf(-m, --no-mount)) +No mounting; prevent bf(apt-cdrom) from mounting and unmounting the mount +point. +Configuration Item: bf(APT::CDROM::NoMount). + +dit(bf(-f, --fast)) +Fast Copy; Assume the package files are valid and do not check every package. +This option should be used only if bf(apt-cdrom) has been run on this disc +before and did not detect any errors. +Configuration Item: bf(APT::CDROM::Fast). + +dit(bf(-a, --thorough)) +Thorough Package Scan; This option may be needed with some old Debian 1.1/1.2 +burns that have Package files in strange places. It takes much longer to +scan the CD but will pick them all up. + +dit(bf(-n --just-print, --recon, --no-act)) +No Changes; Do not change the sources.list and do not write package files. +Everything is still checked however. +Configuration Item: bf(APT::CDROM::NoAct). + +dit(bf(-c, --config-file)) +Configuration File; Specify a configuration file to use. bf(apt-get) will +read the default configuration file and then this configuration file. See +bf(apt.conf(5)) for syntax information. + +dit(bf(-o, --option)) +Set a Configuration Option; This will set an arbitary configuration option. +The syntax is +verb(-o Foo::Bar=bar) +enddit() + +manpagefiles() +itemize( + it() /etc/apt/sources.list + locations to fetch packages from + + it() /var/state/apt/lists/ + storage area for state information for each package resource specified in + + it() /var/state/apt/lists/partial/ + storage area for state information in transit + + it() /var/state/apt/cdroms.list + list of cdrom IDs and names. +) + +manpageseealso() +apt-get(8), +sources.list(5), +apt.conf(5) + +manpagediagnostics() +apt-cdrom returns zero on normal operation, decimal 100 on error. + +manpagebugs() +See http://bugs.debian.org/apt. If you wish to report a +bug in bf(apt-cache), please see bf(/usr/doc/debian/bug-reporting.txt) +or the bf(bug(1)) command. + +manpageauthor() +apt-get was written by the APT team . diff --git a/apt/doc/apt-config.8 b/apt/doc/apt-config.8 new file mode 100644 index 0000000..33542f5 --- /dev/null +++ b/apt/doc/apt-config.8 @@ -0,0 +1,97 @@ +.TH "apt-config" "8" "25 Oct 2000" "apt" "" +.SH "NAME" +apt-config \- APT Configuration Query program +.PP +.SH "SYNOPSIS" +apt-config command +.PP +.SH "DESCRIPTION" +\fBapt-config\fP is an internal program used by various portions of the APT +suite to provide consistent configurability\&. It accesses the main configuarion +file /etc/apt/apt\&.conf in a manner that is easy to use by scripted +applications\&. +.PP +\fIcommand\fP is one of: +.IP o +shell +.IP o +dump +.PP +Unless the -h, or --help option is given one of the above commands +must be present\&. +.PP +.IP "\fBshell\fP" +\fBshell\fP is used to access the configuration information from a shell script\&. +It is given pairs of arguments, the first being a shell variable and the +second the configuration value to query\&. As output it lists a series of shell +assignments commands for each present value\&. In a shell script it should be +used like: +.IP + +.nf + + +OPTS="-f" + +RES=`apt-config shell OPTS MyApp::Options` + +eval $RES + +.fi + + +.IP +This will set the shell environment variable $OPTS to the value of +MyApp::Options with a default of -f\&. +.IP +If the configuration item to retrieve is prefixed with a / then it will +be retrieved using filename mode which prepends base paths\&. +.IP +.IP "\fBdump\fP" +Just show the contents of the configuration space\&. +.IP +.PP +.SH "OPTIONS" +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set\&. For boolean +options you can override the config file by using something like \fB-f-\fP, +\fB--no-f\fP, \fB-f=no\fP or several other variations\&. +.PP +.IP "\fB-h, --help\fP" +Show a short usage summary\&. +.IP +.IP "\fB-v, --version\fP" +Show the program verison\&. +.IP +.IP "\fB-c, --config-file\fP" +Configuration File; Specify a configuration file to use\&. \fBapt-get\fP will +read the default configuration file and then this configuration file\&. See +\fBapt\&.conf(5)\fP for syntax information\&. +.IP +.IP "\fB-o, --option\fP" +Set a Configuration Option; This will set an arbitary configuration option\&. +The syntax is + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "SEE ALSO" +apt\&.conf(5) +.PP +.SH "DIAGNOSTICS" +apt-config returns zero on normal operation, decimal 100 on error\&. +.PP +.SH "BUGS" +See http://bugs\&.debian\&.org/apt\&. If you wish to report a +bug in \fBapt-config\fP, please see \fB/usr/doc/debian/bug-reporting\&.txt\fP +or the \fBbug(1)\fP command\&. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt-get was written by the APT team +and ported to RPM based systems by Conectiva S.A. +\&. diff --git a/apt/doc/apt-config.8.yo b/apt/doc/apt-config.8.yo new file mode 100644 index 0000000..809c790 --- /dev/null +++ b/apt/doc/apt-config.8.yo @@ -0,0 +1,86 @@ +mailto(apt@packages.debian.org) +manpage(apt-config)(8)(14 Feb 1999)(apt)() +manpagename(apt-config)(APT Configuration Query program) + +manpagesynopsis() +apt-config command + +manpagedescription() +bf(apt-config) is an internal program used by various portions of the APT +suite to provide consistent configurability. It accesses the main configuarion +file /etc/apt/apt.conf in a manner that is easy to use by scripted +applications. + +em(command) is one of: +itemize( + it() shell + it() dump +) + +Unless the -h, or --help option is given one of the above commands +must be present. + +startdit() +dit(bf(shell)) +bf(shell) is used to access the configuration information from a shell script. +It is given pairs of arguments, the first being a shell variable and the +second the configuration value to query. As output it lists a series of shell +assignments commands for each present value. In a shell script it should be +used like: + +verb( +OPTS="-f" + +RES=`apt-config shell OPTS MyApp::Options` + +eval $RES +) + +This will set the shell environment variable $OPTS to the value of +MyApp::Options with a default of -f. + +If the configuration item to retrieve is prefixed with a / then it will +be retrieved using filename mode which prepends base paths. + +dit(bf(dump)) +Just show the contents of the configuration space. + +enddit() + +manpageoptions() +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set. For boolean +options you can override the config file by using something like bf(-f-), +bf(--no-f), bf(-f=no) or several other variations. + +startdit() +dit(bf(-h, --help)) +Show a short usage summary. + +dit(bf(-v, --version)) +Show the program verison. + +dit(bf(-c, --config-file)) +Configuration File; Specify a configuration file to use. bf(apt-get) will +read the default configuration file and then this configuration file. See +bf(apt.conf(5)) for syntax information. + +dit(bf(-o, --option)) +Set a Configuration Option; This will set an arbitary configuration option. +The syntax is +verb(-o Foo::Bar=bar) +enddit() + +manpageseealso() +apt.conf(5) + +manpagediagnostics() +apt-config returns zero on normal operation, decimal 100 on error. + +manpagebugs() +See http://bugs.debian.org/apt. If you wish to report a +bug in bf(apt-config), please see bf(/usr/doc/debian/bug-reporting.txt) +or the bf(bug(1)) command. + +manpageauthor() +apt-get was written by the APT team . diff --git a/apt/doc/apt-get.8 b/apt/doc/apt-get.8 new file mode 100644 index 0000000..69e0b18 --- /dev/null +++ b/apt/doc/apt-get.8 @@ -0,0 +1,330 @@ +.TH "apt-get" "8" "25 Oct 2000" "apt" "" +.SH "NAME" +apt-get \- APT package handling utility -- command-line interface +.PP +.SH "SYNOPSIS" +apt-get [options] [command] [package \&.\&.\&.] +.PP +.SH "DESCRIPTION" +.PP +apt-get is the command-line tool for handling packages, and may be considered +the user\'s "back-end" to apt(8)\&. +.PP +\fIcommand\fP is one of: +.IP o +update +.IP o +upgrade +.IP o +dselect-upgrade [1] +.IP o +dist-upgrade +.IP o +install package1 [package2] [\&.\&.\&.] +.IP o +remove package1 [package2] [\&.\&.\&.] +.IP o +source package1 [package2] [\&.\&.\&.] +.IP o +check +.IP o +clean +.IP o +autoclean +.PP +Unless the -h, or --help option is given one of the above commands +must be present\&. +.PP +Note: +[1] Debian systems only +.PP +.IP "\fBupdate\fP" +\fBupdate\fP is used to resynchronize the package overview files from their +sources\&. The overviews of available packages are fetched from the +location(s) specified in \fB/etc/apt/sources\&.list\fP\&. +For example, when using a Debian archive, this command retrieves and +scans the \fBPackages\&.gz\fP files, so that information about new and updated +packages is available\&. An \fBupdate\fP should always be performed before an +\fBupgrade\fP \fBdist-upgrade\fP\&. Please be aware that the overall progress +meter will be incorrect as the size of the package files cannot be known in +advance\&. +.IP +.IP "\fBupgrade\fP" +\fBupgrade\fP is used to install the newest versions of all packages currently +installed on the system from the sources enumerated in +\fB/etc/apt/sources\&.list\fP\&. Packages currently installed with new versions +available are retrieved and upgraded; under no circumstances are currently +installed packages removed, or packages not already installed retrieved and +installed\&. New versions of currently installed packages that cannot be +upgraded without changing the install status of another package will be left +at their current version\&. An \fBupdate\fP must be performed first so that +\fBapt-get\fP knows that new versions of packages are available\&. +.IP +.IP "\fBdselect-upgrade\fP" +\fBdselect-upgrade\fP +is used in conjunction with the traditional Debian GNU/Linux packaging +front-end, \fBdselect (8)\fP\&. \fBdselect-upgrade\fP +follows the changes made by \fBdselect\fP to the \fIStatus\fP +field of available packages, and performs the actions necessary to realize +that state (for instance, the removal of old and the installation of new +packages)\&. +This command is only available on Debian systems. +.IP +.IP "\fBdist-upgrade\fP" +\fBdist-upgrade\fP,in addition to performing the function of \fBupgrade\fP, +also intelligently handles changing dependencies with new versions of +packages; \fBapt-get\fP has a "smart" conflict resolution system, and it will +attempt to upgrade the most important packages at the expense of less +important ones if necessary\&. The \fB/etc/apt/sources\&.list\fP file contains a +list of locations from which to retrieve desired package files\&. +.IP +.IP "\fBinstall\fP" +\fBinstall\fP is followed by one or more \fIpackages\fP desired for installation\&. +Each \fIpackage\fP is a package name, not a fully qualified filename +(for instance, in a Debian GNU/Linux system, \fIldso\fP would be the argument +provided, not \fIldso_1\&.9\&.6-2\&.deb\fP)\&. All packages required by the package(s) +specified for installation will also be retrieved and installed\&. The +\fB/etc/apt/sources\&.list\fP file is used to locate the desired packages\&. If a +hyphen is appended to the package name (with no intervening space), the +identified package will be removed if it is installed\&. This latter feature +may be used to override decisions made by apt-get\'s conflict resolution system\&. +.IP +If no package matches the given expression and the expression contains one +of \'\&.\', \'?\' or \'*\' then it is assumed to be a POSIX regex and it is applied +to all package names in the database\&. Any matches are then installed (or +removed)\&. Note that matching is done by substring so \'lo*\' matches \'how-lo\' +and \'lowest\'\&. If this is undesired prefix with a \'^\' character\&. +.IP +.IP "\fBremove\fP" +\fBremove\fP is identical to \fBinstall\fP except that packages are removed +instead of installed\&. If a plus sign is appended to the package name (with no +intervening space), the identified package will be installed\&. +.IP +.IP "\fBsource\fP" +\fBsource\fP causes apt-get to fetch source packages\&. APT will examine the +available packages to decide which source package to fetch\&. It will then +find and download into the current directory the newest available version of +that source package\&. Source packages are tracked separately from binary +packages via \fBdeb-src\fP or \fBrpm-src\fP type lines in the \fB/etc/apt/sources\&.list\fP file\&. +This probably will mean that you will not get the same source as the package +you have installed or as you could install\&. If the --compile options is +specified then the package will be compiled to a binary \&.deb using +dpkg-buildpackage, or under RPM based systems, it will compile +to a binary \&.rpm using rpm -ba. If --download-only is specified then +the source package will not be unpacked\& +.IP +Note that source packages are not tracked like binary packages, they exist +only in the current directory and are similar to downloading source +tar balls\&. +.IP +.IP "\fBcheck\fP" +\fBcheck\fP is a diagnostic tool; it updates the package cache and checks for +broken packages\&. +.IP +.IP "\fBclean\fP" +\fBclean\fP clears out the local repository of retrieved package files\&. It +removes everything but the lock file from \fB/var/cache/apt/archives/\fP +and \fB/var/cache/apt/archives/partial/\fP\&. +When APT is used as a \fBdselect(8)\fP method, \fBclean\fP is run automatically\&. +Those who do not use dselect will likely want to run \f(CWapt-get clean\fP +from time to time to free up disk space\&. +.IP +.IP "\fBautoclean\fP" +Like \fBclean\fP, \fBautoclean\fP clears out the local repository of retrieved +package files\&. The difference is that it only removes package files that +can no longer be downloaded, and are largely useless\&. This allows a +cache to be maintained over a long period without it growing out of +control\&. +.IP +.PP +.SH "OPTIONS" +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set\&. For boolean +options you can override the config file by using something like \fB-f-\fP, +\fB--no-f\fP, \fB-f=no\fP or several other variations\&. +.PP +.IP "\fB-d, --download-only\fP" +Download only; package files are only retrieved, not unpacked or installed\&. +Configuration Item: \fBAPT::Get::Download-Only\fP\&. +.IP +.IP "\fB-f, --fix-broken\fP" +Fix; attempt to correct a system with broken dependencies in +place\&. This option, when used with install/remove, can omit any packages +to permit APT to deduce a likely solition\&. Any Package that are specified +must completly correct the problem\&. The option is sometimes necessary when +running APT for the first time; APT itself does not allow broken package +dependencies to exist on a system\&. It is possible that a system\'s +dependency structure can be so corrupt as to require manual intervention +(which usually means using dselect or dpkg --remove to eliminate some of +the offending packages)\&. Use of this option together with -m may produce an +error in some situations\&. Configuration Item: \fBAPT::Get::Fix-Broken\fP\&. +.IP +.IP "\fB-h, --help\fP" +Help; display a helpful usage message and exits\&. +.IP +.IP "\fB-v, --version\fP" +Show the program version\&. +.IP +.IP "\fB-m, --ignore-missing, --fix-missing\fP" +Ignore missing packages; If packages cannot be retrieved or fail the +integrity check after retrieval (corrupted package files), hold back +those packages and handle the result\&. Use of this option together with +-f may produce an error in some situations\&. If a package is selected for +installation (particularly if it is mentioned on the command line) and it +could not be downloaded then it will be silently held back\&. +Configuration Item: \fBAPT::Get::ignore-missing\fP\&. +.IP +.IP "\fB-S, --summary\fP" +When used with the upgrade or dist-upgrade commands, +displays information of what would be upgraded, with importance +and a summary of changes (when such data is available) and stops. +Configuration Item: \fBAPT::Get::Show-Upgrade-Summary\fP&. +.IP +.IP "\fB--no-download\fP" +Disables downloading of packages\&. This is best used with --ignore-missing to +force APT to use only the \&.debs it has already downloaded\&. +Configuration Item: \fBAPT::Get::No-Download\fP\&. +.IP +.IP "\fB-q, --quiet\fP" +Quiet; produces output suitable for logging, omitting progress indicators\&. +More q\'s will produce more quiet up to a maximum of 2\&. You can also use +\fB-q=#\fP to set the quiet level, overriding the configuration file\&. Note that +quiet level 2 implies -y, you should never use -qq without a no-action +modifier such as -d, --print-uris or -s as APT may decided to do something +you did not expect\&. +Configuration Item: \fBquiet\fP +.IP +.IP "\fB-s, --simulate, --just-print, --dry-run, --recon, --no-act\fP" +No action; perform a simulation of events that would occur but do not +actually change the system\&. Configuration Item: \fBAPT::Get::Simulate\fP\&. +.IP +Simulate prints out +a series of lines each one representing a dpkg operation, Configure (Conf), +Remove (Remv), Unpack (Inst)\&. Square brackets indicate broken packages with +and empty set of square brackets meaning breaks that are of no consequence +(rare)\&. +.IP +.IP "\fB-y, --yes, --assume-yes\fP" +Automatic yes to prompts; assume "yes" as answer to all prompts and run +non-interactively\&. If an undesirable situation, such as changing a held +package or removing an essential package occurs then \fBapt-get\fP will +abort\&. Configuration Item: \fBAPT::Get::Assume-Yes\fP\&. +.IP +.IP "\fB-u, --show-upgraded\fP" +Show upgraded packages; Print out a list of all packages that are to be +upgraded\&. Configuration Item: \fBAPT::Get::Show-Upgraded\fP\&. +.IP +.IP "\fB-b, --compile, --build\fP" +Compile source packages after downloading them\&. +Configuration Item: \fBAPT::Get::Compile\fP\&. +.IP +.IP "\fB--ignore-hold\fP" +Ignore package Holds; This causes \fBapt-get\fP to ignore a hold placed on +a package\&. This may be useful in conjunction with \fBdist-upgrade\fP to +override a large number of undesired holds\&. Configuration Item: \fBAPT::Ignore-Hold\fP\&. +.IP +.IP "\fB--no-upgrade\fP" +Do not upgrade packages; When used in conjunction with \fBinstall\fP +\fBno-upgrade\fP will prevent packages listed from being upgraded if they +are already installed\&. Configuration Item: \fBAPT::Get::no-upgrade\fP\&. +.IP +.IP "\fB--force-yes\fP" +Force yes; This is a dangerous option that will cause apt to continue without +prompting if it is doing something potentially harmful\&. It should not be used +except in very special situations\&. Using \fBforce-yes\fP can potentially destroy +your system! Configuration Item: \fBAPT::Get::force-yes\fP\&. +.IP +.IP "\fB--print-uris\fP" +Instead of fetching the files to install their URIs are printed\&. Each +URI will have the path, the destination file name, the size and the expected +md5 hash\&. Note that the file name to write to will not always match +the file name on the remote site! This also works with the \fBsource\fP +command\&. Configuration Item: \fBAPT::Get::Print-URIs\fP\&. +.IP +.IP "\fB--purge\fP" +Use purge instead of remove for anything that would be removed\&. +This option has no effect on RPM based systems. +Configuration Item: \fBAPT::Get::Purge\fP\&. +.IP +.IP "\fB--reinstall\fP" +Re-Install packages that are already installed and at the newest version\&. +.IP +.IP "\fB--list-cleanup\fP" +This option defaults to on, use \fB--no-list-cleanup\fP to turn it off\&. +When on apt-get will automatically manage the contents of +/var/state/apt/lists to ensure that obsolete files are erased\&. The only +reason to turn it off is if you frequently change your source list\&. +Configuration Item: \fBAPT::Get::List-Cleanup\fP +.IP +.IP "\fB--trivial-only\fP" +Only perform operations are \'trivial\'\&. Logically this can be considered +related to --assume-yes, where --assume-yes will answer yes to any prompt, +--trivial-only will answer no\&. Configuration Item: \fBAPT::Get::Trivial-Only\fP +.IP +.IP "\fB--no-remove\fP" +If any packages are to be removed apt-get immediately aborts without +prompting\&. Configuration Item: \fBAPT::Get::No-Remove\fP +.IP +.IP "\fB--diff-only\fP, \fB--tar-only\fP" +Download only the diff or tar file of a source archive\&. +Configuration Item: \fBAPT::Get::Diff-Only\fP +.IP +.IP "\fB-c, --config-file\fP" +Configuration File; Specify a configuration file to use\&. \fBapt-get\fP will +read the default configuration file and then this configuration file\&. See +\fBapt\&.conf(5)\fP for syntax information\&. +.IP +.IP "\fB-o, --option\fP" +Set a Configuration Option; This will set an arbitrary configuration option\&. +The syntax is + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "FILES" +.IP o +/etc/apt/sources\&.list +locations to fetch packages from +.IP +.IP o +/var/cache/apt/archives/ +storage area for retrieved package files +.IP +.IP o +/var/cache/apt/archives/partial/ +storage area for package files in transit +.IP +.IP o +/var/state/apt/lists/ +storage area for state information for each package resource specified in +the source list +.IP +.IP o +/var/state/apt/lists/partial/ +storage area for state information in transit +.PP +.SH "SEE ALSO" +apt-cache(8), +dpkg(8), +dselect(8), +sources\&.list(5), +apt\&.conf(5), +The APT Users Guide in /usr/doc/apt/ +.PP +.SH "DIAGNOSTICS" +apt-get returns zero on normal operation, decimal 100 on error\&. +.PP +.SH "BUGS" +See http://bugs\&.debian\&.org/apt\&. If you wish to report a +bug in \fBapt-get\fP, please see \fB/usr/doc/debian/bug-reporting\&.txt\fP +or the \fBbug(1)\fP command\&. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt-get was written by the APT team +and ported to RPM based systems by Conectiva S.A. +\&. diff --git a/apt/doc/apt-get.8.yo b/apt/doc/apt-get.8.yo new file mode 100644 index 0000000..4983b25 --- /dev/null +++ b/apt/doc/apt-get.8.yo @@ -0,0 +1,302 @@ +mailto(apt@packages.debian.org) +manpage(apt-get)(8)(4 Dec 1998)(apt)() +manpagename(apt-get)(APT package handling utility -- command-line interface) + +manpagesynopsis() + apt-get [options] [command] [package ...] + +manpagedescription() + +apt-get is the command-line tool for handling packages, and may be considered +the user's "back-end" to apt(8). + +em(command) is one of: +itemize( + it() update + it() upgrade + it() dselect-upgrade + it() dist-upgrade + it() install package1 [package2] [...] + it() remove package1 [package2] [...] + it() source package1 [package2] [...] + it() check + it() clean + it() autoclean +) + +Unless the -h, or --help option is given one of the above commands +must be present. + +startdit() +dit(bf(update)) +bf(update) is used to resynchronize the package overview files from their +sources. The overviews of available packages are fetched from the +location(s) specified in bf(/etc/apt/sources.list). +For example, when using a Debian archive, this command retrieves and +scans the bf(Packages.gz) files, so that information about new and updated +packages is available. An bf(update) should always be performed before an +bf(upgrade) bf(dist-upgrade). Please be aware that the overall progress +meter will be incorrect as the size of the package files cannot be known in +advance. + +dit(bf(upgrade)) +bf(upgrade) is used to install the newest versions of all packages currently +installed on the system from the sources enumerated in +bf(/etc/apt/sources.list). Packages currently installed with new versions +available are retrieved and upgraded; under no circumstances are currently +installed packages removed, or packages not already installed retrieved and +installed. New versions of currently installed packages that cannot be +upgraded without changing the install status of another package will be left +at their current version. An bf(update) must be performed first so that +bf(apt-get) knows that new versions of packages are available. + +dit(bf(dselect-upgrade)) +bf(dselect-upgrade) +is used in conjunction with the traditional Debian GNU/Linux packaging +front-end, bf(dselect (8)). bf(dselect-upgrade) +follows the changes made by bf(dselect) to the em(Status) +field of available packages, and performs the actions necessary to realize +that state (for instance, the removal of old and the installation of new +packages). + +dit(bf(dist-upgrade)) +bf(dist-upgrade),in addition to performing the function of bf(upgrade), +also intelligently handles changing dependencies with new versions of +packages; bf(apt-get) has a "smart" conflict resolution system, and it will +attempt to upgrade the most important packages at the expense of less +important ones if necessary. The bf(/etc/apt/sources.list) file contains a +list of locations from which to retrieve desired package files. + +dit(bf(install)) +bf(install) is followed by one or more em(packages) desired for installation. +Each em(package) is a package name, not a fully qualified filename +(for instance, in a Debian GNU/Linux system, em(ldso) would be the argument +provided, not em(ldso_1.9.6-2.deb)). All packages required by the package(s) +specified for installation will also be retrieved and installed. The +bf(/etc/apt/sources.list) file is used to locate the desired packages. If a +hyphen is appended to the package name (with no intervening space), the +identified package will be removed if it is installed. This latter feature +may be used to override decisions made by apt-get's conflict resolution system. + +If no package matches the given expression and the expression contains one +of '.', '?' or '*' then it is assumed to be a POSIX regex and it is applied +to all package names in the database. Any matches are then installed (or +removed). Note that matching is done by substring so 'lo*' matches 'how-lo' +and 'lowest'. If this is undesired prefix with a '^' character. + +dit(bf(remove)) +bf(remove) is identical to bf(install) except that packages are removed +instead of installed. If a plus sign is appended to the package name (with no +intervening space), the identified package will be installed. + +dit(bf(source)) +bf(source) causes apt-get to fetch source packages. APT will examine the +available packages to decide which source package to fetch. It will then +find and download into the current directory the newest available version of +that source package. Source packages are tracked separately from binary +packages via bf(deb-src) type lines in the bf(/etc/apt/sources.list) file. +This probably will mean that you will not get the same source as the package +you have installed or as you could install. If the --compile options is +specified then the package will be compiled to a binary .deb using +dpkg-buildpackage, if --download-only is specified then the source package +will not be unpacked. + +Note that source packages are not tracked like binary packages, they exist +only in the current directory and are similar to downloading source +tar balls. + +dit(bf(check)) +bf(check) is a diagnostic tool; it updates the package cache and checks for +broken packages. + +dit(bf(clean)) +bf(clean) clears out the local repository of retrieved package files. It +removes everything but the lock file from bf(/var/cache/apt/archives/) +and bf(/var/cache/apt/archives/partial/). +When APT is used as a bf(dselect(8)) method, bf(clean) is run automatically. +Those who do not use dselect will likely want to run code(apt-get clean) +from time to time to free up disk space. + +dit(bf(autoclean)) +Like bf(clean), bf(autoclean) clears out the local repository of retrieved +package files. The difference is that it only removes package files that +can no longer be downloaded, and are largely useless. This allows a +cache to be maintained over a long period without it growing out of +control. + +enddit() + +manpageoptions() +All command line options may be set using the configuration file, the +descriptions indicate the configuration option to set. For boolean +options you can override the config file by using something like bf(-f-), +bf(--no-f), bf(-f=no) or several other variations. + +startdit() +dit(bf(-d, --download-only)) +Download only; package files are only retrieved, not unpacked or installed. +Configuration Item: bf(APT::Get::Download-Only). + +dit(bf(-f, --fix-broken)) +Fix; attempt to correct a system with broken dependencies in +place. This option, when used with install/remove, can omit any packages +to permit APT to deduce a likely soltion. Any Package that are specified +must completly correct the problem. The option is sometimes necessary when +running APT for the first time; APT itself does not allow broken package +dependencies to exist on a system. It is possible that a system's +dependency structure can be so corrupt as to require manual intervention +(which usually means using dselect or dpkg --remove to eliminate some of +the offending packages). Use of this option together with -m may produce an +error in some situations. Configuration Item: bf(APT::Get::Fix-Broken). + +dit(bf(-h, --help)) +Help; display a helpful usage message and exits. + +dit(bf(-v, --version)) +Show the program version. + +dit(bf(-m, --ignore-missing, --fix-missing)) +Ignore missing packages; If packages cannot be retrieved or fail the +integrity check after retrieval (corrupted package files), hold back +those packages and handle the result. Use of this option together with +-f may produce an error in some situations. If a package is selected for +installation (particularly if it is mentioned on the command line) and it +could not be downloaded then it will be silently held back. +Configuration Item: bf(APT::Get::ignore-missing). + +dit(bf(--no-download)) +Disables downloading of packages. This is best used with --ignore-missing to +force APT to use only the .debs it has already downloaded. +Configuration Item: bf(APT::Get::No-Download). + +dit(bf(-q, --quiet)) +Quiet; produces output suitable for logging, omitting progress indicators. +More q's will produce more quiet up to a maximum of 2. You can also use +bf(-q=#) to set the quiet level, overriding the configuration file. Note that +quiet level 2 implies -y, you should never use -qq without a no-action +modifier such as -d, --print-uris or -s as APT may decided to do something +you did not expect. +Configuration Item: bf(quiet) + +dit(bf(-s, --simulate, --just-print, --dry-run, --recon, --no-act)) +No action; perform a simulation of events that would occur but do not +actually change the system. Configuration Item: bf(APT::Get::Simulate). + +Simulate prints out +a series of lines each one representing a dpkg operation, Configure (Conf), +Remove (Remv), Unpack (Inst). Square brackets indicate broken packages with +and empty set of square brackets meaning breaks that are of no consequence +(rare). + +dit(bf(-y, --yes, --assume-yes)) +Automatic yes to prompts; assume "yes" as answer to all prompts and run +non-interactively. If an undesirable situation, such as changing a held +package or removing an essential package occurs then bf(apt-get) will +abort. Configuration Item: bf(APT::Get::Assume-Yes). + +dit(bf(-u, --show-upgraded)) +Show upgraded packages; Print out a list of all packages that are to be +upgraded. Configuration Item: bf(APT::Get::Show-Upgraded). + +dit(bf(-b, --compile, --build)) +Compile source packages after downloading them. +Configuration Item: bf(APT::Get::Compile). + +dit(bf(--ignore-hold)) +Ignore package Holds; This causes bf(apt-get) to ignore a hold placed on +a package. This may be useful in conjunction with bf(dist-upgrade) to +override a large number of undesired holds. Configuration Item: bf(APT::Ignore-Hold). + +dit(bf(--no-upgrade)) +Do not upgrade packages; When used in conjunction with bf(install) +bf(no-upgrade) will prevent packages listed from being upgraded if they +are already installed. Configuration Item: bf(APT::Get::no-upgrade). + +dit(bf(--force-yes)) +Force yes; This is a dangerous option that will cause apt to continue without +prompting if it is doing something potentially harmful. It should not be used +except in very special situations. Using bf(force-yes) can potentially destroy +your system! Configuration Item: bf(APT::Get::force-yes). + +dit(bf(--print-uris)) +Instead of fetching the files to install their URIs are printed. Each +URI will have the path, the destination file name, the size and the expected +md5 hash. Note that the file name to write to will not always match +the file name on the remote site! This also works with the bf(source) +command. Configuration Item: bf(APT::Get::Print-URIs). + +dit(bf(--purge)) +Use purge instead of remove for anything that would be removed. +Configuration Item: bf(APT::Get::Purge). + +dit(bf(--reinstall)) +Re-Install packages that are already installed and at the newest version. + +dit(bf(--list-cleanup)) +This option defaults to on, use bf(--no-list-cleanup) to turn it off. +When on apt-get will automatically manage the contents of +/var/state/apt/lists to ensure that obsolete files are erased. The only +reason to turn it off is if you frequently change your source list. +Configuration Item: bf(APT::Get::List-Cleanup) + +dit(bf(--trivial-only)) +Only perform operations are 'trivial'. Logically this can be considered +related to --assume-yes, where --assume-yes will answer yes to any prompt, +--trivial-only will answer no. Configuration Item: bf(APT::Get::Trivial-Only) + +dit(bf(--no-remove)) +If any packages are to be removed apt-get immediately aborts without +prompting. Configuration Item: bf(APT::Get::No-Remove) + +dit(bf(--diff-only), bf(--tar-only)) +Download only the diff or tar file of a source archive. +Configuration Item: bf(APT::Get::Diff-Only) + +dit(bf(-c, --config-file)) +Configuration File; Specify a configuration file to use. bf(apt-get) will +read the default configuration file and then this configuration file. See +bf(apt.conf(5)) for syntax information. + +dit(bf(-o, --option)) +Set a Configuration Option; This will set an arbitrary configuration option. +The syntax is +verb(-o Foo::Bar=bar) +enddit() + +manpagefiles() +itemize( + it() /etc/apt/sources.list + locations to fetch packages from + + it() /var/cache/apt/archives/ + storage area for retrieved package files + + it() /var/cache/apt/archives/partial/ + storage area for package files in transit + + it() /var/state/apt/lists/ + storage area for state information for each package resource specified in + the source list + + it() /var/state/apt/lists/partial/ + storage area for state information in transit +) + +manpageseealso() +apt-cache(8), +dpkg(8), +dselect(8), +sources.list(5), +apt.conf(5), +The APT Users Guide in /usr/doc/apt/ + +manpagediagnostics() +apt-get returns zero on normal operation, decimal 100 on error. + +manpagebugs() +See http://bugs.debian.org/apt. If you wish to report a +bug in bf(apt-get), please see bf(/usr/doc/debian/bug-reporting.txt) +or the bf(bug(1)) command. + +manpageauthor() +apt-get was written by the APT team . diff --git a/apt/doc/apt.8 b/apt/doc/apt.8 new file mode 100644 index 0000000..151d2a2 --- /dev/null +++ b/apt/doc/apt.8 @@ -0,0 +1,55 @@ +.\" This manpage is copyright (C) 1998 Branden Robinson . +.\" +.\" Updated for Conectiva by Alfredo K. Kojima . +.\" +.\" This is free software; you may redistribute it and/or modify +.\" it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2, +.\" or (at your option) any later version. +.\" +.\" This is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with APT; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +.\" 02111-1307 USA +.TH apt 8 "25 Oct 2000" "Debian GNU/Linux" +.SH NAME +apt \- Advanced Package Tool +.SH SYNOPSIS +.B apt +.SH DESCRIPTION +APT is a management system for software packages. It is still +under development; the snazzy front ends are not yet available. In the +meantime, please see +.BR apt-get (8). +.SH OPTIONS +None. +.SH FILES +None. +.SH SEE ALSO +.BR apt-cache (8), +.BR apt-get (8), +.BR sources.list (5) +.SH DIAGNOSTICS +apt returns zero on normal operation, decimal 100 on error. +.SH BUGS +This manpage isn't even started. +.PP +See . If you wish to report a +bug in +.BR apt , +please see +.I /usr/doc/debian/bug-reporting.txt +or the +.BR bug (1) +command. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. + +.SH AUTHOR +apt was written by the APT team +and updated for RPM based systems by +Conectiva S.A. diff --git a/apt/doc/apt.conf.5 b/apt/doc/apt.conf.5 new file mode 100644 index 0000000..3e27266 --- /dev/null +++ b/apt/doc/apt.conf.5 @@ -0,0 +1,290 @@ +.TH "apt\&.conf" "5" "25 Oct 2000" "apt" "" +.SH "NAME" +apt\&.conf \- configuration file for APT +.PP +.SH "DESCRIPTION" +\fBapt\&.conf\fP is the main configuration file for the APT suite of +tools, all tools make use of the configuration file and a common command line +parser to provide a uniform environment\&. When an APT tool starts up it will +read \fB/etc/apt/apt\&.conf\fP, then read the configuration specified by the +\fB$APT_CONFIG\fP environment variable and then finally apply the command line +options to override the configuration directives, possibly loading more +config files\&. +.PP +The configuration file is organized in a tree with options organized into +functional groups\&. Option specification is given with a double colon +notation, for instance \fIAPT::Get::Assume-Yes\fP is an option within the +APT tool group, for the Get tool\&. Options do not inherit from their parent +groups\&. +.PP +Syntacticly the configuration language is modeled after what the ISC tools +such as bind and dhcp use\&. Each line is of the form +.RS +APT::Get::Assume-Yes "true"; +.RE +The trailing semicolon is required and +the quotes are optional\&. A new \fIscope\fP can be opened with curly braces, +like: + +.nf + +APT { + Get { + Assume-Yes "true"; + Fix-Broken "true"; + }; +}; + +.fi + + +with newlines placed to make +it more readable\&. Lists can be created by opening a scope an including a +single word enclosed in quotes followed by a semicolon\&. +In general the sample configuration file in +\fI/usr/doc/apt/examples/apt\&.conf\fP and +\fI/usr/doc/apt/examples/configure-index\fP +(or \fI/usr/share/doc/apt*/examples/configure-index\fP in Conectiva) +is a good guide for how it should look\&. +.PP +All of the APT tools take a -o option which allows an arbitary configuration +directive to be specified on the command line\&. The syntax is a full option +name (APT::Get::Assume-Yes for instance) followed by an equals sign then the +new value of the option\&. Lists can be appended too by adding a trailing :: +to the list name\&. +.PP +.SH "The APT Group" +This group of options controls general APT behavoir as well as holding the +options for all of the tools\&. +.PP +.IP "\fBArchitecture\fP" +System Architecture; sets the architecture to use when fetching files and +parsing package lists\&. The internal default is the architecture apt was +compiled for\&. +.IP +.IP "\fBIgnore-Hold\fP" +Ignore Held packages; This global options causes the problem resolver to +ignore held packages in its decision making\&. +.IP +.IP "\fBClean-Installed\fP" +Defaults to on\&. When turned on the autoclean feature will remove any package +which can no longer be downloaded from the cache\&. If turned off then +packages that are locally installed are also excluded from cleaning - but +note that APT provides no direct means to reinstall them\&. +.IP +.IP "\fBImmediate-Configure\fP" +Disable Immedate Configuration; This dangerous option disables some +of APT\'s ordering code to cause it to make fewer dpkg calls\&. Doing +so may be necessary on some extremely slow single user systems but +is very dangerous and may cause package install scripts to fail or worse\&. +Use at your own risk\&. This option does not have any effect on RPM based +systems\&. +.IP +.IP "\fBForce-LoopBreak\fP" +Never Enable this option unless you -really- know what you are doing\&. It +permits APT to temporarily remove an essential package to break a +Conflicts/Conflicts or Conflicts/Pre-Depend loop between two essential +packages\&. SUCH A LOOP SHOULD NEVER EXIST AND IS A GRAVE BUG\&. This option will +work if the essential packages are not tar, gzip, libc, dpkg, bash or +anything that those packages depend on\&. +.IP +.IP "\fBCache-Limit\fP" +APT uses a fixed size memory mapped cache file to store the \'available\' +information\&. This sets the size of that cache\&. +.IP +.IP "\fBGet\fP" +The Get subsection controls the \fBapt-get(8)\fP tool, please see its +documentation for more information about the options here\&. +.IP +.IP "\fBCache\fP" +The Cache subsection controls the \fBapt-cache(8)\fP tool, please see its +documentation for more information about the options here\&. +.IP +.IP "\fBCDROM\fP" +The CDROM subsection controls the \fBapt-cdrom(8)\fP tool, please see its +documentation for more information about the options here\&. +.IP +.PP +.SH "The Acquire Group" +The \fBAcquire\fP group of options controls the download of packages and the +URI handlers\&. +.PP +.IP "\fBQueue-Mode\fP" +Queuing mode; \fBQueue-Mode\fP can be one of \fBhost\fP or \fBaccess\fP which +determins how APT parallelizes outgoing connections\&. \fBhost\fP means that +one connection per target host will be opened, \fBaccess\fP means that one +connection per URI type will be opened\&. +.IP +.IP "\fBRetries\fP" +Number of retries to perform\&. If this is non-zero apt will retry failed +files the given number of times\&. +.IP +.IP "\fBSource-Symlinks\fP" +Use symlinks for source archives\&. If set to true then source archives will +be symlinked when possible instead of copying\&. True is the default +.IP +.IP "\fBhttp\fP" +HTTP URIs; http::Proxy is the default http proxy to use\&. It is in the standard +form of \fIhttp://[[user][:pass]@]host[:port]/\fP\&. Per host proxies can also +be specified by using the form http::Proxy:: with the special keyword +\fIDIRECT\fP meaning to use no proxies\&. The \fI$http_proxy\fP environment variable +will override all settings\&. +.IP +Three settings are provided for cache control with HTTP/1\&.1 complient proxy +caches\&. \fBNo-Cache\fP tells the proxy to not used its cached response under +any circumstances, \fBMax-Age\fP is sent only for index files and tells the +cache to refresh its object if it is older than the given number of seconds\&. +Debian updates its index files daily so the default is 1 day\&. \fBNo-Store\fP +specifies that the cache should never store this request, it is only +set for archive files\&. This may be usefull to prevent polluting a proxy cache +with very large \&.deb files\&. Note: Squid 2\&.0\&.2 does not support any of +these options\&. +.IP +The option \fBtimeout\fP sets the timeout timer used by the method, this +applies to all things including connection timeout and data timeout\&. +.IP +One setting is provided to control the pipeline depth in cases where the +remote server is not RFC conforming or buggy (such as Squid 2\&.0\&.2) +Acquire::http::Pipeline-Depth can be a value from 0 to 5 indicating how many +outstanding requests APT should send\&. +.IP +.IP "\fBftp\fP" +FTP URis; ftp::Proxy is the default proxy server to use\&. It is in the +standard form of \fIftp://[[user][:pass]@]host[:port]/\fP and is overriden +by the ftp_proxy environment variable\&. To use a ftp proxy you will have to +set the ftp::ProxyLogin script in the configuration file\&. This entry +specifies the commands to send to tell the proxy server what to connect +to\&. Please see \fI/usr/doc/apt/examples/configure-index\fP for an example of how +to do this\&. The subsitution variables available are $(PROXY_USER), +$(PROXY_PASS), $(SITE_USER), $(SITE_PASS), $(SITE), and $(SITE_PORT)\&. +Each is taken from it\'s respective URI component\&. +.IP +The option \fBtimeout\fP sets the timeout timer used by the method, this +applies to all things including connection timeout and data timeout\&. +.IP +Several settings are provided to control passive mode\&. Generally it is safe +to leave passive mode on, it works in nearly every environment\&. However some +situations require that passive mode be disabled and port mode ftp used +instead\&. This can be done globally, for connections that go through a proxy +or for a specific host (See the sample config file for examples) +.IP +It is possible to proxy FTP over HTTP by setting the \fIftp_proxy\fP +environment variable to a http url - see the discussion of the http method +above for syntax\&. You cannot set this in the configuration file and it is +not recommended to use FTP over HTTP due to its low efficiency\&. +.IP +.IP "\fBcdrom\fP" +CDROM URIs; the only setting for CDROM URIs is the mount point, cdrom::Mount +which must be the mount point for the CDROM drive as specified in /etc/fstab\&. +It is possible to provide alternate mount and unmount commands if your +mount point cannot be listed in the fstab (such as an SMB mount)\&. The syntax +is to put "/cdrom/"::Mount "foo"; within the cdrom block\&. It is important to +have the trailing slash\&. Unmount commands can be specified using UMount\&. +.IP +.PP +.SH "Directories" +The \fBDir::State\fP section has directories that pertain to local state +information\&. \fBlists\fP is the directory to place downloaded package lists +in and \fBstatus\fP is the name of the dpkg status file\&. \fBDir::State\fP +contains the default directory to prefix on all sub items if they do not +start with \fI/\fP or \fI\&./\fP\&. \fBxstatus\fP and \fBuserstatus\fP are for future +use\&. +.PP +\fBDir::Cache\fP contains locations pertaining to local cache information, such +as the two package caches \fBsrcpkgcache\fP and \fBpkgcache\fP as well as the +location to place downloaded archives, \fBDir::Cache::archives\fP\&. Like +\fBDir::State\fP the default directory is contained in \fBDir::Cache\fP +.PP +\fBDir::Etc\fP contains the location of configuration files, \fBsourcelist\fP +gives the location of the sourcelist and \fBmain\fP is the default configuration +file (setting has no effect) +.PP +Binary programs are pointed to by \fBDir::Bin\fP\&. \fBmethods\fP specifies the +location of the method handlers and \fBgzip\fP, \fBdpkg\fP, \fBrpm\fP, +\fBapt-get\fP, \fBdpkg-source\fP, \fBdpkg-buildpackage\fP and +\fBapt-cache\fP specify the location of the respective programs\&. +.PP +.SH "APT in DSelect" +When APT is used as a \fBdselect(8)\fP method several configuration directives +control the default behavoir\&. These are in the \fBDSelect\fP section\&. +.PP +.IP "\fBClean\fP" +Cache Clean mode; this value may be one of always, auto, prompt and never\&. +always will remove all archives after they have been downloaded while auto +will only remove things that are no longer downloadable (replaced with a new +version for instance) +.IP +.IP "\fBOptions\fP" +The contents of this variable is passed to \fBapt-get(8)\fP as command line +options when it is run for the install phase\&. +.IP +.IP "\fBUpdateOptions\fP" +The contents of this variable is passed to \fBapt-get(8)\fP as command line +options when it is run for the update phase\&. +.IP +.IP "\fBPromptAfterUpdate\fP" +If true the [U]pdate operation in dselect will always prompt to continue\&. +The default is to prompt only on error\&. +.PP +.SH "How APT calls DPkg" +Several configuration directives control how APT invokes dpkg\&. These are in +the \fBDPkg\fP section\&. +.PP +.IP "\fBOptions\fP" +This is a list of options to pass to dpkg\&. The options must be specified +using the list notation and each list item is passed as a single arugment +to dpkg\&. +.IP +.IP "\fBPre-Invoke\fP, \fBPost-Invoke\fP" +This is a list of shell commands to run before/after invoking dpkg\&. Like +\fBOptions\fP this must be specified in list notation\&. The commands +are invoked in order using /bin/sh, should any fail APT will abort\&. +.IP +.IP "\fBPre-Install-Pkgs\fP" +This is a list of shell commands to run before invoking dpkg\&. Like +\fBOptions\fP this must be specified in list notation\&. The commands +are invoked in order using /bin/sh, should any fail APT will abort\&. +Apt will pass to the commands on standard input the filenames of all +\&.deb files it is going to install, one per line\&. +.IP +.IP "\fBRun-Directory\fP" +APT chdirs to this directory before invoking dpkg, the default is /\&. +.IP +.IP "\fBBuild-Options\fP" +These options are passed to dpkg-buildpackage when compiling packages, +the default is to disable signing and produce all binaries\&. +.IP +.PP +.SH "Debug Options" +Most of the options in the \fBdebug\fP section are not interesting to the +normal user, however \fBDebug::pkgProblemResolver\fP shows interesting +output about the decisions dist-upgrade makes\&. \fBDebug::NoLocking\fP +disables file locking so apt can do some operations as non-root and +\fBDebug::pkgDPkgPM\fP (or \fBDebug::pkgRPMPM\fP) will print out the +command line for each dpkg invokation\&. \fBDebug::IdentCdrom\fP will +disable the inclusion of statfs data in CDROM IDs\&. +.PP +.SH "EXAMPLES" +\fB/usr/doc/apt/examples/configure-index\&.gz\fP or +\fB/usr/share/doc/apt*/configure-index\fP +contains a sample configuration +file showing the default values for all possible options\&. +.PP +.SH "FILES" +/etc/apt/apt\&.conf +.PP +.SH "SEE ALSO" +apt-cache (8), +apt-get (8) +.PP +.SH "BUGS" +See http://bugs\&.debian\&.org/apt\&. If you wish to report a +bug in \fBapt-get\fP, please see \fB/usr/doc/debian/bug-reporting\&.txt\fP +or the \fBbug(1)\fP command\&. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt-get was written by the APT team +and ported to RPM based systems by +Alfredo K. Kojima, Conectiva S.A. \&. + diff --git a/apt/doc/apt.conf.5.yo b/apt/doc/apt.conf.5.yo new file mode 100644 index 0000000..d075980 --- /dev/null +++ b/apt/doc/apt.conf.5.yo @@ -0,0 +1,282 @@ +mailto(apt@packages.debian.org) +manpage(apt.conf)(5)(5 Dec 1998)(apt)() +manpagename(apt.conf)(configuration file for APT) + +manpagedescription() +bf(apt.conf) is the main configuration file for the APT suite of +tools, all tools make use of the configuration file and a common command line +parser to provide a uniform environment. When an APT tool starts up it will +read bf(/etc/apt/apt.conf), then read the configuration specified by the +bf($APT_CONFIG) environment variable and then finally apply the command line +options to override the configuration directives, possibly loading more +config files. + +The configuration file is organized in a tree with options organized into +functional groups. Option specification is given with a double colon +notation, for instance em(APT::Get::Assume-Yes) is an option within the +APT tool group, for the Get tool. Options do not inherit from their parent +groups. + +Syntacticly the configuration language is modeled after what the ISC tools +such as bind and dhcp use. Each line is of the form +quote(APT::Get::Assume-Yes "true";) The trailing semicolon is required and +the quotes are optional. A new em(scope) can be opened with curly braces, +like: +verb(APT { + Get { + Assume-Yes "true"; + Fix-Broken "true"; + }; +}; +) +with newlines placed to make +it more readable. Lists can be created by opening a scope an including a +single word enclosed in quotes followed by a semicolon. +In general the sample configuration file in +em(/usr/doc/apt/examples/apt.conf) and +em(/usr/doc/apt/examples/configure-index) +is a good guide for how it should look. + +All of the APT tools take a -o option which allows an arbitary configuration +directive to be specified on the command line. The syntax is a full option +name (APT::Get::Assume-Yes for instance) followed by an equals sign then the +new value of the option. Lists can be appended too by adding a trailing :: +to the list name. + +manpagesection(The APT Group) +This group of options controls general APT behavoir as well as holding the +options for all of the tools. + +startdit() +dit(bf(Architecture)) +System Architecture; sets the architecture to use when fetching files and +parsing package lists. The internal default is the architecture apt was +compiled for. + +dit(bf(Ignore-Hold)) +Ignore Held packages; This global options causes the problem resolver to +ignore held packages in its decision making. + +dit(bf(Clean-Installed)) +Defaults to on. When turned on the autoclean feature will remove any pacakge +which can no longer be downloaded from the cache. If turned off then +packages that are locally installed are also excluded from cleaning - but +note that APT provides no direct means to reinstall them. + +dit(bf(Immediate-Configure)) +Disable Immedate Configuration; This dangerous option disables some +of APT's ordering code to cause it to make fewer dpkg calls. Doing +so may be necessary on some extremely slow single user systems but +is very dangerous and may cause package install scripts to fail or worse. +Use at your own risk. + +dit(bf(Force-LoopBreak)) +Never Enable this option unless you -really- know what you are doing. It +permits APT to temporarily remove an essential package to break a +Conflicts/Conflicts or Conflicts/Pre-Depend loop between two essential +packages. SUCH A LOOP SHOULD NEVER EXIST AND IS A GRAVE BUG. This option will +work if the essential packages are not tar, gzip, libc, dpkg, bash or +anything that those packages depend on. + +dit(bf(Cache-Limit)) +APT uses a fixed size memory mapped cache file to store the 'available' +information. This sets the size of that cache. + +dit(bf(Get)) +The Get subsection controls the bf(apt-get(8)) tool, please see its +documentation for more information about the options here. + +dit(bf(Cache)) +The Cache subsection controls the bf(apt-cache(8)) tool, please see its +documentation for more information about the options here. + +dit(bf(CDROM)) +The CDROM subsection controls the bf(apt-cdrom(8)) tool, please see its +documentation for more information about the options here. + +enddit() + +manpagesection(The Acquire Group) +The bf(Acquire) group of options controls the download of packages and the +URI handlers. + +startdit() +dit(bf(Queue-Mode)) +Queuing mode; bf(Queue-Mode) can be one of bf(host) or bf(access) which +determins how APT parallelizes outgoing connections. bf(host) means that +one connection per target host will be opened, bf(access) means that one +connection per URI type will be opened. + +dit(bf(Retries)) +Number of retries to perform. If this is non-zero apt will retry failed +files the given number of times. + +dit(bf(Source-Symlinks)) +Use symlinks for source archives. If set to true then source archives will +be symlinked when possible instead of copying. True is the default + +dit(bf(http)) +HTTP URIs; http::Proxy is the default http proxy to use. It is in the standard +form of em(http://[[user][:pass]@]host[:port]/). Per host proxies can also +be specified by using the form http::Proxy:: with the special keyword +em(DIRECT) meaning to use no proxies. The em($http_proxy) environment variable +will override all settings. + +Three settings are provided for cache control with HTTP/1.1 complient proxy +caches. bf(No-Cache) tells the proxy to not used its cached response under +any circumstances, bf(Max-Age) is sent only for index files and tells the +cache to refresh its object if it is older than the given number of seconds. +Debian updates its index files daily so the default is 1 day. bf(No-Store) +specifies that the cache should never store this request, it is only +set for archive files. This may be usefull to prevent polluting a proxy cache +with very large .deb files. Note: Squid 2.0.2 does not support any of +these options. + +The option bf(timeout) sets the timeout timer used by the method, this +applies to all things including connection timeout and data timeout. + +One setting is provided to control the pipeline depth in cases where the +remote server is not RFC conforming or buggy (such as Squid 2.0.2) +Acquire::http::Pipeline-Depth can be a value from 0 to 5 indicating how many +outstanding requests APT should send. + +dit(bf(ftp)) +FTP URis; ftp::Proxy is the default proxy server to use. It is in the +standard form of em(ftp://[[user][:pass]@]host[:port]/) and is overriden +by the ftp_proxy environment variable. To use a ftp proxy you will have to +set the ftp::ProxyLogin script in the configuration file. This entry +specifies the commands to send to tell the proxy server what to connect +to. Please see em(/usr/doc/apt/examples/configure-index) for an example of how +to do this. The subsitution variables available are $(PROXY_USER), +$(PROXY_PASS), $(SITE_USER), $(SITE_PASS), $(SITE), and $(SITE_PORT). +Each is taken from it's respective URI component. + +The option bf(timeout) sets the timeout timer used by the method, this +applies to all things including connection timeout and data timeout. + +Several settings are provided to control passive mode. Generally it is safe +to leave passive mode on, it works in nearly every environment. However some +situations require that passive mode be disabled and port mode ftp used +instead. This can be done globally, for connections that go through a proxy +or for a specific host (See the sample config file for examples) + + +It is possible to proxy FTP over HTTP by setting the em(ftp_proxy) +environment variable to a http url - see the discussion of the http method +above for syntax. You cannot set this in the configuration file and it is +not recommended to use FTP over HTTP due to its low efficiency. + +dit(bf(cdrom)) +CDROM URIs; the only setting for CDROM URIs is the mount point, cdrom::Mount +which must be the mount point for the CDROM drive as specified in /etc/fstab. +It is possible to provide alternate mount and unmount commands if your +mount point cannot be listed in the fstab (such as an SMB mount). The syntax +is to put "/cdrom/"::Mount "foo"; within the cdrom block. It is important to +have the trailing slash. Unmount commands can be specified using UMount. + +enddit() + +manpagesection(Directories) +The bf(Dir::State) section has directories that pertain to local state +information. bf(lists) is the directory to place downloaded package lists +in and bf(status) is the name of the dpkg status file. bf(Dir::State) +contains the default directory to prefix on all sub items if they do not +start with em(/) or em(./). bf(xstatus) and bf(userstatus) are for future +use. + +bf(Dir::Cache) contains locations pertaining to local cache information, such +as the two package caches bf(srcpkgcache) and bf(pkgcache) as well as the +location to place downloaded archives, bf(Dir::Cache::archives). Like +bf(Dir::State) the default directory is contained in bf(Dir::Cache) + +bf(Dir::Etc) contains the location of configuration files, bf(sourcelist) +gives the location of the sourcelist and bf(main) is the default configuration +file (setting has no effect) + +Binary programs are pointed to by bf(Dir::Bin). bf(methods) specifies the +location of the method handlers and bf(gzip), bf(dpkg), bf(apt-get), +bf(dpkg-source), bf(dpkg-buildpackage) and +bf(apt-cache) specify the location of the respective programs. + +manpagesection(APT in DSelect) +When APT is used as a bf(dselect(8)) method several configuration directives +control the default behavoir. These are in the bf(DSelect) section. + +startdit() +dit(bf(Clean)) +Cache Clean mode; this value may be one of always, auto, prompt and never. +always will remove all archives after they have been downloaded while auto +will only remove things that are no longer downloadable (replaced with a new +version for instance) + +dit(bf(Options)) +The contents of this variable is passed to bf(apt-get(8)) as command line +options when it is run for the install phase. + +dit(bf(UpdateOptions)) +The contents of this variable is passed to bf(apt-get(8)) as command line +options when it is run for the update phase. + +dit(bf(PromptAfterUpdate)) +If true the [U]pdate operation in dselect will always prompt to continue. +The default is to prompt only on error. +enddit() + +manpagesection(How APT calls DPkg) +Several configuration directives control how APT invokes dpkg. These are in +the bf(DPkg) section. + +startdit() +dit(bf(Options)) +This is a list of options to pass to dpkg. The options must be specified +using the list notation and each list item is passed as a single arugment +to dpkg. + +dit(bf(Pre-Invoke), bf(Post-Invoke)) +This is a list of shell commands to run before/after invoking dpkg. Like +bf(Options) this must be specified in list notation. The commands +are invoked in order using /bin/sh, should any fail APT will abort. + +dit(bf(Pre-Install-Pkgs)) +This is a list of shell commands to run before invoking dpkg. Like +bf(Options) this must be specified in list notation. The commands +are invoked in order using /bin/sh, should any fail APT will abort. +Apt will pass to the commands on standard input the filenames of all +.deb files it is going to install, one per line. + +dit(bf(Run-Directory)) +APT chdirs to this directory before invoking dpkg, the default is /. + +dit(bf(Build-Options)) +These options are passed to dpkg-buildpackage when compiling packages, +the default is to disable signing and produce all binaries. + +enddit() + +manpagesection(Debug Options) +Most of the options in the bf(debug) section are not interesting to the +normal user, however bf(Debug::pkgProblemResolver) shows interesting +output about the decisions dist-upgrade makes. bf(Debug::NoLocking) +disables file locking so apt can do some operations as non-root and +bf(Debug::pkgDPkgPM) will print out the command line for each dpkg +invokation. bf(Debug::IdentCdrom) will disable the inclusion of statfs +data in CDROM IDs. + +manpagesection(EXAMPLES) +bf(/usr/doc/apt/examples/configure-index.gz) contains a sample configuration +file showing the default values for all possible options. + +manpagesection(FILES) +/etc/apt/apt.conf + +manpageseealso() +apt-cache (8), +apt-get (8) + +manpagebugs() +See http://bugs.debian.org/apt. If you wish to report a +bug in bf(apt-get), please see bf(/usr/doc/debian/bug-reporting.txt) +or the bf(bug(1)) command. + +manpageauthor() +apt-get was written by the APT team . diff --git a/apt/doc/cache.sgml b/apt/doc/cache.sgml new file mode 100644 index 0000000..2962a83 --- /dev/null +++ b/apt/doc/cache.sgml @@ -0,0 +1,814 @@ + + + +APT Cache File Format + +Jason Gunthorpe jgg@debian.org +$Id: cache.sgml,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + +This document describes the complete implementation and format of the APT +Cache file. The APT Cache file is a way for APT to parse and store a +large number of package files for display in the UI. It's primary design +goal is to make display of a single package in the tree very fast by +pre-linking important things like dependencies and provides. + +The specification doubles as documentation for one of the in-memory +structures used by the package library and the APT GUI. + + + + +Copyright © Jason Gunthorpe, 1997-1998. +

+APT and this document are free software; you can redistribute them and/or +modify them under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Introduction + + +Purpose + +

+This document describes the implementation of an architecture +dependent binary cache file. The goal of this cache file is two fold, +firstly to speed loading and processing of the package file array and +secondly to reduce memory consumption of the package file array. + +

+The implementation is aimed at an environment with many primary package +files, for instance someone that has a Package file for their CD-ROM, a +Package file for the latest version of the distribution on the CD-ROM and a +package file for the development version. Always present is the information +contained in the status file which might be considered a separate package +file. + +

+Please understand, this is designed as a -CACHE FILE- it is not ment to be +used on any system other than the one it was created for. It is not ment to +be authoritative either, ie if a system crash or software failure occures it +must be perfectly acceptable for the cache file to be in an inconsistant +state. Furthermore at any time the cache file may be erased without losing +any information. + +

+Also the structures and storage layout is optimized for use by the APT +GUI and may not be suitable for all purposes. However it should be possible +to extend it with associate cache files that contain other information. + +

+To keep memory use down the cache file only contains often used fields and +fields that are inexepensive to store, the Package file has a full list of +fields. Also the client may assume that all items are perfectly valid and +need not perform checks against their correctness. Removal of information +from the cache is possible, but blanks will be left in the file, and +unused strings will also be present. The recommended implementation is to +simply rebuild the cache each time any of the data files change. It is +possible to add a new package file to the cache without any negative side +effects. + +Note on Pointer access +

+Every item in every structure is stored as the index to that structure. +What this means is that once the files is mmaped every data access has to +go through a fixup stage to get a real memory pointer. This is done +by taking the index, multiplying it by the type size and then adding +it to the start address of the memory block. This sounds complex, but +in C it is a single array dereference. Because all items are aligned to +their size and indexs are stored as multiples of the size of the structure +the format is immediately portable to all possible architectures - BUT the +generated files are -NOT-. + +

+This scheme allows code like this to be written: + + void *Map = mmap(...); + Package *PkgList = (Package *)Map; + Header *Head = (Header *)Map; + char *Strings = (char *)Map; + cout << (Strings + PkgList[Head->HashTable[0]]->Name) << endl; + +

+Notice the lack of casting or multiplication. The net result is to return +the name of the first package in the first hash bucket, without error +checks. + +

+The generator uses allocation pools to group similarly sized structures in +large blocks to eliminate any alignment overhead. The generator also +assures that no structures overlap and all indexes are unique. Although +at first glance it may seem like there is the potential for two structures +to exist at the same point the generator never allows this to happen. +(See the discussion of free space pools) + + +Structures + + +Header +

+This is the first item in the file. + + struct Header + { + // Signature information + unsigned long Signature; + short MajorVersion; + short MinorVersion; + bool Dirty; + + // Size of structure values + unsigned short HeaderSz; + unsigned short PackageSz; + unsigned short PackageFileSz; + unsigned short VersionSz; + unsigned short DependencySz; + unsigned short ProvidesSz; + unsigned short VerFileSz; + + // Structure counts + unsigned long PackageCount; + unsigned long VersionCount; + unsigned long DependsCount; + unsigned long PackageFileCount; + unsigned long MaxVerFileSize; + + // Offsets + unsigned long FileList; // PackageFile + unsigned long StringList; // StringItem + + // Allocation pools + struct + { + unsigned long ItemSize; + unsigned long Start; + unsigned long Count; + } Pools[7]; + + // Package name lookup + unsigned long HashTable[512]; // Package + }; + + +Signature +This must contain the hex value 0x98FE76DC which is designed to verify +that the system loading the image has the same byte order and byte size as +the system saving the image + +MajorVersion +MinorVersion +These contain the version of the cache file, currently 0.2. + +Dirty +Dirty is true if the cache file was opened for reading, the client expects +to have written things to it and have not fully synced it. The file should +be erased and rebuilt if it is true. + +HeaderSz +PackageSz +PackageFileSz +VersionSz +DependencySz +VerFileSz +ProvidesSz +*Sz contains the sizeof() that particular structure. It is used as an +extra consistancy check on the structure of the file. + +If any of the size values do not exactly match what the client expects then +the client should refuse the load the file. + +PackageCount +VersionCount +DependsCount +PackageFileCount +These indicate the number of each structure contianed in the cache. +PackageCount is especially usefull for generating user state structures. +See Package::Id for more info. + +MaxVerFileSize +The maximum size of a raw entry from the original Package file +(ie VerFile::Size) is stored here. + +FileList +This contains the index of the first PackageFile structure. The PackageFile +structures are singely linked lists that represent all package files that +have been merged into the cache. + +StringList +This contains a list of all the unique strings (string item type strings) in +the cache. The parser reads this list into memory so it can match strings +against it. + +Pools +The Pool structures manage the allocation pools that the generator uses. +Start indicates the first byte of the pool, Count is the number of objects +remaining in the pool and ItemSize is the structure size (alignment factor) +of the pool. An ItemSize of 0 indicates the pool is empty. There should be +the same number of pools as there are structure types. The generator +stores this information so future additions can make use of any unused pool +blocks. + +HashTable +HashTable is a hash table that provides indexing for all of the packages. +Each package name is inserted into the hash table using the following has +function: + + unsigned long Hash(string Str) + { + unsigned long Hash = 0; + for (const char *I = Str.begin(); I != Str.end(); I++) + Hash += *I * ((Str.end() - I + 1)); + return Hash % _count(Head.HashTable); + } + +

+By iterating over each entry in the hash table it is possible to iterate over +the entire list of packages. Hash Collisions are handled with a singely linked +list of packages based at the hash item. The linked list contains only +packages that macth the hashing function. + + + + + +Package +

+This contians information for a single unique package. There can be any +number of versions of a given package. Package exists in a singly +linked list of package records starting at the hash index of the name in +the Header->HashTable. + + struct Pacakge + { + // Pointers + unsigned long Name; // Stringtable + unsigned long VersionList; // Version + unsigned long TargetVer; // Version + unsigned long CurrentVer; // Version + unsigned long TargetDist; // StringTable (StringItem) + unsigned long Section; // StringTable (StringItem) + + // Linked lists + unsigned long NextPackage; // Package + unsigned long RevDepends; // Dependency + unsigned long ProvidesList; // Provides + + // Install/Remove/Purge etc + unsigned char SelectedState; // What + unsigned char InstState; // Flags + unsigned char CurrentState; // State + + // Unique ID for this pkg + unsigned short ID; + unsigned long Flags; + }; + + + +Name +Name of the package. + +VersionList +Base of a singely linked list of version structures. Each structure +represents a unique version of the package. The version structures +contain links into PackageFile and the original text file as well as +detailed infromation about the size and dependencies of the specific +package. In this way multiple versions of a package can be cleanly handled +by the system. Furthermore, this linked list is guarenteed to be sorted +from Highest version to lowest version with no duplicate entries. + +TargetVer +CurrentVer +This is an index (pointer) to the sub version that is being targeted for +upgrading. CurrentVer is an index to the installed version, either can be +0. + +TargetDist +This indicates the target distribution. Automatic upgrades should not go +outside of the specified dist. If it is 0 then the global target dist should +be used. The string should be contained in the StringItem list. + +Section +This indicates the deduced section. It should be "Unknown" or the section +of the last parsed item. + +NextPackage +Next link in this hash item. This linked list is based at Header.HashTable +and contains only packages with the same hash value. + +RevDepends +Reverse Depends is a linked list of all dependencies linked to this package. + +ProvidesList +This is a linked list of all provides for this package name. + +SelectedState +InstState +CurrentState +These corrispond to the 3 items in the Status field found in the status +file. See the section on defines for the possible values. +

+SelectedState is the state that the user wishes the package to be +in. +

+InstState is the installation state of the package. This normally +should be Ok, but if the installation had an accident it may be otherwise. +

+CurrentState indicates if the package is installed, partially installed or +not installed. + +ID +ID is a value from 0 to Header->PackageCount. It is a unique value assigned +by the generator. This allows clients to create an array of size PackageCount +and use it to store state information for the package map. For instance the +status file emitter uses this to track which packages have been emitted +already. + +Flags +Flags are some usefull indicators of the package's state. + + + + + + +PackageFile +

+This contians information for a single package file. Package files are +referenced by Version structures. This is a singly linked list based from +Header.FileList + + struct PackageFile + { + // Names + unsigned long FileName; // Stringtable + unsigned long Archive; // Stringtable + unsigned long Component; // Stringtable + unsigned long Version; // Stringtable + unsigned long Origin; // Stringtable + unsigned long Label; // Stringtable + unsigned long Architecture; // Stringtable + unsigned long Size; + + // Linked list + unsigned long NextFile; // PackageFile + unsigned short ID; + unsigned long Flags; + time_t mtime; // Modification time + }; + + + +FileName +Refers the the physical disk file that this PacakgeFile represents. + +Archive +Component +Version +Origin +Label +Architecture +NotAutomatic +This is the release information. Please see the files document for a +description of what the release information means. + +Size +Size is provided as a simple check to ensure that the package file has not +been altered. + +ID +See Package::ID. + +Flags +Provides some flags for the PackageFile, see the section on defines. + +mtime +Modification time for the file at time of cache generation. + + + + + + +Version +

+This contians the information for a single version of a package. This is a +singley linked list based from Package.Versionlist. + +

+The version list is always sorted from highest version to lowest version by +the generator. Also there may not be any duplicate entries in the list (same +VerStr). + + + struct Version + { + unsigned long VerStr; // Stringtable + unsigned long Section; // StringTable (StringItem) + unsigned long Arch; // StringTable + + // Lists + unsigned long FileList; // VerFile + unsigned long NextVer; // Version + unsigned long DependsList; // Dependency + unsigned long ParentPkg; // Package + unsigned long ProvidesList; // Provides + + unsigned long Size; + unsigned long InstalledSize; + unsigned long Hash; + unsigned short ID; + unsigned char Priority; + }; + + + +VerStr +This is the complete version string. + +FileList +References the all the PackageFile's that this version came out of. FileList +can be used to determine what distribution(s) the Version applies to. If +FileList is 0 then this is a blank version. The structure should also have +a 0 in all other fields excluding VerStr and Possibly NextVer. + +Section +This string indicates which section it is part of. The string should be +contained in the StringItem list. + +Arch +Architecture the package was compiled for. + +NextVer +Next step in the linked list. + +DependsList +This is the base of the dependency list. + +ParentPkg +This links the version to the owning package, allowing reverse dependencies +to determine the package. + +ProvidesList +Head of the linked list of Provides::NextPkgProv, forward provides. + +Size +InstalledSize +The archive size for this version. For debian this is the size of the .deb +file. Installed size is the uncompressed size for this version + +Hash +This is a characteristic value representing this package. No two packages +in existance should have the same VerStr and Hash with different contents. + +ID +See Package::ID. + +Priority +This is the parsed priority value of the package. + + + + + +Dependency +

+Dependency contains the information for a single dependency record. The records +are split up like this to ease processing by the client. The base of list +linked list is Version.DependsList. All forms of dependencies are recorded +here including Conflicts, Suggests and Recommends. + +

+Multiple depends on the same package must be grouped together in +the Dependency lists. Clients should assume this is always true. + + + struct Dependency + { + unsigned long Version; // Stringtable + unsigned long Package; // Package + unsigned long NextDepends; // Dependency + unsigned long NextRevDepends; // Reverse dependency linking + unsigned long ParentVer; // Upwards parent version link + + // Specific types of depends + unsigned char Type; + unsigned char CompareOp; + unsigned short ID; + }; + + +Version +The string form of the version that the dependency is applied against. + +Package +The index of the package file this depends applies to. If the package file +does not already exist when the dependency is inserted a blank one (no +version records) should be created. + +NextDepends +Linked list based off a Version structure of all the dependencies in that +version. + +NextRevDepends +Reverse dependency linking, based off a Package structure. This linked list +is a list of all packages that have a depends line for a given package. + +ParentVer +Parent version linking, allows the reverse dependency list to link +back to the version and package that the dependency are for. + +Type +Describes weather it is depends, predepends, recommends, suggests, etc. + +CompareOp +Describes the comparison operator specified on the depends line. If the high +bit is set then it is a logical or with the previous record. + +ID +See Package::ID. + + + + + + +Provides +

+Provides handles virtual packages. When a Provides: line is encountered +a new provides record is added associating the package with a virtual +package name. The provides structures are linked off the package structures. +This simplifies the analysis of dependencies and other aspects A provides +refers to a specific version of a specific package, not all versions need to +provide that provides. + +

+There is a linked list of provided package names started from each +version that provides packages. This is the forwards provides mechanism. + + struct Provides + { + unsigned long ParentPkg; // Package + unsigned long Version; // Version + unsigned long ProvideVersion; // Stringtable + unsigned long NextProvides; // Provides + unsigned long NextPkgProv; // Provides + }; + + +ParentPkg +The index of the package that head of this linked list is in. ParentPkg->Name +is the name of the provides. + +Version +The index of the version this provide line applies to. + +ProvideVersion +Each provides can specify a version in the provides line. This version allows +dependencies to depend on specific versions of a Provides, as well as allowing +Provides to override existing packages. This is experimental. + +NextProvides +Next link in the singly linked list of provides (based off package) + +NextPkgProv +Next link in the singly linked list of provides for 'Version'. + + + + + + +VerFile +

+VerFile associates a version with a PackageFile, this allows a full +description of all Versions in all files (and hence all sources) under +consideration. + + + struct pkgCache::VerFile + { + unsigned long File; // PackageFile + unsigned long NextFile; // PkgVerFile + unsigned long Offset; + unsigned short Size; + } + + +File +The index of the package file that this version was found in. + +NextFile +The next step in the linked list. + +Offset +Size +These describe the exact position in the package file for the section from +this version. + + + + + +StringItem +

+StringItem is used for generating single instances of strings. Some things +like Section Name are are usefull to have as unique tags. It is part of +a linked list based at Header::StringList. + + struct StringItem + { + unsigned long String; // Stringtable + unsigned long NextItem; // StringItem + }; + + +String +The string this refers to. + +NextItem +Next link in the chain. + + + + +StringTable +

+All strings are simply inlined any place in the file that is natural for the +writer. The client should make no assumptions about the positioning of +strings. All stringtable values point to a byte offset from the start of the +file that a null terminated string will begin. + + + +Defines +

+Several structures use variables to indicate things. Here is a list of all +of them. + +Definitions for Dependency::Type +

+ +#define pkgDEP_Depends 1 +#define pkgDEP_PreDepends 2 +#define pkgDEP_Suggests 3 +#define pkgDEP_Recommends 4 +#define pkgDEP_Conflicts 5 +#define pkgDEP_Replaces 6 + + + +Definitions for Dependency::CompareOp +

+ +#define pkgOP_OR 0x10 +#define pkgOP_LESSEQ 0x1 +#define pkgOP_GREATEREQ 0x2 +#define pkgOP_LESS 0x3 +#define pkgOP_GREATER 0x4 +#define pkgOP_EQUALS 0x5 + +The lower 4 bits are used to indicate what operator is being specified and +the upper 4 bits are flags. pkgOP_OR indicates that the next package is +or'd with the current package. + + +Definitions for Package::SelectedState +

+ +#define pkgSTATE_Unkown 0 +#define pkgSTATE_Install 1 +#define pkgSTATE_Hold 2 +#define pkgSTATE_DeInstall 3 +#define pkgSTATE_Purge 4 + + + +Definitions for Package::InstState +

+ +#define pkgSTATE_Ok 0 +#define pkgSTATE_ReInstReq 1 +#define pkgSTATE_Hold 2 +#define pkgSTATE_HoldReInstReq 3 + + + +Definitions for Package::CurrentState +

+ +#define pkgSTATE_NotInstalled 0 +#define pkgSTATE_UnPacked 1 +#define pkgSTATE_HalfConfigured 2 +#define pkgSTATE_UnInstalled 3 +#define pkgSTATE_HalfInstalled 4 +#define pkgSTATE_ConfigFiles 5 +#define pkgSTATE_Installed 6 + + + +Definitions for Package::Flags +

+ +#define pkgFLAG_Auto (1 << 0) +#define pkgFLAG_New (1 << 1) +#define pkgFLAG_Obsolete (1 << 2) +#define pkgFLAG_Essential (1 << 3) +#define pkgFLAG_ImmediateConf (1 << 4) + + + +Definitions for Version::Priority +

+Zero is used for unparsable or absent Priority fields. + +#define pkgPRIO_Important 1 +#define pkgPRIO_Required 2 +#define pkgPRIO_Standard 3 +#define pkgPRIO_Optional 4 +#define pkgPRIO_Extra 5 + + + +Definitions for PackageFile::Flags +

+ +#define pkgFLAG_NotSource (1 << 0) +#define pkgFLAG_NotAutomatic (1 << 1) + + + + + +Notes on the Generator + + +

+The pkgCache::MergePackageFile function is currently the only generator of +the cache file. It implements a conversion from the normal textual package +file into the cache file. + +

+The generator assumes any package declaration with a +Status: line is a 'Status of the package' type of package declaration. +A Package with a Target-Version field should also really have a status field. +The processing of a Target-Version field can create a place-holder Version +structure that is empty to refer to the specified version (See Version +for info on what a empty Version looks like). The Target-Version syntax +allows the specification of a specific version and a target distribution. + +

+Different section names on different versions is supported, but I +do not expect to use it. To simplify the GUI it will mearly use the section +in the Package structure. This should be okay as I hope sections do not change +much. + +

+The generator goes through a number of post processing steps after producing +a disk file. It sorts all of the version lists to be in descending order +and then generates the reverse dependency lists for all of the packages. +ID numbers and count values are also generated in the post processing step. + +

+It is possible to extend many of the structures in the cache with extra data. +This is done by using the ID member. ID will be a unique number from 0 to +Header->??Count. For example + +struct MyPkgData; +MyPkgData *Data = new MyPkgData[Header->PackageCount]; +Data[Package->ID]->Item = 0; + +This provides a one way reference between package structures and user data. To +get a two way reference would require a member inside the MyPkgData structure. + +

+The generators use of free space pools tend to make the package file quite +large, and quite full of blank space. This could be fixed with sparse files. + + + +Future Directions + + +

+Some good directions to take the cache file is into a cache directory that +contains many associated caches that cache other important bits of +information. (/var/cache/apt, FHS2) + +

+Caching of the info/*.list is an excellent place to start, by generating all +the list files into a tree structure and reverse linking them to the package +structures in the main cache file major speed gains in dpkg might be achived. + + + + diff --git a/apt/doc/design.sgml b/apt/doc/design.sgml new file mode 100644 index 0000000..faa49d7 --- /dev/null +++ b/apt/doc/design.sgml @@ -0,0 +1,411 @@ + + + + + The APT project design document + + Manoj Srivastava + srivasta@debian.org + + $Id: design.sgml,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + This document is an overview of the specifications and design + goals of the APT project. It also attempts to give a broad + description of the implementation as well. + + + Copyright ©1997 Manoj Srivastava + +

+ APT, including this document, is free software; you may + redistribute it and/or modify it under the terms of the GNU + General Public License as published by the Free Software + Foundation; either version 2, or (at your option) any later + version.

+

+ This is distributed in the hope that it will be useful, but + without any warranty; without even the implied + warranty of merchantability or fitness for a particular + purpose. See the GNU General Public License for more + details.

+ +

+ You should have received a copy of the GNU General Public + License with your Debian GNU/Linux system, in + /usr/doc/copyright/GPL, or with the + COPYING. If not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, + USA.

+
+ + + Introduction +

APT is supposed to be a replacement for dselect, and not a + replacement for dpkg. However, since addition functionality + has been required for APT, and given the fact that this is + very closely related to dpkg, it is not unreasonable to expect + that additional functionality in the underlying dpkg would + also be requested.

+ +

Diety/dselect are the first introduction that people have to + Debian, and unfortunately this first impression contributes + greatly to the public perception of the distribution. It is + imperative that this be a showcase for Debian, rather than + frighten novices away (which has been an accusation often + levelled at the current system)

+
+ + Requirements +

+ + +

+ APT should be a replacement for dselect. Therefore it + should have all the functionality that dselect has + currently. This is the primary means of interaction + between the user and the package management system, and + it should be able to handle all tasks involved in + installing, upgrading, and routine management without + having the users take recourse to the underlying + management system.

+
+ +

+ It should be easier to use and less confusing for novice + users. The primary stimulus for the creation of APT + was the perceived intractability, complexity, and + non-intuitive behavior of the existing user interface, + and as such, human factors must be a primary mandate of + APT.

+
+ +

+ It should be able to group packages more flexibly, and + possibly allow operations based on a group. One should + be able to select, or deselect, a coherent group of + related packages simultaneously, allowing one to add, + remove, or upgrade functionality to a machine as one + step. +

+
+ +

+ This would allow APT to handle standard + installations, namely, one could then install a + set of packages to enable a machine to fulfill specific + tasks. Define a few standard installations, and which + packages are included therein. The packages should be + internally consistent.

+
+ +

+ Make use of a keywords field in package headers; provide + a standard list of keywords for people to use. This + could be the underpinning to allow the previous two + requirements to work (though the developers are not + constrained to implement the previous requirements using + keywords) +

+
+ +

+ Use dependencies, conflicts, and reverse dependencies to + properly order packages for installation and + removal. This has been a complaint in the past that the + installation methods do not really understand + dependencies, causing the upgrade process to break, or + allowing the removal of packages that left the system in + an untenable state by breaking the dependencies on + packages that were dependent on the package being + removed. A special emhasis is placed on handling + pre-dependencies correctly; the target of a + predependency has to be fully configured before + attempting to install the pre-dependent package. Also, + configure immediately requests mentioned below + should be handled.

+
+ +

+ Handle replacement of a package providing a virtual + package with another (for example, it has been very + difficult replacing sendmail with + smail, or vice versa), making sure that the + dependencies are still satisfied.

+
+ +

+ Handle source lists for updates from multiple + sources. APT should also be able to handle diverse + methods of acquiring new packages; local filesystem, + mountable CD-ROM drives, FTP accesible repositories are + some of the methods that come to mind. Also, the source + lists can be separated into categories, such as main, + contrib, non-us, non-local, non-free, my-very-own, + etc. APT should be set up to retrive the Packages + files from these multiple source lists, as well as + retrieving the packages themselves.

+
+ +

+ Handle base of source and acquire all Packages files + underneath. (possibly select based on architecture), + this should be a simple extension of the previous + requirement.

+
+ +

+ Handle remote installation (to be implemented maybe in a + future version, it still needs to be designed). This + would ease the burden of maintaining multiple Debian + machines on a site. In the authors opinion this is a + killer difference for the distribution, though it may be + too hard a problem to be implemented with the initial + version of APT. However, some thought must be given to + this to enable APT to retain hooks for future + functionality, or at least to refrain from methods that + may preclude remote activity. It is desirable that + adding remote installation not require a redesign of + APT from the ground up.

+
+ +

+ Be scalable. Dselect worked a lot better with 400 + packages, but at last count the number of packages was + around twelve hundred and climbing. This also requires + APT to pay attention to the needs of small machines + which are low on memory (though this requirement shall + diminish as we move towards bigger machines, it would + still be nice if Debian worked on all old machines where + Linux itself would work).

+
+ +

+ Handle install immediately requests. Some packages, like + watchdog, are required to be working for the stability + of the machine itself. There are others which may be + required for the correct functioning of a production + machine, or which are mission critical + applications. APT should, in these cases, upgrade the + packages with minimal downtime; allowing these packages + to be one of potentially hundreds of packages being + upgraded concurrently may not satisfy the requirements + of the package or the site. (Watchdog, for example, if + not restarted quickly, may cause the machine to reboot + in the midst of installation, which may cause havoc on + the machine)

+
+ +

+ + + Procedural description +

+ Set Options + +

+ This process handles setting of user or + site options, and configuration of all aspects of + APT. It allows the user to set the location and order + of package sources, allowing them to set up source list + details, like ftp site locations, passwords, + etc. Display options may also be set.

+
+ Updates + +

+ Build a list of available packages, using + source lists or a base location and trawling for + Packages files (needs to be aware of architecture). This + may involve finding and retrieving Packages files, + storing them locally for efficiency, and parsing the + data for later use. This would entail contacting various + underlying access modules (ftp, cdrom mounts, etc) Use a + backing store for speed. This may also require + downloading the actual package files locally for + speed.

+
+ Local status + +

+ Build up a list of packages already + installed. This requires reading and writing the local?? + status file. For remote installation, this should + probably use similar mechanisms as the Packages file + retrieval does. Use the backing store for speed. One + should consider multiple backing stores, one for each + machine. +

+
+ Relationship determination + +

+ Determine forward and reverse dependencies. All known + dependency fields should be acted upon, since it is + fairly cheap to do so. Update the backing store with + this information.

+
+ Selection + +

+ Present the data to the user. Look at Behan Webster's + documentation for the user interface procedures. (Note: + In the authors opinion deletions and reverse + dependencies should also be presented to the user, in a + strictly symmetric fashion; this may make it easier to + prevent a package being removed that breaks + dependencies) +

+
+ Ordering of package installations and configuration + +

+ Build a list of events. Simple topological sorting gives + order of packages in dependency order. At certain points + in this ordering, predependencies/immediate configure + directives cause an break in normal ordering. We need to + insert the uninstall/purge directive in the stream + (default: as early as possible).

+
+ Action + +

+ Take the order of installations and removals and build + up a stream of events to send to the packaging system + (dpkg). Execute the list of events if succesful. Do not + partially install packages and leave system in broken + state. Go to The Selection step as needed.

+
+ + +

+ + + Modules and interfaces +

+ The user interface module + +

Look at Behan Webster's documentation.

+
+ Widget set + +

+ Related closely to above Could some one present design + decisions of the widget set here?

+
+ pdate Module + +

+ Distinct versions of the same package are recorded + separately, but if multiple Packages files contain the + same version of a package, then only the forst one is + recorded. For this reason, the least expensive update + source should be listed first (local file system is + better than a remote ftp site)

+

+ This module should interact with the user interface + module to set and change configuration parameters for + the modules listed below. It needs to record that + information in an on disk data file, to be read on + future invocations.

+

+ +

FTP methods

+
+ +

mount and file traversal module(s)?

+
+ +

Other methods ???

+
+ +

+
+ Status file parser/generator + +

+ The status file records the current state of the system, + listing the packages installed, etc. The status file is + also one method of communicating with dpkg, since it is + perfectly permissible for the user to use APT to + request packages be updated, put others on hold, mark + other for removal, etc, and then run dpkg + -BORGiE on a file system.

+
+ Package file parser/generator + +

+ Related to above. Handle multiple Packages files, from + different sources. Each package contains a link back to + the packages file structure that contains details about + the origin of the data.

+
+ Dependency module + +

+ +

dependency/conflict determination and linking

+
+ +

reverse dependency generator. Maybe merged with above

+
+ +

+
+ Package ordering Module + +

Create an ordering of the actions to be taken.

+
+ Event genrator + +

module to interact with dpkg

+
+ + + + Data flow and conversions analysis. +

+ + ____________ + __\|ftp modules| + / /|___________| + _ ____________ / ________________ + | update | / |mount/local file| + |==========================>| module |/_____\| traversals | + | |_____________| /|________________| + | ^ ^ + | | | ______________ + ______|_______ _ _____ ______ | _____v________ \| | + |Configuration | |configuration| | |Packages Files| ===|Status file | + | module |<=>| data | | |______________| / /|____________| + |______________| |_____________| | ^ / + ^ | | / + | | _______v_______|/_ + | | | | ________________ + | | | |/_\| Dependency | + | | |backing store |\ /| Module | + | | |______________| _|_______________| + | \ ^ /| ^ + | \ | / | + | _\|____v_______|/__ ____v_______ + |_____________________________\| User interaction| | dpkg | + /|_________________|<==>| Invoker | + |___________| + + +

dpkg also interacts with status and available files.

+ + +

+ The backing store and the associated data structures are the + core of APT. All modules essentially revolve around the + backing store, feeding it data, adding and manipulating links + and relationships between data in the backing store, allowing + the user to interact with and modify the data in the backing + store, and finally writing it out as the status file and + possibly issuing directives to dpkg.

+ +

The other focal point for APT is the user interface.

+
+ + diff --git a/apt/doc/dpkg-tech.sgml b/apt/doc/dpkg-tech.sgml new file mode 100644 index 0000000..0e01385 --- /dev/null +++ b/apt/doc/dpkg-tech.sgml @@ -0,0 +1,509 @@ + + +dpkg technical manual + +Tom Lees tom@lpsg.demon.co.uk +$Id: dpkg-tech.sgml,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + +This document describes the minimum necessary workings for the APT dselect +replacement. It gives an overall specification of what its external interface +must look like for compatibility, and also gives details of some internal +quirks. + + + +Copyright © Tom Lees, 1997. +

+APT and this document are free software; you can redistribute them and/or +modify them under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Quick summary of dpkg's external interface +Control files + +

+The basic dpkg package control file supports the following major features:- + + +5 types of dependencies:- + + Pre-Depends, which must be satisfied before a package may be + unpacked + Depends, which must be satisfied before a package may be + configured + Recommends, to specify a package which if not installed may + severely limit the usefulness of the package + Suggests, to specify a package which may increase the + productivity of the package + Conflicts, to specify a package which must NOT be installed + in order for the package to be configured + +Each of these dependencies can specify a version and a depedency on that +version, for example "<= 0.5-1", "== 2.7.2-1", etc. The comparators available +are:- + + "<<" - less than + "<=" - less than or equal to + ">>" - greater than + ">=" - greater than or equal to + "==" - equal to + +The concept of "virtual packages", which many other packages may provide, +using the Provides mechanism. An example of this is the "httpd" virtual package, +which all web servers should provide. Virtual package names may be used in +dependency headers. However, current policy is that virtual packages do not +support version numbers, so dependencies on virtual packages with versions +will always fail. +Several other control fields, such as Package, Version, Description, +Section, Priority, etc., which are mainly for classification purposes. The +package name must consist entirely of lowercase characters, plus the characters +'+', '-', and '.'. Fields can extend across multiple lines - on the second +and subsequent lines, there is a space at the beginning instead of a field +name and a ':'. Empty lines must consist of the text " .", which will be +ignored, as will the initial space for other continuation lines. This feature +is usually only used in the Description field. + + +The dpkg status area + +

+The "dpkg status area" is the term used to refer to the directory where dpkg +keeps its various status files (GNU would have you call it the dpkg shared +state directory). This is always, on Debian systems, /var/lib/dpkg. However, +the default directory name should not be hard-coded, but #define'd, so that +alteration is possible (it is available via configure in dpkg 1.4.0.9 and +above). Of course, in a library, code should be allowed to override the +default directory, but the default should be part of the library (so that +the user may change the dpkg admin dir simply by replacing the library). + +

+Dpkg keeps a variety of files in its status area. These are discussed later +on in this document, but a quick summary of the files is here:- + + +available - this file contains a concatenation of control information +from all the packages which dpkg knows about. This is updated using the dpkg +commands "--update-avail <file>", "--merge-avail <file>", and +"--clear-avail". +status - this file contains information on the following things for +every package:- + + Whether it is installed, not installed, unpacked, removed, + failed configuration, or half-installed (deconfigured in + favour of another package). + Whether it is selected as install, hold, remove, or purge. + If it is "ok" (no installation problems), or "not-ok". + It usually also contains the section and priority (so that + dselect may classify packages not in available) + For packages which did not initially appear in the "available" + file when they were installed, the other control information + for them. + +

+ The exact format for the "Status:" field is: + + Status: Want Flag Status + + Where Want may be one of unknown, install, + hold, deinstall, purge. Flag + may be one of ok, reinstreq, hold, + hold-reinstreq. + Status may be one of not-installed, unpacked, + half-configured, installed, half-installed + config-files, post-inst-failed, removal-failed. + The states are as follows:- + + not-installed + No files are installed from the package, it has no config files + left, it uninstalled cleanly if it ever was installed. + unpacked + The basic files have been unpacked (and are listed in + /var/lib/dpkg/info/[package].list. There are config files present, + but the postinst script has _NOT_ been run. + half-configured + The package was installed and unpacked, but the postinst script + failed in some way. + installed + All files for the package are installed, and the configuration + was also successful. + half-installed + An attempt was made to remove the packagem but there was a failure + in the prerm script. + config-files + The package was "removed", not "purged". The config files are left, + but nothing else. + post-inst-failed + Old name for half-configured. Do not use. + removal-failed + Old name for half-installed. Do not use. + + The two last items are only left in dpkg for compatibility - they are + understood by it, but never written out in this form. + +

+ Please see the dpkg source code, lib/parshelp.c, + statusinfos, eflaginfos and wantinfos for more + details. + +info - this directory contains files from the control archive of every +package currently installed. They are installed with a prefix of "<packagename>.". +In addition to this, it also contains a file called <package>.list for every +package, which contains a list of files. Note also that the control file is +not copied into here; it is instead found as part of status or available. +methods - this directory is reserved for "method"-specific files - each +"method" has a subdirectory underneath this directory (or at least, it can +have). In addition, there is another subdirectory "mnt", where misc. +filesystems (floppies, CDROMs, etc.) are mounted. +alternatives - directory used by the "update-alternatives" program. It +contains one file for each "alternatives" interface, which contains information +about all the needed symlinked files for each alternative. +diversions - file used by the "dpkg-divert" program. Each diversion takes +three lines. The first is the package name (or ":" for user diversion), the +second the original filename, and the third the diverted filename. +updates - directory used internally by dpkg. This is discussed later, +in the section . +parts - temporary directory used by dpkg-split + + +The dpkg library files + +

+These files are installed under /usr/lib/dpkg (usually), but +/usr/local/lib/dpkg is also a possibility (as Debian policy dictates). Under +this directory, there is a "methods" subdirectory. The methods subdirectory +in turn contains any number of subdirectories for each general method +processor (note that one set of method scripts can, and is, used for more than +one of the methods listed under dselect). + +

+The following files may be found in each of these subdirectories:- + + +names - One line per method, two-digit priority to appear on menu +at beginning, followed by a space, the name, and then another space and the +short description. +desc.<name> - Contains the long description displayed by dselect +when the cursor is put over the <name> method. +setup - Script or program which sets up the initial values to be used +by this method. Called with first argument as the status area directory +(/var/lib/dpkg), second argument as the name of the method (as in the directory +name), and the third argument as the option (as in the names file). +install - Script/program called when the "install" option of dselect is +run with this method. Same arguments as for setup. +update - Script/program called when the "update" option of dselect is +run. Same arguments as for setup/install. + + +The "dpkg" command-line utility + +"Documented" command-line interfaces + +

+As yet unwritten. You can refer to the other manuals for now. See +. + +Environment variables which dpkg responds to + +

+ +DPKG_NO_TSTP - if set to a non-null value, this variable causes dpkg to +run a child shell process instead of sending itself a SIGTSTP, when the user +selects to background the dpkg process when it asks about conffiles. +SHELL - used to determine which shell to run in the case when +DPKG_NO_TSTP is set. +CC - used as the C compiler to call to determine the target architecture. +The default is "gcc". +PATH - dpkg checks that it can find at least the following files in the +path when it wants to run package installation scripts, and gives an error if +it cannot find all of them:- + + ldconfig + start-stop-daemon + install-info + update-rc.d + + + +Assertions + +

+The dpkg utility itself is required for quite a number of packages, even if +they have been installed with a tool totally separate from dpkg. The reason for +this is that some packages, in their pre-installation scripts, check that your +version of dpkg supports certain features. This was broken from the start, and +it should have actually been a control file header "Dpkg-requires", or similar. +What happens is that the configuration scripts will abort or continue according +to the exit code of a call to dpkg, which will stop them from being wrongly +configured. + +

+These special command-line options, which simply return as true or false are +all prefixed with "--assert-". Here is a list of them (without the prefix):- + + +support-predepends - Returns success or failure according to whether +a version of dpkg which supports predepends properly (1.1.0 or above) is +installed, according to the database. +working-epoch - Return success or failure according to whether a version +of dpkg which supports epochs in version properly (1.4.0.7 or above) is +installed, according to the database. + + +

+Both these options check the status database to see what version of the "dpkg" +package is installed, and check it against a known working version. + +--predep-package + +

+This strange option is described as follows in the source code: + + +/* Print a single package which: + * (a) is the target of one or more relevant predependencies. + * (b) has itself no unsatisfied pre-dependencies. + * If such a package is present output is the Packages file entry, + * which can be massaged as appropriate. + * Exit status: + * 0 = a package printed, OK + * 1 = no suitable package available + * 2 = error + */ + + +

+On further inspection of the source code, it appears that what is does is +this:- + + +Looks at the packages in the database which are selected as "install", +and are installed. +It then looks at the Pre-Depends information for each of these packages +from the available file. When it find a package for which any of the +pre-dependencies are not satisfied, it breaks from the loop through the packages. +It then looks through the unsatisfied pre-dependencies, and looks for +packages which would satisfy this pre-dependency, stopping on the first it +finds. If it finds none, it bombs out with an error. +It then continues this for every dependency of the initial package. + + +Eventually, it writes out the record of all the packages to satisfy the +pre-dependencies. This is used by the disk method to make sure that its +dependency ordering is correct. What happens is that all pre-depending +packages are first installed, then it runs dpkg -iGROEB on the directory, +which installs in the order package files are found. Since pre-dependencies +mean that a package may not even be unpacked unless they are satisfied, it is +necessary to do this (usually, since all the package files are unpacked in one +phase, the configured in another, this is not needed). + +dpkg-deb and .deb file internals + +

+This chapter describes the internals to the "dpkg-deb" tool, which is used +by "dpkg" as a back-end. dpkg-deb has its own tar extraction functions, which +is the source of many problems, as it does not support long filenames, using +extension blocks. + +The .deb archive format + +

+The main principal of the new-format Debian archive (I won't describe the old +format - for that have a look at deb-old.5), is that the archive really is +an archive - as used by "ar" and friends. However, dpkg-deb uses this format +internally, rather than calling "ar". Inside this archive, there are usually +the folowing members:- + + +debian-binary +control.tar.gz +data.tar.gz + + +

+The debian-binary member consists simply of the string "2.0", indicating the +format version. control.tar.gz contains the control files (and scripts), and +the data.tar.gz contains the actual files to populate the filesystem with. +Both tarfiles extract straight into the current directory. Information on the +tar formats can be found in the GNU tar info page. Since dpkg-deb calls +"tar -cf" to build packages, the Debian packages use the GNU extensions. + +The dpkg-deb command-line + +

+dpkg-deb documents itself thoroughly with its '--help' command-line option. +However, I am including a reference to these for completeness. dpkg-deb +supports the following options:- + + +--build (-b) <dir> - builds a .deb archive, takes a directory which +contains all the files as an argument. Note that the directory +<dir>/DEBIAN will be packed separately into the control archive. +--contents (-c) <debfile> - Lists the contents of ther "data.tar.gz" +member. +--control (-e) <debfile> - Extracts the control archive into a +directory called DEBIAN. Alternatively, with another argument, it will extract +it into a different directory. +--info (-I) <debfile> - Prints the contents of the "control" file +in the control archive to stdout. Alternatively, giving it other arguments will +cause it to print the contents of those files instead. +--field (-f) <debfile> <field> ... - Prints any number of +fields from the "control" file. Giving it extra arguments limits the fields it +prints to only those specified. With no command-line arguments other than a +filename, it is equivalent to -I and just the .deb filename. +--extract (-x) <debfile> <dir> - Extracts the data archive +of a debian package under the directory <dir>. +--vextract (-X) <debfile> <dir> - Same as --extract, except +it is equivalent of giving tar the '-v' option - it prints the filenames as +it extracts them. +--fsys-tarfile <debfile> - This option outputs a gunzip'd version +of data.tar.gz to stdout. +--new - sets the archive format to be used to the new Debian format +--old - sets the archive format to be used to the old Debian format +--debug - Tells dpkg-deb to produce debugging output +--nocheck - Tells dpkg-deb not to check the sanity of the control file +--help (-h) - Gives a help message +--version - Shows the version number +--licence/--license (UK/US spellings) - Shows a brief outline of the GPL + + +Internal checks used by dpkg-deb when building packages + +

+Here is a list of the internal checks used by dpkg-deb when building packages. +It is in the order they are done. + + +First, the output Debian archive argument, if it is given, is checked +using stat. If it is a directory, an internal flag is set. This check is only +made if the archive name is specified explicitly on the command-line. If the +argument was not given, the default is the directory name, with ".deb" +appended. +Next, the control file is checked, unless the --nocheck flag was +specified on the command-line. dpkg-deb will bomb out if the second argument +to --build was a directory, and --nocheck was specified. Note that dpkg-deb +will not be able to determine the name of the package in this case. In the +control file, the following things are checked:- + + The package name is checked to see if it contains any invalid + characters (see for this). + The priority field is checked to see if it uses standard values, + and user-defined values are warned against. However, note that this + check is now redundant, since the control file no longer contains + the priority - the changes file now does this. + The control file fields are then checked against the standard + list of fields which appear in control files, and any "user-defined" + fields are reported as warnings. + dpkg-deb then checks that the control file contains a valid + version number. + +After this, in the case where a directory was specified to build the +.deb file in, the filename is created as "directory/pkg_ver.deb" or +"directory/pkg_ver_arch.deb", depending on whether the control file contains +an architecture field. +Next, dpkg-deb checks for the <dir>/DEBIAN directory. It complains +if it doesn't exist, or if it has permissions < 0755, or > 0775. +It then checks that all the files in this subdir are either symlinks +or plain files, and have permissions between 0555 and 0775. +The conffiles file is then checked to see if the filenames are too +long. Warnings are produced for each that is. After this, it checks that +the package provides initial copies of each of these conffiles, and that +they are all plain files. + + +dpkg internals + +

+This chapter describes the internals of dpkg itself. Although the low-level +formats are quite simple, what dpkg does in certain cases often does not +make sense. + +Updates + +

+This describes the /var/lib/dpkg/updates directory. The function of this +directory is somewhat strange, and seems only to be used internally. A function +called cleanupdates is called whenever the database is scanned. This function +in turn uses , to sort the files in this +directory. Files who names do not consist entirely of digits are discarded. +dpkg also causes a fatal error if any of the filenames are different lengths. + +

+After having scanned the directory, dpkg in turn parses each file the same way +it parses the status file (they are sorted by the scandir to be in numerical +order). After having done this, it then writes the status information back +to the "status" file, and removes all the "updates" files. + +

+These files are created internally by dpkg's "checkpoint" function, and are +cleaned up when dpkg exits cleanly. + +

+Juding by the use of the updates directory I would call it a Journal. Inorder +to effeciently ensure the complete integrity of the status file dpkg will +"checkpoint" or journal all of it's activities in the updates directory. By +merging the contents of the updates directory (in order!!) against the +original status file it can get the precise current state of the system, +even in the event of a system failure while dpkg is running. + +

+The other option would be to sync-rewrite the status file after each +operation, which would kill performance. + +

+It is very important that any program that uses the status file abort if +the updates directory is not empty! The user should be informed to run dpkg +manually (what options though??) to correct the situation. + +What happens when dpkg reads the database + +

+First, the status file is read. This gives dpkg an initial idea of the packages +that are there. Next, the updates files are read in, overriding the status +file, and if necessary, the status file is re-written, and updates files are +removed. Finally, the available file is read. The available file is read +with flags which preclude dpkg from updating any status information from it, +though - installed version, etc., and is also told to record that the packages +it reads this time are available, not installed. + +

+More information on updates is given above. + +How dpkg compares version numbers + +

+Version numbers consist of three parts: the epoch, the upstream version, and +the Debian revision. Dpkg compares these parts in that order. If the epochs +are different, it returns immediately, and so on. + +

+However, the important part is how it compares the versions which are +essentially stored as just strings. These are compared in two distinct parts: +those consisting of numerical characters (which are evaluated, and then +compared), and those consisting of other characters. When comparing +non-numerical parts, they are compared as the character values (ASCII), but +non-alphabetical characters are considered "greater than" alphabetical ones. +Also note that longer strings (after excluding differences where numerical +values are equal) are considered "greater than" shorter ones. + +

+Here are a few examples of how these rules apply:- + + +15 > 10 +0010 == 10 + +d.r > dsr +32.d.r == 0032.d.r +d.rnr < d.rnrn + + + diff --git a/apt/doc/examples/CVS/Entries b/apt/doc/examples/CVS/Entries new file mode 100644 index 0000000..daf2a8a --- /dev/null +++ b/apt/doc/examples/CVS/Entries @@ -0,0 +1,5 @@ +/apt.conf/1.1.1.1/Fri Aug 10 14:01:41 2001// +/configure-index/1.2/Fri Aug 10 14:01:42 2001// +/sources.list/1.1.1.1/Fri Aug 10 14:01:42 2001// +/vendors.list/1.2/Fri Aug 10 14:01:42 2001// +D diff --git a/apt/doc/examples/CVS/Repository b/apt/doc/examples/CVS/Repository new file mode 100644 index 0000000..504eb02 --- /dev/null +++ b/apt/doc/examples/CVS/Repository @@ -0,0 +1 @@ +rapt/doc/examples diff --git a/apt/doc/examples/CVS/Root b/apt/doc/examples/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/doc/examples/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/doc/examples/apt.conf b/apt/doc/examples/apt.conf new file mode 100644 index 0000000..edda433 --- /dev/null +++ b/apt/doc/examples/apt.conf @@ -0,0 +1,32 @@ +// $Id: apt.conf,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* This file is a sample configuration file with a few harmless sample + options. +*/ + +APT +{ + // Options for apt-get + Get + { + Download-Only "false"; + }; + +}; + +// Options for the downloading routines +Acquire +{ + Retries "0"; +}; + +// Things that effect the APT dselect method +DSelect +{ + Clean "auto"; // always|auto|prompt|never +}; + +DPkg +{ + // Probably don't want to use force-downgrade.. + Options {"--force-overwrite";} +} diff --git a/apt/doc/examples/configure-index b/apt/doc/examples/configure-index new file mode 100644 index 0000000..d6b0b41 --- /dev/null +++ b/apt/doc/examples/configure-index @@ -0,0 +1,223 @@ +// $Id: configure-index,v 1.2 2001/01/04 21:26:14 kojima Exp $ +/* This file is an index of all APT configuration directives. It should + NOT actually be used as a real config file, though it is a completely + valid file. Most of the options have sane default values, unless + you have specific needs you should NOT include arbitary items in a custom + configuration. + + In some instances involving filenames it is possible to set the default + directory when the path is evaluated. This means you can use relative + paths within the sub scope. + + The configuration directives are specified in a tree with {} designating + a subscope relative to the tag before the {}. You can further specify + a subscope using scope notation eg, + APT::Architecture "i386"; + This is prefixed with the current scope. Scope notation must be used + if an option is specified on the command line with -o. +*/ + +// Options for APT in general +APT +{ + Architecture "i386"; + + // Options for apt-get + Get + { + Download-Only "false"; + Simulate "false"; + Assume-Yes "false"; + Force-Yes "false"; // I would never set this. + Fix-Broken "false"; + Fix-Missing "false"; + Show-Upgraded "false"; + No-Upgrade "false"; + Print-URIs "false"; + Compile "false"; + No-Download "false"; + Purge "false"; + List-Cleanup "true"; + ReInstall "false"; + Trivial-Only "false"; + No-Remove "false"; + }; + + Cache + { + Important "false"; + AllVersions "false"; + GivenOnly "false"; + }; + + CDROM + { + Rename "false"; + NoMount "false"; + Fast "false"; + NoAct "false"; + }; + + // Some general options + Ignore-Hold "false"; + Clean-Installed "true"; + Immediate-Configure "true"; // DO NOT turn this off, see the man page + Force-LoopBreak "false"; // DO NOT turn this on, see the man page + Cache-Limit "4194304"; +}; + +// Options for the downloading routines +Acquire +{ + Queue-Mode "host"; // host|access + Retries "0"; + Source-Symlinks "true"; + + // HTTP method configuration + http + { + Proxy "http://127.0.0.1:3128"; + Proxy::http.us.debian.org "DIRECT"; // Specific per-host setting + Timeout "120"; + Pipeline-Depth "5"; + + // Cache Control. Note these do not work with Squid 2.0.2 + No-Cache "false"; + Max-Age "86400"; // 1 Day age on index files + No-Store "false"; // Prevent the cache from storing archives + }; + + ftp + { + Proxy "ftp://127.0.0.1/"; + Proxy::http.us.debian.org "DIRECT"; // Specific per-host setting + + /* Required script to perform proxy login. This example demonstrates + possible options */ + ProxyLogin + { + "USER $(PROXY_USER)"; + "PASS $(PROXY_PASS)"; + "USER $(SITE_USER)@$(SITE):$(SITE_PORT)"; + "PASS $(SITE_PASS)"; + }; + + /* A script that works with tisfw below. Please note that you + must also set 'Proxy::Passive "false"' and a Proxy line like: + Proxy "ftp://anomymous:ftp.us.debian.org@tisproxy.yourcompany.com/"; */ + ProxyLogin + { + "USER $(SITE_USER)@$(SITE)"; + "PASS $(SITE_PASS)"; + }; + + Timeout "120"; + + /* Passive mode control, proxy, non-proxy and per-host. Pasv mode + is prefered if possible */ + Passive "true"; + Proxy::Passive "true"; + Passive::http.us.debian.org "true"; // Specific per-host setting + }; + + cdrom + { + Mount "/cdrom"; + + // You need the trailing slash! + "/cdrom/" + { + Mount "sleep 1000"; + UMount "sleep 500"; + } + }; +}; + +// Directory layout +Dir +{ + // Location of the state dir + State "/var/state/apt/" + { + lists "lists/"; + xstatus "xstatus"; + userstatus "status.user"; + status "/var/lib/dpkg/status"; + cdroms "cdroms.list"; + }; + + // Location of the cache dir + Cache "/var/cache/apt/" { + archives "archives/"; + srcpkgcache "srcpkgcache.bin"; + pkgcache "pkgcache.bin"; + }; + + // Config files + Etc "/etc/apt/" { + sourcelist "sources.list"; + main "apt.conf"; + }; + + // Locations of binaries + Bin { + methods "/usr/lib/apt/methods/"; + gzip "/bin/gzip"; + dpkg "/usr/bin/dpkg"; + dpkg-source "/usr/bin/dpkg-source"; + dpkg-buildpackage "/usr/bin/dpkg-buildpackage" + apt-get "/usr/bin/apt-get"; + apt-cache "/usr/bin/apt-cache"; + }; +}; + +// Things that effect the APT dselect method +DSelect +{ + Clean "auto"; // always|auto|prompt|never + Options "-f"; + UpdateOptions ""; + PromptAfterUpdate "no"; +} + +DPkg +{ + // Probably don't want to use force-downgrade.. + Options {"--force-overwrite";"--force-downgrade";} + + // Auto re-mounting of a readonly /usr + Pre-Invoke {"mount -o remount,rw /usr";}; + Post-Invoke {"mount -o remount,ro /usr";}; + + // Prevents daemons from getting cwd as something mountable (default) + Run-Directory "/"; + + // Build options for apt-get source --compile + Build-Options "-b -uc"; + + // Pre-configure all packages before they are installed using debconf. + Pre-Install-Pkgs {"dpkg-preconfig --apt --priority=low --frontend=dialog";}; + + // Flush the contents of stdin before forking dpkg. + FlushSTDIN "true"; +} + +/* Options you can set to see some debugging text They corrispond to names + of classes in the source code */ +Debug +{ + pkgProblemResolver "false"; + pkgAcquire "false"; + pkgAcquire::Worker "false"; + pkgDPkgPM "false"; + + pkgInitialize "false"; // This one will dump the configuration space + NoLocking "false"; + Acquire::Ftp "false"; // Show ftp command traffic + Acquire::Http "false"; // Show http command traffic + aptcdrom "false"; // Show found package files +} + +/* Whatever you do, do not use this configuration file!! Take out ONLY + the portions you need! */ +This Is Not A Valid Config File diff --git a/apt/doc/examples/sources.list b/apt/doc/examples/sources.list new file mode 100644 index 0000000..ed5ad75 --- /dev/null +++ b/apt/doc/examples/sources.list @@ -0,0 +1,10 @@ +# See sources.list(5) for more information, especialy +# Remember that you can only use http, ftp or file URIs +# CDROMs are managed through the apt-cdrom tool. +deb http://http.us.debian.org/debian stable main contrib non-free +deb http://non-us.debian.org/debian-non-US stable/non-US main contrib non-free +deb http://security.debian.org stable/updates main contrib non-free + +# Uncomment if you want the apt-get source function to work +#deb-src http://http.us.debian.org/debian stable main contrib non-free +#deb-src http://non-us.debian.org/debian-non-US stable non-US diff --git a/apt/doc/examples/vendors.list b/apt/doc/examples/vendors.list new file mode 100644 index 0000000..05ca729 --- /dev/null +++ b/apt/doc/examples/vendors.list @@ -0,0 +1,12 @@ +# Trusted Package Provider List +# +# This file contains the list of package providers (vendors or individuals) +# from whom packages you trust. +# + +simple-key "akk" +{ + Fingerprint "B24534AA5D10F86B46EAB46B3EB3759E05BBD9E4"; + Name "Alfredo K. Kojima "; +} + diff --git a/apt/doc/files.sgml b/apt/doc/files.sgml new file mode 100644 index 0000000..d1618bc --- /dev/null +++ b/apt/doc/files.sgml @@ -0,0 +1,442 @@ + + + +APT Files + +Jason Gunthorpe jgg@debian.org +$Id: files.sgml,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + +This document describes the complete implementation and format of the +installed APT directory structure. It also serves as guide to how APT +views the Debian archive. + + + +Copyright © Jason Gunthorpe, 1998-1999. +

+"APT" and this document are free software; you can redistribute them and/or +modify them under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Introduction + + +General + +

+This document serves two purposes. The first is to document the installed +directory structure and the format and purpose of each file. The second +purpose is to document how APT views the Debian archive and deals with +multiple package files. + +

+The var directory structure is as follows: + + /var/state/apt/ + lists/ + partial/ + xstatus + userstatus + cdroms.list + /var/cache/apt/ + pkgcache.bin + srcpkgcache.bin + archives/ + partial/ + /etc/apt/ + sources.list + apt.conf + /usr/lib/apt/ + methods/ + cdrom + ftp + http + file + gzip + copy + + +

+As is specified in the FHS 2.0 /var/state/apt is used for application +data that is not expected to be user modified. /var/cache/apt is used +for regeneratable data and is where the package cache and downloaded .debs +go. + + + +Files + + +Distribution Source list (sources.list) + +

+The distribution source list is used to locate archives of the debian +distribution. It is designed to support any number of active sources and to +support a mix of source media. The file lists one source per line, with the +fastest source listed first. The format of each line is: + +

+type uri args + +

+The first item, type, indicates the format for the remainder +of the line. It is designed to indicate the structure of the distribution +the line is talking about. Currently the only defined value is deb +which indicates a standard debian archive with a dists dir. + +The deb Type +

+ The deb type is to be a typical two level debian distributions, + dist/distribution/component. Typically distribution + is one of stable, unstable or frozen while component is one of main, + contrib, non-free or non-us. The format for the deb line is as follows: + +

+ deb uri distribution compontent + [component ...] + +

+ uri for the deb type must specify the base of the + debian distribution. APT will automatically generate the proper longer + URIs to get the information it needs. distribution can specify + an exact path, in this case the components must be omitted and + distribution must end in a slash. + +

+ Since only one distribution can be specified per deb line it may be + necessary to list a number of deb lines for the same URI. APT will + sort the URI list after it has generated a complete set to allow + connection reuse. It is important to order things in the sourcelist + from most prefered to least prefered (fastest to slowest). + + +URI specification +

+URIs in the source list support a large number of access schemes. + + +cdrom + The cdrom scheme is special in that If Modifed Since queries are never + performed and that APT knows how to match a cdrom to the name it + was given when first inserted. APT also knows all of the possible + mount points the cdrom drives and that the user should be prompted + to insert a CD if it cannot be found. The path is relative to an + arbitary mount point (of APT's choosing) and must not start with a + slash. The first pathname component is the given name and is purely + descriptive and of the users choice. However, if a file in the root of + the cdrom is called '.disk/info' its contents will be used instead of + prompting. The name serves as a tag for the cdrom and should be unique. + + cdrom:Debian 1.3/debian + + +http + This scheme specifies a HTTP server for the debian archive. HTTP is prefered + over FTP because If Modified Since queries against the Package file are + possible as well as deep pipelining and resume capabilities. + + http://www.debian.org/archive + + +ftp + This scheme specifies a FTP connection to the server. FTP is limited because + there is no support for IMS and is hard to proxy over firewalls. + + ftp://ftp.debian.org/debian + + +file + The file scheme allows an arbitary directory in the file system to be + considered as a debian archive. This is usefull for NFS mounts and + local mirrors/archives. + + file:/var/debian + + +smb + A possible future expansion may be to have direct support for smb (Samba + servers). + + smb://ftp.kernel.org/pub/mirrors/debian + + + + +Hashing the URI +

+All permanent information aquired from any of the sources is stored in the +lists directory. Thus, there must be a way to relate the filename in the +lists directory to a line in the sourcelist. To simplify things this is +done by quoting the URI and treating _'s as quoteable characters and +converting / to _. The URI spec says this is done by converting a +sensitive character into %xx where xx is the hexadecimal representation +from the ascii character set. Examples: + + +http://www.debian.org/archive/dists/stable/binary-i386/Packages +/var/state/apt/lists/www.debian.org_archive_dists_stable_binary-i386_Packages + +cdrom:Debian 1.3/debian/Packages +/var/state/apt/info/Debian%201.3_debian_Packages + + +

+The other alternative that was considered was to use a deep directory +structure but this poses two problems, it makes it very difficult to prune +directories back when sources are no longer used and complicates the handling +of the partial directory. This gives a very simple way to deal with all +of the situations that can arise. Also note that the same rules described in +the Archive Directory section regarding the partial sub dir apply +here as well. + + + + + + +Extra Status File (xstatus) + +

+The extra status file serves the same purpose as the normal dpkg status file +(/var/lib/dpkg/status) except that it stores information unique to apt. +This includes the autoflag, target distribution and version and any other +uniqe features that come up over time. It duplicates nothing from the normal +dpkg status file. Please see other APT documentation for a discussion +of the exact internal behavior of these fields. The Package field is +placed directly before the new fields to indicate which package they +apply to. The new fields are as follows: + + +X-Auto + The Auto flag can be Yes or No and controls whether the package is in + auto mode. + +X-TargetDist + The TargetDist item indicates which distribution versions are offered for + installation from. It should be stable, unstable or frozen. + +X-TargetVersion + The target version item is set if the user selects a specific version, it + overrides the TargetDist selection if both are present. + + + + + +Binary Package Cache (pkgcache.bin) + +

+Please see cache.sgml for a complete description of what this file is. The +cache file is updated whenever the contents of the lists directory changes. +If the cache is erased, corrupted or of a non-matching version it will +be automatically rebuilt by all of the tools that need it. +srcpkgcache.bin contains a cache of all of the package files in the +source list. This allows regeneration of the cache when the status files +change to use a prebuilt version for greater speed. + + + + +Downloads Directory (archives) + +

+The archives directory is where all downloaded .deb archives go. When the +file transfer is initiated the deb is placed in partial. Once the file +is fully downloaded and its MD5 hash and size are verifitied it is moved +from partial into archives/. Any files found in archives/ can be assumed +to be verified. + +

+No dirctory structure is transfered from the receiving site and all .deb +file names conform to debian conventions. No short (msdos) filename should +be placed in archives. If the need arises .debs should be unpacked, scanned +and renamed to their correct internal names. This is mostly to prevent +file name conflicts but other programs may depend on this if convenient. +A conforming .deb is one of the form, name_version_arch.deb. Our archive +scripts do not handle epochs, but they are necessary and should be re-inserted. +If necessary _'s and :'s in the fields should be quoted using the % convention. +It must be possible to extract all 3 fields by examining the file name. +Downloaded .debs must be found in one of the package lists with an exact +name + version match.. + + + + + The Methods Directory (/usr/lib/apt/methods) + +

+The Methods directory is more fully described in the APT Methods interface +document. + + + + + The Mirror List + +

+The mirror list is stored on the primary debian web server (www.debian.org) +and contains a machine readable list of all known debian mirrors. It's +format and style mirror the Package file. + + +Site +This is the proper host name of the site. It should not be a host within +debian.org and generally cnames should be advoided here. + +Aliases +These list any commonly used aliases for the site. This field is used to make +sure that a site is not added twice. + +Type +This field can either be Push-Primary or leaf. +Push-Primary are authorized top level mirrors of the archive, all +other mirrors are leaf. + +Archive-[access] +The Archive field gives the path(s) to the debian archive. [access] +specifies the access method and may be one of ftp, http, rsync, nfs, or +smb. For many of the types it is possible to prefix the path with :### +indicating that an alternate port should be used. Generaly paths +start with a / and end with a /, rsync is an exception in that the +first directory component is not a path but a label. + +WWW-[access] +The WWW field gives the path(s) to the debian web site. + +CDImage-[access] +The WWW field gives the path(s) to the debian CD-ROM images + +Incoming-[access] +The Incoming field gives the path(s) to a mirror of the debian incoming +directory. + +nonUS-[access] +The nonUS field gives the path(s) to a mirror of the non-US distribution. + +Maintainer +This is the email address of the maintainer of the mirror. + +Location +Location gives the general geographical region the mirror is in. + +Sponsor +The Sponsor field indicates who owns the mirror and a URL to a web page +describing the organization. + +Comment +General free-form text. + + + +

+Some form of network measurement will have to be used to gauge performance +of each of the mirrors. This will be discussed later, initial versions +will use the first found URI. + + + + + The Release File + +

+This file plays and important role in how APT presents the archive to the +user. Its main purpose is to present a descriptive name for the source +of each version of each package. It also is used to detect when new versions +of debian are released. It augments the package file it is associated with +by providing meta information about the entire archive which the Packages +file describes. + +

+The full name of the distribution for presentation to the user is formed +as 'label version archive', with a possible extended name being +'label version archive component'. + +

+The file is formed as the package file (RFC-822) with the following tags +defined: + + +Archive +This is the common name we give our archives, such as stable or +unstable. + +Component +Referes to the sub-component of the archive, main, contrib +etc. Component may be omitted if there are no components for this archive. + +Version +This is a version string with the same properties as in the Packages file. +It represents the release level of the archive. + +Origin +This specifies who is providing this archive. In the case of Debian the +string will read 'Debian'. Other providers may use their own string + +Label +This carries the encompassing name of the distribution. For Debian proper +this field reads 'Debian'. For derived distributions it should contain their +proper name. + +Architecture +When the archive has packages for a single architecture then the Architecture +is listed here. If a mixed set of systems are represented then this should +contain the keyword mixed. + +NotAutomatic +A Yes/No flag indicating that the archive is extremely unstable and its +version's should never be automatically selected. This is to be used by +experimental. + +Description +Description is used to describe the release. For instance experimental would +contain a warning that the packages have problems. + + +

+The location of the Release file in the archive is very important, it must +be located in the same location as the packages file so that it can be +located in all situations. The following is an example for the current stable +release, 1.3.1r6 + + +Archive: stable +Compontent: main +Version: 1.3.1r6 +Origin: Debian +Label: Debian +Architecture: i386 + + +This is an example of experimental, + +Archive: experimental +Version: 0 +Origin: Debian +Label: Debian +Architecture: mixed +NotAutomatic: Yes + + +And unstable, + +Archive: unstable +Compontent: main +Version: 2.1 +Origin: Debian +Label: Debian +Architecture: i386 + + + + + + diff --git a/apt/doc/guide.sgml b/apt/doc/guide.sgml new file mode 100644 index 0000000..da2c111 --- /dev/null +++ b/apt/doc/guide.sgml @@ -0,0 +1,547 @@ + + + +APT User's Guide + +Jason Gunthorpe jgg@debian.org +$Id: guide.sgml,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + +This document provides an overview of how to use the the APT package manager. + + + +Copyright © Jason Gunthorpe, 1998. +

+"APT" and this document are free software; you can redistribute them and/or +modify them under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + + + +General + +

+The APT package currently contains two sections, the APT dselect +method and the apt-get command line user interface. Both provide +a way to install and remove packages as well as download new packages from +the Internet. + +Anatomy of the Package System +

+The Debian packaging system has a large amount of information associated with +each package to help assure that it integrates cleanly and easily into +the system. The most prominent of features is the dependency system. + +

+The dependency system allows individual programs to make use of shared +elements in the system such as libraries. It simplifies placing infrequently +used portions of a program in separate packages to reduce the +number of things the average user is required to install. Also, it allows +a choices in for such things as mail transport agents, X servers and +so on. + +

+The first step to understanding the dependency system is to grasp the concept +of a simple dependency. The meaning of a simple dependency is that a package +requires another package to be installed at the same time to work properly. + +

+For instance, mail-crypt is an emacs extension that aids in encrypting email +with PGP. Without PGP installed mail-crypt is useless, so mail-crypt has a +simple dependency on PGP. Also, because it is an emacs extension it has a +simple dependency on emacs, without emacs it is completely useless. + +

+The other important dependency to understand is a conflicting dependency. It +means that a package, when installed with another package, will not work and +may possibly be extremely harmful to the system. As an example consider a +mail transport agent such as sendmail, exim or qmail. It is not possible +to have two mail transport agents installed because both need to listen to +the network to receive mail. Attempting to install two will seriously +damage the system so all mail transport agents have a conflicting dependency +with all other mail transport agents. + +

+As an added complication there is the possibility for a package to pretend +to be another package. Consider that exim and sendmail for many intents are +identical, they both deliver mail and understand a common interface. Hence, +the package system has a way for them to declare that they are both +mail-transport-agents. So, exim and sendmail both declare that they provide a +mail-transport-agent and other packages that need a mail transport agent +depend on mail-transport-agent. This can add a great deal of confusion when +trying to manually fix packages. + +

+At any given time a single dependency may be met by packages that are already +installed or it may not be. APT attempts to help resolve dependency issues +by providing a number of automatic algorithms that help in selecting packages +for installation. + + + + + + +apt-get + +

+apt-get provides a simple way to install packages from the command +line. Unlike dpkg, apt-get does not understand .deb files, +it works with the packages proper name and can only install .deb archives from +a Source. + +

+The first If you are using an http proxy server you must set the +http_proxy environment variable first, see sources.list(5) thing that +should be done before using apt-get is to fetch the package lists +from the Sources so that it knows what packages are +available. This is done with apt-get update. For instance, + +

+ +# apt-get update +Get http://ftp.de.debian.org/debian-non-US/ stable/binary-i386/ Packages +Get http://llug.sep.bnl.gov/debian/ frozen/contrib Packages +Reading Package Lists... Done +Building Dependency Tree... Done + + +

+Once updated there are several useful commands that can be used, + +upgrade +Upgrade will attempt to gently upgrade the whole system. Upgrade will +never install a new package or remove an existing package, nor will it +ever upgrade a package that might cause some other package to break. +This can be used daily to relatively safely upgrade the system. Upgrade +will list all of the packages that it could not upgrade, this usually +means that they depend on new packages or conflict with some other package. +Dselect or apt-get install can be used to force these +packages to install. + +install +Install is used to install single packages by name. The package is +automatically fetched and installed. This can be useful if you already +know the name of the package to install and do not want to go into a GUI +to select it. Any number of packages may be passed to install, they will +all be fetched. Install automatically attempts to resolve dependency problems +with the listed packages and will print a summary and ask for confirmation +if anything other than it's arguments are changed + +dist-upgrade +Dist-upgrade is a complete upgrader designed to make simple upgrading between +releases of Debian. It uses a sophisticated algorithm to determine the best +set of packages to install, upgrade and remove to get as much of the system +to the newest release. In some situations it may be desired to use dist-upgrade +rather than spend the time manually resolving dependencies in dselect. +Once dist-upgrade has completed then dselect can be used to install +any packages that may have been left out. + +

+It is important to closely look at what dist-upgrade is going to do, its +decisions may sometimes be quite surprising. + + +

+apt-get has several command line options that are detailed in it's +man page, . The most useful option is +-d which does not install the fetched files. If the system has to +download a large number of package it would be undesired to start installing +them in case something goes wrong. When -d is used the downloaded +archives can be installed by simply running the command that caused them to +be downloaded again without -d. + + + + + +DSelect +

+The APT dselect method provides the complete APT system with +the dselect package selection GUI. dselect is used to +select the packages to be installed or removed and APT actually installs them. + +

+To enable the APT method you need to to select [A]ccess in dselect +and then choose the APT method. You will be prompted for a set of +Sources which are places to fetch archives from. These can be remote +Internet sites, local Debian mirrors or CDROMs. Each source can provide +a fragment of the total Debian archive, APT will automatically combine them +to form a complete set of packages. If you have a CDROM then it is a good idea +to specify it first and then specify a mirror so that you have access to +the latest bug fixes. APT will automatically use packages on your CDROM before +downloading from the Internet. + +

+ + Set up a list of distribution source locations + + Please give the base URL of the debian distribution. + The access schemes I know about are: http file + + For example: + file:/mnt/debian, + ftp://ftp.debian.org/debian, + http://ftp.de.debian.org/debian, + + + URL [http://llug.sep.bnl.gov/debian]: + + +

+The Sources setup starts by asking for the base of the Debian +archive, defaulting to a HTTP mirror. Next it asks for the distribution to +get. + +

+ + Please give the distribution tag to get or a path to the + package file ending in a /. The distribution + tags are typically something like: stable unstable frozen non-US + + Distribution [stable]: + + +

+The distribution refers to the Debian version in the archive, stable +refers to the latest released version and unstable refers to the +developmental version. non-US is only available on some mirrors and +refers to packages that contain encryption technology or other things that +cannot be exported from the United States. Importing these packages into the +US is legal however. + +

+ + Please give the components to get + The components are typically something like: main contrib non-free + + Components [main contrib non-free]: + + +

+The components list refers to the list of sub distributions to fetch. The +distribution is split up based on software copyright, main being DFSG free +packages while contrib and non-free contain things that have various +restrictions placed on their use and distribution. + +

+Any number of sources can be added, the setup script will continue to +prompt until you have specified all that you want. + +

+Before starting to use dselect it is necessary to update the +available list by selecting [U]pdate from the menu. This is a super-set of +apt-get update that makes the fetched information available to +dselect. [U]pdate must be performed even if apt-get update +has been run before. + +

+You can then go on and make your selections using [S]elect and then +perform the installation using [I]nstall. When using the APT method +the [C]onfig and [R]emove commands have no meaning, the [I]nstall command +performs both of them together. + +

+By default APT will automatically remove the packages once they have been +sucessfully installed. To change this behavor place Dselect::clean +"prompt"; in /etc/apt/apt.conf. + + + + + +The Interface + +

+Both that APT dselect method and apt-get share the same +interface. It is a simple system that generally tells you what it will do +and then goes and does it. + +The dselect method actually is a set of wrapper scripts +to apt-get. The method actually provides more functionality than +is present in apt-get alone. + +After printing out a summary of what will happen APT then will print out some +informative status messages so that you can estimate how far along it is and +how much is left to do. + + +Startup + +

+Before all operations, except update, APT performs a number of actions to +prepare its internal state. It also does some checks of the systems state. +At any time these operations can be performed by running apt-get chec +

+ +# apt-get check +Reading Package Lists... Done +Building Dependancy Tree... Done + + +

+The first thing it does is read all the package files into memory. APT +uses a caching scheme so this operation will be faster the second time it +is run. If some of the package files are not found then they will be ignored +and a warning will be printed when apt-get exits. + +

+The final operation performs a detailed analysis of the systems dependencies. +It checks every dependency of every installed or unpacked package and considers +if it is ok. Should this find a problem then a report will be printed out and +apt-get will refuse to run. + +

+ +# apt-get check +Reading Package Lists... Done +Building Dependancy Tree... Done +You might want to run apt-get -f install' to correct these. +Sorry, but the following packages have unmet dependencies: + 9fonts: Depends: xlib6g but it is not installed + uucp: Depends: mailx but it is not installed + blast: Depends: xlib6g (>= 3.3-5) but it is not installed + adduser: Depends: perl-base but it is not installed + aumix: Depends: libgpmg1 but it is not installed + debiandoc-sgml: Depends: sgml-base but it is not installed + bash-builtins: Depends: bash (>= 2.01) but 2.0-3 is installed + cthugha: Depends: svgalibg1 but it is not installed + Depends: xlib6g (>= 3.3-5) but it is not installed + libreadlineg2: Conflicts:libreadline2 (<< 2.1-2.1) + + +

+In this example the system has many problems, including a serious problem +with libreadlineg2. For each package that has unmet dependencies a line +is printed out indicating the package with the problem and the dependencies +that are unmet. A short explanation of why the package has a dependency +problem is also included. + +

+There are two ways a system can get into a broken state like this. The +first is caused by dpkg missing some subtle relationships between +packages when performing upgrades. APT however considers all known +dependencies and attempts to prevent broken packages. The second is +if a package installation fails during an operation. In this situation a +package may have been unpacked without its dependents being installed. + +

+The second situation is much less serious than the first because APT places +certain assurances on the order that packages are installed. In both cases +supplying the -f option to atp-get will cause APT to deduce a +possible solution to the problem and then continue on. The APT dselect +method always supplies the -f option to allow for easy continuation +of failed maintainer scripts. + +

+However, if the -f option is used to correct a seriously broken system +caused by the first case then it is possible that it will either fail +immediately or the installation sequence will fail. In either case it is +necessary to manually use dpkg (possibly with forcing options) to correct +the situation enough to allow APT to proceed. + + + +The Status Report + +

+Before proceeding apt-get will present a report on what will happen. +Generally the report reflects the type of operation being performed but there +are several common elements. In all cases the lists reflect the final state +of things, taking into account the -f option and any other relevant +activities to the command being executed. + +The Extra Package list +

+ +The following extra packages will be installed: + libdbd-mysql-perl xlib6 zlib1 xzx libreadline2 libdbd-msql-perl + mailpgp xdpkg fileutils pinepgp zlib1g xlib6g perl-base + bin86 libgdbm1 libgdbmg1 quake-lib gmp2 bcc xbuffy + squake pgp-i python-base debmake ldso perl libreadlineg2 + ssh + + +

+The Extra Package list shows all of the packages that will be installed +or upgraded in excess of the ones mentioned on the command line. It is +only generated for an install command. The listed packages are +often the result of an Auto Install. + + +The Packages to Remove +

+ +The following packages will be REMOVED: + xlib6-dev xpat2 tk40-dev xkeycaps xbattle xonix + xdaliclock tk40 tk41 xforms0.86 ghostview xloadimage xcolorsel + xadmin xboard perl-debug tkined xtetris libreadline2-dev perl-suid + nas xpilot xfig + + +

+The Packages to Remove list shows all of the packages that will be +removed from the system. It can be shown for any of the operations and +should be given a careful inspection to ensure nothing important is to +be taken off. The -f option is especially good at generating packages +to remove so extreme care should be used in that case. The list may contain +packages that are going to be removed because they are only +partially removed, possibly due to an aborted installation. + + +The New Packages list +

+ +The following NEW packages will installed: + zlib1g xlib6g perl-base libgdbmg1 quake-lib gmp2 pgp-i python-base + + +

+The New Packages list is simply a reminder of what will happen. The packages +listed are not presently installed in the system but will be when APT is done. + + +The Kept Back list +

+ +The following packages have been kept back + compface man-db tetex-base msql libpaper svgalib1 + gs snmp arena lynx xpat2 groff xscreensaver + + +

+Whenever the whole system is being upgraded there is the possibility that +new versions of packages cannot be installed because they require new things +or conflict with already installed things. In this case the package will +appear in the Kept Back list. The best way to convince packages listed +there to install is with apt-get install or by using dselect +to resolve their problems. + + +Held Packages warning +

+ +The following held packages will be changed: + cvs + + +

+Sometimes you can ask APT to install a package that is on hold, in such a +case it prints out a warning that the held package is going to be +changed. This should only happen during dist-upgrade or install. + + +Final summary +

+Finally, APT will print out a summary of all the changes that will occur. + +

+ +206 packages upgraded, 8 newly installed, 23 to remove and 51 not upgraded. +12 packages not fully installed or removed. +Need to get 65.7M/66.7M of archives. After unpacking 26.5M will be used. + + +

+The first line of the summary simply is a reduced version of all of the +lists and includes the number of upgrades - that is packages already +installed that have new versions available. The second line indicates the +number of poorly configured packages, possibly the result of an aborted +installation. The final line shows the space requirements that the +installation needs. The first pair of numbers refer to the size of +the archive files. The first number indicates the number of bytes that +must be fetched from remote locations and the second indicates the +total size of all the archives required. The next number indicates the +size difference between the presently installed packages and the newly +installed packages. It is roughly equivalent to the space required in +/usr after everything is done. If a large number of packages are being +removed then the value may indicate the amount of space that will be +freed. + +

+Some other reports can be generated by using the -u option to show packages +to upgrade, they are similar to the previous examples. + + + +The Status Display +

+During the download of archives and package files APT prints out a series of +status messages, + +

+ +# apt-get update +Get:1 http://ftp.de.debian.org/debian-non-US/ stable/non-US/ Packages +Get:2 http://llug.sep.bnl.gov/debian/ frozen/contrib Packages +Hit http://llug.sep.bnl.gov/debian/ frozen/main Packages +Get:4 http://ftp.de.debian.org/debian-non-US/ unstable/binary-i386/ Packages +Get:5 http://llug.sep.bnl.gov/debian/ frozen/non-free Packages +11% [5 frozen/non-free `Waiting for file' 0/32.1k 0%] 2203b/s 1m52s + + +

+The lines starting with Get are printed out when APT begins to fetch +a file while the last line indicates the progress of the download. The first +percent value on the progress line indicates the total percent done of all +files. Unfortunately since the size of the Package files is unknown +apt-get update estimates the percent done which causes some +inaccuracies. + +

+The next section of the status line is repeated once for each dowload thread +and indicates the operation being performed and some usefull information +about what is happening. Sometimes this section will simply read Forking +which means the OS is loading the download module. The first word after the [ +is the fetch number as shown on the history lines. The next word +is the short form name of the object being downloaded. For archives it will +contain the name of the package that is being fetched. + +

+Inside of the single quote is an informative string indicating the progress +of the negotiation phase of the download. Typically it progresses from +Connecting to Waiting for file to Downloading or +Resuming. The final value is the number of bytes downloaded from the +remote site. Once the download beings this is represented as 102/10.2k +indicating that 102 bytes have been fetched and 10.2 kilobytes is expected. +The total size is always shown in 4 figure notation to preserve space. After +the size display is a percent meter for the file itself. +The second last element is the instantenous average speed. This values is +updated every 5 seconds and reflects the rate of data transfer for that +period. Finally is shown the estimated transfer time. This is updated +regularly and reflects the time to complete everything at the shown +transfer rate. + +

+The status display updates every half second to provide a constant feedback +on the download progress while the Get lines scroll back whenever a new +file is started. Since the status display is constantly updated it is +unsuitable for logging to a file, use the -q option to remove the +status display. + + + +Dpkg + +

+APT uses dpkg for installing the archives and will switch +over to the dpkg interface once downloading is completed. +dpkg will also as a number of questions as it processes the packages +and the packages themselves may also ask several questions. Before each +question there is usually a description of what it is asking and the +questions are too varied to discuss completely here. + + + + + + diff --git a/apt/doc/makefile b/apt/doc/makefile new file mode 100644 index 0000000..e4a6994 --- /dev/null +++ b/apt/doc/makefile @@ -0,0 +1,24 @@ +# -*- make -*- +BASE=.. +SUBDIR=doc doc/pt_BR + +# Bring in the default rules +include ../buildlib/defaults.mak + +# SGML Documents +SOURCE = dpkg-tech.sgml design.sgml files.sgml guide.sgml cache.sgml \ + method.sgml offline.sgml +include $(DEBIANDOC_H) + +# Man pages +SOURCE = apt-cache.8 apt-get.8 apt-cdrom.8 apt.conf.5 \ + sources.list.5 vendors.list.5 apt-config.8 \ + pt_BR/apt-cache.8 pt_BR/apt-get.8 pt_BR/apt-cdrom.8 \ + pt_BR/apt.conf.5 pt_BR/sources.list.5 pt_BR/vendors.list.5 \ + pt_BR/apt-config.8 +include $(YODL_MANPAGE_H) + +# Examples +SOURCE = examples/apt.conf examples/sources.list examples/vendors.list examples/configure-index +TO = $(DOC) +include $(COPY_H) diff --git a/apt/doc/method.sgml b/apt/doc/method.sgml new file mode 100644 index 0000000..56b0c71 --- /dev/null +++ b/apt/doc/method.sgml @@ -0,0 +1,354 @@ + + + +APT Method Interface + +Jason Gunthorpe jgg@debian.org +$Id: method.sgml,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + +This document describes the interface that APT uses to the archive +access methods. + + + +Copyright © Jason Gunthorpe, 1998. +

+"APT" and this document are free software; you can redistribute them and/or +modify them under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Introduction + + +General + +

+The APT method interface allows APT to acquire archive files (.deb), index +files (Packages, Release, Mirrors) and source files (.tar.gz, .diff). It +is a general, extensible system designed to satisfy all of these +requirements: + + +Remote methods that download files from a distant site +Resume of aborted downloads +Progress reporting +If-Modified-Since (IMS) checking for index files +In-Line MD5 generation +No-copy in-filesystem methods +Multi-media methods (like CD's) +Dynamic source selection for failure recovery +User interaction for user/password requests and media swaps +Global configuration + + +Initial releases of APT (0.1.x) used a completely different method +interface that only supported the first 6 items. This new interface +deals with the remainder. + + + + +Terms + +

+Several terms are used through out the document, they have specific +meanings which may not be immediately evident. To clarify they are summarized +here. + + +source +Refers to an item in source list. More specifically it is the broken down +item, that is each source maps to exactly one index file. Archive sources +map to Package files and Source Code sources map to Source files. + +archive file +Refers to a binary package archive (.deb, .rpm, etc). + +source file +Refers to one of the files making up the source code of a package. In +debian it is one of .diff.gz, .dsc. or .tar.gz. + +URI +Universal Resource Identifier (URI) is a super-set of the familiar URL +syntax used by web browsers. It consists of an access specification +followed by a specific location in that access space. The form is +<access>:<location>. Network addresses are given with the form +<access>://[<user>[:<pas>]@]hostname[:port]/<location>. +Some examples: + +file:/var/mirrors/debian/ +ftp://ftp.debian.org/debian +ftp://jgg:MooCow@localhost:21/debian +nfs://bigred/var/mirrors/debian +rsync://debian.midco.net/debian +cdrom:Debian 2.0r1 Disk 1/ + + +method +There is a one to one mapping of URI access specifiers to methods. A method +is a program that knows how to handle a URI access type and operates according +to the specifications in this file. + +method instance +A specific running method. There can be more than one instance of each method +as APT is capable of concurrent method handling. + +message +A series of lines terminated by a blank line sent down one of the +communication lines. The first line should have the form xxx TAG +where xxx are digits forming the status code and TAG is an informational +string + +acquire +The act of bring a URI into the local pathname space. This may simply +be verifiying the existence of the URI or actually downloading it from +a remote site. + + + + + +Specification + + +Overview + +

+All methods operate as a sub process of a main controlling parent. 3 FD's +are opened for use by the method allowing two way communication and +emergency error reporting. The FD's corrispond to the well known unix FD's, +stdin, stdout and stderr. + +

+Throught operation of the method communication is done via http +style plain text. Specifically RFC-822 (like the Package file) fields +are used to describe items and a numeric-like header is used to indicate +what is happening. Each of these distinct communication messages should be +sent quickly and without pause. + +

+In some instances APT may pre-invoke a method to allow things like file +URI's to determine how many files are available locally. + + + + +Message Overview + +

+The first line of each message is called the message header. The first +3 digits (called the Status Code) have the usual meaning found in the +http protocol. 1xx is informational, 2xx is successfull and 4xx is failure. +The 6xx series is used to specify things sent to the method. After the +status code is an informational string provided for visual debugging. + + +100 Capabilities - Method capabilities +101 Log - General Logging +102 Status - Inter-URI status reporting (login progress) +200 URI Start - URI is starting acquire +201 URI Done - URI is finished acquire +400 URI Failure - URI has failed to acquire +401 General Failure - Method did not like something sent to it +402 Authorization Required - Method requires authorization + to access the URI. Authorization is User/Pass +403 Media Failure - Method requires a media change +600 URI Acquire - Request a URI be acquired +601 Configuration - Sends the configuration space +602 Authorization Credentials - Response to the 402 message +603 Media Changed - Response to the 403 message + + +Only the 6xx series of status codes is sent TO the method. Furthermore +the method may not emit status codes in the 6xx range. The Codes 402 +and 403 require that the method continue reading all other 6xx codes +until the proper 602/603 code is recieved. This means the method must be +capable of handling an unlimited number of 600 messages. + +

+The flow of messages starts with the method sending out a +100 Capabilities and APT sending out a 601 Configuration. +After that APT begins sending 600 URI Acquire and the method +sends out 200 URI Start, 201 URI Done or +400 URI Failure. No syncronization is performed, it is expected +that APT will send 600 URI Acquire messages at -any- time and +that the method should queue the messages. This allows methods like http +to pipeline requests to the remote server. It should be noted however +that APT will buffer messages so it is not neccessary for the method +to be constantly ready to recieve them. + + + + +Header Fields + +

+The following is a short index of the header fields that are supported + + +URIURI being described by the message +FilenameLocation in the filesystem +Last-ModifiedA time stamp in RFC1123 notation for use by IMS checks +IMS-HitThe already existing item is valid +SizeSize of the file in bytes +Resume-PointLocation that transfer was started +MD5-HashComputed MD5 hash for the file +MessageString indicating some displayable message +MediaString indicating the media name required +SiteString indicating the site authorization is required for +UserUsername for authorization +PasswordPassword for authorization +FailOperation failed +DriveDrive the media should be placed in +Config-Item +A string of the form item=value derived from the APT +configuration space. These may include method specific values and general +values not related to the method. It is up to the method to filter out +the ones it wants. +Single-InstanceRequires that only one instance of the method be run + This is a yes/no value. +PipelineThe method is capable of pipelining. +LocalThe method only returns Filename: feilds. +Send-ConfigSend configuration to the method. +Needs-CleanupThe process is kept around while the files it returned +are being used. This is primarily intended for CDROM and File URIs that need +to unmount filesystems. +VersionVersion string for the method + + +This is a list of which headers each status code can use + + +100 Capabilities +Displays the capabilities of the method. Methods should set the +pipeline bit if their underlying protocol supports pipeling. The +only known method that does support pipelining is http. +Fields: Version, Single-Instance, Pre-Scan, Pipeline, Send-Config, +Needs-Cleanup + +101 Log +A log message may be printed to the screen if debugging is enabled. This +is only for debugging the method. +Fields: Message + +102 Status +Message gives a progress indication for the method. It can be used to show +pre-transfer status for internet type methods. +Fields: Message + +200 URI Start +Indicates the URI is starting to be transfered. The URI is specified +along with stats about the file itself. +Fields: URI, Size, Last-Modified, Resume-Point + +201 URI Done +Indicates that a URI has completed being transfered. It is possible +to specify a 201 URI Done without a URI Start which would +mean no data was transfered but the file is now available. A Filename +field is specified when the URI is directly available in the local +pathname space. APT will either directly use that file or copy it into +another location. It is possible to return Alt-* feilds to indicate that +another possibility for the URI has been found in the local pathname space. +This is done if a decompressed version of a .gz file is found. +Fields: URI, Size, Last-Modified, Filename, MD5-Hash + +400 URI Failure +Indicates a fatal URI failure. The URI is not retrievable from this source. +As with 201 URI Done 200 URI Start is not required to preceed +this message +Fields: URI, Message + +401 General Failure +Indicates that some unspecific failure has occured and the method is unable +to continue. The method should terminate after sending this message. It +is intended to check for invalid configuration options or other severe +conditions. +Fields: Message + +402 Authorization Required +The method requires a Username and Password pair to continue. After sending +this message the method will expect APT to send a 602 Authorization +Credentials message with the required information. It is possible for +a method to send this multiple times. +Fields: Site + +403 Media Failure +A method that deals with multiple media requires that a new media be inserted. +The Media field contains the name of the media to be inserted. +Fields: Media, Drive + +600 URI Acquire +APT is requesting that a new URI be added to the acquire list. Last-Modified +has the time stamp of the currently cache file if applicable. Filename +is the name of the file that the acquired URI should be written to. +Fields: URI, Filename Last-Modified + +601 Configuration +APT is sending the configuration space to the method. A series of +Config-Item fields will be part of this message, each containing an entry +from the configuration space. +Fields: Config-Item. + +602 Authorization Credentials +This is sent in response to a 402 Authorization Required message. +It contains the entered username and password. +Fields: Site, User, Password + +603 Media Changed +This is sent in response to a 403 Media Failure message. It +indicates that the user has changed media and it is safe to proceed. +Fields: Media, Fail + + + + + + +Notes + +

+The methods supplied by the stock apt are: + +cdrom - For Multi-Disc CDROMs +copy - (internal) For copying files around the filesystem +file - For local files +gzip - (internal) For decompression +http - For HTTP servers + + +

+The two internal methods, copy and gzip, are used by the acquire code to +parallize and simplify the automatic decompression of package files as well +as copying package files around the file system. Both methods can be seen to +act the same except that one decompresses on the fly. APT uses them by +generating a copy URI that is formed identically to a file URI. The destination +file is send as normal. The method then takes the file specified by the +URI and writes it to the destination file. A typical set of operations may +be: + +http://foo.com/Packages.gz -> /bar/Packages.gz +gzip:/bar/Packages.gz -> /bar/Packages.decomp +rename Packages.decomp to /final/Packages + + +

+The http method implements a fully featured HTTP/1.1 client that supports +deep pipelining and reget. It works best when coupled with an apache 1.3 +server. The file method simply generates failures or success responses with +the filename field set to the proper location. The cdrom method acts the same +except that it checks that the mount point has a valid cdrom in it. It does +this by (effectively) computing a md5 hash of 'ls -l' on the mountpoint. + + + + + diff --git a/apt/doc/offline.sgml b/apt/doc/offline.sgml new file mode 100644 index 0000000..17be474 --- /dev/null +++ b/apt/doc/offline.sgml @@ -0,0 +1,221 @@ + + + +Using APT Offline + +Jason Gunthorpe jgg@debian.org +$Id: offline.sgml,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ + + +This document describes how to use APT in a non-networked environment, +specifically a 'sneaker-net' approach for performing upgrades. + + + +Copyright © Jason Gunthorpe, 1999. +

+"APT" and this document are free software; you can redistribute them and/or +modify them under the terms of the GNU General Public License as published +by the Free Software Foundation; either version 2 of the License, or (at your +option) any later version. + +

+For more details, on Debian GNU/Linux systems, see the file +/usr/doc/copyright/GPL for the full license. + + + + +Introduction + + +Overview + +

+Normally APT requires direct access to a Debian archive, either from a local +media or through a network. Another common complaint is that a Debian machine +is on a slow link, such as a modem and another machine has a very fast +connection but they are physically distant. + +

+The solution to this is to use large removable media such as a Zip disc or a +SuperDisk disc. These discs are not large enough to store the entire Debian +archive but can easily fit a subset large enough for most users. The idea +is to use APT to generate a list of packages that are required and then fetch +them onto the disc using another machine with good connectivity. It is +even Possible to use another Debian machine with APT or to use a completely +different OS and a download tool like wget. + +

+This is achieved by creatively manipulating the APT configuration file. The +essential premis to tell APT to look on a disc for it's archive files. Note +that the disc should be formated with a filesystem that can handle long file +names such as ext2, fat32 or vfat. + + + + +Using APT on both machines + + +Overview + +

+APT being available on both machines gives the simplest configuration. The +basic idea is to place a copy of the status file on the disc and use the +remote machine to fetch the latest package files and decide which packages to +download. The disk directory structure should look like: + + + /disc/ + archives/ + partial/ + lists/ + partial/ + status + sources.list + apt.conf + + + + + + +The configuration file + +

+The configuration file should tell APT to store its files on the disc and +to use the configuration files on the disc as well. The sources.list should +contain the proper sites that you wish to use from the remote machine, and +the status file should be a copy of /var/lib/dpkg/status. Please note, +if you are using a local archive you must use copy URIs, the syntax is identical +to file URIs. + +

+apt.conf must contain the necessary information to make APT use the +disc: + + + APT + { + /* This is not necessary if the two machines are the same arch, it tells + the remote APT what architecture the Debian machine is */ + Architecture "i386"; + + Get::Download-Only "true"; + }; + + Dir + { + /* Use the disc for state information and redirect the status file from + the /var/lib/dpkg default */ + State "/disc/"; + State::status "status"; + + // Binary caches will be stored locally + Cache::archives "/disc/archives/"; + + // Location of the source list. + Etc "/disc/"; + }; + + +More details can be seen by examining the apt.conf man page and the sample +configuration file in /usr/doc/apt/examples/apt.conf. + +

+On the Debian machine the first thing to do is mount the disc and copy +/var/lib/dpkg/status to it. You will also need to create the directories +outlined in the Overview, archives/partial/ and lists/partial/ +Then take the disc to the remote machine and configure the sources.list. +On the remote machine execute the following: + + + # export APT_CONFIG="/disc/apt.conf" + # apt-get update + [ APT fetches the package files ] + # apt-get dist-upgrade + [ APT fetches all the packages needed to upgrade your machine ] + + +The dist-upgrade command can be replaced with any-other standard APT commands, +you can even use an APT front end such as gnome-apt [still in +development]. + +

+Now the disc contains all of the index files and archives needed to upgrade +the Debian machine. Take the disc back and run: + + + # export APT_CONFIG="/disc/apt.conf" + # apt-get check + [ APT generates a local copy of the cache files ] + # apt-get --no-d -o dir::etc::status=/var/lib/dpkg/status dist-upgrade + [ Or any other APT command ] + + +

+It is necessary for proper function to re-specify the status file to be the +local one. This is very important! + + + + +Using APT and wget + + +Overview + +

+wget is a popular and portable download tool that can run on nearly +any machine. Unlike the method above this requires that the Debian machine +already has a list of available packages. + +

+The basic idea is to create a disc that has only the archive files downloaded +from the remote site. This is done by using the --print-uris option to apt-get +and then preparing a wget script to actually fetch the packages. + + + + + +Operation + +

+Unlike the previous technique no special configuration files are required. We +merely use the standard APT commands to generate the file list. + + + # apt-get dist-upgrade + [ Press no when prompted, make sure you are happy with the actions ] + # apt-get -qq --print-uris dist-upgrade > uris + # awk '{print "wget -O " $2 " " $1}' < uris > /disc/wget-script + + +The /disc/wget-script file will now contain a list of wget commands to execute +in order to fetch the necessary archives. This script should be run with the +current directory as the disc's mount point so as to save the output on the +disc. + +

+The remote machine would do something like + + + # cd /disc + # sh -x ./wget-script + [ wait.. ] + + +Once the archives are downloaded and the disc returned to the Debian machine +installation can proceed using, + + + # apt-get -o dir::cache::archives="/disc/" dist-upgrade + + +Which will use the already fetched archives on the disc. + + + + diff --git a/apt/doc/pt_BR/CVS/Entries b/apt/doc/pt_BR/CVS/Entries new file mode 100644 index 0000000..c189382 --- /dev/null +++ b/apt/doc/pt_BR/CVS/Entries @@ -0,0 +1,9 @@ +/apt-cache.8/1.1/Fri Aug 10 14:01:42 2001// +/apt-cdrom.8/1.1/Fri Aug 10 14:01:42 2001// +/apt-config.8/1.1/Fri Aug 10 14:01:42 2001// +/apt-get.8/1.1/Fri Aug 10 14:01:44 2001// +/apt.8/1.1/Fri Aug 10 14:01:49 2001// +/apt.conf.5/1.1/Fri Aug 10 14:01:51 2001// +/sources.list.5/1.1/Fri Aug 10 14:01:51 2001// +/vendors.list.5/1.1/Fri Aug 10 14:01:51 2001// +D diff --git a/apt/doc/pt_BR/CVS/Repository b/apt/doc/pt_BR/CVS/Repository new file mode 100644 index 0000000..7ea68e2 --- /dev/null +++ b/apt/doc/pt_BR/CVS/Repository @@ -0,0 +1 @@ +rapt/doc/pt_BR diff --git a/apt/doc/pt_BR/CVS/Root b/apt/doc/pt_BR/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/doc/pt_BR/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/doc/pt_BR/apt-cache.8 b/apt/doc/pt_BR/apt-cache.8 new file mode 100644 index 0000000..31afd50 --- /dev/null +++ b/apt/doc/pt_BR/apt-cache.8 @@ -0,0 +1,319 @@ +.TH "apt-cache" "8" "25 Oct 2000" "apt" "" +.SH "NOME" +apt-cache \- APT utilitбrio de gerenciamento de pacotes -- manipulador de cache +.PP +.SH "SINOPSE" +apt-cache comando [argumento \&.\&.\&.] +.PP +.SH "DESCRIЗГO" +\fBapt-cache\fP realiza uma variedade de operaзхes no cache de pacotes do APT\&. +\fBapt-cache\fP й raramente chamado diretamente; ao invйs disso, suas +operaзхes sгo realizadas automaticamente pelos outros utilitбrios do \fBapt\fP\&. +.PP +\fIcomando\fP й um de: +.IP o +add file1 [file2] [\&.\&.\&.] +.IP o +gencaches +.IP o +showpkg package1 [package2] [\&.\&.\&.] +.IP o +stats +.IP o +dump +.IP o +dumpavail +.IP o +unmet +.IP o +check +.IP o +search +.IP o +show +.IP o +showpkg +.IP o +depends +.IP o +pkgnames +.IP o +dotty +.PP +A menos que -h, ou a opзгo --help seja dada um dos comandos acima +deve estar presente\&. +.PP +.IP "\fBadd\fP" +\fBadd\fP adiciona os nomes de arquivos de нndice de pacotes ao cache de pacotes\&. +.IP +.IP "\fBgencaches\fP" +\fBgencaches\fP realiza a mesma operaзгo que \fBapt-get check\fP\&. Constrуi +o cache de pacotes a partir dos fontes em \fB/etc/apt/sources\&.list\f +e a partir de \fB/var/lib/dpkg/status\fP\&. +.IP +.IP "\fBshowpkg\fP" +\fBshowpkg\fP mostra informaзгo sobre os pacotes listados na linha de +comando\&. Argumentos restantes sгo nomes de pacotes\&. As versхes +disponнveis de retro-dependкncias de cada pacote listado sгo listadas, +assim como as dependкncias para cada versгo\&. Dependкncias +normais sгo aqueles pacotes sobre os quais o pacote em questгo depende; +retro-dependкncias sгo aqueles pacotes que dependem sobre o pacote em +questгo\&. Assim, as demais dependкncias devem ser satisfeitas por um pacote, +porйm as retro-dependкncias nгo precisam\&. +Por exemplo, \fBapt-cache showpkg libreadline2\fP iria produzir uma saнda +semelhante ao que se segue: +.IP + +.nf + + +Pacote: libreadline2 + +Versхes: + +2\&.1-12(/var/state/apt/lists/debian\&.midco\&.net_debian_dists_slink_main_binary-i386_Packages), + +Retro-Dependкncias: + + libreadlineg2,libreadline2 + + libreadline2-altdev,libreadline2 +Dependкncias: + +2\&.1-12 - libc5 (2 5\&.4\&.0-0) ncurses3\&.0 (0 (null)) ldso (2 1\&.9\&.0-1) + +Fornece: + +2\&.1-12 - + +Provimentos inversos: + +.fi + + +.IP +Assim pode ser visto que a versгo 2\&.1-8 do libreadline2 depende da libc5, +ncurses3\&.0 e ldso, que devem estar instalados para ela funcione\&. +Desta forma, libreadlineg2 e libreadline2-altdev dependem de libreadline2\&. Se +libreadline2 for instalada, libc5, ncurses3\&.0, e ldso devem tambйm ser +instaladas; mas libreadlineg2 e libreadline2-altdev nгo precisam ser +instaladas\&. Para saber o significado especнfico do restante de saнda й melhor +consultar o cуdigo-fonte do apt\&. +.IP: +.IP "\fBstats\fP" +\fBstats\fP mostra algumas estatнsticas sobre o \fBcache\fP\&. +Nгo sгo esperados mais argumentos\&. Estatнsticas informadas sгo: +.IP o +\fBTotal de pacotes\fP й o nъmero de nomes de pacotes encontrados no cache\&. +.IP +.IP o +\fBPacotes normais\fP й o nъmero de nomes de pacotes normais; estes +sгo pacotes que suportam correspondкncia entre seus nomes e os nomes usados +por outros pacotes para eles em dependкncias\&. A maioria dos pacotes entram +nessa categoria\&. +.IP +.IP o +\BPacotes virtuais puros\fP й o nъmero de pacotes que existe apenas como +um nome de pacote virtual; isto й, pacotes apenas provкem o nome do +pacote virtual, e nenhum pacote realmente usa o nome\&. Por exemplo, +"mail-transport-agent" no sistema Debian GNU/Linux й um pacote puramente +virtual; vбrios pacotes fornecem "mail-transport-agent", mas nгo existe +nenhum pacote chamado "mail-transport-agent"\&. +.IP +.IP o +\fBPacotes virtuais simples\fP й o nъmero de pacotes virtuais providos +por um ъnico pacote\&. Por exemplo, no sistema +Debian GNU/Linux, "X11-text-viewer" й um pacote virtual, mas somente um +pacote, xless, fornece "X11-text-viewer"\&. +.IP +.IP o +\fBPacotes virtuais mistos\fP й o nъmero de pacotes que fornecem um pacote +virtual ou possuem o nome do pacote virtual como nome do pacote\&. Por +exemplo, no sistema Debian GNU/Linux, e2fsprogs sгo pacotes reais, +fornecidos pelo pacote e2compr\&. +.IP +.IP o +\fBFaltando\fP й o nъmero de nomes de pacotes que foram referenciados em uma +dependкncia, mas nгo foram fornecidos por nenhum pacote\&. Pacotes ausentes +podem estar em evidкncia se uma completa distribuiзгo nгo for acessada, ou se +um pacote (real ou virtual) foi removido da distribuiзгo\&. +.IP +.IP o +\fBTotal de versхes distintas\fP versхes sгo o nъmero de pacotes encontrados +no cache; este valor й entгo pelo menos igual ao nъmero total de nomes de +pacotes\&. Se mais de uma distribuiзгo (ambas "estбveis" e "instбveis", +por exemplo), estiver sendo acessada, este valor pode ser consideravelmente +maior do que o nъmero total de nomes de pacotes\&. +.IP +.IP o +\fBTotal de dependкncia\fP й o nъmero de relaзхes de dependкncia reinvidicadas +por todos os pacotes no cache\&. +.IP +.IP "\fBdump\fP" +\fBdump\fP mostra uma lista curta de cada pacote no cache\&. Й basicamente +para depuraзгo\&. +.IP +.IP "\fBdumpavail\fP" +\fBdumpavail\fP imprime uma lista de disponнveis para stdout\&. Isto й adequado +para uso com \fBdpkg\fP e й usado pelo mйtodo \fBdselect\fP\&. +.IP +.IP "\fBunmet\fP" +\fBunmet\fP mostra um resumo de todas as dependкncias nгo satisfeitas no cache +de pacotes\&. +.IP +.IP "\fBcheck\fP" +\fBcheck\fP й uma funзгo randфmica para testar certos aspectos do cache\&. +Nгo a use\&. +.IP +.IP "\fBshowpkg\fP" +\fBshowpkg\fP lista a estrutura de cache de pacotes dado +e algumas informaзхes referentes a ela\&. A lista й basicamente direcionada +para depuraзгo\&. +.IP +.IP "\fBshow\fP" +\fBshow\fP realiza uma funзгo semelhante ao dpkg --print-avail ou rpm -qi, +mostrando os registros do pacote para o pacote nomeado\&. +.IP +.IP "\fBsearch\fP" +\fBsearch\fP realiza uma busca completa do padrгo dado em todos os arquivos de +pacotes disponнveis\&. Procura pelos nomes de pacotes +e as descriзхes para ocorrкncia da string e imprime o nome do pacote +em uma curta descriзгo\&. Se --full for dado entгo uma saнda idкntica а +\fBshow\fP й produzida para cada pacote que bater. Se --names-only for +fornecido a busca irб desconsiderar a descriзгo comprida\&. +.IP +.IP "\fBdepends\fP" +\fBdepends\fP mostra uma lista de cada dependкncia que um pacote possui e +todos os outros pacotes possнveis que podem completar aquela dependкncia\&. +.IP +.IP "\fBpkgnames\fP" +Este comando mostra o nome de cada pacote no sistema\&. O argumento opcional +й um prefixo usado para filtrar a lista de nomes\&. A saнda й adequada +para uso em uma funзгo de completamento por tab do shell e geraзгo da saнda й +extremamente rбpida\&. Este comando й melhor usado com a +opзгo\& \fB--no-generate\fP. +.IP +.IP "\fBdotty\fP" +\fBdotty\fP Toma uma lista de pacotes na linha de comando e gera uma saнda +adequada para uso pelo dotty do pacote\& GraphVis +(http://www\&.research\&.att\&.com/sw/tools/graphviz/). O resultado serб um +conjunto de conexхes e bordas representando as relaзхes entre pacotes\&. +Por padrгo os pacotes fornecidos irгo traзar todos os pacotes dependentes +que podem produzir um amplo grбfico\&. Isto pode ser desativado configurando a +opзгo\& APT::Cache::GivenOnly. +.IP +As conexхes resultantes terгo vбrios formatos. Pacotes normais sгo caixas, +provimentos puros sгo triвngulos, provimentos misturados sгo losangos, +hexбgonos sгo pacotes que faltam\&. Caixas laranjas significam que a recursiva +foi parada [leaf packages], linhas azuis sгo prй-dependentes, linhas verdes +sгo conflitos\&. +.IP +Cuidado, dotty nгo pode representar graficamente conjuntos maiores de pacotes\&. +.IP +.PP.\" XXX +.SH "OPЗХES" +Todas as opзхes de linha de comando podem ser configuradas usando o arquivo de +configuraзгo. As descriзхes indicam a opзгo de configuraзгo a ser configurada\&.Para opзхes Booleanas vocк pode ignorar o arquivo de configuraзгo usando-se algocomo \fB-f-\fP, +\fB--no-f\fP, \fB-f=no\fP ou muitas outras variaзхes\&. +.PP +.IP "\fB-h, --help\fP" +Mostra um curto resumo de uso\&. +.IP +.IP "\fB-v, --version\fP" +Mostra a versгo do programa\&. +.IP +.IP "\fB-p --pkg-cache\fP" +Selecionar o arquivo a ser armazenado no cache de pacote\&. O cache de pacote +й o cache primбrio usado por todas as operaзхes\&. +Нtem de configuraзгo: \fBDir::Cache::pkgcache\fP\&. +.IP +.IP "\fB-s --src-cache\fP" +Selecionar o arquivo a ser armazenado no cache de fonte\&. O fonte й usado +somente pelo \fBgencaches\fP e armazena uma versгo de parse da informaзгo +de pacote a partir de fontes remotos\&. Quando construindo o cache de +pacote o cache do fonte й usado para evitar reparse de todos os arquivos do +pacote\&. +Нtem de configuraзгo: \fBDir::Cache::srcpkgcache\fP\&. +.IP +.IP "\fB-q, --quiet\fP" +Quiet; Produz uma saнda adequada para registro, omitindo indicadores de +progresso\&. +Mais qs produzirгo mais "quiet" a um mбximo de 2\&. Vocк pode usar tambйm +\fB-q=#\fP para configurar o nнvel de "quiet", ignorando o arquivo de +configuraзгo\&. Нtem de configuraзгo: \fBquiet\fP\&. +.IP +.IP "\fB-i --important\fP" +Mostrar somente dependкncias importantes; para uso com unmet causando somente \fIDepends\fP e +\fIPre-Depends\fP relaзхes a serem impressas\&. +Item de configuraзгo: \fBAPT::Cache::Important\fP\&. +.IP +.IP "\fB-f --full\fP" +Mostrar registros de pacotes completos quando em busca\&. Нtem de configuraзгo: \fBAPT::Cache::ShowFull\fP\&. +.IP +.IP "\fB-a --all-versions\fP" +Mostrar registros completos para todas as versхes disponнveis, isto aplica-se +somente ao comando mostrado\&. Нtem de configuraзгo: \fBAPT::Cache::AllVersions\\fP +.IP +.IP "\fB-g --no-generate\fP" +Nгo realizar regeneraзгo automбtica de cache de pacote, usar o cache como ele й +\&. +Нtem de configuraзгo: \fBAPT::Cache::NoGenerate\fP\&. +.IP +.IP "\fB--names-only\fP" +Pesquisar somente nos nomes de pacotes, nгo a descriзгo longa\&. +Нtem de configuraзгo: \fBAPT::Cache::NamesOnly\fP\&. +.IP +.IP "\fB--all-names\fP" +Fazer \fBpkgnames\fP imprimir todos os nomes, incluindo pacotes virtuais e +dependкncias que faltam\&. Нtem de configuraзгo: \fBAPT::Cache::AllNames\fP\& +.IP +.IP "\fB-c, --config-file\fP" +Arquivo de configuraзгo; Especificar um arquivo de configuraзгo a ser usado\&. \fBapt-get\fP irб ler o arquivo de configuraзгo padrгo e entгo este arquivo de +configuraзгo\&. Ver +\fBapt\&.conf(5)\fP para informaзгo de sintaxe\&. +.IP +.IP "\fB-o, --option\fP" +Configurar a opзгo de configuraзгo; isto irб configurar uma opзгo de +configuraзгo arbritбria\&. +A sintaxe й + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "ARQUIVOS" +.IP o +/etc/apt/sources\&.list +locais de onde obter os pacotes +.IP +.IP o +/var/state/apt/lists/ +бrea de armazenamento para exibir informaзгo para cada recurso de pacote +especificado em +.IP +.IP o +/var/state/apt/lists/partial/ +бrea de armazenamento para exibir informaзгo de estado em trвnsito +.PP +.SH "CONSULTE TAMBЙM" +apt-get(8), +sources\&.list(5), +apt\&.conf(5) +.PP +.SH "DIAGNУSTICOS" +apt-cache retorna zero em operaзгo normal, decimal 100 em erro\&. +.PP +.SH "BUGS" +Ver http://bugs\&.debian\&.org/apt\&. Se vocк deseja informar sobre um +bug em \fBapt-cache\fP, favor ver \fB/usr/doc/debian/bug-reporting\&.txt\fP +ou o comando\& \fBbug(1)\fP. Se vocк estб usando apt em um sistema baseado +em RPM, favor usar http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTOR" +apt-get foi escrito pela equipe APT +e portado para sistemas baseados em RPM pela Conectiva S.A. +\&. + diff --git a/apt/doc/pt_BR/apt-cdrom.8 b/apt/doc/pt_BR/apt-cdrom.8 new file mode 100644 index 0000000..a6d3098 --- /dev/null +++ b/apt/doc/pt_BR/apt-cdrom.8 @@ -0,0 +1,132 @@ +.TH "apt-cdrom" "8" "25 Oct 2000" "apt" "" +.SH "NOME" +apt-cdrom \- APT CDROM aplicativo de gerenciamento +.PP +.SH "SINOPSE" +apt-cdrom comando +.PP +.SH "DESCRIЗГO" +\fBapt-cdrom\fP й usado para adicionar um novo CDROM na lista APT dos +fontes disponнveis\&. +\fBapt-cdrom\fP cuida de determinar a estrutura do disco bem como corrigir +vбrios possнveis problemas e verifica os arquivos de нndice\&. +Й necessбrio usar \fBapt-cdrom\fP para adicionar CDs no sistema APT, isto +nгo pode ser feito manualmente\&. Alйm disso cada disco em um conjunto de +multi-cd deve ser inserido e examinado separadamente para contabilizar +possнveis problemas\&. +.PP +\fIcommand\fP й um dos: +.IP +add +.PP +A menos que a opзгo -h, ou --help seja dada em um dos comandos acima +deve estar presente\&. +.PP +.IP "\fBadd\fP" +\fBadd\fP й usado para adicionar um novo disco а lista fonte\&. Irб +desmontar o CDROM, verificar por um disco a ser inserido e entгo +proceder com a verificaзгo e copiar os arquivos de нndice\&. Se o +nгo tive um diretуrio \fB\&.disk/\fP adequado, vocк serб indagado +por um tнtulo descritivo\&. +.IP +APT usa uma identificaзгo de CDROM para rastrear qual disco estб +atualmente no drive e mantйm uma base de dados destes IDs em +\fB/var/state/apt/cdroms\&.list\fP +.IP +.PP +.SH "OPЗХES" +Todas as opзхes de linhas de comando podem ser configuradas usando +o arquivo de configuraзгo, as descriзхes indicam a opзгo de configuraзгo +a ser usada\&. Para opзхes booleanas vocк pode ignorar o arquivo de +configuraзгo usando algo como \fB-f-\fP, +\fB--no-f\fP, \fB-f=no\fP ou muitas outras variaзхes\&. +.PP +.IP "\fB-h, --help\fP" +Mostra um curto resumo de uso\&. +.IP +.IP "\fB-v, --version\fP" +Mostra a versгo do programa\&. +.IP +.IP "\fB-d --cdrom\fP" +Ponto de montagem; especificar o local a ser montado o cdrom\&. Este ponto +de montagem deve ser listado em \fB/etc/fstab\fP e configurado adequadamente\&. +Item de configuraзгo: \fBAcquire::cdrom::mount\fP\&. +.IP +.IP "\fB-r --rename\fP" +Renomear um disco; muda o rуtulo de um disco ou ignora o rуtulo dados do disco\&. +Esta opзгo irб causar \fBapt-cdrom\fP de apontar para um novo rуtulo +Item de configuraзгo: \fBAPT::CDROM::Rename\fP\&. +.IP +.IP "\fB-m, --no-mount\fP" +Sem montagem; previne \fBapt-cdrom\fP de montar e desmontar o ponto de montagem\&. +Item de configuraзгo: \fBAPT::CDROM::NoMount\fP\&. +.IP +.IP "\fB-f, --fast\fP" +Cуpia rбpida; assume que os arquivos do pacote sгo vбlidos e nгo verifica cada pacote\&. +Esta opзгo deve ser usada somente se \fBapt-cdrom\fP foi executado previamente no disco e nгo encontrou nenhum erro\&. +Item de configuraзгo: \fBAPT::CDROM::Fast\fP\&. +.IP +.IP "\fB-a, --thorough\fP" +Atravйs do exame de pacote; esta opзгo pode ser necessбria com algum antigo Debian 1\&.1/1\&.2 +que possui arquivos de pacotes em lugares estranhos\&. Leva muito mais tempo +para examinar o CD, mas irб obter todas\&. +.IP +.IP "\fB-n --just-print, --recon, --no-act\fP" +Sem mudanзas; Nгo alterar os fontes\&.list e nгo gravar arquivos de pacotes\&. +Tudo estб verificado\&. +Item de configuraзгo: \fBAPT::CDROM::NoAct\fP\&. +.IP +.IP "\fB-c, --config-file\fP" +Arquivo de configuraзгo; especifica um arquivo de configuraзгo a ser usado\&. \fBapt-get\fP irб fazer a leitura do arquivo de configuraзгo padrгo\&. Consulte +\fBapt\&.conf(5)\fP para informaзгo de sintaxe\&. +.IP +.IP "\fB-o, --option\fP" +Ativar a opзгo de configuraзгo; isto irб configurar uma opзгo de configuraзгo +arbitrбria\&. +A sintaxe й + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "FILES" +.IP o +/etc/apt/sources\&.list +locais da onde obter pacotes +.IP +.IP o +/var/state/apt/lists/ +бrea de armazenamento para informaзгo de estado para cada tipo de recurso de +pacote especificado em +.IP +.IP o +/var/state/apt/lists/partial/ +бrea de armazenamento para informaзгo de estado em trвnsito +.IP +.IP o +/var/state/apt/cdroms\&.list +lista de IDs de CDROMs e nomes\&. +.PP +.SH "CONSULTE TAMBЙM" +apt-get(8), +sources\&.list(5), +apt\&.conf(5) +.PP +.SH "DIAGNУSTICOS" +apt-cdrom retorna zero em operaзгo norma, decimal 100 em erro\&. +.PP +.SH "BUGS" +Consultar http://bugs\&.debian\&.org/apt\&. Se vocк deseja informar +sobre um bug em \fBapt-cache\fP, favor consultar +\fB/usr/doc/debian/bug-reporting\&.txt\fP +ou o comando\& \fBbug(1)\fP. Se vocк estiver usando o apt em um sistema +baseado em RPM, favor usar http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTOR" +apt-get foi escrito pela equipe do APT +e portado para sistemas RPM pela Conectiva S.A. +\&. + diff --git a/apt/doc/pt_BR/apt-config.8 b/apt/doc/pt_BR/apt-config.8 new file mode 100644 index 0000000..d32768f --- /dev/null +++ b/apt/doc/pt_BR/apt-config.8 @@ -0,0 +1,103 @@ +.TH "apt-config" "8" "25 Out 2000" "apt" "" +.SH "NOME" +apt-config \- programa APT Configuration Query +.PP +.SH "SINOPSE" +apt-config comando +.PP +.SH "DESCRIЗГO" +\fBapt-config\fP й um programa interno usado por vбrias partes da +suнte APT para fornecer configurabilidade consistente\&. Ele acessa o +arquivo principal de configuraзгo /etc/apt/apt\&.conf de uma forma que +seja fбcil de ser usado por aplicaзхes em script\&. +.PP +\fIcomando\fP й um dos seguintes: +.IP o +shell +.IP o +dump +.PP +A menos que as opзхes -h ou --help sejam fornecidas, um dos comandos +acima precisa estar presente\&. +.PP +.IP "\fBshell\fP" +\fBshell\fP й usado para acessar as informaзхes de configuraзгo de um +script shell\&. +Sгo fornecidos pares de argumentos, o primeiro sendo uma variбvel +shell e o segundo o valor de configuraзгo a ser questionado\&. Como +saнda ele lista uma sйrie de comandos shell de atribuiзгo para cada +valor presente\&. Em um script shell ele seria usado como: +.IP + +.nf + + +OPTS="-f" + +RES=`apt-config shell OPTS MeuApp::Opзхes` + +eval $RES + +.fi + + +.IP +Isto irб configurar a variбvel shell de ambiente $OPTS ao valor de +MeuApp::Opзхes com um padrгo de -f\&. +.IP +Se o нtem de configuraзгo a ser resgatado tiver uma / como prefixo, +ele serб resgatado atravйs do modo de nome de arquivo que insere +caminhos base no inнcio\&. +.IP +.IP "\fBdump\fP" +Mostra somente o conteъdo do espaзo de configuraзгo\&. +.IP +.PP +.SH "OPЗХES" +Todas as opзхes de linha de comando podem ser definidas atravйs do +arquivo de configuraзгo; as descriзхes indicam a opзгo de configuraзгo +a ser usada\&. Para opзхes booleanas vocк pode ignorar o arquivo de +configuraзгo usando algo como \fB-f-\fP, \fB--no-f\fP, \fB-f=no\fP ou +muitas outras variaзхes\&. +.PP +.IP "\fB-h, --help\fP" +Mostra um pequeno resumo de utilizaзгo\&. +.IP +.IP "\fB-v, --version\fP" +Mostra a versгo de programa\&. +.IP +.IP "\fB-c, --config-file\fP" +Arquivo de Configuraзгo; Especifique um arquivo de configuraзгo a ser +usado\&. \fBapt-get\fP irб ler o arquivo padrгo de configuraзгo e +entгo este arquivo de configuraзгo\&. Consulte \fBapt\&.conf(5)\fP +para informaзхes sobre a sintaxe\&. +.IP +.IP "\fB-o, --option\fP" +Define uma Opзгo de Configuraзгo; Isto irб configurar uma opзгo +arbitrбria de configuraзгo\&. +A sintaxe й + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "VEJA TAMBЙM" +apt\&.conf(5) +.PP +.SH "DIAGNУSTICOS" +apt-config retorna zero em operaзгo normal, 100 decimal 100 quando hб erro\&. +.PP +.SH "ERROS" +Veja http://bugs\&.debian\&.org/apt\&. Se vocк deseja reportar um +erro no \fBapt-config\fP, por favor consulte +\fB/usr/doc/debian/bug-reporting\&.txt\fP ou o comando \fBbug(1)\fP +\&. Se vocк estб usando apt em um sistema baseado em RPM, por favor +use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTOR" +apt-get foi escrito pelo time APT e +portado a sistemas RPM pela Conectiva +S.A. \&. diff --git a/apt/doc/pt_BR/apt-get.8 b/apt/doc/pt_BR/apt-get.8 new file mode 100644 index 0000000..3f16cf6 --- /dev/null +++ b/apt/doc/pt_BR/apt-get.8 @@ -0,0 +1,338 @@ +.TH "apt-get" "8" "25 Oct 2000" "apt" "" +.SH "NAME" +apt-get \- APT utilitбrio de manipulaзгo de pacotes -- interface de linha de comando +.PP +.SH "SYNOPSIS" +apt-get [opзхes] [comando] [pacote \&.\&.\&.] +.PP +.SH "DESCRIPTION" +.PP +apt-get й uma ferramenta em linha de comando para a manipulaзгo de pacotes, e pode ser considerada o "back-end" do usuбrio\ para o apt(8)\&. +.PP +\fIcommand\fP й um dos: +.IP o +update +.IP o +upgrade +.IP o +dselect-upgrade [1] +.IP o +dist-upgrade +.IP o +install pacote1 [pacote2] [\&.\&.\&.] +.IP o +remove pacote1 [pacote2] [\&.\&.\&.] +.IP o +source pacote1 [pacote2] [\&.\&.\&.] +.IP o +check +.IP o +clean +.IP o +auto-clean +.PP +Ao menos que as opзхes -h, ou --help sejam dadas um dos comandos acima deve estar presente\&. +.PP +Nota: +[1] Apenas para sistemas Debian +.PP +.IP "\fBupdate\fP" +\fBupdate\fP й utilizado para resincronizar os arquivos de sumбrio dos pacotes de seus +fontes\&. Os sumбrios dos pacotes disponнveis sгo trazidos dos locais especificados em +\fB/etc/apt/sources\&.list\fP\&. +Por exemplo, quando utilizar arquivos Debian, este comando recupera e procura por +arquivos \fBPackages\&.gz\fP, de forma que as informaзхes de pacotes novos e atualizados +esteja disponнvel\&. Um \fBupdate\fP deve sempre ser realizado antes de um +\fBupgrade\fP \fBdist-upgrade\fP\&. Esteja ciente de que o medidor de progresso total estarб +incorreto assim como o tamanho dos arquivos nгo podem ser conhecidos antes\&. +.IP +.IP "\fBupgrade\fP" +\fBupgrade\fP й usado para instalar a versгo mais nova de todos os pacotes instalados no +sistema dos fontes enumerados em \fB/etc/apt/sources\&.list\fP\&. Os pacotes atualmente +instalados com novas versхes disponнveis e atualizados; em nenhuma circunstвncia os +pacotes atualmente instalados sгo removidos, ou pacotes ainda nгo instalados recuperados e +instalados\&. Novas versхes de pacotes instalados que nгo podem ser atualizados sem alterar +o status da instalaзгo ou outros pacotes serгo deixados em sua versгo atual\&. +Um \fBupdate\fP deve ser realizado antes de forma que o \fBapt-get\fP reconhece que novas +versхes de pacotes estгo disponнveis\&. +.IP +.IP "\fBdselect-upgrade\fP" +\fBdselect-upgrade\fP +й usado com o tradicional front-end de empacotamento do Debian GNU/Linux, \fBdselect (8)\fP\&. \fBdselect-upgrade\fP segue as alteraзхes feitas por \fBdselect\fP para o campo de \fIStatus\fP dos pacotes disponнveis, e realiza as aзхes necessбrias para alcanзar este estado (por enquanto a remoзгo de pacotes antigos e a instalaзгo de novos)\&. +Este comando esta apenas disponнvel em sistemas Debian. +.IP +.IP "\fBdist-upgrade\fP" +\fBdist-upgrade\fP, alйm de realizar a funзгo do \fBupgrade\fP, +tambйm manipula de forma inteligente alterando dependкncias com as novas versхes dos +pacotes; o \fBapt-get\fP possui u sistema "inteligente" de resoluзгo de conflitos, +e esta tentarб atualizar os pacotes mais importantes e deixando os menos importantes se +necessбrio\&. O arquivo \fB/etc/apt/sources\&.list\fP contйm uma lista dos +locais aonde й possнvel se recuperar os arquivos do pacote\&. +.IP +.IP "\fBinstall\fP" +\fBinstall\fP й seguido por um ou mais \fIpackages\fP que se deseja instalar\&. +Cada \fIpackage\fP й o nome de uma pacote, nгo o nome de um arquivo altamente especifico +(em um sistema Debian GNU/Linux, \fIldso\fP deve ser o argumento fornecido, nгo +\fIldso_1\&.9\&.6-2\&.deb\fP)\&. Todos os pacotes solicitados para a instalaзгo serгo +recuperados e instalados\&. O arquivo \fB/etc/apt/sources\&.list\fP й utilizado para +localizar os pacotes desejados\&. Se um hнfen estiver anexado ao nome do pacote (sem nenhum +espaзo), o pacote indicado serб removido se estiver instalado\&. Esta funзгo pode ser +usada mais tarde para corrigir decisхes feitas no sistema de resoluзгo de conflitos +apt-get\\&. +.IP +Caso nгo haja a expressгo dada em nenhum pacote e a expressгo possua um +dos seguintes sнmbolos \'\&.\', \'?\' ou \'*\' esta pode ser considerada como sendo uma +expressгo regular POSIX e serб aplicada a todos os nomes dos pacotes no banco de dados\&. +Quaisquer correspondкncias sгo entгo instaladas (ou removidas)\&. Note que a correspondкncia +feita pela substring de modo que \'lo*\' corresponde a \'how-lo\' +e \'lowest\'\&. Caso isto nгo seja desejado inclua um caractere \'^\'\& como prefixo. +.IP +.IP "\fBremove\fP" +\fBremove\fP й idкntico a \fBinstall\fP exceto que os pacotes sгo removidos ao invйs de +instalados\&. Se um sinal de adiзгo for incluнdo no nome do pacote (sem nenhum espaзo), +o pacote identificados serб instalado\&. +.IP +.IP "\fBsource\fP" +O \fBsource\fP faz com que o apt-get traga os pacotes fonte\&. O APT examinarб os pacotes +disponнveis para decidir qual pacote fonte trazer\&. Este entгo encontrarб e farб o +download no diretуrio atual da mais na versгo disponнvel do pacote fonte\&. +Os pacotes fonte sгo colocados separadamente dos pacotes binбrios via \fBdeb-src\fP ou +\fBrpm-src\fP linhas de tipo no arquivo \fB/etc/apt/sources\&.list\fP\&. +Isto provavelmente significarб o mesmo fonte do mesmo pacote que vocк instalou ou que +vocк poderia instalar\&. Caso a opзгo --compile seja dada entгo o pacote serб compilado +com um binбrio\&.deb utilizando dpkg-buildpackage, ou sob sistemas baseados em RPM, +este irб compilar a um binбrio\&.rpm utilizando-se rpm -ba. Caso --download-only seja +utilizado o fonte nгo serб desempacotado\&. +.IP +Note que os pacotes fontes nгo sгo pesquisados como pacotes binбrios, eles existem apenas no +diretуrio atual e sгo similares quando se faz o download de tarballs\&. +.IP +.IP "\fBcheck\fP" +\fBcheck\fP й uma ferramenta de diagnуstico; esta atualiza o cache do pacote e verifica +pacotes corrompidos\&. +.IP +.IP "\fBclean\fP" +O \fBclean\fP limpa todo o repositуrio local do pacote de arquivos recuperados\&. +Ele remove tudo menos o arquivo de lock em \fB/var/cache/apt/archives/\fP +e \fB/var/cache/apt/archives/partial/\fP\&. +Quando o APT й usado como um mйtodo \fBdselect(8)\fP, o \fBclean\fP й rodado automaticamente\&. +Aqueles que nгo usam dselect irгo dessa forma rodar \f(CWapt-get clean\fP +de tempos em tempos para liberar espaзo em disco\&. +.IP +.IP "\fBautoclean\fP" +Assim como \fBclean\fP, o \fBautoclean\fP limpa todo o repositуrio local do +pacote de arquivos recuperado\&. A diferenзa й que este apenas remove arquivos +do pacote os quais nгo pode-se mais fazer o download e que sгo largamente utilizados\&. +Este permite que se mantenha um cache por um longo perнodo sem que o mesmo cresзa atй +que se perca o controle\&. +.IP +.PP +.SH "OPЗХES" +Todas as opзхes de linha de comando podem ser configuradas utilizando-se um arquivo de +configuraзгo, as descriзхes indicam a opзгo de configuraзгo a ser utilizada\&. +Para opзхes booleanas vocк pode anular o arquivo de configuraзгo utilizando algo como +\fB-f-\fP, \fB--no-f\fP, \fB-f=no\fP ou ainda outras variaзхes\&. +.PP +.IP "\fB-d, --download-only\fP" +Apenas download; os arquivos do pacote sгo apenas recuperados, nгo desempacotados nem mesmo +instalados\&. +Item de Configuraзгo: \fBAPT::Get::Download-Only\fP\&. +.IP +.IP "\fB-f, --fix-broken\fP" +Conserta; tenta corrigir um sistema com dependкncias rompidas em local\&. +Esta opзгo, quando utilizada com install/remove, pode omitir qualquer +pacote para permitir ao APT deduzir uma provбvel soluзгo\&. Quaisquer +pacotes que forem especificados devem corrigir completamente o +problema\&. A opзгo й, algumas vezes, necessбria ao executar o APT +pela primeira vez; o prуprio APT nгo permite a existкncia de dependкncias de +pacotes corrompidos em um sistema\&. Й possнvel que a estrutura de +dependкncia do sistema pode estar tгo corrompida que seja necessбria +intervenзгo manual (que geralmente significa usar dselect ou dpkg +--remove para eliminar alguns dos pacotes com problemas)\&. O uso desta +opзгo junto com -m pode ocasionar erro em algumas situaзхes\&. O item +de configuraзгo: \fBAPT::Get::Fix-Broken\fP\&. +.IP +.IP "\fB-h, --help\fP" +Ajuda; exibe uma mensagem ъtil e sai\&. +.IP +.IP "\fB-v, --version\fP" +Exibe a versгo do programa\&. +.IP +.IP "\fB-m, --ignore-missing, --fix-missing\fP" +Ignora pacotes faltantes; se pacotes nгo puderem ser recuperados ou +causarem falha no teste de integridade apуs a restauraзгo (arquivos +com pacotes corrompidos), retйm estes pacotes e processa o +resultado\&. O uso desta opзгo junto com -f pode ocasionar um erro em +algumas situaзхes\&. Se um pacote for selecionado para instalaзгo +(particularmente se for mencionado na linha de comando) e nгo puder +ser baixado, entгo este pacote serб retido\&. +Item de configuraзгo: \fBAPT::Get::ignore-missing\fP\&. +.IP +.IP "\fB-S, --summary\fP" +Quando usado com os comandos upgrade ou dist-upgrade, exibe +informaзхes do que seria atualizado, com importвncia e um resumo das +alteraзхes (quando tais dados estiverem disponнveis) e pбra. +Item de configuraзгo: \fBAPT::Get::Show-Upgrade-Summary\fP&. +.IP +.IP "\fB--no-download\fP" +Desabilita o download de pacotes\&. Isto й melhor usado com +--ignore-missing para forзar o APT a usar apenas o \&.debs se tiver +realmente feito download\&. +Item de configuraзгo: \fBAPT::Get::No-Download\fP\&. +.IP +.IP "\fB-q, --quiet\fP" +Quiet; produz saнda adequada para logging, omite indicadores de progresso\&. +Mais q\'s produzirб mais quiet atй um mбximo de 2\&. Vocк tambйm pode usar +\fB-q=#\fP para definir o nнvel de quiet, sobrescrevendo o arquivo de +configuraзгo\&. Observe que o nнvel de quiet 2 implica -y, nunca se +deve usar -qq sem um modificador sem aзгo como -d, --print-uris ou -s +porque o APT pode decidir fazer algo nгo esperado\&. +Item de configuraзгo: \fBquiet\fP +.IP +.IP "\fB-s, --simulate, --just-print, --dry-run, --recon, --no-act\fP" +Nenhuma aзгo; executa uma simulaзгo de eventos que iriam ocorrer mas +nгo altera realmente o sistema\&. +Item de configuraзгo: \fBAPT::Get::Simulate\fP\&. +.IP +Simula a impressгo de uma sйria de linha, onde cada uma representa uma + de linhas representando uma operaзгo dpkg, Configure (Conf), Remove +(Remv), Unpack (Inst)\&. Os colchetes indicam pacotes corrompidos e +um conjunto vazio de colchetes significa que nгo hб seqькncia (raro)\&. +.IP +.IP "\fB-y, --yes, --assume-yes\fP" +Afirmativa automбtica para os prompts; assume "yes" como resposta para +todos os prompts e й executado nгo interativamente\&. Se ocorrer uma situaзгo +indesejбvel, como alteraзгo de um pacote retido ou remoзгo de um +pacote essencial, entгo \fBapt-get\fP irб cancelar\&. +Item de configuraзгo: \fBAPT::Get::Assume-Yes\fP\&. +.IP +.IP "\fB-u, --show-upgraded\fP" +Exibe pacotes com upgrade; imprime uma lista de todos os pacotes devem +ser atualizados (upgrade)\&. +Item de configuraзгo: \fBAPT::Get::Show-Upgraded\fP\&. +.IP +.IP "\fB-b, --compile, --build\fP" +Compila pacotes-fonte apуs baixб-los\&. +Item de configuraзгo: \fBAPT::Get::Compile\fP\&. +.IP +.IP "\fB--ignore-hold\fP" +Ignora pacotes retidos; Isto faz com o \fBapt-get\fP ignore um pacote retido +colocado em um pacote\&. Isto pode ser ъtil em conjunto com +\fBdist-upgrade\fP para sobre sobregravar uma grande quantidade de +pacotes retidos indesejados\&. +Item de configuraзгo: \fBAPT::Ignore-Hold\fP\&. +.IP +.IP "\fB--no-upgrade\fP" +Nгo atualiza pacotes; Quando usado em conjunto com \fBinstall\fP +\fBno-upgrade\fP irб evitar que os pacotes relacionados sejam +atualizados se estes jб estiverem instalados\&. +Item de configuraзгo: \fBAPT::Get::no-upgrade\fP\&. +.IP +.IP "\fB--force-yes\fP" +Forзa sim; esta й uma opзгo perigosa que que farб com que o APT +continue sem exibir se estiver fazendo algo potencialmente +danoso\&. Nгo deve ser usado exceto em situaзхes especiais\&. O uso de +\fBforce-yes\fP pode destruir potencialmente seu sistema! +Item configuraзгo: \fBAPT::Get::force-yes\fP\&. +.IP +.IP "\fB--print-uris\fP" +Em vez de obter os arquivos para serem instalados seus URIs sгo +exibidos\&. Cada URI terб o caminho, o nome de arquivo de destino, o +tamanho e o hash md5 esperado\&. Observe que o nome de arquivo a ser +escrito nem sempre serб igual ao nome de arquivo no site remoto! Isto +tambйm funciona com o comando \fBsource\fP\&. +Item de configuraзгo: \fBAPT::Get::Print-URIs\fP\&. +.IP +.IP "\fB--purge\fP" +Use purge em vez de remove para remover qualquer coisa\&. +Esta opзгo nгo tem efeito nos sistemas baseados em RPM. +Item de configuraзгo: \fBAPT::Get::Purge\fP\&. +.IP +.IP "\fB--reinstall\fP" +Reinstala pacotes que jб foram instalados e na versгo mais nova\&. +.IP +.IP "\fB--list-cleanup\fP" +Esta opзгo й habilitada por padrгo, use \fB--no-list-cleanup\fP para +desabilitб-la\&. Quando habilitada o apt-get irб gerenciar +automaticamente os conteъdos de /var/state/apt/lists para +certificar-se de que os arquivos obsoletos serгo apagados\&. A ъnica +razгo para desativб-la й se vocк altera sua lista-fonte com freqькncia\&. +Item de configuraзгo: \fBAPT::Get::List-Cleanup\fP +.IP +.IP "\fB--trivial-only\fP" +Executa apenas as operaзхes consideradas \'triviais\'\&. Й lуgico que +isto pode ser relacionado a --assume-yes, onde --assume-yes irб +responder sim para qualquer prompt, --trivial-only irб responder +nгo\&. +Item de configuraзгo: \fBAPT::Get::Trivial-Only\fP +.IP +.IP "\fB--no-remove\fP" +Se nenhum pacote tiver que ser removido o apt-get cancela +imediatamente sem aviso\&. +Item de configuraзгo: \fBAPT::Get::No-Remove\fP +.IP +.IP "\fB--diff-only\fP, \fB--tar-only\fP" +Faz download apenas do arquivo diff ou tar de um arquivo-fonte\&. +Item de configuraзгo: \fBAPT::Get::Diff-Only\fP +.IP +.IP "\fB-c, --config-file\fP" +Arquivo de configuraзгo; Especifica um arquivo de configuraзгo para +ser usado\&. \fBapt-get\fP irб ler o arquivo de configuraзгo padrгo e +depois este arquivo de configuraзгo\&. Veja +\fBapt\&.conf(5)\fP para informaзхes sobre sintaxe\&. +.IP +.IP "\fB-o, --option\fP" +Configura uma opзгo de configuraзгo; Isto irб ajustar uma opзгo de +configuraзгo arbitrбria\&. +A sintaxe й + +.nf + +-o Foo::Bar=bar +.fi + + +.PP +.SH "FILES" +.IP o +/etc/apt/sources\&.list +locais de onde se obtйm pacotes +.IP +.IP o +/var/cache/apt/archives/ +бrea de armazenagem para arquivos de pacotes recuperados +.IP +.IP o +/var/cache/apt/archives/partial/ +бrea de armazenagem para arquivos de pacotes em trвnsito +.IP +.IP o +/var/state/apt/lists/ +бrea de armazenagem para informaзгo de estado para cada recurso de +pacote especificado na lista de fontes +.IP +.IP o +/var/state/apt/lists/partial/ +бrea de armazenagem para informaзгo de estado em trвnsito +.PP +.SH "SEE ALSO" +apt-cache(8), +dpkg(8), +dselect(8), +sources\&.list(5), +apt\&.conf(5), +O guia do usuбrio APT em /usr/doc/apt/ +.PP +.SH "DIAGNOSTICS" +apt-get retorna zero em operaзгo normal, decimal 100 em erro\&. +.PP +.SH "BUGS" +Veja http://bugs\&.debian\&.org/apt\&. Caso queira reportar um bug em +\fBapt-get\fP, por favor leia \fB/usr/doc/debian/bug-reporting\&.txt\fP +ou use o comando \fBbug(1)\fP\&. Se vocк estiver usando um sistema +baseado em RPM, por favor use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt-get foi escrito pelo time APT +e portado para os sistemas baseados em RPM pela Conectiva S.A. +\&. diff --git a/apt/doc/pt_BR/apt.8 b/apt/doc/pt_BR/apt.8 new file mode 100644 index 0000000..be1240d --- /dev/null +++ b/apt/doc/pt_BR/apt.8 @@ -0,0 +1,56 @@ +.\" This manpage is copyright (C) 1998 Branden Robinson . +.\" +.\" Updated for Conectiva by Alfredo K. Kojima . +.\" +.\" This is free software; you may redistribute it and/or modify +.\" it under the terms of the GNU General Public License as +.\" published by the Free Software Foundation; either version 2, +.\" or (at your option) any later version. +.\" +.\" This is distributed in the hope that it will be useful, but +.\" WITHOUT ANY WARRANTY; without even the implied warranty of +.\" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +.\" GNU General Public License for more details. +.\" +.\" You should have received a copy of the GNU General Public +.\" License along with APT; if not, write to the Free Software +.\" Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA +.\" 02111-1307 USA +.TH apt 8 "25 Oct 2000" "Debian GNU/Linux" +.SH NOME +apt \- Advanced Package Tool +.SH SINOPSE +.B apt +.SH DESCRIЗГO +APT й um sistema de gerenciamento para pacotes de software, ainda em fase +de desenvolvimento; as partes sofisticadas do projeto ainda nгo estгo +disponнveis. Por enquanto, +favor consultar +.BR apt-get (8). +.SH OPЗХES +Nenhum. +.SH ARQUIVOS +Nenhum. +.SH CONSULTE TAMBЙM +.BR apt-tache (8), +.BR apt-get (8), +.BR sources.list (5) +.SH DIAGNУSTICOS +apt retorna a zero em operaзгo normal, decimal 100 em erro. +.SH BUGS +Esta pбgina de manual nгo nem iniciada. +.PP +Consulte . Se vocк deseja informar +sobre um bug no +.BR apt , +favor consultar +.I /usr/doc/debian/bug-reporting.txt +or the +.BR bug (1) +comando. Se vocк estiver usando o apt em um sistema baseado em RPM, +favor usar http://distro\&.conectiva\&.com\&.br/bugzilla/\&. + +.SH AUTOR +apt foi escrito pela equipe APT +e atualizado para sistemas baseados em RPM pela +Conectiva S.A. diff --git a/apt/doc/pt_BR/apt.conf.5 b/apt/doc/pt_BR/apt.conf.5 new file mode 100644 index 0000000..71ace5f --- /dev/null +++ b/apt/doc/pt_BR/apt.conf.5 @@ -0,0 +1,280 @@ +.TH "apt\&.conf" "5" "01 Nov 2000" "apt" "" +.SH "NOME" +apt\&.conf \- arquivo de configuraзгo do APT +.PP +.SH "DESCRIЗГO" +\fBapt\&.conf\fP й o principal arquivo de configuraзгo da suнte de +ferramentas APT, todas as ferramentas fazem uso do arquivo de +configuraзгo e de um verificador comum de linha de comando para +fornecer um ambiente uniforme\&. Quando uma ferramenta APT й iniciada, +ela irб ler \fB/etc/apt/apt\&.conf\fP, e entгo ler a configuraзгo +especificada pela variбvel de ambiente \fB$APT_CONFIG\fP e, +finalmente, irб aplicar as opзхes de linha de comando (as quais tкm +prioridade sobre as diretivas de configuraзгo), possivelmente +carregando mais arquivos de configuraзгo\&. +.PP +O arquivo de configuraзгo й estruturado em uma бrvore com opзхes +organizadas em grupos funcionais\&. Especificaзгo de opзгo й fornecida +com uma notaзгo de dois pontos duplos, por exemplo +\fIAPT::Get::Assume-Yes\fP й uma opзгo na qual o grupo de ferramentas +APT, para a ferramenta Get\&. Opзхes sгo herdadas de seus grupos pai\&. +.PP +Sintaticamente, a linguagem de configuraзгo й modelada conforme as +ferramentas ISC, como bind e dhcp usam\&. Cada linha й na forma +.RS +APT::Get::Assume-Yes "true"; +.RE +O ponto-e-vнrgula final й necessбrio e as aspas sгo opcionais\&. Um +novo \fIescopo\fP pode ser aberto com chaves, como:: + +.nf + +APT { + Get { + Assume-Yes "true"; + Fix-Broken "true"; + }; +}; + +.fi + + +com retornos de carro colocados para tornб-lo mais legнvel\&. Listas +podem ser criadas abrindo-se um escopo e incluindo uma palavra simples +encapsulada em aspas seguida por um ponto-e-vнrgula\&. +Geralmente o arquivo exemplo de configuraзгo em +\fI/usr/doc/apt/examples/apt\&.conf\fP e \fI/usr/doc/apt/examples/configure-index\fP +(ou \fI/usr/share/doc/apt*/examples/configure-index\fP no Conectiva) й +um bom guia sobre como o arquivo deve ficar. +.PP +Todas as ferramentas APT usam uma opзгo -o que permite que uma +diretiva arbitrбria de configuraзгo seja especificada na linha de +comando\&. A sintaxe й um nome completo de opзгo (APT::Get::Assume-Yes +por exemplo) seguido por um sinal de igual e o novo valor da +opзгo\&. Listas podem tambйm ser anexadas atravйs da adiзгo de :: no +final do nome da lista.\&. +.PP +.SH "O Grupo APT" +Este grupo de opзхes controla o comportamento geral do APT e tambйm +mantйm as opзхes para todas as ferramentas\&. +.PP +.IP "\fBArchitecture\fP" +Arquitetura do Sistema; define a arquitetura a ser usada quando da +busca de arquivos e verificaзгo das listas de pacotes\&. O padrгo +interno й a arquitetura para a qual o apt foi compilado\&. +.IP +.IP "\fBIgnore-Hold\fP" +Ignora pacotes retidos; Esta opзгo global faz com que o resolvedor de +problemas ignore pacotes retidos quando da tomada de decisхes\&. +.IP +.IP "\fBClean-Installed\fP" +O padrгo й ligado (on)\&. Quando ligada, a caracterнstica de +auto-limpeza irб remover qualquer pacote o qual nгo possa ser mais +baixado do cache\&. Quando desligado, pacotes instalados localmente +tambйm sгo excluнdos da limpeza - mas observe que APT nгo fornece +meios diretos de reinstalб-los.\&. +.IP +.IP "\fBImmediate-Configure\fP" +Desabilita Configuraзгo Imediata; Esta perigosa opзгo desabilita +alguns cуdigos de ordens do APT para fazк-lo executar algumas poucas +chamadas dpkg\&. Fazer isso pode ser necessбrio em alguns sistemas +monousuбrio extremamente lentos mas й muito perigoso e pode fazer com +que os scripts de instalaзгo de pacotes nгo funcionem, ou pior que isso\&. +Use por sua conta e risco\&. Esta opзгo nгo tem nenhum efeito em +sistemas baseados em RPM\&. +.IP +.IP "\fBForce-LoopBreak\fP" +Nunca habilite esta opзгo a menos que vocк -realmente- saiba o que +estб fazendo\&. Ela permite que o APT remova temporariamente um pacote +essencial para quebrar loops Conflitos/Conflitos ou +Conflitos/Prй-dependкncias entre dois pacotes essenciais\&. TAIS LOOPS +NГO DEVERIAM EXISTIR E SГO ERROS GRAVES\&. Esta opзгo irб funcionar se +os pacotes essenciais nгo forem tar, gzip, libc, dpkg, bash ou +qualquer coisa que estes pacotes dependam\&. +.IP +.IP "\fBCache-Limit\fP" +APT usa arquivo de cache de tamanho fixo mapeando a memуria que +armazena as informaзхes \'disponнveis\'\&. Isto define o tamanho +desse cache\&. +.IP +.IP "\fBGet\fP" +A subseзгo Get controla a ferramenta \fBapt-get(8)\fP, por favor +consulte sua documentaзгo para mais informaзхes sobre as opзхes aqui\&. +.IP +.IP "\fBCache\fP" +A subseзгo Cache controla a ferramenta \fBapt-cache(8)\fP, por favor +consulte sua documentaзгo para mais informaзхes sobre estas opзхes\&. +.IP +.IP "\fBCDROM\fP" +A subseзгo CDROM controla a ferramenta \fBapt-cdrom(8)\fP, por favor +consulte sua documentaзгo para mais informaзхes sobre estas opзхes\&. +.IP +.PP +.SH "O Grupo Acquire" +O grupo de opзхes \fBAcquire\fP controla o download de pacotes e de +tratadores URI\&. +.PP +.IP "\fBQueue-Mode\fP" +Modo de fila; \fBQueue-Mode\fP pode ser um dos \fBhost\fP ou +\fBaccess\fP o que determina como APT paraleliza conexхes +externas\&. \fBhost\fP significa que uma conexгo por mбquina alvo pode +ser aberta, \fBaccess\fP significa que uma conexгo por tipo URI pode +ser aberta\&. +.IP +.IP "\fBRetries\fP" +Nъmero de tentativas a executar\&. Se for diferente de zero, apt irб +tentar buscar por arquivos que falharam pelo nъmero fornecido de vezes\&. +.IP +.IP "\fBSource-Symlinks\fP" +Usar links simbуlicos para arquivos fonte\&. Se configurado para +"true" entгo os arquivos fonte serгo simbolicamente linkados quando +possнvel, em vez de serem copiados\&. "True" й o padrгo +.IP +.IP "\fBhttp\fP" +HTTP URIs; http::Proxy й o proxy http padrгo a ser usado\&. Ele estб +na forma padrгo de +\fIhttp://[[usuбrio][:pass]@]mбquina[:porta]/\fP\&. Proxies para +mбquinas tambйm podem ser especificados atravйs da forma +http::Proxy:: com a palavra-chave especial \fIDIRECT\fP +significando o nгo uso de proxies\&. A variбvel de ambiente +\fI$http_proxy\fP sobrepхe todas as configuraзхes\&. +.IP +Trкs configuraзхes sгo fornecidas para controle de cache com caches de +proxy que estejam de acordo com o padrгo HTTP/1\&.1\&. \fBNo-Cache\fP +diz ao proxy para nгo usar sua resposta sob cache em algumas +circunstвncias, \fBMax-Age\fP й enviada apenas para arquivos de нndice +e diz ao cache para atualizar seu objeto caso seja mais antigo que o +nъmero fornecido de segundos\&. +Debian atualiza seus arquivos de нndice diariamente, de forma que o +padrгo й 1 dia\&. \fBNo-Store\fP especifica que o cache nгo deve nunca +armazenar este pedidom ele й apenas definido para arquivos +comuns\&. Isto pode ser ъtil para evitar a poluiзгo de um cache de +proxy com arquivos \&.deb muito longos\&. Nota: Squid 2\&.0\&.2 nгo +suporta nenhuma destas opзхes\&. +.IP +A opзгo \fBtimeout\fP configura o temporizador de tempo limite usado +pelo mйtodo, isto se aplica a todas as coisas, incluindo o tempo +limite de conexгo e o tempo limite de dados\&. +.IP +Uma configuraзгo й fornecida para controlar a profundidade do pipeline +em casos onde o servidor remoto nгo estб de acordo com RFC ou tem +erros (como o Squid 2\&.0\&.2) +Acquire::http::Pipeline-Depth pode ser um valor de 0 a 5, indicando o +nъmero de pedidos que APT deve enviar\&. +.IP +.IP "\fBftp\fP" +URis FTP; ftp::Proxy й o servidor proxy padrгo a ser usado\&. Ele estб +na forma padrгo de \fIftp://[[usuбrio][:pass]@]mбquina[:porta]/\fP e й +sobreposto pela variбvel de ambiente ftp_proxy\&. Para usar um proxy +ftp vocк deverб configurar o script ftp::ProxyLogin no arquivo de +configuraзгo\&. Esta entrada especifica os comandos a serem enviados +para dizer ao servidor proxy o que deve ser conectado aonde\&. Por +favor consulte \fI/usr/doc/apt/examples/configure-index\fP para um +exemplo de como fazer isso\&. As variбveis de substituiзгo disponнveis +sгo $(PROXY_USER), $(PROXY_PASS), $(SITE_USER), $(SITE_PASS), $(SITE), +e $(SITE_PORT)\&. +Cada uma й obtida de seu respectivo componente URI\&. +.IP +A opзгo \fBtimeout\fP define o temporizador de tempo limite a ser +utilizado pelo mйtodo, isto se aplica a todas as coisas, incluindo +tempo limite de conexгo e tempo limite de dados\&. +.IP +Muitas configuraзхes sгo fornecidas para controlar o modo +passivo\&. Geralmente й seguro deixar o modo passivo ligado (on), ele +funciona em quase todos os ambientes\&. Entretanto, algumas situaзхes +necessitam do modo passivo desligado, e o modo ftp de porta usado em +seu lugar\&. Isto pode ser executado globalmente, para conexхes que +passam por um proxy ou por uma mбquina especнfica (Consulte o arquivo +exemplo de configuraзгo para exemplos) +.IP +Й possнvel executar proxy FTP sobre HTTP configurando a variбvel de +ambiente \fIftp_proxy\fP para uma url http - consulte a discussгo do +mйtodo http acima para informaзхes na sintaxe\&. Vocк nгo pode +definir isto no arquivo de configuraзгo e nгo й recomendбvel usar FTP +sobre HTTP devido a sua baixa eficiкncia\&. +.IP +.IP "\fBcdrom\fP" +URIs CDROM; a ъnica configuraзгo para URIs CDROM й o ponto de +montagem, cdrom::Mount, o qual precisa ser o ponto de montagem do +drive de CDROM conforme especificado em /etc/fstab\&. +Й possнvel fornecer comandos alternativos de montagem e desmontagem +caso o seu ponto de montagem nгo possa ser listado no fstab (como uma +montagem SMB)\&. A sintaxe й colocar "/cdrom/"::Mount "foo"; dentro do +bloco cdrom\&. Й importante manter a barra no final\&. Comandos de +desmontagem podem ser especificados atravйs de UMount\&. +.IP +.PP +.SH "Diretуrios" +A seзгo \fBDir::State\fP tem diretуrios pertinentes a informaзхes do +estado local\&. \fBlists\fP й o diretуrio onde devem ser colocadas +listas de pacotes e \fBstatus\fP й o nome do arquivo de status +dpkg\&. \fBDir::State\fP contйm o diretуrio padrгo que entrarб como +prefixo em todos os sub-itens, caso eles nгo se iniciem com \fI/\fP ou +\fI\&./\fP\&. \fBxstatus\fP e \fBuserstatus\fP sгo para uso futuro\&. +.PP +\fBDir::Cache\fP contйm posiзхes pertinentes a informaзхes sobre o cache local, como os caches de dois pacotes \fBsrcpkgcache\fP e \fBpkgcache\fP bem como a posiзгo onde devem ser colocados arquivos baixados, \fBDir::Cache::archives\fP\&. Como \fBDir::State\fP o diretуrio padrгo й contido em \fBDir::Cache\fP +.PP +\fBDir::Etc\fP contйm a localizaзгo dos arquivos de configuraзгo, \fBsourcelist\fP fornece a localizaзгo da lista de fontes e \fBmain\fP й o arquivo padrгo de configuraзгo (configuraзгo sem efeito) +.PP +Programas binбrios sгo apontados por \fBDir::Bin\fP\&. \fBmethods\fP especifica a localizaзгo dos tratadores de mйtodos e \fBgzip\fP, \fBdpkg\fP, \fBrpm\fP, \fBapt-get\fP, \fBdpkg-source\fP, \fBdpkg-buildpackage\fP e \fBapt-cache\fP especificam a localizaзгo dos respectivos programas\&. +.PP +.SH "APT em DSelect" +Quando APT й usado como um mйtodo \fBdselect(8)\fP, muitas diretivas de configuraзгo controlam o comportamento padrгo\&. Elas estгo na seзгo \fBDSelect\fP\&. +.PP +.IP "\fBClean\fP" +Modo de cache limpo; este valor pode ser um entre always, auto, prompt e never\&. +always irб remover todos os arquivos apуs eles serem baixados; auto apenas removerб coisas que nгo podem mais ser baixadas (substituнdas por uma nova versгo, por exemplo) +.IP +.IP "\fBOptions\fP" +O conteъdo desta variбvel й passado ao \fBapt-get(8)\fP como opзхes de linha de comando durante a execuзгo na fase de instalaзгo\&. +.IP +.IP "\fBUpdateOptions\fP" +O conteъdo desta variбvel й passado ao \fBapt-get(8)\fP como opзхes de linha de comando durante a execuзгo na fase de atualizaзгo\&. +.IP +.IP "\fBPromptAfterUpdate\fP" +Se for "true", a operaзгo de Atualizaзгo ([U]pdate) no dselect sempre irб pedir para continuar\&. +O padrгo й pedir apenas quando houver erros\&. +.PP +.SH "How APT calls DPkg" +Muitas diretivas de configuraзгo controlam como o APT chama dpkg\&. Elas estгo na seзгo \fBDPkg\fP\&. +.PP +.IP "\fBOptions\fP" +Esta й uma lista de opзхes a serem passadas ao dpkg\&. As opзхes precisam ser especificadas atravйs na notaзгo de lista e cada item da lista deve ser passado como um argumento simples ao dpkg\&. +.IP +.IP "\fBPre-Invoke\fP, \fBPost-Invoke\fP" +Esta й uma lista de comandos shell a serem executados antes/depois de chamar dpkg\&. Como \fBOptions\fP isto deve ser especificado na notaзгo lista\&. Os comandos sгo chamados em ordem usando /bin/sh; em caso de falhas a execuзгo do APT й cancelada\&. +.IP +.IP "\fBPre-Install-Pkgs\fP" +Esta й uma lista de comandos shell a serem executados antes de se chamar dpkg\&. Como \fBOptions\fP isto deve ser especificado na notaзгo lista\&. Os comandos sгo chamados em ordem usando /bin/sh; em caso de falhas a execuзгo do APT й cancelada\&. +Apt irб passar aos comandos na entrada padrгo os nomes de todos os arquivos \&.deb que ele for instalar, um por linha\&. +.IP +.IP "\fBRun-Directory\fP" +APT alterna para este diretуrio antes de chamar dpkg, o padrгo й /\&. +.IP +.IP "\fBBuild-Options\fP" +Estas opзхes sгo passadas ao dpkg-buildpackage durante a compilaзгo de pacotes, o padrгo й desabilitar sinalizaзгo e produzir todos os binбrios\&. +.IP +.PP +.SH "Debug - Opзхes de depuraзгo" +A maioria das opзхes na seзгo \fBdebug\fP nгo sгo interessantes ao usuбrio normal, entretanto, \fBDebug::pkgProblemResolver\fP mostra uma saнda interessante sobre as decisхes feitas por dist-upgrade\&. \fBDebug::NoLocking\fP desabilita a trava de arquivos de forma que o apt possa executar algumas operaзхes sem ser root e \fBDebug::pkgDPkgPM\fP (ou \fBDebug::pkgRPMPM\fP) irб imprimir a linha de comando para cada chamada de dpkg\&. \fBDebug::IdentCdrom\fP irб desabilitar a inclusгo de dados statfs nas IDs de CDROMs\&. +.PP +.SH "EXEMPLOS" +\fB/usr/doc/apt/examples/configure-index\&.gz\fP ou +\fB/usr/share/doc/apt*/configure-index\fP +contйm um arquivo exemplo de configuraзхes mostrando os valores padrгo de todas as opзхes possнveis\&. +.PP +.SH "ARQUIVOS" +/etc/apt/apt\&.conf +.PP +.SH "VEJA TAMBЙM" +apt-cache (8), +apt-get (8) +.PP +.SH "ERROS" +Consulte http://bugs\&.debian\&.org/apt\&. Se vocк desejar reportar um erro no \fBapt-get\fP, por favor consulte \fB/usr/doc/debian/bug-reporting\&.txt\fP ou o comando \fBbug(1)\fP\&. Se vocк estiver usando apt em um sistema baseado em RPM, consulte http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTOR" +apt-get foi escrito pelo time APT e portado para sistemas baseados em RPM pela Conectiva S.A. +\&. + + diff --git a/apt/doc/pt_BR/sources.list.5 b/apt/doc/pt_BR/sources.list.5 new file mode 100644 index 0000000..03a61f6 --- /dev/null +++ b/apt/doc/pt_BR/sources.list.5 @@ -0,0 +1,220 @@ +.TH "sources\&.list" "5" "25 Oct 2000" "apt" "" +.SH "NOME" +sources\&.list \- package resource list for APT +.PP +.SH "DESCRIЗГO" +A lista de recursos de pacotes й usada para localizar arquivos do +sistema de distribuiзгo de pacotes em uso no sistema\&. +.PP +A lista de fontes й planejada para suportar qualquer quantidade de +fontes ativos e uma variedade de meios de fonte\&. O arquivo relaciona +um fonte por linha, com o fonte mais preferido relacionado +primeiro\&. O formato de cada linha й: \fItype uri args\fP o primeiro +item, \fItype\fP, determina o formato para \fIargs\fP\&. \fIuri\fP й +um Identificador de Recurso Universal (URI), que й um super conjunto +de Localizadores de Recurso Universal ou URL mais conhecidos e mais +especнficos\&. +.PP +.SH "Os tipos deb e deb-src" +O tipo \fBdeb\fP descreve o ibes, um arquivo tipo Debian de dois nнveis, +\fIdistribuiзгo/componente\fP\&. Tipicamente, \fIdistribuiзгo\fP й um +dentre \fIstable\fP, \fIunstable\fP ou \fIfrozen\fP, enquanto o +componente й um dos \fImain\fP, \fIcontrib\fP, \fInon-free\fP ou +\fInon-us\fP\&. O tipo \fBdeb-src\fP descreve um cуdigo-fonte da +distribuiзгo debian da mesma forma do tipo \fBdeb\fP\&. Uma linha +\fBdeb-src\fP й necessбria para obter нndices de fonte\&. +O formato para uma entrada \fBsources\&.list\fP usando os tipos +\fIdeb\fP e \fIdeb-src\fP sгo: + +.nf + +deb uri distribution [componente1] [componente2] [\&.\&.\&.] +.fi + + +O URI para o tipo \fIdeb\fP deve especificar a base da distribuiзгo Debian, +de onde \fBAPT\fP encontrarб as informaзхes que ele +precisa\&. \fIdistribution\fP pode especificar um caminho exato, neste +caso o \fIcomponent\fPs deve ser omitido e \fBdistribution\fP deve +terminar com uma barra (/)\&. Isto й ъtil para quando hб interesse em +apenas uma sub-seзгo particular do arquivo denotado pelo URI\&. Se +\fBdistribution\fP nгo especificar um caminho exato, pelo menos um +\fBcomponent\fP deve estar presente\&. +.PP +\fBdistribution\fP tambйm pode conter uma variбvel, \fB$(ARCH)\fP, +que expande para a arquitetura Debian (i386, m68k, powerpc, \&.\&.\&.) +usada no sistema\&. Isto permite o uso dos arquivos +\fBsources\&.list\fP independentes da arquitetura\&. Em geral, isto sу +й interessante ao especificar um caminho exato, caso contrбrio +\fBAPT\fP irб gerar automaticamente um URI com a arquitetura atual\&. +.PP +Uma vez que apenas uma distribuiзгo pode ser especificada por linha, +por ser necessбrio ter linhas mъltiplas para o mesmo URI, se um +subconjunto de todas as distribuiзхes ou componentes disponнveis nesta +localizaзгo for desejado\&. \fBAPT\fP classificarб a lista de URI apуs +ter criado um conjunto completo internamente, e irб reduzir as mъltiplas referкncias ao mesmo servidor de Internet, por exemplo, em uma conexгo simples, dessa forma nгo estabelece de forma ineficiente uma conexгo FTP, a fecha, faz mais alguma coisa e depois restabelece uma conexгo para o mesmo servidor\&. Este serviзo й ъtil para acesso a sites FTP ocupados com limites no nъmero de usuбrios anфnimos simultвneos\&. \fBAPT\fP tambйm paralisa conexхes para diferentes servidores para lidar com sites de baixa largura de banda com mais eficбcia\&. +.PP +Й importante listar os fontes em ordem de preferкncia, sendo o fonte mais preferido listado primeiro\&. Isto resultarб tipicamente na classificaзгo por velocidade do mais rбpido para o mais lento (CD-ROM seguido por servidores em uma rede local, seguido por servidores de Internet distantes, por exemplo)\&. +.PP +Alguns exemplos: + +.nf + +deb http://http\&.us\&.debian\&.org/debian stable main contrib non-free +.fi + + + +.nf + +deb http://http\&.us\&.debian\&.org/debian dists/stable-updates +.fi + +.PP +.SH "The rpm and rpm-src types" +O tipo \fBrpm\fP descreve um repositуrio de distribuiзгo baseado em RPM, dividido em dois nнveis, \fIdistribuiзгo\fP e \fIcomponente\fP. +\fIDistribuiзгo\fP й composto tipicamente pela versгo da distribuiзгo e o nome do fornecedor, tal como \fI6.0/conectiva\fP. +\fIComponente\fP й o nome do componente, tal como o tipo \fBrpm-src\fP descreve o cуdigo-fonte da distribuiзгo\ da mesma forma que o tipo \fBrpm\fP\&. Uma linha \fBrpm-src\fP й requerida para obter os нndices-fonte\&. +O formato para uma entrada \fBsources\&.list\fP usando os tipos \fIrpm\fP +e \fIrpm-src\fP sгo: + +.nf + +rpm [\&[fornecedor\&]] uri distribution [componente1] [componente2] [\&.\&.\&.] +.fi + + +O URI para o tipo \fIrpm\fP deve especificar a base da distribuiзгo a partir do qual \fBAPT\fP encontrarб a informaзгo necessбria\&. +Pelo menos um \fBcomponent\fP deve estar presente\&. +.PP +Jб que apenas uma distribuiзгo pode ser especificada por linha, pode ser necessбrio ter linhas mъltiplas para o mesmo URI, se for desejado um subconjunto de todas as distribuiзхes ou componentes disponнveis no mesmo local\&. +\fBAPT\fP classificarб a lista de URI apуs ela ter gerado um conjunto completo internamente e irб reduzir referкncias mъltiplas para o mesmo servidor de Internet, por exemplo, em uma conexгo simples, dessa forma nгo estabelece de forma ineficiente uma conexгo FTP, a fecha, faz mais alguma coisa e depois restabelece uma conexгo para o mesmo servidor\&. Este serviзo й ъtil para acesso a sites FTP ocupados com limites no nъmero de usuбrios anфnimos simultвneos\&. \fBAPT\fP tambйm paralisa conexхes para diferentes servidores para lidar com sites de baixa largura de banda com mais eficбcia\&. +.PP +Й importante listar os fontes em ordem de preferкncia, sendo o fonte mais preferido listado primeiro\&. Isto resultarб tipicamente na classificaзгo por velocidade do mais rбpido para o mais lento (CD-ROM seguido por servidores em uma rede local, seguido por servidores de Internet distantes, por exemplo)\&. +.PP +Alguns exemplos: + +.nf + +rpm ftp://ftp\&.conectiva\&.com/pub/conectiva/.0 6.0/conectiva main extra non-us non-free +.fi + + +.PP +.SH "Autenticaзгo-mirror de repositуrio" +Ao usar um mirror para uma distribuiзгo, existe o risco do mantenedor do site infiltrar pacotes maliciosos dentro dele, comprometendo a seguranзa de todos os sistemas que usam este site como um fonte de pacote. Para reduzir a possibilidade de situaзхes como esta, o apt pode autenticar os repositуrios de pacote. Observe que a autenticaзгo NГO garante que os conteъdos de um repositуrio sejam completamente seguros. Pode apenas verificar se: +.IP o +todos os pacotes no repositуrio tкm um checksum vбlido, em relaзгo ao conteъdo da lista de pacotes; + +.IP o +todos os pacotes que sгo conhecidos para a lista de pacotes podem ser baixados pelo apt-get; + +.IP o +todas as listas de pacotes tкm um checksum correto, em relaзгo ao conteъdo de um arquivo de нndice; + +.IP o +o arquivo de нndice й assinado digitalmente pelo fornecedor identificado em +\fBsources.list\fP e a assinatura digital gpg correspondente gpg em +\fBvendors.list\fP\&. + +.PP +Pode verificar se um site que espelha um repositуrio tem os mesmos conteъdos do site original. +.PP +Consulte \fBvendors.list\fP (5) para mais informaзхes sobre como configurar a autenticaзгo. + + +.PP +.SH "Especificaзгo de URI" +Os tipos de URI atualmente reconhecidos sгo cd-rom, arquivo, http e ftp\&. +.PP +.IP "\fBarquivo\fP" +O esquema de arquivos permite um diretуrio arbitrбrio no sistema de arquivos a ser considerado como um arquivo\&. Isto й ъtil para montagem de NFS e mirros ou arquivos locais\&. +.IP +.IP "\fBc-drom\fP" +O esquema de cd-rom permite que o \fBAPT\fP use um drive de CD-ROM local com troca de meio\&. Use o programa \fBapt-cdrom(8)\fP para criar todo o cd-rom na lista de fontes\&. +.IP +.IP "\fBhttp\fP" +O esquema http especifica um servidor HTTP para o arquivo\&. Se uma variбvel de ambiente \fB$http_proxy\fP for configurada com o formato +\fBhttp://server:port/\fP, o servidor proxy especificado em +\fB$http_proxy\fP serб usado\&. Os usuбrios dos proxies HTTP/1\&.1 autenticados podem usar uma string com o formato \fBhttp://user:pass@server:port/\fP +Observe que este nгo й um mйtodo seguro de autenticaзгo\&. +.IP +.IP "\fBftp\fP" +O esquema ftp especifica um servidor FTP para o arquivo\&. O comportamento FTP do APT й altamente configurбvel. Para maiores informaзхes consulte a pбgina de manual \fBapt\&.conf(5)\fP\&. Por favor observe que um proxy ftp pode ser especificado usando a variбvel de ambiente ftp_proxy\&. Й possнvel especificar um proxy http (servidores proxy http muitas vezes compreendem urls ftp) usando este mйtodo e SOMENTE este mйtodo\&. Os proxies ftp usando http especificado no arquivo de configuraзгo serгo ignorados\&. +.IP +.IP "\fBcуpia\fP" +O esquema de cуpia й idкntico ao esquema de arquivo exceto que os pacotes sгo copiados para o diretуrio de cache em vez de serem usados diretamente em sua localizaзгo\&. Isto й ъtil para pessoas que usam um disco de zip para copiar arquivos com o APT\&. +.IP +.PP +.SH "EXEMPLOS" +Usa o arquivo armazenado localmente (ou NFS montado) em /home/jason/debian +para stable/main, stable/contrib e stable/non-free\&. +.RS +"deb file:/home/jason/debian stable main contrib non-free" +.RE +.PP +Como o acima, exceto que este usa a distribuiзгo instбvel (desenvolvimento)\&. +.RS +"deb file:/home/jason/debian unstable main contrib non-free" +.RE +.PP +Linha do fonte para o acima +.RS +"deb-src file:/home/jason/debian unstable main contrib non-free" +.RE +.PP +Usa HTTP para acessar o arquivo no arquivo \&.debian\&.org e usa apenas a бrea hamm/main\&. +.RS +"deb http://archive\&.debian\&.org/debian-archive hamm main" +.RE +.PP +Usa FTP para acessar o arquivo em ftp\&.debian\&.org, no diretуrio debian +e usa apenas a бrea stable/contrib\&. +.RS +"deb ftp://ftp\&.debian\&.org/debian stable contrib" +.RE +.PP +Uses FTP to access the archive at ftp\&.conectiva\&.com, under the +/pub/conectiva directory, for version 6.0 of the conectiva distribution +and the main component\&. +.RS +"rpm ftp://ftp\&.conectiva\&.cpm/pub/conectiva 6.0/conectiva main" +.RE +.PP +Usa FTP para acessar o arquivo em ftp\&.debian\&.org, no diretуrio debian +e usa apenas a бrea unstable/contrib\&. Se esta linha aparecer bem +como aquela no exemplo anterior em \fBsources\&.list\fP, +uma sessгo FTP simples serб usada para ambas as linhas de recurso\&. +.RS +"deb ftp://ftp\&.debian\&.org/debian unstable contrib" +.RE +.PP +Usa HTTP para acessar o arquivo em ###nonus\&.debian\&.org, no diretуrio que nгo й o da debian-US\&. +.RS +"deb http://nonus\&.debian\&.org/debian-non-US stable/non-US main contrib non-free" +.RE +.PP +O mesmo que o acima, mas com a autenticaзгo contra o fornecedor chamado \fIbla\fP, que deveria estar relacionado em \fBvendors\&.list\fP\&. +.RS +"deb [bla] http://nonus\&.debian\&.org/debian-non-US stable/non-US main contrib non-free" +.RE +.PP +Usa HTTP para acessar o arquivo em ###nonus\&.debian\&.org, no diretуrio que nгo й o da debian-US, e usa apenas os arquivos encontrados em unstable/binary-i386 em computadores i386, unstable/binary-m68k em m68k e assim por diante para outras arquiteturas suportadas\&. [Observe que este exemplo apenas ilustra como usar a variбvel ##substitation non-us nгo estб mais estruturada como este] +.RS +"deb http://ftp\&.de\&.debian\&.org/debian-non-US unstable/binary-$(ARCH)/" +.RE +.PP +.SH "CONSULTE TAMBЙM" +apt-cache (8), +apt\&.conf (5) +vendors\&.list (5) +.PP +.SH "BUGS" +Consulte http://bugs\&.debian\&.org/apt\&. Caso queira reportar um bug em \fBapt-get\fP, por favor veja \fB/usr/doc/debian/bug-reporting\&.txt\fP +ou o comando \fBbug(1)\fP\&. Se estiver usando o apt em um sistema baseado em RPM, por favor use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTOR" +O apt foi escrito pelo time do APT +e atualizado para os sistemas baseados em RPM por +Conectiva S.A. + diff --git a/apt/doc/pt_BR/vendors.list.5 b/apt/doc/pt_BR/vendors.list.5 new file mode 100644 index 0000000..d08a3ef --- /dev/null +++ b/apt/doc/pt_BR/vendors.list.5 @@ -0,0 +1,78 @@ +.TH "vendors\&.list" "5" "25 Out 2000" "apt" "" +.SH "NOME" +vendors\&.list \- package vendor list for APT +.PP +.SH "DESCRIЗГO" +A lista do fornecedor do pacote contйm uma lista de todos os fornecedores +dos quais vocк deseja autenticar pacotes que foram baixados. Para cada +fornecedor listado deve conter a impressгo de chave GPG correspondente, +para que o apt possa realizar verificaзгo de assinatura do arquivo hash +de нndice (hashfile) +e verificaзгo subseqьente da verificaзгo de cada pacote baixado. +Para ter autenticaзгo habilitada, vocк deverб adicionar a string de +identificaзгo do fornecedor (veja abaixo) entre colchetes para a +linha \fBsources.list\fP para todos os sites que espelham o repositуrio +fornecido para aquele fornecedor. +O formato deste arquivo й semelhante ao usado em \fBapt.conf\fP\&. +Constitui-se de um nъmero arbitrбrio de blocos de fornecedores, +onde cada bloco inicia com uma string informando +.RI key_type +e o +.RI vendor_id +\&. + +.RI key_type +й o tipo de chave do fornecedor a ser definido. Atualmente existe +somente um tipo disponнvel, o qual й \fBsimple-key\fP\&. + +.RI vendor_id +й a string de identificaзгo do fornecedor. Й uma string arbitrбria que +deve ser fornecida para identificar um fornecedor que estб listdo neste +arquivo. + +.PP +.SH "simple-key" +Esta chave й composta de dois campos, +\fIFingerprint\fP +e +\fIName\fP +\&. Ambos sгo obrigatуrios\&. + + +\fIFingerprint\fP +й a impressгo de chave-publica gpg(1) para o fornecedor, incluнda em +TODAS EM MAIЪSCULAS\&. +A impressгo pode ser obtida com a opзгo --fingerprint da gpg\&. + +\fIName\fP +й uma string contendo uma descriзгo do dono da chave ou fornecedor\&. +Vocк poderб colocar o nome e email do fornecedor. A string deve estar +destacada com "\&. + +.PP +Exemplo: +.nf +single_key "joe" +{ + Fingerprint "0987AB4378FSD872343298787ACC"; + Nome "Joe Shmoe "; +} +.fi +Para mais informaзхes sobre autenticaзгo de repositуrio, consultar fontes\&.list(5)\&. + +.PP +.SH "CONSULTE TAMBЙM" +gpg (1) +sources\&.list (5) +apt-get (8) +.PP +.SH "BUGS" +Consultar http://bugs\&.debian\&.org/apt\&. Se vocк deseja informar sobre um +bug em \fBapt-get\fP, favor consultar \fB/usr/doc/debian/bug-reporting\&.txt\fP +ou o comando\& \fBbug(1)\fP. Se vocк estiver usando o apt em um sistema baseado em RPM, favor usar http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTOR" +apt foi escrito pela equipe do APT +e atualizado para sistemas baseados em RPM pela +Conectiva S.A. + diff --git a/apt/doc/sources.list.5 b/apt/doc/sources.list.5 new file mode 100644 index 0000000..17d7719 --- /dev/null +++ b/apt/doc/sources.list.5 @@ -0,0 +1,278 @@ +.TH "sources\&.list" "5" "25 Oct 2000" "apt" "" +.SH "NAME" +sources\&.list \- package resource list for APT +.PP +.SH "DESCRIPTION" +The package resource list is used to locate archives of the package +distribution system in use on the system\&. +.PP +The source list is designed to support any number of active sources and a +variety of source media\&. The file lists one source per line, with the +most preferred source listed first\&. The format of each line is: +\fItype uri args\fP The first item, \fItype\fP, determines the format for +\fIargs\fP\&. \fIuri\fP is a Universal Resource Identifier (URI), which is a +superset of the more specific and well-known Universal Resource Locator, or +URL\&. +.PP +.SH "The deb and deb-src types" +The \fBdeb\fP type describes a typical two-level Debian archive, +\fIdistribution/component\fP\&. Typically, \fIdistribution\fP is one of +\fIstable\fP, \fIunstable\fP, or \fIfrozen\fP, while component is one of +\fImain\fP, \fIcontrib\fP, \fInon-free\fP, or \fInon-us\fP\&. The \fBdeb-src\fP type +describes a debian distribution\'s source code in the same form as the \fBdeb\fP +type\&. A \fBdeb-src\fP line is required to fetch source indexes\&. +The format for a \fBsources\&.list\fP entry using the \fIdeb\fP and \fIdeb-src\fP +types are: + +.nf + +deb uri distribution [component1] [componenent2] [\&.\&.\&.] +.fi + + +The URI for the \fIdeb\fP type must specify the base of the Debian distribution, +from which \fBAPT\fP will find the information it needs\&. \fIdistribution\fP +can specify an exact path, in which case the \fIcomponent\fPs +must be omitted and \fBdistribution\fP must end with a slash (/)\&. This is +useful for when only a particular sub-section of the archive denoted by the +URI is of interest\&. If \fBdistribution\fP does not specify an exact path, at +least one \fBcomponent\fP must be present\&. +.PP +\fBdistribution\fP may also contain a variable, \fB$(ARCH)\fP, +which expands to the Debian architecture (i386, m68k, powerpc, \&.\&.\&.) +used on the system\&. This permits archiecture-independent +\fBsources\&.list\fP files to be used\&. In general this is only of interest +when specifying an exact path, \fBAPT\fP will automatically generate a URI +with the current architecture otherwise\&. +.PP +Since only one distribution can be specified per line it may be necessary +to have multiple lines for the same URI, if a subset of all available +distributions or components at that location is desired\&. +\fBAPT\fP will sort the URI list after it has generated a complete set +internally, and will collapse multiple references to the same Internet host, +for instance, into a single connection, so that it does not inefficiently +establish an FTP connection, close it, do something else, and then +re-establish a connection to that same host\&. This feature is useful +for accessing busy FTP sites with limits on the number of simultaneous +anonymous users\&. \fBAPT\fP also parallizes connections to different hosts +to more effectively deal with sites with low bandwidth\&. +.PP +It is important to list sources in order of preference, with the most +preferred source listed first\&. Typically this will result in sorting +by speed from fastest to slowest (CD-ROM followed by hosts on a local +network, followed by distant Internet hosts, for example)\&. +.PP +Some examples: + +.nf + +deb http://http\&.us\&.debian\&.org/debian stable main contrib non-free +.fi + + + +.nf + +deb http://http\&.us\&.debian\&.org/debian dists/stable-updates +.fi + +.PP +.SH "The rpm and rpm-src types" +The \fBrpm\fP type describes a RPM based distribution repository, +divided in two levels, \fIdistribution\fP and \fIcomponent\fP. +\fIdistribution\fP is typically composed by the version of the +distribution and the vendor name, such as \fI6.0/conectiva\fP. +\fIcomponent\fP is the name of the component, such as +The \fBrpm-src\fP type describes the distribution\'s source code in +the same form as the \fBrpm\fP +type\&. A \fBrpm-src\fP line is required to fetch source indexes\&. +The format for a \fBsources\&.list\fP entry using the \fIrpm\fP +and \fIrpm-src\fP types are: + +.nf + +rpm [\&[vendor\&]] uri distribution [component1] [componenent2] [\&.\&.\&.] +.fi + + +The URI for the \fIrpm\fP type must specify the base of the distribution, +from which \fBAPT\fP will find the information it needs\&. +At least one \fBcomponent\fP must be present\&. +.PP +Since only one distribution can be specified per line it may be necessary +to have multiple lines for the same URI, if a subset of all available +distributions or components at that location is desired\&. +\fBAPT\fP will sort the URI list after it has generated a complete set +internally, and will collapse multiple references to the same Internet host, +for instance, into a single connection, so that it does not inefficiently +establish an FTP connection, close it, do something else, and then +re-establish a connection to that same host\&. This feature is useful +for accessing busy FTP sites with limits on the number of simultaneous +anonymous users\&. \fBAPT\fP also parallizes connections to different hosts +to more effectively deal with sites with low bandwidth\&. +.PP +It is important to list sources in order of preference, with the most +preferred source listed first\&. Typically this will result in sorting +by speed from fastest to slowest (CD-ROM followed by hosts on a local +network, followed by distant Internet hosts, for example)\&. +.PP +Some examples: + +.nf + +rpm ftp://ftp\&.conectiva\&.com/pub/conectiva/.0 6.0/conectiva main extra non-us non-free +.fi + + +.PP +.SH "Repository Mirror Authentication" +When you use a mirror for a distribution, there is the risk +that a site keeper infiltrates malicious packages in it, +compromising the security of all systems that use such site +as a package source. To reduce possibility of situations like +that, apt can authenticate package repositories. Note that +authentication DOES NOT guarantee that the contents of a repository +is completely secure. It can only verify that: +.IP o +all packages in the repository have a valid checksum, in relation +to what is contained in the package list; + +.IP o +only packages that are known to the package list are downloadable +by apt-get; + +.IP o +all package lists have a correct checksum, in relation to what +is contained in a index file; + +.IP o +the index file is digitally signed by the vendor identified in +\fBsources.list\fP and the corresponding gpg fingerprint in +\fBvendors.list\fP\&. + +.PP +That can verify that a site that mirrors a repository +has the same contents as the original site. +.PP +See \fBvendors.list\fP (5) for more information about how to setup +authentication. + + +.PP +.SH "URI specification" +The currently recognized URI types are cdrom, file, http, and ftp\&. +.PP +.IP "\fBfile\fP" +The file scheme allows an arbitrary directory in the file system to be +considered an archive\&. This is useful for NFS mounts and local mirrors or +archives\&. +.IP +.IP "\fBcdrom\fP" +The cdrom scheme allows \fBAPT\fP to use a local CDROM drive with media +swapping\&. Use the \fBapt-cdrom(8)\fP program to create cdrom entires in the +source list\&. +.IP +.IP "\fBhttp\fP" +The http scheme specifies an HTTP server for the archive\&. If an environment +variable \fB$http_proxy\fP is set with the format +\fBhttp://server:port/\fP, the proxy server specified in +\fB$http_proxy\fP will be used\&. Users of authenticated HTTP/1\&.1 proxies may +use a string of the format \fBhttp://user:pass@server:port/\fP +Note that this is an insecure method of authentication\&. +.IP +.IP "\fBftp\fP" +The ftp scheme specifies an FTP server for the archive\&. APT\'s FTP behavior +is highly configurable; for more information see the +\fBapt\&.conf(5)\fP manual page\&. Please note that a ftp proxy can be specified +by using the ftp_proxy environment variable\&. It is possible to specify a http +proxy (http proxy servers often understand ftp urls) using this method and +ONLY this method\&. ftp proxies using http specified in the configuration +file will be ignored\&. +.IP +.IP "\fBcopy\fP" +The copy scheme is identical to the file scheme except that packages are +copied into the cache directory instead of used directly at their location\&. +This is usefull for people using a zip disk to copy files around with APT\&. +.IP +.PP +.SH "EXAMPLES" +Uses the archive stored locally (or NFS mounted) at /home/jason/debian +for stable/main, stable/contrib, and stable/non-free\&. +.RS +"deb file:/home/jason/debian stable main contrib non-free" +.RE +.PP +As above, except this uses the unstable (development) distribution\&. +.RS +"deb file:/home/jason/debian unstable main contrib non-free" +.RE +.PP +Source line for the above +.RS +"deb-src file:/home/jason/debian unstable main contrib non-free" +.RE +.PP +Uses HTTP to access the archive at archive\&.debian\&.org, and uses only the +hamm/main area\&. +.RS +"deb http://archive\&.debian\&.org/debian-archive hamm main" +.RE +.PP +Uses FTP to access the archive at ftp\&.debian\&.org, under the debian +directory, and uses only the stable/contrib area\&. +.RS +"deb ftp://ftp\&.debian\&.org/debian stable contrib" +.RE +.PP +Uses FTP to access the archive at ftp\&.conectiva\&.com, under the +/pub/conectiva directory, for version 6.0 of the conectiva distribution +and the main component\&. +.RS +"rpm ftp://ftp\&.conectiva\&.cpm/pub/conectiva 6.0/conectiva main" +.RE +.PP +Uses FTP to access the archive at ftp\&.debian\&.org, under the debian +directory, and uses only the unstable/contrib area\&. If this line appears as +well as the one in the previous example in \fBsources\&.list\fP, +a single FTP session will be used for both resource lines\&. +.RS +"deb ftp://ftp\&.debian\&.org/debian unstable contrib" +.RE +.PP +Uses HTTP to access the archive at nonus\&.debian\&.org, under the debian-non-US +directory\&. +.RS +"deb http://nonus\&.debian\&.org/debian-non-US stable/non-US main contrib non-free" +.RE +.PP +Same as above, but with authentication against the vendor named \fIbla\fP, +which should be listed in \fBvendors\&.list\fP\&. +.RS +"deb [bla] http://nonus\&.debian\&.org/debian-non-US stable/non-US main contrib non-free" +.RE +.PP +Uses HTTP to access the archive at nonus\&.debian\&.org, under the +debian-non-US directory, and uses only files found under +unstable/binary-i386 on i386 machines, unstable/binary-m68k on m68k, and so +forth for other supported architectures\&. [Note this example only illustrates +how to use the substitution variable non-us is no longer structured like this] +.RS +"deb http://ftp\&.de\&.debian\&.org/debian-non-US unstable/binary-$(ARCH)/" +.RE +.PP +.SH "SEE ALSO" +apt-cache (8), +apt\&.conf (5) +vendors\&.list (5) +.PP +.SH "BUGS" +See http://bugs\&.debian\&.org/apt\&. If you wish to report a +bug in \fBapt-get\fP, please see \fB/usr/doc/debian/bug-reporting\&.txt\fP +or the \fBbug(1)\fP command\&. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt was written by the APT team +and updated for RPM based systems by +Alfredo K. Kojima, Conectiva S.A. + diff --git a/apt/doc/sources.list.5.yo b/apt/doc/sources.list.5.yo new file mode 100644 index 0000000..2a501f7 --- /dev/null +++ b/apt/doc/sources.list.5.yo @@ -0,0 +1,148 @@ +mailto(apt@packages.debian.org) +manpage(sources.list)(5)(5 Dec 1998)(apt)() +manpagename(sources.list)(package resource list for APT) + +manpagedescription() +The package resource list is used to locate archives of the package +distribution system in use on the system. At this time, this manual page +documents only the packaging system used by the Debian GNU/Linux system. + +The source list is designed to support any number of active sources and a +variety of source media. The file lists one source per line, with the +most preferred source listed first. The format of each line is: +em(type uri args) The first item, em(type), determines the format for +em(args). em(uri) is a Universal Resource Identifier (URI), which is a +superset of the more specific and well-known Universal Resource Locator, or +URL. + +manpagesection(The deb and deb-src types) +The bf(deb) type describes a typical two-level Debian archive, +em(distribution/component). Typically, em(distribution) is one of +em(stable), em(unstable), or em(frozen), while component is one of +em(main), em(contrib), em(non-free), or em(non-us). The bf(deb-src) type +describes a debian distribution's source code in the same form as the bf(deb) +type. A bf(deb-src) line is required to fetch source indexes. +The format for a bf(sources.list) entry using the em(deb) and em(deb-src) +types are: +verb(deb uri distribution [component1] [componenent2] [...]) +The URI for the em(deb) type must specify the base of the Debian distribution, +from which bf(APT) will find the information it needs. em(distribution) +can specify an exact path, in which case the em(component)s +must be omitted and bf(distribution) must end with a slash (/). This is +useful for when only a particular sub-section of the archive denoted by the +URI is of interest. If bf(distribution) does not specify an exact path, at +least one bf(component) must be present. + +bf(distribution) may also contain a variable, bf($(ARCH)), +which expands to the Debian architecture (i386, m68k, powerpc, ...) +used on the system. This permits archiecture-independent +bf(sources.list) files to be used. In general this is only of interest +when specifying an exact path, bf(APT) will automatically generate a URI +with the current architecture otherwise. + +Since only one distribution can be specified per line it may be necessary +to have multiple lines for the same URI, if a subset of all available +distributions or components at that location is desired. +bf(APT) will sort the URI list after it has generated a complete set +internally, and will collapse multiple references to the same Internet host, +for instance, into a single connection, so that it does not inefficiently +establish an FTP connection, close it, do something else, and then +re-establish a connection to that same host. This feature is useful +for accessing busy FTP sites with limits on the number of simultaneous +anonymous users. bf(APT) also parallizes connections to different hosts +to more effectively deal with sites with low bandwidth. + +It is important to list sources in order of preference, with the most +preferred source listed first. Typically this will result in sorting +by speed from fastest to slowest (CD-ROM followed by hosts on a local +network, followed by distant Internet hosts, for example). + +Some examples: +verb(deb http://http.us.debian.org/debian stable main contrib non-free) +verb(deb http://http.us.debian.org/debian dists/stable-updates) + +manpagesection(URI specification) +The currently recognized URI types are cdrom, file, http, and ftp. + +startdit() +dit(bf(file)) +The file scheme allows an arbitrary directory in the file system to be +considered an archive. This is useful for NFS mounts and local mirrors or +archives. + +dit(bf(cdrom)) +The cdrom scheme allows bf(APT) to use a local CDROM drive with media +swapping. Use the bf(apt-cdrom(8)) program to create cdrom entires in the +source list. + +dit(bf(http)) +The http scheme specifies an HTTP server for the archive. If an environment +variable bf($http_proxy) is set with the format +bf(http://server:port/), the proxy server specified in +bf($http_proxy) will be used. Users of authenticated HTTP/1.1 proxies may +use a string of the format bf(http://user:pass@server:port/) +Note that this is an insecure method of authentication. + +dit(bf(ftp)) +The ftp scheme specifies an FTP server for the archive. APT's FTP behavior +is highly configurable; for more information see the +bf(apt.conf(5)) manual page. Please note that a ftp proxy can be specified +by using the ftp_proxy environment variable. It is possible to specify a http +proxy (http proxy servers often understand ftp urls) using this method and +ONLY this method. ftp proxies using http specified in the configuration +file will be ignored. + +dit(bf(copy)) +The copy scheme is identical to the file scheme except that packages are +copied into the cache directory instead of used directly at their location. +This is usefull for people using a zip disk to copy files around with APT. + +enddit() + +manpagesection(EXAMPLES) +Uses the archive stored locally (or NFS mounted) at /home/jason/debian +for stable/main, stable/contrib, and stable/non-free. +quote("deb file:/home/jason/debian stable main contrib non-free") + +As above, except this uses the unstable (development) distribution. +quote("deb file:/home/jason/debian unstable main contrib non-free") + +Source line for the above +quote("deb-src file:/home/jason/debian unstable main contrib non-free") + +Uses HTTP to access the archive at archive.debian.org, and uses only the +hamm/main area. +quote("deb http://archive.debian.org/debian-archive hamm main") + +Uses FTP to access the archive at ftp.debian.org, under the debian +directory, and uses only the stable/contrib area. +quote("deb ftp://ftp.debian.org/debian stable contrib") + +Uses FTP to access the archive at ftp.debian.org, under the debian +directory, and uses only the unstable/contrib area. If this line appears as +well as the one in the previous example in bf(sources.list), +a single FTP session will be used for both resource lines. +quote("deb ftp://ftp.debian.org/debian unstable contrib") + +Uses HTTP to access the archive at nonus.debian.org, under the debian-non-US +directory. +quote("deb http://nonus.debian.org/debian-non-US stable/non-US main contrib non-free") + +Uses HTTP to access the archive at nonus.debian.org, under the +debian-non-US directory, and uses only files found under +unstable/binary-i386 on i386 machines, unstable/binary-m68k on m68k, and so +forth for other supported architectures. [Note this example only illistrates +how to use the substitation variable non-us is no longer structured like this] +quote("deb http://ftp.de.debian.org/debian-non-US unstable/binary-$(ARCH)/") + +manpageseealso() +apt-cache (8), +apt.conf (5) + +manpagebugs() +See http://bugs.debian.org/apt. If you wish to report a +bug in bf(apt-get), please see bf(/usr/doc/debian/bug-reporting.txt) +or the bf(bug(1)) command. + +manpageauthor() +apt-get was written by the APT team . diff --git a/apt/doc/vendors.list.5 b/apt/doc/vendors.list.5 new file mode 100644 index 0000000..b796dfd --- /dev/null +++ b/apt/doc/vendors.list.5 @@ -0,0 +1,77 @@ +.TH "vendors\&.list" "5" "25 Oct 2000" "apt" "" +.SH "NAME" +vendors\&.list \- package vendor list for APT +.PP +.SH "DESCRIPTION" +The package vendor list contains a list of all vendors from whom +you wish to authenticate downloaded packages. For each vendor listed, +it must contain the corresponding GPG key fingerprint, so that apt +can perform signature verification of the index hash file (hashfile) +and subsequent checking of the checksums of each downloaded package\&. +To have authentication enabled, you must add the vendor identification +string (see below) enclosed in braces to the \fBsources\&.list\fP line +for all sites that mirror the repository provided for that vendor\&. + +The format of this file is similar to the one used in \fBapt.conf\fP\&. +It consists of an arbitrary number of blocks of vendors, where each +block starts with a string telling the +.RI key_type +and the +.RI vendor_id +\&. + +.RI key_type +is the type of the key of the vendor being defined. Currently, +there is only one type available, which is \fBsimple-key\fP\&. + +.RI vendor_id +is the vendor identification string. It is an arbitrary string you +must supply to uniquely identifify a vendor that's listed in this file. + +.PP +.SH "simple-key" +This key type is composed of two fields, +\fIFingerprint\fP +and +\fIName\fP +\&. Both are mandatory\&. + + +\fIFingerprint\fP +is the gpg(1) public key fingerprint for the vendor, enclosed in " and +in ALL CAPS\&. +The fingerprint can be obtained with the --fingerprint option of gpg\&. + +\fIName\fP +is a string containing a description of the owner of the key or vendor\&. +You may put the vendor name and it's email. The string must be quoted +with "\&. + +.PP +Example: +.nf +simple-key "joe" +{ + Fingerprint "0987AB4378FSD872343298787ACC"; + Name "Joe Shmoe "; +} +.fi +For more information about repository authentication see sources\&.list(5)\&. + +.PP +.SH "SEE ALSO" +gpg (1) +sources\&.list (5) +apt-get (8) +.PP +.SH "BUGS" +See http://bugs\&.debian\&.org/apt\&. If you wish to report a +bug in \fBapt-get\fP, please see \fB/usr/doc/debian/bug-reporting\&.txt\fP +or the \fBbug(1)\fP command\&. If you are using apt on a RPM based +system, please use http://distro\&.conectiva\&.com\&.br/bugzilla/\&. +.PP +.SH "AUTHOR" +apt was written by the APT team +and updated for RPM based systems by +Conectiva S.A. + diff --git a/apt/docs.tar.gz b/apt/docs.tar.gz new file mode 100644 index 0000000..6ad9a58 Binary files /dev/null and b/apt/docs.tar.gz differ diff --git a/apt/dselect/CVS/Entries b/apt/dselect/CVS/Entries new file mode 100644 index 0000000..1dd0cf7 --- /dev/null +++ b/apt/dselect/CVS/Entries @@ -0,0 +1,7 @@ +/desc.apt/1.1.1.1/Fri Aug 10 14:01:51 2001// +/install/1.1.1.1/Fri Aug 10 14:01:51 2001// +/makefile/1.1.1.1/Fri Aug 10 14:01:51 2001// +/names/1.1.1.1/Fri Aug 10 14:01:51 2001// +/setup/1.1.1.1/Fri Aug 10 14:01:51 2001// +/update/1.1.1.1/Fri Aug 10 14:01:51 2001// +D diff --git a/apt/dselect/CVS/Repository b/apt/dselect/CVS/Repository new file mode 100644 index 0000000..a1dbedc --- /dev/null +++ b/apt/dselect/CVS/Repository @@ -0,0 +1 @@ +rapt/dselect diff --git a/apt/dselect/CVS/Root b/apt/dselect/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/dselect/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/dselect/desc.apt b/apt/dselect/desc.apt new file mode 100644 index 0000000..c79e3c8 --- /dev/null +++ b/apt/dselect/desc.apt @@ -0,0 +1,9 @@ +The APT installation method encompasses most other installation methods +under the umbrella of the new Package Acquisition code. This method allows +installation from locations in the filesystem, ftp and http URLs, supports +full installation ordering and dependency checking as well as multiple +sources. See the man pages apt-get(8) and sources.list(5) + +HTTP proxies can be used by setting http_proxy="http://proxy:port/" before +running DSelect. FTP proxies require special configuration detailed in +the apt.conf(5) man page (see /usr/doc/apt/examples/apt.conf) diff --git a/apt/dselect/install b/apt/dselect/install new file mode 100755 index 0000000..8ac3523 --- /dev/null +++ b/apt/dselect/install @@ -0,0 +1,98 @@ +#!/bin/sh + +# Get the configuration from /etc/apt/apt.conf +CLEAN="prompt" +OPTS="-f" +APTGET="/usr/bin/apt-get" +DPKG="/usr/bin/dpkg" +set -e +RES=`apt-config shell CLEAN DSelect::Clean OPTS DSelect::Options \ + DPKG Dir::Bin::dpkg APTGET Dir::Bin::apt-get \ + ARCHIVES Dir::Cache::Archives/ \ + WAIT DSelect::WaitAfterDownload` +eval $RES +set +e + +# Yes/No Prompter +yesno() { +# $1 = prompt +# $2 = default(y) + local ans def defp + if [ "$2" ];then + case $2 in + Y|y) defp="[Y/n]" def=y;; + N|n) defp="[y/N]" def=n;; + *) echo "Bad default setting!" 1>&2; exit 1;; + esac + else + defp="[y/N]" def=n + fi + while :;do + echo -n "$1 $defp " 1>&3 + read ans + case $ans in + Y|y|N|n) break;; + "") ans=$def;break;; + esac + echo + done + echo $ans | tr YN yn +} + +OLDLS=`ls -ld $ARCHIVES` +if [ x$WAIT = "xyes" ]; then + $APTGET $OPTS -d dselect-upgrade + echo "Press enter to continue." && read RES + $APTGET $OPTS dselect-upgrade + RES=$? +else + $APTGET $OPTS dselect-upgrade + RES=$? +fi + +# 1 means the user choose no at the prompt +if [ $RES -eq 1 ]; then + exit 0 +fi + +# Finished OK +if [ $RES -eq 0 ]; then + + if [ `ls $ARCHIVES $ARCHIVES/partial | egrep -v "^lock$|^partial$" | wc -l` \ + -eq 0 ]; then + exit 0 + fi + + NEWLS=`ls -ld $ARCHIVES` + if [ "x$OLDLS" = "x$NEWLS" ]; then + exit 0 + fi + + # Check the cleaning mode + case `echo $CLEAN | tr '[:upper:]' '[:lower:]'` in + auto) + $APTGET autoclean && echo "Press enter to continue." && read RES && exit 0; + ;; + always) + $APTGET clean && echo "Press enter to continue." && read RES && exit 0; + ;; + prompt) + exec 3>&1 + if [ `yesno "Do you want to erase the downloaded .deb files?" y` = y ]; then + $APTGET clean && echo "Press enter to continue." && read RES && exit 0; + fi + ;; + *) + ;; + esac +else + echo "Some errors occurred while unpacking. I'm going to configure the" + echo "packages that were installed. This may result in duplicate errors" + echo "or errors caused by missing dependencies. This is OK, only the errors" + echo "above this message are important. Please fix them and run [I]nstall again" + echo "Press enter to continue." + read RES && $DPKG --configure -a + exit 100 +fi + +exit $? diff --git a/apt/dselect/makefile b/apt/dselect/makefile new file mode 100644 index 0000000..f4a781e --- /dev/null +++ b/apt/dselect/makefile @@ -0,0 +1,12 @@ +# -*- make -*- +BASE=.. +SUBDIR=dselect + +# Bring in the default rules +include ../buildlib/defaults.mak + +# DSelect interfacing directory +SOURCE = desc.apt install names setup update +TO = $(BUILD)/scripts/dselect +include $(COPY_H) + diff --git a/apt/dselect/names b/apt/dselect/names new file mode 100644 index 0000000..8daa537 --- /dev/null +++ b/apt/dselect/names @@ -0,0 +1 @@ +70 apt APT Acquisition [file,http,ftp] diff --git a/apt/dselect/setup b/apt/dselect/setup new file mode 100755 index 0000000..8386d90 --- /dev/null +++ b/apt/dselect/setup @@ -0,0 +1,286 @@ +#!/usr/bin/perl -w +# -*- Mode: Perl -*- +# setup.pl --- +# Author : Manoj Srivastava ( srivasta@tiamat.datasync.com ) +# Created On : Wed Mar 4 15:11:47 1998 +# Created On Node : tiamat.datasync.com +# Last Modified By : Manoj Srivastava +# Last Modified On : Tue May 19 11:25:32 1998 +# Last Machine Used: tiamat.datasync.com +# Update Count : 87 +# Status : Unknown, Use with caution! +# HISTORY : +# Description : +# This file is designed to go into /usr/lib/apt/methods/setup +# + +#use strict; +#use diagnostics; +#printf STDERR "DEBUG: Arguments $ARGV[0];$ARGV[1];$ARGV[2];\n"; + + +# Handle the arguments +my $vardir=$ARGV[0]; +my $method=$ARGV[1]; +my $option=$ARGV[2]; +my $config_file = '/etc/apt/sources.list'; + +my $boldon=`setterm -bold on`; +my $boldoff=`setterm -bold off`; + +my @known_types = ('deb'); +my @known_access = ('http', 'ftp', 'file'); +my @typical_distributions = ('stable', 'unstable', 'frozen', 'non-US'); +my @typical_components = ('main', 'contrib', 'non-free'); + +my %known_access = map {($_,$_)} @known_access; +my %typical_distributions = map {($_,$_)} @typical_distributions; + +# Read the config file, creating source records +sub read_config { + my %params = @_; + my @Config = (); + + die "Required parameter Filename Missing" unless + $params{'Filename'}; + + open (CONFIG, "$params{'Filename'}") || + die "Could not open $params{'Filename'}: $!"; + while () { + chomp; + my $rec = {}; + my ($type, $urn, $distribution, $components) = + m/^\s*(\S+)\s+(\S+)\s+(\S+)\s*(?:\s+(\S.*))?$/o; + $rec->{'Type'} = $type; + $rec->{'URN'} = $urn; + $rec->{'Distribution'} = $distribution; + $rec->{'Components'} = $components; + push @Config, $rec; + } + close(CONFIG); + + return @Config; +} + +# write the config file; writing out the current set of source records +sub write_config { + my %params = @_; + my $rec; + my %Seen = (); + + die "Required parameter Filename Missing" unless + $params{'Filename'}; + die "Required parameter Config Missing" unless + $params{'Config'}; + + open (CONFIG, ">$params{'Filename'}") || + die "Could not open $params{'Filename'} for writing: $!"; + for $rec (@{$params{'Config'}}) { + my $line = "$rec->{'Type'} $rec->{'URN'} $rec->{'Distribution'} "; + $line .= "$rec->{'Components'}" if $rec->{'Components'}; + $line .= "\n"; + print CONFIG $line unless $Seen{$line}++; + } + close(CONFIG); +} + +# write the config file; writing out the current set of source records +sub print_config { + my %params = @_; + my $rec; + my %Seen = (); + + die "Required parameter Config Missing" unless + $params{'Config'}; + + for $rec (@{$params{'Config'}}) { + next unless $rec; + + my $line = "$rec->{'Type'} " if $rec->{'Type'}; + $line .= "$rec->{'URN'} " if $rec->{'URN'}; + $line .= "$rec->{'Distribution'} " if $rec->{'Distribution'}; + $line .= "$rec->{'Components'}" if $rec->{'Components'}; + $line .= "\n"; + print $line unless $Seen{$line}++; + } +} + +# Ask for and add a source record +sub get_source { + my %params = @_; + my $rec = {}; + my $answer; + my ($type, $urn, $distribution, $components); + + if ($params{'Default'}) { + ($type, $urn, $distribution, $components) = + $params{'Default'} =~ m/^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S.*)$/o; + } + + $type = 'deb'; + $urn = "http://http.us.debian.org/debian" unless $urn; + $distribution = "stable" unless $distribution; + $components = "main contrib non-free" unless $components; + + + $rec->{'Type'} = 'deb'; + $| = 1; + + my $done = 0; + + while (!$done) { + print "\n"; + print "$boldon URL [$urn]: $boldoff"; + + $answer=; + chomp ($answer); + $answer =~ s/\s*//og; + + if ($answer =~ /^\s*$/o) { + $rec->{'URN'} = $urn; + last; + } + else { + my ($scheme) = $answer =~ /^\s*([^:]+):/o; + if (! defined $known_access{$scheme}) { + print "Unknown access scheme $scheme in $answer\n"; + print " The available access methods known to me are\n"; + print join (' ', @known_access), "\n"; + print "\n"; + } + else { + $rec->{'URN'} = $answer; + last; + } + } + } + + print "\n"; + + print " Please give the distribution tag to get or a path to the\n"; + print " package file ending in a /. The distribution\n"; + print " tags are typically something like:$boldon "; + print join(' ', @typical_distributions), "$boldoff\n"; + print "\n"; + print "$boldon Distribution [$distribution]:$boldoff "; + $answer=; + chomp ($answer); + $answer =~ s/\s*//og; + + if ($answer =~ /^\s*$/o) { + $rec->{'Distribution'} = $distribution; + $rec->{'Components'} = &get_components($components); + } + elsif ($answer =~ m|/$|o) { + $rec->{'Distribution'} = "$answer"; + $rec->{'Components'} = ""; + } + else { + # A distribution tag, eh? + warn "$answer does not seem to be a typical distribution tag\n" + unless defined $typical_distributions{$answer}; + + $rec->{'Distribution'} = "$answer"; + $rec->{'Components'} = &get_components($components); + } + + return $rec; +} + +sub get_components { + my $default = shift; + my $answer; + + print "\n"; + print " Please give the components to get\n"; + print " The components are typically something like:$boldon "; + print join(' ', @typical_components), "$boldoff\n"; + print "\n"; + print "$boldon Components [$default]:$boldoff "; + $answer=; + chomp ($answer); + $answer =~ s/\s+/ /og; + + if ($answer =~ /^\s*$/o) { + return $default; + } + else { + return $answer; + } +} + +sub get_sources { + my @Config = (); + my $done = 0; + + my @Oldconfig = (); + + if (-e $config_file) { + @Oldconfig = &read_config('Filename' => $config_file) + } + + print "\t$boldon Set up a list of distribution source locations $boldoff \n"; + print "\n"; + + print " Please give the base URL of the debian distribution.\n"; + print " The access schemes I know about are:$boldon "; + print join (' ', @known_access), "$boldoff\n"; +# print " The mirror scheme is special that it does not specify the\n"; +# print " location of a debian archive but specifies the location\n"; +# print " of a list of mirrors to use to access the archive.\n"; + print "\n"; + print " For example:\n"; + print " file:/mnt/debian,\n"; + print " ftp://ftp.debian.org/debian,\n"; + print " http://ftp.de.debian.org/debian,\n"; +# print " and the special mirror scheme,\n"; +# print " mirror:http://www.debian.org/archivemirrors \n"; + print "\n"; + + my $index = 0; + while (!$done) { + if ($Oldconfig[$index]) { + push (@Config, &get_source('Default' => $Oldconfig[$index++])); + } + else { + push (@Config, &get_source()); + } + print "\n"; + print "$boldon Would you like to add another source?[y/N]$boldoff "; + my $answer = ; + chomp ($answer); + $answer =~ s/\s+/ /og; + if ($answer =~ /^\s*$/o) { + last; + } + elsif ($answer !~ m/\s*y/io) { + last; + } + } + + return @Config; +} + +sub main { + if (-e $config_file) { + my @Oldconfig = &read_config('Filename' => $config_file); + + print "$boldon I see you already have a source list.$boldoff\n"; + print "-" x 72, "\n"; + &print_config('Config' => \@Oldconfig); + print "-" x 72, "\n"; + print "$boldon Do you wish to change (overwrite) it?[y/N]$boldoff "; + my $answer = ; + chomp ($answer); + $answer =~ s/\s+/ /og; + exit 0 unless $answer =~ m/\s*y/io; + } + # OK. They want to be here. + my @Config = &get_sources(); + #&print_config('Config' => \@Config); + &write_config('Config' => \@Config, 'Filename' => $config_file); +} + +&main(); + + diff --git a/apt/dselect/update b/apt/dselect/update new file mode 100755 index 0000000..9195912 --- /dev/null +++ b/apt/dselect/update @@ -0,0 +1,35 @@ +#!/bin/sh +set -e + +# Get the configuration from /etc/apt/apt.conf +OPTS="-f" +APTGET="/usr/bin/apt-get" +APTCACHE="/usr/bin/apt-cache" +DPKG="/usr/bin/dpkg" +CACHEDIR="/var/cache/apt" +PROMPT="no" +RES=`apt-config shell OPTS DSelect::UpdateOptions \ + DPKG Dir::Bin::dpkg APTGET Dir::Bin::apt-get \ + APTCACHE Dir::Bin::apt-cache CACHEDIR Dir::Cache \ + PROMPT DSelect::PromptAfterUpdate` +eval $RES + +# It looks slightly ugly to have a double / in the dpkg output +CACHEDIR=`echo $CACHEDIR | sed -e "s|/$||"` + +set +e +FAILED=0 +$APTGET $OPTS update || FAILED=1 +set -e + +echo "Merging Available information" +rm -f $CACHEDIR/available +$APTCACHE dumpavail > $CACHEDIR/available +$DPKG --update-avail $CACHEDIR/available +rm -f $CACHEDIR/available + +if [ $PROMPT = "yes" ]; then + echo "Press enter to continue." && read RES; +fi + +exit $FAILED diff --git a/apt/gui/CVS/Entries b/apt/gui/CVS/Entries new file mode 100644 index 0000000..e234c40 --- /dev/null +++ b/apt/gui/CVS/Entries @@ -0,0 +1,33 @@ +/apt.cc/1.1.1.1/Fri Aug 10 14:01:51 2001// +/aptwidgets.cc/1.1.1.1/Fri Aug 10 14:01:51 2001// +/aptwidgets.h/1.1.1.1/Fri Aug 10 14:01:51 2001// +/checkoff.xpm/1.1.1.1/Fri Aug 10 14:01:51 2001// +/checkon.xpm/1.1.1.1/Fri Aug 10 14:01:51 2001// +/conflicts.xpm/1.1.1.1/Fri Aug 10 14:01:51 2001// +/depends.xpm/1.1.1.1/Fri Aug 10 14:01:51 2001// +/downgrade.xpm/1.1.1.1/Fri Aug 10 14:01:51 2001// +/errorshow.cc/1.1.1.1/Fri Aug 10 14:01:58 2001// +/errorshow.h/1.1.1.1/Fri Aug 10 14:01:58 2001// +/extracache.cc/1.1.1.1/Fri Aug 10 14:03:14 2001// +/extracache.h/1.1.1.1/Fri Aug 10 14:03:14 2001// +/makefile/1.1.1.1/Fri Aug 10 14:03:14 2001// +/minus.xpm/1.1.1.1/Fri Aug 10 14:03:16 2001// +/package.xpm/1.1.1.1/Fri Aug 10 14:03:16 2001// +/pkgtree.cc/1.1.1.1/Fri Aug 10 14:03:17 2001// +/pkgtree.h/1.1.1.1/Fri Aug 10 14:03:17 2001// +/pkgtreeitem.cc/1.1.1.1/Fri Aug 10 14:03:17 2001// +/pkgtreeitem.h/1.1.1.1/Fri Aug 10 14:03:18 2001// +/plus.xpm/1.1.1.1/Fri Aug 10 14:03:18 2001// +/policy.cc/1.1.1.1/Fri Aug 10 14:03:18 2001// +/policy.h/1.1.1.1/Fri Aug 10 14:03:18 2001// +/progressmeter.cc/1.1.1.1/Fri Aug 10 14:03:18 2001// +/progressmeter.h/1.1.1.1/Fri Aug 10 14:03:18 2001// +/radiooff.xpm/1.1.1.1/Fri Aug 10 14:03:18 2001// +/radioon.xpm/1.1.1.1/Fri Aug 10 14:03:18 2001// +/recommends.xpm/1.1.1.1/Fri Aug 10 14:03:18 2001// +/section.xpm/1.1.1.1/Fri Aug 10 14:03:18 2001// +/statuswidgets.cc/1.1.1.1/Fri Aug 10 14:03:18 2001// +/statuswidgets.h/1.1.1.1/Fri Aug 10 14:03:18 2001// +/suggests.xpm/1.1.1.1/Fri Aug 10 14:03:18 2001// +/upgrade.xpm/1.1.1.1/Fri Aug 10 14:03:19 2001// +D diff --git a/apt/gui/CVS/Repository b/apt/gui/CVS/Repository new file mode 100644 index 0000000..ae7583b --- /dev/null +++ b/apt/gui/CVS/Repository @@ -0,0 +1 @@ +rapt/gui diff --git a/apt/gui/CVS/Root b/apt/gui/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/gui/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/gui/apt.cc b/apt/gui/apt.cc new file mode 100644 index 0000000..61373a4 --- /dev/null +++ b/apt/gui/apt.cc @@ -0,0 +1,90 @@ +#include +#include +#include + +#include +#include +#include +#include +#include "extracache.h" +#include "policy.h" + +#include + +#include "aptwidgets.h" +#include "progressmeter.h" +#include "errorshow.h" + +#include + +// OpenCache - Construct all caches from the source list /*{{{*/ +// --------------------------------------------------------------------- +/* This is ment to run asyncronously so that event processing can continue + normally. Input is a pointer to a progress meter. */ +void *OpenCache(void *Prog) +{ + ProgressMeter *Progress = (ProgressMeter *)Prog; + + // Read the source list + pkgSourceList List; + if (List.ReadMainList() == false) + ShowErrors("The list of sources could not be read.",true); + + // Build all of the caches + pkgMakeStatusCache(List,*Progress); + if (_error->PendingError() == true) + ShowErrors("The package lists or status file could not be parsed or opened.",true); + + // Means some warnings were generated by MakeStatusCache. + Progress->Done(); + ShowErrors("Some of the package information could not be loaded.\n" + "This means that you will have an incomplete list of selections.\n" + "Use the Update command to fix this."); + + + // Open our cache and extra data. + ExtraCacheF *Cache = new ExtraCacheF(*Policy::Cur,*Progress); + if (_error->PendingError() == true) + ShowErrors("The cache files could not be read."); + Progress->Done(); + + return Cache; +} + /*}}}*/ + +int main(int,char **) +{ + SelectLoop Loop; + Widget *Root = 0; + + // Initialize the widget library and bring up the best display + Root = InitWidgets(Loop); + + if (Root == 0) + { + cerr << "Can't find a compatible display system. Supported are: " + << InitWidgetsSupported() << endl; + return 100; + } + + // Initialize the package library + if (pkgInitialize(*_config) == false) + { + _error->DumpErrors(); + return 100; + } + + // Use 'apt 3> file' to see the debug information from clog. + ReAttachStreams(); +// Base = new MainWindow(Root); + + ProgressMeter *Progress = new ProgressMeter("Generating Cache",Root); + + // Create a detached thread to create the caches. + pthread_t T; + pthread_create(&T,0,&OpenCache,Progress); + pthread_detach(T); + + Loop.Loop(); + return 0; +} diff --git a/apt/gui/aptwidgets.cc b/apt/gui/aptwidgets.cc new file mode 100644 index 0000000..b1a8e12 --- /dev/null +++ b/apt/gui/aptwidgets.cc @@ -0,0 +1,408 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: aptwidgets.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + DeityWidgets - Constructors for the APT widget tree. + + These routines construct and layout all of the widgets used in + APT. + + ##################################################################### */ + /*}}}*/ +// Include files /*{{{*/ +#include + +#include +#include +#include +#include + +#include "aptwidgets.h" +#include "pkgtree.h" +#include "policy.h" +#include "extracache.h" +#include "statuswidgets.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + /*}}}*/ + +MainWindow *Base = 0; +#define _(x) x + +// ListToggle - Notifyer class to toggle a check item /*{{{*/ +// --------------------------------------------------------------------- +/* This is attached to all of the toggles in the list menu and inverts + the associated field in the policy class then rebuilds the list */ +class ListToggle : public Notifyer +{ + public: + typedef void (*TFunc)(Widget *From,bool &State); + + private: + bool &Target; + TFunc CallFunc; + public: + + // Toggle the attached boolean and rebuild the tree + virtual bool Trigger(Widget *From,Notifyer::Tag,void *) + { + Target = !Target; + if (Target == true) + From->Flag(Widget::Set,Widget::Set); + else + From->Flag(0,Widget::Set); + if (CallFunc != 0) + CallFunc(From,Target); + return true; + } + + // Create a CheckMenu item, attach this notification and set the state + ListToggle(const char *I,bool &Target,TFunc Call = 0) : Notifyer(Nt_Action), + Target(Target), CallFunc(Call) + { + Widget *W = new CheckMenuItem(I); + W->Add(this); + if (Target == true) + W->Flag(Widget::Set,Widget::Set); + else + W->Flag(0,Widget::Set); + } +}; + /*}}}*/ +// RegenList - Callback for list regeneration /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void RegenList(Widget *,bool &) +{ + Base->PkgView.PTree->MakeList(Base->CurCache); +} + /*}}}*/ +// SetColumns - Callback to change the column layout /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void SetColumns(Widget *,bool &) +{ + // This is the size transform table, order is CV, IV IW + long GPos[][7] = {{16,16,16,-100,-200,-200,-200}, // 000 + {16,16,16,190,-200,-200,-100}, // 001 + {16,16,16,190,-200,-100,-200}, // 010 + {16,16,16,190,-200,-40,-60}, // 011 + {16,16,16,190,-100,-200,-200}, // 100 + {16,16,16,190,-40,-200,-60}, // 101 + {16,16,16,190,-50,-50,-200}, // 110 + {16,16,16,190,85,85,-100}}; // 111 + + // Compute the table index for the current state + unsigned long Index = 0; + if (Policy::Cur->Columns.CurVersion == true) + Index |= (1 << 2); + if (Policy::Cur->Columns.InstVersion == true) + Index |= (1 << 1); + if (Policy::Cur->Columns.InstAsWell == true) + Index |= (1 << 0); + + if (GraphicGC::GC != 0) + Base->PkgView.Columns->Position(GPos[Index],7); + Base->PkgView.PTree->Damage(); +} + /*}}}*/ + +// MainWindow::MainWindow - The main APT window /*{{{*/ +// --------------------------------------------------------------------- +/* */ +MainWindow::MainWindow(Widget *Root) : PkgView(*this) +{ + CurCache = 0; + CtrlCache = 0; + ::Base = this; + + // Construct the top level window when in graphics mode + if (GraphicGC::GC != 0) + { + Main = new GUIWindow("APT",Root); + Base = Main; + } + else + Base = Root; + + PkgView.Create(); + PkgView.Layout(); +} + /*}}}*/ +// PackageView::Create - Create all of the widgets /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PackageView::Create() +{ + Widget *Base = Owner.Base; + + // Construct the Main Menu + Menu = new MenuBar(Base); + + // The file menu + Widget::LastWidget = new MenuItem(_("&File")); + new MenuPopup(); + new MenuItem(_("&Import List of Installed Packages")); + new MenuItem(_("&Export List of Installed Packages")); + new MenuItem(_("&Go Back to Main Screen")); + new Separator(); + new MenuItem(_("&Quit")); + + // The Edit menu + Widget::LastWidget = new MenuItem(_("&Edit"),Menu); + new MenuPopup(); + new MenuItem(_("&Find\t/")); + new MenuItem(_("Find &Again\tn")); + + // The List menu + Widget::LastWidget = new MenuItem(_("&List"),Menu); + new MenuPopup(); + new ListToggle(_("Packages in &Profile"),Policy::Cur->Displayable.InProfile,RegenList); + new ListToggle(_("&Installed Packages"),Policy::Cur->Displayable.Installed,RegenList); + new ListToggle(_("Packages to &Upgrade"),Policy::Cur->Displayable.ToUpgrade,RegenList); + new ListToggle(_("Packages to &Downgrade"),Policy::Cur->Displayable.ToDowngrade,RegenList); + new ListToggle(_("I&gnored Up/Downgrades"),Policy::Cur->Displayable.HeldUpDn,RegenList); + new ListToggle(_("B&roken Packages"),Policy::Cur->Displayable.Broken,RegenList); + new ListToggle(_("&New Packages"),Policy::Cur->Displayable.New); + new ListToggle(_("&Obsolete Packages"),Policy::Cur->Displayable.Obsolete,RegenList); + new ListToggle(_("No&t Installed Packages"),Policy::Cur->Displayable.NotInstalled,RegenList); + new Separator(); + new MenuItem(_("&Choose Profile")); + new MenuItem(_("&Modify Profile")); + + // The Package menu + Widget::LastWidget = new MenuItem(_("&Package"),Menu); + new MenuPopup(); + new MenuItem(_("Check for &Errors")); + new MenuItem(_("&Configure Packages")); + new MenuItem(_("&Install/Upgrade/Remove")); + new Separator(); + Widget *MarkInst = new MenuItem(_("Mark for I&nstallation\tI")); + Widget *MarkHold = new MenuItem(_("Mark for &Keep\tK")); + Widget *MarkRemove = new MenuItem(_("Mark for &Deletion\tD")); + + // The Options menu + Widget::LastWidget = new MenuItem(_("&Options"),Menu); + new MenuPopup(); + new MenuItem(_("&Preferences")); + new Separator(); + new CheckMenuItem(_("Show &Toolbar")); + new ListToggle(_("Show &Sections"),Policy::Cur->ShowSections,RegenList); + new Separator(); + new ListToggle(_("&Current Version"),Policy::Cur->Columns.CurVersion,SetColumns); + new ListToggle(_("&Install Version"),Policy::Cur->Columns.InstVersion,SetColumns); + new ListToggle(_("Install as &Well"),Policy::Cur->Columns.InstAsWell,SetColumns); + + // Help menu item + new HelpMenuItem(_("&Help"),Menu); + Menu->Extent(); + + // The Column bar + if (GraphicGC::GC != 0) + Columns = new ColumnBar(_("\eD\eK\eI\tPackage\tCur-Version\tInst-Version\tInstall as well"),Base); + else + Columns = new ColumnBar(_("DKI\tPackage\tCur-Version\tInst-Version\tInstall as well"),Base); + new Anchor(Columns,Anchor::RightToRight | Anchor::TopToTop | Anchor::BotToTop); + + // The status bar + Status = new TextWidget(Base); + Status->Flag(Widget::Region); + new Anchor(Status,Anchor::RightToRight | Anchor::TopToBot | Anchor::BotToBot); + Status->Add(new ClassNotifyer(this,Nt_Sync,&SyncStatus)); + Usr = new TextWidget(Status); + Usr->DrawFlags(GenGC::YCenter); + Debs = new TextWidget(Status); + Debs->DrawFlags(GenGC::YCenter); + new Anchor(Debs,Anchor::RightToRight | Anchor::TopToBot | Anchor::BotToBot); + + // The tree widget + PTree = new PkgTree(this,Columns,Base); + PTree->Flag(Widget::Region); + new Anchor(PTree,Anchor::RightToRight | Anchor::TopToTop | Anchor::BotToBot); + PTree->Add(new ClassNotifyer(this,Nt_SelectChange,&TreeChange)); + + // The tab dialog + StatusBox = new TabDialog(Base); + new TabPage(_("Info"),StatusBox); + InfoPage = new InfoWidget; + new TabPage(_("Stat"),StatusBox); + new TabPage(_("Words"),StatusBox); + StatusBox->Flag(Widget::Region); + StatusBox->Location(TabDialog::Bottom); + new Anchor(StatusBox,Anchor::RightToRight | Anchor::TopToTop | Anchor::BotToTop | Anchor::LeftToRight); + + // The description widget + Description = new MultiLineWidget(Base); + Description->Flag(Widget::Region); + new Anchor(Description,Anchor::LeftToRight | Anchor::TopToTop | Anchor::BotToBot); + + // Connect some methods to the d/k/i commands + MarkInst->Add(new ClassNotifyer(PTree,Nt_Action,&PkgTree::InstallPkg)); + MarkHold->Add(new ClassNotifyer(PTree,Nt_Action,&PkgTree::KeepPkg)); + MarkRemove->Add(new ClassNotifyer(PTree,Nt_Action,&PkgTree::DeletePkg)); +} + /*}}}*/ +// PackageView::Layout - Position all of the widgets /*{{{*/ +// --------------------------------------------------------------------- +/* Once positions the anchors will ensure that they remain in the correct + location. */ +void PackageView::Layout() +{ + Widget *Base = Owner.Base; + + // Perform graphic mode widget layout (400x100) + if (GraphicGC::GC != 0) + { + Menu->Extent(); + + // Set the column positions and the location of the column headr + Columns->Extent(); + Columns->Resize(Rect(0,Menu->Loc().y2,250,Columns->Size().h)); + SetColumns(0,Policy::Cur->Columns.CurVersion); + + // Setup the status bar + Usr->BorderWidth(1); + Usr->Margins(Point(2,2)); + Usr->SwapBorderColors(); + Usr->Extent(); + + Debs->BorderWidth(1); + Debs->Margins(Point(2,2)); + Debs->SwapBorderColors(); + Debs->Extent(); + + Status->BorderWidth(1); + Status->Margins(Point(2,2)); + Status->Extent(); + + Status->Resize(Rect(0,100 - Status->Size().h,400,Status->Size().h)); + Usr->Resize(Rect(2,1,196,Status->Size().h-4)); + Debs->Resize(Rect(202,1,194,Status->Size().h-4)); + + Status->Sync(); + + // Position the main list + PTree->Resize(AbsRect(Columns->Loc().x1,Columns->Loc().y2, + Columns->Loc().x2,Status->Loc().y1)); + + // Set the initial size. + Owner.Base->Resize(Rect(Owner.Base->Size().x,Owner.Base->Size().y, + 600,370)); + + // Position the tabbed widget + StatusBox->Resize(AbsRect(PTree->Loc().x2,Menu->Loc().y2, + Base->Size().w,Menu->Loc().y2 + 200)); + + // Position the description + Description->Resize(AbsRect(StatusBox->Loc().x1,StatusBox->Loc().y2, + StatusBox->Loc().x2,Status->Loc().y1)); + Description->BorderWidth(1); + } + + // Perform text mode widget layout (80x25) + if (TextGC::GC != 0) + { + // Set the column positions and the location of the column header + long Poses[4] = {4,19,17,-100}; + Columns->Position(Poses,4); + Columns->Resize(Rect(0,1,55,1)); + Columns->Margins(Point(1,0)); + + // Position the status bar + Status->Resize(Rect(0,24,80,1)); + Usr->Resize(Rect(0,0,30,1)); + Debs->Resize(Rect(30,0,50,1)); + Status->Sync(); + + // Construct the main list + PTree->Resize(AbsRect(Columns->Loc().x1,Columns->Loc().y2, + Columns->Loc().x2,Status->Loc().y1)); + + // Position the tabbed widget + StatusBox->Resize(AbsRect(PTree->Loc().x2,Menu->Loc().y2, + Base->Size().w,Menu->Loc().y2 + 13)); + + // Position the description widget + Description->Resize(AbsRect(StatusBox->Loc().x1,StatusBox->Loc().y2, + StatusBox->Loc().x2,Status->Loc().y1)); + Description->BorderWidth(0); + } + + PTree->GiveFocus(); +} + /*}}}*/ +// PackageView::SyncStatus - Regenerate the status bar /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool PackageView::SyncStatus(Widget *,Notifyer::Tag,void *) +{ + struct statfs Buf; + if (statfs("/usr",&Buf) != 0) + { + cerr << "Statfs failed" << endl; + Buf.f_bfree = 0; + } + + ExtraCache &Cache = *Owner.CurCache; + char S[300]; + sprintf(S,"/usr: %liMB free, %liMB needed",(long)Buf.f_bfree/(1024*1024/Buf.f_bsize), + Cache.UsrSize()/1024/1024); + Usr->Text(S); + + sprintf(S,".debs: %liMB, %li broken, %li kept, %li inst, %li del", + Owner.CurCache->DebSize()/1024/1024,Cache.BrokenCount(), + Cache.KeepCount(),Cache.InstCount(),Cache.DelCount()); + Debs->Text(S); + return true; +} + /*}}}*/ +// PackageView::TreeChange - Called when the tree selection changes /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool PackageView::TreeChange(Widget *,Notifyer::Tag,void *) +{ +/* pkgCache::PkgIterator Pkg = PTree->CurrentPkg(); + if (Pkg.end() == true) + { + Description->Set(0); + InfoPage->Set(0); + return true; + } + + ExtraCache &Cache = *Owner.CurCache; + pkgSPkgCtrlInfo Inf = (*Owner.CtrlCache)[Cache[Pkg].CandidateVerIter(Cache)]; + + if (Inf.isNull() == false) + { + Description->Set(Inf->Find("Description")); + InfoPage->Set(Inf); + } + else + { + Description->Set(0); + InfoPage->Set(0); + } */ + + return true; +} + /*}}}*/ +// PackageView::Sync - Calls the various syncing functions /*{{{*/ +// --------------------------------------------------------------------- +/* This is called when the tree changes something */ +void PackageView::Sync() +{ + Status->Sync(); +}; + /*}}}*/ diff --git a/apt/gui/aptwidgets.h b/apt/gui/aptwidgets.h new file mode 100644 index 0000000..cb2685d --- /dev/null +++ b/apt/gui/aptwidgets.h @@ -0,0 +1,87 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: aptwidgets.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + DeityWidgets - Manages groups of widgets + + ##################################################################### */ + /*}}}*/ +#ifndef APTWIDGETS_H +#define APTWIDGETS_H + +#include + +/* We simply declare the items so we can advoid including all the headers + very few modules actually need more than a few of these at once */ +class Widget; +class BasicWidget; +class TextWidget; +class GUIWindow; +class PkgTree; +class ColumnBar; +class MainWindow; +class TabDialog; +class MenuBar; +class pkgCache; +class ExtraCache; +class pkgControlCache; +class MultiLineWidget; +class InfoWidget; + +class PackageView +{ + MainWindow &Owner; + + public: + + // The main elements of the display + MenuBar *Menu; + ColumnBar *Columns; + PkgTree *PTree; + TabDialog *StatusBox; + MultiLineWidget *Description; + TextWidget *Status; + TextWidget *Usr; + TextWidget *Debs; + InfoWidget *InfoPage; + + // The contents of the Info Page + + // The contents of the Stat Page + + // The contents of the Words Page + + void Layout(); + void Create(); + void Sync(); + + // Resyncronize the status display + bool SyncStatus(Widget *,Notifyer::Tag,void *); + bool TreeChange(Widget *,Notifyer::Tag,void *); + + PackageView(MainWindow &Owner) : Owner(Owner) {}; +}; + +class MainWindow +{ + public: + + // Main Window for Graphics Mode and root widget for text mode + GUIWindow *Main; + Widget *Base; + ExtraCache *CurCache; + pkgControlCache *CtrlCache; + + // PackageView Pane + PackageView PkgView; + + // Causes the panes to perform layout + void Layout(); + + MainWindow(Widget *Root); +}; + +extern MainWindow *Base; + +#endif diff --git a/apt/gui/checkoff.xpm b/apt/gui/checkoff.xpm new file mode 100644 index 0000000..be0eeb4 --- /dev/null +++ b/apt/gui/checkoff.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * checkoff_xpm[] = { +"16 16 5 1", +" c #FFFFFFFFFFFF", +". c #767779", +"+ c #B0B1B2", +"@ c #030310", +"# c #F6F6F5", +" ", +" ", +" ", +" .........+ ", +" .@@@@@@@@# ", +" .@######@# ", +" .@######@# ", +" .@######@# ", +" .@######@# ", +" .@######@# ", +" .@######@# ", +" .@@@@@@@@# ", +" +######### ", +" ", +" ", +" "}; diff --git a/apt/gui/checkon.xpm b/apt/gui/checkon.xpm new file mode 100644 index 0000000..93be5d2 --- /dev/null +++ b/apt/gui/checkon.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * checkon_xpm[] = { +"16 16 5 1", +" c #FFFFFFFFFFFF", +". c #767779", +"+ c #B0B1B2", +"@ c #030310", +"# c #F6F6F5", +" ", +" ", +" ", +" .........+ ", +" .@@@@@@@@# ", +" .@######@@ ", +" .@#@@##@@@ ", +" .@#@@#@@@# ", +" .@#@@@@#@# ", +" .@#@@@##@# ", +" .@#@@###@# ", +" .@@@@@@@@# ", +" +######### ", +" ", +" ", +" "}; diff --git a/apt/gui/conflicts.xpm b/apt/gui/conflicts.xpm new file mode 100644 index 0000000..951633c --- /dev/null +++ b/apt/gui/conflicts.xpm @@ -0,0 +1,29 @@ +/* XPM */ +static char * conflicts_xpm[] = { +"16 16 10 1", +" c #FFFFFFFFFFFF", +". c #F4DADA", +"+ c #D97979", +"@ c #C73A3A", +"# c #C12424", +"$ c #E9B4B4", +"% c #CB4848", +"& c #E6A9A9", +"* c #F8E8E8", +"= c #FFFFFF", +" ", +" ", +" .+@#@+. ", +" $#######$ ", +" .#%&*=*###. ", +" +#&===####+ ", +" @#*==###*#@ ", +" ##==###==## ", +" @#*###==*#@ ", +" +####===&#+ ", +" .###*=*&%#. ", +" $#######$ ", +" .+@#@+. ", +" ", +" ", +" "}; diff --git a/apt/gui/depends.xpm b/apt/gui/depends.xpm new file mode 100644 index 0000000..f0a1bc9 --- /dev/null +++ b/apt/gui/depends.xpm @@ -0,0 +1,37 @@ +/* XPM */ +static char * depends_xpm[] = { +"16 16 18 1", +" c #FFFFFFFFFFFF", +". c #585858", +"+ c #B2B2B2", +"@ c #4A4A4A", +"# c #000000", +"$ c #E0E0E0", +"% c #DEDEDE", +"& c #F8F8F8", +"* c #FFFFFF", +"= c #B7B7B7", +"- c #F7F7F7", +"; c #AAAAAA", +"> c #C0C0C0", +", c #434343", +"' c #373737", +") c #3E3E3E", +"! c #EBEBEB", +"~ c #959595", +" ", +" .+ ", +" +@##. ", +" ##$+# ", +" #%&*+. ", +" .=*-;# ", +" #+>,# ", +" .##'##. ", +" #)++# ", +" #+!*+. ", +" .+***# ", +" #+*.# ", +" .##@~ ", +" +@ ", +" ", +" "}; diff --git a/apt/gui/downgrade.xpm b/apt/gui/downgrade.xpm new file mode 100644 index 0000000..53206f2 --- /dev/null +++ b/apt/gui/downgrade.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char * downgrade_xpm[] = { +"16 16 3 1", +" c #FFFFFFFFFFFF s Background", +". c #000000", +"+ c #2F2F2F", +" ", +" ", +" ", +" ", +" ", +" ... ", +" ... ", +" ... ", +" ... ", +" .+..... ", +" ..... ", +" ... ", +" . ", +" ", +" ", +" "}; diff --git a/apt/gui/errorshow.cc b/apt/gui/errorshow.cc new file mode 100644 index 0000000..f0f4569 --- /dev/null +++ b/apt/gui/errorshow.cc @@ -0,0 +1,111 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: errorshow.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Error Show - Show errors from the apt-pkg error class. + + ##################################################################### */ + /*}}}*/ +// Include /*{{{*/ +#include "errorshow.h" + +#include +#include +#include +#include +#include + +#include + /*}}}*/ + +// ShowErrors - Show any errors that may have come up /*{{{*/ +// --------------------------------------------------------------------- +/* If this returns true then a fatal error has occured and things should + be aborted. */ +bool ShowErrors(string Reason,bool Fatal) +{ + // Nothing to show. + if (_error->empty() == true) + return false; + + Widget::Lock Lock; + + // Create the dialog window + GUIWindow *Win; + if (Fatal == true) + Win = new GUIWindow("Fatal Error"); + else + Win = new GUIWindow("Error"); + + // Create the OK button + TextButton *OkButton; + if (Fatal == true) + OkButton = new TextButton("Exit",Win); + else + OkButton = new TextButton("Ok",Win); + + SNotify *Trigger; + OkButton->Add(Trigger = new SNotify(Nt_Action)); + OkButton->Extent(); + + // Add each string element to the dialog + long Spacer = OkButton->IdealSize().y; + long H = Spacer/2; + if (TextGC::GC != 0) + H = 1; + long Width = (long)(Widget::Root->Size().w*0.90) - 2*Spacer; + + // Generate widgets for each of the error codes + int Narrow = -1; + while (true) + { + WrapedText *String = new WrapedText(Reason,Win); + + // Narrow the positions of the raw error texts a bit + if (Narrow == 1) + String->Resize(Rect(Spacer + Spacer/2,H,Width - Spacer/2,1)); + else + String->Resize(Rect(Spacer,H,Width,1)); + + /* This extenting mode makes sure the widget takes the correct amount + of space in all cases. */ + String->ExtentMode(Widget::ExtentAlways,Widget::ExtentAlways); + + // We are now showing error texts not the title + if (Narrow == -1 && Reason.empty() == false) + { + /* We also change the colour and use a bigger font for the + main error message */ + String->Foreground(Wc_Blue); + String->Font(SimpleFont("helvetica",140)); + Width = String->IdealSize().x; + Narrow = 1; + } + else + Narrow = 0; + + H += String->IdealSize().y; + if (_error->empty() == true) + break; + _error->PopMessage(Reason); + } + + // Resize the window and position the OK button + Point WinSize = ChildrenExtent(Win); + OkButton->Resize(Rect((WinSize.x + Spacer - OkButton->Size().w)/2, + H + Spacer/2,OkButton->Size().w,OkButton->Size().h)); + Win->Resize(Rect(0,0,WinSize.x + Spacer,WinSize.y + 2*Spacer)); + CenterWidget(Win,Widget::Root->Size()); + Win->RealizeFamily(); + + Trigger->Wait(); + + delete Win; + + if (Fatal == true) + exit(100); + + return false; +} + /*}}}*/ diff --git a/apt/gui/errorshow.h b/apt/gui/errorshow.h new file mode 100644 index 0000000..2b64d81 --- /dev/null +++ b/apt/gui/errorshow.h @@ -0,0 +1,20 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: errorshow.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Error Show - Show errors from the apt-pkg error class. + + This should be called when an apt-pkg function fails. It will display + a dialog box with an errors/warnings that occured or do nothing. + + ##################################################################### */ + /*}}}*/ +#ifndef ERRORSHOW_H +#define ERRORSHOW_H + +#include + +bool ShowErrors(string Reason = string(),bool Fatal = false); + +#endif diff --git a/apt/gui/extracache.cc b/apt/gui/extracache.cc new file mode 100644 index 0000000..b212f4c --- /dev/null +++ b/apt/gui/extracache.cc @@ -0,0 +1,140 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: extracache.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + ExtraCache - Extension data for the cache + + This class stores the cache data and a set of extension structures for + monitoring the current state of all the packages. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "extracache.h" +#include "policy.h" + +#include +#include + /*}}}*/ + +ExtraCache *ExtraCache::SortCache = 0; + +// ExtraCache::ExtraCache - Constructors /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ExtraCache::ExtraCache(Policy &Pol,MMap &Map,OpProgress &Prog) : + pkgDepCache(Map,Prog), SortedPkgs(0), SecSortedPkgs(0), CurPolicy(Pol) +{ + if (_error->PendingError() == false) + Init(); +} + /*}}}*/ +// ExtraCache::~ExtraCache - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ExtraCache::~ExtraCache() +{ + delete [] SortedPkgs; + delete [] SecSortedPkgs; +} + /*}}}*/ +// ExtraCache::NameComp - QSort compare by name /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int ExtraCache::NameComp(const void *a,const void *b) +{ + const Package &A = **(Package **)a; + const Package &B = **(Package **)b; + + return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name); +} + /*}}}*/ +// ExtraCache::SecNameComp - Compare by name and then by section /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int ExtraCache::SecNameComp(const void *a,const void *b) +{ + const Package &A = **(Package **)a; + const Package &B = **(Package **)b; + + // Sort by section first + if (A.Section == B.Section) + return strcmp(SortCache->StrP + A.Name,SortCache->StrP + B.Name); + return strcmp(SortCache->StrP + A.Section,SortCache->StrP + B.Section); +} + /*}}}*/ +// ExtraCache::Init - Generate the initial extra structures. /*{{{*/ +// --------------------------------------------------------------------- +/* This allocats the extension buffers and then sorts the packages two + ways. */ +bool ExtraCache::Init() +{ + // Grab some memory including space for the trailing null + delete [] SortedPkgs; + delete [] SecSortedPkgs; + SortedPkgs = new Package *[Head().PackageCount + 1]; + SecSortedPkgs = new Package *[Head().PackageCount + 1]; + + // Initialize both lists + int J = 0; + for (PkgIterator I = PkgBegin(); I.end() != true; I++, J++) + SortedPkgs[J] = SecSortedPkgs[J] = I; + SortedPkgs[J] = SecSortedPkgs[J] = 0; + + // Sort them + SortCache = this; + qsort(SortedPkgs,J,sizeof(*SortedPkgs),NameComp); + qsort(SecSortedPkgs,J,sizeof(*SecSortedPkgs),SecNameComp); + + return true; +} + /*}}}*/ +// ExtraCache::GetCandidateVer - Returns the Candidate install version /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ExtraCache::VerIterator ExtraCache::GetCandidateVer(PkgIterator Pkg) +{ + return CurPolicy.GetCandidateVer(Pkg); +}; + /*}}}*/ +// ExtraCache::IsImportantDep - True if the dep is important /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ExtraCache::IsImportantDep(DepIterator Dep) +{ + return CurPolicy.IsImportantDep(Dep); +}; + /*}}}*/ + +// ExtraCacheF::ExtraCacheF - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* This creats objects to load the cache data into memory in an nice + single package. */ +ExtraCacheF::ExtraCacheF(Policy &Pol,OpProgress &Prog) : + File(0), Map(0), Cache(0) +{ + string FName = _config->FindFile("Dir::Cache::pkgcache"); + File = new FileFd(FName,FileFd::ReadOnly); + if (_error->PendingError() == true) + return; + + Map = new MMap(*File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + return; + + Cache = new ExtraCache(Pol,*Map,Prog); + if (_error->PendingError() == true) + return; +} + /*}}}*/ +// ExtraCacheF::~ExtraCacheF - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ExtraCacheF::~ExtraCacheF() +{ + delete Cache; + delete Map; + delete File; +} + /*}}}*/ diff --git a/apt/gui/extracache.h b/apt/gui/extracache.h new file mode 100644 index 0000000..1edcfdf --- /dev/null +++ b/apt/gui/extracache.h @@ -0,0 +1,62 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: extracache.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + ExtraCache - Extension data for the cache + + Two name sorted lists of packages are maintained. One is sorted purely + by name and the other is sorted by section and then by name. This + class also provides Originally pkgDepCache used to be in here, but it + has migrated into pkglib. + + ##################################################################### */ + /*}}}*/ +#ifndef EXTRACACHE_H +#define EXTRACACHE_H + +#include + +class Policy; +class ExtraCache : public pkgDepCache +{ + // Helper functions + static ExtraCache *SortCache; + static int NameComp(const void *a,const void *b); + static int SecNameComp(const void *a,const void *b); + bool Init(); + + protected: + + // Policy implementation for DepCache + virtual VerIterator GetCandidateVer(PkgIterator Pkg); + virtual bool IsImportantDep(DepIterator Dep); + + public: + + // Name sorted lists of packages + Package **SortedPkgs; + Package **SecSortedPkgs; + + Policy &CurPolicy; + inline bool PromoteAutoKeep() {return true;}; + + ExtraCache(Policy &Pol,MMap &Map,OpProgress &Prog); + virtual ~ExtraCache(); +}; + +class ExtraCacheF +{ + FileFd *File; + MMap *Map; + ExtraCache *Cache; + public: + + ExtraCache &operator *() {return *Cache;}; + ExtraCache &operator ->() {return *Cache;}; + + ExtraCacheF(Policy &Pol,OpProgress &Prog); + ~ExtraCacheF(); +}; + +#endif diff --git a/apt/gui/makefile b/apt/gui/makefile new file mode 100644 index 0000000..6f657be --- /dev/null +++ b/apt/gui/makefile @@ -0,0 +1,17 @@ +# -*- make -*- +BASE=.. +SUBDIR=gui + +# Bring in the default rules +include ../buildlib/defaults.mak + +# The program name +PROGRAM=apt +SLIBS = -lapt-pkg -ldeity -lpthread +LIB_MAKES = apt-pkg/makefile deity/makefile + +# Source files +SOURCE = apt.cc aptwidgets.cc extracache.cc pkgtree.cc pkgtreeitem.cc \ + policy.cc statuswidgets.cc progressmeter.cc errorshow.cc + +include $(PROGRAM_H) diff --git a/apt/gui/minus.xpm b/apt/gui/minus.xpm new file mode 100644 index 0000000..027cb18 --- /dev/null +++ b/apt/gui/minus.xpm @@ -0,0 +1,91 @@ +/* XPM */ +static char * minus_xpm[] = { +"16 16 72 1", +" c #FFFFFFFFFFFF s Background", +". c #D1D1D1", +"+ c #5D5D5D", +"@ c #181818", +"# c #000000", +"$ c #171717", +"% c #595959", +"& c #CDCDCD", +"* c #A3A3A3", +"= c #272727", +"- c #919191", +"; c #D4D4D4", +"> c #EBEBEB", +", c #CACACA", +"' c #818181", +") c #202020", +"! c #989898", +"~ c #F3F3F3", +"{ c #F4F4F4", +"] c #E9E9E9", +"^ c #DADADA", +"/ c #C5C5C5", +"( c #1C1C1C", +"_ c #C9C9C9", +": c #5E5E5E", +"< c #949494", +"[ c #F6F6F6", +"} c #FBFBFB", +"| c #EDEDED", +"1 c #696969", +"2 c #4C4C4C", +"3 c #191919", +"4 c #E3E3E3", +"5 c #343434", +"6 c #1D1D1D", +"7 c #444444", +"8 c #BFBFBF", +"9 c #959595", +"0 c #121212", +"a c #EEEEEE", +"b c #161616", +"c c #101010", +"d c #B8B8B8", +"e c #9F9F9F", +"f c #F1F1F1", +"g c #E2E2E2", +"h c #C3C3C3", +"i c #AAAAAA", +"j c #858585", +"k c #5B5B5B", +"l c #868686", +"m c #DDDDDD", +"n c #D3D3D3", +"o c #C6C6C6", +"p c #B3B3B3", +"q c #555555", +"r c #464646", +"s c #CECECE", +"t c #222222", +"u c #D2D2D2", +"v c #CFCFCF", +"w c #CBCBCB", +"x c #B4B4B4", +"y c #151515", +"z c #9B9B9B", +"A c #747474", +"B c #A6A6A6", +"C c #B1B1B1", +"D c #8C8C8C", +"E c #525252", +"F c #131313", +"G c #4A4A4A", +" ", +" ", +" .+@#$%& ", +" *=-;>,')! ", +" .=~{]]]^/(_ ", +" :<[}|||^/12 ", +" 34%%5657890 ", +" #a%5bc67de# ", +" @.|fg^^hij0 ", +" klg4mnopeqr ", +" stuvwhx* c #958D74", +", c #F1ECE0", +"' c #E3DBC2", +") c #6D6452", +"! c #443F33", +"~ c #ABA185", +"{ c #7A6B58", +"] c #CCA070", +"^ c #F5EEE6", +"/ c #54493E", +"( c #7D7661", +"_ c #5E5949", +": c #382D25", +"< c #685444", +"[ c #504031", +"} c #888077", +"| c #F5F1E9", +"1 c #5E4C3D", +"2 c #281F19", +"3 c #E5D0B9", +"4 c #4E3F33", +"5 c #261E18", +"6 c #5A493B", +" ", +" ", +" ", +" ... ", +" ..++@#$ ", +" ..%&*=-;>.. ", +" .,'+%)!*~%{. ", +" .]^,/(+(_:<. ", +" .]][}|'+12<. ", +" .]][]]31<2<. ", +" .]][]]]1<24. ", +" .]][]]]1<5. ", +" ..[]]]1<. ", +" ..]]6. ", +" ... ", +" "}; diff --git a/apt/gui/pkgtree.cc b/apt/gui/pkgtree.cc new file mode 100644 index 0000000..a51adf5 --- /dev/null +++ b/apt/gui/pkgtree.cc @@ -0,0 +1,344 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgtree.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + PkgTree - Manages a tree of packages. + + The Package Tree class manages a list of packages. + + ##################################################################### */ + /*}}}*/ +// Include files /*{{{*/ +#include "pkgtreeitem.h" +#include "policy.h" +#include "aptwidgets.h" + +#include + /*}}}*/ + +// PkgTree::PkgTree - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +PkgTree::PkgTree(PackageView *Owner,ColumnBar *Bar, Widget *Parent) : + Tree(Parent), Bar(Bar), Owner(Owner) +{ +} + /*}}}*/ +// PkgTree::MakeList - Generate the package list based on the policy /*{{{*/ +// --------------------------------------------------------------------- +/* This runs over either the section sorted list or the sorted list and + generates the tree. */ +void PkgTree::MakeList(ExtraCache *Cache) +{ + // Remove all items + EraseAll(); + this->Cache = Cache; + + // Generate a new list + Tree::Item *Root = 0; + if (Policy::Cur->ShowSections == true) + { + Tree::Item *Sec = 0; + Tree::Item *Last = 0; + unsigned long LastSect = 0; + for (pkgCache::Package **I = Cache->SecSortedPkgs; *I != 0; I++) + { + pkgCache::PkgIterator P = pkgCache::PkgIterator(*Cache,*I); + if (Policy::Cur->ShouldDisplay(*Cache,P) == false) + continue; + + // Create a new section + if (Sec == 0 || LastSect != (*I)->Section) + { + (new SecItem(P.Section()))->AfterStep(Root,Sec); + Sec->Flag(Tree::Item::Expanded); + Last = 0; + LastSect = P->Section; + } + + (new Item(*I,this,Sec))->AfterStep(Sec->Child,Last); + Last->Parent = Sec; + } + } + else + { + Tree::Item *Last = 0; + for (pkgCache::Package **I = Cache->SortedPkgs; *I != 0; I++) + { + pkgCache::PkgIterator P = pkgCache::PkgIterator(*Cache,*I); + if (Policy::Cur->ShouldDisplay(*Cache,P) == false) + continue; + + (new Item(*I,this))->AfterStep(Root,Last); + } + } + + this->Root(Root); +} + /*}}}*/ +// PkgTree::GetLocs - Returns the location of the 8 dividers /*{{{*/ +// --------------------------------------------------------------------- +/* Locs should be an array of 8 longs. The function will fill the array + with the 8 positions of the vertical lines. Fields is a boolean + array indicating if the field is activated */ +void PkgTree::GetLocs(CombinedGC &GC,Rect Pos,long *Locs,bool *Fields) +{ + if (RegenLocs == false) + { + memcpy(Locs,ColLocs,sizeof(ColLocs)); + memcpy(Fields,ColFields,sizeof(ColFields)); + return; + } + + for (int I = 0; I != 8; I++) + Fields[I] = true; + + // Put a fake end loc for simplicity + Locs[7] = Pos.w - Pos.x + 1; + + // Convert the smaller list from the text widget + if (GC.IsText() == true) + { + // Get column alignment from the columns widget + long Alignment[5] = {1,4,-1,20,40}; + Bar->PixelPositions(Alignment,5); + + // Deal with inactive fields + int J = 3; + for (int I = 1; I != 5; I++) + { + if (Alignment[I] == -1) + { + Fields[I+2] = false; + continue; + } + + Alignment[I] -= Pos.x; + for (;J <= I+2; J++) + Locs[J] = Alignment[I]; + } + for (;J <= 6; J++) + Locs[J] = Pos.w; + Locs[0] = 0; + Locs[1] = 1; + Locs[2] = 2; + } + + // Use the full list from the graphic column widget + if (GC.IsGraphic() == true) + { + // Get column alignment from the columns widget + long Alignment[7] = {4,8,12,16,-1,70,90}; + Bar->PixelPositions(Alignment,7); + + // Deal with inactive fields + int J = 0; + for (int I = 1; I != 7; I++) + { + if (Alignment[I] == -1) + { + Fields[I] = false; + continue; + } + + if (Alignment[I] - 1 >= Pos.w) + break; + Alignment[I] -= 1 + Pos.x; + for (;J <= I; J++) + Locs[J] = Alignment[I]; + } + for (;J <= 6; J++) + Locs[J] = Pos.w; + Locs[0] = -1; + } + + memcpy(ColLocs,Locs,sizeof(ColLocs)); + memcpy(ColFields,Fields,sizeof(ColFields)); + RegenLocs = false; +} + /*}}}*/ +// PkgTree::DeletePkg - Mark the current package for deletion /*{{{*/ +// --------------------------------------------------------------------- +/* This is hooked to the proper menu item */ +bool PkgTree::DeletePkg(Widget *,Notifyer::Tag,void *) +{ + Cache->MarkDelete(CurrentPkg()); + Damage(); + Owner->Sync(); + return true; +} + /*}}}*/ +// PkgTree::KeepPkg - Mark the current package for keep /*{{{*/ +// --------------------------------------------------------------------- +/* This is hooked to the proper menu item */ +bool PkgTree::KeepPkg(Widget *,Notifyer::Tag,void *) +{ + Cache->MarkKeep(CurrentPkg()); + Damage(); + Owner->Sync(); + return true; +} + /*}}}*/ +// PkgTree::InstallPkg - Mark the current package for installation /*{{{*/ +// --------------------------------------------------------------------- +/* This is hooked to the proper menu item */ +bool PkgTree::InstallPkg(Widget *,Notifyer::Tag,void *) +{ + Cache->MarkInstall(CurrentPkg()); + Cache->PromoteAutoKeep(); + + Damage(); + Owner->Sync(); + return true; +} + /*}}}*/ +// PkgTree::CurrentPkg - Return the currently selected package /*{{{*/ +// --------------------------------------------------------------------- +/* This will return the end iterator if no package is selected */ +pkgCache::PkgIterator PkgTree::CurrentPkg() +{ + Tree::Item *Cur = CurrentItem(); + if (Cur == 0) + return pkgCache::PkgIterator(*Cache,0); + + if (Cur->Type() == 100) + return ((Item *)Cur)->Package(*Cache); + if (Cur->Type() == 101) + return ((DepItem *)Cur)->Package(*Cache); + return pkgCache::PkgIterator(*Cache,0); +} + /*}}}*/ +// PkgTree::Key - Handle keyboard events /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool PkgTree::Key(const KeyEvent &Key,Widget *Source) +{ + /* We check for d/k/i keys and handle them as though the user clicked + on the proper button */ + switch (toupper(Key.Key)) + { + case 'D': + DeletePkg(this,Nt_Action,0); + return true; + + case 'K': + KeepPkg(this,Nt_Action,0); + return true; + + case 'I': + InstallPkg(this,Nt_Action,0); + return true; + } + return Tree::Key(Key,Source); +} + /*}}}*/ +// PkgTree::ItemMouse - Generic mouse handler for the items /*{{{*/ +// --------------------------------------------------------------------- +/* This is a generic mouse handler for all of the items. */ +void PkgTree::ItemMouse(Tree::Item *Itm,pkgCache::PkgIterator Pkg, + const MouseEvent &Event,int Spacer) +{ + // Mouse is just moving around with no pressed buttons. + if (Event.IsMotion() == true && Event.IsDrag() == false) + return; + + CurrentItem(Itm); + + // Get the division locations + CombinedGC GC; + long Locs[8]; + bool Fields[8]; + GetLocs(GC,Rect(BorderX,0,Pos.w - 2*BorderX,ItemHeight),Locs,Fields); + + // In the name column + if (Event.Pos.x >= Locs[3] && Event.Pos.x < Locs[4]) + { + // Item isnt expandable + if (Itm->IsExpandable() == false) + return; + + if (Event.IsClick() == false) + return; + + // Check if it is in the +/- inidicator + int Depth = 0; + for (Tree::Item *I = Itm; I != 0; I = I->Parent) + Depth++; + Depth--; + + // Determine the spacing + long Space; + if (GC.IsGraphic() == true) + Space = Spacer; + else + Space = 1; + + // Is it in the +/- region? + if ((Locs[3] + Space*Depth) <= Event.Pos.x && + (Locs[3] + Space*(Depth + 1)) > Event.Pos.x) + { + if (Itm->IsExpanded() == true) + Itm->ContractChildren(this); + else + Itm->ExpandChildren(this); + } + } + + // In the dki column + if (Event.Pos.x < Locs[3] && Pkg.end() == false) + { + if (Event.IsClick() == false) + return; + + // Figure out which one + ExtraCache::StateCache &State = (*Cache)[Pkg]; + int Item = 0; + for (;Event.Pos.x >= Locs[Item]; Item++); + Item--; + + // Toggle the install column (not installed) + if (Pkg->CurrentVer == 0 && Item == 2) + { + if (State.Mode == ExtraCache::ModeInstall) + Cache->MarkKeep(Pkg); + else + { + Cache->MarkInstall(Pkg); + Cache->PromoteAutoKeep(); + } + Damage(); + Owner->Sync(); + } + + // Toggle the delete column (installed, no upgrade) + if (State.Upgradable() == false && Item == 0) + { + if (State.Mode == ExtraCache::ModeDelete) + Cache->MarkKeep(Pkg); + else + Cache->MarkDelete(Pkg); + Damage(); + Owner->Sync(); + } + + // Any of the three states + if (Pkg->CurrentVer != 0 && State.Upgradable() == true) + { + if (Item == 0) + Cache->MarkDelete(Pkg); + if (Item == 1) + Cache->MarkKeep(Pkg); + if (Item == 2) + { + Cache->MarkInstall(Pkg); + Cache->PromoteAutoKeep(); + } + + Damage(); + Owner->Sync(); + } + } +} + /*}}}*/ + diff --git a/apt/gui/pkgtree.h b/apt/gui/pkgtree.h new file mode 100644 index 0000000..dd19e3f --- /dev/null +++ b/apt/gui/pkgtree.h @@ -0,0 +1,75 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgtree.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + PkgTree - A tree class for displaying packages + + The package tree class handles the various item classes and provides + them with some utility functions. It also handles all of the user + interaction for the item classes. + + To speed up the rendering we cache the location data from the column + bar, it is regenerated each time the Tree's render function is called. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGTREE_H +#define PKGTREE_H + +#include +#include + +class ColumnBar; +class ExtraCache; +class PackageView; + +class PkgTree : public Tree +{ + protected: + + // Various internal items + class Item; + class DepItem; + class SecItem; + class Drawer; + friend Drawer; + friend Item; + friend DepItem; + friend SecItem; + + // Usefull lists + ExtraCache *Cache; + ColumnBar *Bar; + PackageView *Owner; + + // Draw Cache + long ColLocs[8]; + bool ColFields[8]; + bool RegenLocs; + + virtual void Render(CombinedGC &GC) {RegenLocs = true; Tree::Render(GC);} + virtual bool Key(const KeyEvent &Key,Widget *Source); + virtual void ItemMouse(Tree::Item *I,pkgCache::PkgIterator P, + const MouseEvent &Event,int Spacer); + + // Helper functions + void GetLocs(CombinedGC &GC,Rect Pos,long *Locs,bool *Fields); + + public: + + // Populates the tree + void MakeList(ExtraCache *Cache); + + // User actions + bool DeletePkg(Widget *,Notifyer::Tag,void *); + bool KeepPkg(Widget *,Notifyer::Tag,void *); + bool InstallPkg(Widget *,Notifyer::Tag,void *); + + // Accessors + pkgCache::PkgIterator CurrentPkg(); + + PkgTree(PackageView *Owner,ColumnBar *Bar, Widget *Parent = 0); +}; + +#endif diff --git a/apt/gui/pkgtreeitem.cc b/apt/gui/pkgtreeitem.cc new file mode 100644 index 0000000..b6b07d7 --- /dev/null +++ b/apt/gui/pkgtreeitem.cc @@ -0,0 +1,731 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgtreeitem.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + PkgTree Items - Tree::Item classes for displaying items in the package + tree + + This class renders each package item directly from the actual storage + for the package item. This simplifies the managment of the tree as + stringified versions of package items don't have to be constantly + resynced with the tree. + + Two sorted lists of package pointers are kept, one is sorted by package + name the other is sorted by section then by package name. This allows + the display to be inorder. + + ##################################################################### */ + /*}}}*/ +// Include files /*{{{*/ +#include "pkgtreeitem.h" +#include "policy.h" + +#include + /*}}}*/ +// Images /*{{{*/ +#include "minus.xpm" +#include "plus.xpm" +#include "package.xpm" +#include "section.xpm" +#include "upgrade.xpm" +#include "downgrade.xpm" +#include "checkon.xpm" +#include "checkoff.xpm" +#include "radioon.xpm" +#include "radiooff.xpm" +#include "conflicts.xpm" +#include "depends.xpm" +#include "suggests.xpm" +#include "recommends.xpm" +static XPMImage MinusImg(minus_xpm); +static XPMImage PlusImg(plus_xpm); +static XPMImage PackageImg(package_xpm); +static XPMImage SectionImg(section_xpm); +static XPMImage UpgradeImg(upgrade_xpm); +static XPMImage DowngradeImg(downgrade_xpm); +static XPMImage CheckOnImg(checkon_xpm); +static XPMImage CheckOffImg(checkoff_xpm); +static XPMImage RadioOnImg(radioon_xpm); +static XPMImage RadioOffImg(radiooff_xpm); +static XPMImage ConflictsImg(conflicts_xpm); +static XPMImage DependsImg(depends_xpm); +static XPMImage SuggestsImg(suggests_xpm); +static XPMImage RecommendsImg(recommends_xpm); + /*}}}*/ + +// Drawer::Init - Constructor helper /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::Drawer::Init() +{ + // Determine the spacing unit + if (GC.IsGraphic() == true) + Space = PlusImg.Dim().x; + else + Space = 1; + + // Column layout + ((PkgTree *)Owner)->GetLocs(GC,Pos,Locs,Fields); + + // Color selection + Selected = Item->IsFlag(Tree::Item::Selected); + Item->SetColors(GC,Owner,GC.IsText() == true && Selected == true); +} + /*}}}*/ +// Drawer::RenderCheck - Render a single checkbox in the list /*{{{*/ +// --------------------------------------------------------------------- +/* This renders one checkbox out of the 3 possible columns in the list. */ +void PkgTree::Drawer::RenderCheck(bool D,bool K,bool I,bool State) +{ + int Loc = Delete; + + // Background fill the unused entries + if (D == true) + Loc = Delete; + else + GC->BFill(AbsRect(Locs[Delete],0,Locs[Delete + 1],Height)); + + if (I == true) + Loc = Install; + else + GC->BFill(AbsRect(Locs[Install],0,Locs[Install + 1],Height)); + + if (K == true) + Loc = Keep; + else + GC->BFill(AbsRect(Locs[Keep],0,Locs[Keep+1],Height)); + + // Render the check box + if (State == true) + GC.gGC->DrawBitmap(AbsRect(Locs[Loc],0,Locs[Loc+1],Height),CheckOnImg, + GenGC::YCenter | GenGC::XCenter); + else + GC.gGC->DrawBitmap(AbsRect(Locs[Loc],0,Locs[Loc+1],Height),CheckOffImg, + GenGC::YCenter | GenGC::XCenter); +} + /*}}}*/ +// Drawer::DrawState - Draw the 3 state indicators /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::Drawer::DrawState() +{ + Rect Pos = AbsRect(Locs[0],0,Locs[3],Height); + + // Purely virtual pacakge + if (Pkg->VersionList == 0) + { + BFill(AllStates); + return; + } + + // Render the 3 state indicators + if (GC.IsGraphic() == true) + { + // Render only the Install checkbox (not installed) + if (Pkg->CurrentVer == 0) + RenderCheck(false,false,true,State->Mode == 2); + + // Render only the remove checkbox (installed, no upgrade) + if (State->Upgradable() == false) + RenderCheck(true,false,false,State->Mode == 0); + + // Render all three as radio buttons, installed and upgradeable + if (Pkg->CurrentVer != 0 && State->Upgradable() == true) + { + for (int I = 0; I != 3; I++) + { + if (State->Mode == I) + GC.gGC->DrawBitmap(AbsRect(Locs[I],0,Locs[I+1],Pos.h), + RadioOnImg,GenGC::YCenter | GenGC::XCenter); + else + GC.gGC->DrawBitmap(AbsRect(Locs[I],0,Locs[I+1],Pos.h), + RadioOffImg,GenGC::YCenter | GenGC::XCenter); + } + } + } + else + { + char S[4] = {'-','-','-',0}; + S[State->Mode] = '*'; + + if (Pkg->CurrentVer == 0 || State->Upgradable() == false) + S[1] = ' '; + + // Render only the install checkbox (not installed) + if (Pkg->CurrentVer == 0) + S[0] = ' '; + + // Render only the remove checkbox (installed, no upgrade) + if (State->Upgradable() == false) + S[2] = ' '; + + GC->DrawString(Point(0,0),S); + } +} + /*}}}*/ +// Drawer::DrawName - Draw the Name feild /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::Drawer::DrawName(const char *Text,XPMImage &Image, + Color Clr) +{ + if (Fields[Name] == false) + return; + + if (Text == 0) + Text = Pkg.Name(); + + // Determine if there are any children that are expandable + bool Expandy = false; + if (Item->Parent != 0) + { + for (Tree::Item *I = Item->Parent->Child; I != 0; I = I->Next) + { + if (I->IsExpandable() == true) + { + Expandy = true; + break; + } + } + } + else + Expandy = true; + + // Draw the tree lines + AbsRect TextBox(Locs[Name],0,Locs[Name+1],Height); + long Width = Locs[Name+1] - Locs[Name]; + if (GC.IsGraphic() == true) + { + GC->SetColor(Wc_LightGray); + Item->DrawLines(GC,Space,Depth,AbsRect(Locs[Name],0,Width,Height)); + + // Draw the item graphic + TextBox.x1 = Locs[Name] + Space*Depth; + if (Expandy == true) + { + if (Item->IsExpandable() == true) + { + if (Item->IsFlag(Tree::Item::Expanded) == true) + GC.gGC->DrawBitmap(Rect(TextBox.x1,0,PlusImg.Dim().x,Height), + MinusImg,GenGC::YCenter | GenGC::XCenter); + else + GC.gGC->DrawBitmap(Rect(TextBox.x1,0,PlusImg.Dim().x,Height), + PlusImg,GenGC::YCenter); + } + else + { + GC.gGC->BFill(Rect(TextBox.x1,0,PlusImg.Dim().x,Height)); + GC.gGC->Line(Point(TextBox.x1,Height/2),Point(TextBox.x1+PlusImg.Dim().x,Height/2)); + } + + TextBox.x1 += PlusImg.Dim().x; + } + + GC.gGC->DrawBitmap(Rect(TextBox.x1,0,Image.Dim().x,Height), + Image,GenGC::YCenter | GenGC::XCenter); + TextBox.x1 += Image.Dim().x; + } + else + { + Item->DrawLines(GC,1,Depth,AbsRect(Locs[Name],0,Width,Height)); + + // Indent the text region and remove 1 space from the end + TextBox.x1 += Depth; + TextBox.x2--; + + if (Expandy == true) + { + if (Item->IsExpandable() == true) + { + if (Item->IsFlag(Tree::Item::Expanded) == true) + GC->DrawString(TextBox,"-"); + else + GC->DrawString(TextBox,"+"); + } + else + GC.tGC->DrawLineChar(Point(TextBox.x1,TextBox.y1), + TextGC::HLineChar); + TextBox.x1++; + } + + GC->BFill(Rect(TextBox.x2,0,1,Height)); + } + + if (GC.IsGraphic() == true) + Item->SetColors(GC,Owner,Selected,Clr); + + if (GC.IsText() == true && Clr != Wc_None) + GC->SetColor(Clr); + + GC->DrawString(TextBox,Point(Space/3,Height/2),Text,GenGC::YCenter); + + if (GC.IsGraphic() == true && Selected == true) + Item->SetColors(GC,Owner,false); + + if (GC.IsText() == true && Clr != Wc_None) + Item->SetColors(GC,Owner,Selected); +} + /*}}}*/ +// Drawer::DrawCurrentVersion - Draw the current version /*{{{*/ +// --------------------------------------------------------------------- +/* Draw the current version field */ +void PkgTree::Drawer::DrawCurrentVersion() +{ + if (Fields[CurrentVer] == false) + return; + + // Draw the current version field + AbsRect TextBox = AbsRect(Locs[CurrentVer],0,Locs[CurrentVer+1],Height); + if (Pkg->CurrentVer != 0) + { + // Check if the package has an error with its current version + if ((State->DepState & ExtraCache::DepNowMin) != ExtraCache::DepNowMin) + { + if (Selected == true && GC.IsText() == true) + GC->SetColor(Color(239,44,40,Color::Brown)); + else + GC->SetColor(Color(239,44,40,Color::BrightRed)); + } + + GC->DrawString(TextBox,Point(Space/3,Height/2),State->CurVersion, + GenGC::YCenter); + + // Set the colouring back + if ((State->DepState & ExtraCache::DepNowMin) != ExtraCache::DepNowMin) + Item->SetColors(GC,Owner,GC.IsText() == true && Selected == true); + } + else + GC->BFill(TextBox); +} + /*}}}*/ +// Drawer::DrawCandidateVersion - Draw the candidate version /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::Drawer::DrawCandidateVersion() +{ + if (Fields[CandidateVer] == false) + return; + + /* Draw the Install Version. The version is only drawn if something is going + to happen to the package */ + AbsRect TextBox = AbsRect(Locs[CandidateVer],0,Locs[CandidateVer+1],Height); + + // We have to draw a status icon.. + if (State->Status != 0) + { + // In graphic mode + if (GC.IsGraphic() == true) + { + // Draw the upgrade image, downgrade image or a blank + TextBox.x2 = TextBox.x1 + UpgradeImg.Dim().x; + if (State->Status == -1) + GC.gGC->DrawBitmap(TextBox,Point(0,Height/2), + DowngradeImg,GenGC::YCenter); + if (State->Status == 1) + GC.gGC->DrawBitmap(TextBox,Point(0,Height/2), + UpgradeImg,GenGC::YCenter); + + if (State->Status != -1 && State->Status != 1) + GC->BFill(TextBox); + } + else + { + // Perform the image lookup in a table for text mode.. + TextBox.x2 = TextBox.x1 + Space; + char *StatusChar[] = {"v","=","^"," "}; + GC->DrawString(TextBox,StatusChar[State->Status + 1], + GenGC::YCenter | GenGC::XCenter); + } + + // Redner the version text + TextBox.x1 = TextBox.x2; + TextBox.x2 = Locs[CandidateVer+1]; + + GC->DrawString(TextBox,Point(Space/3,Height/2),State->CandVersion, + GenGC::YCenter); + } + else + { + // Just fill. + TextBox.x2 = Locs[CandidateVer+1]; + GC->BFill(TextBox); + } +} + /*}}}*/ +// Drawer::DrawAsWell - Draw the Install as well field /*{{{*/ +// --------------------------------------------------------------------- +/* The install as well field has a number of special requirements to make + it work properly these are all handled by the extra cache dep generator. */ +void PkgTree::Drawer::DrawAsWell() +{ + if (Fields[InstAsWell] == false) + return; + + AbsRect Pos(Locs[InstAsWell],0,Locs[InstAsWell + 1],Height); + + if (State->CandidateVer == 0) + { + GC->BFill(Pos); + return; + } + + // Run over the deps of the candidate version + pkgCache::DepIterator Dep = State->CandidateVerIter(Cache).DependsList(); + long Space = GC->ExtentText(" ").w; + for (; Dep.end() != true;) + { + pkgCache::DepIterator Start = Dep; + bool Result = true; + for (bool LastOR = true; Dep.end() == false && LastOR == true; Dep++) + { + LastOR = (Dep->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; + + // Figure out some of the flags + unsigned char DepState = Cache[Dep]; + ExtraCache::StateCache &Parent = Cache[Dep.TargetPkg()]; + bool Auto = (Parent.Flags & pkgCache::Flag::Auto) == pkgCache::Flag::Auto; + bool Current = (DepState & ExtraCache::DepNow) == + ExtraCache::DepNow; + bool Install = (DepState & ExtraCache::DepInstall) == + ExtraCache::DepInstall; + + /* The currently installed version and target install version are + both okay, there is no need to show the dep */ + if (Current == true && Install == true) + Result = false; + + /* The install version is okay and the target package is not in auto + mode */ + if (Install == true && Auto == false) + Result = false; + } + + // Dep is satisfied okay. + if (Result == false) + continue; + + /* Now, decide if we should show user deps (suggest/rec). This is done by + checking if the package was installed, if so then user deps are + ignored otherwise they are shown. */ + if (Policy::Cur->IsImportantDep(Start) == false) + continue; + if (Pkg->CurrentVer != 0 && Start.IsCritical() == false) + continue; + + // Ah, now we show the dep. + const char *Name = Start.TargetPkg().Name(); + Rect Size = GC->ExtentText(Name); + Size.w += Space; + GC->DrawString(Rect(Pos.x1,Pos.y1,Size.w,Pos.y2 - Pos.y1), + Point(Space,(Pos.y2 - Pos.y1)/2),Name,GenGC::YCenter); + Pos.x1 += Size.w; + + if (Pos.x1 >= Pos.x2) + return; + } + GC->BFill(Pos); +} + /*}}}*/ +// Drawer::BFill - Fills one of the sections /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::Drawer::BFill(unsigned int Region) +{ + if (Region == AllStates) + GC->BFill(AbsRect(Locs[0],0,Locs[3],Height)); + else + GC->BFill(AbsRect(Locs[Region],0,Locs[Region+1],Height)); +} + /*}}}*/ + +// Item::Item - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +PkgTree::Item::Item(pkgCache::Package *Pkg,PkgTree *Owner,Tree::Item *Parent) : + Tree::Item(Parent), Pkg(Pkg) +{ + pkgCache::PkgIterator Pkg(*Owner->Cache,this->Pkg); + ExtraCache::StateCache &State = (*Owner->Cache)[Pkg]; + + // Pick a version iterator + if (State.CandidateVer == 0) + return; + pkgCache::VerIterator Ver = State.CandidateVerIter(*Owner->Cache); + + if (Ver->DependsList != 0) + Flag(Expandable); +} + /*}}}*/ +// Item::Render - Draw the item /*{{{*/ +// --------------------------------------------------------------------- +/* This does the complex redering of each package item, including all the + columns and the images that are required. */ +void PkgTree::Item::Render(CombinedGC &GC,unsigned long Depth,Rect Pos, + Tree *Owner) +{ + GC->AddClipping(Pos); + + Drawer Draw(GC,Depth,Pos,Owner,Pkg,this); + + // Check if the packages install state is broken, draw in red. + pkgCache::PkgIterator P(Draw,Pkg); + if ((Draw.GetCache()[P].DepState & ExtraCache::DepInstMin) != + ExtraCache::DepInstMin) + { + if (Draw.IsSelected() == true && GC.IsText() == true) + Draw.DrawName(0,PackageImg,Color(239,44,40,Color::Brown)); + else + Draw.DrawName(0,PackageImg,Color(239,44,40,Color::BrightRed)); + } + else + Draw.DrawName(0,PackageImg); + + Draw.DrawState(); + Draw.DrawCurrentVersion(); + Draw.DrawCandidateVersion(); + Draw.DrawAsWell(); + + GC->PopClipping(); +} + /*}}}*/ +// Item::Height - Return the Height of the item /*{{{*/ +// --------------------------------------------------------------------- +/* */ +long PkgTree::Item::Height() +{ + if (TextGC::GC != 0) + return GenGC::GC->ExtentText("").h; + else + return GenGC::GC->ExtentText("").h + 2; +} + /*}}}*/ +// Item::Expand - Expand the tree node /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool PkgTree::Item::Expand(Tree *Owner) +{ + PkgTree *Tree = (PkgTree *)Owner; + pkgCache::PkgIterator Pkg(*Tree->Cache,this->Pkg); + ExtraCache::StateCache &State = (*Tree->Cache)[Pkg]; + + // Pick a version iterator + if (State.CandidateVer == 0) + return false; + pkgCache::VerIterator Ver = State.CandidateVerIter(*Tree->Cache); + + // Generate the new child list + Tree::Item *Root = 0; + Tree::Item *Last = 0; + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) + { + (new DepItem(D,Tree))->AfterStep(Root,Last); + Last->Parent = this; + } + + Child = Root; + return true; +} + /*}}}*/ +// Item::Contract - Collapse the tree node /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::Item::Contract(Tree *) +{ + // Erase all the children + for (Tree::Item *I = Child; I != 0;) + { + Tree::Item *Next = I->Next; + I->Parent = 0; + I->Next = 0; + I->Last = 0; + delete I; + I = Next; + } + Child = 0; +} + /*}}}*/ +// Item::Mouse - Mouse handler /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::Item::Mouse(Tree *Owner,const MouseEvent &Event) +{ + PkgTree &P = *(PkgTree *)Owner; + P.ItemMouse(this,Package(*P.Cache),Event,PlusImg.Dim().x); +} + /*}}}*/ + +// DepItem::DepItem - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +PkgTree::DepItem::DepItem(pkgCache::Dependency *Dep,PkgTree *Owner, + Tree::Item *Parent) : Tree::Item(Parent), Dep(Dep) +{ + // Check if the provide list only has one item + pkgCache::DepIterator D(*Owner->Cache,Dep); + pkgCache::PkgIterator P(*Owner->Cache); + if (D.SmartTargetPkg(P) == true) + Flag(Expandable); +} + /*}}}*/ +// DepItem::Height - Return the Height of the item /*{{{*/ +// --------------------------------------------------------------------- +/* */ +long PkgTree::DepItem::Height() +{ + if (TextGC::GC != 0) + return GenGC::GC->ExtentText("").h; + else + return GenGC::GC->ExtentText("").h + 2; +} + /*}}}*/ +// DepItem::Expand - Expand the tree node /*{{{*/ +// --------------------------------------------------------------------- +/* This iterates over all the packages providing this name. If a package + exists already with this name then it is shown as the parent. */ +bool PkgTree::DepItem::Expand(Tree *Owner) +{ + PkgTree *Tree = (PkgTree *)Owner; + pkgCache::DepIterator D(*Tree->Cache,Dep); + pkgCache::PrvIterator Prv = D.TargetPkg().ProvidesList(); + + // Generate the new child list + Tree::Item *Root = 0; + Tree::Item *Last = 0; + for (; Prv.end() == false; Prv++) + { + // Check if this provides is duplicated in the list. + pkgCache::PrvIterator DupCheck = Prv; + for (DupCheck++;DupCheck.end() == false && DupCheck.OwnerPkg() != Prv.OwnerPkg(); + DupCheck++); + if (DupCheck.end() == false) + continue; + + // Create the new item and add it to the end of the child list. + (new PkgTree::Item(Prv.OwnerPkg(),Tree))->AfterStep(Root,Last); + Last->Parent = this; + Last->Flag(0,Expandable); + } + + Child = Root; + return true; +} + /*}}}*/ +// DepItem::Render - Draw the item /*{{{*/ +// --------------------------------------------------------------------- +/* This does the complex redering of each package item, including all the + columns and the images that are required. */ +void PkgTree::DepItem::Render(CombinedGC &GC,unsigned long Depth,Rect Pos, + Tree *Owner) +{ + GC->AddClipping(Pos); + + Drawer Draw(GC,Depth,Pos,Owner,this); + pkgCache::DepIterator Dep(Draw,this->Dep); + + // Smart locate the target package + pkgCache::PkgIterator TargetPkg(Draw); + Dep.SmartTargetPkg(TargetPkg); + Draw.SetPkg(TargetPkg); + + // Determine if the item should be drawn in red (firebrick2 to be exact) + Color Clr = Wc_None; + pkgCache::DepIterator D = Dep; + for (;(D->CompareOp & pkgCache::Dep::Or) == pkgCache::Dep::Or; D++); + if ((Draw.GetCache()[D] & ExtraCache::DepGInstall) == 0) + { + if (Draw.IsSelected() == true && GC.IsText() == true) + Clr = Color(239,44,40,Color::Brown); + else + Clr = Color(239,44,40,Color::BrightRed); + } + + // Draw the name with the proper image + switch (Dep->Type) + { + case pkgCache::Dep::PreDepends: + case pkgCache::Dep::Depends: + Draw.DrawName(0,DependsImg,Clr); + break; + + case pkgCache::Dep::Suggests: + Draw.DrawName(0,SuggestsImg,Clr); + break; + + case pkgCache::Dep::Recommends: + Draw.DrawName(0,RecommendsImg,Clr); + break; + + case pkgCache::Dep::Conflicts: + Draw.DrawName(0,ConflictsImg,Clr); + break; + + default: + Draw.DrawName(0,PackageImg,Clr); + break; + } + + Draw.DrawState(); + Draw.DrawCurrentVersion(); + Draw.DrawCandidateVersion(); + Draw.DrawAsWell(); + + GC->PopClipping(); +} + /*}}}*/ +// DepItem::Mouse - Mouse handler /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::DepItem::Mouse(Tree *Owner,const MouseEvent &Event) +{ + PkgTree &P = *(PkgTree *)Owner; + P.ItemMouse(this,Package(*P.Cache),Event,PlusImg.Dim().x); +} + /*}}}*/ + +// SecItem::SecItem - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +PkgTree::SecItem::SecItem(const char *Sec,Tree::Item *Parent) : + Tree::Item(Parent), Section(Sec) +{ +} + /*}}}*/ +// SecItem::Render - Draw the item /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::SecItem::Render(CombinedGC &GC,unsigned long Depth, + Rect Pos,Tree *Owner) +{ + GC->AddClipping(Pos); + + Drawer Draw(GC,Depth,Pos,Owner,this); + Draw.DrawName(Section,SectionImg); + Draw.BFill(Drawer::AllStates); + Draw.BFill(Drawer::CurrentVer); + Draw.BFill(Drawer::CandidateVer); + Draw.BFill(Drawer::InstAsWell); + + GC->PopClipping(); +} + /*}}}*/ +// SecItem::Height - Return the Height of the item /*{{{*/ +// --------------------------------------------------------------------- +/* */ +long PkgTree::SecItem::Height() +{ + if (TextGC::GC != 0) + return GenGC::GC->ExtentText("").h; + else + return GenGC::GC->ExtentText("").h + 2; +} + /*}}}*/ +// SecItem::Mouse - Mouse handler /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void PkgTree::SecItem::Mouse(Tree *Owner,const MouseEvent &Event) +{ + PkgTree &P = *(PkgTree *)Owner; + P.ItemMouse(this,pkgCache::PkgIterator(*P.Cache,0),Event,PlusImg.Dim().x); +} + /*}}}*/ diff --git a/apt/gui/pkgtreeitem.h b/apt/gui/pkgtreeitem.h new file mode 100644 index 0000000..ccc76e0 --- /dev/null +++ b/apt/gui/pkgtreeitem.h @@ -0,0 +1,147 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: pkgtreeitem.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + PkgTree Items - Tree::Item classes for displaying items in the package + tree + + Each of these classes handles a different sort of item. All of them + display directly from the ExtraCache structure and store minimal + internal data making them cheap to instantiate. + + The drawer class contains functions to help draw the items as well + as a collection of variables determined for each item to help the + render process. + + ##################################################################### */ + /*}}}*/ +#ifndef PKGTREEITEM_H +#define PKGTREEITEM_H + +#include "pkgtree.h" +#include "extracache.h" + +class PkgTree::Item : public Tree::Item +{ + protected: + + pkgCache::Package *Pkg; + + // Base class members + virtual void Render(CombinedGC &GC,unsigned long Depth, + Rect Pos,Tree *Owner); + virtual long Height(); + virtual bool Expand(Tree *Owner); + virtual void Contract(Tree *Owner); + virtual void Mouse(Tree *Owner,const MouseEvent &Event); + + public: + + pkgCache::PkgIterator Package(pkgCache &Cache) {return pkgCache::PkgIterator(Cache,Pkg);}; + + virtual unsigned int Type() {return 100;}; + Item(pkgCache::Package *Pkg,PkgTree *Owner,Tree::Item *Parent = 0); +}; + +class PkgTree::DepItem : public Tree::Item +{ + protected: + + pkgCache::Dependency *Dep; + + // Base class members + virtual void Render(CombinedGC &GC,unsigned long Depth, + Rect Pos,Tree *Owner); + virtual bool Expand(Tree *Owner); + virtual long Height(); + virtual void Mouse(Tree *Owner,const MouseEvent &Event); + + public: + + pkgCache::PkgIterator Package(pkgCache &Cache) {return pkgCache::DepIterator(Cache,Dep).TargetPkg();}; + virtual unsigned int Type() {return 101;}; + + DepItem(pkgCache::Dependency *Dep,PkgTree *Owner,Tree::Item *Parent = 0); +}; + +class PkgTree::SecItem : public Tree::Item +{ + protected: + + const char *Section; + + virtual void Render(CombinedGC &GC,unsigned long Depth,Rect Pos,Tree *Owner); + virtual long Height(); + virtual void Mouse(Tree *Owner,const MouseEvent &Event); + + public: + + SecItem(const char *Section,Tree::Item *Parent = 0); +}; + +class PkgTree::Drawer +{ + CombinedGC &GC; + ExtraCache &Cache; + pkgCache::PkgIterator Pkg; + ExtraCache::StateCache *State; + int Height; + unsigned long Depth; + Tree *Owner; + Tree::Item *Item; + Rect Pos; + bool Selected; + + long Locs[8]; + bool Fields[8]; + int Space; + + void RenderCheck(bool D,bool K,bool I,bool State); + void Init(); + + public: + + // Locations of each region in the locs array + enum Regions {AllStates = 10,Delete = 0,Keep = 1,Install = 2,Name = 3, + CurrentVer = 4,CandidateVer = 5,InstAsWell = 6}; + + // Some usefull accessors + operator pkgCache &() {return Cache;}; + ExtraCache &GetCache() {return Cache;}; + inline bool IsSelected() {return Selected;}; + + void SetPkg(pkgCache::PkgIterator const &P) + { + Pkg = P; + State = &Cache[P]; + }; + + // Drawing functions + void DrawAsWell(); + void DrawState(); + void DrawCurrentVersion(); + void DrawCandidateVersion(); + void DrawName(const char *Name,XPMImage &Image,Color TextClr = Wc_None); + void BFill(unsigned int Region); + + Drawer(CombinedGC &GC,unsigned long Depth,Rect Pos,Tree *Owner, + Tree::Item *Item) : + GC(GC), Cache(*((PkgTree *)Owner)->Cache), Pkg(Cache), + State(0), Height(Pos.h), Depth(Depth), + Owner(Owner), Item(Item), Pos(Pos) + { + Init(); + } + + Drawer(CombinedGC &GC,unsigned long Depth,Rect Pos,Tree *Owner, + pkgCache::Package *PkgP,Tree::Item *Item) : + GC(GC), Cache(*((PkgTree *)Owner)->Cache), Pkg(Cache,PkgP), + State(&Cache[Pkg]), Height(Pos.h), Depth(Depth), + Owner(Owner), Item(Item), Pos(Pos) + { + Init(); + } +}; + +#endif diff --git a/apt/gui/plus.xpm b/apt/gui/plus.xpm new file mode 100644 index 0000000..57901cb --- /dev/null +++ b/apt/gui/plus.xpm @@ -0,0 +1,90 @@ +/* XPM */ +static char * plus_xpm[] = { +"16 16 71 1", +" c #FFFFFFFFFFFF s Background", +". c #D1D1D1", +"+ c #5D5D5D", +"@ c #181818", +"# c #000000", +"$ c #171717", +"% c #595959", +"& c #CDCDCD", +"* c #A3A3A3", +"= c #272727", +"- c #919191", +"; c #D4D4D4", +"> c #EBEBEB", +", c #CACACA", +"' c #818181", +") c #202020", +"! c #989898", +"~ c #F3F3F3", +"{ c #F4F4F4", +"] c #757575", +"^ c #E9E9E9", +"/ c #DADADA", +"( c #C5C5C5", +"_ c #1C1C1C", +": c #C9C9C9", +"< c #5E5E5E", +"[ c #949494", +"} c #F6F6F6", +"| c #FBFBFB", +"1 c #343434", +"2 c #EDEDED", +"3 c #696969", +"4 c #4C4C4C", +"5 c #191919", +"6 c #E3E3E3", +"7 c #1D1D1D", +"8 c #444444", +"9 c #BFBFBF", +"0 c #959595", +"a c #121212", +"b c #EEEEEE", +"c c #161616", +"d c #101010", +"e c #B8B8B8", +"f c #9F9F9F", +"g c #F1F1F1", +"h c #C3C3C3", +"i c #AAAAAA", +"j c #858585", +"k c #5B5B5B", +"l c #868686", +"m c #E2E2E2", +"n c #C6C6C6", +"o c #B3B3B3", +"p c #555555", +"q c #464646", +"r c #CECECE", +"s c #222222", +"t c #D2D2D2", +"u c #CFCFCF", +"v c #CBCBCB", +"w c #B4B4B4", +"x c #151515", +"y c #9B9B9B", +"z c #747474", +"A c #A6A6A6", +"B c #B1B1B1", +"C c #8C8C8C", +"D c #525252", +"E c #131313", +"F c #4A4A4A", +" ", +" ", +" .+@#$%& ", +" *=-;>,')! ", +" .=~{]%^/(_: ", +" <[}|%12/(34 ", +" 56%%171890a ", +" #b%1cd78ef# ", +" @.2g1=/hija ", +" klm688nofpq ", +" rstuvhw*[xh ", +" y)zAB[kxC ", +" vDE#aFh ", +" ", +" ", +" "}; diff --git a/apt/gui/policy.cc b/apt/gui/policy.cc new file mode 100644 index 0000000..6656345 --- /dev/null +++ b/apt/gui/policy.cc @@ -0,0 +1,136 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: policy.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Policy - Contains a number of configurable algorithms designed to + effect the way things work. + + The policy class allows user control of some important policy choices + and algorithms. Other classes use this class to determine how to + make choices. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "policy.h" +#include "extracache.h" + /*}}}*/ + +Policy *Policy::Cur = new Policy; + +// Policy::Policy - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +Policy::Policy() +{ + Displayable.InProfile = false; + Displayable.Installed = true; + Displayable.ToUpgrade = false; + Displayable.ToDowngrade = false; + Displayable.HeldUpDn = false; + Displayable.New = false; + Displayable.Obsolete = false; + Displayable.NotInstalled = false; + Displayable.Broken = false; + Displayable.All = false; + + Columns.CurVersion = false; + Columns.InstVersion = true; + Columns.InstAsWell = true; + + ImportantDeps.Suggests = true; + ImportantDeps.Recommends = false; + + ShowSections = true; +} + /*}}}*/ +// Policy::GetCandidateVersion - Determine the candidate install ver /*{{{*/ +// --------------------------------------------------------------------- +/* This decides what version to offer for installation based on + user preferences. It is used to generate the extra cache which will + cache the result of this function. */ +pkgCache::VerIterator Policy::GetCandidateVer(pkgCache::PkgIterator Pkg) +{ + // Try to use an explicit target + if (Pkg->TargetVer == 0) + return Pkg.VersionList(); + else + return Pkg.TargetVer(); +} + /*}}}*/ +// Policy::ShouldDisplay - Determine if a package meets the policy /*{{{*/ +// --------------------------------------------------------------------- +/* We just run through all the items on the displayable list.. The + extra cache is used to speed this up. */ +bool Policy::ShouldDisplay(ExtraCache &Cache,pkgCache::PkgIterator Pkg) +{ + /* Packages without versions are not shown ever, these are probably + virtual package place holders or some other evilness */ + if (Pkg->VersionList == 0) + return false; + + // All Packages + if (Displayable.All == true) + return true; + + // Packages with an installed version + if (Displayable.Installed == true && Pkg->CurrentVer != 0) + return true; + + // Packages not installed + if (Displayable.NotInstalled == true && Pkg->CurrentVer == 0) + return true; + + // Already Cached info about the package + ExtraCache::StateCache &State = Cache[Pkg]; + + // Held upgrade/downgrade + if (Displayable.HeldUpDn == true && Pkg->CurrentVer != 0 && + State.Held() == true) + return true; + + // Broken + if (Displayable.Broken == true && + (State.DepState & ExtraCache::DepInstMin) == 0) + return true; + + // Target version is newer + if (Displayable.ToUpgrade == true && State.Upgrade() == true) + return true; + + // Cant downgrade a not installed package + if (Pkg->CurrentVer == 0) + return false; + + // Target version is older or delete is selected + if (Displayable.ToDowngrade == true && (State.Downgrade() == true || + State.Delete() == true)) + return true; + + return false; +} + /*}}}*/ +// Policy::IsImportantDep - Returns true if the dependency is important /*{{{*/ +// --------------------------------------------------------------------- +/* This is used to control what dependencies are important. An important + dependency is one that should be automatically installed but is not + critical for the package. The other type of dependency is a critical + dependency that must be present for the package to be installable. */ +bool Policy::IsImportantDep(pkgCache::DepIterator Dep) +{ + // Basic important dependencies + if (Dep.IsCritical() == true) + return true; + + // User control for suggests being important + if (ImportantDeps.Suggests == true && Dep->Type == pkgCache::Dep::Suggests) + return true; + + // User control for Recommends being important + if (ImportantDeps.Recommends == true && Dep->Type == pkgCache::Dep::Recommends) + return true; + + return false; +} + /*}}}*/ diff --git a/apt/gui/policy.h b/apt/gui/policy.h new file mode 100644 index 0000000..2014943 --- /dev/null +++ b/apt/gui/policy.h @@ -0,0 +1,83 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: policy.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Policy - Contains a number of configurable algorithms designed to + effect the way things work. + + Upgrade Policy - This controls the selection of packages for + 'Inst-Version'. + List Policy - Controls wheather a package is currently displayed + in the tree. + Column Policy - Controls wheather a column is displayed in the tree + + Terms: + Candidate Version - Version which is offered for install to the user. + This shows up as the Install-Version on the tree. + Install Version - Version that is actually going to be installed + This is the canidate version, current version or + none (remove). + Current Version - Version that is installed in the system right now. + Displayable - Meets the users profile/filter requirements + + This may end up being derived from a pkgPolicy class so alogrithms + in pkglib can use a similar scheme.. + + ##################################################################### */ + /*}}}*/ +#ifndef POLICY_H +#define POLICY_H + +#include + +class ExtraCache; +class Policy +{ + public: + + // Which packages to display + struct + { + bool InProfile; + bool Installed; + bool ToUpgrade; + bool ToDowngrade; + bool HeldUpDn; + bool New; + bool Obsolete; + bool NotInstalled; + bool Broken; + bool All; + } Displayable; + + // Which columns to display + struct ColumnsT + { + bool CurVersion; + bool InstVersion; + bool InstAsWell; + } Columns; + + struct + { + bool Suggests; + bool Recommends; + } ImportantDeps; + + bool ShowSections; + + // Single global instance of the policy class + static Policy *Cur; + + // Find the Install Candidate Version of a package + pkgCache::VerIterator GetCandidateVer(pkgCache::PkgIterator Pkg); + + // See if the Pkg meets the display policy + bool ShouldDisplay(ExtraCache &Cache,pkgCache::PkgIterator Pkg); + bool IsImportantDep(pkgCache::DepIterator Dep); + + Policy(); +}; + +#endif diff --git a/apt/gui/progressmeter.cc b/apt/gui/progressmeter.cc new file mode 100644 index 0000000..6da0164 --- /dev/null +++ b/apt/gui/progressmeter.cc @@ -0,0 +1,133 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: progressmeter.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Progress Meter - Graphical progress meter from the package library's + progress meter class + + This is split into two halfs, one is a meter dialog window the + other is an interfacing module for the libapt-pkg progress class. + It was designed to either run from a thread or directly within the + main task. + + ##################################################################### */ + /*}}}*/ +// Include /*{{{*/ +#include "progressmeter.h" +#include +#include + /*}}}*/ + +// ProgressWindow::ProgressWindow - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ProgressWindow::ProgressWindow(string Title,Widget *Parent) : + GUIWindow(Title,Parent) +{ + Meter = new Progress(this); + Operation = new TextWidget(this); + SubOp = new TextWidget(this); + Divider = new Separator(this); + + Operation->Text("Initializing..."); + } + /*}}}*/ +// ProgressWindow::~ProgressWindow - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ProgressWindow::~ProgressWindow() +{ + delete Meter; + delete Operation; + delete SubOp; + delete Divider; +} + /*}}}*/ +// ProgressWindow::Realize - Size the window /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ProgressWindow::Realize() +{ + ExtentFamily(); + if (TextGC::GC != 0) + { + Operation->Resize(Rect(1,0,58,1)); + SubOp->Resize(Rect(1,1,58,1)); + Meter->Resize(Rect(0,3,58,1)); + Divider->Resize(Rect(0,2,58,1)); + Resize(Rect(0,0,60,6)); + + Meter->Foreground(Wc_Magenta); + Meter->BorderWidth(0); + Meter->Background(Wc_Black); + } + + if (GraphicGC::GC != 0) + { + Operation->Font(SimpleFont("helvetica",140,SimpleFont::Bold)); + + unsigned int UnitHeight = SubOp->Size().h; + Resize(Rect(0,0,300,100)); + Operation->Resize(Rect(0.2*UnitHeight,0.6*UnitHeight, + Size().w - UnitHeight,Operation->IdealSize().y)); + SubOp->Resize(Rect(UnitHeight,Operation->Loc().y2 + 0.3*UnitHeight, + Size().w - UnitHeight,SubOp->Size().h)); + Divider->Resize(Rect(0,SubOp->Loc().y2 + 0.5*UnitHeight, + Size().w,Divider->Size().h)); + Meter->Resize(Rect(0.7*UnitHeight,Divider->Loc().y2 + 0.5*UnitHeight, + Size().w - 2*0.7*UnitHeight,Meter->Size().h)); + + Meter->Foreground(Wc_Blue); + Meter->Background(Wc_White); + } + + CenterWidget(this,Rect(0,0,Parent->Pos.w,Parent->Pos.h)); + + GUIWindow::Realize(); +} + /*}}}*/ + +// ProgressMeter::ProgressMeter - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ProgressMeter::ProgressMeter(string Title,Widget *Parent) +{ + Win = new ProgressWindow(Title,Parent); +} + /*}}}*/ +// ProgressMeter::~ProgressMeter - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ProgressMeter::~ProgressMeter() +{ + delete Win; +} + /*}}}*/ +// ProgressMeter::Update - Update the display /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ProgressMeter::Update() +{ + if (CheckChange(0.5) == false) + return; + + Widget::Lock Lock; + + Win->SetOp(Op); + Win->SetSubOp(SubOp); + Win->Percent(Percent); +} + /*}}}*/ +// ProgressMeter::Done - Finalize the display /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void ProgressMeter::Done() +{ + Widget::Lock Lock; + + Win->SetOp(Op); + Win->SetSubOp(SubOp); + Win->Percent(Percent); +} + /*}}}*/ diff --git a/apt/gui/progressmeter.h b/apt/gui/progressmeter.h new file mode 100644 index 0000000..dc289d3 --- /dev/null +++ b/apt/gui/progressmeter.h @@ -0,0 +1,53 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: progressmeter.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Progress Meter - Graphical progress meter from the package library's + progress meter class + + ##################################################################### */ + /*}}}*/ +#ifndef PROGRESSMETER_H +#define PROGRESSMETER_H + +#include +#include +#include +#include + +class ProgressWindow : public GUIWindow +{ + protected: + + Progress *Meter; + TextWidget *Operation; + TextWidget *SubOp; + Separator *Divider; + + virtual void Realize(); + + public: + + void SetOp(string Op) {Operation->Text(Op);}; + void SetSubOp(string Op) {SubOp->Text(Op);}; + void Percent(double Per) {Meter->Percent(Per);}; + + ProgressWindow(string Title,Widget *Parent); + virtual ~ProgressWindow(); +}; + +class ProgressMeter : public OpProgress +{ + virtual void Update(); + ProgressWindow *Win; + + public: + + virtual void Done(); + + ProgressMeter(string Title,Widget *Parent); + virtual ~ProgressMeter(); +}; + +#endif diff --git a/apt/gui/radiooff.xpm b/apt/gui/radiooff.xpm new file mode 100644 index 0000000..ae692db --- /dev/null +++ b/apt/gui/radiooff.xpm @@ -0,0 +1,62 @@ +/* XPM */ +static char * radiooff_xpm[] = { +"16 16 43 1", +" c #FFFFFFFFFFFF", +". c #D4D4D4", +"+ c #636363", +"@ c #1A1A1A", +"# c #000000", +"$ c #A8A8A8", +"% c #292929", +"& c #626262", +"* c #767676", +"= c #8A8A8A", +"- c #A5A5A5", +"; c #6F6F6F", +"> c #2A2A2A", +", c #4F4F4F", +"' c #A0A0A0", +") c #E6E6E6", +"! c #EFEFEF", +"~ c #F5F5F5", +"{ c #FFFFFF", +"] c #BCBCBC", +"^ c #404040", +"/ c #606060", +"( c #979797", +"_ c #EEEEEE", +": c #D8D8D8", +"< c #545454", +"[ c #C6C6C6", +"} c #FDFDFD", +"| c #6B6B6B", +"1 c #D1D1D1", +"2 c #585858", +"3 c #D6D6D6", +"4 c #616161", +"5 c #E9E9E9", +"6 c #353535", +"7 c #ACACAC", +"8 c #F3F3F3", +"9 c #464646", +"0 c #303030", +"a c #CDCDCD", +"b c #FEFEFE", +"c c #DEDEDE", +"d c #484848", +" ", +" ", +" .+@#@+. ", +" $%&*=-;%$ ", +" .>,')!~{]^. ", +" +/(_{{{{{:+ ", +" @<[{{{{{{}@ ", +" #|1{{{{{{{# ", +" @23{{{{{{}@ ", +" +4:{{{{{{5+ ", +" .678{{{{{9. ", +" $0ab{}cd$ ", +" .+@#@+. ", +" ", +" ", +" "}; diff --git a/apt/gui/radioon.xpm b/apt/gui/radioon.xpm new file mode 100644 index 0000000..7a28d2d --- /dev/null +++ b/apt/gui/radioon.xpm @@ -0,0 +1,64 @@ +/* XPM */ +static char * radioon_xpm[] = { +"16 16 45 1", +" c #FFFFFFFFFFFF", +". c #D4D4D4", +"+ c #636363", +"@ c #1A1A1A", +"# c #000000", +"$ c #A8A8A8", +"% c #292929", +"& c #626262", +"* c #767676", +"= c #8A8A8A", +"- c #A5A5A5", +"; c #6F6F6F", +"> c #2A2A2A", +", c #4F4F4F", +"' c #A0A0A0", +") c #E6E6E6", +"! c #EFEFEF", +"~ c #F5F5F5", +"{ c #FFFFFF", +"] c #BCBCBC", +"^ c #404040", +"/ c #606060", +"( c #979797", +"_ c #EEEEEE", +": c #D8D8D8", +"< c #545454", +"[ c #C6C6C6", +"} c #3D3D3D", +"| c #FDFDFD", +"1 c #6B6B6B", +"2 c #D1D1D1", +"3 c #828282", +"4 c #585858", +"5 c #D6D6D6", +"6 c #616161", +"7 c #E9E9E9", +"8 c #353535", +"9 c #ACACAC", +"0 c #CACACA", +"a c #464646", +"b c #303030", +"c c #CDCDCD", +"d c #FEFEFE", +"e c #DEDEDE", +"f c #484848", +" ", +" ", +" .+@#@+. ", +" $%&*=-;%$ ", +" .>,')!~{]^. ", +" +/(_{{{{{:+ ", +" @<[.<#}.{|@ ", +" #12<{3#}{{# ", +" @45#3###{|@ ", +" +6:}###}{7+ ", +" .890}#}.{a. ", +" $bcd{|ef$ ", +" .+@#@+. ", +" ", +" ", +" "}; diff --git a/apt/gui/recommends.xpm b/apt/gui/recommends.xpm new file mode 100644 index 0000000..c0c942c --- /dev/null +++ b/apt/gui/recommends.xpm @@ -0,0 +1,40 @@ +/* XPM */ +static char * recommends_xpm[] = { +"16 16 21 1", +" c #FFFFFFFFFFFF", +". c #919191", +"+ c #000000", +"@ c #9F9F9F", +"# c #DDDDDD", +"$ c #1E1E1E", +"% c #D1D1D1", +"& c #454545", +"* c #C0C0C0", +"= c #5D5D5D", +"- c #CFCFCF", +"; c #E7E7E7", +"> c #8B8B8B", +", c #A2A2A2", +"' c #9A9A9A", +") c #797979", +"! c #535353", +"~ c #5A5A5A", +"{ c #444444", +"] c #E8E8E8", +"^ c #CDCDCD", +" ", +" ", +" .+@ ", +" +#$% ", +" +#$% ", +" +#& ", +" +##+++* ", +" +++##=-;.+ ", +" #####*+.+. ", +" #####=-;.+ ", +" ***##.+>+, ", +" +++.')!;~{ ", +" ].+++++^ ", +" ", +" ", +" "}; diff --git a/apt/gui/section.xpm b/apt/gui/section.xpm new file mode 100644 index 0000000..6429d9d --- /dev/null +++ b/apt/gui/section.xpm @@ -0,0 +1,24 @@ +/* XPM */ +static char * section_xpm[] = { +"16 16 5 1", +" c #FFFFFFFFFFFF s Background", +". c #B6DA82070000", +"X c #FFFFFFFF0000", +"o c #FFFFD34C1861", +"O c #6185618571C6", +" ", +" ", +" ", +" ..... ", +" .......XXXoO ", +" .oooooo.XXXoO ", +" .........XXXoO ", +" .XXXXXXXXXXXoO ", +" .XXXXXXXXXXXoO ", +" .XXXXXXXXXXXoO ", +" .XXXXXXXXXXXoO ", +" .XXXXXXXXXXXoO ", +" . oO ", +" .ooooooooooooO ", +" OOOOOOOOOOOOO ", +" "}; diff --git a/apt/gui/statuswidgets.cc b/apt/gui/statuswidgets.cc new file mode 100644 index 0000000..55375f8 --- /dev/null +++ b/apt/gui/statuswidgets.cc @@ -0,0 +1,116 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: statuswidgets.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + StatusWidgets - The right hand status display widgets + + These show various bits of information derived from the package + control block. + + ##################################################################### */ + /*}}}*/ +#include "statuswidgets.h" +#include + +// MultiLineWidget::Render - Draw the description text with wrapping /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void MultiLineWidget::Render(CombinedGC &GC) +{ + /* + BasicRender(GC,true); + + if (Elm == 0) + return; + + vector Lines; + Elm->GetLines(Lines); + + AbsRect Loc(BorderX,BorderY,Pos.w - BorderX,Pos.h - BorderY); + GC->SetColor(Wc_Blue); + Loc.y1 = GC->DrawWrappedText(Loc,Elm->Value(),true); + GC->SetColor(iColor); + for (vector::iterator I = Lines.begin(); I < Lines.end();) + { + string Tmp = *I; + for (I++; I != Lines.end(); I++) + { + const char *J = (*I).begin(); + for (;J != (*I).end() && *J == ' '; J++); + if (J == (*I).end()) + { + I++; + break; + } + + // * indicates a list + if (*J == '*') + break; + + Tmp += ' '; + Tmp += string(J,(*I).end() - J); + } + + Loc.y1 = GC->DrawWrappedText(Loc,Tmp,true); + }*/ +} + /*}}}*/ + +// InfoWidget::InfoWidget - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +InfoWidget::InfoWidget(Widget *Parent) : BasicWidget(Parent) +{ + if (GraphicGC::GC != 0) + Margins(Point(1,1)); + BorderWidth(0); +}; + /*}}}*/ +// InfoWidget::Render - Draw all the single fields /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void InfoWidget::Render(CombinedGC &GC) +{ +/* BasicRender(GC,true); + + if (Info.isNull() == true) + return; + + long Height = GC->ExtentText(" ").h; + Point Pos(BorderX + iMargins.x,BorderY + iMargins.y); + for (const pkgElement **I = List; I != List + _count(List); I++) + { + if (*I == 0) + continue; + + string Tag = (*I)->Tag() + ": "; + string Value = (*I)->Value(); + long Width = GC->ExtentText(Tag).w; + GC->SetColor(Wc_Blue); + GC->DrawString(Pos,Tag); + GC->SetColor(iColor); + + if (Width + GC->ExtentText(Value).w < this->Pos.w) + { + GC->DrawString(Point(Pos.x + Width,Pos.y),Value); + Pos.y += Height; + } + else + { + Pos.y += Height; + Pos.y = GC->DrawWrappedText(AbsRect(Pos.x+Height,Pos.y, + this->Pos.w,this->Pos.h), + Value,false); + } + }*/ +} + /*}}}*/ +// InfoWidget::IdealSize - Returns the proper size for the info widget /*{{{*/ +// --------------------------------------------------------------------- +/* */ +Point InfoWidget::IdealSize() +{ + return Point(Parent->Pos.w,Parent->Pos.h); +} + /*}}}*/ diff --git a/apt/gui/statuswidgets.h b/apt/gui/statuswidgets.h new file mode 100644 index 0000000..2b7dab7 --- /dev/null +++ b/apt/gui/statuswidgets.h @@ -0,0 +1,37 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: statuswidgets.h,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + StatusWidgets - The right hand status display widgets + + These show various bits of information derived from the package + control block. + + ##################################################################### */ + /*}}}*/ +#ifndef STATUSWIDGETS_H +#define STATUSWIDGETS_H + +#include + +class MultiLineWidget : public BasicWidget +{ + virtual void Render(CombinedGC &GC); + + public: + + MultiLineWidget(Widget *Parent = 0) : BasicWidget(Parent) {}; +}; + +class InfoWidget : public BasicWidget +{ + virtual void Render(CombinedGC &GC); + + public: + + virtual Point IdealSize(); + InfoWidget(Widget *Parent = 0); +}; + +#endif diff --git a/apt/gui/suggests.xpm b/apt/gui/suggests.xpm new file mode 100644 index 0000000..ffecd3c --- /dev/null +++ b/apt/gui/suggests.xpm @@ -0,0 +1,23 @@ +/* XPM */ +static char * suggests_xpm[] = { +"16 16 4 1", +" c #FFFFFFFFFFFF", +". c #8E388A288E38", +"X c #FFFFD75C1861", +"o c #000000000000", +" ", +" . ", +" .X. ", +" .XXX. ", +" .XXX. ", +" .XXXXX. ", +" .XXoXX. ", +" .XXo.oXX. ", +" .XXXo.oXXX. ", +" .XXXo.oXXX. ", +" .XXXXXoXXXXX. ", +" .XXXXXXXXXXX. ", +".XXXXXXoXXXXXX. ", +".XXXXXXXXXXXXX. ", +"ooooooooooooooo ", +" "}; diff --git a/apt/gui/upgrade.xpm b/apt/gui/upgrade.xpm new file mode 100644 index 0000000..a8d9f83 --- /dev/null +++ b/apt/gui/upgrade.xpm @@ -0,0 +1,22 @@ +/* XPM */ +static char * upgrade_xpm[] = { +"16 16 3 1", +" c #FFFFFFFFFFFF s Background", +". c #000000", +"+ c #2F2F2F", +" ", +" ", +" ", +" ", +" . ", +" ... ", +" ..... ", +" .+..... ", +" ... ", +" ... ", +" ... ", +" ... ", +" ", +" ", +" ", +" "}; diff --git a/apt/intl/CVS/Entries b/apt/intl/CVS/Entries new file mode 100644 index 0000000..b5e84f6 --- /dev/null +++ b/apt/intl/CVS/Entries @@ -0,0 +1,24 @@ +/ChangeLog/1.1/Fri Aug 10 14:03:21 2001// +/Makefile.in/1.1/Fri Aug 10 14:03:22 2001// +/VERSION/1.1/Fri Aug 10 14:03:22 2001// +/bindtextdom.c/1.1/Fri Aug 10 14:03:22 2001// +/cat-compat.c/1.1/Fri Aug 10 14:03:28 2001// +/dcgettext.c/1.1/Fri Aug 10 14:03:29 2001// +/dgettext.c/1.1/Fri Aug 10 14:03:29 2001// +/explodename.c/1.1/Fri Aug 10 14:03:29 2001// +/finddomain.c/1.1/Fri Aug 10 14:03:29 2001// +/gettext.c/1.1/Fri Aug 10 14:03:29 2001// +/gettext.h/1.1/Fri Aug 10 14:03:29 2001// +/gettextP.h/1.1/Fri Aug 10 14:03:29 2001// +/hash-string.h/1.1/Fri Aug 10 14:03:29 2001// +/intl-compat.c/1.1/Fri Aug 10 14:03:29 2001// +/l10nflist.c/1.1/Fri Aug 10 14:03:29 2001// +/libgettext.h/1.1/Fri Aug 10 14:03:29 2001// +/linux-msg.sed/1.1/Fri Aug 10 14:03:29 2001// +/loadinfo.h/1.1/Fri Aug 10 14:03:29 2001// +/loadmsgcat.c/1.1/Fri Aug 10 14:03:31 2001// +/localealias.c/1.1/Fri Aug 10 14:03:31 2001// +/po2tbl.sed.in/1.1/Fri Aug 10 14:03:31 2001// +/textdomain.c/1.1/Fri Aug 10 14:03:31 2001// +/xopen-msg.sed/1.1/Fri Aug 10 14:03:31 2001// +D diff --git a/apt/intl/CVS/Repository b/apt/intl/CVS/Repository new file mode 100644 index 0000000..da3eb3e --- /dev/null +++ b/apt/intl/CVS/Repository @@ -0,0 +1 @@ +rapt/intl diff --git a/apt/intl/CVS/Root b/apt/intl/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/intl/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/intl/ChangeLog b/apt/intl/ChangeLog new file mode 100644 index 0000000..75cd3f4 --- /dev/null +++ b/apt/intl/ChangeLog @@ -0,0 +1,1106 @@ +1999-08-12 Paul Eggert + + * localealias.c (memcpy): Return 2nd argument, so that it's + compatible with memcpy spec. + +1998-10-20 Paul Eggert + + * po2tbl.sed.in: Escape trigraphs. + +1999-08-11 Paul Eggert + + * Makefile.in (uninstall): Fix problem in most recent change, + on old BSD/OS hosts whose buggy shells report nonzero exit status + for `if false; then true; fi'. + +1998-10-05 Jim Meyering + + * Makefile.in (uninstall): Uninstall only if the current package is + gettext. From Akim Demaille. + +1998-04-29 Ulrich Drepper + + * intl/localealias.c (read_alias_file): Use unsigned char for + local variables. Remove unused variable tp. + * intl/l10nflist.c (_nl_normalize_codeset): Use unsigned char * + for type of codeset. For loosing Solaris systems. + * intl/loadinfo.h: Adapt prototype of _nl_normalize_codeset. + * intl/bindtextdom.c (BINDTEXTDOMAIN): Don't define local variable + len if not needed. + Patches by Jim Meyering. + +1998-04-28 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): Don't assign the element use_mmap if + mmap is not supported. + + * hash-string.h: Don't include . + +1998-04-27 Ulrich Drepper + + * textdomain.c: Use strdup is available. + + * localealias.c: Define HAVE_MEMPCPY so that we can use this + function. Define and use semapahores to protect modfication of + global objects when compiling for glibc. Add code to allow + freeing alias table. + + * l10nflist.c: Don't assume stpcpy not being a macro. + + * gettextP.h: Define internal_function macri if not already done. + Use glibc byte-swap macros instead of defining SWAP when compiled + for glibc. + (struct loaded_domain): Add elements to allow unloading. + + * Makefile.in (distclean): Don't remove libintl.h here. + + * bindtextdomain.c: Carry over changes from glibc. Use strdup if + available. + + * dcgettext.c: Don't assume stpcpy not being a macro. Mark internal + functions. Add memory freeing code for glibc. + + * dgettext.c: Update copyright. + + * explodename.c: Include stdlib.h and string.h only if they exist. + Use strings.h eventually. + + * finddomain.c: Mark internal functions. Use strdup if available. + Add memory freeing code for glibc. + +1997-10-10 20:00 Ulrich Drepper + + * libgettext.h: Fix dummy textdomain and bindtextdomain macros. + They should return reasonable values. + Reported by Tom Tromey . + +1997-09-16 03:33 Ulrich Drepper + + * libgettext.h: Define PARAMS also to `args' if __cplusplus is defined. + * intlh.inst.in: Likewise. + Reported by Jean-Marc Lasgouttes . + + * libintl.glibc: Update from current glibc version. + +1997-09-06 02:10 Ulrich Drepper + + * intlh.inst.in: Reformat copyright. + +1997-08-19 15:22 Ulrich Drepper + + * dcgettext.c (DCGETTEXT): Remove wrong comment. + +1997-08-16 00:13 Ulrich Drepper + + * Makefile.in (install-data): Don't change directory to install. + +1997-08-01 14:30 Ulrich Drepper + + * cat-compat.c: Fix copyright. + + * localealias.c: Don't define strchr unless !HAVE_STRCHR. + + * loadmsgcat.c: Update copyright. Fix typos. + + * l10nflist.c: Don't define strchr unless !HAVE_STRCHR. + (_nl_make_l10nflist): Handle sponsor and revision correctly. + + * gettext.c: Update copyright. + * gettext.h: Likewise. + * hash-string.h: Likewise. + + * finddomain.c: Remoave dead code. Define strchr only if + !HAVE_STRCHR. + + * explodename.c: Include . + + * explodename.c: Reformat copyright text. + (_nl_explode_name): Fix typo. + + * dcgettext.c: Define and use __set_errno. + (guess_category_value): Don't use setlocale if HAVE_LC_MESSAGES is + not defined. + + * bindtextdom.c: Pretty printing. + +1997-05-01 02:25 Ulrich Drepper + + * dcgettext.c (guess_category_value): Don't depend on + HAVE_LC_MESSAGES. We don't need the macro here. + Patch by Bruno Haible . + + * cat-compat.c (textdomain): DoN't refer to HAVE_SETLOCALE_NULL + macro. Instead use HAVE_LOCALE_NULL and define it when using + glibc, as in dcgettext.c. + Patch by Bruno Haible . + + * Makefile.in (CPPFLAGS): New variable. Reported by Franc,ois + Pinard. + +Mon Mar 10 06:51:17 1997 Ulrich Drepper + + * Makefile.in: Implement handling of libtool. + + * gettextP.h: Change data structures for use of generic lowlevel + i18n file handling. + +Wed Dec 4 20:21:18 1996 Ulrich Drepper + + * textdomain.c: Put parentheses around arguments of memcpy macro + definition. + * localealias.c: Likewise. + * l10nflist.c: Likewise. + * finddomain.c: Likewise. + * bindtextdom.c: Likewise. + Reported by Thomas Esken. + +Mon Nov 25 22:57:51 1996 Ulrich Drepper + + * textdomain.c: Move definition of `memcpy` macro to right + position. + +Fri Nov 22 04:01:58 1996 Ulrich Drepper + + * finddomain.c [!HAVE_STRING_H && !_LIBC]: Define memcpy using + bcopy if not already defined. Reported by Thomas Esken. + * bindtextdom.c: Likewise. + * l10nflist.c: Likewise. + * localealias.c: Likewise. + * textdomain.c: Likewise. + +Tue Oct 29 11:10:27 1996 Ulrich Drepper + + * Makefile.in (libdir): Change to use exec_prefix instead of + prefix. Reported by Knut-HеvardAksnes . + +Sat Aug 31 03:07:09 1996 Ulrich Drepper + + * l10nflist.c (_nl_normalize_codeset): We convert to lower case, + so don't prepend uppercase `ISO' for only numeric arg. + +Fri Jul 19 00:15:46 1996 Ulrich Drepper + + * l10nflist.c: Move inclusion of argz.h, ctype.h, stdlib.h after + definition of _GNU_SOURCE. Patch by Roland McGrath. + + * Makefile.in (uninstall): Fix another bug with `for' loop and + empty arguments. Patch by Jim Meyering. Correct name os + uninstalled files: no intl- prefix anymore. + + * Makefile.in (install-data): Again work around shells which + cannot handle mpty for list. Reported by Jim Meyering. + +Sat Jul 13 18:11:35 1996 Ulrich Drepper + + * Makefile.in (install): Split goal. Now depend on install-exec + and install-data. + (install-exec, install-data): New goals. Created from former + install goal. + Reported by Karl Berry. + +Sat Jun 22 04:58:14 1996 Ulrich Drepper + + * Makefile.in (MKINSTALLDIRS): New variable. Path to + mkinstalldirs script. + (install): use MKINSTALLDIRS variable or if the script is not present + try to find it in the $top_scrdir). + +Wed Jun 19 02:56:56 1996 Ulrich Drepper + + * l10nflist.c: Linux libc *partly* includes the argz_* functions. + Grr. Work around by renaming the static version and use macros + for renaming. + +Tue Jun 18 20:11:17 1996 Ulrich Drepper + + * l10nflist.c: Correct presence test macros of __argz_* functions. + + * l10nflist.c: Include based on test of it instead when + __argz_* functions are available. + Reported by Andreas Schwab. + +Thu Jun 13 15:17:44 1996 Ulrich Drepper + + * explodename.c, l10nflist.c: Define NULL for dumb systems. + +Tue Jun 11 17:05:13 1996 Ulrich Drepper + + * intlh.inst.in, libgettext.h (dcgettext): Rename local variable + result to __result to prevent name clash. + + * l10nflist.c, localealias.c, dcgettext.c: Define _GNU_SOURCE to + get prototype for stpcpy and strcasecmp. + + * intlh.inst.in, libgettext.h: Move declaration of + `_nl_msg_cat_cntr' outside __extension__ block to prevent warning + from gcc's -Wnested-extern option. + +Fri Jun 7 01:58:00 1996 Ulrich Drepper + + * Makefile.in (install): Remove comment. + +Thu Jun 6 17:28:17 1996 Ulrich Drepper + + * Makefile.in (install): Work around for another Buglix stupidity. + Always use an `else' close for `if's. Reported by Nelson Beebe. + + * Makefile.in (intlh.inst): Correct typo in phony rule. + Reported by Nelson Beebe. + +Thu Jun 6 01:49:52 1996 Ulrich Drepper + + * dcgettext.c (read_alias_file): Rename variable alloca_list to + block_list as the macro calls assume. + Patch by Eric Backus. + + * localealias.c [!HAVE_ALLOCA]: Define alloca as macro using + malloc. + (read_alias_file): Rename varriabe alloca_list to block_list as the + macro calls assume. + Patch by Eric Backus. + + * l10nflist.c: Correct conditional for inclusion. + Reported by Roland McGrath. + + * Makefile.in (all): Depend on all-@USE_INCLUDED_LIBINTL@, not + all-@USE_NLS@. + + * Makefile.in (install): intlh.inst comes from local dir, not + $(srcdir). + + * Makefile.in (intlh.inst): Special handling of this goal. If + used in gettext, this is really a rul to construct this file. If + used in any other package it is defined as a .PHONY rule with + empty body. + + * finddomain.c: Extract locale file information handling into + l10nfile.c. Rename local stpcpy__ function to stpcpy. + + * dcgettext.c (stpcpy): Add local definition. + + * l10nflist.c: Solve some portability problems. Patches partly by + Thomas Esken. Add local definition of stpcpy. + +Tue Jun 4 02:47:49 1996 Ulrich Drepper + + * intlh.inst.in: Don't depend including on + HAVE_LOCALE_H. Instead configure must rewrite this fiile + depending on the result of the configure run. + + * Makefile.in (install): libintl.inst is now called intlh.inst. + Add rules for updating intlh.inst from intlh.inst.in. + + * libintl.inst: Renamed to intlh.inst.in. + + * localealias.c, dcgettext.c [__GNUC__]: Define HAVE_ALLOCA to 1 + because gcc has __buitlin_alloca. + Reported by Roland McGrath. + +Mon Jun 3 00:32:16 1996 Ulrich Drepper + + * Makefile.in (installcheck): New goal to fulfill needs of + automake's distcheck. + + * Makefile.in (install): Reorder commands so that VERSION is + found. + + * Makefile.in (gettextsrcdir): Now use subdirectory intl/ in + @datadir@/gettext. + (COMSRCS): Add l10nfile.c. + (OBJECTS): Add l10nfile.o. + (DISTFILES): Rename to DISTFILE.normal. Remove $(DISTFILES.common). + (DISTFILE.gettext): Remove $(DISTFILES.common). + (all-gettext): Remove goal. + (install): If $(PACKAGE) = gettext install, otherwose do nothing. No + package but gettext itself should install libintl.h + headers. + (dist): Extend goal to work for gettext, too. + (dist-gettext): Remove goal. + + * dcgettext.c [!HAVE_ALLOCA]: Define macro alloca by using malloc. + +Sun Jun 2 17:33:06 1996 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): Parameter is now comes from + find_l10nfile. + +Sat Jun 1 02:23:03 1996 Ulrich Drepper + + * l10nflist.c (__argz_next): Add definition. + + * dcgettext.c [!HAVE_ALLOCA]: Add code for handling missing alloca + code. Use new l10nfile handling. + + * localealias.c [!HAVE_ALLOCA]: Add code for handling missing + alloca code. + + * l10nflist.c: Initial revision. + +Tue Apr 2 18:51:18 1996 Ulrich Drepper + + * Makefile.in (all-gettext): New goal. Same as all-yes. + +Thu Mar 28 23:01:22 1996 Karl Eichwalder + + * Makefile.in (gettextsrcdir): Define using @datadir@. + +Tue Mar 26 12:39:14 1996 Ulrich Drepper + + * finddomain.c: Include . Reported by Roland McGrath. + +Sat Mar 23 02:00:35 1996 Ulrich Drepper + + * finddomain.c (stpcpy): Rename to stpcpy__ to prevent clashing + with external declaration. + +Sat Mar 2 00:47:09 1996 Ulrich Drepper + + * Makefile.in (all-no): Rename from all_no. + +Sat Feb 17 00:25:59 1996 Ulrich Drepper + + * gettextP.h [loaded_domain]: Array `successor' must now contain up + to 63 elements (because of codeset name normalization). + + * finddomain.c: Implement codeset name normalization. + +Thu Feb 15 04:39:09 1996 Ulrich Drepper + + * Makefile.in (all): Define to `all-@USE_NLS@'. + (all-yes, all_no): New goals. `all-no' is noop, `all-yes' + is former all. + +Mon Jan 15 21:46:01 1996 Howard Gayle + + * localealias.c (alias_compare): Increment string pointers in loop + of strcasecmp replacement. + +Fri Dec 29 21:16:34 1995 Ulrich Drepper + + * Makefile.in (install-src): Who commented this goal out ? :-) + +Fri Dec 29 15:08:16 1995 Ulrich Drepper + + * dcgettext.c (DCGETTEXT): Save `errno'. Failing system calls + should not effect it because a missing catalog is no error. + Reported by Harald Knig . + +Tue Dec 19 22:09:13 1995 Ulrich Drepper + + * Makefile.in (Makefile): Explicitly use $(SHELL) for running + shell scripts. + +Fri Dec 15 17:34:59 1995 Andreas Schwab + + * Makefile.in (install-src): Only install library and header when + we use the own implementation. Don't do it when using the + system's gettext or catgets functions. + + * dcgettext.c (find_msg): Must not swap domain->hash_size here. + +Sat Dec 9 16:24:37 1995 Ulrich Drepper + + * localealias.c, libintl.inst, libgettext.h, hash-string.h, + gettextP.h, finddomain.c, dcgettext.c, cat-compat.c: + Use PARAMS instead of __P. Suggested by Roland McGrath. + +Tue Dec 5 11:39:14 1995 Larry Schwimmer + + * libgettext.h: Use `#if !defined (_LIBINTL_H)' instead of `#if + !_LIBINTL_H' because Solaris defines _LIBINTL_H as empty. + +Mon Dec 4 15:42:07 1995 Ulrich Drepper + + * Makefile.in (install-src): + Install libintl.inst instead of libintl.h.install. + +Sat Dec 2 22:51:38 1995 Marcus Daniels + + * cat-compat.c (textdomain): + Reverse order in which files are tried you load. First + try local file, when this failed absolute path. + +Wed Nov 29 02:03:53 1995 Nelson H. F. Beebe + + * cat-compat.c (bindtextdomain): Add missing { }. + +Sun Nov 26 18:21:41 1995 Ulrich Drepper + + * libintl.inst: Add missing __P definition. Reported by Nelson Beebe. + + * Makefile.in: + Add dummy `all' and `dvi' goals. Reported by Tom Tromey. + +Sat Nov 25 16:12:01 1995 Franc,ois Pinard + + * hash-string.h: Capitalize arguments of macros. + +Sat Nov 25 12:01:36 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): Prevent files names longer than 13 + characters. libintl.h.glibc->libintl.glibc, + libintl.h.install->libintl.inst. Reported by Joshua R. Poulson. + +Sat Nov 25 11:31:12 1995 Eric Backus + + * dcgettext.c: Fix bug in preprocessor conditionals. + +Sat Nov 25 02:35:27 1995 Nelson H. F. Beebe + + * libgettext.h: Solaris cc does not understand + #if !SYMBOL1 && !SYMBOL2. Sad but true. + +Thu Nov 23 16:22:14 1995 Ulrich Drepper + + * hash-string.h (hash_string): + Fix for machine with >32 bit `unsigned long's. + + * dcgettext.c (DCGETTEXT): + Fix horrible bug in loop for alternative translation. + +Thu Nov 23 01:45:29 1995 Ulrich Drepper + + * po2tbl.sed.in, linux-msg.sed, xopen-msg.sed: + Some further simplifications in message number generation. + +Mon Nov 20 21:08:43 1995 Ulrich Drepper + + * libintl.h.glibc: Use __const instead of const in prototypes. + + * Makefile.in (install-src): + Install libintl.h.install instead of libintl.h. This + is a stripped-down version. Suggested by Peter Miller. + + * libintl.h.install, libintl.h.glibc: Initial revision. + + * localealias.c (_nl_expand_alias, read_alias_file): + Protect prototypes in type casts by __P. + +Tue Nov 14 16:43:58 1995 Ulrich Drepper + + * hash-string.h: Correct prototype for hash_string. + +Sun Nov 12 12:42:30 1995 Ulrich Drepper + + * hash-string.h (hash_string): Add prototype. + + * gettextP.h: Fix copyright. + (SWAP): Add prototype. + +Wed Nov 8 22:56:33 1995 Ulrich Drepper + + * localealias.c (read_alias_file): Forgot sizeof. + Avoid calling *printf function. This introduces a big overhead. + Patch by Roland McGrath. + +Tue Nov 7 14:21:08 1995 Ulrich Drepper + + * finddomain.c, cat-compat.c: Wrong indentation in #if for stpcpy. + + * finddomain.c (stpcpy): + Define substitution function local. The macro was to flaky. + + * cat-compat.c: Fix typo. + + * xopen-msg.sed, linux-msg.sed: + While bringing message number to right place only accept digits. + + * linux-msg.sed, xopen-msg.sed: Now that the counter does not have + leading 0s we don't need to remove them. Reported by Marcus + Daniels. + + * Makefile.in (../po/cat-id-tbl.o): Use $(top_srdir) in + dependency. Reported by Marcus Daniels. + + * cat-compat.c: (stpcpy) [!_LIBC && !HAVE_STPCPY]: Define replacement. + Generally cleanup using #if instead of #ifndef. + + * Makefile.in: Correct typos in comment. By Franc,ois Pinard. + +Mon Nov 6 00:27:02 1995 Ulrich Drepper + + * Makefile.in (install-src): Don't install libintl.h and libintl.a + if we use an available gettext implementation. + +Sun Nov 5 22:02:08 1995 Ulrich Drepper + + * libgettext.h: Fix typo: HAVE_CATGETTS -> HAVE_CATGETS. Reported + by Franc,ois Pinard. + + * libgettext.h: Use #if instead of #ifdef/#ifndef. + + * finddomain.c: + Comments describing what has to be done should start with FIXME. + +Sun Nov 5 19:38:01 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): Split. Use DISTFILES with normal meaning. + DISTFILES.common names the files common to both dist goals. + DISTFILES.gettext are the files only distributed in GNU gettext. + +Sun Nov 5 17:32:54 1995 Ulrich Drepper + + * dcgettext.c (DCGETTEXT): Correct searching in derived locales. + This was necessary since a change in _nl_find_msg several weeks + ago. I really don't know this is still not fixed. + +Sun Nov 5 12:43:12 1995 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): Test for FILENAME == NULL. This + might mark a special condition. + + * finddomain.c (make_entry_rec): Don't make illegal entry as decided. + + * Makefile.in (dist): Suppress error message when ln failed. + Get files from $(srcdir) explicitly. + + * libgettext.h (gettext_const): Rename to gettext_noop. + +Fri Nov 3 07:36:50 1995 Ulrich Drepper + + * finddomain.c (make_entry_rec): + Protect against wrong locale names by testing mask. + + * libgettext.h (gettext_const): Add macro definition. + Capitalize macro arguments. + +Thu Nov 2 23:15:51 1995 Ulrich Drepper + + * finddomain.c (_nl_find_domain): + Test for pointer != NULL before accessing value. + Reported by Tom Tromey. + + * gettext.c (NULL): + Define as (void*)0 instad of 0. Reported by Franc,ois Pinard. + +Mon Oct 30 21:28:52 1995 Ulrich Drepper + + * po2tbl.sed.in: Serious typo bug fixed by Jim Meyering. + +Sat Oct 28 23:20:47 1995 Ulrich Drepper + + * libgettext.h: Disable dcgettext optimization for Solaris 2.3. + + * localealias.c (alias_compare): + Peter Miller reported that tolower in some systems is + even dumber than I thought. Protect call by `isupper'. + +Fri Oct 27 22:22:51 1995 Ulrich Drepper + + * Makefile.in (libdir, includedir): New variables. + (install-src): Install libintl.a and libintl.h in correct dirs. + +Fri Oct 27 22:07:29 1995 Ulrich Drepper + + * Makefile.in (SOURCES): Fix typo: intrl.compat.c -> intl-compat.c. + + * po2tbl.sed.in: Patch for buggy SEDs by Christian von Roques. + + * localealias.c: + Fix typo and superflous test. Reported by Christian von Roques. + +Fri Oct 6 11:52:05 1995 Ulrich Drepper + + * finddomain.c (_nl_find_domain): + Correct some remainder from the pre-CEN syntax. Now + we don't have a constant number of successors anymore. + +Wed Sep 27 21:41:13 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): Add libintl.h.glibc. + + * Makefile.in (dist-libc): Add goal for packing sources for glibc. + (COMSRCS, COMHDRS): Splitted to separate sources shared with glibc. + + * loadmsgcat.c: Forget to continue #if line. + + * localealias.c: + [_LIBC]: Rename strcasecmp to __strcasecmp to keep ANSI C name + space clean. + + * dcgettext.c, finddomain.c: Better comment to last change. + + * loadmsgcat.c: + [_LIBC]: Rename fstat, open, close, read, mmap, and munmap to + __fstat, __open, __close, __read, __mmap, and __munmap resp + to keep ANSI C name space clean. + + * finddomain.c: + [_LIBC]: Rename stpcpy to __stpcpy to keep ANSI C name space clean. + + * dcgettext.c: + [_LIBC]: Rename getced and stpcpy to __getcwd and __stpcpy resp to + keep ANSI C name space clean. + + * libgettext.h: + Include sys/types.h for those old SysV systems out there. + Reported by Francesco Potorti`. + + * loadmsgcat.c (use_mmap): Define if compiled for glibc. + + * bindtextdom.c: Include all those standard headers + unconditionally if _LIBC is defined. + + * finddomain.c: Fix 2 times defiend -> defined. + + * textdomain.c: Include libintl.h instead of libgettext.h when + compiling for glibc. Include all those standard headers + unconditionally if _LIBC is defined. + + * localealias.c, loadmsgcat.c: Prepare to be compiled in glibc. + + * gettext.c: + Include libintl.h instead of libgettext.h when compiling for glibc. + Get NULL from stddef.h if we compile for glibc. + + * finddomain.c: Include libintl.h instead of libgettext.h when + compiling for glibc. Include all those standard headers + unconditionally if _LIBC is defined. + + * dcgettext.c: Include all those standard headers unconditionally + if _LIBC is defined. + + * dgettext.c: If compiled in glibc include libintl.h instead of + libgettext.h. + (locale.h): Don't rely on HAVE_LOCALE_H when compiling for glibc. + + * dcgettext.c: If compiled in glibc include libintl.h instead of + libgettext.h. + (getcwd): Don't rely on HAVE_GETCWD when compiling for glibc. + + * bindtextdom.c: + If compiled in glibc include libintl.h instead of libgettext.h. + +Mon Sep 25 22:23:06 1995 Ulrich Drepper + + * localealias.c (_nl_expand_alias): Don't call bsearch if NMAP <= 0. + Reported by Marcus Daniels. + + * cat-compat.c (bindtextdomain): + String used in putenv must not be recycled. + Reported by Marcus Daniels. + + * libgettext.h (__USE_GNU_GETTEXT): + Additional symbol to signal that we use GNU gettext + library. + + * cat-compat.c (bindtextdomain): + Fix bug with the strange stpcpy replacement. + Reported by Nelson Beebe. + +Sat Sep 23 08:23:51 1995 Ulrich Drepper + + * cat-compat.c: Include for stpcpy prototype. + + * localealias.c (read_alias_file): + While expand strdup code temporary variable `cp' hided + higher level variable with same name. Rename to `tp'. + + * textdomain.c (textdomain): + Avoid warning by using temporary variable in strdup code. + + * finddomain.c (_nl_find_domain): Remove unused variable `application'. + +Thu Sep 21 15:51:44 1995 Ulrich Drepper + + * localealias.c (alias_compare): + Use strcasecmp() only if available. Else use + implementation in place. + + * intl-compat.c: + Wrapper functions now call *__ functions instead of __*. + + * libgettext.h: Declare prototypes for *__ functions instead for __*. + + * cat-compat.c, loadmsgcat.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + + * bindtextdom.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + Rename to bindtextdomain__ if not used in GNU C Library. + + * dgettext.c: + Rename function to dgettext__ if not used in GNU C Library. + + * gettext.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + Functions now called gettext__ if not used in GNU C Library. + + * dcgettext.c, localealias.c, textdomain.c, finddomain.c: + Don't use xmalloc, xstrdup, and stpcpy. These functions are not part + of the standard libc and so prevent libintl.a from being used + standalone. + +Sun Sep 17 23:14:49 1995 Ulrich Drepper + + * finddomain.c: Correct some bugs in handling of CEN standard + locale definitions. + +Thu Sep 7 01:49:28 1995 Ulrich Drepper + + * finddomain.c: Implement CEN syntax. + + * gettextP.h (loaded_domain): Extend number of successors to 31. + +Sat Aug 19 19:25:29 1995 Ulrich Drepper + + * Makefile.in (aliaspath): Remove path to X11 locale dir. + + * Makefile.in: Make install-src depend on install. This helps + gettext to install the sources and other packages can use the + install goal. + +Sat Aug 19 15:19:33 1995 Ulrich Drepper + + * Makefile.in (uninstall): Remove stuff installed by install-src. + +Tue Aug 15 13:13:53 1995 Ulrich Drepper + + * VERSION.in: Initial revision. + + * Makefile.in (DISTFILES): + Add VERSION file. This is not necessary for gettext, but + for other packages using this library. + +Tue Aug 15 06:16:44 1995 Ulrich Drepper + + * gettextP.h (_nl_find_domain): + New prototype after changing search strategy. + + * finddomain.c (_nl_find_domain): + We now try only to find a specified catalog. Fall back to other + catalogs listed in the locale list is now done in __dcgettext. + + * dcgettext.c (__dcgettext): + Now we provide message fall back even to different languages. + I.e. if a message is not available in one language all the other + in the locale list a tried. Formerly fall back was only possible + within one language. Implemented by moving one loop from + _nl_find_domain to here. + +Mon Aug 14 23:45:50 1995 Ulrich Drepper + + * Makefile.in (gettextsrcdir): + Directory where source of GNU gettext library are made + available. + (INSTALL, INSTALL_DATA): Programs used for installing sources. + (gettext-src): New. Rule to install GNU gettext sources for use in + gettextize shell script. + +Sun Aug 13 14:40:48 1995 Ulrich Drepper + + * loadmsgcat.c (_nl_load_domain): + Use mmap for loading only when munmap function is + also available. + + * Makefile.in (install): Depend on `all' goal. + +Wed Aug 9 11:04:33 1995 Ulrich Drepper + + * localealias.c (read_alias_file): + Do not overwrite '\n' when terminating alias value string. + + * localealias.c (read_alias_file): + Handle long lines. Ignore the rest not fitting in + the buffer after the initial `fgets' call. + +Wed Aug 9 00:54:29 1995 Ulrich Drepper + + * gettextP.h (_nl_load_domain): + Add prototype, replacing prototype for _nl_load_msg_cat. + + * finddomain.c (_nl_find_domain): + Remove unneeded variable filename and filename_len. + (expand_alias): Remove prototype because functions does not + exist anymore. + + * localealias.c (read_alias_file): + Change type of fname_len parameter to int. + (xmalloc): Add prototype. + + * loadmsgcat.c: Better prototypes for xmalloc. + +Tue Aug 8 22:30:39 1995 Ulrich Drepper + + * finddomain.c (_nl_find_domain): + Allow alias name to be constructed from the four components. + + * Makefile.in (aliaspath): New variable. Set to preliminary value. + (SOURCES): Add localealias.c. + (OBJECTS): Add localealias.o. + + * gettextP.h: Add prototype for _nl_expand_alias. + + * finddomain.c: Aliasing handled in intl/localealias.c. + + * localealias.c: Aliasing for locale names. + + * bindtextdom.c: Better prototypes for xmalloc and xstrdup. + +Mon Aug 7 23:47:42 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): gettext.perl is now found in misc/. + + * cat-compat.c (bindtextdomain): + Correct implementation. dirname parameter was not used. + Reported by Marcus Daniels. + + * gettextP.h (loaded_domain): + New fields `successor' and `decided' for oo, lazy + message handling implementation. + + * dcgettext.c: + Adopt for oo, lazy message handliing. + Now we can inherit translations from less specific locales. + (find_msg): New function. + + * loadmsgcat.c, finddomain.c: + Complete rewrite. Implement oo, lazy message handling :-). + We now have an additional environment variable `LANGUAGE' with + a higher priority than LC_ALL for the LC_MESSAGE locale. + Here we can set a colon separated list of specifications each + of the form `language[_territory[.codeset]][@modifier]'. + +Sat Aug 5 09:55:42 1995 Ulrich Drepper + + * finddomain.c (unistd.h): + Include to get _PC_PATH_MAX defined on system having it. + +Fri Aug 4 22:42:00 1995 Ulrich Drepper + + * finddomain.c (stpcpy): Include prototype. + + * Makefile.in (dist): Remove `copying instead' message. + +Wed Aug 2 18:52:03 1995 Ulrich Drepper + + * Makefile.in (ID, TAGS): Do not use $^. + +Tue Aug 1 20:07:11 1995 Ulrich Drepper + + * Makefile.in (TAGS, ID): Use $^ as command argument. + (TAGS): Give etags -o option t write to current directory, + not $(srcdir). + (ID): Use $(srcdir) instead os $(top_srcdir)/src. + (distclean): Remove ID. + +Sun Jul 30 11:51:46 1995 Ulrich Drepper + + * Makefile.in (gnulocaledir): + New variable, always using share/ for data directory. + (DEFS): Add GNULOCALEDIR, used in finddomain.c. + + * finddomain.c (_nl_default_dirname): + Set to GNULOCALEDIR, because it always has to point + to the directory where GNU gettext Library writes it to. + + * intl-compat.c (textdomain, bindtextdomain): + Undefine macros before function definition. + +Sat Jul 22 01:10:02 1995 Ulrich Drepper + + * libgettext.h (_LIBINTL_H): + Protect definition in case where this file is included as + libgettext.h on Solaris machines. Add comment about this. + +Wed Jul 19 02:36:42 1995 Ulrich Drepper + + * intl-compat.c (textdomain): Correct typo. + +Wed Jul 19 01:51:35 1995 Ulrich Drepper + + * dcgettext.c (dcgettext): Function now called __dcgettext. + + * dgettext.c (dgettext): Now called __dgettext and calls + __dcgettext. + + * gettext.c (gettext): + Function now called __gettext and calls __dgettext. + + * textdomain.c (textdomain): Function now called __textdomain. + + * bindtextdom.c (bindtextdomain): Function now called + __bindtextdomain. + + * intl-compat.c: Initial revision. + + * Makefile.in (SOURCES): Add intl-compat.c. + (OBJECTS): We always compile the GNU gettext library functions. + OBJECTS contains all objects but cat-compat.o, ../po/cat-if-tbl.o, + and intl-compat.o. + (GETTOBJS): Contains now only intl-compat.o. + + * libgettext.h: + Re-include protection matches dualistic character of libgettext.h. + For all functions in GNU gettext library define __ counter part. + + * finddomain.c (strchr): Define as index if not found in C library. + (_nl_find_domain): For relative paths paste / in between. + +Tue Jul 18 16:37:45 1995 Ulrich Drepper + + * loadmsgcat.c, finddomain.c: Add inclusion of sys/types.h. + + * xopen-msg.sed: Fix bug with `msgstr ""' lines. + A little bit better comments. + +Tue Jul 18 01:18:27 1995 Ulrich Drepper + + * Makefile.in: + po-mode.el, makelinks, combine-sh are now found in ../misc. + + * po-mode.el, makelinks, combine-sh, elisp-comp: + Moved to ../misc/. + + * libgettext.h, gettextP.h, gettext.h: Uniform test for __STDC__. + +Sun Jul 16 22:33:02 1995 Ulrich Drepper + + * Makefile.in (INSTALL, INSTALL_DATA): New variables. + (install-data, uninstall): Install/uninstall .elc file. + + * po-mode.el (Installation comment): + Add .pox as possible extension of .po files. + +Sun Jul 16 13:23:27 1995 Ulrich Drepper + + * elisp-comp: Complete new version by Franc,ois: This does not + fail when not compiling in the source directory. + +Sun Jul 16 00:12:17 1995 Ulrich Drepper + + * Makefile.in (../po/cat-id-tbl.o): + Use $(MAKE) instead of make for recursive make. + + * Makefile.in (.el.elc): Use $(SHELL) instead of /bin/sh. + (install-exec): Add missing dummy goal. + (install-data, uninstall): @ in multi-line shell command at + beginning, not in front of echo. Reported by Eric Backus. + +Sat Jul 15 00:21:28 1995 Ulrich Drepper + + * Makefile.in (DISTFILES): + Rename libgettext.perl to gettext.perl to fit in 14 chars + file systems. + + * gettext.perl: + Rename to gettext.perl to fit in 14 chars file systems. + +Thu Jul 13 23:17:20 1995 Ulrich Drepper + + * cat-compat.c: If !STDC_HEADERS try to include malloc.h. + +Thu Jul 13 20:55:02 1995 Ulrich Drepper + + * po2tbl.sed.in: Pretty printing. + + * linux-msg.sed, xopen-msg.sed: + Correct bugs with handling substitute flags in branches. + + * hash-string.h (hash_string): + Old K&R compilers don't under stand `unsigned char'. + + * gettext.h (nls_uint32): + Some old K&R compilers (eg HP) don't understand `unsigned int'. + + * cat-compat.c (msg_to_cat_id): De-ANSI-fy prototypes. + +Thu Jul 13 01:34:33 1995 Ulrich Drepper + + * Makefile.in (ELCFILES): New variable. + (DISTFILES): Add elisp-comp. + Add implicit rule for .el -> .elc compilation. + (install-data): install $ELCFILES + (clean): renamed po-to-tbl and po-to-msg to po2tbl and po2msg resp. + + * elisp-comp: Initial revision + +Wed Jul 12 16:14:52 1995 Ulrich Drepper + + * Makefile.in: + cat-id-tbl.c is now found in po/. This enables us to use an identical + intl/ directory in all packages. + + * dcgettext.c (dcgettext): hashing does not work for table size <= 2. + + * textdomain.c: fix typo (#if def -> #if defined) + +Tue Jul 11 18:44:43 1995 Ulrich Drepper + + * Makefile.in (stamp-cat-id): use top_srcdir to address source files + (DISTFILES,distclean): move tupdate.perl to src/ + + * po-to-tbl.sed.in: + add additional jump to clear change flag to recognize multiline strings + +Tue Jul 11 01:32:50 1995 Ulrich Drepper + + * textdomain.c: Protect inclusion of stdlib.h and string.h. + + * loadmsgcat.c: Protect inclusion of stdlib.h. + + * libgettext.h: Protect inclusion of locale.h. + Allow use in C++ programs. + Define NULL is not happened already. + + * Makefile.in (DISTFILES): ship po-to-tbl.sed.in instead of + po-to-tbl.sed. + (distclean): remove po-to-tbl.sed and tupdate.perl. + + * tupdate.perl.in: Substitute Perl path even in exec line. + Don't include entries without translation from old .po file. + +Tue Jul 4 00:41:51 1995 Ulrich Drepper + + * tupdate.perl.in: use "Updated: " in msgid "". + + * cat-compat.c: Fix typo (LOCALDIR -> LOCALEDIR). + Define getenv if !__STDC__. + + * bindtextdom.c: Protect stdlib.h and string.h inclusion. + Define free if !__STDC__. + + * finddomain.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. + Define free if !__STDC__. + + * cat-compat.c: Change DEF_MSG_DOM_DIR to LOCALEDIR. + +Mon Jul 3 23:56:30 1995 Ulrich Drepper + + * Makefile.in: Use LOCALEDIR instead of DEF_MSG_DOM_DIR. + Remove unneeded $(srcdir) from Makefile.in dependency. + + * makelinks: Add copyright and short description. + + * po-mode.el: Last version for 0.7. + + * tupdate.perl.in: Fix die message. + + * dcgettext.c: Protect include of string.h. + + * gettext.c: Protect include of stdlib.h and further tries to get NULL. + + * finddomain.c: Some corrections in includes. + + * Makefile.in (INCLUDES): Prune list correct path to Makefile.in. + + * po-to-tbl.sed: Adopt for new .po file format. + + * linux-msg.sed, xopen-msg.sed: Adopt for new .po file format. + +Sun Jul 2 23:55:03 1995 Ulrich Drepper + + * tupdate.perl.in: Complete rewrite for new .po file format. + +Sun Jul 2 02:06:50 1995 Ulrich Drepper + + * First official release. This directory contains all the code + needed to internationalize own packages. It provides functions + which allow to use the X/Open catgets function with an interface + like the Uniforum gettext function. For system which does not + have neither of those a complete implementation is provided. diff --git a/apt/intl/Makefile.in b/apt/intl/Makefile.in new file mode 100644 index 0000000..9a877c8 --- /dev/null +++ b/apt/intl/Makefile.in @@ -0,0 +1,218 @@ +# Makefile for directory with message catalog handling in GNU NLS Utilities. +# Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +top_builddir = .. +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +transform = @program_transform_name@ +libdir = $(exec_prefix)/lib +includedir = $(prefix)/include +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale +gnulocaledir = $(prefix)/share/locale +gettextsrcdir = @datadir@/gettext/intl +aliaspath = $(localedir):. +subdir = intl + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = @MKINSTALLDIRS@ + +l = @l@ + +AR = ar +CC = @CC@ +LIBTOOL = @LIBTOOL@ +RANLIB = @RANLIB@ + +DEFS = -DLOCALEDIR=\"$(localedir)\" -DGNULOCALEDIR=\"$(gnulocaledir)\" \ +-DLOCALE_ALIAS_PATH=\"$(aliaspath)\" @DEFS@ +CPPFLAGS = @CPPFLAGS@ +CFLAGS = @CFLAGS@ +LDFLAGS = @LDFLAGS@ + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +HEADERS = $(COMHDRS) libgettext.h loadinfo.h +COMHDRS = gettext.h gettextP.h hash-string.h +SOURCES = $(COMSRCS) intl-compat.c cat-compat.c +COMSRCS = bindtextdom.c dcgettext.c dgettext.c gettext.c \ +finddomain.c loadmsgcat.c localealias.c textdomain.c l10nflist.c \ +explodename.c +OBJECTS = @INTLOBJS@ bindtextdom.$lo dcgettext.$lo dgettext.$lo gettext.$lo \ +finddomain.$lo loadmsgcat.$lo localealias.$lo textdomain.$lo l10nflist.$lo \ +explodename.$lo +CATOBJS = cat-compat.$lo ../po/cat-id-tbl.$lo +GETTOBJS = intl-compat.$lo +DISTFILES.common = ChangeLog Makefile.in linux-msg.sed po2tbl.sed.in \ +xopen-msg.sed $(HEADERS) $(SOURCES) +DISTFILES.normal = VERSION +DISTFILES.gettext = libintl.glibc intlh.inst.in + +.SUFFIXES: +.SUFFIXES: .c .o .lo +.c.o: + $(COMPILE) $< +.c.lo: + $(LIBTOOL) --mode=compile $(COMPILE) $< + +INCLUDES = -I.. -I. -I$(top_srcdir)/intl -I$(top_srcdir)/lib + +all: all-@USE_INCLUDED_LIBINTL@ + +all-yes: libintl.$la intlh.inst +all-no: + +libintl.a: $(OBJECTS) + rm -f $@ + $(AR) cru $@ $(OBJECTS) + $(RANLIB) $@ + +libintl.la: $(OBJECTS) + $(LIBTOOL) --mode=link $(CC) $(LDFLAGS) -o $@ $(OBJECTS) \ + -version-info 1:0 -rpath $(libdir) + +../po/cat-id-tbl.$lo: ../po/cat-id-tbl.c $(top_srcdir)/po/$(PACKAGE).pot + cd ../po && $(MAKE) cat-id-tbl.$lo + +check: all + +# This installation goal is only used in GNU gettext. Packages which +# only use the library should use install instead. + +# We must not install the libintl.h/libintl.a files if we are on a +# system which has the gettext() function in its C library or in a +# separate library or use the catgets interface. A special case is +# where configure found a previously installed GNU gettext library. +# If you want to use the one which comes with this version of the +# package, you have to use `configure --with-included-gettext'. +install: install-exec install-data +install-exec: all + if test "$(PACKAGE)" = "gettext" \ + && test '@INTLOBJS@' = '$(GETTOBJS)'; then \ + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $(libdir) $(includedir); \ + else \ + $(top_srcdir)/mkinstalldirs $(libdir) $(includedir); \ + fi; \ + $(INSTALL_DATA) intlh.inst $(includedir)/libintl.h; \ + $(INSTALL_DATA) libintl.a $(libdir)/libintl.a; \ + else \ + : ; \ + fi +install-data: all + if test "$(PACKAGE)" = "gettext"; then \ + if test -r $(MKINSTALLDIRS); then \ + $(MKINSTALLDIRS) $(gettextsrcdir); \ + else \ + $(top_srcdir)/mkinstalldirs $(gettextsrcdir); \ + fi; \ + $(INSTALL_DATA) VERSION $(gettextsrcdir)/VERSION; \ + dists="$(DISTFILES.common)"; \ + for file in $$dists; do \ + $(INSTALL_DATA) $(srcdir)/$$file $(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + if test "$(PACKAGE)" = "gettext"; then \ + dists="$(DISTFILES.common)"; \ + for file in $$dists; do \ + rm -f $(gettextsrcdir)/$$file; \ + done; \ + else \ + : ; \ + fi + +info dvi: + +$(OBJECTS): ../config.h libgettext.h +bindtextdom.$lo finddomain.$lo loadmsgcat.$lo: gettextP.h gettext.h loadinfo.h +dcgettext.$lo: gettextP.h gettext.h hash-string.h loadinfo.h + +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && etags -o $$here/TAGS $(HEADERS) $(SOURCES) + +id: ID + +ID: $(HEADERS) $(SOURCES) + here=`pwd`; cd $(srcdir) && mkid -f$$here/ID $(HEADERS) $(SOURCES) + + +mostlyclean: + rm -f *.a *.o *.lo core core.* + +clean: mostlyclean + +distclean: clean + rm -f Makefile ID TAGS po2msg.sed po2tbl.sed + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + + +# GNU gettext needs not contain the file `VERSION' but contains some +# other files which should not be distributed in other packages. +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: Makefile $(DISTFILES) + if test "$(PACKAGE)" = gettext; then \ + additional="$(DISTFILES.gettext)"; \ + else \ + additional="$(DISTFILES.normal)"; \ + fi; \ + for file in $(DISTFILES.common) $$additional; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +dist-libc: + tar zcvf intl-glibc.tar.gz $(COMSRCS) $(COMHDRS) libintl.h.glibc + +Makefile: Makefile.in ../config.status + cd .. \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +# The dependency for intlh.inst is different in gettext and all other +# packages. Because we cannot you GNU make features we have to solve +# the problem while rewriting Makefile.in. +@GT_YES@intlh.inst: intlh.inst.in ../config.status +@GT_YES@ cd .. \ +@GT_YES@ && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= \ +@GT_YES@ $(SHELL) ./config.status +@GT_NO@.PHONY: intlh.inst +@GT_NO@intlh.inst: + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/apt/intl/VERSION b/apt/intl/VERSION new file mode 100644 index 0000000..ee66b06 --- /dev/null +++ b/apt/intl/VERSION @@ -0,0 +1 @@ +GNU gettext library from gettext-0.10.35 diff --git a/apt/intl/bindtextdom.c b/apt/intl/bindtextdom.c new file mode 100644 index 0000000..d9c3f34 --- /dev/null +++ b/apt/intl/bindtextdom.c @@ -0,0 +1,203 @@ +/* Implementation of the bindtextdomain(3) function + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif +#include "gettext.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +/* Contains the default location of the message catalogs. */ +extern const char _nl_default_dirname[]; + +/* List with bindings of specific domains. */ +extern struct binding *_nl_domain_bindings; + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define BINDTEXTDOMAIN __bindtextdomain +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define BINDTEXTDOMAIN bindtextdomain__ +#endif + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +char * +BINDTEXTDOMAIN (domainname, dirname) + const char *domainname; + const char *dirname; +{ + struct binding *binding; + + /* Some sanity checks. */ + if (domainname == NULL || domainname[0] == '\0') + return NULL; + + for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) + { + int compare = strcmp (domainname, binding->domainname); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It is not in the list. */ + binding = NULL; + break; + } + } + + if (dirname == NULL) + /* The current binding has be to returned. */ + return binding == NULL ? (char *) _nl_default_dirname : binding->dirname; + + if (binding != NULL) + { + /* The domain is already bound. If the new value and the old + one are equal we simply do nothing. Otherwise replace the + old binding. */ + if (strcmp (dirname, binding->dirname) != 0) + { + char *new_dirname; + + if (strcmp (dirname, _nl_default_dirname) == 0) + new_dirname = (char *) _nl_default_dirname; + else + { +#if defined _LIBC || defined HAVE_STRDUP + new_dirname = strdup (dirname); + if (new_dirname == NULL) + return NULL; +#else + size_t len = strlen (dirname) + 1; + new_dirname = (char *) malloc (len); + if (new_dirname == NULL) + return NULL; + + memcpy (new_dirname, dirname, len); +#endif + } + + if (binding->dirname != _nl_default_dirname) + free (binding->dirname); + + binding->dirname = new_dirname; + } + } + else + { + /* We have to create a new binding. */ +#if !defined _LIBC && !defined HAVE_STRDUP + size_t len; +#endif + struct binding *new_binding = + (struct binding *) malloc (sizeof (*new_binding)); + + if (new_binding == NULL) + return NULL; + +#if defined _LIBC || defined HAVE_STRDUP + new_binding->domainname = strdup (domainname); + if (new_binding->domainname == NULL) + return NULL; +#else + len = strlen (domainname) + 1; + new_binding->domainname = (char *) malloc (len); + if (new_binding->domainname == NULL) + return NULL; + memcpy (new_binding->domainname, domainname, len); +#endif + + if (strcmp (dirname, _nl_default_dirname) == 0) + new_binding->dirname = (char *) _nl_default_dirname; + else + { +#if defined _LIBC || defined HAVE_STRDUP + new_binding->dirname = strdup (dirname); + if (new_binding->dirname == NULL) + return NULL; +#else + len = strlen (dirname) + 1; + new_binding->dirname = (char *) malloc (len); + if (new_binding->dirname == NULL) + return NULL; + memcpy (new_binding->dirname, dirname, len); +#endif + } + + /* Now enqueue it. */ + if (_nl_domain_bindings == NULL + || strcmp (domainname, _nl_domain_bindings->domainname) < 0) + { + new_binding->next = _nl_domain_bindings; + _nl_domain_bindings = new_binding; + } + else + { + binding = _nl_domain_bindings; + while (binding->next != NULL + && strcmp (domainname, binding->next->domainname) > 0) + binding = binding->next; + + new_binding->next = binding->next; + binding->next = new_binding; + } + + binding = new_binding; + } + + return binding->dirname; +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__bindtextdomain, bindtextdomain); +#endif diff --git a/apt/intl/cat-compat.c b/apt/intl/cat-compat.c new file mode 100644 index 0000000..867d901 --- /dev/null +++ b/apt/intl/cat-compat.c @@ -0,0 +1,262 @@ +/* Compatibility code for gettext-using-catgets interface. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef STDC_HEADERS +# include +# include +#else +char *getenv (); +# ifdef HAVE_MALLOC_H +# include +# endif +#endif + +#ifdef HAVE_NL_TYPES_H +# include +#endif + +#include "libgettext.h" + +/* @@ end of prolog @@ */ + +/* XPG3 defines the result of `setlocale (category, NULL)' as: + ``Directs `setlocale()' to query `category' and return the current + setting of `local'.'' + However it does not specify the exact format. And even worse: POSIX + defines this not at all. So we can use this feature only on selected + system (e.g. those using GNU C Library). */ +#ifdef _LIBC +# define HAVE_LOCALE_NULL +#endif + +/* The catalog descriptor. */ +static nl_catd catalog = (nl_catd) -1; + +/* Name of the default catalog. */ +static const char default_catalog_name[] = "messages"; + +/* Name of currently used catalog. */ +static const char *catalog_name = default_catalog_name; + +/* Get ID for given string. If not found return -1. */ +static int msg_to_cat_id PARAMS ((const char *msg)); + +/* Substitution for systems lacking this function in their C library. */ +#if !_LIBC && !HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +#endif + + +/* Set currently used domain/catalog. */ +char * +textdomain (domainname) + const char *domainname; +{ + nl_catd new_catalog; + char *new_name; + size_t new_name_len; + char *lang; + +#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES \ + && defined HAVE_LOCALE_NULL + lang = setlocale (LC_MESSAGES, NULL); +#else + lang = getenv ("LC_ALL"); + if (lang == NULL || lang[0] == '\0') + { + lang = getenv ("LC_MESSAGES"); + if (lang == NULL || lang[0] == '\0') + lang = getenv ("LANG"); + } +#endif + if (lang == NULL || lang[0] == '\0') + lang = "C"; + + /* See whether name of currently used domain is asked. */ + if (domainname == NULL) + return (char *) catalog_name; + + if (domainname[0] == '\0') + domainname = default_catalog_name; + + /* Compute length of added path element. */ + new_name_len = sizeof (LOCALEDIR) - 1 + 1 + strlen (lang) + + sizeof ("/LC_MESSAGES/") - 1 + sizeof (PACKAGE) - 1 + + sizeof (".cat"); + + new_name = (char *) malloc (new_name_len); + if (new_name == NULL) + return NULL; + + strcpy (new_name, PACKAGE); + new_catalog = catopen (new_name, 0); + + if (new_catalog == (nl_catd) -1) + { + /* NLSPATH search didn't work, try absolute path */ + sprintf (new_name, "%s/%s/LC_MESSAGES/%s.cat", LOCALEDIR, lang, + PACKAGE); + new_catalog = catopen (new_name, 0); + + if (new_catalog == (nl_catd) -1) + { + free (new_name); + return (char *) catalog_name; + } + } + + /* Close old catalog. */ + if (catalog != (nl_catd) -1) + catclose (catalog); + if (catalog_name != default_catalog_name) + free ((char *) catalog_name); + + catalog = new_catalog; + catalog_name = new_name; + + return (char *) catalog_name; +} + +char * +bindtextdomain (domainname, dirname) + const char *domainname; + const char *dirname; +{ +#if HAVE_SETENV || HAVE_PUTENV + char *old_val, *new_val, *cp; + size_t new_val_len; + + /* This does not make much sense here but to be compatible do it. */ + if (domainname == NULL) + return NULL; + + /* Compute length of added path element. If we use setenv we don't need + the first byts for NLSPATH=, but why complicate the code for this + peanuts. */ + new_val_len = sizeof ("NLSPATH=") - 1 + strlen (dirname) + + sizeof ("/%L/LC_MESSAGES/%N.cat"); + + old_val = getenv ("NLSPATH"); + if (old_val == NULL || old_val[0] == '\0') + { + old_val = NULL; + new_val_len += 1 + sizeof (LOCALEDIR) - 1 + + sizeof ("/%L/LC_MESSAGES/%N.cat"); + } + else + new_val_len += strlen (old_val); + + new_val = (char *) malloc (new_val_len); + if (new_val == NULL) + return NULL; + +# if HAVE_SETENV + cp = new_val; +# else + cp = stpcpy (new_val, "NLSPATH="); +# endif + + cp = stpcpy (cp, dirname); + cp = stpcpy (cp, "/%L/LC_MESSAGES/%N.cat:"); + + if (old_val == NULL) + { +# if __STDC__ + stpcpy (cp, LOCALEDIR "/%L/LC_MESSAGES/%N.cat"); +# else + + cp = stpcpy (cp, LOCALEDIR); + stpcpy (cp, "/%L/LC_MESSAGES/%N.cat"); +# endif + } + else + stpcpy (cp, old_val); + +# if HAVE_SETENV + setenv ("NLSPATH", new_val, 1); + free (new_val); +# else + putenv (new_val); + /* Do *not* free the environment entry we just entered. It is used + from now on. */ +# endif + +#endif + + return (char *) domainname; +} + +#undef gettext +char * +gettext (msg) + const char *msg; +{ + int msgid; + + if (msg == NULL || catalog == (nl_catd) -1) + return (char *) msg; + + /* Get the message from the catalog. We always use set number 1. + The message ID is computed by the function `msg_to_cat_id' + which works on the table generated by `po-to-tbl'. */ + msgid = msg_to_cat_id (msg); + if (msgid == -1) + return (char *) msg; + + return catgets (catalog, 1, msgid, (char *) msg); +} + +/* Look through the table `_msg_tbl' which has `_msg_tbl_length' entries + for the one equal to msg. If it is found return the ID. In case when + the string is not found return -1. */ +static int +msg_to_cat_id (msg) + const char *msg; +{ + int cnt; + + for (cnt = 0; cnt < _msg_tbl_length; ++cnt) + if (strcmp (msg, _msg_tbl[cnt]._msg) == 0) + return _msg_tbl[cnt]._msg_number; + + return -1; +} + + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif diff --git a/apt/intl/dcgettext.c b/apt/intl/dcgettext.c new file mode 100644 index 0000000..c4c7a2c --- /dev/null +++ b/apt/intl/dcgettext.c @@ -0,0 +1,624 @@ +/* Implementation of the dcgettext(3) function. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#ifdef __GNUC__ +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +#endif + +#include +#ifndef errno +extern int errno; +#endif +#ifndef __set_errno +# define __set_errno(val) errno = (val) +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +char *getenv (); +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# endif +# include +#else +# include +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include "gettext.h" +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif +#include "hash-string.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define getcwd __getcwd +# ifndef stpcpy +# define stpcpy __stpcpy +# endif +#else +# if !defined HAVE_GETCWD +char *getwd (); +# define getcwd(buf, max) getwd (buf) +# else +char *getcwd (); +# endif +# ifndef HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +# endif +#endif + +/* Amount to increase buffer size by in each try. */ +#define PATH_INCR 32 + +/* The following is from pathmax.h. */ +/* Non-POSIX BSD systems might have gcc's limits.h, which doesn't define + PATH_MAX but might cause redefinition warnings when sys/param.h is + later included (as on MORE/BSD 4.3). */ +#if defined(_POSIX_VERSION) || (defined(HAVE_LIMITS_H) && !defined(__GNUC__)) +# include +#endif + +#ifndef _POSIX_PATH_MAX +# define _POSIX_PATH_MAX 255 +#endif + +#if !defined(PATH_MAX) && defined(_PC_PATH_MAX) +# define PATH_MAX (pathconf ("/", _PC_PATH_MAX) < 1 ? 1024 : pathconf ("/", _PC_PATH_MAX)) +#endif + +/* Don't include sys/param.h if it already has been. */ +#if defined(HAVE_SYS_PARAM_H) && !defined(PATH_MAX) && !defined(MAXPATHLEN) +# include +#endif + +#if !defined(PATH_MAX) && defined(MAXPATHLEN) +# define PATH_MAX MAXPATHLEN +#endif + +#ifndef PATH_MAX +# define PATH_MAX _POSIX_PATH_MAX +#endif + +/* XPG3 defines the result of `setlocale (category, NULL)' as: + ``Directs `setlocale()' to query `category' and return the current + setting of `local'.'' + However it does not specify the exact format. And even worse: POSIX + defines this not at all. So we can use this feature only on selected + system (e.g. those using GNU C Library). */ +#ifdef _LIBC +# define HAVE_LOCALE_NULL +#endif + +/* Name of the default domain used for gettext(3) prior any call to + textdomain(3). The default value for this is "messages". */ +const char _nl_default_default_domain[] = "messages"; + +/* Value used as the default domain for gettext(3). */ +const char *_nl_current_default_domain = _nl_default_default_domain; + +/* Contains the default location of the message catalogs. */ +const char _nl_default_dirname[] = GNULOCALEDIR; + +/* List with bindings of specific domains created by bindtextdomain() + calls. */ +struct binding *_nl_domain_bindings; + +/* Prototypes for local functions. */ +static char *find_msg PARAMS ((struct loaded_l10nfile *domain_file, + const char *msgid)) internal_function; +static const char *category_to_name PARAMS ((int category)) internal_function; +static const char *guess_category_value PARAMS ((int category, + const char *categoryname)) + internal_function; + + +/* For those loosing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +/* Nothing has to be done. */ +# define ADD_BLOCK(list, address) /* nothing */ +# define FREE_BLOCKS(list) /* nothing */ +#else +struct block_list +{ + void *address; + struct block_list *next; +}; +# define ADD_BLOCK(list, addr) \ + do { \ + struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ + /* If we cannot get a free block we cannot add the new element to \ + the list. */ \ + if (newp != NULL) { \ + newp->address = (addr); \ + newp->next = (list); \ + (list) = newp; \ + } \ + } while (0) +# define FREE_BLOCKS(list) \ + do { \ + while (list != NULL) { \ + struct block_list *old = list; \ + list = list->next; \ + free (old); \ + } \ + } while (0) +# undef alloca +# define alloca(size) (malloc (size)) +#endif /* have alloca */ + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DCGETTEXT __dcgettext +#else +# define DCGETTEXT dcgettext__ +#endif + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +char * +DCGETTEXT (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ +#ifndef HAVE_ALLOCA + struct block_list *block_list = NULL; +#endif + struct loaded_l10nfile *domain; + struct binding *binding; + const char *categoryname; + const char *categoryvalue; + char *dirname, *xdomainname; + char *single_locale; + char *retval; + int saved_errno = errno; + + /* If no real MSGID is given return NULL. */ + if (msgid == NULL) + return NULL; + + /* If DOMAINNAME is NULL, we are interested in the default domain. If + CATEGORY is not LC_MESSAGES this might not make much sense but the + defintion left this undefined. */ + if (domainname == NULL) + domainname = _nl_current_default_domain; + + /* First find matching binding. */ + for (binding = _nl_domain_bindings; binding != NULL; binding = binding->next) + { + int compare = strcmp (domainname, binding->domainname); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It is not in the list. */ + binding = NULL; + break; + } + } + + if (binding == NULL) + dirname = (char *) _nl_default_dirname; + else if (binding->dirname[0] == '/') + dirname = binding->dirname; + else + { + /* We have a relative path. Make it absolute now. */ + size_t dirname_len = strlen (binding->dirname) + 1; + size_t path_max; + char *ret; + + path_max = (unsigned) PATH_MAX; + path_max += 2; /* The getcwd docs say to do this. */ + + dirname = (char *) alloca (path_max + dirname_len); + ADD_BLOCK (block_list, dirname); + + __set_errno (0); + while ((ret = getcwd (dirname, path_max)) == NULL && errno == ERANGE) + { + path_max += PATH_INCR; + dirname = (char *) alloca (path_max + dirname_len); + ADD_BLOCK (block_list, dirname); + __set_errno (0); + } + + if (ret == NULL) + { + /* We cannot get the current working directory. Don't signal an + error but simply return the default string. */ + FREE_BLOCKS (block_list); + __set_errno (saved_errno); + return (char *) msgid; + } + + stpcpy (stpcpy (strchr (dirname, '\0'), "/"), binding->dirname); + } + + /* Now determine the symbolic name of CATEGORY and its value. */ + categoryname = category_to_name (category); + categoryvalue = guess_category_value (category, categoryname); + + xdomainname = (char *) alloca (strlen (categoryname) + + strlen (domainname) + 5); + ADD_BLOCK (block_list, xdomainname); + + stpcpy (stpcpy (stpcpy (stpcpy (xdomainname, categoryname), "/"), + domainname), + ".mo"); + + /* Creating working area. */ + single_locale = (char *) alloca (strlen (categoryvalue) + 1); + ADD_BLOCK (block_list, single_locale); + + + /* Search for the given string. This is a loop because we perhaps + got an ordered list of languages to consider for th translation. */ + while (1) + { + /* Make CATEGORYVALUE point to the next element of the list. */ + while (categoryvalue[0] != '\0' && categoryvalue[0] == ':') + ++categoryvalue; + if (categoryvalue[0] == '\0') + { + /* The whole contents of CATEGORYVALUE has been searched but + no valid entry has been found. We solve this situation + by implicitly appending a "C" entry, i.e. no translation + will take place. */ + single_locale[0] = 'C'; + single_locale[1] = '\0'; + } + else + { + char *cp = single_locale; + while (categoryvalue[0] != '\0' && categoryvalue[0] != ':') + *cp++ = *categoryvalue++; + *cp = '\0'; + } + + /* If the current locale value is C (or POSIX) we don't load a + domain. Return the MSGID. */ + if (strcmp (single_locale, "C") == 0 + || strcmp (single_locale, "POSIX") == 0) + { + FREE_BLOCKS (block_list); + __set_errno (saved_errno); + return (char *) msgid; + } + + + /* Find structure describing the message catalog matching the + DOMAINNAME and CATEGORY. */ + domain = _nl_find_domain (dirname, single_locale, xdomainname); + + if (domain != NULL) + { + retval = find_msg (domain, msgid); + + if (retval == NULL) + { + int cnt; + + for (cnt = 0; domain->successor[cnt] != NULL; ++cnt) + { + retval = find_msg (domain->successor[cnt], msgid); + + if (retval != NULL) + break; + } + } + + if (retval != NULL) + { + FREE_BLOCKS (block_list); + __set_errno (saved_errno); + return retval; + } + } + } + /* NOTREACHED */ +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dcgettext, dcgettext); +#endif + + +static char * +internal_function +find_msg (domain_file, msgid) + struct loaded_l10nfile *domain_file; + const char *msgid; +{ + size_t top, act, bottom; + struct loaded_domain *domain; + + if (domain_file->decided == 0) + _nl_load_domain (domain_file); + + if (domain_file->data == NULL) + return NULL; + + domain = (struct loaded_domain *) domain_file->data; + + /* Locate the MSGID and its translation. */ + if (domain->hash_size > 2 && domain->hash_tab != NULL) + { + /* Use the hashing table. */ + nls_uint32 len = strlen (msgid); + nls_uint32 hash_val = hash_string (msgid); + nls_uint32 idx = hash_val % domain->hash_size; + nls_uint32 incr = 1 + (hash_val % (domain->hash_size - 2)); + nls_uint32 nstr = W (domain->must_swap, domain->hash_tab[idx]); + + if (nstr == 0) + /* Hash table entry is empty. */ + return NULL; + + if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len + && strcmp (msgid, + domain->data + W (domain->must_swap, + domain->orig_tab[nstr - 1].offset)) == 0) + return (char *) domain->data + W (domain->must_swap, + domain->trans_tab[nstr - 1].offset); + + while (1) + { + if (idx >= domain->hash_size - incr) + idx -= domain->hash_size - incr; + else + idx += incr; + + nstr = W (domain->must_swap, domain->hash_tab[idx]); + if (nstr == 0) + /* Hash table entry is empty. */ + return NULL; + + if (W (domain->must_swap, domain->orig_tab[nstr - 1].length) == len + && strcmp (msgid, + domain->data + W (domain->must_swap, + domain->orig_tab[nstr - 1].offset)) + == 0) + return (char *) domain->data + + W (domain->must_swap, domain->trans_tab[nstr - 1].offset); + } + /* NOTREACHED */ + } + + /* Now we try the default method: binary search in the sorted + array of messages. */ + bottom = 0; + top = domain->nstrings; + while (bottom < top) + { + int cmp_val; + + act = (bottom + top) / 2; + cmp_val = strcmp (msgid, domain->data + + W (domain->must_swap, + domain->orig_tab[act].offset)); + if (cmp_val < 0) + top = act; + else if (cmp_val > 0) + bottom = act + 1; + else + break; + } + + /* If an translation is found return this. */ + return bottom >= top ? NULL : (char *) domain->data + + W (domain->must_swap, + domain->trans_tab[act].offset); +} + + +/* Return string representation of locale CATEGORY. */ +static const char * +internal_function +category_to_name (category) + int category; +{ + const char *retval; + + switch (category) + { +#ifdef LC_COLLATE + case LC_COLLATE: + retval = "LC_COLLATE"; + break; +#endif +#ifdef LC_CTYPE + case LC_CTYPE: + retval = "LC_CTYPE"; + break; +#endif +#ifdef LC_MONETARY + case LC_MONETARY: + retval = "LC_MONETARY"; + break; +#endif +#ifdef LC_NUMERIC + case LC_NUMERIC: + retval = "LC_NUMERIC"; + break; +#endif +#ifdef LC_TIME + case LC_TIME: + retval = "LC_TIME"; + break; +#endif +#ifdef LC_MESSAGES + case LC_MESSAGES: + retval = "LC_MESSAGES"; + break; +#endif +#ifdef LC_RESPONSE + case LC_RESPONSE: + retval = "LC_RESPONSE"; + break; +#endif +#ifdef LC_ALL + case LC_ALL: + /* This might not make sense but is perhaps better than any other + value. */ + retval = "LC_ALL"; + break; +#endif + default: + /* If you have a better idea for a default value let me know. */ + retval = "LC_XXX"; + } + + return retval; +} + +/* Guess value of current locale from value of the environment variables. */ +static const char * +internal_function +guess_category_value (category, categoryname) + int category; + const char *categoryname; +{ + const char *retval; + + /* The highest priority value is the `LANGUAGE' environment + variable. This is a GNU extension. */ + retval = getenv ("LANGUAGE"); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* `LANGUAGE' is not set. So we have to proceed with the POSIX + methods of looking to `LC_ALL', `LC_xxx', and `LANG'. On some + systems this can be done by the `setlocale' function itself. */ +#if defined HAVE_SETLOCALE && defined HAVE_LC_MESSAGES && defined HAVE_LOCALE_NULL + return setlocale (category, NULL); +#else + /* Setting of LC_ALL overwrites all other. */ + retval = getenv ("LC_ALL"); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* Next comes the name of the desired category. */ + retval = getenv (categoryname); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* Last possibility is the LANG environment variable. */ + retval = getenv ("LANG"); + if (retval != NULL && retval[0] != '\0') + return retval; + + /* We use C as the default domain. POSIX says this is implementation + defined. */ + return "C"; +#endif +} + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif + + +#ifdef _LIBC +/* If we want to free all resources we have to do some work at + program's end. */ +static void __attribute__ ((unused)) +free_mem (void) +{ + struct binding *runp; + + for (runp = _nl_domain_bindings; runp != NULL; runp = runp->next) + { + free (runp->domainname); + if (runp->dirname != _nl_default_dirname) + /* Yes, this is a pointer comparison. */ + free (runp->dirname); + } + + if (_nl_current_default_domain != _nl_default_default_domain) + /* Yes, again a pointer comparison. */ + free ((char *) _nl_current_default_domain); +} + +text_set_element (__libc_subfreeres, free_mem); +#endif diff --git a/apt/intl/dgettext.c b/apt/intl/dgettext.c new file mode 100644 index 0000000..0510c2b --- /dev/null +++ b/apt/intl/dgettext.c @@ -0,0 +1,59 @@ +/* Implementation of the dgettext(3) function + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined HAVE_LOCALE_H || defined _LIBC +# include +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define DGETTEXT __dgettext +# define DCGETTEXT __dcgettext +#else +# define DGETTEXT dgettext__ +# define DCGETTEXT dcgettext__ +#endif + +/* Look up MSGID in the DOMAINNAME message catalog of the current + LC_MESSAGES locale. */ +char * +DGETTEXT (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return DCGETTEXT (domainname, msgid, LC_MESSAGES); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__dgettext, dgettext); +#endif diff --git a/apt/intl/explodename.c b/apt/intl/explodename.c new file mode 100644 index 0000000..8066dc2 --- /dev/null +++ b/apt/intl/explodename.c @@ -0,0 +1,188 @@ +/* Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +#endif +#include + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +int +_nl_explode_name (name, language, modifier, territory, codeset, + normalized_codeset, special, sponsor, revision) + char *name; + const char **language; + const char **modifier; + const char **territory; + const char **codeset; + const char **normalized_codeset; + const char **special; + const char **sponsor; + const char **revision; +{ + enum { undecided, xpg, cen } syntax; + char *cp; + int mask; + + *modifier = NULL; + *territory = NULL; + *codeset = NULL; + *normalized_codeset = NULL; + *special = NULL; + *sponsor = NULL; + *revision = NULL; + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = 0; + syntax = undecided; + *language = cp = name; + while (cp[0] != '\0' && cp[0] != '_' && cp[0] != '@' + && cp[0] != '+' && cp[0] != ',') + ++cp; + + if (*language == cp) + /* This does not make sense: language has to be specified. Use + this entry as it is without exploding. Perhaps it is an alias. */ + cp = strchr (*language, '\0'); + else if (cp[0] == '_') + { + /* Next is the territory. */ + cp[0] = '\0'; + *territory = ++cp; + + while (cp[0] != '\0' && cp[0] != '.' && cp[0] != '@' + && cp[0] != '+' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= TERRITORY; + + if (cp[0] == '.') + { + /* Next is the codeset. */ + syntax = xpg; + cp[0] = '\0'; + *codeset = ++cp; + + while (cp[0] != '\0' && cp[0] != '@') + ++cp; + + mask |= XPG_CODESET; + + if (*codeset != cp && (*codeset)[0] != '\0') + { + *normalized_codeset = _nl_normalize_codeset (*codeset, + cp - *codeset); + if (strcmp (*codeset, *normalized_codeset) == 0) + free ((char *) *normalized_codeset); + else + mask |= XPG_NORM_CODESET; + } + } + } + + if (cp[0] == '@' || (syntax != xpg && cp[0] == '+')) + { + /* Next is the modifier. */ + syntax = cp[0] == '@' ? xpg : cen; + cp[0] = '\0'; + *modifier = ++cp; + + while (syntax == cen && cp[0] != '\0' && cp[0] != '+' + && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= XPG_MODIFIER | CEN_AUDIENCE; + } + + if (syntax != xpg && (cp[0] == '+' || cp[0] == ',' || cp[0] == '_')) + { + syntax = cen; + + if (cp[0] == '+') + { + /* Next is special application (CEN syntax). */ + cp[0] = '\0'; + *special = ++cp; + + while (cp[0] != '\0' && cp[0] != ',' && cp[0] != '_') + ++cp; + + mask |= CEN_SPECIAL; + } + + if (cp[0] == ',') + { + /* Next is sponsor (CEN syntax). */ + cp[0] = '\0'; + *sponsor = ++cp; + + while (cp[0] != '\0' && cp[0] != '_') + ++cp; + + mask |= CEN_SPONSOR; + } + + if (cp[0] == '_') + { + /* Next is revision (CEN syntax). */ + cp[0] = '\0'; + *revision = ++cp; + + mask |= CEN_REVISION; + } + } + + /* For CEN syntax values it might be important to have the + separator character in the file name, not for XPG syntax. */ + if (syntax == xpg) + { + if (*territory != NULL && (*territory)[0] == '\0') + mask &= ~TERRITORY; + + if (*codeset != NULL && (*codeset)[0] == '\0') + mask &= ~XPG_CODESET; + + if (*modifier != NULL && (*modifier)[0] == '\0') + mask &= ~XPG_MODIFIER; + } + + return mask; +} diff --git a/apt/intl/finddomain.c b/apt/intl/finddomain.c new file mode 100644 index 0000000..81ea29b --- /dev/null +++ b/apt/intl/finddomain.c @@ -0,0 +1,216 @@ +/* Handle list of needed message catalogs + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include +#include + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#include "gettext.h" +#include "gettextP.h" +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ +/* List of already loaded domains. */ +static struct loaded_l10nfile *_nl_loaded_domains; + + +/* Return a data structure describing the message catalog described by + the DOMAINNAME and CATEGORY parameters with respect to the currently + established bindings. */ +struct loaded_l10nfile * +internal_function +_nl_find_domain (dirname, locale, domainname) + const char *dirname; + char *locale; + const char *domainname; +{ + struct loaded_l10nfile *retval; + const char *language; + const char *modifier; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *special; + const char *sponsor; + const char *revision; + const char *alias_value; + int mask; + + /* LOCALE can consist of up to four recognized parts for the XPG syntax: + + language[_territory[.codeset]][@modifier] + + and six parts for the CEN syntax: + + language[_territory][+audience][+special][,[sponsor][_revision]] + + Beside the first part all of them are allowed to be missing. If + the full specified locale is not found, the less specific one are + looked for. The various parts will be stripped off according to + the following order: + (1) revision + (2) sponsor + (3) special + (4) codeset + (5) normalized codeset + (6) territory + (7) audience/modifier + */ + + /* If we have already tested for this locale entry there has to + be one data set in the list of loaded domains. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, 0, locale, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, domainname, 0); + if (retval != NULL) + { + /* We know something about this locale. */ + int cnt; + + if (retval->decided == 0) + _nl_load_domain (retval); + + if (retval->data != NULL) + return retval; + + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt]); + + if (retval->successor[cnt]->data != NULL) + break; + } + return cnt >= 0 ? retval : NULL; + /* NOTREACHED */ + } + + /* See whether the locale value is an alias. If yes its value + *overwrites* the alias name. No test for the original value is + done. */ + alias_value = _nl_expand_alias (locale); + if (alias_value != NULL) + { +#if defined _LIBC || defined HAVE_STRDUP + locale = strdup (alias_value); + if (locale == NULL) + return NULL; +#else + size_t len = strlen (alias_value) + 1; + locale = (char *) malloc (len); + if (locale == NULL) + return NULL; + + memcpy (locale, alias_value, len); +#endif + } + + /* Now we determine the single parts of the locale name. First + look for the language. Termination symbols are `_' and `@' if + we use XPG4 style, and `_', `+', and `,' if we use CEN syntax. */ + mask = _nl_explode_name (locale, &language, &modifier, &territory, + &codeset, &normalized_codeset, &special, + &sponsor, &revision); + + /* Create all possible locale entries which might be interested in + generalization. */ + retval = _nl_make_l10nflist (&_nl_loaded_domains, dirname, + strlen (dirname) + 1, mask, language, territory, + codeset, normalized_codeset, modifier, special, + sponsor, revision, domainname, 1); + if (retval == NULL) + /* This means we are out of core. */ + return NULL; + + if (retval->decided == 0) + _nl_load_domain (retval); + if (retval->data == NULL) + { + int cnt; + for (cnt = 0; retval->successor[cnt] != NULL; ++cnt) + { + if (retval->successor[cnt]->decided == 0) + _nl_load_domain (retval->successor[cnt]); + if (retval->successor[cnt]->data != NULL) + break; + } + } + + /* The room for an alias was dynamically allocated. Free it now. */ + if (alias_value != NULL) + free (locale); + + return retval; +} + + +#ifdef _LIBC +static void __attribute__ ((unused)) +free_mem (void) +{ + struct loaded_l10nfile *runp = _nl_loaded_domains; + + while (runp != NULL) + { + struct loaded_l10nfile *here = runp; + if (runp->data != NULL) + _nl_unload_domain ((struct loaded_domain *) runp->data); + runp = runp->next; + free (here); + } +} + +text_set_element (__libc_subfreeres, free_mem); +#endif diff --git a/apt/intl/gettext.c b/apt/intl/gettext.c new file mode 100644 index 0000000..d929f98 --- /dev/null +++ b/apt/intl/gettext.c @@ -0,0 +1,70 @@ +/* Implementation of gettext(3) function. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define __need_NULL +# include +#else +# ifdef STDC_HEADERS +# include /* Just for NULL. */ +# else +# ifdef HAVE_STRING_H +# include +# else +# define NULL ((void *) 0) +# endif +# endif +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define GETTEXT __gettext +# define DGETTEXT __dgettext +#else +# define GETTEXT gettext__ +# define DGETTEXT dgettext__ +#endif + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +char * +GETTEXT (msgid) + const char *msgid; +{ + return DGETTEXT (NULL, msgid); +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__gettext, gettext); +#endif diff --git a/apt/intl/gettext.h b/apt/intl/gettext.h new file mode 100644 index 0000000..3cd23d7 --- /dev/null +++ b/apt/intl/gettext.h @@ -0,0 +1,105 @@ +/* Internal header for GNU gettext internationalization functions. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#ifndef _GETTEXT_H +#define _GETTEXT_H 1 + +#include + +#if HAVE_LIMITS_H || _LIBC +# include +#endif + +/* @@ end of prolog @@ */ + +/* The magic number of the GNU message catalog format. */ +#define _MAGIC 0x950412de +#define _MAGIC_SWAPPED 0xde120495 + +/* Revision number of the currently used .mo (binary) file format. */ +#define MO_REVISION_NUMBER 0 + +/* The following contortions are an attempt to use the C preprocessor + to determine an unsigned integral type that is 32 bits wide. An + alternative approach is to use autoconf's AC_CHECK_SIZEOF macro, but + doing that would require that the configure script compile and *run* + the resulting executable. Locally running cross-compiled executables + is usually not possible. */ + +#if __STDC__ +# define UINT_MAX_32_BITS 4294967295U +#else +# define UINT_MAX_32_BITS 0xFFFFFFFF +#endif + +/* If UINT_MAX isn't defined, assume it's a 32-bit type. + This should be valid for all systems GNU cares about because + that doesn't include 16-bit systems, and only modern systems + (that certainly have ) have 64+-bit integral types. */ + +#ifndef UINT_MAX +# define UINT_MAX UINT_MAX_32_BITS +#endif + +#if UINT_MAX == UINT_MAX_32_BITS +typedef unsigned nls_uint32; +#else +# if USHRT_MAX == UINT_MAX_32_BITS +typedef unsigned short nls_uint32; +# else +# if ULONG_MAX == UINT_MAX_32_BITS +typedef unsigned long nls_uint32; +# else + /* The following line is intended to throw an error. Using #error is + not portable enough. */ + "Cannot determine unsigned 32-bit data type." +# endif +# endif +#endif + + +/* Header for binary .mo file format. */ +struct mo_file_header +{ + /* The magic number. */ + nls_uint32 magic; + /* The revision number of the file format. */ + nls_uint32 revision; + /* The number of strings pairs. */ + nls_uint32 nstrings; + /* Offset of table with start offsets of original strings. */ + nls_uint32 orig_tab_offset; + /* Offset of table with start offsets of translation strings. */ + nls_uint32 trans_tab_offset; + /* Size of hashing table. */ + nls_uint32 hash_tab_size; + /* Offset of first hashing entry. */ + nls_uint32 hash_tab_offset; +}; + +struct string_desc +{ + /* Length of addressed string. */ + nls_uint32 length; + /* Offset of string in file. */ + nls_uint32 offset; +}; + +/* @@ begin of epilog @@ */ + +#endif /* gettext.h */ diff --git a/apt/intl/gettextP.h b/apt/intl/gettextP.h new file mode 100644 index 0000000..00c5203 --- /dev/null +++ b/apt/intl/gettextP.h @@ -0,0 +1,89 @@ +/* Header describing internals of gettext library + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef _GETTEXTP_H +#define _GETTEXTP_H + +#include "loadinfo.h" + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef internal_function +# define internal_function +#endif + +#ifndef W +# define W(flag, data) ((flag) ? SWAP (data) : (data)) +#endif + + +#ifdef _LIBC +# include +# define SWAP(i) bswap_32 (i) +#else +static nls_uint32 SWAP PARAMS ((nls_uint32 i)); + +static inline nls_uint32 +SWAP (i) + nls_uint32 i; +{ + return (i << 24) | ((i & 0xff00) << 8) | ((i >> 8) & 0xff00) | (i >> 24); +} +#endif + + +struct loaded_domain +{ + const char *data; + int use_mmap; + size_t mmap_size; + int must_swap; + nls_uint32 nstrings; + struct string_desc *orig_tab; + struct string_desc *trans_tab; + nls_uint32 hash_size; + nls_uint32 *hash_tab; +}; + +struct binding +{ + struct binding *next; + char *domainname; + char *dirname; +}; + +struct loaded_l10nfile *_nl_find_domain PARAMS ((const char *__dirname, + char *__locale, + const char *__domainname)) + internal_function; +void _nl_load_domain PARAMS ((struct loaded_l10nfile *__domain)) + internal_function; +void _nl_unload_domain PARAMS ((struct loaded_domain *__domain)) + internal_function; + +/* @@ begin of epilog @@ */ + +#endif /* gettextP.h */ diff --git a/apt/intl/hash-string.h b/apt/intl/hash-string.h new file mode 100644 index 0000000..cacb38e --- /dev/null +++ b/apt/intl/hash-string.h @@ -0,0 +1,59 @@ +/* Implements a string hashing function. + Copyright (C) 1995, 1997 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ +# define PARAMS(Args) Args +# else +# define PARAMS(Args) () +# endif +#endif + +/* We assume to have `unsigned long int' value with at least 32 bits. */ +#define HASHWORDBITS 32 + + +/* Defines the so called `hashpjw' function by P.J. Weinberger + [see Aho/Sethi/Ullman, COMPILERS: Principles, Techniques and Tools, + 1986, 1987 Bell Telephone Laboratories, Inc.] */ +static unsigned long hash_string PARAMS ((const char *__str_param)); + +static inline unsigned long +hash_string (str_param) + const char *str_param; +{ + unsigned long int hval, g; + const char *str = str_param; + + /* Compute the hash value for the given string. */ + hval = 0; + while (*str != '\0') + { + hval <<= 4; + hval += (unsigned long) *str++; + g = hval & ((unsigned long) 0xf << (HASHWORDBITS - 4)); + if (g != 0) + { + hval ^= g >> (HASHWORDBITS - 8); + hval ^= g; + } + } + return hval; +} diff --git a/apt/intl/intl-compat.c b/apt/intl/intl-compat.c new file mode 100644 index 0000000..503efa0 --- /dev/null +++ b/apt/intl/intl-compat.c @@ -0,0 +1,76 @@ +/* intl-compat.c - Stub functions to call gettext functions from GNU gettext + Library. + Copyright (C) 1995 Software Foundation, Inc. + +This program is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2, or (at your option) +any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include "libgettext.h" + +/* @@ end of prolog @@ */ + + +#undef gettext +#undef dgettext +#undef dcgettext +#undef textdomain +#undef bindtextdomain + + +char * +bindtextdomain (domainname, dirname) + const char *domainname; + const char *dirname; +{ + return bindtextdomain__ (domainname, dirname); +} + + +char * +dcgettext (domainname, msgid, category) + const char *domainname; + const char *msgid; + int category; +{ + return dcgettext__ (domainname, msgid, category); +} + + +char * +dgettext (domainname, msgid) + const char *domainname; + const char *msgid; +{ + return dgettext__ (domainname, msgid); +} + + +char * +gettext (msgid) + const char *msgid; +{ + return gettext__ (msgid); +} + + +char * +textdomain (domainname) + const char *domainname; +{ + return textdomain__ (domainname); +} diff --git a/apt/intl/l10nflist.c b/apt/intl/l10nflist.c new file mode 100644 index 0000000..9c7dc18 --- /dev/null +++ b/apt/intl/l10nflist.c @@ -0,0 +1,411 @@ +/* Handle list of needed message catalogs + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + + +#if defined HAVE_STRING_H || defined _LIBC +# ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# endif +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#if defined _LIBC || defined HAVE_ARGZ_H +# include +#endif +#include +#include + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#include "loadinfo.h" + +/* On some strange systems still no definition of NULL is found. Sigh! */ +#ifndef NULL +# if defined __STDC__ && __STDC__ +# define NULL ((void *) 0) +# else +# define NULL 0 +# endif +#endif + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# ifndef stpcpy +# define stpcpy(dest, src) __stpcpy(dest, src) +# endif +#else +# ifndef HAVE_STPCPY +static char *stpcpy PARAMS ((char *dest, const char *src)); +# endif +#endif + +/* Define function which are usually not available. */ + +#if !defined _LIBC && !defined HAVE___ARGZ_COUNT +/* Returns the number of strings in ARGZ. */ +static size_t argz_count__ PARAMS ((const char *argz, size_t len)); + +static size_t +argz_count__ (argz, len) + const char *argz; + size_t len; +{ + size_t count = 0; + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len + 1; + len -= part_len + 1; + count++; + } + return count; +} +# undef __argz_count +# define __argz_count(argz, len) argz_count__ (argz, len) +#endif /* !_LIBC && !HAVE___ARGZ_COUNT */ + +#if !defined _LIBC && !defined HAVE___ARGZ_STRINGIFY +/* Make '\0' separated arg vector ARGZ printable by converting all the '\0's + except the last into the character SEP. */ +static void argz_stringify__ PARAMS ((char *argz, size_t len, int sep)); + +static void +argz_stringify__ (argz, len, sep) + char *argz; + size_t len; + int sep; +{ + while (len > 0) + { + size_t part_len = strlen (argz); + argz += part_len; + len -= part_len + 1; + if (len > 0) + *argz++ = sep; + } +} +# undef __argz_stringify +# define __argz_stringify(argz, len, sep) argz_stringify__ (argz, len, sep) +#endif /* !_LIBC && !HAVE___ARGZ_STRINGIFY */ + +#if !defined _LIBC && !defined HAVE___ARGZ_NEXT +static char *argz_next__ PARAMS ((char *argz, size_t argz_len, + const char *entry)); + +static char * +argz_next__ (argz, argz_len, entry) + char *argz; + size_t argz_len; + const char *entry; +{ + if (entry) + { + if (entry < argz + argz_len) + entry = strchr (entry, '\0') + 1; + + return entry >= argz + argz_len ? NULL : (char *) entry; + } + else + if (argz_len > 0) + return argz; + else + return 0; +} +# undef __argz_next +# define __argz_next(argz, len, entry) argz_next__ (argz, len, entry) +#endif /* !_LIBC && !HAVE___ARGZ_NEXT */ + + +/* Return number of bits set in X. */ +static int pop PARAMS ((int x)); + +static inline int +pop (x) + int x; +{ + /* We assume that no more than 16 bits are used. */ + x = ((x & ~0x5555) >> 1) + (x & 0x5555); + x = ((x & ~0x3333) >> 2) + (x & 0x3333); + x = ((x >> 4) + x) & 0x0f0f; + x = ((x >> 8) + x) & 0xff; + + return x; +} + + +struct loaded_l10nfile * +_nl_make_l10nflist (l10nfile_list, dirlist, dirlist_len, mask, language, + territory, codeset, normalized_codeset, modifier, special, + sponsor, revision, filename, do_allocate) + struct loaded_l10nfile **l10nfile_list; + const char *dirlist; + size_t dirlist_len; + int mask; + const char *language; + const char *territory; + const char *codeset; + const char *normalized_codeset; + const char *modifier; + const char *special; + const char *sponsor; + const char *revision; + const char *filename; + int do_allocate; +{ + char *abs_filename; + struct loaded_l10nfile *last = NULL; + struct loaded_l10nfile *retval; + char *cp; + size_t entries; + int cnt; + + /* Allocate room for the full file name. */ + abs_filename = (char *) malloc (dirlist_len + + strlen (language) + + ((mask & TERRITORY) != 0 + ? strlen (territory) + 1 : 0) + + ((mask & XPG_CODESET) != 0 + ? strlen (codeset) + 1 : 0) + + ((mask & XPG_NORM_CODESET) != 0 + ? strlen (normalized_codeset) + 1 : 0) + + (((mask & XPG_MODIFIER) != 0 + || (mask & CEN_AUDIENCE) != 0) + ? strlen (modifier) + 1 : 0) + + ((mask & CEN_SPECIAL) != 0 + ? strlen (special) + 1 : 0) + + (((mask & CEN_SPONSOR) != 0 + || (mask & CEN_REVISION) != 0) + ? (1 + ((mask & CEN_SPONSOR) != 0 + ? strlen (sponsor) + 1 : 0) + + ((mask & CEN_REVISION) != 0 + ? strlen (revision) + 1 : 0)) : 0) + + 1 + strlen (filename) + 1); + + if (abs_filename == NULL) + return NULL; + + retval = NULL; + last = NULL; + + /* Construct file name. */ + memcpy (abs_filename, dirlist, dirlist_len); + __argz_stringify (abs_filename, dirlist_len, ':'); + cp = abs_filename + (dirlist_len - 1); + *cp++ = '/'; + cp = stpcpy (cp, language); + + if ((mask & TERRITORY) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, territory); + } + if ((mask & XPG_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, codeset); + } + if ((mask & XPG_NORM_CODESET) != 0) + { + *cp++ = '.'; + cp = stpcpy (cp, normalized_codeset); + } + if ((mask & (XPG_MODIFIER | CEN_AUDIENCE)) != 0) + { + /* This component can be part of both syntaces but has different + leading characters. For CEN we use `+', else `@'. */ + *cp++ = (mask & CEN_AUDIENCE) != 0 ? '+' : '@'; + cp = stpcpy (cp, modifier); + } + if ((mask & CEN_SPECIAL) != 0) + { + *cp++ = '+'; + cp = stpcpy (cp, special); + } + if ((mask & (CEN_SPONSOR | CEN_REVISION)) != 0) + { + *cp++ = ','; + if ((mask & CEN_SPONSOR) != 0) + cp = stpcpy (cp, sponsor); + if ((mask & CEN_REVISION) != 0) + { + *cp++ = '_'; + cp = stpcpy (cp, revision); + } + } + + *cp++ = '/'; + stpcpy (cp, filename); + + /* Look in list of already loaded domains whether it is already + available. */ + last = NULL; + for (retval = *l10nfile_list; retval != NULL; retval = retval->next) + if (retval->filename != NULL) + { + int compare = strcmp (retval->filename, abs_filename); + if (compare == 0) + /* We found it! */ + break; + if (compare < 0) + { + /* It's not in the list. */ + retval = NULL; + break; + } + + last = retval; + } + + if (retval != NULL || do_allocate == 0) + { + free (abs_filename); + return retval; + } + + retval = (struct loaded_l10nfile *) + malloc (sizeof (*retval) + (__argz_count (dirlist, dirlist_len) + * (1 << pop (mask)) + * sizeof (struct loaded_l10nfile *))); + if (retval == NULL) + return NULL; + + retval->filename = abs_filename; + retval->decided = (__argz_count (dirlist, dirlist_len) != 1 + || ((mask & XPG_CODESET) != 0 + && (mask & XPG_NORM_CODESET) != 0)); + retval->data = NULL; + + if (last == NULL) + { + retval->next = *l10nfile_list; + *l10nfile_list = retval; + } + else + { + retval->next = last->next; + last->next = retval; + } + + entries = 0; + /* If the DIRLIST is a real list the RETVAL entry corresponds not to + a real file. So we have to use the DIRLIST separation mechanism + of the inner loop. */ + cnt = __argz_count (dirlist, dirlist_len) == 1 ? mask - 1 : mask; + for (; cnt >= 0; --cnt) + if ((cnt & ~mask) == 0 + && ((cnt & CEN_SPECIFIC) == 0 || (cnt & XPG_SPECIFIC) == 0) + && ((cnt & XPG_CODESET) == 0 || (cnt & XPG_NORM_CODESET) == 0)) + { + /* Iterate over all elements of the DIRLIST. */ + char *dir = NULL; + + while ((dir = __argz_next ((char *) dirlist, dirlist_len, dir)) + != NULL) + retval->successor[entries++] + = _nl_make_l10nflist (l10nfile_list, dir, strlen (dir) + 1, cnt, + language, territory, codeset, + normalized_codeset, modifier, special, + sponsor, revision, filename, 1); + } + retval->successor[entries] = NULL; + + return retval; +} + +/* Normalize codeset name. There is no standard for the codeset + names. Normalization allows the user to use any of the common + names. */ +const char * +_nl_normalize_codeset (codeset, name_len) + const unsigned char *codeset; + size_t name_len; +{ + int len = 0; + int only_digit = 1; + char *retval; + char *wp; + size_t cnt; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalnum (codeset[cnt])) + { + ++len; + + if (isalpha (codeset[cnt])) + only_digit = 0; + } + + retval = (char *) malloc ((only_digit ? 3 : 0) + len + 1); + + if (retval != NULL) + { + if (only_digit) + wp = stpcpy (retval, "iso"); + else + wp = retval; + + for (cnt = 0; cnt < name_len; ++cnt) + if (isalpha (codeset[cnt])) + *wp++ = tolower (codeset[cnt]); + else if (isdigit (codeset[cnt])) + *wp++ = codeset[cnt]; + + *wp = '\0'; + } + + return (const char *) retval; +} + + +/* @@ begin of epilog @@ */ + +/* We don't want libintl.a to depend on any other library. So we + avoid the non-standard function stpcpy. In GNU C Library this + function is available, though. Also allow the symbol HAVE_STPCPY + to be defined. */ +#if !_LIBC && !HAVE_STPCPY +static char * +stpcpy (dest, src) + char *dest; + const char *src; +{ + while ((*dest++ = *src++) != '\0') + /* Do nothing. */ ; + return dest - 1; +} +#endif diff --git a/apt/intl/libgettext.h b/apt/intl/libgettext.h new file mode 100644 index 0000000..3a92960 --- /dev/null +++ b/apt/intl/libgettext.h @@ -0,0 +1,182 @@ +/* Message catalogs for internationalization. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +/* Because on some systems (e.g. Solaris) we sometimes have to include + the systems libintl.h as well as this file we have more complex + include protection above. But the systems header might perhaps also + define _LIBINTL_H and therefore we have to protect the definition here. */ + +#if !defined _LIBINTL_H || !defined _LIBGETTEXT_H +#ifndef _LIBINTL_H +# define _LIBINTL_H 1 +#endif +#define _LIBGETTEXT_H 1 + +/* We define an additional symbol to signal that we use the GNU + implementation of gettext. */ +#define __USE_GNU_GETTEXT 1 + +#include + +#if HAVE_LOCALE_H +# include +#endif + + +#ifdef __cplusplus +extern "C" { +#endif + +/* @@ end of prolog @@ */ + +#ifndef PARAMS +# if __STDC__ || defined __cplusplus +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +#ifndef NULL +# if !defined __cplusplus || defined __GNUC__ +# define NULL ((void *) 0) +# else +# define NULL (0) +# endif +#endif + +#if !HAVE_LC_MESSAGES +/* This value determines the behaviour of the gettext() and dgettext() + function. But some system does not have this defined. Define it + to a default value. */ +# define LC_MESSAGES (-1) +#endif + + +/* Declarations for gettext-using-catgets interface. Derived from + Jim Meyering's libintl.h. */ +struct _msg_ent +{ + const char *_msg; + int _msg_number; +}; + + +#if HAVE_CATGETS +/* These two variables are defined in the automatically by po-to-tbl.sed + generated file `cat-id-tbl.c'. */ +extern const struct _msg_ent _msg_tbl[]; +extern int _msg_tbl_length; +#endif + + +/* For automatical extraction of messages sometimes no real + translation is needed. Instead the string itself is the result. */ +#define gettext_noop(Str) (Str) + +/* Look up MSGID in the current default message catalog for the current + LC_MESSAGES locale. If not found, returns MSGID itself (the default + text). */ +extern char *gettext PARAMS ((const char *__msgid)); +extern char *gettext__ PARAMS ((const char *__msgid)); + +/* Look up MSGID in the DOMAINNAME message catalog for the current + LC_MESSAGES locale. */ +extern char *dgettext PARAMS ((const char *__domainname, const char *__msgid)); +extern char *dgettext__ PARAMS ((const char *__domainname, + const char *__msgid)); + +/* Look up MSGID in the DOMAINNAME message catalog for the current CATEGORY + locale. */ +extern char *dcgettext PARAMS ((const char *__domainname, const char *__msgid, + int __category)); +extern char *dcgettext__ PARAMS ((const char *__domainname, + const char *__msgid, int __category)); + + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +extern char *textdomain PARAMS ((const char *__domainname)); +extern char *textdomain__ PARAMS ((const char *__domainname)); + +/* Specify that the DOMAINNAME message catalog will be found + in DIRNAME rather than in the system locale data base. */ +extern char *bindtextdomain PARAMS ((const char *__domainname, + const char *__dirname)); +extern char *bindtextdomain__ PARAMS ((const char *__domainname, + const char *__dirname)); + +#if ENABLE_NLS + +/* Solaris 2.3 has the gettext function but dcgettext is missing. + So we omit this optimization for Solaris 2.3. BTW, Solaris 2.4 + has dcgettext. */ +# if !HAVE_CATGETS && (!HAVE_GETTEXT || HAVE_DCGETTEXT) + +# define gettext(Msgid) \ + dgettext (NULL, Msgid) + +# define dgettext(Domainname, Msgid) \ + dcgettext (Domainname, Msgid, LC_MESSAGES) + +# if defined __GNUC__ && __GNUC__ == 2 && __GNUC_MINOR__ >= 7 +/* This global variable is defined in loadmsgcat.c. We need a sign, + whether a new catalog was loaded, which can be associated with all + translations. */ +extern int _nl_msg_cat_cntr; + +# define dcgettext(Domainname, Msgid, Category) \ + (__extension__ \ + ({ \ + char *__result; \ + if (__builtin_constant_p (Msgid)) \ + { \ + static char *__translation__; \ + static int __catalog_counter__; \ + if (! __translation__ || __catalog_counter__ != _nl_msg_cat_cntr) \ + { \ + __translation__ = \ + dcgettext__ (Domainname, Msgid, Category); \ + __catalog_counter__ = _nl_msg_cat_cntr; \ + } \ + __result = __translation__; \ + } \ + else \ + __result = dcgettext__ (Domainname, Msgid, Category); \ + __result; \ + })) +# endif +# endif + +#else + +# define gettext(Msgid) (Msgid) +# define dgettext(Domainname, Msgid) (Msgid) +# define dcgettext(Domainname, Msgid, Category) (Msgid) +# define textdomain(Domainname) ((char *) Domainname) +# define bindtextdomain(Domainname, Dirname) ((char *) Dirname) + +#endif + +/* @@ begin of epilog @@ */ + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/apt/intl/linux-msg.sed b/apt/intl/linux-msg.sed new file mode 100644 index 0000000..5918e72 --- /dev/null +++ b/apt/intl/linux-msg.sed @@ -0,0 +1,100 @@ +# po2msg.sed - Convert Uniforum style .po file to Linux style .msg file +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# The first directive in the .msg should be the definition of the +# message set number. We use always set number 1. +# +1 { + i\ +$set 1 # Automatically created by po2msg.sed + h + s/.*/0/ + x +} +# +# Mitch's old catalog format does not allow comments. +# +# We copy the original message as a comment into the .msg file. +# +/^msgid/ { + s/msgid[ ]*"// +# +# This does not work now with the new format. +# /"$/! { +# s/\\$// +# s/$/ ... (more lines following)"/ +# } + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x + G + s/\(.*\)"\n\([0-9]*\)/$ #\2 Original Message:(\1)/p +} +# +# The .msg file contains, other then the .po file, only the translations +# but each given a unique ID. Starting from 1 and incrementing by 1 for +# each message we assign them to the messages. +# It is important that the .po file used to generate the cat-id-tbl.c file +# (with po-to-tbl) is the same as the one used here. (At least the order +# of declarations must not be changed.) +# +/^msgstr/ { + s/msgstr[ ]*"\(.*\)"/# \1/ +# Clear substitution flag. + tb +# Append the next line. + :b + N +# Look whether second part is continuation line. + s/\(.*\n\)"\(.*\)"/\1\2/ +# Yes, then branch. + ta + P + D +# Note that D includes a jump to the start!! +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use D here. + s/.*\n\(.*\)/\1/ + tb +} +d diff --git a/apt/intl/loadinfo.h b/apt/intl/loadinfo.h new file mode 100644 index 0000000..f4ebf6d --- /dev/null +++ b/apt/intl/loadinfo.h @@ -0,0 +1,76 @@ +/* Copyright (C) 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper , 1996. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifndef PARAMS +# if __STDC__ +# define PARAMS(args) args +# else +# define PARAMS(args) () +# endif +#endif + +/* Encoding of locale name parts. */ +#define CEN_REVISION 1 +#define CEN_SPONSOR 2 +#define CEN_SPECIAL 4 +#define XPG_NORM_CODESET 8 +#define XPG_CODESET 16 +#define TERRITORY 32 +#define CEN_AUDIENCE 64 +#define XPG_MODIFIER 128 + +#define CEN_SPECIFIC (CEN_REVISION|CEN_SPONSOR|CEN_SPECIAL|CEN_AUDIENCE) +#define XPG_SPECIFIC (XPG_CODESET|XPG_NORM_CODESET|XPG_MODIFIER) + + +struct loaded_l10nfile +{ + const char *filename; + int decided; + + const void *data; + + struct loaded_l10nfile *next; + struct loaded_l10nfile *successor[1]; +}; + + +extern const char *_nl_normalize_codeset PARAMS ((const unsigned char *codeset, + size_t name_len)); + +extern struct loaded_l10nfile * +_nl_make_l10nflist PARAMS ((struct loaded_l10nfile **l10nfile_list, + const char *dirlist, size_t dirlist_len, int mask, + const char *language, const char *territory, + const char *codeset, + const char *normalized_codeset, + const char *modifier, const char *special, + const char *sponsor, const char *revision, + const char *filename, int do_allocate)); + + +extern const char *_nl_expand_alias PARAMS ((const char *name)); + +extern int _nl_explode_name PARAMS ((char *name, const char **language, + const char **modifier, + const char **territory, + const char **codeset, + const char **normalized_codeset, + const char **special, + const char **sponsor, + const char **revision)); diff --git a/apt/intl/loadmsgcat.c b/apt/intl/loadmsgcat.c new file mode 100644 index 0000000..515892d --- /dev/null +++ b/apt/intl/loadmsgcat.c @@ -0,0 +1,222 @@ +/* Load needed message catalogs. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#if defined HAVE_UNISTD_H || defined _LIBC +# include +#endif + +#if (defined HAVE_MMAP && defined HAVE_MUNMAP) || defined _LIBC +# include +#endif + +#include "gettext.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ISO C functions. This is required by the standard + because some ISO C functions will require linking with this object + file and the name space must not be polluted. */ +# define open __open +# define close __close +# define read __read +# define mmap __mmap +# define munmap __munmap +#endif + +/* We need a sign, whether a new catalog was loaded, which can be associated + with all translations. This is important if the translations are + cached by one of GCC's features. */ +int _nl_msg_cat_cntr = 0; + + +/* Load the message catalogs specified by FILENAME. If it is no valid + message catalog do nothing. */ +void +internal_function +_nl_load_domain (domain_file) + struct loaded_l10nfile *domain_file; +{ + int fd; + size_t size; + struct stat st; + struct mo_file_header *data = (struct mo_file_header *) -1; +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + int use_mmap = 0; +#endif + struct loaded_domain *domain; + + domain_file->decided = 1; + domain_file->data = NULL; + + /* If the record does not represent a valid locale the FILENAME + might be NULL. This can happen when according to the given + specification the locale file name is different for XPG and CEN + syntax. */ + if (domain_file->filename == NULL) + return; + + /* Try to open the addressed file. */ + fd = open (domain_file->filename, O_RDONLY); + if (fd == -1) + return; + + /* We must know about the size of the file. */ + if (fstat (fd, &st) != 0 + || (size = (size_t) st.st_size) != st.st_size + || size < sizeof (struct mo_file_header)) + { + /* Something went wrong. */ + close (fd); + return; + } + +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + /* Now we are ready to load the file. If mmap() is available we try + this first. If not available or it failed we try to load it. */ + data = (struct mo_file_header *) mmap (NULL, size, PROT_READ, + MAP_PRIVATE, fd, 0); + + if (data != (struct mo_file_header *) -1) + { + /* mmap() call was successful. */ + close (fd); + use_mmap = 1; + } +#endif + + /* If the data is not yet available (i.e. mmap'ed) we try to load + it manually. */ + if (data == (struct mo_file_header *) -1) + { + size_t to_read; + char *read_ptr; + + data = (struct mo_file_header *) malloc (size); + if (data == NULL) + return; + + to_read = size; + read_ptr = (char *) data; + do + { + long int nb = (long int) read (fd, read_ptr, to_read); + if (nb == -1) + { + close (fd); + return; + } + + read_ptr += nb; + to_read -= nb; + } + while (to_read > 0); + + close (fd); + } + + /* Using the magic number we can test whether it really is a message + catalog file. */ + if (data->magic != _MAGIC && data->magic != _MAGIC_SWAPPED) + { + /* The magic number is wrong: not a message catalog file. */ +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + return; + } + + domain_file->data + = (struct loaded_domain *) malloc (sizeof (struct loaded_domain)); + if (domain_file->data == NULL) + return; + + domain = (struct loaded_domain *) domain_file->data; + domain->data = (char *) data; +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + domain->use_mmap = use_mmap; +#endif + domain->mmap_size = size; + domain->must_swap = data->magic != _MAGIC; + + /* Fill in the information about the available tables. */ + switch (W (domain->must_swap, data->revision)) + { + case 0: + domain->nstrings = W (domain->must_swap, data->nstrings); + domain->orig_tab = (struct string_desc *) + ((char *) data + W (domain->must_swap, data->orig_tab_offset)); + domain->trans_tab = (struct string_desc *) + ((char *) data + W (domain->must_swap, data->trans_tab_offset)); + domain->hash_size = W (domain->must_swap, data->hash_tab_size); + domain->hash_tab = (nls_uint32 *) + ((char *) data + W (domain->must_swap, data->hash_tab_offset)); + break; + default: + /* This is an illegal revision. */ +#if (defined HAVE_MMAP && defined HAVE_MUNMAP && !defined DISALLOW_MMAP) \ + || defined _LIBC + if (use_mmap) + munmap ((caddr_t) data, size); + else +#endif + free (data); + free (domain); + domain_file->data = NULL; + return; + } + + /* Show that one domain is changed. This might make some cached + translations invalid. */ + ++_nl_msg_cat_cntr; +} + + +#ifdef _LIBC +void +internal_function +_nl_unload_domain (domain) + struct loaded_domain *domain; +{ + if (domain->use_mmap) + munmap ((caddr_t) domain->data, domain->mmap_size); + else + free ((void *) domain->data); + + free (domain); +} +#endif diff --git a/apt/intl/localealias.c b/apt/intl/localealias.c new file mode 100644 index 0000000..7365454 --- /dev/null +++ b/apt/intl/localealias.c @@ -0,0 +1,424 @@ +/* Handle aliases for locale names. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include +#include +#include + +#ifdef __GNUC__ +# define alloca __builtin_alloca +# define HAVE_ALLOCA 1 +#else +# if defined HAVE_ALLOCA_H || defined _LIBC +# include +# else +# ifdef _AIX + #pragma alloca +# else +# ifndef alloca +char *alloca (); +# endif +# endif +# endif +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#else +char *getenv (); +# ifdef HAVE_MALLOC_H +# include +# else +void free (); +# endif +#endif + +#if defined HAVE_STRING_H || defined _LIBC +# ifndef _GNU_SOURCE +# define _GNU_SOURCE 1 +# endif +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) (bcopy (Src, Dst, Num), Dst) +# endif +#endif +#if !HAVE_STRCHR && !defined _LIBC +# ifndef strchr +# define strchr index +# endif +#endif + +#include "gettext.h" +#include "gettextP.h" + +/* @@ end of prolog @@ */ + +#ifdef _LIBC +/* Rename the non ANSI C functions. This is required by the standard + because some ANSI C functions will require linking with this object + file and the name space must not be polluted. */ +# define strcasecmp __strcasecmp + +# define mempcpy __mempcpy +# define HAVE_MEMPCPY 1 + +/* We need locking here since we can be called from different places. */ +# include + +__libc_lock_define_initialized (static, lock); +#endif + + +/* For those loosing systems which don't have `alloca' we have to add + some additional code emulating it. */ +#ifdef HAVE_ALLOCA +/* Nothing has to be done. */ +# define ADD_BLOCK(list, address) /* nothing */ +# define FREE_BLOCKS(list) /* nothing */ +#else +struct block_list +{ + void *address; + struct block_list *next; +}; +# define ADD_BLOCK(list, addr) \ + do { \ + struct block_list *newp = (struct block_list *) malloc (sizeof (*newp)); \ + /* If we cannot get a free block we cannot add the new element to \ + the list. */ \ + if (newp != NULL) { \ + newp->address = (addr); \ + newp->next = (list); \ + (list) = newp; \ + } \ + } while (0) +# define FREE_BLOCKS(list) \ + do { \ + while (list != NULL) { \ + struct block_list *old = list; \ + list = list->next; \ + free (old); \ + } \ + } while (0) +# undef alloca +# define alloca(size) (malloc (size)) +#endif /* have alloca */ + + +struct alias_map +{ + const char *alias; + const char *value; +}; + + +static char *string_space = NULL; +static size_t string_space_act = 0; +static size_t string_space_max = 0; +static struct alias_map *map; +static size_t nmap = 0; +static size_t maxmap = 0; + + +/* Prototypes for local functions. */ +static size_t read_alias_file PARAMS ((const char *fname, int fname_len)) + internal_function; +static void extend_alias_table PARAMS ((void)); +static int alias_compare PARAMS ((const struct alias_map *map1, + const struct alias_map *map2)); + + +const char * +_nl_expand_alias (name) + const char *name; +{ + static const char *locale_alias_path = LOCALE_ALIAS_PATH; + struct alias_map *retval; + const char *result = NULL; + size_t added; + +#ifdef _LIBC + __libc_lock_lock (lock); +#endif + + do + { + struct alias_map item; + + item.alias = name; + + if (nmap > 0) + retval = (struct alias_map *) bsearch (&item, map, nmap, + sizeof (struct alias_map), + (int (*) PARAMS ((const void *, + const void *)) + ) alias_compare); + else + retval = NULL; + + /* We really found an alias. Return the value. */ + if (retval != NULL) + { + result = retval->value; + break; + } + + /* Perhaps we can find another alias file. */ + added = 0; + while (added == 0 && locale_alias_path[0] != '\0') + { + const char *start; + + while (locale_alias_path[0] == ':') + ++locale_alias_path; + start = locale_alias_path; + + while (locale_alias_path[0] != '\0' && locale_alias_path[0] != ':') + ++locale_alias_path; + + if (start < locale_alias_path) + added = read_alias_file (start, locale_alias_path - start); + } + } + while (added != 0); + +#ifdef _LIBC + __libc_lock_unlock (lock); +#endif + + return result; +} + + +static size_t +internal_function +read_alias_file (fname, fname_len) + const char *fname; + int fname_len; +{ +#ifndef HAVE_ALLOCA + struct block_list *block_list = NULL; +#endif + FILE *fp; + char *full_fname; + size_t added; + static const char aliasfile[] = "/locale.alias"; + + full_fname = (char *) alloca (fname_len + sizeof aliasfile); + ADD_BLOCK (block_list, full_fname); +#ifdef HAVE_MEMPCPY + mempcpy (mempcpy (full_fname, fname, fname_len), + aliasfile, sizeof aliasfile); +#else + memcpy (full_fname, fname, fname_len); + memcpy (&full_fname[fname_len], aliasfile, sizeof aliasfile); +#endif + + fp = fopen (full_fname, "r"); + if (fp == NULL) + { + FREE_BLOCKS (block_list); + return 0; + } + + added = 0; + while (!feof (fp)) + { + /* It is a reasonable approach to use a fix buffer here because + a) we are only interested in the first two fields + b) these fields must be usable as file names and so must not + be that long + */ + char buf[BUFSIZ]; + char *alias; + char *value; + unsigned char *cp; + + if (fgets (buf, sizeof buf, fp) == NULL) + /* EOF reached. */ + break; + + /* Possibly not the whole line fits into the buffer. Ignore + the rest of the line. */ + if (strchr (buf, '\n') == NULL) + { + char altbuf[BUFSIZ]; + do + if (fgets (altbuf, sizeof altbuf, fp) == NULL) + /* Make sure the inner loop will be left. The outer loop + will exit at the `feof' test. */ + break; + while (strchr (altbuf, '\n') == NULL); + } + + cp = (unsigned char *) buf; + /* Ignore leading white space. */ + while (isspace (cp[0])) + ++cp; + + /* A leading '#' signals a comment line. */ + if (cp[0] != '\0' && cp[0] != '#') + { + alias = (char *) cp++; + while (cp[0] != '\0' && !isspace (cp[0])) + ++cp; + /* Terminate alias name. */ + if (cp[0] != '\0') + *cp++ = '\0'; + + /* Now look for the beginning of the value. */ + while (isspace (cp[0])) + ++cp; + + if (cp[0] != '\0') + { + size_t alias_len; + size_t value_len; + + value = (char *) cp++; + while (cp[0] != '\0' && !isspace (cp[0])) + ++cp; + /* Terminate value. */ + if (cp[0] == '\n') + { + /* This has to be done to make the following test + for the end of line possible. We are looking for + the terminating '\n' which do not overwrite here. */ + *cp++ = '\0'; + *cp = '\n'; + } + else if (cp[0] != '\0') + *cp++ = '\0'; + + if (nmap >= maxmap) + extend_alias_table (); + + alias_len = strlen (alias) + 1; + value_len = strlen (value) + 1; + + if (string_space_act + alias_len + value_len > string_space_max) + { + /* Increase size of memory pool. */ + size_t new_size = (string_space_max + + (alias_len + value_len > 1024 + ? alias_len + value_len : 1024)); + char *new_pool = (char *) realloc (string_space, new_size); + if (new_pool == NULL) + { + FREE_BLOCKS (block_list); + return added; + } + string_space = new_pool; + string_space_max = new_size; + } + + map[nmap].alias = memcpy (&string_space[string_space_act], + alias, alias_len); + string_space_act += alias_len; + + map[nmap].value = memcpy (&string_space[string_space_act], + value, value_len); + string_space_act += value_len; + + ++nmap; + ++added; + } + } + } + + /* Should we test for ferror()? I think we have to silently ignore + errors. --drepper */ + fclose (fp); + + if (added > 0) + qsort (map, nmap, sizeof (struct alias_map), + (int (*) PARAMS ((const void *, const void *))) alias_compare); + + FREE_BLOCKS (block_list); + return added; +} + + +static void +extend_alias_table () +{ + size_t new_size; + struct alias_map *new_map; + + new_size = maxmap == 0 ? 100 : 2 * maxmap; + new_map = (struct alias_map *) realloc (map, (new_size + * sizeof (struct alias_map))); + if (new_map == NULL) + /* Simply don't extend: we don't have any more core. */ + return; + + map = new_map; + maxmap = new_size; +} + + +#ifdef _LIBC +static void __attribute__ ((unused)) +free_mem (void) +{ + if (string_space != NULL) + free (string_space); + if (map != NULL) + free (map); +} +text_set_element (__libc_subfreeres, free_mem); +#endif + + +static int +alias_compare (map1, map2) + const struct alias_map *map1; + const struct alias_map *map2; +{ +#if defined _LIBC || defined HAVE_STRCASECMP + return strcasecmp (map1->alias, map2->alias); +#else + const unsigned char *p1 = (const unsigned char *) map1->alias; + const unsigned char *p2 = (const unsigned char *) map2->alias; + unsigned char c1, c2; + + if (p1 == p2) + return 0; + + do + { + /* I know this seems to be odd but the tolower() function in + some systems libc cannot handle nonalpha characters. */ + c1 = isupper (*p1) ? tolower (*p1) : *p1; + c2 = isupper (*p2) ? tolower (*p2) : *p2; + if (c1 == '\0') + break; + ++p1; + ++p2; + } + while (c1 == c2); + + return c1 - c2; +#endif +} diff --git a/apt/intl/po2tbl.sed.in b/apt/intl/po2tbl.sed.in new file mode 100644 index 0000000..ee89f8b --- /dev/null +++ b/apt/intl/po2tbl.sed.in @@ -0,0 +1,106 @@ +# po2tbl.sed - Convert Uniforum style .po file to lookup table for catgets +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +1 { + i\ +/* Automatically generated by po2tbl.sed from @PACKAGE NAME@.pot. */\ +\ +#if HAVE_CONFIG_H\ +# include \ +#endif\ +\ +#include "libgettext.h"\ +\ +const struct _msg_ent _msg_tbl[] = { + h + s/.*/0/ + x +} +# +# Write msgid entries in C array form. +# +/^msgid/ { + s/msgid[ ]*\(".*"\)/ {\1/ + tb +# Append the next line + :b + N +# Look whether second part is continuation line. + s/\(.*\)"\(\n\)"\(.*"\)/\1\2\3/ +# Yes, then branch. + ta +# Because we assume that the input file correctly formed the line +# just read cannot be again be a msgid line. So it's safe to ignore +# it. + s/\(.*\)\n.*/\1/ + bc +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ +# Escape trigraphs. + s/[?][?]\([-=(/)']\)/?\\?\1/g + P +# We cannot use D here. + s/.*\n\(.*\)/\1/ +# Some buggy seds do not clear the `successful substitution since last ``t''' +# flag on `N', so we do a `t' here to clear it. + tb +# Not reached + :c + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x + G + s/\(.*\)\n\([0-9]*\)/\1, \2},/ + s/\(.*\)"$/\1/ +# Escape trigraphs. + s/[?][?]\([-=(/)']\)/?\\?\1/g + p +} +# +# Last line. +# +$ { + i\ +};\ + + g + s/0*\(.*\)/int _msg_tbl_length = \1;/p +} +d diff --git a/apt/intl/textdomain.c b/apt/intl/textdomain.c new file mode 100644 index 0000000..8855746 --- /dev/null +++ b/apt/intl/textdomain.c @@ -0,0 +1,108 @@ +/* Implementation of the textdomain(3) function. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. + Written by Ulrich Drepper , 1995. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software Foundation, + Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#if defined STDC_HEADERS || defined _LIBC +# include +#endif + +#if defined STDC_HEADERS || defined HAVE_STRING_H || defined _LIBC +# include +#else +# include +# ifndef memcpy +# define memcpy(Dst, Src, Num) bcopy (Src, Dst, Num) +# endif +#endif + +#ifdef _LIBC +# include +#else +# include "libgettext.h" +#endif + +/* @@ end of prolog @@ */ + +/* Name of the default text domain. */ +extern const char _nl_default_default_domain[]; + +/* Default text domain in which entries for gettext(3) are to be found. */ +extern const char *_nl_current_default_domain; + + +/* Names for the libintl functions are a problem. They must not clash + with existing names and they should follow ANSI C. But this source + code is also used in GNU C Library where the names have a __ + prefix. So we have to make a difference here. */ +#ifdef _LIBC +# define TEXTDOMAIN __textdomain +# ifndef strdup +# define strdup(str) __strdup (str) +# endif +#else +# define TEXTDOMAIN textdomain__ +#endif + +/* Set the current default message catalog to DOMAINNAME. + If DOMAINNAME is null, return the current default. + If DOMAINNAME is "", reset to the default of "messages". */ +char * +TEXTDOMAIN (domainname) + const char *domainname; +{ + char *old; + + /* A NULL pointer requests the current setting. */ + if (domainname == NULL) + return (char *) _nl_current_default_domain; + + old = (char *) _nl_current_default_domain; + + /* If domain name is the null string set to default domain "messages". */ + if (domainname[0] == '\0' + || strcmp (domainname, _nl_default_default_domain) == 0) + _nl_current_default_domain = _nl_default_default_domain; + else + { + /* If the following malloc fails `_nl_current_default_domain' + will be NULL. This value will be returned and so signals we + are out of core. */ +#if defined _LIBC || defined HAVE_STRDUP + _nl_current_default_domain = strdup (domainname); +#else + size_t len = strlen (domainname) + 1; + char *cp = (char *) malloc (len); + if (cp != NULL) + memcpy (cp, domainname, len); + _nl_current_default_domain = cp; +#endif + } + + if (old != _nl_default_default_domain) + free (old); + + return (char *) _nl_current_default_domain; +} + +#ifdef _LIBC +/* Alias for function name in GNU C Library. */ +weak_alias (__textdomain, textdomain); +#endif diff --git a/apt/intl/xopen-msg.sed b/apt/intl/xopen-msg.sed new file mode 100644 index 0000000..b19c0bb --- /dev/null +++ b/apt/intl/xopen-msg.sed @@ -0,0 +1,104 @@ +# po2msg.sed - Convert Uniforum style .po file to X/Open style .msg file +# Copyright (C) 1995 Free Software Foundation, Inc. +# Ulrich Drepper , 1995. +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +# +# +# The first directive in the .msg should be the definition of the +# message set number. We use always set number 1. +# +1 { + i\ +$set 1 # Automatically created by po2msg.sed + h + s/.*/0/ + x +} +# +# We copy all comments into the .msg file. Perhaps they can help. +# +/^#/ s/^#[ ]*/$ /p +# +# We copy the original message as a comment into the .msg file. +# +/^msgid/ { +# Does not work now +# /"$/! { +# s/\\$// +# s/$/ ... (more lines following)"/ +# } + s/^msgid[ ]*"\(.*\)"$/$ Original Message: \1/ + p +} +# +# The .msg file contains, other then the .po file, only the translations +# but each given a unique ID. Starting from 1 and incrementing by 1 for +# each message we assign them to the messages. +# It is important that the .po file used to generate the cat-id-tbl.c file +# (with po-to-tbl) is the same as the one used here. (At least the order +# of declarations must not be changed.) +# +/^msgstr/ { + s/msgstr[ ]*"\(.*\)"/\1/ + x +# The following nice solution is by +# Bruno + td +# Increment a decimal number in pattern space. +# First hide trailing `9' digits. + :d + s/9\(_*\)$/_\1/ + td +# Assure at least one digit is available. + s/^\(_*\)$/0\1/ +# Increment the last digit. + s/8\(_*\)$/9\1/ + s/7\(_*\)$/8\1/ + s/6\(_*\)$/7\1/ + s/5\(_*\)$/6\1/ + s/4\(_*\)$/5\1/ + s/3\(_*\)$/4\1/ + s/2\(_*\)$/3\1/ + s/1\(_*\)$/2\1/ + s/0\(_*\)$/1\1/ +# Convert the hidden `9' digits to `0's. + s/_/0/g + x +# Bring the line in the format ` ' + G + s/^[^\n]*$/& / + s/\(.*\)\n\([0-9]*\)/\2 \1/ +# Clear flag from last substitution. + tb +# Append the next line. + :b + N +# Look whether second part is a continuation line. + s/\(.*\n\)"\(.*\)"/\1\2/ +# Yes, then branch. + ta + P + D +# Note that `D' includes a jump to the start!! +# We found a continuation line. But before printing insert '\'. + :a + s/\(.*\)\(\n.*\)/\1\\\2/ + P +# We cannot use the sed command `D' here + s/.*\n\(.*\)/\1/ + tb +} +d diff --git a/apt/methods/CVS/Entries b/apt/methods/CVS/Entries new file mode 100644 index 0000000..0fd23d9 --- /dev/null +++ b/apt/methods/CVS/Entries @@ -0,0 +1,17 @@ +/file.cc/1.2/Wed Aug 1 21:35:12 2001// +/cdrom.cc/1.3/Fri Aug 10 14:03:40 2001// +/connect.h/1.1.1.1/Fri Aug 10 14:03:40 2001// +/copy.cc/1.1.1.1/Fri Aug 10 14:03:40 2001// +/ftp.cc/1.3/Fri Aug 10 14:03:44 2001// +/ftp.h/1.1.1.1/Fri Aug 10 14:03:46 2001// +/gzip.cc/1.2/Fri Aug 10 14:03:46 2001// +/http.cc/1.3/Fri Aug 10 14:03:48 2001// +/http.h/1.1.1.1/Fri Aug 10 14:03:50 2001// +/makefile/1.7/Fri Aug 10 14:03:50 2001// +/rfc2553emu.cc/1.1.1.1/Fri Aug 10 14:03:58 2001// +/rfc2553emu.h/1.1.1.1/Fri Aug 10 14:03:58 2001// +/connect.cc/1.2/Tue Nov 13 14:24:16 2001// +/gpg.cc/1.7/Fri Nov 16 01:13:06 2001// +/rsh.cc/1.1/Fri Nov 30 20:34:13 2001// +/rsh.h/1.1/Fri Nov 30 20:34:13 2001// +D diff --git a/apt/methods/CVS/Repository b/apt/methods/CVS/Repository new file mode 100644 index 0000000..da58c51 --- /dev/null +++ b/apt/methods/CVS/Repository @@ -0,0 +1 @@ +rapt/methods diff --git a/apt/methods/CVS/Root b/apt/methods/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/methods/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/methods/cdrom.cc b/apt/methods/cdrom.cc new file mode 100644 index 0000000..e56de31 --- /dev/null +++ b/apt/methods/cdrom.cc @@ -0,0 +1,236 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: cdrom.cc,v 1.3 2001/06/25 16:16:18 kojima Exp $ +/* ###################################################################### + + CDROM URI method for APT + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include + +#include +#include +#include + /*}}}*/ + +class CDROMMethod : public pkgAcqMethod +{ + bool DatabaseLoaded; + ::Configuration Database; + string CurrentID; + string CDROM; + bool Mounted; + + virtual bool Fetch(FetchItem *Itm); + string GetID(string Name); + virtual void Exit(); + + bool Copy(string Src, string Dest); + + public: + + CDROMMethod(); +}; + +// CDROMMethod::CDROMethod - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +CDROMMethod::CDROMMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly | + SendConfig | NeedsCleanup | + Removable), + DatabaseLoaded(false), + Mounted(false) +{ +}; + /*}}}*/ +// CDROMMethod::Exit - Unmount the disc if necessary /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void CDROMMethod::Exit() +{ + if (Mounted == true) + UnmountCdrom(CDROM); +} + /*}}}*/ +// CDROMMethod::GetID - Search the database for a matching string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +string CDROMMethod::GetID(string Name) +{ + // Search for an ID + const Configuration::Item *Top = Database.Tree("CD"); + if (Top != 0) + Top = Top->Child; + + for (; Top != 0;) + { + if (Top->Value == Name) + return Top->Tag; + + Top = Top->Next; + } + return string(); +} + /*}}}*/ + +bool CDROMMethod::Copy(string Src, string Dest) +{ + // See if the file exists + FileFd From(Src,FileFd::ReadOnly); + FileFd To(Dest,FileFd::WriteEmpty); + To.EraseOnFailure(); + if (_error->PendingError() == true) + { + To.OpFail(); + return false; + } + + // Copy the file + if (CopyFile(From,To) == false) + { + To.OpFail(); + return false; + } + + From.Close(); + To.Close(); + + struct stat Buf; + if (stat(Src.c_str(),&Buf) != 0) + return _error->Error("File not found"); + + // Transfer the modification times + struct utimbuf TimeBuf; + TimeBuf.actime = Buf.st_atime; + TimeBuf.modtime = Buf.st_mtime; + if (utime(Dest.c_str(),&TimeBuf) != 0) + { + To.OpFail(); + return _error->Errno("utime","Failed to set modification time"); + } +} + +// CDROMMethod::Fetch - Fetch a file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool CDROMMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + string File = Get.Path; + FetchResult Res; + + bool Debug = _config->FindB("Debug::Acquire::cdrom",false); + + /* All IMS queries are returned as a hit, CDROMs are readonly so + time stamps never change */ + if (Itm->LastModified != 0) + { + Res.LastModified = Itm->LastModified; + Res.IMSHit = true; + Res.Filename = File; + URIDone(Res); + return true; + } + + // Load the database + if (DatabaseLoaded == false) + { + // Read the database + string DFile = _config->FindFile("Dir::State::cdroms"); + if (FileExists(DFile) == true) + { + if (ReadConfigFile(Database,DFile) == false) + return _error->Error("Unable to read the cdrom database %s", + DFile.c_str()); + } + DatabaseLoaded = true; + } + + // All non IMS queries for package files fail. + if (Itm->IndexFile == true || GetID(Get.Host).empty() == true) + { + Fail("Please use apt-cdrom to make this CD recognized by APT." + " apt-get update cannot be used to add new CDs"); + return true; + } + + // We already have a CD inserted, but it is the wrong one + if (CurrentID.empty() == false && Database.Find("CD::" + CurrentID) != Get.Host) + { + Fail("Wrong CD",true); + return true; + } + + CDROM = _config->FindDir("Acquire::cdrom::mount","/cdrom/"); + if (CDROM[0] == '.') + CDROM= SafeGetCWD() + '/' + CDROM; + string NewID; + while (CurrentID.empty() == true) + { + bool Hit = false; + for (unsigned int Version = 2; Version != 0; Version--) + { + if (IdentCdrom(CDROM,NewID,Version) == false) + return false; + + if (Debug == true) + clog << "ID " << Version << " " << NewID << endl; + + // A hit + if (Database.Find("CD::" + NewID) == Get.Host) + { + Hit = true; + break; + } + } + + if (Hit == true) + break; + + // I suppose this should prompt somehow? + if (UnmountCdrom(CDROM) == false) + return _error->Error("Unable to unmount the CD-ROM in %s, it may still be in use.", + CDROM.c_str()); + if (MediaFail(Get.Host,CDROM) == false) + { + CurrentID = "FAIL"; + Fail("Wrong CD",true); + return true; + } + + MountCdrom(CDROM); + Mounted = true; + } + + // Found a CD + if (_config->FindB("Acquire::cdrom::copy", false) == true) { + Res.Filename = Queue->DestFile; + URIStart(Res); + Copy(CDROM+File, Queue->DestFile); + } else { + Res.Filename = CDROM + File; + } + + struct stat Buf; + if (stat(Res.Filename.c_str(),&Buf) != 0) + return _error->Error("File not found"); + if (NewID.empty() == false) + CurrentID = NewID; + Res.LastModified = Buf.st_mtime; + Res.Size = Buf.st_size; + URIDone(Res); + return true; +} + /*}}}*/ + +int main() +{ + CDROMMethod Mth; + return Mth.Run(); +} diff --git a/apt/methods/connect.cc b/apt/methods/connect.cc new file mode 100644 index 0000000..ba6693d --- /dev/null +++ b/apt/methods/connect.cc @@ -0,0 +1,168 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: connect.cc,v 1.2 2001/11/12 16:04:38 kojima Exp $ +/* ###################################################################### + + Connect - Replacement connect call + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include "connect.h" +#include +#include + +#include +#include +#include + +// Internet stuff +#include +#include +#include +#include + +#include "rfc2553emu.h" + /*}}}*/ + +static string LastHost; +static int LastPort = 0; +static struct addrinfo *LastHostAddr = 0; +static struct addrinfo *LastUsed = 0; + +// DoConnect - Attempt a connect operation /*{{{*/ +// --------------------------------------------------------------------- +/* This helper function attempts a connection to a single address. */ +static bool DoConnect(struct addrinfo *Addr,string Host, + unsigned long TimeOut,int &Fd,pkgAcqMethod *Owner) +{ + // Show a status indicator + char Name[NI_MAXHOST]; + Name[0] = 0; + getnameinfo(Addr->ai_addr,Addr->ai_addrlen, + Name,sizeof(Name),0,0,NI_NUMERICHOST); + Owner->Status("Connecting to %s (%s)",Host.c_str(),Name); + + // Get a socket + if ((Fd = socket(Addr->ai_family,Addr->ai_socktype, + Addr->ai_protocol)) < 0) + return _error->Errno("socket","Could not create a socket"); + + SetNonBlock(Fd,true); + if (connect(Fd,Addr->ai_addr,Addr->ai_addrlen) < 0 && + errno != EINPROGRESS) + return _error->Errno("connect","Cannot initiate the connection " + "to %s (%s).",Host.c_str(),Name); + + /* This implements a timeout for connect by opening the connection + nonblocking */ + if (WaitFd(Fd,true,TimeOut) == false) + return _error->Error("Could not connect to %s (%s), " + "connection timed out",Host.c_str(),Name); + + // Check the socket for an error condition + unsigned int Err; + unsigned int Len = sizeof(Err); + if (getsockopt(Fd,SOL_SOCKET,SO_ERROR,&Err,&Len) != 0) + return _error->Errno("getsockopt","Failed"); + + if (Err != 0) + return _error->Error("Could not connect to %s (%s).",Host.c_str(),Name); + + return true; +} + /*}}}*/ +// Connect - Connect to a server /*{{{*/ +// --------------------------------------------------------------------- +/* Performs a connection to the server */ +bool Connect(string Host,int Port,const char *Service,int DefPort,int &Fd, + unsigned long TimeOut,pkgAcqMethod *Owner) +{ + if (_error->PendingError() == true) + return false; + + /* We used a cached address record.. Yes this is against the spec but + the way we have setup our rotating dns suggests that this is more + sensible */ + if (LastHost != Host || LastPort != Port) + { + Owner->Status("Connecting to %s",Host.c_str()); + + // Lookup the host + char S[300]; + if (Port != 0) + snprintf(S,sizeof(S),"%u",Port); + else + snprintf(S,sizeof(S),"%s",Service); + + // Free the old address structure + if (LastHostAddr != 0) + { + freeaddrinfo(LastHostAddr); + LastHostAddr = 0; + } + + // We only understand SOCK_STREAM sockets. + struct addrinfo Hints; + memset(&Hints,0,sizeof(Hints)); + Hints.ai_socktype = SOCK_STREAM; + Hints.ai_protocol = IPPROTO_TCP; // Right? + + // Resolve both the host and service simultaneously + while (1) + { + int Res; + if ((Res = getaddrinfo(Host.c_str(),S,&Hints,&LastHostAddr)) != 0 || + LastHostAddr == 0) + { + if (Res == EAI_NONAME || Res == EAI_SERVICE) + { + if (DefPort != 0) + { + snprintf(S,sizeof(S),"%u",DefPort); + DefPort = 0; + continue; + } + return _error->Error("Could not resolve '%s'",Host.c_str()); + } + + return _error->Error("Something wicked happened resolving '%s/%s'", + Host.c_str(),S); + } + break; + } + + if (LastHostAddr->ai_family == AF_UNIX) + return _error->Error("getaddrinfo returned a unix domain socket\n"); + + LastHost = Host; + LastPort = Port; + LastUsed = 0; + } + + // Get the printable IP address + struct addrinfo *CurHost = LastHostAddr; + if (LastUsed != 0) + CurHost = LastUsed; + + while (CurHost != 0) + { + if (DoConnect(CurHost,Host,TimeOut,Fd,Owner) == true) + { + LastUsed = CurHost; + return true; + } + close(Fd); + Fd = -1; + + CurHost = CurHost->ai_next; + LastUsed = 0; + if (CurHost != 0) + _error->Discard(); + } + + if (_error->PendingError() == true) + return false; + return _error->Error("Unable to connect to '%s'",Host.c_str()); +} + /*}}}*/ diff --git a/apt/methods/connect.h b/apt/methods/connect.h new file mode 100644 index 0000000..85d920d --- /dev/null +++ b/apt/methods/connect.h @@ -0,0 +1,19 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: connect.h,v 1.1.1.1 2000/08/10 12:42:38 kojima Exp $ +/* ###################################################################### + + Connect - Replacement connect call + + ##################################################################### */ + /*}}}*/ +#ifndef CONNECT_H +#define CONNECT_H + +#include +#include + +bool Connect(string To,int Port,const char *Service,int DefPort, + int &Fd,unsigned long TimeOut,pkgAcqMethod *Owner); + +#endif diff --git a/apt/methods/copy.cc b/apt/methods/copy.cc new file mode 100644 index 0000000..536bd98 --- /dev/null +++ b/apt/methods/copy.cc @@ -0,0 +1,90 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: copy.cc,v 1.1.1.1 2000/08/10 12:42:38 kojima Exp $ +/* ###################################################################### + + Copy URI - This method takes a uri like a file: uri and copies it + to the destination file. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include + +#include +#include +#include + /*}}}*/ + +class CopyMethod : public pkgAcqMethod +{ + virtual bool Fetch(FetchItem *Itm); + + public: + + CopyMethod() : pkgAcqMethod("1.0",SingleInstance) {}; +}; + +// CopyMethod::Fetch - Fetch a file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool CopyMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + string File = Get.Path; + + // Stat the file and send a start message + struct stat Buf; + if (stat(File.c_str(),&Buf) != 0) + return _error->Errno("stat","Failed to stat"); + + // Forumulate a result and send a start message + FetchResult Res; + Res.Size = Buf.st_size; + Res.Filename = Itm->DestFile; + Res.LastModified = Buf.st_mtime; + Res.IMSHit = false; + URIStart(Res); + + // See if the file exists + FileFd From(File,FileFd::ReadOnly); + FileFd To(Itm->DestFile,FileFd::WriteEmpty); + To.EraseOnFailure(); + if (_error->PendingError() == true) + { + To.OpFail(); + return false; + } + + // Copy the file + if (CopyFile(From,To) == false) + { + To.OpFail(); + return false; + } + + From.Close(); + To.Close(); + + // Transfer the modification times + struct utimbuf TimeBuf; + TimeBuf.actime = Buf.st_atime; + TimeBuf.modtime = Buf.st_mtime; + if (utime(Itm->DestFile.c_str(),&TimeBuf) != 0) + { + To.OpFail(); + return _error->Errno("utime","Failed to set modification time"); + } + + URIDone(Res); + return true; +} + /*}}}*/ + +int main() +{ + CopyMethod Mth; + return Mth.Run(); +} diff --git a/apt/methods/file.cc b/apt/methods/file.cc new file mode 100644 index 0000000..420da60 --- /dev/null +++ b/apt/methods/file.cc @@ -0,0 +1,91 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: file.cc,v 1.2 2001/08/01 21:35:12 kojima Exp $ +/* ###################################################################### + + File URI method for APT + + This simply checks that the file specified exists, if so the relevent + information is returned. If a .gz filename is specified then the file + name with .gz removed will also be checked and information about it + will be returned in Alt-* + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include + +#include +#include + /*}}}*/ + +class FileMethod : public pkgAcqMethod +{ + virtual bool Fetch(FetchItem *Itm); + + public: + + FileMethod() : pkgAcqMethod("1.0",SingleInstance | LocalOnly | SendConfig) {}; +}; + +// FileMethod::Fetch - Fetch a file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool FileMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + string File = Get.Path; + FetchResult Res; + if (Get.Host.empty() == false) + return _error->Error("Invalid URI, local URIS must not start with //"); + + // See if the file exists + struct stat Buf; + if (stat(File.c_str(),&Buf) == 0) + { + Res.Size = Buf.st_size; + Res.Filename = File; + Res.LastModified = Buf.st_mtime; + Res.IMSHit = false; + if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0) + Res.IMSHit = true; + } + + // See if we can compute a file without a .gz exentsion + string ComprExtension = _config->Find("Acquire::ComprExtension"); + if(ComprExtension.empty() == true) { + ComprExtension = ".bz2"; + } + string::size_type Pos = File.rfind(ComprExtension); + if (Pos + ComprExtension.length() == File.length()) + { + File = string(File,0,Pos); + if (stat(File.c_str(),&Buf) == 0) + { + FetchResult AltRes; + AltRes.Size = Buf.st_size; + AltRes.Filename = File; + AltRes.LastModified = Buf.st_mtime; + AltRes.IMSHit = false; + if (Itm->LastModified == Buf.st_mtime && Itm->LastModified != 0) + AltRes.IMSHit = true; + + URIDone(Res,&AltRes); + return true; + } + } + + if (Res.Filename.empty() == true) + return _error->Error("File not found"); + + URIDone(Res); + return true; +} + /*}}}*/ + +int main() +{ + FileMethod Mth; + return Mth.Run(); +} diff --git a/apt/methods/ftp.cc b/apt/methods/ftp.cc new file mode 100644 index 0000000..965e3f3 --- /dev/null +++ b/apt/methods/ftp.cc @@ -0,0 +1,933 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: ftp.cc,v 1.3 2001/02/20 18:20:02 kojima Exp $ +/* ###################################################################### + + HTTP Aquire Method - This is the FTP aquire method for APT. + + This is a very simple implementation that does not try to optimize + at all. Commands are sent syncronously with the FTP server (as the + rfc recommends, but it is not really necessary..) and no tricks are + done to speed things along. + + RFC 2428 describes the IPv6 FTP behavior + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +// Internet stuff +#include +#include +#include +#include + +#include "rfc2553emu.h" +#include "connect.h" +#include "ftp.h" + /*}}}*/ + +unsigned long TimeOut = 120; +URI Proxy; +string FtpMethod::FailFile; +int FtpMethod::FailFd = -1; +time_t FtpMethod::FailTime = 0; + +// FTPConn::FTPConn - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +FTPConn::FTPConn(URI Srv) : Len(0), ServerFd(-1), DataFd(-1), + DataListenFd(-1), ServerName(Srv) +{ + Debug = _config->FindB("Debug::Acquire::Ftp",false); + memset(&PasvAddr,0,sizeof(PasvAddr)); +} + /*}}}*/ +// FTPConn::~FTPConn - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +FTPConn::~FTPConn() +{ + Close(); +} + /*}}}*/ +// FTPConn::Close - Close down the connection /*{{{*/ +// --------------------------------------------------------------------- +/* Just tear down the socket and data socket */ +void FTPConn::Close() +{ + close(ServerFd); + ServerFd = -1; + close(DataFd); + DataFd = -1; + close(DataListenFd); + DataListenFd = -1; + memset(&PasvAddr,0,sizeof(PasvAddr)); +} + /*}}}*/ +// FTPConn::Open - Open a new connection /*{{{*/ +// --------------------------------------------------------------------- +/* Connect to the server using a non-blocking connection and perform a + login. */ +bool FTPConn::Open(pkgAcqMethod *Owner) +{ + // Use the already open connection if possible. + if (ServerFd != -1) + return true; + + Close(); + + // Determine the proxy setting + if (getenv("ftp_proxy") == 0) + { + string DefProxy = _config->Find("Acquire::ftp::Proxy"); + string SpecificProxy = _config->Find("Acquire::ftp::Proxy::" + ServerName.Host); + if (SpecificProxy.empty() == false) + { + if (SpecificProxy == "DIRECT") + Proxy = ""; + else + Proxy = SpecificProxy; + } + else + Proxy = DefProxy; + } + else + Proxy = getenv("ftp_proxy"); + + // Parse no_proxy, a , seperated list of domains + if (getenv("no_proxy") != 0) + { + const char *Start = getenv("no_proxy"); + const char *ServerEnd = ServerName.Host.end(); + + for (const char *Cur = Start; true ; Cur++) + { + if (*Cur != ',' && *Cur != 0) + continue; + + // match end of the string + if ((ServerName.Host.size() >= (Cur - Start)) + && stringcasecmp(ServerEnd - (Cur - Start), + ServerEnd,Start,Cur) == 0) + { + Proxy = ""; + break; + } + + Start = Cur + 1; + if (*Cur == 0) + break; + } + } + + // Determine what host and port to use based on the proxy settings + int Port = 0; + string Host; + if (Proxy.empty() == true) + { + if (ServerName.Port != 0) + Port = ServerName.Port; + Host = ServerName.Host; + } + else + { + if (Proxy.Port != 0) + Port = Proxy.Port; + Host = Proxy.Host; + } + + // Connect to the remote server + if (Connect(Host,Port,"ftp",21,ServerFd,TimeOut,Owner) == false) + return false; + socklen_t Len = sizeof(Peer); + if (getpeername(ServerFd,(sockaddr *)&Peer,&Len) != 0) + return _error->Errno("getpeername","Unable to determine the peer name"); + + Owner->Status("Logging in"); + return Login(); +} + /*}}}*/ +// FTPConn::Login - Login to the remote server /*{{{*/ +// --------------------------------------------------------------------- +/* This performs both normal login and proxy login using a simples script + stored in the config file. */ +bool FTPConn::Login() +{ + unsigned int Tag; + string Msg; + + // Setup the variables needed for authentication + string User = "anonymous"; + string Pass; + if (0) //akk + Pass = "apt_get_ftp_2.0@debian.linux.user"; + else + Pass = "apt_get_ftp_2.0@conectiva.linux.user"; + + // Fill in the user/pass + if (ServerName.User.empty() == false) + User = ServerName.User; + if (ServerName.Password.empty() == false) + Pass = ServerName.Password; + + // Perform simple login + if (Proxy.empty() == true) + { + // Read the initial response + if (ReadResp(Tag,Msg) == false) + return false; + if (Tag >= 400) + return _error->Error("Server refused our connection and said: %s",Msg.c_str()); + + // Send the user + if (WriteMsg(Tag,Msg,"USER %s",User.c_str()) == false) + return false; + if (Tag >= 400) + return _error->Error("USER failed, server said: %s",Msg.c_str()); + + // Send the Password + if (WriteMsg(Tag,Msg,"PASS %s",Pass.c_str()) == false) + return false; + if (Tag >= 400) + return _error->Error("PASS failed, server said: %s",Msg.c_str()); + + // Enter passive mode + if (_config->Exists("Acquire::FTP::Passive::" + ServerName.Host) == true) + TryPassive = _config->FindB("Acquire::FTP::Passive::" + ServerName.Host,true); + else + TryPassive = _config->FindB("Acquire::FTP::Passive",true); + } + else + { + // Read the initial response + if (ReadResp(Tag,Msg) == false) + return false; + if (Tag >= 400) + return _error->Error("Server refused our connection and said: %s",Msg.c_str()); + + // Perform proxy script execution + Configuration::Item const *Opts = _config->Tree("Acquire::ftp::ProxyLogin"); + if (Opts == 0 || Opts->Child == 0) + return _error->Error("A proxy server was specified but no login " + "script, Acquire::ftp::ProxyLogin is empty."); + Opts = Opts->Child; + + // Iterate over the entire login script + for (; Opts != 0; Opts = Opts->Next) + { + if (Opts->Value.empty() == true) + continue; + + // Substitute the variables into the command + char SitePort[20]; + if (ServerName.Port != 0) + sprintf(SitePort,"%u",ServerName.Port); + else + strcpy(SitePort,"21"); + string Tmp = Opts->Value; + Tmp = SubstVar(Tmp,"$(PROXY_USER)",Proxy.User); + Tmp = SubstVar(Tmp,"$(PROXY_PASS)",Proxy.Password); + Tmp = SubstVar(Tmp,"$(SITE_USER)",User); + Tmp = SubstVar(Tmp,"$(SITE_PASS)",Pass); + Tmp = SubstVar(Tmp,"$(SITE_PORT)",SitePort); + Tmp = SubstVar(Tmp,"$(SITE)",ServerName.Host); + + // Send the command + if (WriteMsg(Tag,Msg,"%s",Tmp.c_str()) == false) + return false; + if (Tag >= 400) + return _error->Error("Login script command '%s' failed, server said: %s",Tmp.c_str(),Msg.c_str()); + } + + // Enter passive mode + TryPassive = false; + if (_config->Exists("Acquire::FTP::Passive::" + ServerName.Host) == true) + TryPassive = _config->FindB("Acquire::FTP::Passive::" + ServerName.Host,true); + else + { + if (_config->Exists("Acquire::FTP::Proxy::Passive") == true) + TryPassive = _config->FindB("Acquire::FTP::Proxy::Passive",true); + else + TryPassive = _config->FindB("Acquire::FTP::Passive",true); + } + } + + // Binary mode + if (WriteMsg(Tag,Msg,"TYPE I") == false) + return false; + if (Tag >= 400) + return _error->Error("TYPE failed, server said: %s",Msg.c_str()); + + return true; +} + /*}}}*/ +// FTPConn::ReadLine - Read a line from the server /*{{{*/ +// --------------------------------------------------------------------- +/* This performs a very simple buffered read. */ +bool FTPConn::ReadLine(string &Text) +{ + if (ServerFd == -1) + return false; + + // Suck in a line + while (Len < sizeof(Buffer)) + { + // Scan the buffer for a new line + for (unsigned int I = 0; I != Len; I++) + { + // Escape some special chars + if (Buffer[I] == 0) + Buffer[I] = '?'; + + // End of line? + if (Buffer[I] != '\n') + continue; + + I++; + Text = string(Buffer,I); + memmove(Buffer,Buffer+I,Len - I); + Len -= I; + return true; + } + + // Wait for some data.. + if (WaitFd(ServerFd,false,TimeOut) == false) + { + Close(); + return _error->Error("Connection timeout"); + } + + // Suck it back + int Res = read(ServerFd,Buffer + Len,sizeof(Buffer) - Len); + if (Res <= 0) + { + _error->Errno("read","Read error"); + Close(); + return false; + } + Len += Res; + } + + return _error->Error("A response overflowed the buffer."); +} + /*}}}*/ +// FTPConn::ReadResp - Read a full response from the server /*{{{*/ +// --------------------------------------------------------------------- +/* This reads a reply code from the server, it handles both p */ +bool FTPConn::ReadResp(unsigned int &Ret,string &Text) +{ + // Grab the first line of the response + string Msg; + if (ReadLine(Msg) == false) + return false; + + // Get the ID code + char *End; + Ret = strtol(Msg.c_str(),&End,10); + if (End - Msg.c_str() != 3) + return _error->Error("Protocol corruption"); + + // All done ? + Text = Msg.c_str()+4; + if (*End == ' ') + { + if (Debug == true) + cerr << "<- '" << QuoteString(Text,"") << "'" << endl; + return true; + } + + if (*End != '-') + return _error->Error("Protocol corruption"); + + /* Okay, here we do the continued message trick. This is foolish, but + proftpd follows the protocol as specified and wu-ftpd doesn't, so + we filter. I wonder how many clients break if you use proftpd and + put a '- in the 3rd spot in the message? */ + char Leader[4]; + strncpy(Leader,Msg.c_str(),3); + Leader[3] = 0; + while (ReadLine(Msg) == true) + { + // Short, it must be using RFC continuation.. + if (Msg.length() < 4) + { + Text += Msg; + continue; + } + + // Oops, finished + if (strncmp(Msg.c_str(),Leader,3) == 0 && Msg[3] == ' ') + { + Text += Msg.c_str()+4; + break; + } + + // This message has the wu-ftpd style reply code prefixed + if (strncmp(Msg.c_str(),Leader,3) == 0 && Msg[3] == '-') + { + Text += Msg.c_str()+4; + continue; + } + + // Must be RFC style prefixing + Text += Msg; + } + + if (Debug == true && _error->PendingError() == false) + cerr << "<- '" << QuoteString(Text,"") << "'" << endl; + + return !_error->PendingError(); +} + /*}}}*/ +// FTPConn::WriteMsg - Send a message to the server /*{{{*/ +// --------------------------------------------------------------------- +/* Simple printf like function.. */ +bool FTPConn::WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...) +{ + va_list args; + va_start(args,Fmt); + + // sprintf the description + char S[400]; + vsnprintf(S,sizeof(S) - 4,Fmt,args); + strcat(S,"\r\n"); + + if (Debug == true) + cerr << "-> '" << QuoteString(S,"") << "'" << endl; + + // Send it off + unsigned long Len = strlen(S); + unsigned long Start = 0; + while (Len != 0) + { + if (WaitFd(ServerFd,true,TimeOut) == false) + { + Close(); + return _error->Error("Connection timeout"); + } + + int Res = write(ServerFd,S + Start,Len); + if (Res <= 0) + { + _error->Errno("write","Write Error"); + Close(); + return false; + } + + Len -= Res; + Start += Res; + } + + return ReadResp(Ret,Text); +} + /*}}}*/ +// FTPConn::GoPasv - Enter Passive mode /*{{{*/ +// --------------------------------------------------------------------- +/* Try to enter passive mode, the return code does not indicate if passive + mode could or could not be established, only if there was a fatal error. + Borrowed mostly from lftp. We have to enter passive mode every time + we make a data connection :| */ +bool FTPConn::GoPasv() +{ + // Try to enable pasv mode + unsigned int Tag; + string Msg; + if (WriteMsg(Tag,Msg,"PASV") == false) + return false; + + // Unsupported function + string::size_type Pos = Msg.find('('); + if (Tag >= 400 || Pos == string::npos) + { + memset(&PasvAddr,0,sizeof(PasvAddr)); + return true; + } + + // Scan it + unsigned a0,a1,a2,a3,p0,p1; + if (sscanf(Msg.c_str() + Pos,"(%u,%u,%u,%u,%u,%u)",&a0,&a1,&a2,&a3,&p0,&p1) != 6) + { + memset(&PasvAddr,0,sizeof(PasvAddr)); + return true; + } + + // lftp used this horrid byte order manipulation.. Ik. + PasvAddr.sin_family = AF_INET; + unsigned char *a; + unsigned char *p; + a = (unsigned char *)&PasvAddr.sin_addr; + p = (unsigned char *)&PasvAddr.sin_port; + + // Some evil servers return 0 to mean their addr + if (a0 == 0 && a1 == 0 && a2 == 0 && a3 == 0) + { + PasvAddr.sin_addr = Peer.sin_addr; + } + else + { + a[0] = a0; + a[1] = a1; + a[2] = a2; + a[3] = a3; + } + + p[0] = p0; + p[1] = p1; + + return true; +} + /*}}}*/ +// FTPConn::Size - Return the size of a file /*{{{*/ +// --------------------------------------------------------------------- +/* Grab the file size from the server, 0 means no size or empty file */ +bool FTPConn::Size(const char *Path,unsigned long &Size) +{ + // Query the size + unsigned int Tag; + string Msg; + Size = 0; + if (WriteMsg(Tag,Msg,"SIZE %s",Path) == false) + return false; + + char *End; + Size = strtol(Msg.c_str(),&End,10); + if (Tag >= 400 || End == Msg.c_str()) + Size = 0; + return true; +} + /*}}}*/ +// FTPConn::ModTime - Return the modification time of the file /*{{{*/ +// --------------------------------------------------------------------- +/* Like Size no error is returned if the command is not supported. If the + command fails then time is set to the current time of day to fool + date checks. */ +bool FTPConn::ModTime(const char *Path, time_t &Time) +{ + Time = time(&Time); + + // Query the mod time + unsigned int Tag; + string Msg; + if (WriteMsg(Tag,Msg,"MDTM %s",Path) == false) + return false; + if (Tag >= 400 || Msg.empty() == true || isdigit(Msg[0]) == 0) + return true; + + // Parse it + StrToTime(Msg,Time); + return true; +} + /*}}}*/ +// FTPConn::CreateDataFd - Get a data connection /*{{{*/ +// --------------------------------------------------------------------- +/* Create the data connection. Call FinalizeDataFd after this though.. */ +bool FTPConn::CreateDataFd() +{ + close(DataFd); + DataFd = -1; + + // Attempt to enter passive mode. + if (TryPassive == true) + { + if (GoPasv() == false) + return false; + + // Oops, didn't work out, don't bother trying again. + if (PasvAddr.sin_port == 0) + TryPassive = false; + } + + // Passive mode? + if (PasvAddr.sin_port != 0) + { + // Get a socket + if ((DataFd = socket(AF_INET,SOCK_STREAM,0)) < 0) + return _error->Errno("socket","Could not create a socket"); + + // Connect to the server + SetNonBlock(DataFd,true); + if (connect(DataFd,(sockaddr *)&PasvAddr,sizeof(PasvAddr)) < 0 && + errno != EINPROGRESS) + return _error->Errno("socket","Could not create a socket"); + + /* This implements a timeout for connect by opening the connection + nonblocking */ + if (WaitFd(ServerFd,true,TimeOut) == false) + return _error->Error("Could not connect data socket, connection timed out"); + unsigned int Err; + unsigned int Len = sizeof(Err); + if (getsockopt(ServerFd,SOL_SOCKET,SO_ERROR,&Err,&Len) != 0) + return _error->Errno("getsockopt","Failed"); + if (Err != 0) + return _error->Error("Could not connect."); + + return true; + } + + // Port mode :< + close(DataListenFd); + DataListenFd = -1; + + // Get a socket + if ((DataListenFd = socket(AF_INET,SOCK_STREAM,0)) < 0) + return _error->Errno("socket","Could not create a socket"); + + // Bind and listen + sockaddr_in Addr; + memset(&Addr,0,sizeof(Addr)); + if (bind(DataListenFd,(sockaddr *)&Addr,sizeof(Addr)) < 0) + return _error->Errno("bind","Could not bind a socket"); + if (listen(DataListenFd,1) < 0) + return _error->Errno("listen","Could not listen on the socket"); + SetNonBlock(DataListenFd,true); + + // Determine the name to send to the remote + sockaddr_in Addr2; + socklen_t Jnk = sizeof(Addr); + if (getsockname(DataListenFd,(sockaddr *)&Addr,&Jnk) < 0) + return _error->Errno("getsockname","Could not determine the socket's name"); + Jnk = sizeof(Addr2); + if (getsockname(ServerFd,(sockaddr *)&Addr2,&Jnk) < 0) + return _error->Errno("getsockname","Could not determine the socket's name"); + + // This bit ripped from qftp + unsigned long badr = ntohl(*(unsigned long *)&Addr2.sin_addr); + unsigned long bp = ntohs(Addr.sin_port); + + // Send the port command + unsigned int Tag; + string Msg; + if (WriteMsg(Tag,Msg,"PORT %d,%d,%d,%d,%d,%d", + (int) (badr >> 24) & 0xff, (int) (badr >> 16) & 0xff, + (int) (badr >> 8) & 0xff, (int) badr & 0xff, + (int) (bp >> 8) & 0xff, (int) bp & 0xff) == false) + return false; + if (Tag >= 400) + return _error->Error("Unable to send port command"); + + return true; +} + /*}}}*/ +// FTPConn::Finalize - Complete the Data connection /*{{{*/ +// --------------------------------------------------------------------- +/* If the connection is in port mode this waits for the other end to hook + up to us. */ +bool FTPConn::Finalize() +{ + // Passive mode? Do nothing + if (PasvAddr.sin_port != 0) + return true; + + // Close any old socket.. + close(DataFd); + DataFd = -1; + + // Wait for someone to connect.. + if (WaitFd(DataListenFd,false,TimeOut) == false) + return _error->Error("Data socket connect timed out"); + + // Accept the connection + struct sockaddr_in Addr; + socklen_t Len = sizeof(Addr); + DataFd = accept(DataListenFd,(struct sockaddr *)&Addr,&Len); + if (DataFd < 0) + return _error->Errno("accept","Unable to accept connection"); + + close(DataListenFd); + DataListenFd = -1; + + return true; +} + /*}}}*/ +// FTPConn::Get - Get a file /*{{{*/ +// --------------------------------------------------------------------- +/* This opens a data connection, sends REST and RETR and then + transfers the file over. */ +bool FTPConn::Get(const char *Path,FileFd &To,unsigned long Resume, + MD5Summation &MD5,bool &Missing) +{ + Missing = false; + if (CreateDataFd() == false) + return false; + + unsigned int Tag; + string Msg; + if (Resume != 0) + { + if (WriteMsg(Tag,Msg,"REST %u",Resume) == false) + return false; + if (Tag >= 400) + Resume = 0; + } + + if (To.Truncate(Resume) == false) + return false; + + if (To.Seek(0) == false) + return false; + + if (Resume != 0) + { + if (MD5.AddFD(To.Fd(),Resume) == false) + { + _error->Errno("read","Problem hashing file"); + return false; + } + } + + // Send the get command + if (WriteMsg(Tag,Msg,"RETR %s",Path) == false) + return false; + + if (Tag >= 400) + { + if (Tag == 550) + Missing = true; + return _error->Error("Unable to fetch file, server said '%s'",Msg.c_str()); + } + + // Finish off the data connection + if (Finalize() == false) + return false; + + // Copy loop + unsigned char Buffer[4096]; + while (1) + { + // Wait for some data.. + if (WaitFd(DataFd,false,TimeOut) == false) + { + Close(); + return _error->Error("Data socket timed out"); + } + + // Read the data.. + int Res = read(DataFd,Buffer,sizeof(Buffer)); + if (Res == 0) + break; + if (Res < 0) + { + if (errno == EAGAIN) + continue; + break; + } + + MD5.Add(Buffer,Res); + if (To.Write(Buffer,Res) == false) + { + Close(); + return false; + } + } + + // All done + close(DataFd); + DataFd = -1; + + // Read the closing message from the server + if (ReadResp(Tag,Msg) == false) + return false; + if (Tag >= 400) + return _error->Error("Data transfer failed, server said '%s'",Msg.c_str()); + return true; +} + /*}}}*/ + +// FtpMethod::FtpMethod - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +FtpMethod::FtpMethod() : pkgAcqMethod("1.0",SendConfig) +{ + signal(SIGTERM,SigTerm); + signal(SIGINT,SigTerm); + + Server = 0; + FailFd = -1; +} + /*}}}*/ +// FtpMethod::SigTerm - Handle a fatal signal /*{{{*/ +// --------------------------------------------------------------------- +/* This closes and timestamps the open file. This is neccessary to get + resume behavoir on user abort */ +void FtpMethod::SigTerm(int) +{ + if (FailFd == -1) + _exit(100); + close(FailFd); + + // Timestamp + struct utimbuf UBuf; + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(FailFile.c_str(),&UBuf); + + _exit(100); +} + /*}}}*/ +// FtpMethod::Configuration - Handle a configuration message /*{{{*/ +// --------------------------------------------------------------------- +/* We stash the desired pipeline depth */ +bool FtpMethod::Configuration(string Message) +{ + if (pkgAcqMethod::Configuration(Message) == false) + return false; + + TimeOut = _config->FindI("Acquire::Ftp::Timeout",TimeOut); + return true; +} + /*}}}*/ +// FtpMethod::Fetch - Fetch a file /*{{{*/ +// --------------------------------------------------------------------- +/* Fetch a single file, called by the base class.. */ +bool FtpMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + const char *File = Get.Path.c_str(); + FetchResult Res; + Res.Filename = Itm->DestFile; + Res.IMSHit = false; + + // Connect to the server + if (Server == 0 || Server->Comp(Get) == false) + { + delete Server; + Server = new FTPConn(Get); + } + + // Could not connect is a transient error.. + if (Server->Open(this) == false) + { + Server->Close(); + Fail(true); + return true; + } + + // Get the files information + Status("Query"); + unsigned long Size; + if (Server->Size(File,Size) == false || + Server->ModTime(File,FailTime) == false) + { + Fail(true); + return true; + } + Res.Size = Size; + + // See if it is an IMS hit + if (Itm->LastModified == FailTime) + { + Res.Size = 0; + Res.IMSHit = true; + URIDone(Res); + return true; + } + + // See if the file exists + struct stat Buf; + if (stat(Itm->DestFile.c_str(),&Buf) == 0) + { + if (Size == (unsigned)Buf.st_size && FailTime == Buf.st_mtime) + { + Res.Size = Buf.st_size; + Res.LastModified = Buf.st_mtime; + Res.ResumePoint = Buf.st_size; + URIDone(Res); + return true; + } + + // Resume? + if (FailTime == Buf.st_mtime && Size > (unsigned)Buf.st_size) + Res.ResumePoint = Buf.st_size; + } + + // Open the file + MD5Summation MD5; + { + FileFd Fd(Itm->DestFile,FileFd::WriteAny); + if (_error->PendingError() == true) + return false; + + URIStart(Res); + + FailFile = Itm->DestFile; + FailFile.c_str(); // Make sure we dont do a malloc in the signal handler + FailFd = Fd.Fd(); + + bool Missing; + if (Server->Get(File,Fd,Res.ResumePoint,MD5,Missing) == false) + { + Fd.Close(); + + // Timestamp + struct utimbuf UBuf; + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(FailFile.c_str(),&UBuf); + + // If the file is missing we hard fail otherwise transient fail + if (Missing == true) + return false; + Fail(true); + return true; + } + + Res.Size = Fd.Size(); + } + + Res.LastModified = FailTime; + Res.MD5Sum = MD5.Result(); + + // Timestamp + struct utimbuf UBuf; + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(Queue->DestFile.c_str(),&UBuf); + FailFd = -1; + + URIDone(Res); + + return true; +} + /*}}}*/ + +int main(int argc,const char *argv[]) +{ + /* See if we should become the http client - we do this for http + proxy urls */ + if (getenv("ftp_proxy") != 0) + { + URI Proxy = string(getenv("ftp_proxy")); + + if (Proxy.Access == "http") + { + // Copy over the environment setting + char S[300]; + snprintf(S,sizeof(S),"http_proxy=%s",getenv("ftp_proxy")); + putenv(S); + + // Run the http method + string Path = flNotFile(argv[0]) + "/http"; + execl(Path.c_str(),Path.c_str(),0); + cerr << "Unable to invoke " << Path << endl; + exit(100); + } + } + + FtpMethod Mth; + + return Mth.Run(); +} diff --git a/apt/methods/ftp.h b/apt/methods/ftp.h new file mode 100644 index 0000000..38783a9 --- /dev/null +++ b/apt/methods/ftp.h @@ -0,0 +1,72 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/// $Id: ftp.h,v 1.1.1.1 2000/08/10 12:42:38 kojima Exp $ +/* ###################################################################### + + FTP Aquire Method - This is the FTP aquire method for APT. + + ##################################################################### */ + /*}}}*/ +#ifndef APT_FTP_H +#define APT_FTP_H + +class FTPConn +{ + char Buffer[1024*10]; + unsigned long Len; + int ServerFd; + int DataFd; + int DataListenFd; + URI ServerName; + bool TryPassive; + bool Debug; + + struct sockaddr_in PasvAddr; + struct sockaddr_in Peer; + + // Private helper functions + bool ReadLine(string &Text); + bool Login(); + bool CreateDataFd(); + bool Finalize(); + + public: + + bool Comp(URI Other) {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; + + // Raw connection IO + bool ReadResp(unsigned int &Ret,string &Text); + bool WriteMsg(unsigned int &Ret,string &Text,const char *Fmt,...); + + // Connection control + bool Open(pkgAcqMethod *Owner); + void Close(); + bool GoPasv(); + + // Query + bool Size(const char *Path,unsigned long &Size); + bool ModTime(const char *Path, time_t &Time); + bool Get(const char *Path,FileFd &To,unsigned long Resume, + MD5Summation &MD5,bool &Missing); + + FTPConn(URI Srv); + ~FTPConn(); +}; + +class FtpMethod : public pkgAcqMethod +{ + virtual bool Fetch(FetchItem *Itm); + virtual bool Configuration(string Message); + + FTPConn *Server; + + static string FailFile; + static int FailFd; + static time_t FailTime; + static void SigTerm(int); + + public: + + FtpMethod(); +}; + +#endif diff --git a/apt/methods/gpg.cc b/apt/methods/gpg.cc new file mode 100644 index 0000000..532bfb5 --- /dev/null +++ b/apt/methods/gpg.cc @@ -0,0 +1,171 @@ + +#include +#include +#include + +#include +#include +#include +#include +#include + + +class GPGMethod : public pkgAcqMethod +{ + virtual bool Fetch(FetchItem *Itm); + + public: + + GPGMethod() : pkgAcqMethod("1.0",SingleInstance | SendConfig) {}; +}; + + + +static char *getFileSigner(const char *file, const char *outfile, + string &signerKeyID, bool useDefaultPubring) +{ + pid_t pid; + int fd[2]; + char buffer[1024]; + FILE *f; + char keyid[64]; + int status; + bool goodsig = false; + + if (pipe(fd) < 0) { + return "could not create pipe"; + } + + pid = fork(); + if (pid < 0) { + return "could not spawn new process"; + } else if (pid == 0) { + string path = _config->Find("Dir::Bin::gpg"); +// New option to provide more flexible way to specify +// public ring to check signatures + string pubringpath = _config->Find("Apt::GPG::PubringPath"); + + close(fd[0]); + close(STDERR_FILENO); + close(STDOUT_FILENO); + dup2(fd[1], STDOUT_FILENO); + dup2(fd[1], STDERR_FILENO); + + putenv("LANG="); + putenv("LC_ALL="); + putenv("LC_MESSAGES="); + + if((pubringpath.length() > 0) && useDefaultPubring) { + execlp(path.c_str(), "gpg", "--batch", "--no-secmem-warning", "--homedir", + pubringpath.c_str(), "--status-fd", "2", "-o", outfile, file, NULL); + } else { + execlp(path.c_str(), "gpg", "--batch", "--no-secmem-warning", + "--status-fd", "2", "-o", outfile, file, NULL); + } + + exit(111); + } + close(fd[1]); + keyid[0] = 0; + goodsig = false; + + f = fdopen(fd[0], "r"); + + while (1) { + char *ptr, *ptr1; + + if (!fgets(buffer, 1024, f)) + break; + + if (goodsig && keyid[0]) { + continue; + } + +// Use strstr because response likely to be further than buffer start +#define SIGPACK "[GNUPG:] VALIDSIG" + if ((ptr1 = strstr(buffer, SIGPACK)) != NULL) { + char *sig; + ptr = sig = ptr1 + sizeof(SIGPACK); + while (isxdigit(*ptr)) ptr++; + *ptr = 0; + strcpy(keyid, sig); + } +#undef SIGPACK + +#define GOODSIG "[GNUPG:] GOODSIG" + if ((ptr1 = strstr(buffer, GOODSIG)) != NULL) { + goodsig = true; + } +#undef GOODSIG + } + fclose(f); + + waitpid(pid, &status, 0); + + if (WEXITSTATUS(status) == 0) { + signerKeyID = string(keyid); + return NULL; + } else if (WEXITSTATUS(status) == 111) { + return "could not execute gpg to verify signature"; + } else { + if (!goodsig || !keyid[0]) + return "file was not signed with a known key. Check if the proper gpg key was imported to your keyring."; + + return "file could not be authenticated"; + } +} + + +bool GPGMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + string Path = Get.Host + Get.Path; // To account for relative paths + string keyID; + + FetchResult Res; + Res.Filename = Itm->DestFile; + URIStart(Res); + + // Run GPG on file, extract contents and get the key ID of the signer + // First use default public ring provided by packaging engine (IPL feature) + char *msg = getFileSigner(Path.c_str(), Itm->DestFile.c_str(), keyID, true); + if (msg) { + // Run GPG on file, extract contents and get the key ID of the signer + // Now use user's public ring + char *msg1 = getFileSigner(Path.c_str(), Itm->DestFile.c_str(), keyID, false); + if (msg1) { + return _error->Error(msg1); + } + } + + + // Transfer the modification times + struct stat Buf; + if (stat(Path.c_str(),&Buf) != 0) + return _error->Errno("stat","Failed to stat ", Path.c_str()); + + struct utimbuf TimeBuf; + TimeBuf.actime = Buf.st_atime; + TimeBuf.modtime = Buf.st_mtime; + if (utime(Itm->DestFile.c_str(),&TimeBuf) != 0) + return _error->Errno("utime","Failed to set modification time"); + + if (stat(Itm->DestFile.c_str(),&Buf) != 0) + return _error->Errno("stat","Failed to stat"); + + // Return a Done response + Res.LastModified = Buf.st_mtime; + Res.Size = Buf.st_size; + Res.SignatureKeyID = keyID; + URIDone(Res); + + return true; +} + + +int main() +{ + GPGMethod Mth; + + return Mth.Run(); +} diff --git a/apt/methods/gzip.cc b/apt/methods/gzip.cc new file mode 100644 index 0000000..c480fac --- /dev/null +++ b/apt/methods/gzip.cc @@ -0,0 +1,155 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: gzip.cc,v 1.2 2001/03/22 12:01:47 kojima Exp $ +/* ###################################################################### + + GZip method - Take a file URI in and decompress it into the target + file. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include + /*}}}*/ + +class GzipMethod : public pkgAcqMethod +{ + virtual bool Fetch(FetchItem *Itm); + + public: + + GzipMethod() : pkgAcqMethod("1.0",SingleInstance | SendConfig) {}; +}; + + +// GzipMethod::Fetch - Decompress the passed URI /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool GzipMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + string Path = Get.Host + Get.Path; // To account for relative paths + + FetchResult Res; + Res.Filename = Itm->DestFile; + URIStart(Res); + + // Open the source and destination files + FileFd From(Path,FileFd::ReadOnly); + FileFd To(Itm->DestFile,FileFd::WriteEmpty); + To.EraseOnFailure(); + if (_error->PendingError() == true) + return false; + + int GzOut[2]; + + if (pipe(GzOut) < 0) + return _error->Errno("fork","Couldn't open pipe for gzip"); + + + // Fork gzip + int Process = fork(); + if (Process < 0) + return _error->Errno("fork","Couldn't fork gzip"); + + // The child + if (Process == 0) + { + dup2(From.Fd(),STDIN_FILENO); + dup2(GzOut[1],STDOUT_FILENO); + From.Close(); + close(GzOut[1]); + SetCloseExec(STDIN_FILENO,false); + SetCloseExec(STDOUT_FILENO,false); + + const char *Args[3]; + Args[0] = _config->Find("Dir::bin::gzip","gzip").c_str(); + Args[1] = "-d"; + Args[2] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + From.Close(); + close(GzOut[1]); + + MD5Summation MD5; + + bool Failed = false; + + // Read data from gzip, generate checksums and write + while (1) + { + unsigned char Buffer[4*1024]; + unsigned long Count; + + Count = read(GzOut[0],Buffer,4*1024); + if (Count < 0 && errno == EINTR) + continue; + + if (Count < 0) + { + _error->Errno("read", "Read error from gzip process"); + Failed = true; + break; + } + + if (Count == 0) + break; + + MD5.Add(Buffer,Count); + + To.Write(Buffer,Count); + } + + // Wait for gzip to finish + if (ExecWait(Process,_config->Find("Dir::bin::gzip","gzip").c_str(),false) == false) + { + To.OpFail(); + return false; + } + + To.Close(); + + if (Failed == true) + return false; + + // Transfer the modification times + struct stat Buf; + if (stat(Path.c_str(),&Buf) != 0) + return _error->Errno("stat","Failed to stat"); + + struct utimbuf TimeBuf; + TimeBuf.actime = Buf.st_atime; + TimeBuf.modtime = Buf.st_mtime; + if (utime(Itm->DestFile.c_str(),&TimeBuf) != 0) + return _error->Errno("utime","Failed to set modification time"); + + if (stat(Itm->DestFile.c_str(),&Buf) != 0) + return _error->Errno("stat","Failed to stat"); + + // Return a Done response + Res.LastModified = Buf.st_mtime; + Res.Size = Buf.st_size; + Res.MD5Sum = MD5.Result(); + + URIDone(Res); + + return true; +} + /*}}}*/ + +int main() +{ + GzipMethod Mth; + return Mth.Run(); +} diff --git a/apt/methods/http.cc b/apt/methods/http.cc new file mode 100644 index 0000000..da95669 --- /dev/null +++ b/apt/methods/http.cc @@ -0,0 +1,1149 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: http.cc,v 1.3 2001/02/20 18:20:02 kojima Exp $ +/* ###################################################################### + + HTTP Aquire Method - This is the HTTP aquire method for APT. + + It uses HTTP/1.1 and many of the fancy options there-in, such as + pipelining, range, if-range and so on. It accepts on the command line + a list of url destination pairs and writes to stdout the status of the + operation as defined in the APT method spec. + + It is based on a doubly buffered select loop. All the requests are + fed into a single output buffer that is constantly fed out the + socket. This provides ideal pipelining as in many cases all of the + requests will fit into a single packet. The input socket is buffered + the same way and fed into the fd for the file. + + This double buffering provides fairly substantial transfer rates, + compared to wget the http method is about 4% faster. Most importantly, + when HTTP is compared with FTP as a protocol the speed difference is + huge. In tests over the internet from two sites to llug (via ATM) this + program got 230k/s sustained http transfer rates. FTP on the other + hand topped out at 170k/s. That combined with the time to setup the + FTP connection makes HTTP a vastly superior protocol. + + ##################################################################### */ + /*}}}*/ +// Include Files /*{{{*/ +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +// Internet stuff +#include + +#include "connect.h" +#include "rfc2553emu.h" +#include "http.h" + + /*}}}*/ + +string HttpMethod::FailFile; +int HttpMethod::FailFd = -1; +time_t HttpMethod::FailTime = 0; +unsigned long PipelineDepth = 10; +unsigned long TimeOut = 120; +bool Debug = false; + +// CircleBuf::CircleBuf - Circular input buffer /*{{{*/ +// --------------------------------------------------------------------- +/* */ +CircleBuf::CircleBuf(unsigned long Size) : Size(Size), MD5(0) +{ + Buf = new unsigned char[Size]; + Reset(); +} + /*}}}*/ +// CircleBuf::Reset - Reset to the default state /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void CircleBuf::Reset() +{ + InP = 0; + OutP = 0; + StrPos = 0; + MaxGet = (unsigned int)-1; + OutQueue = string(); + if (MD5 != 0) + { + delete MD5; + MD5 = new MD5Summation; + } +}; + /*}}}*/ +// CircleBuf::Read - Read from a FD into the circular buffer /*{{{*/ +// --------------------------------------------------------------------- +/* This fills up the buffer with as much data as is in the FD, assuming it + is non-blocking.. */ +bool CircleBuf::Read(int Fd) +{ + while (1) + { + // Woops, buffer is full + if (InP - OutP == Size) + return true; + + // Write the buffer segment + int Res; + Res = read(Fd,Buf + (InP%Size),LeftRead()); + + if (Res == 0) + return false; + if (Res < 0) + { + if (errno == EAGAIN) + return true; + return false; + } + + if (InP == 0) + gettimeofday(&Start,0); + InP += Res; + } +} + /*}}}*/ +// CircleBuf::Read - Put the string into the buffer /*{{{*/ +// --------------------------------------------------------------------- +/* This will hold the string in and fill the buffer with it as it empties */ +bool CircleBuf::Read(string Data) +{ + OutQueue += Data; + FillOut(); + return true; +} + /*}}}*/ +// CircleBuf::FillOut - Fill the buffer from the output queue /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void CircleBuf::FillOut() +{ + if (OutQueue.empty() == true) + return; + while (1) + { + // Woops, buffer is full + if (InP - OutP == Size) + return; + + // Write the buffer segment + unsigned long Sz = LeftRead(); + if (OutQueue.length() - StrPos < Sz) + Sz = OutQueue.length() - StrPos; + memcpy(Buf + (InP%Size),OutQueue.begin() + StrPos,Sz); + + // Advance + StrPos += Sz; + InP += Sz; + if (OutQueue.length() == StrPos) + { + StrPos = 0; + OutQueue = ""; + return; + } + } +} + /*}}}*/ +// CircleBuf::Write - Write from the buffer into a FD /*{{{*/ +// --------------------------------------------------------------------- +/* This empties the buffer into the FD. */ +bool CircleBuf::Write(int Fd) +{ + while (1) + { + FillOut(); + + // Woops, buffer is empty + if (OutP == InP) + return true; + + if (OutP == MaxGet) + return true; + + // Write the buffer segment + int Res; + Res = write(Fd,Buf + (OutP%Size),LeftWrite()); + + if (Res == 0) + return false; + if (Res < 0) + { + if (errno == EAGAIN) + return true; + + return false; + } + + if (MD5 != 0) + MD5->Add(Buf + (OutP%Size),Res); + + OutP += Res; + } +} + /*}}}*/ +// CircleBuf::WriteTillEl - Write from the buffer to a string /*{{{*/ +// --------------------------------------------------------------------- +/* This copies till the first empty line */ +bool CircleBuf::WriteTillEl(string &Data,bool Single) +{ + // We cheat and assume it is unneeded to have more than one buffer load + for (unsigned long I = OutP; I < InP; I++) + { + if (Buf[I%Size] != '\n') + continue; + for (I++; I < InP && Buf[I%Size] == '\r'; I++); + + if (Single == false) + { + if (Buf[I%Size] != '\n') + continue; + for (I++; I < InP && Buf[I%Size] == '\r'; I++); + } + + if (I > InP) + I = InP; + + Data = ""; + while (OutP < I) + { + unsigned long Sz = LeftWrite(); + if (Sz == 0) + return false; + if (I - OutP < LeftWrite()) + Sz = I - OutP; + Data += string((char *)(Buf + (OutP%Size)),Sz); + OutP += Sz; + } + return true; + } + return false; +} + /*}}}*/ +// CircleBuf::Stats - Print out stats information /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void CircleBuf::Stats() +{ + if (InP == 0) + return; + + struct timeval Stop; + gettimeofday(&Stop,0); +/* float Diff = Stop.tv_sec - Start.tv_sec + + (float)(Stop.tv_usec - Start.tv_usec)/1000000; + clog << "Got " << InP << " in " << Diff << " at " << InP/Diff << endl;*/ +} + /*}}}*/ + +// ServerState::ServerState - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +ServerState::ServerState(URI Srv,HttpMethod *Owner) : Owner(Owner), + In(64*1024), Out(4*1024), + ServerName(Srv) +{ + Reset(); +} + /*}}}*/ +// ServerState::Open - Open a connection to the server /*{{{*/ +// --------------------------------------------------------------------- +/* This opens a connection to the server. */ +string LastHost; +int LastPort = 0; +struct addrinfo *LastHostAddr = 0; +bool ServerState::Open() +{ + // Use the already open connection if possible. + if (ServerFd != -1) + return true; + + Close(); + In.Reset(); + Out.Reset(); + + // Determine the proxy setting + if (getenv("http_proxy") == 0) + { + string DefProxy = _config->Find("Acquire::http::Proxy"); + string SpecificProxy = _config->Find("Acquire::http::Proxy::" + ServerName.Host); + if (SpecificProxy.empty() == false) + { + if (SpecificProxy == "DIRECT") + Proxy = ""; + else + Proxy = SpecificProxy; + } + else + Proxy = DefProxy; + } + else + Proxy = getenv("http_proxy"); + + // Parse no_proxy, a , seperated list of domains + if (getenv("no_proxy") != 0) + { + const char *Start = getenv("no_proxy"); + const char *ServerEnd = ServerName.Host.end(); + + for (const char *Cur = Start; true ; Cur++) + { + if (*Cur != ',' && *Cur != 0) + continue; + + // match end of the string + if ((ServerName.Host.size() >= (Cur - Start)) + && stringcasecmp(ServerEnd - (Cur - Start), + ServerEnd,Start,Cur) == 0) + { + Proxy = ""; + break; + } + + Start = Cur + 1; + if (*Cur == 0) + break; + } + } + + // Determine what host and port to use based on the proxy settings + int Port = 0; + string Host; + if (Proxy.empty() == true || Proxy.Host.empty() == true) + { + if (ServerName.Port != 0) + Port = ServerName.Port; + Host = ServerName.Host; + } + else + { + if (Proxy.Port != 0) + Port = Proxy.Port; + Host = Proxy.Host; + } + + // Connect to the remote server + if (Connect(Host,Port,"http",80,ServerFd,TimeOut,Owner) == false) + return false; + + return true; +} + /*}}}*/ +// ServerState::Close - Close a connection to the server /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ServerState::Close() +{ + close(ServerFd); + ServerFd = -1; + return true; +} + /*}}}*/ +// ServerState::RunHeaders - Get the headers before the data /*{{{*/ +// --------------------------------------------------------------------- +/* Returns 0 if things are OK, 1 if an IO error occursed and 2 if a header + parse error occured */ +int ServerState::RunHeaders() +{ + State = Header; + + Owner->Status("Waiting for file"); + + Major = 0; + Minor = 0; + Result = 0; + Size = 0; + StartPos = 0; + Encoding = Closes; + HaveContent = false; + time(&Date); + + do + { + string Data; + if (In.WriteTillEl(Data) == false) + continue; + + if (Debug == true) + clog << Data; + + for (string::const_iterator I = Data.begin(); I < Data.end(); I++) + { + string::const_iterator J = I; + for (; J != Data.end() && *J != '\n' && *J != '\r';J++); + if (HeaderLine(string(I,J-I)) == false) + return 2; + I = J; + } + return 0; + } + while (Owner->Go(false,this) == true); + + return 1; +} + /*}}}*/ +// ServerState::RunData - Transfer the data from the socket /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ServerState::RunData() +{ + State = Data; + + // Chunked transfer encoding is fun.. + if (Encoding == Chunked) + { + while (1) + { + // Grab the block size + bool Last = true; + string Data; + In.Limit(-1); + do + { + if (In.WriteTillEl(Data,true) == true) + break; + } + while ((Last = Owner->Go(false,this)) == true); + + if (Last == false) + return false; + + // See if we are done + unsigned long Len = strtol(Data.c_str(),0,16); + if (Len == 0) + { + In.Limit(-1); + + // We have to remove the entity trailer + Last = true; + do + { + if (In.WriteTillEl(Data,true) == true && Data.length() <= 2) + break; + } + while ((Last = Owner->Go(false,this)) == true); + if (Last == false) + return false; + return !_error->PendingError(); + } + + // Transfer the block + In.Limit(Len); + while (Owner->Go(true,this) == true) + if (In.IsLimit() == true) + break; + + // Error + if (In.IsLimit() == false) + return false; + + // The server sends an extra new line before the next block specifier.. + In.Limit(-1); + Last = true; + do + { + if (In.WriteTillEl(Data,true) == true) + break; + } + while ((Last = Owner->Go(false,this)) == true); + if (Last == false) + return false; + } + } + else + { + /* Closes encoding is used when the server did not specify a size, the + loss of the connection means we are done */ + if (Encoding == Closes) + In.Limit(-1); + else + In.Limit(Size - StartPos); + + // Just transfer the whole block. + do + { + if (In.IsLimit() == false) + continue; + + In.Limit(-1); + return !_error->PendingError(); + } + while (Owner->Go(true,this) == true); + } + + return Owner->Flush(this) && !_error->PendingError(); +} + /*}}}*/ +// ServerState::HeaderLine - Process a header line /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool ServerState::HeaderLine(string Line) +{ + if (Line.empty() == true) + return true; + + // The http server might be trying to do something evil. + if (Line.length() >= MAXLEN) + return _error->Error("Got a single header line over %u chars",MAXLEN); + + string::size_type Pos = Line.find(' '); + if (Pos == string::npos || Pos+1 > Line.length()) + { + // Blah, some servers use "connection:closes", evil. + Pos = Line.find(':'); + if (Pos == string::npos || Pos + 2 > Line.length()) + return _error->Error("Bad header line"); + Pos++; + } + + // Parse off any trailing spaces between the : and the next word. + string::size_type Pos2 = Pos; + while (Pos2 < Line.length() && isspace(Line[Pos2]) != 0) + Pos2++; + + string Tag = string(Line,0,Pos); + string Val = string(Line,Pos2); + + if (stringcasecmp(Tag.begin(),Tag.begin()+4,"HTTP") == 0) + { + // Evil servers return no version + if (Line[4] == '/') + { + if (sscanf(Line.c_str(),"HTTP/%u.%u %u %[^\n]",&Major,&Minor, + &Result,Code) != 4) + return _error->Error("The http server sent an invalid reply header"); + } + else + { + Major = 0; + Minor = 9; + if (sscanf(Line.c_str(),"HTTP %u %[^\n]",&Result,Code) != 2) + return _error->Error("The http server sent an invalid reply header"); + } + + return true; + } + + if (stringcasecmp(Tag,"Content-Length:") == 0) + { + if (Encoding == Closes) + Encoding = Stream; + HaveContent = true; + + // The length is already set from the Content-Range header + if (StartPos != 0) + return true; + + if (sscanf(Val.c_str(),"%lu",&Size) != 1) + return _error->Error("The http server sent an invalid Content-Length header"); + return true; + } + + if (stringcasecmp(Tag,"Content-Type:") == 0) + { + HaveContent = true; + return true; + } + + if (stringcasecmp(Tag,"Content-Range:") == 0) + { + HaveContent = true; + + if (sscanf(Val.c_str(),"bytes %lu-%*u/%lu",&StartPos,&Size) != 2) + return _error->Error("The http server sent an invalid Content-Range header"); + if ((unsigned)StartPos > Size) + return _error->Error("This http server has broken range support"); + return true; + } + + if (stringcasecmp(Tag,"Transfer-Encoding:") == 0) + { + HaveContent = true; + if (stringcasecmp(Val,"chunked") == 0) + Encoding = Chunked; + + return true; + } + + if (stringcasecmp(Tag,"Last-Modified:") == 0) + { + if (StrToTime(Val,Date) == false) + return _error->Error("Unknown date format"); + return true; + } + + return true; +} + /*}}}*/ + +// HttpMethod::SendReq - Send the HTTP request /*{{{*/ +// --------------------------------------------------------------------- +/* This places the http request in the outbound buffer */ +void HttpMethod::SendReq(FetchItem *Itm,CircleBuf &Out) +{ + URI Uri = Itm->Uri; + + // The HTTP server expects a hostname with a trailing :port + char Buf[1000]; + string ProperHost = Uri.Host; + if (Uri.Port != 0) + { + sprintf(Buf,":%u",Uri.Port); + ProperHost += Buf; + } + + // Just in case. + if (Itm->Uri.length() >= sizeof(Buf)) + abort(); + + /* Build the request. We include a keep-alive header only for non-proxy + requests. This is to tweak old http/1.0 servers that do support keep-alive + but not HTTP/1.1 automatic keep-alive. Doing this with a proxy server + will glitch HTTP/1.0 proxies because they do not filter it out and + pass it on, HTTP/1.1 says the connection should default to keep alive + and we expect the proxy to do this */ + if (Proxy.empty() == true) + sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\nConnection: keep-alive\r\n", + QuoteString(Uri.Path,"~").c_str(),ProperHost.c_str()); + else + { + /* Generate a cache control header if necessary. We place a max + cache age on index files, optionally set a no-cache directive + and a no-store directive for archives. */ + sprintf(Buf,"GET %s HTTP/1.1\r\nHost: %s\r\n", + Itm->Uri.c_str(),ProperHost.c_str()); + if (_config->FindB("Acquire::http::No-Cache",false) == true) + strcat(Buf,"Cache-Control: no-cache\r\nPragma: no-cache\r\n"); + else + { + if (Itm->IndexFile == true) + sprintf(Buf+strlen(Buf),"Cache-Control: max-age=%u\r\n", + _config->FindI("Acquire::http::Max-Age",60*60*24)); + else + { + if (_config->FindB("Acquire::http::No-Store",false) == true) + strcat(Buf,"Cache-Control: no-store\r\n"); + } + } + } + + string Req = Buf; + + // Check for a partial file + struct stat SBuf; + if (stat(Itm->DestFile.c_str(),&SBuf) >= 0 && SBuf.st_size > 0) + { + // In this case we send an if-range query with a range header + sprintf(Buf,"Range: bytes=%li-\r\nIf-Range: %s\r\n",(long)SBuf.st_size - 1, + TimeRFC1123(SBuf.st_mtime).c_str()); + Req += Buf; + } + else + { + if (Itm->LastModified != 0) + { + sprintf(Buf,"If-Modified-Since: %s\r\n",TimeRFC1123(Itm->LastModified).c_str()); + Req += Buf; + } + } + + if (Proxy.User.empty() == false || Proxy.Password.empty() == false) + Req += string("Proxy-Authorization: Basic ") + + Base64Encode(Proxy.User + ":" + Proxy.Password) + "\r\n"; + + if (0)//akk + Req += "User-Agent: Debian APT-HTTP/1.2\r\n\r\n"; + else + Req += "User-Agent: Conectiva APT-HTTP/1.2\r\n\r\n"; + + if (Debug == true) + cerr << Req << endl; + + Out.Read(Req); +} + /*}}}*/ +// HttpMethod::Go - Run a single loop /*{{{*/ +// --------------------------------------------------------------------- +/* This runs the select loop over the server FDs, Output file FDs and + stdin. */ +bool HttpMethod::Go(bool ToFile,ServerState *Srv) +{ + // Server has closed the connection + if (Srv->ServerFd == -1 && (Srv->In.WriteSpace() == false || + ToFile == false)) + return false; + + fd_set rfds,wfds; + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + // Add the server + if (Srv->Out.WriteSpace() == true && Srv->ServerFd != -1) + FD_SET(Srv->ServerFd,&wfds); + if (Srv->In.ReadSpace() == true && Srv->ServerFd != -1) + FD_SET(Srv->ServerFd,&rfds); + + // Add the file + int FileFD = -1; + if (File != 0) + FileFD = File->Fd(); + + if (Srv->In.WriteSpace() == true && ToFile == true && FileFD != -1) + FD_SET(FileFD,&wfds); + + // Add stdin + FD_SET(STDIN_FILENO,&rfds); + + // Figure out the max fd + int MaxFd = FileFD; + if (MaxFd < Srv->ServerFd) + MaxFd = Srv->ServerFd; + + // Select + struct timeval tv; + tv.tv_sec = TimeOut; + tv.tv_usec = 0; + int Res = 0; + if ((Res = select(MaxFd+1,&rfds,&wfds,0,&tv)) < 0) + return _error->Errno("select","Select failed"); + + if (Res == 0) + { + _error->Error("Connection timed out"); + return ServerDie(Srv); + } + + // Handle server IO + if (Srv->ServerFd != -1 && FD_ISSET(Srv->ServerFd,&rfds)) + { + errno = 0; + if (Srv->In.Read(Srv->ServerFd) == false) + return ServerDie(Srv); + } + + if (Srv->ServerFd != -1 && FD_ISSET(Srv->ServerFd,&wfds)) + { + errno = 0; + if (Srv->Out.Write(Srv->ServerFd) == false) + return ServerDie(Srv); + } + + // Send data to the file + if (FileFD != -1 && FD_ISSET(FileFD,&wfds)) + { + if (Srv->In.Write(FileFD) == false) + return _error->Errno("write","Error writing to output file"); + } + + // Handle commands from APT + if (FD_ISSET(STDIN_FILENO,&rfds)) + { + if (Run(true) != -1) + exit(100); + } + + return true; +} + /*}}}*/ +// HttpMethod::Flush - Dump the buffer into the file /*{{{*/ +// --------------------------------------------------------------------- +/* This takes the current input buffer from the Server FD and writes it + into the file */ +bool HttpMethod::Flush(ServerState *Srv) +{ + if (File != 0) + { + SetNonBlock(File->Fd(),false); + if (Srv->In.WriteSpace() == false) + return true; + + while (Srv->In.WriteSpace() == true) + { + if (Srv->In.Write(File->Fd()) == false) + return _error->Errno("write","Error writing to file"); + if (Srv->In.IsLimit() == true) + return true; + } + + if (Srv->In.IsLimit() == true || Srv->Encoding == ServerState::Closes) + return true; + } + return false; +} + /*}}}*/ +// HttpMethod::ServerDie - The server has closed the connection. /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool HttpMethod::ServerDie(ServerState *Srv) +{ + unsigned int LErrno = errno; + + // Dump the buffer to the file + if (Srv->State == ServerState::Data) + { + SetNonBlock(File->Fd(),false); + while (Srv->In.WriteSpace() == true) + { + if (Srv->In.Write(File->Fd()) == false) + return _error->Errno("write","Error writing to the file"); + + // Done + if (Srv->In.IsLimit() == true) + return true; + } + } + + // See if this is because the server finished the data stream + if (Srv->In.IsLimit() == false && Srv->State != ServerState::Header && + Srv->Encoding != ServerState::Closes) + { + Srv->Close(); + if (LErrno == 0) + return _error->Error("Error reading from server Remote end closed connection"); + errno = LErrno; + return _error->Errno("read","Error reading from server"); + } + else + { + Srv->In.Limit(-1); + + // Nothing left in the buffer + if (Srv->In.WriteSpace() == false) + return false; + + // We may have got multiple responses back in one packet.. + Srv->Close(); + return true; + } + + return false; +} + /*}}}*/ +// HttpMethod::DealWithHeaders - Handle the retrieved header data /*{{{*/ +// --------------------------------------------------------------------- +/* We look at the header data we got back from the server and decide what + to do. Returns + 0 - File is open, + 1 - IMS hit + 3 - Unrecoverable error + 4 - Error with error content page + 5 - Unrecoverable non-server error (close the connection) */ +int HttpMethod::DealWithHeaders(FetchResult &Res,ServerState *Srv) +{ + // Not Modified + if (Srv->Result == 304) + { + unlink(Queue->DestFile.c_str()); + Res.IMSHit = true; + Res.LastModified = Queue->LastModified; + return 1; + } + + /* We have a reply we dont handle. This should indicate a perm server + failure */ + if (Srv->Result < 200 || Srv->Result >= 300) + { + _error->Error("%u %s",Srv->Result,Srv->Code); + if (Srv->HaveContent == true) + return 4; + return 3; + } + + // This is some sort of 2xx 'data follows' reply + Res.LastModified = Srv->Date; + Res.Size = Srv->Size; + + // Open the file + delete File; + File = new FileFd(Queue->DestFile,FileFd::WriteAny); + if (_error->PendingError() == true) + return 5; + + FailFile = Queue->DestFile; + FailFile.c_str(); // Make sure we dont do a malloc in the signal handler + FailFd = File->Fd(); + FailTime = Srv->Date; + + // Set the expected size + if (Srv->StartPos >= 0) + { + Res.ResumePoint = Srv->StartPos; + ftruncate(File->Fd(),Srv->StartPos); + } + + // Set the start point + lseek(File->Fd(),0,SEEK_END); + + delete Srv->In.MD5; + Srv->In.MD5 = new MD5Summation; + + // Fill the MD5 Hash if the file is non-empty (resume) + if (Srv->StartPos > 0) + { + lseek(File->Fd(),0,SEEK_SET); + if (Srv->In.MD5->AddFD(File->Fd(),Srv->StartPos) == false) + { + _error->Errno("read","Problem hashing file"); + return 5; + } + lseek(File->Fd(),0,SEEK_END); + } + + SetNonBlock(File->Fd(),true); + return 0; +} + /*}}}*/ +// HttpMethod::SigTerm - Handle a fatal signal /*{{{*/ +// --------------------------------------------------------------------- +/* This closes and timestamps the open file. This is neccessary to get + resume behavoir on user abort */ +void HttpMethod::SigTerm(int) +{ + if (FailFd == -1) + _exit(100); + close(FailFd); + + // Timestamp + struct utimbuf UBuf; + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(FailFile.c_str(),&UBuf); + + _exit(100); +} + /*}}}*/ +// HttpMethod::Fetch - Fetch an item /*{{{*/ +// --------------------------------------------------------------------- +/* This adds an item to the pipeline. We keep the pipeline at a fixed + depth. */ +bool HttpMethod::Fetch(FetchItem *) +{ + if (Server == 0) + return true; + + // Queue the requests + int Depth = -1; + bool Tail = false; + for (FetchItem *I = Queue; I != 0 && Depth < (signed)PipelineDepth; + I = I->Next, Depth++) + { + // If pipelining is disabled, we only queue 1 request + if (Server->Pipeline == false && Depth >= 0) + break; + + // Make sure we stick with the same server + if (Server->Comp(I->Uri) == false) + break; + if (QueueBack == I) + Tail = true; + if (Tail == true) + { + QueueBack = I->Next; + SendReq(I,Server->Out); + continue; + } + } + + return true; +}; + /*}}}*/ +// HttpMethod::Configuration - Handle a configuration message /*{{{*/ +// --------------------------------------------------------------------- +/* We stash the desired pipeline depth */ +bool HttpMethod::Configuration(string Message) +{ + if (pkgAcqMethod::Configuration(Message) == false) + return false; + + TimeOut = _config->FindI("Acquire::http::Timeout",TimeOut); + PipelineDepth = _config->FindI("Acquire::http::Pipeline-Depth", + PipelineDepth); + Debug = _config->FindB("Debug::Acquire::http",false); + + return true; +} + /*}}}*/ +// HttpMethod::Loop - Main loop /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int HttpMethod::Loop() +{ + signal(SIGTERM,SigTerm); + signal(SIGINT,SigTerm); + + Server = 0; + + int FailCounter = 0; + while (1) + { + // We have no commands, wait for some to arrive + if (Queue == 0) + { + if (WaitFd(STDIN_FILENO) == false) + return 0; + } + + /* Run messages, we can accept 0 (no message) if we didn't + do a WaitFd above.. Otherwise the FD is closed. */ + int Result = Run(true); + if (Result != -1 && (Result != 0 || Queue == 0)) + return 100; + + if (Queue == 0) + continue; + + // Connect to the server + if (Server == 0 || Server->Comp(Queue->Uri) == false) + { + delete Server; + Server = new ServerState(Queue->Uri,this); + } + + // Reset the pipeline + if (Server->ServerFd == -1) + QueueBack = Queue; + + // Connnect to the host + if (Server->Open() == false) + { + Fail(true); + delete Server; + Server = 0; + continue; + } + + // Fill the pipeline. + Fetch(0); + + // Fetch the next URL header data from the server. + switch (Server->RunHeaders()) + { + case 0: + break; + + // The header data is bad + case 2: + { + _error->Error("Bad header Data"); + Fail(true); + continue; + } + + // The server closed a connection during the header get.. + default: + case 1: + { + FailCounter++; + _error->Discard(); + Server->Close(); + Server->Pipeline = false; + + if (FailCounter >= 2) + { + Fail("Connection failed",true); + FailCounter = 0; + } + + continue; + } + }; + + // Decide what to do. + FetchResult Res; + Res.Filename = Queue->DestFile; + switch (DealWithHeaders(Res,Server)) + { + // Ok, the file is Open + case 0: + { + URIStart(Res); + + // Run the data + bool Result = Server->RunData(); + + // Close the file, destroy the FD object and timestamp it + FailFd = -1; + delete File; + File = 0; + + // Timestamp + struct utimbuf UBuf; + time(&UBuf.actime); + UBuf.actime = Server->Date; + UBuf.modtime = Server->Date; + utime(Queue->DestFile.c_str(),&UBuf); + + // Send status to APT + if (Result == true) + { + Res.MD5Sum = Server->In.MD5->Result(); + URIDone(Res); + } + else + Fail(true); + + break; + } + + // IMS hit + case 1: + { + URIDone(Res); + break; + } + + // Hard server error, not found or something + case 3: + { + Fail(); + break; + } + + // Hard internal error, kill the connection and fail + case 5: + { + Fail(); + Server->Close(); + break; + } + + // We need to flush the data, the header is like a 404 w/ error text + case 4: + { + Fail(); + + // Send to content to dev/null + File = new FileFd("/dev/null",FileFd::WriteExists); + Server->RunData(); + delete File; + File = 0; + break; + } + + default: + Fail("Internal error"); + break; + } + + FailCounter = 0; + } + + return 0; +} + /*}}}*/ + +int main() +{ + HttpMethod Mth; + + return Mth.Loop(); +} diff --git a/apt/methods/http.h b/apt/methods/http.h new file mode 100644 index 0000000..0d106b5 --- /dev/null +++ b/apt/methods/http.h @@ -0,0 +1,149 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/// $Id: http.h,v 1.1.1.1 2000/08/10 12:42:38 kojima Exp $ +/* ###################################################################### + + HTTP Aquire Method - This is the HTTP aquire method for APT. + + ##################################################################### */ + /*}}}*/ + +#ifndef APT_HTTP_H +#define APT_HTTP_H + +#define MAXLEN 360 + +class HttpMethod; + +class CircleBuf +{ + unsigned char *Buf; + unsigned long Size; + unsigned long InP; + unsigned long OutP; + string OutQueue; + unsigned long StrPos; + unsigned long MaxGet; + struct timeval Start; + + unsigned long LeftRead() + { + unsigned long Sz = Size - (InP - OutP); + if (Sz > Size - (InP%Size)) + Sz = Size - (InP%Size); + return Sz; + } + unsigned long LeftWrite() + { + unsigned long Sz = InP - OutP; + if (InP > MaxGet) + Sz = MaxGet - OutP; + if (Sz > Size - (OutP%Size)) + Sz = Size - (OutP%Size); + return Sz; + } + void FillOut(); + + public: + + MD5Summation *MD5; + + // Read data in + bool Read(int Fd); + bool Read(string Data); + + // Write data out + bool Write(int Fd); + bool WriteTillEl(string &Data,bool Single = false); + + // Control the write limit + void Limit(long Max) {if (Max == -1) MaxGet = 0-1; else MaxGet = OutP + Max;} + bool IsLimit() {return MaxGet == OutP;}; + void Print() {cout << MaxGet << ',' << OutP << endl;}; + + // Test for free space in the buffer + bool ReadSpace() {return Size - (InP - OutP) > 0;}; + bool WriteSpace() {return InP - OutP > 0;}; + + // Dump everything + void Reset(); + void Stats(); + + CircleBuf(unsigned long Size); + ~CircleBuf() {delete [] Buf;}; +}; + +struct ServerState +{ + // This is the last parsed Header Line + unsigned int Major; + unsigned int Minor; + unsigned int Result; + char Code[MAXLEN]; + + // These are some statistics from the last parsed header lines + unsigned long Size; + signed long StartPos; + time_t Date; + bool HaveContent; + enum {Chunked,Stream,Closes} Encoding; + enum {Header, Data} State; + bool Pipeline; + + HttpMethod *Owner; + + // This is the connection itself. Output is data FROM the server + CircleBuf In; + CircleBuf Out; + int ServerFd; + URI ServerName; + + bool HeaderLine(string Line); + bool Comp(URI Other) {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; + void Reset() {Major = 0; Minor = 0; Result = 0; Size = 0; StartPos = 0; + Encoding = Closes; time(&Date); ServerFd = -1; + Pipeline = true;}; + int RunHeaders(); + bool RunData(); + + bool Open(); + bool Close(); + + ServerState(URI Srv,HttpMethod *Owner); + ~ServerState() {Close();}; +}; + +class HttpMethod : public pkgAcqMethod +{ + void SendReq(FetchItem *Itm,CircleBuf &Out); + bool Go(bool ToFile,ServerState *Srv); + bool Flush(ServerState *Srv); + bool ServerDie(ServerState *Srv); + int DealWithHeaders(FetchResult &Res,ServerState *Srv); + + virtual bool Fetch(FetchItem *); + virtual bool Configuration(string Message); + + // In the event of a fatal signal this file will be closed and timestamped. + static string FailFile; + static int FailFd; + static time_t FailTime; + static void SigTerm(int); + + public: + friend ServerState; + + FileFd *File; + ServerState *Server; + + int Loop(); + + HttpMethod() : pkgAcqMethod("1.2",Pipeline | SendConfig) + { + File = 0; + Server = 0; + }; +}; + +URI Proxy; + +#endif diff --git a/apt/methods/makefile b/apt/methods/makefile new file mode 100644 index 0000000..70edd1b --- /dev/null +++ b/apt/methods/makefile @@ -0,0 +1,65 @@ +# -*- make -*- +BASE=.. +SUBDIR=methods + +# Bring in the default rules +include ../buildlib/defaults.mak +BIN := $(BIN)/methods + +# The file method +PROGRAM=file +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = file.cc +include $(PROGRAM_H) + +# The copy method +PROGRAM=copy +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = copy.cc +include $(PROGRAM_H) + +# The gzip method +PROGRAM=gzip +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = gzip.cc +include $(PROGRAM_H) + +# The gpg method +PROGRAM=gpg +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = gpg.cc +include $(PROGRAM_H) + + + +# The cdrom method +PROGRAM=cdrom +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = cdrom.cc +include $(PROGRAM_H) + +# The http method +PROGRAM=http +SLIBS = -lapt-pkg $(SOCKETLIBS) $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = http.cc rfc2553emu.cc connect.cc +include $(PROGRAM_H) + +# The ftp method +PROGRAM=ftp +SLIBS = -lapt-pkg $(SOCKETLIBS) $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = ftp.cc rfc2553emu.cc connect.cc +include $(PROGRAM_H) + +# The rsh method +#PROGRAM=rsh +#SLIBS = -lapt-pkg $(SOCKETLIBS) $(RPMLIBS) +#LIB_MAKES = apt-pkg/makefile +#SOURCE = rsh.cc +#include $(PROGRAM_H) diff --git a/apt/methods/rfc2553emu.cc b/apt/methods/rfc2553emu.cc new file mode 100644 index 0000000..dcc71d7 --- /dev/null +++ b/apt/methods/rfc2553emu.cc @@ -0,0 +1,230 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rfc2553emu.cc,v 1.1.1.1 2000/08/10 12:42:38 kojima Exp $ +/* ###################################################################### + + RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo, + freeaddrinfo and getnameinfo + + This is really C code, it just has a .cc extensions to play nicer with + the rest of APT. + + Originally written by Jason Gunthorpe and placed into + the Public Domain, do with it what you will. + + ##################################################################### */ + /*}}}*/ +#include "rfc2553emu.h" +#include +#include +#include +#include +#include + +#ifndef HAVE_GETADDRINFO +// getaddrinfo - Resolve a hostname /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, + struct addrinfo **res) +{ + struct addrinfo **Result = res; + hostent *Addr; + unsigned int Port; + int Proto; + const char *End; + char **CurAddr; + + Addr = gethostbyname(nodename); + if (Addr == 0) + { + if (h_errno == TRY_AGAIN) + return EAI_AGAIN; + if (h_errno == NO_RECOVERY) + return EAI_FAIL; + return EAI_NONAME; + } + + // No A records + if (Addr->h_addr_list[0] == 0) + return EAI_NONAME; + + // Try to convert the service as a number + Port = htons(strtol(servname,(char **)&End,0)); + Proto = SOCK_STREAM; + + if (hints != 0 && hints->ai_socktype != 0) + Proto = hints->ai_socktype; + + // Not a number, must be a name. + if (End != servname + strlen(servname)) + { + struct servent *Srv = 0; + + // Do a lookup in the service database + if (hints == 0 || hints->ai_socktype == SOCK_STREAM) + Srv = getservbyname(servname,"tcp"); + if (hints != 0 && hints->ai_socktype == SOCK_DGRAM) + Srv = getservbyname(servname,"udp"); + if (Srv == 0) + return EAI_NONAME; + + // Get the right protocol + Port = Srv->s_port; + if (strcmp(Srv->s_proto,"tcp") == 0) + Proto = SOCK_STREAM; + else + { + if (strcmp(Srv->s_proto,"udp") == 0) + Proto = SOCK_DGRAM; + else + return EAI_NONAME; + } + + if (hints != 0 && hints->ai_socktype != Proto && + hints->ai_socktype != 0) + return EAI_SERVICE; + } + + // Start constructing the linked list + *res = 0; + for (CurAddr = Addr->h_addr_list; *CurAddr != 0; CurAddr++) + { + // New result structure + *Result = (struct addrinfo *)calloc(sizeof(**Result),1); + if (*Result == 0) + { + freeaddrinfo(*res); + return EAI_MEMORY; + } + if (*res == 0) + *res = *Result; + + (*Result)->ai_family = AF_INET; + (*Result)->ai_socktype = Proto; + + // If we have the IPPROTO defines we can set the protocol field + #ifdef IPPROTO_TCP + if (Proto == SOCK_STREAM) + (*Result)->ai_protocol = IPPROTO_TCP; + if (Proto == SOCK_DGRAM) + (*Result)->ai_protocol = IPPROTO_UDP; + #endif + + // Allocate space for the address + (*Result)->ai_addrlen = sizeof(struct sockaddr_in); + (*Result)->ai_addr = (struct sockaddr *)calloc(sizeof(sockaddr_in),1); + if ((*Result)->ai_addr == 0) + { + freeaddrinfo(*res); + return EAI_MEMORY; + } + + // Set the address + ((struct sockaddr_in *)(*Result)->ai_addr)->sin_family = AF_INET; + ((struct sockaddr_in *)(*Result)->ai_addr)->sin_port = Port; + ((struct sockaddr_in *)(*Result)->ai_addr)->sin_addr = *(in_addr *)(*CurAddr); + + Result = &(*Result)->ai_next; + } + + return 0; +} + /*}}}*/ +// freeaddrinfo - Free the result of getaddrinfo /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void freeaddrinfo(struct addrinfo *ai) +{ + struct addrinfo *Tmp; + while (ai != 0) + { + free(ai->ai_addr); + Tmp = ai; + ai = ai->ai_next; + free(ai); + } +} + /*}}}*/ +#endif // HAVE_GETADDRINFO + +#ifndef HAVE_GETNAMEINFO +// getnameinfo - Convert a sockaddr to a string /*{{{*/ +// --------------------------------------------------------------------- +/* */ +int getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, + int flags) +{ + struct sockaddr_in *sin = (struct sockaddr_in *)sa; + + // This routine only supports internet addresses + if (sa->sa_family != AF_INET) + return EAI_ADDRFAMILY; + + if (host != 0) + { + // Try to resolve the hostname + if ((flags & NI_NUMERICHOST) != NI_NUMERICHOST) + { + struct hostent *Ent = gethostbyaddr((char *)&sin->sin_addr,sizeof(sin->sin_addr), + AF_INET); + if (Ent != 0) + strncpy(host,Ent->h_name,hostlen); + else + { + if ((flags & NI_NAMEREQD) == NI_NAMEREQD) + { + if (h_errno == TRY_AGAIN) + return EAI_AGAIN; + if (h_errno == NO_RECOVERY) + return EAI_FAIL; + return EAI_NONAME; + } + + flags |= NI_NUMERICHOST; + } + } + + // Resolve as a plain numberic + if ((flags & NI_NUMERICHOST) == NI_NUMERICHOST) + { + strncpy(host,inet_ntoa(sin->sin_addr),hostlen); + } + } + + if (serv != 0) + { + // Try to resolve the hostname + if ((flags & NI_NUMERICSERV) != NI_NUMERICSERV) + { + struct servent *Ent; + if ((flags & NI_DATAGRAM) == NI_DATAGRAM) + Ent = getservbyport(sin->sin_port,"udp"); + else + Ent = getservbyport(sin->sin_port,"tcp"); + + if (Ent != 0) + strncpy(serv,Ent->s_name,servlen); + else + { + if ((flags & NI_NAMEREQD) == NI_NAMEREQD) + return EAI_NONAME; + + flags |= NI_NUMERICSERV; + } + } + + // Resolve as a plain numberic + if ((flags & NI_NUMERICSERV) == NI_NUMERICSERV) + { + snprintf(serv,servlen,"%u",sin->sin_port); + } + } + + return 0; +} + /*}}}*/ +#endif // HAVE_GETNAMEINFO diff --git a/apt/methods/rfc2553emu.h b/apt/methods/rfc2553emu.h new file mode 100644 index 0000000..0ffc773 --- /dev/null +++ b/apt/methods/rfc2553emu.h @@ -0,0 +1,102 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rfc2553emu.h,v 1.1.1.1 2000/08/10 12:42:38 kojima Exp $ +/* ###################################################################### + + RFC 2553 Emulation - Provides emulation for RFC 2553 getaddrinfo, + freeaddrinfo and getnameinfo + + These functions are necessary to write portable protocol independent + networking. They transparently support IPv4, IPv6 and probably many + other protocols too. This implementation is needed when the host does + not support these standards. It implements a simple wrapper that + basically supports only IPv4. + + Perfect emulation is not provided, but it is passable.. + + Originally written by Jason Gunthorpe and placed into + the Public Domain, do with it what you will. + + ##################################################################### */ + /*}}}*/ +#ifndef RFC2553EMU_H +#define RFC2553EMU_H + +#include +#include +#include + +// Autosense getaddrinfo +#if defined(AI_PASSIVE) && defined(EAI_NONAME) +#define HAVE_GETADDRINFO +#endif + +// Autosense getnameinfo +#if defined(NI_NUMERICHOST) +#define HAVE_GETNAMEINFO +#endif + +// getaddrinfo support? +#ifndef HAVE_GETADDRINFO + // Renamed to advoid type clashing.. (for debugging) + struct addrinfo_emu + { + int ai_flags; /* AI_PASSIVE, AI_CANONNAME, AI_NUMERICHOST */ + int ai_family; /* PF_xxx */ + int ai_socktype; /* SOCK_xxx */ + int ai_protocol; /* 0 or IPPROTO_xxx for IPv4 and IPv6 */ + size_t ai_addrlen; /* length of ai_addr */ + char *ai_canonname; /* canonical name for nodename */ + struct sockaddr *ai_addr; /* binary address */ + struct addrinfo_emu *ai_next; /* next structure in linked list */ + }; + #define addrinfo addrinfo_emu + + int getaddrinfo(const char *nodename, const char *servname, + const struct addrinfo *hints, + struct addrinfo **res); + void freeaddrinfo(struct addrinfo *ai); + + #ifndef AI_PASSIVE + #define AI_PASSIVE (1<<1) + #endif + + #ifndef EAI_NONAME + #define EAI_NONAME -1 + #define EAI_AGAIN -2 + #define EAI_FAIL -3 + #define EAI_NODATA -4 + #define EAI_FAMILY -5 + #define EAI_SOCKTYPE -6 + #define EAI_SERVICE -7 + #define EAI_ADDRFAMILY -8 + #define EAI_SYSTEM -10 + #define EAI_MEMORY -11 + #endif + +#endif + +// getnameinfo support (glibc2.0 has getaddrinfo only) +#ifndef HAVE_GETNAMEINFO + + int getnameinfo(const struct sockaddr *sa, socklen_t salen, + char *host, size_t hostlen, + char *serv, size_t servlen, + int flags); + + #ifndef NI_MAXHOST + #define NI_MAXHOST 1025 + #define NI_MAXSERV 32 + #endif + + #ifndef NI_NUMERICHOST + #define NI_NUMERICHOST (1<<0) + #define NI_NUMERICSERV (1<<1) +// #define NI_NOFQDN (1<<2) + #define NI_NAMEREQD (1<<3) + #define NI_DATAGRAM (1<<4) + #endif + +#endif + +#endif diff --git a/apt/methods/rsh.cc b/apt/methods/rsh.cc new file mode 100644 index 0000000..bb435d7 --- /dev/null +++ b/apt/methods/rsh.cc @@ -0,0 +1,486 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: rsh.cc,v 1.1 2001/11/30 20:34:13 kojima Exp $ +/* ###################################################################### + + RSH method - Transfer files via rsh compatible program + + Written by Ben Collins , Copyright (c) 2000 + Licensed under the GNU General Public License v2 [no exception clauses] + + ##################################################################### */ + /*}}}*/ +// Iclude Files /*{{{*/ +#include "rsh.h" +#include + +#include +#include +#include +#include +#include +#include +#include +#include + /*}}}*/ + +const char *Prog; +unsigned long TimeOut = 120; +time_t RSHMethod::FailTime = 0; +string RSHMethod::FailFile; +int RSHMethod::FailFd = -1; + +// RSHConn::RSHConn - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +RSHConn::RSHConn(URI Srv) : Len(0), WriteFd(-1), ReadFd(-1), + ServerName(Srv), Process(-1) {} + /*}}}*/ +// RSHConn::RSHConn - Destructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +RSHConn::~RSHConn() +{ + Close(); +} + /*}}}*/ +// RSHConn::Close - Forcibly terminate the connection /*{{{*/ +// --------------------------------------------------------------------- +/* Often this is called when things have gone wrong to indicate that the + connection is no longer usable. */ +void RSHConn::Close() +{ + if (Process == -1) + return; + + close(WriteFd); + close(ReadFd); + kill(Process,SIGINT); + ExecWait(Process,"",true); + WriteFd = -1; + ReadFd = -1; + Process = -1; +} + /*}}}*/ +// RSHConn::Open - Connect to a host /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool RSHConn::Open() +{ + // Use the already open connection if possible. + if (Process != -1) + return true; + + if (Connect(ServerName.Host,ServerName.User) == false) + return false; + + return true; +} + /*}}}*/ +// RSHConn::Connect - Fire up rsh and connect /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool RSHConn::Connect(string Host, string User) +{ + // Create the pipes + int Pipes[4] = {-1,-1,-1,-1}; + if (pipe(Pipes) != 0 || pipe(Pipes+2) != 0) + { + _error->Errno("pipe","Failed to create IPC pipe to subprocess"); + for (int I = 0; I != 4; I++) + close(Pipes[I]); + return false; + } + for (int I = 0; I != 4; I++) + SetCloseExec(Pipes[I],true); + + Process = ExecFork(); + + // The child + if (Process == 0) + { + const char *Args[6]; + int i = 0; + + dup2(Pipes[1],STDOUT_FILENO); + dup2(Pipes[2],STDIN_FILENO); + + // Probably should do + // dup2(open("/dev/null",O_RDONLY),STDERR_FILENO); + + Args[i++] = Prog; + if (User.empty() == false) { + Args[i++] = "-l"; + Args[i++] = User.c_str(); + } + if (Host.empty() == false) { + Args[i++] = Host.c_str(); + } + Args[i++] = "/bin/sh"; + Args[i] = 0; + execvp(Args[0],(char **)Args); + exit(100); + } + + ReadFd = Pipes[0]; + WriteFd = Pipes[3]; + SetNonBlock(Pipes[0],true); + SetNonBlock(Pipes[3],true); + close(Pipes[1]); + close(Pipes[2]); + + return true; +} + /*}}}*/ +// RSHConn::ReadLine - Very simple buffered read with timeout /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool RSHConn::ReadLine(string &Text) +{ + if (Process == -1 || ReadFd == -1) + return false; + + // Suck in a line + while (Len < sizeof(Buffer)) + { + // Scan the buffer for a new line + for (unsigned int I = 0; I != Len; I++) + { + // Escape some special chars + if (Buffer[I] == 0) + Buffer[I] = '?'; + + // End of line? + if (Buffer[I] != '\n') + continue; + + I++; + Text = string(Buffer,I); + memmove(Buffer,Buffer+I,Len - I); + Len -= I; + return true; + } + + // Wait for some data.. + if (WaitFd(ReadFd,false,TimeOut) == false) + { + Close(); + return _error->Error("Connection timeout"); + } + + // Suck it back + int Res = read(ReadFd,Buffer + Len,sizeof(Buffer) - Len); + if (Res <= 0) + { + _error->Errno("read","Read error"); + Close(); + return false; + } + Len += Res; + } + + return _error->Error("A response overflowed the buffer."); +} + /*}}}*/ +// RSHConn::WriteMsg - Send a message with optional remote sync. /*{{{*/ +// --------------------------------------------------------------------- +/* The remote sync flag appends a || echo which will insert blank line + once the command completes. */ +bool RSHConn::WriteMsg(string &Text,bool Sync,const char *Fmt,...) +{ + va_list args; + va_start(args,Fmt); + + // sprintf the description + char S[512]; + vsnprintf(S,sizeof(S) - 4,Fmt,args); + if (Sync == true) + strcat(S," 2> /dev/null || echo\n"); + else + strcat(S," 2> /dev/null\n"); + + // Send it off + unsigned long Len = strlen(S); + unsigned long Start = 0; + while (Len != 0) + { + if (WaitFd(WriteFd,true,TimeOut) == false) + { + + Close(); + return _error->Error("Connection timeout"); + } + + int Res = write(WriteFd,S + Start,Len); + if (Res <= 0) + { + _error->Errno("write","Write Error"); + Close(); + return false; + } + + Len -= Res; + Start += Res; + } + + if (Sync == true) + return ReadLine(Text); + return true; +} + /*}}}*/ +// RSHConn::Size - Return the size of the file /*{{{*/ +// --------------------------------------------------------------------- +/* Right now for successfull transfer the file size must be known in + advance. */ +bool RSHConn::Size(const char *Path,unsigned long &Size) +{ + // Query the size + string Msg; + Size = 0; + + if (WriteMsg(Msg,true,"find %s -follow -printf '%%s\\n'",Path) == false) + return false; + + // FIXME: Sense if the bad reply is due to a File Not Found. + + char *End; + Size = strtoul(Msg.c_str(),&End,10); + if (End == Msg.c_str()) + return _error->Error("File Not Found"); + return true; +} + /*}}}*/ +// RSHConn::ModTime - Get the modification time in UTC /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool RSHConn::ModTime(const char *Path, time_t &Time) +{ + Time = time(&Time); + // Query the mod time + string Msg; + + if (WriteMsg(Msg,true,"TZ=UTC find %s -follow -printf '%%TY%%Tm%%Td%%TH%%TM%%TS\\n'",Path) == false) + return false; + + // Parse it + StrToTime(Msg,Time); + return true; +} + /*}}}*/ +// RSHConn::Get - Get a file /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool RSHConn::Get(const char *Path,FileFd &To,unsigned long Resume, + Hashes &Hash,bool &Missing, unsigned long Size) +{ + Missing = false; + + // Round to a 2048 byte block + Resume = Resume - (Resume % 2048); + + if (To.Truncate(Resume) == false) + return false; + if (To.Seek(0) == false) + return false; + + if (Resume != 0) { + if (Hash.AddFD(To.Fd(),Resume) == false) { + _error->Errno("read","Problem hashing file"); + return false; + } + } + + // FIXME: Detect file-not openable type errors. + string Jnk; + if (WriteMsg(Jnk,false,"dd if=%s bs=2048 skip=%u", Path, Resume / 2048) == false) + return false; + + // Copy loop + unsigned int MyLen = Resume; + unsigned char Buffer[4096]; + while (MyLen < Size) + { + // Wait for some data.. + if (WaitFd(ReadFd,false,TimeOut) == false) + { + Close(); + return _error->Error("Data socket timed out"); + } + + // Read the data.. + int Res = read(ReadFd,Buffer,sizeof(Buffer)); + if (Res == 0) + { + Close(); + return _error->Error("Connection closed prematurely"); + } + + if (Res < 0) + { + if (errno == EAGAIN) + continue; + break; + } + MyLen += Res; + + Hash.Add(Buffer,Res); + if (To.Write(Buffer,Res) == false) + { + Close(); + return false; + } + } + + return true; +} + /*}}}*/ + +// RSHMethod::RSHMethod - Constructor /*{{{*/ +// --------------------------------------------------------------------- +/* */ +RSHMethod::RSHMethod() : pkgAcqMethod("1.0") +{ + signal(SIGTERM,SigTerm); + signal(SIGINT,SigTerm); + Server = 0; + FailFd = -1; +}; + /*}}}*/ +// RSHMethod::SigTerm - Clean up and timestamp the files on exit /*{{{*/ +// --------------------------------------------------------------------- +/* */ +void RSHMethod::SigTerm(int sig) +{ + if (FailFd == -1) + _exit(100); + close(FailFd); + + // Timestamp + struct utimbuf UBuf; + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(FailFile.c_str(),&UBuf); + + _exit(100); +} + /*}}}*/ +// RSHMethod::Fetch - Fetch a URI /*{{{*/ +// --------------------------------------------------------------------- +/* */ +bool RSHMethod::Fetch(FetchItem *Itm) +{ + URI Get = Itm->Uri; + const char *File = Get.Path.c_str(); + FetchResult Res; + Res.Filename = Itm->DestFile; + Res.IMSHit = false; + + // Connect to the server + if (Server == 0 || Server->Comp(Get) == false) { + delete Server; + Server = new RSHConn(Get); + } + + // Could not connect is a transient error.. + if (Server->Open() == false) { + Server->Close(); + Fail(true); + return true; + } + + // We say this mainly because the pause here is for the + // ssh connection that is still going + Status("Connecting to %s", Get.Host.c_str()); + + // Get the files information + unsigned long Size; + if (Server->Size(File,Size) == false || + Server->ModTime(File,FailTime) == false) + { + //Fail(true); + //_error->Error("File Not Found"); // Will be handled by Size + return false; + } + Res.Size = Size; + + // See if it is an IMS hit + if (Itm->LastModified == FailTime) { + Res.Size = 0; + Res.IMSHit = true; + URIDone(Res); + return true; + } + + // See if the file exists + struct stat Buf; + if (stat(Itm->DestFile.c_str(),&Buf) == 0) { + if (Size == (unsigned)Buf.st_size && FailTime == Buf.st_mtime) { + Res.Size = Buf.st_size; + Res.LastModified = Buf.st_mtime; + Res.ResumePoint = Buf.st_size; + URIDone(Res); + return true; + } + + // Resume? + if (FailTime == Buf.st_mtime && Size > (unsigned)Buf.st_size) + Res.ResumePoint = Buf.st_size; + } + + // Open the file + Hashes Hash; + { + FileFd Fd(Itm->DestFile,FileFd::WriteAny); + if (_error->PendingError() == true) + return false; + + URIStart(Res); + + FailFile = Itm->DestFile; + FailFile.c_str(); // Make sure we dont do a malloc in the signal handler + FailFd = Fd.Fd(); + + bool Missing; + if (Server->Get(File,Fd,Res.ResumePoint,Hash,Missing,Res.Size) == false) + { + Fd.Close(); + + // Timestamp + struct utimbuf UBuf; + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(FailFile.c_str(),&UBuf); + + // If the file is missing we hard fail otherwise transient fail + if (Missing == true) + return false; + Fail(true); + return true; + } + + Res.Size = Fd.Size(); + } + + Res.LastModified = FailTime; + Res.TakeHashes(Hash); + + // Timestamp + struct utimbuf UBuf; + UBuf.actime = FailTime; + UBuf.modtime = FailTime; + utime(Queue->DestFile.c_str(),&UBuf); + FailFd = -1; + + URIDone(Res); + + return true; +} + /*}}}*/ + +int main(int argc, const char *argv[]) +{ + RSHMethod Mth; + Prog = strrchr(argv[0],'/'); + Prog++; + return Mth.Run(); +} diff --git a/apt/methods/rsh.h b/apt/methods/rsh.h new file mode 100644 index 0000000..921762f --- /dev/null +++ b/apt/methods/rsh.h @@ -0,0 +1,69 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/// $Id: rsh.h,v 1.1 2001/11/30 20:34:13 kojima Exp $ +// $Id: rsh.h,v 1.1 2001/11/30 20:34:13 kojima Exp $ +/* ###################################################################### + + RSH method - Transfer files via rsh compatible program + + ##################################################################### */ + /*}}}*/ +#ifndef APT_RSH_H +#define APT_RSH_H + +#include +#include +#include +#include +#include + +class RSHConn +{ + char Buffer[1024*10]; + unsigned long Len; + int WriteFd; + int ReadFd; + URI ServerName; + + // Private helper functions + bool ReadLine(string &Text); + + public: + + int Process; + + // Raw connection IO + bool WriteMsg(string &Text,bool Sync,const char *Fmt,...); + bool Connect(string Host, string User); + bool Comp(URI Other) {return Other.Host == ServerName.Host && Other.Port == ServerName.Port;}; + + // Connection control + bool Open(); + void Close(); + + // Query + bool Size(const char *Path,unsigned long &Size); + bool ModTime(const char *Path, time_t &Time); + bool Get(const char *Path,FileFd &To,unsigned long Resume, + Hashes &Hash,bool &Missing, unsigned long Size); + + RSHConn(URI Srv); + ~RSHConn(); +}; + +class RSHMethod : public pkgAcqMethod +{ + virtual bool Fetch(FetchItem *Itm); + + RSHConn *Server; + + static string FailFile; + static int FailFd; + static time_t FailTime; + static void SigTerm(int); + + public: + + RSHMethod(); +}; + +#endif diff --git a/apt/mkinstalldirs b/apt/mkinstalldirs new file mode 100755 index 0000000..8d29ca1 --- /dev/null +++ b/apt/mkinstalldirs @@ -0,0 +1,40 @@ +#! /bin/sh +# mkinstalldirs --- make directory hierarchy +# Author: Noah Friedman +# Created: 1993-05-16 +# Public domain + +# $Id: mkinstalldirs,v 1.1 2000/09/13 21:58:08 kojima Exp $ + +errstatus=0 + +for file +do + set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'` + shift + + pathcomp= + for d + do + pathcomp="$pathcomp$d" + case "$pathcomp" in + -* ) pathcomp=./$pathcomp ;; + esac + + if test ! -d "$pathcomp"; then + echo "mkdir $pathcomp" 1>&2 + + mkdir "$pathcomp" || lasterr=$? + + if test ! -d "$pathcomp"; then + errstatus=$lasterr + fi + fi + + pathcomp="$pathcomp/" + done +done + +exit $errstatus + +# mkinstalldirs ends here diff --git a/apt/po/CVS/Entries b/apt/po/CVS/Entries new file mode 100644 index 0000000..892f008 --- /dev/null +++ b/apt/po/CVS/Entries @@ -0,0 +1,10 @@ +/Makefile.in.in/1.1/Fri Aug 10 14:03:58 2001// +/apt.pot/1.10/Fri Aug 10 14:04:12 2001// +/cat-id-tbl.c/1.6/Fri Aug 10 14:04:12 2001// +/es_ES.po/1.7/Fri Aug 10 14:04:14 2001// +/it_IT.po/1.1/Fri Aug 10 14:04:16 2001// +/stamp-cat-id/1.1/Fri Aug 10 14:04:24 2001// +/pt_BR.po/1.18/Tue Nov 13 14:24:16 2001// +/POTFILES.in/1.4/Fri Nov 16 01:13:06 2001// +/ru.po/1.1/Tue Nov 13 17:32:08 2001// +D diff --git a/apt/po/CVS/Repository b/apt/po/CVS/Repository new file mode 100644 index 0000000..b65def8 --- /dev/null +++ b/apt/po/CVS/Repository @@ -0,0 +1 @@ +rapt/po diff --git a/apt/po/CVS/Root b/apt/po/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/po/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/po/Makefile.in.in b/apt/po/Makefile.in.in new file mode 100644 index 0000000..ea01d49 --- /dev/null +++ b/apt/po/Makefile.in.in @@ -0,0 +1,247 @@ +# Makefile for program source directory in GNU NLS utilities package. +# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper +# +# This file file be copied and used freely without restrictions. It can +# be used in projects which are not available under the GNU Public License +# but which still want to provide support for the GNU gettext functionality. +# Please note that the actual code is *not* freely available. + +PACKAGE = @PACKAGE@ +VERSION = @VERSION@ + +SHELL = /bin/sh +@SET_MAKE@ + +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ +VPATH = @srcdir@ + +prefix = @prefix@ +exec_prefix = @exec_prefix@ +datadir = $(prefix)/@DATADIRNAME@ +localedir = $(datadir)/locale +gnulocaledir = $(prefix)/share/locale +gettextsrcdir = $(prefix)/share/gettext/po +subdir = po + +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +MKINSTALLDIRS = @MKINSTALLDIRS@ + +CC = @CC@ +GENCAT = @GENCAT@ +GMSGFMT = PATH=../src:$$PATH @GMSGFMT@ +MSGFMT = @MSGFMT@ +XGETTEXT = PATH=../src:$$PATH @XGETTEXT@ +MSGMERGE = PATH=../src:$$PATH msgmerge + +DEFS = @DEFS@ +CFLAGS = @CFLAGS@ +CPPFLAGS = @CPPFLAGS@ + +INCLUDES = -I.. -I$(top_srcdir)/intl + +COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $(XCFLAGS) + +SOURCES = cat-id-tbl.c +POFILES = @POFILES@ +GMOFILES = @GMOFILES@ +DISTFILES = Makefile.in.in POTFILES.in $(PACKAGE).pot \ +stamp-cat-id $(POFILES) $(GMOFILES) $(SOURCES) + +POTFILES = \ + +CATALOGS = @CATALOGS@ +CATOBJEXT = @CATOBJEXT@ +INSTOBJEXT = @INSTOBJEXT@ + +.SUFFIXES: +.SUFFIXES: .c .o .po .pox .gmo .mo .msg .cat + +.c.o: + $(COMPILE) $< + +.po.pox: + $(MAKE) $(PACKAGE).pot + $(MSGMERGE) $< $(srcdir)/$(PACKAGE).pot -o $*.pox + +.po.mo: + $(MSGFMT) -o $@ $< + +.po.gmo: + file=$(srcdir)/`echo $* | sed 's,.*/,,'`.gmo \ + && rm -f $$file && $(GMSGFMT) -o $$file $< + +.po.cat: + sed -f ../intl/po2msg.sed < $< > $*.msg \ + && rm -f $@ && $(GENCAT) $@ $*.msg + + +all: all-@USE_NLS@ + +all-yes: cat-id-tbl.c $(CATALOGS) +all-no: + +$(srcdir)/$(PACKAGE).pot: $(POTFILES) + $(XGETTEXT) --default-domain=$(PACKAGE) --directory=$(top_srcdir) \ + --add-comments --keyword=_ --keyword=N_ \ + --files-from=$(srcdir)/POTFILES.in \ + && test ! -f $(PACKAGE).po \ + || ( rm -f $(srcdir)/$(PACKAGE).pot \ + && mv $(PACKAGE).po $(srcdir)/$(PACKAGE).pot ) + +$(srcdir)/cat-id-tbl.c: stamp-cat-id; @: +$(srcdir)/stamp-cat-id: $(PACKAGE).pot + rm -f cat-id-tbl.tmp + sed -f ../intl/po2tbl.sed $(srcdir)/$(PACKAGE).pot \ + | sed -e "s/@PACKAGE NAME@/$(PACKAGE)/" > cat-id-tbl.tmp + if cmp -s cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; then \ + rm cat-id-tbl.tmp; \ + else \ + echo cat-id-tbl.c changed; \ + rm -f $(srcdir)/cat-id-tbl.c; \ + mv cat-id-tbl.tmp $(srcdir)/cat-id-tbl.c; \ + fi + cd $(srcdir) && rm -f stamp-cat-id && echo timestamp > stamp-cat-id + + +install: install-exec install-data +install-exec: +install-data: install-data-@USE_NLS@ +install-data-no: all +install-data-yes: all + if test -x "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(DESTDIR)$(datadir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(datadir); \ + fi + @catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + case "$$cat" in \ + *.gmo) destdir=$(DESTDIR)$(gnulocaledir);; \ + *) destdir=$(DESTDIR)$(localedir);; \ + esac; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + dir=$$destdir/$$lang/LC_MESSAGES; \ + if test -r "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $$dir; \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $$dir; \ + fi; \ + if test -r $$cat; then \ + $(INSTALL_DATA) $$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $$cat as $$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + else \ + $(INSTALL_DATA) $(srcdir)/$$cat $$dir/$(PACKAGE)$(INSTOBJEXT); \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT)"; \ + fi; \ + if test -r $$cat.m; then \ + $(INSTALL_DATA) $$cat.m $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $$cat.m as $$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + if test -r $(srcdir)/$$cat.m ; then \ + $(INSTALL_DATA) $(srcdir)/$$cat.m \ + $$dir/$(PACKAGE)$(INSTOBJEXT).m; \ + echo "installing $(srcdir)/$$cat as" \ + "$$dir/$(PACKAGE)$(INSTOBJEXT).m"; \ + else \ + true; \ + fi; \ + fi; \ + done + if test "$(PACKAGE)" = "gettext"; then \ + if test -x "$(MKINSTALLDIRS)"; then \ + $(MKINSTALLDIRS) $(DESTDIR)$(gettextsrcdir); \ + else \ + $(SHELL) $(top_srcdir)/mkinstalldirs $(DESTDIR)$(gettextsrcdir); \ + fi; \ + $(INSTALL_DATA) $(srcdir)/Makefile.in.in \ + $(DESTDIR)$(gettextsrcdir)/Makefile.in.in; \ + else \ + : ; \ + fi + +# Define this as empty until I found a useful application. +installcheck: + +uninstall: + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(localedir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT); \ + rm -f $(DESTDIR)$(gnulocaledir)/$$lang/LC_MESSAGES/$(PACKAGE)$(INSTOBJEXT).m; \ + done + +check: all + +cat-id-tbl.o: ../intl/libgettext.h + +dvi info tags TAGS ID: + +mostlyclean: + rm -f core core.* *.pox $(PACKAGE).po *.old.po cat-id-tbl.tmp + rm -fr *.o + +clean: mostlyclean + +distclean: clean + rm -f Makefile Makefile.in POTFILES *.mo *.msg *.cat *.cat.m + +maintainer-clean: distclean + @echo "This command is intended for maintainers to use;" + @echo "it deletes files that may require special tools to rebuild." + rm -f $(GMOFILES) + +distdir = ../$(PACKAGE)-$(VERSION)/$(subdir) +dist distdir: update-po $(DISTFILES) + dists="$(DISTFILES)"; \ + for file in $$dists; do \ + ln $(srcdir)/$$file $(distdir) 2> /dev/null \ + || cp -p $(srcdir)/$$file $(distdir); \ + done + +update-po: Makefile + $(MAKE) $(PACKAGE).pot + PATH=`pwd`/../src:$$PATH; \ + cd $(srcdir); \ + catalogs='$(CATALOGS)'; \ + for cat in $$catalogs; do \ + cat=`basename $$cat`; \ + lang=`echo $$cat | sed 's/\$(CATOBJEXT)$$//'`; \ + mv $$lang.po $$lang.old.po; \ + echo "$$lang:"; \ + if $(MSGMERGE) $$lang.old.po $(PACKAGE).pot -o $$lang.po; then \ + rm -f $$lang.old.po; \ + else \ + echo "msgmerge for $$cat failed!"; \ + rm -f $$lang.po; \ + mv $$lang.old.po $$lang.po; \ + fi; \ + done + +POTFILES: POTFILES.in + ( if test 'x$(srcdir)' != 'x.'; then \ + posrcprefix='$(top_srcdir)/'; \ + else \ + posrcprefix="../"; \ + fi; \ + rm -f $@-t $@ \ + && (sed -e '/^#/d' -e '/^[ ]*$$/d' \ + -e "s@.*@ $$posrcprefix& \\\\@" < $(srcdir)/$@.in \ + | sed -e '$$s/\\$$//') > $@-t \ + && chmod a-w $@-t \ + && mv $@-t $@ ) + +Makefile: Makefile.in.in ../config.status POTFILES + cd .. \ + && CONFIG_FILES=$(subdir)/$@.in CONFIG_HEADERS= \ + $(SHELL) ./config.status + +# Tell versions [3.59,3.63) of GNU make not to export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/apt/po/POTFILES.in b/apt/po/POTFILES.in new file mode 100644 index 0000000..06c1ba7 --- /dev/null +++ b/apt/po/POTFILES.in @@ -0,0 +1,32 @@ +cmdline/apt-cache.cc +cmdline/apt-cdrom.cc +cmdline/apt-config.cc +cmdline/apt-get.cc +apt-pkg/acquire-item.cc +apt-pkg/acquire-worker.cc +apt-pkg/acquire.cc +apt-pkg/cachefile.cc +apt-pkg/clean.cc +apt-pkg/depcache.cc +apt-pkg/packagemanager.cc +apt-pkg/pkgcache.cc +apt-pkg/pkgcachegen.cc +apt-pkg/pkgrecords.cc +apt-pkg/contrib/cdromutl.cc +apt-pkg/contrib/cmndline.cc +apt-pkg/contrib/configuration.cc +apt-pkg/contrib/error.cc +apt-pkg/contrib/fileutl.cc +apt-pkg/contrib/mmap.cc +apt-pkg/contrib/progress.cc +apt-pkg/contrib/strutl.cc +apt-pkg/rpm/rpmfactory.cc +apt-pkg/rpm/rpminit.cc +apt-pkg/rpm/rpmlistparser.cc +apt-pkg/rpm/rpmpackagedata.cc +apt-pkg/rpm/rpmpm.cc +apt-pkg/rpm/rpmsrcrecords.cc +apt-pkg/sourcelist.cc +apt-pkg/srcrecords.cc +apt-pkg/systemfactory.cc +apt-pkg/tagfile.cc diff --git a/apt/po/apt.pot b/apt/po/apt.pot new file mode 100644 index 0000000..e9c2172 --- /dev/null +++ b/apt/po/apt.pot @@ -0,0 +1,1474 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR Free Software Foundation, Inc. +# FIRST AUTHOR , YEAR. +# +#, fuzzy +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2001-01-10 13:40-0200\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME \n" +"Language-Team: LANGUAGE \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" + +#. Yes/No +#: cmdline/apt-get.cc:129 +msgid "Y" +msgstr "" + +#: cmdline/apt-get.cc:129 +msgid "y" +msgstr "" + +#: cmdline/apt-get.cc:215 +msgid "Sorry, but the following packages have unmet dependencies:" +msgstr "" + +#: cmdline/apt-get.cc:275 +msgid " but " +msgstr "" + +#: cmdline/apt-get.cc:278 +msgid " is installed" +msgstr "" + +#: cmdline/apt-get.cc:278 +msgid " is to be installed" +msgstr "" + +#: cmdline/apt-get.cc:284 +msgid "it is not installable" +msgstr "" + +#: cmdline/apt-get.cc:286 +msgid "it is a virtual package" +msgstr "" + +#: cmdline/apt-get.cc:289 +msgid "it is not installed" +msgstr "" + +#: cmdline/apt-get.cc:289 +msgid "it is not going to be installed" +msgstr "" + +#: cmdline/apt-get.cc:294 +msgid " or" +msgstr "" + +#: cmdline/apt-get.cc:320 +msgid "The following NEW packages will be installed:" +msgstr "" + +#: cmdline/apt-get.cc:343 +msgid "The following packages will be REMOVED:" +msgstr "" + +#: cmdline/apt-get.cc:363 +msgid "The following packages have been kept back" +msgstr "" + +#: cmdline/apt-get.cc:383 +msgid "The following packages will be upgraded" +msgstr "" + +#: cmdline/apt-get.cc:415 +msgid "The following packages can be upgraded:" +msgstr "" + +#: cmdline/apt-get.cc:426 +msgid " from " +msgstr "" + +#: cmdline/apt-get.cc:427 +msgid " to " +msgstr "" + +#: cmdline/apt-get.cc:429 +msgid " Importance: " +msgstr "" + +#: cmdline/apt-get.cc:430 +msgid " Date: " +msgstr "" + +#: cmdline/apt-get.cc:450 +msgid "The following held packages will be changed:" +msgstr "" + +#: cmdline/apt-get.cc:500 +#, c-format +msgid "%s (due to %s) " +msgstr "" + +#: cmdline/apt-get.cc:508 +msgid "WARNING: The following essential packages will be removed" +msgstr "" + +#: cmdline/apt-get.cc:509 +msgid "This should NOT be done unless you know exactly what you are doing!" +msgstr "" + +#: cmdline/apt-get.cc:531 +msgid " packages upgraded, " +msgstr "" + +#: cmdline/apt-get.cc:532 +msgid " newly installed, " +msgstr "" + +#: cmdline/apt-get.cc:534 +msgid " reinstalled, " +msgstr "" + +#: cmdline/apt-get.cc:535 +msgid " to remove and " +msgstr "" + +#: cmdline/apt-get.cc:536 +msgid " not upgraded." +msgstr "" + +#: cmdline/apt-get.cc:539 +msgid " packages not fully installed or removed." +msgstr "" + +#: apt-pkg/pkgrecords.cc:36 cmdline/apt-cache.cc:364 cmdline/apt-cache.cc:970 +#: cmdline/apt-cache.cc:1005 cmdline/apt-get.cc:555 +#, c-format +msgid "Package file %s is out of sync." +msgstr "" + +#: cmdline/apt-get.cc:672 +msgid "Correcting dependencies..." +msgstr "" + +#: cmdline/apt-get.cc:675 +msgid " failed." +msgstr "" + +#: cmdline/apt-get.cc:678 +msgid "Unable to correct dependencies" +msgstr "" + +#: cmdline/apt-get.cc:681 +msgid "Unable to minimize the upgrade set" +msgstr "" + +#: cmdline/apt-get.cc:683 +msgid " Done" +msgstr "" + +#: cmdline/apt-get.cc:687 +msgid "You might want to run `apt-get -f install' to correct these." +msgstr "" + +#: cmdline/apt-get.cc:690 +msgid "Unmet dependencies. Try using -f." +msgstr "" + +#: cmdline/apt-get.cc:743 +msgid "Internal Error, InstallPackages was called with broken packages!" +msgstr "" + +#: cmdline/apt-get.cc:752 +msgid "Packages need to be removed but No Remove was specified." +msgstr "" + +#: cmdline/apt-get.cc:762 +msgid "Internal Error, Ordering didn't finish" +msgstr "" + +#: cmdline/apt-get.cc:777 cmdline/apt-get.cc:1536 cmdline/apt-get.cc:1569 +msgid "Unable to lock the download directory" +msgstr "" + +#: apt-pkg/cachefile.cc:73 cmdline/apt-get.cc:787 cmdline/apt-get.cc:1619 +msgid "The list of sources could not be read." +msgstr "" + +#: cmdline/apt-get.cc:804 +msgid "How odd.. The sizes didn't match, email apt@packages.debian.org" +msgstr "" + +#. Number of bytes +#: cmdline/apt-get.cc:808 cmdline/apt-get.cc:1752 +msgid "Need to get " +msgstr "" + +#: cmdline/apt-get.cc:814 +msgid " of archives. After unpacking " +msgstr "" + +#: cmdline/apt-get.cc:818 +msgid "B will be used." +msgstr "" + +#: cmdline/apt-get.cc:820 +msgid "B will be freed." +msgstr "" + +#: cmdline/apt-get.cc:832 cmdline/apt-get.cc:1745 +#, c-format +msgid "Couldn't determine free space in %s" +msgstr "" + +#: cmdline/apt-get.cc:835 +#, c-format +msgid "Sorry, you don't have enough free space in %s to hold all packages." +msgstr "" + +#: cmdline/apt-get.cc:844 +msgid "There are problems and -y was used without --force-yes" +msgstr "" + +#: cmdline/apt-get.cc:850 cmdline/apt-get.cc:867 +msgid "Trivial Only specified but this is not a trivial operation." +msgstr "" + +#: cmdline/apt-get.cc:852 +msgid "You are about to do something potentially harmful" +msgstr "" + +#: cmdline/apt-get.cc:853 +msgid "To continue type in the phrase 'Yes, I understand this may be bad'" +msgstr "" + +#: cmdline/apt-get.cc:854 +msgid " ?] " +msgstr "" + +#: cmdline/apt-get.cc:855 +msgid "Yes, I understand this may be bad" +msgstr "" + +#: cmdline/apt-get.cc:857 cmdline/apt-get.cc:876 +msgid "Aborted." +msgstr "" + +#: cmdline/apt-get.cc:872 +msgid "Do you want to continue? [Y/n] " +msgstr "" + +#: cmdline/apt-get.cc:936 cmdline/apt-get.cc:1196 cmdline/apt-get.cc:1788 +msgid "Failed to fetch " +msgstr "" + +#: cmdline/apt-get.cc:954 +msgid "Some files failed to download" +msgstr "" + +#: cmdline/apt-get.cc:960 +msgid "Unable to fetch some archives, maybe try with --fix-missing?" +msgstr "" + +#: cmdline/apt-get.cc:964 +msgid "--fix-missing and media swapping is not currently supported" +msgstr "" + +#: cmdline/apt-get.cc:969 +msgid "Unable to correct missing packages." +msgstr "" + +#: cmdline/apt-get.cc:970 +msgid "Aborting Install." +msgstr "" + +#: cmdline/apt-get.cc:1001 +msgid "Note, selecting " +msgstr "" + +#: cmdline/apt-get.cc:1001 +msgid " instead of " +msgstr "" + +#: cmdline/apt-get.cc:1010 +msgid "Skipping " +msgstr "" + +#: cmdline/apt-get.cc:1010 +msgid ", it is already installed and no-upgrade is set." +msgstr "" + +#: cmdline/apt-get.cc:1020 +#, c-format +msgid "Package %s is not installed" +msgstr "" + +#: cmdline/apt-cache.cc:116 cmdline/apt-get.cc:1030 cmdline/apt-get.cc:1050 +msgid "Package " +msgstr "" + +#: cmdline/apt-get.cc:1030 +msgid " is a virtual package provided by:" +msgstr "" + +#: cmdline/apt-get.cc:1041 +msgid " [Installed]" +msgstr "" + +#: cmdline/apt-get.cc:1046 +msgid "You should explicitly select one to install." +msgstr "" + +#: cmdline/apt-get.cc:1050 +msgid " has no available version, but exists in the database." +msgstr "" + +#: cmdline/apt-get.cc:1051 +msgid "" +"This typically means that the package was mentioned in a dependency and " +msgstr "" + +#: cmdline/apt-get.cc:1052 +msgid "" +"never uploaded, has been obsoleted or is not available with the contents " +msgstr "" + +#: cmdline/apt-get.cc:1053 +msgid "of sources.list" +msgstr "" + +#: cmdline/apt-get.cc:1064 +msgid "However the following packages replace it:" +msgstr "" + +#: cmdline/apt-get.cc:1067 +#, c-format +msgid "Package %s has no installation candidate" +msgstr "" + +#: cmdline/apt-get.cc:1087 +msgid "Sorry, re-installation of " +msgstr "" + +#: cmdline/apt-get.cc:1087 +msgid " is not possible, it cannot be downloaded" +msgstr "" + +#: cmdline/apt-get.cc:1094 +msgid "Sorry, " +msgstr "" + +#: cmdline/apt-get.cc:1094 +msgid " is already the newest version" +msgstr "" + +#: cmdline/apt-get.cc:1123 +msgid "Unable to lock the list directory" +msgstr "" + +#: cmdline/apt-get.cc:1148 +msgid "Could not retrieve digitally signed hash file" +msgstr "" + +#: cmdline/apt-get.cc:1160 +msgid "Failed to fetch hash file: " +msgstr "" + +#: cmdline/apt-get.cc:1168 +msgid "" +"Some of the signed hash files could not be retrieved. Aborting operation." +msgstr "" + +#: cmdline/apt-get.cc:1210 +msgid "Some of the index files had mismatching MD5 sums!" +msgstr "" + +#: cmdline/apt-get.cc:1218 +msgid "" +"Some index files failed to download, they have been ignored, or old ones " +"used instead." +msgstr "" + +#: cmdline/apt-get.cc:1223 +msgid " will not be authenticated." +msgstr "" + +#: cmdline/apt-get.cc:1244 +msgid "Internal Error, AllUpgrade broke stuff" +msgstr "" + +#: cmdline/apt-get.cc:1313 cmdline/apt-get.cc:1346 +#, c-format +msgid "Couldn't find package %s" +msgstr "" + +#: cmdline/apt-get.cc:1326 +msgid "Regex compilation error:" +msgstr "" + +#: cmdline/apt-get.cc:1360 +msgid "You might want to run `apt-get -f install' to correct these:" +msgstr "" + +#: cmdline/apt-get.cc:1363 +msgid "" +"Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a " +"solution)." +msgstr "" + +#: cmdline/apt-get.cc:1374 +msgid "Some packages could not be installed. This may mean that you have" +msgstr "" + +#: cmdline/apt-get.cc:1375 +msgid "requested an impossible situation or if you are using the unstable" +msgstr "" + +#: cmdline/apt-get.cc:1376 +msgid "distribution that some required packages have not yet been created" +msgstr "" + +#: cmdline/apt-get.cc:1377 +msgid "or been moved out of Incoming." +msgstr "" + +#: cmdline/apt-get.cc:1381 +msgid "Since you only requested a single operation it is extremely likely that" +msgstr "" + +#: cmdline/apt-get.cc:1382 +msgid "the package is simply not installable and a bug report against" +msgstr "" + +#: cmdline/apt-get.cc:1383 +msgid "that package should be filed." +msgstr "" + +#: cmdline/apt-get.cc:1386 +msgid "The following information may help to resolve the situation:" +msgstr "" + +#: cmdline/apt-get.cc:1389 +msgid "Sorry, broken packages" +msgstr "" + +#: cmdline/apt-get.cc:1412 +msgid "The following extra packages will be installed:" +msgstr "" + +#: cmdline/apt-get.cc:1431 +msgid "Calculating Upgrade... " +msgstr "" + +#: cmdline/apt-get.cc:1434 +msgid "Failed" +msgstr "" + +#: cmdline/apt-get.cc:1439 +msgid "Done" +msgstr "" + +#: cmdline/apt-get.cc:1504 cmdline/apt-get.cc:1512 +msgid "Internal Error, problem resolver broke stuff" +msgstr "" + +#: cmdline/apt-get.cc:1614 +msgid "Must specify at least one package to fetch source for" +msgstr "" + +#: cmdline/apt-get.cc:1688 +#, c-format +msgid "Unable to find a source package for %s" +msgstr "" + +#: cmdline/apt-get.cc:1748 +#, c-format +msgid "Sorry, you don't have enough free space in %s" +msgstr "" + +#: cmdline/apt-get.cc:1757 +msgid " of source archives." +msgstr "" + +#: cmdline/apt-get.cc:1762 +msgid "Fetch Source " +msgstr "" + +#: cmdline/apt-get.cc:1793 +msgid "Failed to fetch some archives." +msgstr "" + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1859 +msgid "Build command '" +msgstr "" + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1842 cmdline/apt-get.cc:1859 +msgid "' failed." +msgstr "" + +#: cmdline/apt-get.cc:1831 +msgid "Skipping unpack of already unpacked source in " +msgstr "" + +#: cmdline/apt-get.cc:1842 +msgid "Unpack command '" +msgstr "" + +#: cmdline/apt-get.cc:1875 +msgid "Couldn't wait for subprocess" +msgstr "" + +#: cmdline/apt-get.cc:1879 +msgid "Child process failed" +msgstr "" + +#: cmdline/apt-get.cc:1895 +msgid "Usage: apt-get [options] command" +msgstr "" + +#: cmdline/apt-get.cc:1896 +msgid " apt-get [options] install pkg1 [pkg2 ...]" +msgstr "" + +#: cmdline/apt-get.cc:1898 +msgid "apt-get is a simple command line interface for downloading and" +msgstr "" + +#: cmdline/apt-get.cc:1899 +msgid "installing packages. The most frequently used commands are update" +msgstr "" + +#: cmdline/apt-get.cc:1900 +msgid "and install." +msgstr "" + +#: cmdline/apt-cache.cc:1203 cmdline/apt-cdrom.cc:864 cmdline/apt-config.cc:79 +#: cmdline/apt-get.cc:1902 +msgid "Commands:" +msgstr "" + +#: cmdline/apt-get.cc:1903 +msgid " update - Retrieve new lists of packages" +msgstr "" + +#: cmdline/apt-get.cc:1904 +msgid " upgrade - Perform an upgrade" +msgstr "" + +#: cmdline/apt-get.cc:1905 +msgid " install - Install new packages" +msgstr "" + +#: cmdline/apt-get.cc:1906 +msgid " remove - Remove packages" +msgstr "" + +#: cmdline/apt-get.cc:1907 +msgid " source - Download source archives" +msgstr "" + +#: cmdline/apt-get.cc:1908 +msgid " dist-upgrade - Distribution upgrade, see apt-get(8)" +msgstr "" + +#. cout << " dselect-upgrade - Follow dselect selections" << endl; +#: cmdline/apt-get.cc:1910 +msgid " clean - Erase downloaded archive files" +msgstr "" + +#: cmdline/apt-get.cc:1911 +msgid " autoclean - Erase old downloaded archive files" +msgstr "" + +#: cmdline/apt-get.cc:1912 +msgid " check - Verify that there are no broken dependencies" +msgstr "" + +#: cmdline/apt-cache.cc:1218 cmdline/apt-cdrom.cc:867 cmdline/apt-config.cc:83 +#: cmdline/apt-get.cc:1914 +msgid "Options:" +msgstr "" + +#: cmdline/apt-get.cc:1915 +msgid " -h This help text." +msgstr "" + +#: cmdline/apt-get.cc:1916 +msgid " -q Loggable output - no progress indicator" +msgstr "" + +#: cmdline/apt-get.cc:1917 +msgid " -qq No output except for errors" +msgstr "" + +#: cmdline/apt-get.cc:1918 +msgid " -S Show summary for upgrade operation and quit" +msgstr "" + +#: cmdline/apt-get.cc:1919 +msgid " -d Download only - do NOT install or unpack archives" +msgstr "" + +#: cmdline/apt-get.cc:1920 +msgid " -s No-act. Perform ordering simulation" +msgstr "" + +#: cmdline/apt-get.cc:1921 +msgid " -y Assume Yes to all queries and do not prompt" +msgstr "" + +#: cmdline/apt-get.cc:1922 +msgid " -f Attempt to continue if the integrity check fails" +msgstr "" + +#: cmdline/apt-get.cc:1923 +msgid " -m Attempt to continue if archives are unlocatable" +msgstr "" + +#: cmdline/apt-get.cc:1924 +msgid " -u Show a list of upgraded packages as well" +msgstr "" + +#: cmdline/apt-get.cc:1925 +msgid " -b Build the source package after fetching it" +msgstr "" + +#: cmdline/apt-cache.cc:1224 cmdline/apt-cdrom.cc:874 cmdline/apt-config.cc:85 +#: cmdline/apt-get.cc:1926 +msgid " -c=? Read this configuration file" +msgstr "" + +#: cmdline/apt-cache.cc:1225 cmdline/apt-cdrom.cc:875 cmdline/apt-config.cc:86 +#: cmdline/apt-get.cc:1927 +msgid " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" +msgstr "" + +#: cmdline/apt-get.cc:1928 +msgid "See the apt-get(8), sources.list(5) and apt.conf(5) manual" +msgstr "" + +#: cmdline/apt-get.cc:1929 +msgid "pages for more information and options." +msgstr "" + +#: cmdline/apt-cdrom.cc:76 cmdline/apt-cdrom.cc:144 cmdline/apt-cdrom.cc:189 +#: cmdline/apt-cdrom.cc:258 +#, c-format +msgid "Unable to change to %s" +msgstr "" + +#: apt-pkg/clean.cc:38 cmdline/apt-cdrom.cc:88 cmdline/apt-cdrom.cc:221 +#, c-format +msgid "Unable to read %s" +msgstr "" + +#: cmdline/apt-cdrom.cc:451 cmdline/apt-cdrom.cc:507 +#, c-format +msgid "Failed to open %s.new" +msgstr "" + +#: cmdline/apt-cdrom.cc:478 cmdline/apt-cdrom.cc:605 +#, c-format +msgid "Failed to rename %s.new to %s" +msgstr "" + +#: cmdline/apt-cdrom.cc:552 cmdline/apt-cdrom.cc:586 cmdline/apt-cdrom.cc:806 +#: cmdline/apt-cdrom.cc:824 +msgid "Internal error" +msgstr "" + +#: cmdline/apt-cdrom.cc:650 +msgid "Using CD-ROM mount point " +msgstr "" + +#: cmdline/apt-cdrom.cc:658 +#, c-format +msgid "Unable to read the cdrom database %s" +msgstr "" + +#: cmdline/apt-cdrom.cc:665 +msgid "Unmounting CD-ROM" +msgstr "" + +#. Mount the new CDROM +#: cmdline/apt-cdrom.cc:669 +msgid "Please insert a Disc in the drive and press enter" +msgstr "" + +#: cmdline/apt-cdrom.cc:670 +msgid "Mounting CD-ROM" +msgstr "" + +#: cmdline/apt-cdrom.cc:672 +msgid "Failed to mount the cdrom." +msgstr "" + +#. Hash the CD to get an ID +#: cmdline/apt-cdrom.cc:676 +msgid "Identifying.. " +msgstr "" + +#: cmdline/apt-cdrom.cc:686 +msgid "Scanning Disc for index files.. " +msgstr "" + +#: cmdline/apt-cdrom.cc:702 +msgid "I found (binary):" +msgstr "" + +#: cmdline/apt-cdrom.cc:705 +msgid "I found (source):" +msgstr "" + +#: cmdline/apt-cdrom.cc:718 +msgid "Found " +msgstr "" + +#: cmdline/apt-cdrom.cc:718 +msgid " package indexes and " +msgstr "" + +#: cmdline/apt-cdrom.cc:719 +msgid " source indexes." +msgstr "" + +#: cmdline/apt-cdrom.cc:724 +msgid "Unable to locate any package files, perhaps this is not a Debian Disc" +msgstr "" + +#: cmdline/apt-cdrom.cc:726 +msgid "" +"Unable to locate any package files, perhaps this is not a Conectiva Disc" +msgstr "" + +#: cmdline/apt-cdrom.cc:743 +msgid "Found label '" +msgstr "" + +#: cmdline/apt-cdrom.cc:751 +msgid "Please provide a name for this Disc, such as 'MyDistro 6.0 Disk 1'" +msgstr "" + +#: cmdline/apt-cdrom.cc:761 +msgid "That is not a valid name, try again " +msgstr "" + +#: cmdline/apt-cdrom.cc:775 +msgid "This Disc is called:" +msgstr "" + +#: cmdline/apt-cdrom.cc:794 +msgid "Writing new source list" +msgstr "" + +#. Print the sourcelist entries +#: cmdline/apt-cdrom.cc:801 +msgid "Source List entries for this Disc are:" +msgstr "" + +#: cmdline/apt-cdrom.cc:838 +msgid "Repeat this process for the rest of the CDs in your set." +msgstr "" + +#: cmdline/apt-cdrom.cc:858 +msgid "Usage: apt-cdrom [options] command" +msgstr "" + +#: cmdline/apt-cdrom.cc:860 +msgid "apt-cdrom is a tool to add CDROM's to APT's source list. The " +msgstr "" + +#: cmdline/apt-cdrom.cc:861 +msgid "CDROM mount point and device information is taken from apt.conf" +msgstr "" + +#: cmdline/apt-cdrom.cc:862 +msgid "and /etc/fstab." +msgstr "" + +#: cmdline/apt-cdrom.cc:865 +msgid " add - Add a CDROM" +msgstr "" + +#: cmdline/apt-cdrom.cc:868 +msgid " -h This help text" +msgstr "" + +#: cmdline/apt-cdrom.cc:869 +msgid " -d CD-ROM mount point" +msgstr "" + +#: cmdline/apt-cdrom.cc:870 +msgid " -r Rename a recognized CD-ROM" +msgstr "" + +#: cmdline/apt-cdrom.cc:871 +msgid " -m No mounting" +msgstr "" + +#: cmdline/apt-cdrom.cc:872 +msgid " -f Fast mode, don't check package files" +msgstr "" + +#: cmdline/apt-cdrom.cc:873 +msgid " -a Thorough scan mode" +msgstr "" + +#: cmdline/apt-cdrom.cc:876 +msgid "See fstab(5)" +msgstr "" + +#: cmdline/apt-cache.cc:116 +msgid " version " +msgstr "" + +#: cmdline/apt-cache.cc:117 +msgid " has an unmet dep:" +msgstr "" + +#: cmdline/apt-cache.cc:156 cmdline/apt-cache.cc:410 cmdline/apt-cache.cc:534 +#: cmdline/apt-cache.cc:1089 +#, c-format +msgid "Unable to locate package %s" +msgstr "" + +#: cmdline/apt-cache.cc:160 cmdline/apt-cache.cc:320 +msgid "Package: " +msgstr "" + +#: cmdline/apt-cache.cc:161 +msgid "Versions: " +msgstr "" + +#: cmdline/apt-cache.cc:172 +msgid "Reverse Depends: " +msgstr "" + +#: cmdline/apt-cache.cc:176 +msgid "Dependencies: " +msgstr "" + +#: cmdline/apt-cache.cc:185 cmdline/apt-cache.cc:926 +msgid "Provides: " +msgstr "" + +#: cmdline/apt-cache.cc:193 +msgid "Reverse Provides: " +msgstr "" + +#: cmdline/apt-cache.cc:207 +msgid "Total Package Names : " +msgstr "" + +#: cmdline/apt-cache.cc:247 +msgid " Normal Packages: " +msgstr "" + +#: cmdline/apt-cache.cc:248 +msgid " Pure Virtual Packages: " +msgstr "" + +#: cmdline/apt-cache.cc:249 +msgid " Single Virtual Packages: " +msgstr "" + +#: cmdline/apt-cache.cc:250 +msgid " Mixed Virtual Packages: " +msgstr "" + +#: cmdline/apt-cache.cc:251 +msgid " Missing: " +msgstr "" + +#: cmdline/apt-cache.cc:253 +msgid "Total Distinct Versions: " +msgstr "" + +#: cmdline/apt-cache.cc:255 +msgid "Total Dependencies: " +msgstr "" + +#: cmdline/apt-cache.cc:258 +msgid "Total Ver/File relations: " +msgstr "" + +#: cmdline/apt-cache.cc:260 +msgid "Total Provides Mappings: " +msgstr "" + +#: cmdline/apt-cache.cc:272 +msgid "Total Globbed Strings: " +msgstr "" + +#: cmdline/apt-cache.cc:277 +msgid "Total Slack space: " +msgstr "" + +#: cmdline/apt-cache.cc:285 +msgid "Total Space Accounted for: " +msgstr "" + +#: cmdline/apt-cache.cc:300 +msgid "Bad section " +msgstr "" + +#: cmdline/apt-cache.cc:306 +msgid "Bad prio " +msgstr "" + +#: cmdline/apt-cache.cc:323 cmdline/apt-cache.cc:339 +msgid " Version: " +msgstr "" + +#: cmdline/apt-cache.cc:324 +msgid " File: " +msgstr "" + +#: cmdline/apt-cache.cc:326 +msgid " Depends: " +msgstr "" + +#: cmdline/apt-cache.cc:332 +msgid "File: " +msgstr "" + +#: cmdline/apt-cache.cc:333 +msgid " Size: " +msgstr "" + +#: cmdline/apt-cache.cc:334 +msgid " ID: " +msgstr "" + +#: cmdline/apt-cache.cc:335 +msgid " Flags: " +msgstr "" + +#: cmdline/apt-cache.cc:336 +msgid " Time: " +msgstr "" + +#: cmdline/apt-cache.cc:337 +msgid " Archive: " +msgstr "" + +#: cmdline/apt-cache.cc:338 +msgid " Component: " +msgstr "" + +#: cmdline/apt-cache.cc:340 +msgid " Origin: " +msgstr "" + +#: cmdline/apt-cache.cc:341 +msgid " Label: " +msgstr "" + +#: cmdline/apt-cache.cc:342 +msgid " Architecture: " +msgstr "" + +#: cmdline/apt-cache.cc:669 +msgid "You must give at least one file name" +msgstr "" + +#: cmdline/apt-cache.cc:688 +msgid "Generating cache" +msgstr "" + +#: apt-pkg/systemfactory.cc:188 cmdline/apt-cache.cc:696 +#, c-format +msgid "Problem opening %s" +msgstr "" + +#: cmdline/apt-cache.cc:699 +msgid "Problem with SelectFile" +msgstr "" + +#: cmdline/apt-cache.cc:702 +msgid "Problem with MergeList" +msgstr "" + +#: cmdline/apt-cache.cc:806 +msgid "Oh shit!" +msgstr "" + +#: cmdline/apt-cache.cc:841 +#, c-format +msgid "Package: %s\n" +msgstr "" + +#: cmdline/apt-cache.cc:844 +#, c-format +msgid "Section: %s\n" +msgstr "" + +#: cmdline/apt-cache.cc:847 +#, c-format +msgid "Installed Size: %i\n" +msgstr "" + +#: cmdline/apt-cache.cc:854 +#, c-format +msgid "Maintainer: %s\n" +msgstr "" + +#: cmdline/apt-cache.cc:858 +#, c-format +msgid "Version: %i:%s" +msgstr "" + +#: cmdline/apt-cache.cc:860 +#, c-format +msgid "Version: %s" +msgstr "" + +#: cmdline/apt-cache.cc:894 +msgid "Pre-Depends: " +msgstr "" + +#: cmdline/apt-cache.cc:907 +msgid "Depends: " +msgstr "" + +#: cmdline/apt-cache.cc:920 +msgid "Conflicts: " +msgstr "" + +#: cmdline/apt-cache.cc:932 +msgid "Obsoletes: " +msgstr "" + +#: cmdline/apt-cache.cc:937 +#, c-format +msgid "Architecture: %s\n" +msgstr "" + +#: cmdline/apt-cache.cc:940 +#, c-format +msgid "Size: %d\n" +msgstr "" + +#: cmdline/apt-cache.cc:943 +#, c-format +msgid "MD5sum: %s\n" +msgstr "" + +#: cmdline/apt-cache.cc:946 +#, c-format +msgid "Filename: %s\n" +msgstr "" + +#: cmdline/apt-cache.cc:949 +#, c-format +msgid "Description: %s\n" +msgstr "" + +#: cmdline/apt-cache.cc:1038 +msgid "You must give exactly one pattern" +msgstr "" + +#: cmdline/apt-cache.cc:1044 +msgid "Regex compilation error" +msgstr "" + +#: cmdline/apt-cache.cc:1195 +msgid "Usage: apt-cache [options] command" +msgstr "" + +#: cmdline/apt-cache.cc:1196 +msgid " apt-cache [options] add file1 [file1 ...]" +msgstr "" + +#: cmdline/apt-cache.cc:1197 +msgid " apt-cache [options] showpkg pkg1 [pkg2 ...]" +msgstr "" + +#: cmdline/apt-cache.cc:1199 +msgid "apt-cache is a low-level tool used to manipulate APT's binary" +msgstr "" + +#: cmdline/apt-cache.cc:1200 +msgid "cache files stored in " +msgstr "" + +#: cmdline/apt-cache.cc:1201 +msgid "It is not meant for ordinary use only as a debug aide." +msgstr "" + +#: cmdline/apt-cache.cc:1204 +msgid " add - Add an package file to the source cache" +msgstr "" + +#: cmdline/apt-cache.cc:1205 +msgid " gencaches - Build both the package and source cache" +msgstr "" + +#: cmdline/apt-cache.cc:1206 +msgid " showpkg - Show some general information for a single package" +msgstr "" + +#: cmdline/apt-cache.cc:1207 +msgid " stats - Show some basic statistics" +msgstr "" + +#: cmdline/apt-cache.cc:1208 +msgid " dump - Show the entire file in a terse form" +msgstr "" + +#: cmdline/apt-cache.cc:1209 +msgid " dumpavail - Print an available file to stdout" +msgstr "" + +#: cmdline/apt-cache.cc:1210 +msgid " unmet - Show unmet dependencies" +msgstr "" + +#: cmdline/apt-cache.cc:1211 +msgid " check - Check the cache a bit" +msgstr "" + +#: cmdline/apt-cache.cc:1212 +msgid " search - Search the package list for a regex pattern" +msgstr "" + +#: cmdline/apt-cache.cc:1213 +msgid " show - Show a readable record for the package" +msgstr "" + +#: cmdline/apt-cache.cc:1214 +msgid " depends - Show raw dependency information for a package" +msgstr "" + +#: cmdline/apt-cache.cc:1215 +msgid " pkgnames - List the names of all packages" +msgstr "" + +#: cmdline/apt-cache.cc:1216 +msgid " dotty - Generate package graphs for GraphVis" +msgstr "" + +#: cmdline/apt-cache.cc:1219 cmdline/apt-config.cc:84 +msgid " -h This help text." +msgstr "" + +#: cmdline/apt-cache.cc:1220 +msgid " -p=? The package cache. [" +msgstr "" + +#: cmdline/apt-cache.cc:1221 +msgid " -s=? The source cache. [" +msgstr "" + +#: cmdline/apt-cache.cc:1222 +msgid " -q Disable progress indicator." +msgstr "" + +#: cmdline/apt-cache.cc:1223 +msgid " -i Show only important deps for the unmet command." +msgstr "" + +#: cmdline/apt-cache.cc:1226 +msgid "See the apt-cache(8) and apt.conf(5) manual pages for more information." +msgstr "" + +#: cmdline/apt-config.cc:37 +msgid "Arguments not in pairs" +msgstr "" + +#: cmdline/apt-config.cc:75 +msgid "Usage: apt-config [options] command" +msgstr "" + +#: cmdline/apt-config.cc:77 +msgid "apt-config is a simple tool to read the APT config file" +msgstr "" + +#: cmdline/apt-config.cc:80 +msgid " shell - Shell mode" +msgstr "" + +#: cmdline/apt-config.cc:81 +msgid " dump - Show the configuration" +msgstr "" + +#: apt-pkg/acquire-item.cc:142 +#, c-format +msgid "Size of %s did not match what's in the hashfile and was redownloaded." +msgstr "" + +#: apt-pkg/acquire-item.cc:154 +#, c-format +msgid "MD5 of %s did not match what's int the hashfile and was redownloaded." +msgstr "" + +#: apt-pkg/acquire-item.cc:426 +msgid "Hashfile signer is not who it's supposed to be (expected " +msgstr "" + +#: apt-pkg/acquire-item.cc:428 +msgid ", got " +msgstr "" + +#: apt-pkg/acquire-worker.cc:108 +#, c-format +msgid "The method driver %s could not be found." +msgstr "" + +#: apt-pkg/acquire-worker.cc:117 +msgid "Failed to create IPC pipe to subprocess" +msgstr "" + +#: apt-pkg/acquire-worker.cc:160 +#, c-format +msgid "Method %s did not start correctly" +msgstr "" + +#: apt-pkg/acquire-worker.cc:197 +#, c-format +msgid "Invalid message from method %s: %s" +msgstr "" + +#: apt-pkg/acquire-worker.cc:210 +#, c-format +msgid "Unable to process Capabilities message from %s" +msgstr "" + +#: apt-pkg/acquire-worker.cc:229 +msgid "Method gave invalid 200 URI Start message" +msgstr "" + +#: apt-pkg/acquire-worker.cc:268 +#, c-format +msgid "Bizzar Error - File size is not what the server reported %s %u" +msgstr "" + +#: apt-pkg/acquire-worker.cc:297 +msgid "Method gave invalid 400 URI Failure message" +msgstr "" + +#: apt-pkg/acquire-worker.cc:319 +#, c-format +msgid "Method %s General failure: %s" +msgstr "" + +#: apt-pkg/acquire-worker.cc:503 +#, c-format +msgid "Method %s has died unexpectedly!" +msgstr "" + +#: apt-pkg/acquire.cc:58 +#, c-format +msgid "Lists directory %spartial is missing." +msgstr "" + +#: apt-pkg/acquire.cc:62 +#, c-format +msgid "Archive directory %spartial is missing." +msgstr "" + +#: apt-pkg/acquire.cc:557 +msgid "Tried to dequeue a fetching object" +msgstr "" + +#: apt-pkg/cachefile.cc:83 +msgid "The package lists or status file could not be parsed or opened." +msgstr "" + +#: apt-pkg/cachefile.cc:85 +msgid "You may want to run apt-get update to correct these missing files" +msgstr "" + +#: apt-pkg/clean.cc:44 +msgid "Unable to change to " +msgstr "" + +#: apt-pkg/clean.cc:58 +#, c-format +msgid "Unable to stat %s." +msgstr "" + +#: apt-pkg/depcache.cc:61 apt-pkg/depcache.cc:90 +msgid "Building Dependency Tree" +msgstr "" + +#: apt-pkg/depcache.cc:62 +msgid "Candidate Versions" +msgstr "" + +#: apt-pkg/depcache.cc:91 +msgid "Dependency Generation" +msgstr "" + +#: apt-pkg/packagemanager.cc:397 +#, c-format +msgid "" +"This installation run will require temporarily removing the essential " +"package %s due to a Conflicts/Pre-Depends loop. This is often bad, but if " +"you really want to do it, activate the APT::Force-LoopBreak option." +msgstr "" + +#: apt-pkg/pkgcache.cc:125 +msgid "The package cache file is corrupted" +msgstr "" + +#: apt-pkg/pkgcache.cc:130 +msgid "The package cache file is an incompatible version" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:90 +#, c-format +msgid "Error occured while processing %s (NewPackage)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:102 +#, c-format +msgid "Error occured while processing %s (UsePackage1)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:124 +#, c-format +msgid "Error occured while processing %s (UsePackage2)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:127 +#, c-format +msgid "Error occured while processing %s (NewFileVer1)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "WARNING: '" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "' has 2 packages with same version but different dependencies. " +msgstr "" + +#: apt-pkg/pkgcachegen.cc:139 +msgid "That usually means a packaging bug." +msgstr "" + +#: apt-pkg/pkgcachegen.cc:158 +#, c-format +msgid "Error occured while processing %s (NewVersion1)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:161 +#, c-format +msgid "Error occured while processing %s (UsePackage3)" +msgstr "" + +#: apt-pkg/pkgcachegen.cc:164 +#, c-format +msgid "Error occured while processing %s (NewVersion2)" +msgstr "" + +#: apt-pkg/sourcelist.cc:76 +#, c-format +msgid "Block %s is invalid" +msgstr "" + +#: apt-pkg/sourcelist.cc:121 +#, c-format +msgid "Malformed line %u in source list %s (type)" +msgstr "" + +#: apt-pkg/sourcelist.cc:123 apt-pkg/sourcelist.cc:135 +#, c-format +msgid "Malformed line %u in source list %s (URI)" +msgstr "" + +#: apt-pkg/sourcelist.cc:130 +#, c-format +msgid "Malformed line %u in source list %s (vendor ID)" +msgstr "" + +#: apt-pkg/sourcelist.cc:141 +#, c-format +msgid "Malformed line %u in source list %s (dist)" +msgstr "" + +#: apt-pkg/sourcelist.cc:145 +#, c-format +msgid "Malformed line %u in source list %s (bad vendor ID)" +msgstr "" + +#: apt-pkg/sourcelist.cc:148 +#, c-format +msgid "Malformed line %u in source list %s (bad type)" +msgstr "" + +#: apt-pkg/sourcelist.cc:151 +#, c-format +msgid "Malformed line %u in source list %s (bad URI)" +msgstr "" + +#: apt-pkg/sourcelist.cc:161 +#, c-format +msgid "Malformed line %u in source list %s (Absolute dist)" +msgstr "" + +#: apt-pkg/sourcelist.cc:174 +#, c-format +msgid "Malformed line %u in source list %s (dist parse)" +msgstr "" + +#: apt-pkg/sourcelist.cc:353 +msgid "could not open hash index" +msgstr "" + +#: apt-pkg/sourcelist.cc:363 +msgid "No MD5SUM data in hashfile" +msgstr "" + +#: apt-pkg/sourcelist.cc:377 +msgid "Error parsing MD5 hash record" +msgstr "" + +#: apt-pkg/sourcelist.cc:400 +#, c-format +msgid "" +"Repository entry in sources.list contains extra components that are not " +"listed in the signed hash file: %s" +msgstr "" + +#: apt-pkg/srcrecords.cc:47 +msgid "Sorry, you must put some 'source' uris in your sources.list" +msgstr "" + +#: apt-pkg/systemfactory.cc:72 +#, c-format +msgid "Failed to rename %s to %s" +msgstr "" + +#: apt-pkg/systemfactory.cc:77 +#, c-format +msgid "Couldn't stat source package list '%s' (%s)" +msgstr "" + +#. Mostly from MakeStatusCache.. +#: apt-pkg/systemfactory.cc:184 apt-pkg/systemfactory.cc:240 +#: apt-pkg/systemfactory.cc:272 apt-pkg/systemfactory.cc:273 +#: apt-pkg/systemfactory.cc:280 apt-pkg/systemfactory.cc:350 +#: apt-pkg/systemfactory.cc:386 +msgid "Reading Package Lists" +msgstr "" + +#: apt-pkg/systemfactory.cc:196 +#, c-format +msgid "Problem with SelectFile %s" +msgstr "" + +#: apt-pkg/systemfactory.cc:201 +#, c-format +msgid "Problem with MergeList %s" +msgstr "" + +#: apt-pkg/systemfactory.cc:263 +msgid "IO Error saving source cache" +msgstr "" + +#: apt-pkg/tagfile.cc:59 +#, c-format +msgid "Unable to parse package file %s (1)" +msgstr "" + +#: apt-pkg/tagfile.cc:142 +#, c-format +msgid "Unable to parse package file %s (2)" +msgstr "" diff --git a/apt/po/cat-id-tbl.c b/apt/po/cat-id-tbl.c new file mode 100644 index 0000000..224fe8c --- /dev/null +++ b/apt/po/cat-id-tbl.c @@ -0,0 +1,367 @@ +/* Automatically generated by po2tbl.sed from apt.pot. */ + +#if HAVE_CONFIG_H +# include +#endif + +#include "libgettext.h" + +const struct _msg_ent _msg_tbl[] = { + {"", 1}, + {"Y", 2}, + {"y", 3}, + {"Sorry, but the following packages have unmet dependencies:", 4}, + {" but ", 5}, + {" is installed", 6}, + {" is to be installed", 7}, + {"it is not installable", 8}, + {"it is a virtual package", 9}, + {"it is not installed", 10}, + {"it is not going to be installed", 11}, + {" or", 12}, + {"The following NEW packages will be installed:", 13}, + {"The following packages will be REMOVED:", 14}, + {"The following packages have been kept back", 15}, + {"The following packages will be upgraded", 16}, + {"The following packages can be upgraded:", 17}, + {" from ", 18}, + {" to ", 19}, + {" Importance: ", 20}, + {" Date: ", 21}, + {"The following held packages will be changed:", 22}, + {"%s (due to %s) ", 23}, + {"WARNING: The following essential packages will be removed", 24}, + {"This should NOT be done unless you know exactly what you are doing!", 25}, + {" packages upgraded, ", 26}, + {" newly installed, ", 27}, + {" reinstalled, ", 28}, + {" to remove and ", 29}, + {" not upgraded.", 30}, + {" packages not fully installed or removed.", 31}, + {"Package file %s is out of sync.", 32}, + {"Correcting dependencies...", 33}, + {" failed.", 34}, + {"Unable to correct dependencies", 35}, + {"Unable to minimize the upgrade set", 36}, + {" Done", 37}, + {"You might want to run `apt-get -f install' to correct these.", 38}, + {"Unmet dependencies. Try using -f.", 39}, + {"Internal Error, InstallPackages was called with broken packages!", 40}, + {"Packages need to be removed but No Remove was specified.", 41}, + {"Internal Error, Ordering didn't finish", 42}, + {"Unable to lock the download directory", 43}, + {"The list of sources could not be read.", 44}, + {"How odd.. The sizes didn't match, email apt@packages.debian.org", 45}, + {"Need to get ", 46}, + {" of archives. After unpacking ", 47}, + {"B will be used.", 48}, + {"B will be freed.", 49}, + {"Couldn't determine free space in %s", 50}, + {"Sorry, you don't have enough free space in %s to hold all packages.", 51}, + {"There are problems and -y was used without --force-yes", 52}, + {"Trivial Only specified but this is not a trivial operation.", 53}, + {"You are about to do something potentially harmful", 54}, + {"To continue type in the phrase 'Yes, I understand this may be bad'", 55}, + {" ?] ", 56}, + {"Yes, I understand this may be bad", 57}, + {"Aborted.", 58}, + {"Do you want to continue? [Y/n] ", 59}, + {"Failed to fetch ", 60}, + {"Some files failed to download", 61}, + {"Unable to fetch some archives, maybe try with --fix-missing?", 62}, + {"--fix-missing and media swapping is not currently supported", 63}, + {"Unable to correct missing packages.", 64}, + {"Aborting Install.", 65}, + {"Note, selecting ", 66}, + {" instead of ", 67}, + {"Skipping ", 68}, + {", it is already installed and no-upgrade is set.", 69}, + {"Package %s is not installed", 70}, + {"Package ", 71}, + {" is a virtual package provided by:", 72}, + {" [Installed]", 73}, + {"You should explicitly select one to install.", 74}, + {" has no available version, but exists in the database.", 75}, + {"\ +This typically means that the package was mentioned in a dependency and ", 76}, + {"\ +never uploaded, has been obsoleted or is not available with the contents ", 77}, + {"of sources.list", 78}, + {"However the following packages replace it:", 79}, + {"Package %s has no installation candidate", 80}, + {"Sorry, re-installation of ", 81}, + {" is not possible, it cannot be downloaded", 82}, + {"Sorry, ", 83}, + {" is already the newest version", 84}, + {"Unable to lock the list directory", 85}, + {"Could not retrieve digitally signed hash file", 86}, + {"Failed to fetch hash file: ", 87}, + {"\ +Some of the signed hash files could not be retrieved. Aborting operation.", 88}, + {"Some of the index files had mismatching MD5 sums!", 89}, + {"\ +Some index files failed to download, they have been ignored, or old ones \ +used instead.", 90}, + {" will not be authenticated.", 91}, + {"Internal Error, AllUpgrade broke stuff", 92}, + {"Couldn't find package %s", 93}, + {"Regex compilation error:", 94}, + {"You might want to run `apt-get -f install' to correct these:", 95}, + {"\ +Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a \ +solution).", 96}, + {"Some packages could not be installed. This may mean that you have", 97}, + {"requested an impossible situation or if you are using the unstable", 98}, + {"distribution that some required packages have not yet been created", 99}, + {"or been moved out of Incoming.", 100}, + {"Since you only requested a single operation it is extremely likely that", 101}, + {"the package is simply not installable and a bug report against", 102}, + {"that package should be filed.", 103}, + {"The following information may help to resolve the situation:", 104}, + {"Sorry, broken packages", 105}, + {"The following extra packages will be installed:", 106}, + {"Calculating Upgrade... ", 107}, + {"Failed", 108}, + {"Done", 109}, + {"Internal Error, problem resolver broke stuff", 110}, + {"Must specify at least one package to fetch source for", 111}, + {"Unable to find a source package for %s", 112}, + {"Sorry, you don't have enough free space in %s", 113}, + {" of source archives.", 114}, + {"Fetch Source ", 115}, + {"Failed to fetch some archives.", 116}, + {"Build command '", 117}, + {"' failed.", 118}, + {"Skipping unpack of already unpacked source in ", 119}, + {"Unpack command '", 120}, + {"Couldn't wait for subprocess", 121}, + {"Child process failed", 122}, + {"Usage: apt-get [options] command", 123}, + {" apt-get [options] install pkg1 [pkg2 ...]", 124}, + {"apt-get is a simple command line interface for downloading and", 125}, + {"installing packages. The most frequently used commands are update", 126}, + {"and install.", 127}, + {"Commands:", 128}, + {" update - Retrieve new lists of packages", 129}, + {" upgrade - Perform an upgrade", 130}, + {" install - Install new packages", 131}, + {" remove - Remove packages", 132}, + {" source - Download source archives", 133}, + {" dist-upgrade - Distribution upgrade, see apt-get(8)", 134}, + {" clean - Erase downloaded archive files", 135}, + {" autoclean - Erase old downloaded archive files", 136}, + {" check - Verify that there are no broken dependencies", 137}, + {"Options:", 138}, + {" -h This help text.", 139}, + {" -q Loggable output - no progress indicator", 140}, + {" -qq No output except for errors", 141}, + {" -S Show summary for upgrade operation and quit", 142}, + {" -d Download only - do NOT install or unpack archives", 143}, + {" -s No-act. Perform ordering simulation", 144}, + {" -y Assume Yes to all queries and do not prompt", 145}, + {" -f Attempt to continue if the integrity check fails", 146}, + {" -m Attempt to continue if archives are unlocatable", 147}, + {" -u Show a list of upgraded packages as well", 148}, + {" -b Build the source package after fetching it", 149}, + {" -c=? Read this configuration file", 150}, + {" -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp", 151}, + {"See the apt-get(8), sources.list(5) and apt.conf(5) manual", 152}, + {"pages for more information and options.", 153}, + {"Unable to change to %s", 154}, + {"Unable to read %s", 155}, + {"Failed to open %s.new", 156}, + {"Failed to rename %s.new to %s", 157}, + {"Internal error", 158}, + {"Using CD-ROM mount point ", 159}, + {"Unable to read the cdrom database %s", 160}, + {"Unmounting CD-ROM", 161}, + {"Please insert a Disc in the drive and press enter", 162}, + {"Mounting CD-ROM", 163}, + {"Failed to mount the cdrom.", 164}, + {"Identifying.. ", 165}, + {"Scanning Disc for index files.. ", 166}, + {"I found (binary):", 167}, + {"I found (source):", 168}, + {"Found ", 169}, + {" package indexes and ", 170}, + {" source indexes.", 171}, + {"Unable to locate any package files, perhaps this is not a Debian Disc", 172}, + {"\ +Unable to locate any package files, perhaps this is not a Conectiva Disc", 173}, + {"Found label '", 174}, + {"Please provide a name for this Disc, such as 'MyDistro 6.0 Disk 1'", 175}, + {"That is not a valid name, try again ", 176}, + {"This Disc is called:", 177}, + {"Writing new source list", 178}, + {"Source List entries for this Disc are:", 179}, + {"Repeat this process for the rest of the CDs in your set.", 180}, + {"Usage: apt-cdrom [options] command", 181}, + {"apt-cdrom is a tool to add CDROM's to APT's source list. The ", 182}, + {"CDROM mount point and device information is taken from apt.conf", 183}, + {"and /etc/fstab.", 184}, + {" add - Add a CDROM", 185}, + {" -h This help text", 186}, + {" -d CD-ROM mount point", 187}, + {" -r Rename a recognized CD-ROM", 188}, + {" -m No mounting", 189}, + {" -f Fast mode, don't check package files", 190}, + {" -a Thorough scan mode", 191}, + {"See fstab(5)", 192}, + {" version ", 193}, + {" has an unmet dep:", 194}, + {"Unable to locate package %s", 195}, + {"Package: ", 196}, + {"Versions: ", 197}, + {"Reverse Depends: ", 198}, + {"Dependencies: ", 199}, + {"Provides: ", 200}, + {"Reverse Provides: ", 201}, + {"Total Package Names : ", 202}, + {" Normal Packages: ", 203}, + {" Pure Virtual Packages: ", 204}, + {" Single Virtual Packages: ", 205}, + {" Mixed Virtual Packages: ", 206}, + {" Missing: ", 207}, + {"Total Distinct Versions: ", 208}, + {"Total Dependencies: ", 209}, + {"Total Ver/File relations: ", 210}, + {"Total Provides Mappings: ", 211}, + {"Total Globbed Strings: ", 212}, + {"Total Slack space: ", 213}, + {"Total Space Accounted for: ", 214}, + {"Bad section ", 215}, + {"Bad prio ", 216}, + {" Version: ", 217}, + {" File: ", 218}, + {" Depends: ", 219}, + {"File: ", 220}, + {" Size: ", 221}, + {" ID: ", 222}, + {" Flags: ", 223}, + {" Time: ", 224}, + {" Archive: ", 225}, + {" Component: ", 226}, + {" Origin: ", 227}, + {" Label: ", 228}, + {" Architecture: ", 229}, + {"You must give at least one file name", 230}, + {"Generating cache", 231}, + {"Problem opening %s", 232}, + {"Problem with SelectFile", 233}, + {"Problem with MergeList", 234}, + {"Oh shit!", 235}, + {"Package: %s\n", 236}, + {"Section: %s\n", 237}, + {"Installed Size: %i\n", 238}, + {"Maintainer: %s\n", 239}, + {"Version: %i:%s", 240}, + {"Version: %s", 241}, + {"Pre-Depends: ", 242}, + {"Depends: ", 243}, + {"Conflicts: ", 244}, + {"Obsoletes: ", 245}, + {"Architecture: %s\n", 246}, + {"Size: %d\n", 247}, + {"MD5sum: %s\n", 248}, + {"Filename: %s\n", 249}, + {"Description: %s\n", 250}, + {"You must give exactly one pattern", 251}, + {"Regex compilation error", 252}, + {"Usage: apt-cache [options] command", 253}, + {" apt-cache [options] add file1 [file1 ...]", 254}, + {" apt-cache [options] showpkg pkg1 [pkg2 ...]", 255}, + {"apt-cache is a low-level tool used to manipulate APT's binary", 256}, + {"cache files stored in ", 257}, + {"It is not meant for ordinary use only as a debug aide.", 258}, + {" add - Add an package file to the source cache", 259}, + {" gencaches - Build both the package and source cache", 260}, + {" showpkg - Show some general information for a single package", 261}, + {" stats - Show some basic statistics", 262}, + {" dump - Show the entire file in a terse form", 263}, + {" dumpavail - Print an available file to stdout", 264}, + {" unmet - Show unmet dependencies", 265}, + {" check - Check the cache a bit", 266}, + {" search - Search the package list for a regex pattern", 267}, + {" show - Show a readable record for the package", 268}, + {" depends - Show raw dependency information for a package", 269}, + {" pkgnames - List the names of all packages", 270}, + {" dotty - Generate package graphs for GraphVis", 271}, + {" -h This help text.", 272}, + {" -p=? The package cache. [", 273}, + {" -s=? The source cache. [", 274}, + {" -q Disable progress indicator.", 275}, + {" -i Show only important deps for the unmet command.", 276}, + {"See the apt-cache(8) and apt.conf(5) manual pages for more information.", 277}, + {"Arguments not in pairs", 278}, + {"Usage: apt-config [options] command", 279}, + {"apt-config is a simple tool to read the APT config file", 280}, + {" shell - Shell mode", 281}, + {" dump - Show the configuration", 282}, + {"Size of %s did not match what's in the hashfile and was redownloaded.", 283}, + {"MD5 of %s did not match what's int the hashfile and was redownloaded.", 284}, + {"Hashfile signer is not who it's supposed to be (expected ", 285}, + {", got ", 286}, + {"The method driver %s could not be found.", 287}, + {"Failed to create IPC pipe to subprocess", 288}, + {"Method %s did not start correctly", 289}, + {"Invalid message from method %s: %s", 290}, + {"Unable to process Capabilities message from %s", 291}, + {"Method gave invalid 200 URI Start message", 292}, + {"Bizzar Error - File size is not what the server reported %s %u", 293}, + {"Method gave invalid 400 URI Failure message", 294}, + {"Method %s General failure: %s", 295}, + {"Method %s has died unexpectedly!", 296}, + {"Lists directory %spartial is missing.", 297}, + {"Archive directory %spartial is missing.", 298}, + {"Tried to dequeue a fetching object", 299}, + {"The package lists or status file could not be parsed or opened.", 300}, + {"You may want to run apt-get update to correct these missing files", 301}, + {"Unable to change to ", 302}, + {"Unable to stat %s.", 303}, + {"Building Dependency Tree", 304}, + {"Candidate Versions", 305}, + {"Dependency Generation", 306}, + {"\ +This installation run will require temporarily removing the essential \ +package %s due to a Conflicts/Pre-Depends loop. This is often bad, but if \ +you really want to do it, activate the APT::Force-LoopBreak option.", 307}, + {"The package cache file is corrupted", 308}, + {"The package cache file is an incompatible version", 309}, + {"Error occured while processing %s (NewPackage)", 310}, + {"Error occured while processing %s (UsePackage1)", 311}, + {"Error occured while processing %s (UsePackage2)", 312}, + {"Error occured while processing %s (NewFileVer1)", 313}, + {"WARNING: '", 314}, + {"' has 2 packages with same version but different dependencies. ", 315}, + {"That usually means a packaging bug.", 316}, + {"Error occured while processing %s (NewVersion1)", 317}, + {"Error occured while processing %s (UsePackage3)", 318}, + {"Error occured while processing %s (NewVersion2)", 319}, + {"Block %s is invalid", 320}, + {"Malformed line %u in source list %s (type)", 321}, + {"Malformed line %u in source list %s (URI)", 322}, + {"Malformed line %u in source list %s (vendor ID)", 323}, + {"Malformed line %u in source list %s (dist)", 324}, + {"Malformed line %u in source list %s (bad vendor ID)", 325}, + {"Malformed line %u in source list %s (bad type)", 326}, + {"Malformed line %u in source list %s (bad URI)", 327}, + {"Malformed line %u in source list %s (Absolute dist)", 328}, + {"Malformed line %u in source list %s (dist parse)", 329}, + {"could not open hash index", 330}, + {"No MD5SUM data in hashfile", 331}, + {"Error parsing MD5 hash record", 332}, + {"\ +Repository entry in sources.list contains extra components that are not \ +listed in the signed hash file: %s", 333}, + {"Sorry, you must put some 'source' uris in your sources.list", 334}, + {"Failed to rename %s to %s", 335}, + {"Couldn't stat source package list '%s' (%s)", 336}, + {"Reading Package Lists", 337}, + {"Problem with SelectFile %s", 338}, + {"Problem with MergeList %s", 339}, + {"IO Error saving source cache", 340}, + {"Unable to parse package file %s (1)", 341}, + {"Unable to parse package file %s (2)", 342}, +}; + +int _msg_tbl_length = 342; diff --git a/apt/po/es_ES.po b/apt/po/es_ES.po new file mode 100644 index 0000000..6483db6 --- /dev/null +++ b/apt/po/es_ES.po @@ -0,0 +1,1478 @@ +# Spanish messages for apt. +# Copyright (C) 2000 Free Software Foundation, Inc. +# Andrea Mara Pimenta Alonso , 2000. +# +msgid "" +msgstr "" +"Project-Id-Version: apt\n" +"POT-Creation-Date: 2001-01-10 13:40-0200\n" +"PO-Revision-Date: 2001-01-11 15:40-02:00\n" +"Last-Translator: Jorge Carrasquilla Soares \n" +"Language-Team: Spanish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8 bit\n" + +#. Yes/No +#: cmdline/apt-get.cc:129 +msgid "Y" +msgstr "S" + +#: cmdline/apt-get.cc:129 +msgid "y" +msgstr "s" + +#: cmdline/apt-get.cc:215 +msgid "Sorry, but the following packages have unmet dependencies:" +msgstr "Los paquetes siguientes tienen dependencias no resueltas:" + +#: cmdline/apt-get.cc:275 +msgid " but " +msgstr " pero " + +#: cmdline/apt-get.cc:278 +msgid " is installed" +msgstr " estб instalado" + +#: cmdline/apt-get.cc:278 +msgid " is to be installed" +msgstr "se instalarб" + +#: cmdline/apt-get.cc:284 +msgid "it is not installable" +msgstr "no se puede instalar" + +#: cmdline/apt-get.cc:286 +msgid "it is a virtual package" +msgstr "es un paquete virtual" + +#: cmdline/apt-get.cc:289 +msgid "it is not installed" +msgstr "no estб instalado" + +#: cmdline/apt-get.cc:289 +msgid "it is not going to be installed" +msgstr "no serб instalado" + +#: cmdline/apt-get.cc:294 +msgid " or" +msgstr " o" + +#: cmdline/apt-get.cc:320 +msgid "The following NEW packages will be installed:" +msgstr "Se instalarбn los paquetes NUEVOS siguientes:" + +#: cmdline/apt-get.cc:343 +msgid "The following packages will be REMOVED:" +msgstr "Se ELIMINARБN los siguientes paquetes:" + +#: cmdline/apt-get.cc:363 +msgid "The following packages have been kept back" +msgstr "Se han manetenido los siguientes paquetes" + +#: cmdline/apt-get.cc:383 +msgid "The following packages will be upgraded" +msgstr "Se actualizarбn los siguientes paquetes" + +#: cmdline/apt-get.cc:415 +msgid "The following packages can be upgraded:" +msgstr "Los siguientes paquetes pueden ser actualizados:" + +#: cmdline/apt-get.cc:426 +msgid " from " +msgstr " de " + +#: cmdline/apt-get.cc:427 +msgid " to " +msgstr " para " + +#: cmdline/apt-get.cc:429 +msgid " Importance: " +msgstr " Importancia: " + +#: cmdline/apt-get.cc:430 +msgid " Date: " +msgstr " Fecha: " + +#: cmdline/apt-get.cc:450 +msgid "The following held packages will be changed:" +msgstr "Los siguientes paquetes serбn alterados:" + +#: cmdline/apt-get.cc:500 +#, c-format +msgid "%s (due to %s) " +msgstr "%s (debido a %s) " + +#: cmdline/apt-get.cc:508 +msgid "WARNING: The following essential packages will be removed" +msgstr "AVISO: Los siguientes paquetes esenciales se eliminarбn" + +#: cmdline/apt-get.cc:509 +msgid "This should NOT be done unless you know exactly what you are doing!" +msgstr "ЎEsto NO debe hacerse, a menos que usted sepa exactamente lo que estб haciendo!" + +#: cmdline/apt-get.cc:531 +msgid " packages upgraded, " +msgstr " paquetes actualizados, " + +#: cmdline/apt-get.cc:532 +msgid " newly installed, " +msgstr " instalados recientemente, " + +#: cmdline/apt-get.cc:534 +msgid " reinstalled, " +msgstr " reinstalados, " + +#: cmdline/apt-get.cc:535 +msgid " to remove and " +msgstr " a eliminar y " + +#: cmdline/apt-get.cc:536 +msgid " not upgraded." +msgstr " no actualizados." + +#: cmdline/apt-get.cc:539 +msgid " packages not fully installed or removed." +msgstr " paquetes no instalados o eliminados totalmente." + +#: apt-pkg/pkgrecords.cc:36 cmdline/apt-cache.cc:364 cmdline/apt-cache.cc:970 +#: cmdline/apt-cache.cc:1005 cmdline/apt-get.cc:555 +#, c-format +msgid "Package file %s is out of sync." +msgstr "El paquete %s no estб sincronizado." + +#: cmdline/apt-get.cc:672 +msgid "Correcting dependencies..." +msgstr "Corrigiendo dependencias..." + +#: cmdline/apt-get.cc:675 +msgid " failed." +msgstr " fallу." + +#: cmdline/apt-get.cc:678 +msgid "Unable to correct dependencies" +msgstr "Imposible corregir dependencias" + +#: cmdline/apt-get.cc:681 +msgid "Unable to minimize the upgrade set" +msgstr "Imposible minimizar el grupo de actualizaciуn" + +#: cmdline/apt-get.cc:683 +msgid " Done" +msgstr " Hecho" + +#: cmdline/apt-get.cc:687 +msgid "You might want to run `apt-get -f install' to correct these." +msgstr "Tal vez quiera ejecutar `apt-get -f install' para corregirlos." + +#: cmdline/apt-get.cc:690 +msgid "Unmet dependencies. Try using -f." +msgstr "Dependencias no resueltas. Pruebe usar -f." + +#: cmdline/apt-get.cc:743 +msgid "Internal Error, InstallPackages was called with broken packages!" +msgstr "Error interno, ЎInstallPackages fue llamado con paquetes rotos!" + +#: cmdline/apt-get.cc:752 +msgid "Packages need to be removed but No Remove was specified." +msgstr "Deben eliminarse algunos paquetes, sin embargo, estб especificado No Eliminar." + +#: cmdline/apt-get.cc:762 +msgid "Internal Error, Ordering didn't finish" +msgstr "Error interno, la ordenaciуn no ha terminado" + +#: cmdline/apt-get.cc:777 cmdline/apt-get.cc:1536 cmdline/apt-get.cc:1569 +msgid "Unable to lock the download directory" +msgstr "Imposible bloquear el directorio para descargas" + +#: apt-pkg/cachefile.cc:73 cmdline/apt-get.cc:787 cmdline/apt-get.cc:1619 +msgid "The list of sources could not be read." +msgstr "No se puede leer la lista de fuentes." + +#: cmdline/apt-get.cc:804 +msgid "How odd.. The sizes didn't match, email apt@packages.debian.org" +msgstr "Quй estraсo... Los tamaсos no son iguales, envнe un mensaje para apt@packages.debian.org" + +#. Number of bytes +#: cmdline/apt-get.cc:808 cmdline/apt-get.cc:1752 +msgid "Need to get " +msgstr "Se necesita conseguir " + +#: cmdline/apt-get.cc:814 +msgid " of archives. After unpacking " +msgstr " para los archivos. Despuйs de desempaquetar, " + +#: cmdline/apt-get.cc:818 +msgid "B will be used." +msgstr "B serбn usados." + +#: cmdline/apt-get.cc:820 +msgid "B will be freed." +msgstr "B serбn liberados." + +#: cmdline/apt-get.cc:832 cmdline/apt-get.cc:1745 +#, c-format +msgid "Couldn't determine free space in %s" +msgstr "No se puede determinar el espacio libre en %s" + +#: cmdline/apt-get.cc:835 +#, c-format +msgid "Sorry, you don't have enough free space in %s to hold all packages." +msgstr "Lo siento, no tiene espacio libre suficiente en %s para contener todos los paquetes." + +#: cmdline/apt-get.cc:844 +msgid "There are problems and -y was used without --force-yes" +msgstr "Hay algunos problemas, por eso se usу -y sin --force-yes" + +#: cmdline/apt-get.cc:850 cmdline/apt-get.cc:867 +msgid "Trivial Only specified but this is not a trivial operation." +msgstr "Se especificу `Sуlo trivial', pero йsta no es una operaciуn trivial." + +#: cmdline/apt-get.cc:852 +msgid "You are about to do something potentially harmful" +msgstr "Estб a punto de cometer un acto potencialmente daсino" + +#: cmdline/apt-get.cc:853 +msgid "To continue type in the phrase 'Yes, I understand this may be bad'" +msgstr "Para continuar teclee la frase 'Sн, ya sй que esto puede ser malo'" + +#: cmdline/apt-get.cc:854 +msgid " ?] " +msgstr " ?] " + +#: cmdline/apt-get.cc:855 +msgid "Yes, I understand this may be bad" +msgstr "Sн, ya sй que esto puede ser malo" + +#: cmdline/apt-get.cc:857 cmdline/apt-get.cc:876 +msgid "Aborted." +msgstr "Terminado." + +#: cmdline/apt-get.cc:872 +msgid "Do you want to continue? [Y/n] " +msgstr "їQuiere continuar? [S/n] " + +#: cmdline/apt-get.cc:936 cmdline/apt-get.cc:1196 cmdline/apt-get.cc:1788 +msgid "Failed to fetch " +msgstr "Fallу en la carga " + +#: cmdline/apt-get.cc:954 +msgid "Some files failed to download" +msgstr "Hubo un fallo al descargar algunos archivos" + +#: cmdline/apt-get.cc:960 +msgid "Unable to fetch some archives, maybe try with --fix-missing?" +msgstr "Imposible cargar algunos archivos, їintentar quizбs con --fix-missing?" + +#: cmdline/apt-get.cc:964 +msgid "--fix-missing and media swapping is not currently supported" +msgstr "actualmente no se soporta --fix-missing e intercambio de soporte fнsico" + +#: cmdline/apt-get.cc:969 +msgid "Unable to correct missing packages." +msgstr "Imposible corregir los paquetes perdidos." + +#: cmdline/apt-get.cc:970 +msgid "Aborting Install." +msgstr "Interrumpiendo instalaciуn." + +#: cmdline/apt-get.cc:1001 +msgid "Note, selecting " +msgstr "Nota, seleccionando " + +#: cmdline/apt-get.cc:1001 +msgid " instead of " +msgstr " en lugar de " + +#: cmdline/apt-get.cc:1010 +msgid "Skipping " +msgstr "Omitiendo " + +#: cmdline/apt-get.cc:1010 +msgid ", it is already installed and no-upgrade is set." +msgstr ", ya estб instalado y la opciуn no-upgrade estб habilitada." + +#: cmdline/apt-get.cc:1020 +#, c-format +msgid "Package %s is not installed" +msgstr "El paquete %s no estб instalado" + +#: cmdline/apt-cache.cc:116 cmdline/apt-get.cc:1030 cmdline/apt-get.cc:1050 +msgid "Package " +msgstr "Paquete " + +#: cmdline/apt-get.cc:1030 +msgid " is a virtual package provided by:" +msgstr " es un paquete virtual suministrado por:" + +#: cmdline/apt-get.cc:1041 +msgid " [Installed]" +msgstr " [Instalado]" + +#: cmdline/apt-get.cc:1046 +msgid "You should explicitly select one to install." +msgstr "Deberнa explicitar uno para instalarlo." + +#: cmdline/apt-get.cc:1050 +msgid " has no available version, but exists in the database." +msgstr " no tiene versiуn disponible, aunque existe en la base de datos." + +#: cmdline/apt-get.cc:1051 +msgid "" +"This typically means that the package was mentioned in a dependency and " +msgstr "Esto significa que se mencionу el paquete en una dependencia y " + +#: cmdline/apt-get.cc:1052 +msgid "" +"never uploaded, has been obsoleted or is not available with the contents " +msgstr "nunca fue cargado, se ha vuelto obsoleto o no estб disponible con tales contenidos" + +#: cmdline/apt-get.cc:1053 +msgid "of sources.list" +msgstr "de sources.list" + +#: cmdline/apt-get.cc:1064 +msgid "However the following packages replace it:" +msgstr "No obstante, los siguientes paquetes lo sustituyen:" + +#: cmdline/apt-get.cc:1067 +#, c-format +msgid "Package %s has no installation candidate" +msgstr "El paquete %s no tiene candidato a instalaciуn" + +#: cmdline/apt-get.cc:1087 +msgid "Sorry, re-installation of " +msgstr "Lo siento, la reinstalaciуn de " + +#: cmdline/apt-get.cc:1087 +msgid " is not possible, it cannot be downloaded" +msgstr " no es posible, no se puede descargarlo" + +#: cmdline/apt-get.cc:1094 +msgid "Sorry, " +msgstr "Lo siento, " + +#: cmdline/apt-get.cc:1094 +msgid " is already the newest version" +msgstr " ya es la versiуn mбs nueva" + +#: cmdline/apt-get.cc:1123 +msgid "Unable to lock the list directory" +msgstr "Imposible bloquear el directorio de lista" + +#: cmdline/apt-get.cc:1148 +msgid "Could not retrieve digitally signed hash file" +msgstr "No fue posible recuperar el archivo hash con firma digital" + +#: cmdline/apt-get.cc:1160 +msgid "Failed to fetch hash file: " +msgstr "Fallу al cargar el archivo hash:" + +#: cmdline/apt-get.cc:1168 +msgid "" +"Some of the signed hash files could not be retrieved. Aborting operation." +msgstr "No se pudieron recuperar algunos de los archivos hash firmados. Terminando operaciуn." + +#: cmdline/apt-get.cc:1210 +msgid "Some of the index files had mismatching MD5 sums!" +msgstr "ЎAlgunos de los archivos de нndice tenнan sus sumas MD5 diferentes!" + +#: cmdline/apt-get.cc:1218 +msgid "" +"Some index files failed to download, they have been ignored, or old ones " +"used instead." +msgstr "Hubo un fallo al descargar algunos archivos de нndice. Se han ignorado o se han usado los antiguos." + +#: cmdline/apt-get.cc:1223 +msgid " will not be authenticated." +msgstr "no se autenticarб." + +#: cmdline/apt-get.cc:1244 +msgid "Internal Error, AllUpgrade broke stuff" +msgstr "Error interno en el AllUpgrade" + +#: cmdline/apt-get.cc:1313 cmdline/apt-get.cc:1346 +#, c-format +msgid "Couldn't find package %s" +msgstr "No se encontrу el paquete %s" + +#: cmdline/apt-get.cc:1326 +msgid "Regex compilation error:" +msgstr "Error al compilar expresiones regulares:" + +#: cmdline/apt-get.cc:1360 +msgid "You might want to run `apt-get -f install' to correct these:" +msgstr "Tal vez quiera ejecutar `apt-get -f install' para corregirlos:" + +#: cmdline/apt-get.cc:1363 +msgid "" +"Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a " +"solution)." +msgstr "Dependencias no resueltas. Intente 'apt-get -f install' sin paquetes (o especifique una soluciуn)." + +#: cmdline/apt-get.cc:1374 +msgid "Some packages could not be installed. This may mean that you have" +msgstr "Algunos paquetes no se pudieron instalar. Esto puede significar que usted" + +#: cmdline/apt-get.cc:1375 +msgid "requested an impossible situation or if you are using the unstable" +msgstr "solicitу una situaciуn imposible o si estб usando la distribuciуn" + +#: cmdline/apt-get.cc:1376 +msgid "distribution that some required packages have not yet been created" +msgstr "inestable, que algunos de los paquetes necesarios aъn no se crearon" + +#: cmdline/apt-get.cc:1377 +msgid "or been moved out of Incoming." +msgstr "o que se movieron de la Entrada." + +#: cmdline/apt-get.cc:1381 +msgid "Since you only requested a single operation it is extremely likely that" +msgstr "Como solicitу solamente una ъnica operaciуn, es muy probable que" + +#: cmdline/apt-get.cc:1382 +msgid "the package is simply not installable and a bug report against" +msgstr "el paquete simplemente no se pueda instalar y se deba informar" + +#: cmdline/apt-get.cc:1383 +msgid "that package should be filed." +msgstr "de un error acerca de este paquete." + +#: cmdline/apt-get.cc:1386 +msgid "The following information may help to resolve the situation:" +msgstr "La siguiente informaciуn puede ayudar a resolver la situaciуn:" + +#: cmdline/apt-get.cc:1389 +msgid "Sorry, broken packages" +msgstr "Lo siento, paquetes rotos" + +#: cmdline/apt-get.cc:1412 +msgid "The following extra packages will be installed:" +msgstr "Se instalarбn los siguientes paquetes extras: " + +#: cmdline/apt-get.cc:1431 +msgid "Calculating Upgrade... " +msgstr "Calculando actualizaciуn... " + +#: cmdline/apt-get.cc:1434 +msgid "Failed" +msgstr "Fallу" + +#: cmdline/apt-get.cc:1439 +msgid "Done" +msgstr "Hecho" + +#: cmdline/apt-get.cc:1504 cmdline/apt-get.cc:1512 +msgid "Internal Error, problem resolver broke stuff" +msgstr "Error interno en el solucionador de problemas" + +#: cmdline/apt-get.cc:1614 +msgid "Must specify at least one package to fetch source for" +msgstr "Debe especificar por lo menos un paquete del que buscar su fuente" + +#: cmdline/apt-get.cc:1688 +#, c-format +msgid "Unable to find a source package for %s" +msgstr "Imposible encontrar un paquete fuente para %s" + +#: cmdline/apt-get.cc:1748 +#, c-format +msgid "Sorry, you don't have enough free space in %s" +msgstr "Lo siento, no tiene suficiente espacio libre en %s" + +#: cmdline/apt-get.cc:1757 +msgid " of source archives." +msgstr " para archivos fuente." + +#: cmdline/apt-get.cc:1762 +msgid "Fetch Source " +msgstr "Cargar fuente" + +#: cmdline/apt-get.cc:1793 +msgid "Failed to fetch some archives." +msgstr "Fallo al traer algunos archivos." + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1859 +msgid "Build command '" +msgstr "Comando construir '" + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1842 cmdline/apt-get.cc:1859 +msgid "' failed." +msgstr "' fallу." + +#: cmdline/apt-get.cc:1831 +msgid "Skipping unpack of already unpacked source in " +msgstr "Omitiendo la operaciуn. Fuente ya desempaquetada en " + +#: cmdline/apt-get.cc:1842 +msgid "Unpack command '" +msgstr "Comando desempaquetar '" + +#: cmdline/apt-get.cc:1875 +msgid "Couldn't wait for subprocess" +msgstr "No se pudo esperar al subproceso" + +#: cmdline/apt-get.cc:1879 +msgid "Child process failed" +msgstr "Fallу el proceso hijo" + +#: cmdline/apt-get.cc:1895 +msgid "Usage: apt-get [options] command" +msgstr "Uso: apt-get [opciones] comando" + +#: cmdline/apt-get.cc:1896 +msgid " apt-get [options] install pkg1 [pkg2 ...]" +msgstr " apt-get [opciones] install pac1 [pac2 ...]" + +#: cmdline/apt-get.cc:1898 +msgid "apt-get is a simple command line interface for downloading and" +msgstr "apt-get es una interfaz de lнnea de comando simple para descargar e" + +#: cmdline/apt-get.cc:1899 +msgid "installing packages. The most frequently used commands are update" +msgstr "instalar paquetes. Los comandos usados con mбs frecuencia son update" + +#: cmdline/apt-get.cc:1900 +msgid "and install." +msgstr "e install." + +#: cmdline/apt-cache.cc:1203 cmdline/apt-cdrom.cc:864 cmdline/apt-config.cc:79 +#: cmdline/apt-get.cc:1902 +msgid "Commands:" +msgstr "Comandos:" + +#: cmdline/apt-get.cc:1903 +msgid " update - Retrieve new lists of packages" +msgstr " update - Recupera listas nuevas de paquetes" + +#: cmdline/apt-get.cc:1904 +msgid " upgrade - Perform an upgrade" +msgstr " upgrade - Realiza una actualizaciуn" + +#: cmdline/apt-get.cc:1905 +msgid " install - Install new packages" +msgstr " install - Instala nuevos paquetes" + +#: cmdline/apt-get.cc:1906 +msgid " remove - Remove packages" +msgstr " remove - Elimina paquetes" + +#: cmdline/apt-get.cc:1907 +msgid " source - Download source archives" +msgstr " source - Descarga archivos fuente" + +#: cmdline/apt-get.cc:1908 +msgid " dist-upgrade - Distribution upgrade, see apt-get(8)" +msgstr " dist-upgrade - Actualiza la distribuciуn, ver apt-get(8)" + +#. cout << " dselect-upgrade - Follow dselect selections" << endl; +#: cmdline/apt-get.cc:1910 +msgid " clean - Erase downloaded archive files" +msgstr " clean - Borra archivos descargados" + +#: cmdline/apt-get.cc:1911 +msgid " autoclean - Erase old downloaded archive files" +msgstr " autoclean - Borra archivos antiguos descargados" + +#: cmdline/apt-get.cc:1912 +msgid " check - Verify that there are no broken dependencies" +msgstr " check - Verifica si no hay dependencias" + +#: cmdline/apt-cache.cc:1218 cmdline/apt-cdrom.cc:867 cmdline/apt-config.cc:83 +#: cmdline/apt-get.cc:1914 +msgid "Options:" +msgstr "Opciones:" + +#: cmdline/apt-get.cc:1915 +msgid " -h This help text." +msgstr " -h Este texto de ayuda." + +#: cmdline/apt-get.cc:1916 +msgid " -q Loggable output - no progress indicator" +msgstr " -q Salida accesible - ningъn indicador de progreso" + +#: cmdline/apt-get.cc:1917 +msgid " -qq No output except for errors" +msgstr " -qq Sin mensajes, salvo para errores" + +#: cmdline/apt-get.cc:1918 +msgid " -S Show summary for upgrade operation and quit" +msgstr " -S Muestra sumario para la operaciуn de actualizaciуn y sale" + +#: cmdline/apt-get.cc:1919 +msgid " -d Download only - do NOT install or unpack archives" +msgstr " -d Sуlo download - NO instala ni desempaqueta archivos" + +#: cmdline/apt-get.cc:1920 +msgid " -s No-act. Perform ordering simulation" +msgstr " -s Ninguna acciуn. Ejecuta simulaciуn de ordenaciуn" + +#: cmdline/apt-get.cc:1921 +msgid " -y Assume Yes to all queries and do not prompt" +msgstr " -y Responder Sн a todas las preguntas y no mostrarlas" + +#: cmdline/apt-get.cc:1922 +msgid " -f Attempt to continue if the integrity check fails" +msgstr " -f Intenta continuar si falla la verificaciуn de integridad" + +#: cmdline/apt-get.cc:1923 +msgid " -m Attempt to continue if archives are unlocatable" +msgstr " -m Intenta continuar si no se pueden ubicar algunos archivos" + +#: cmdline/apt-get.cc:1924 +msgid " -u Show a list of upgraded packages as well" +msgstr " -u Exhibe una lista de paquetes actualizados" + +#: cmdline/apt-get.cc:1925 +msgid " -b Build the source package after fetching it" +msgstr " -b Construye el paquete fuente despuйs de cargarlo" + +#: cmdline/apt-cache.cc:1224 cmdline/apt-cdrom.cc:874 cmdline/apt-config.cc:85 +#: cmdline/apt-get.cc:1926 +msgid " -c=? Read this configuration file" +msgstr " -c=? Lee este archivo de configuraciуn" + +#: cmdline/apt-cache.cc:1225 cmdline/apt-cdrom.cc:875 cmdline/apt-config.cc:86 +#: cmdline/apt-get.cc:1927 +msgid " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" +msgstr " -o=? Define una opciуn de configuraciуn arbitraria, p.ex -o dir::cache=/tmp" + +#: cmdline/apt-get.cc:1928 +msgid "See the apt-get(8), sources.list(5) and apt.conf(5) manual" +msgstr "Consulte las manpages de apt-get(8), sources.list(5) y apt.conf(5)" + +#: cmdline/apt-get.cc:1929 +msgid "pages for more information and options." +msgstr "para mбs informaciуn y opciones." + +#: cmdline/apt-cdrom.cc:76 cmdline/apt-cdrom.cc:144 cmdline/apt-cdrom.cc:189 +#: cmdline/apt-cdrom.cc:258 +#, c-format +msgid "Unable to change to %s" +msgstr "Imposible alterar para %s" + +#: apt-pkg/clean.cc:38 cmdline/apt-cdrom.cc:88 cmdline/apt-cdrom.cc:221 +#, c-format +msgid "Unable to read %s" +msgstr "Imposible leer %s" + +#: cmdline/apt-cdrom.cc:451 cmdline/apt-cdrom.cc:507 +#, c-format +msgid "Failed to open %s.new" +msgstr "Fallу al abrir %s.new" + +#: cmdline/apt-cdrom.cc:478 cmdline/apt-cdrom.cc:605 +#, c-format +msgid "Failed to rename %s.new to %s" +msgstr "Fallу al cambiar el nombre de %s.new para %s" + +#: cmdline/apt-cdrom.cc:552 cmdline/apt-cdrom.cc:586 cmdline/apt-cdrom.cc:806 +#: cmdline/apt-cdrom.cc:824 +msgid "Internal error" +msgstr "Error interno" + +#: cmdline/apt-cdrom.cc:650 +msgid "Using CD-ROM mount point " +msgstr "Usando punto de montaje del CD-ROM " + +#: cmdline/apt-cdrom.cc:658 +#, c-format +msgid "Unable to read the cdrom database %s" +msgstr "Imposible leer la base de datos %s" + +#: cmdline/apt-cdrom.cc:665 +msgid "Unmounting CD-ROM" +msgstr "Desmontando el CD-ROM" + +#. Mount the new CDROM +#: cmdline/apt-cdrom.cc:669 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Inserte un disco en la unidad y presione intro" + +#: cmdline/apt-cdrom.cc:670 +msgid "Mounting CD-ROM" +msgstr "Montando CD-ROM" + +#: cmdline/apt-cdrom.cc:672 +msgid "Failed to mount the cdrom." +msgstr "Fallу al montar el CD-ROM." + +#. Hash the CD to get an ID +#: cmdline/apt-cdrom.cc:676 +msgid "Identifying.. " +msgstr "Identificando.. " + +#: cmdline/apt-cdrom.cc:686 +msgid "Scanning Disc for index files.. " +msgstr "Buscando archivos de нndice en el disco.. " + +#: cmdline/apt-cdrom.cc:702 +msgid "I found (binary):" +msgstr "Encontrado (binario):" + +#: cmdline/apt-cdrom.cc:705 +msgid "I found (source):" +msgstr "Encontrado (fuente):" + +#: cmdline/apt-cdrom.cc:718 +msgid "Found " +msgstr "Encontrado " + +#: cmdline/apt-cdrom.cc:718 +msgid " package indexes and " +msgstr " нndice de paquetes y " + +#: cmdline/apt-cdrom.cc:719 +msgid " source indexes." +msgstr " нndice de fuentes." + +#: cmdline/apt-cdrom.cc:724 +msgid "Unable to locate any package files, perhaps this is not a Debian Disc" +msgstr "No se pudo encontrar ningъn archivo de paquete, quizбs no sea un disco de Debian" + +#: cmdline/apt-cdrom.cc:726 +msgid "" +"Unable to locate any package files, perhaps this is not a Conectiva Disc" +msgstr "No se pudo encontrar ningъn archivo de paquete, quizбs no sea un disco Conectiva" + +#: cmdline/apt-cdrom.cc:743 +msgid "Found label '" +msgstr "Encontrada etiqueta '" + +#: cmdline/apt-cdrom.cc:751 +msgid "Please provide a name for this Disc, such as 'MyDistro 6.0 Disk 1'" +msgstr "Proporcione un nombre para este disco, como 'MiDistro 6.0 disco 1'" + +#: cmdline/apt-cdrom.cc:761 +msgid "That is not a valid name, try again " +msgstr "No es un nombre vбlido, intйntelo otra vez " + +#: cmdline/apt-cdrom.cc:775 +msgid "This Disc is called:" +msgstr "Este disco se denomina:" + +#: cmdline/apt-cdrom.cc:794 +msgid "Writing new source list" +msgstr "Grabando nueva lista fuente" + +#. Print the sourcelist entries +#: cmdline/apt-cdrom.cc:801 +msgid "Source List entries for this Disc are:" +msgstr "Las entradas de lista fuente para este disco son:" + +#: cmdline/apt-cdrom.cc:838 +msgid "Repeat this process for the rest of the CDs in your set." +msgstr "Repetir este proceso para el resto de los CDs." + +#: cmdline/apt-cdrom.cc:858 +msgid "Usage: apt-cdrom [options] command" +msgstr "Uso: apt-cdrom [opciones] comando" + +#: cmdline/apt-cdrom.cc:860 +msgid "apt-cdrom is a tool to add CDROM's to APT's source list. The " +msgstr "" +"apt-cdrom es una herramienta para aсadir la lista de fuentes del CD-ROM para " +"la de APT." + +#: cmdline/apt-cdrom.cc:861 +msgid "CDROM mount point and device information is taken from apt.conf" +msgstr "La informaciуn del punto de montaje y del dispositivo se obtienen a partir de apt.conf" + +#: cmdline/apt-cdrom.cc:862 +msgid "and /etc/fstab." +msgstr "y /etc/fstab." + +#: cmdline/apt-cdrom.cc:865 +msgid " add - Add a CDROM" +msgstr " add - Aсadir un CD-ROM" + +#: cmdline/apt-cdrom.cc:868 +msgid " -h This help text" +msgstr " -h Este texto de ayuda" + +#: cmdline/apt-cdrom.cc:869 +msgid " -d CD-ROM mount point" +msgstr " -d punto de montaje del CD-ROM" + +#: cmdline/apt-cdrom.cc:870 +msgid " -r Rename a recognized CD-ROM" +msgstr " -r Cambia el nombre de un CD-ROM reconocido" + +#: cmdline/apt-cdrom.cc:871 +msgid " -m No mounting" +msgstr " -m Sin montaje" + +#: cmdline/apt-cdrom.cc:872 +msgid " -f Fast mode, don't check package files" +msgstr " -f Modo rбpido, no verifica los archivos de paquete" + +#: cmdline/apt-cdrom.cc:873 +msgid " -a Thorough scan mode" +msgstr " -a Por el modo scan" + +#: cmdline/apt-cdrom.cc:876 +msgid "See fstab(5)" +msgstr "Mire fstab(5)" + +#: cmdline/apt-cache.cc:116 +msgid " version " +msgstr " versiуn " + +#: cmdline/apt-cache.cc:117 +msgid " has an unmet dep:" +msgstr " hay una dep. no resuelta:" + +#: cmdline/apt-cache.cc:156 cmdline/apt-cache.cc:410 cmdline/apt-cache.cc:534 +#: cmdline/apt-cache.cc:1089 +#, c-format +msgid "Unable to locate package %s" +msgstr "Imposible ubicar el paquete %s" + +#: cmdline/apt-cache.cc:160 cmdline/apt-cache.cc:320 +msgid "Package: " +msgstr "Paquete: " + +#: cmdline/apt-cache.cc:161 +msgid "Versions: " +msgstr "Versiones: " + +#: cmdline/apt-cache.cc:172 +msgid "Reverse Depends: " +msgstr "Dependencias inversas: " + +#: cmdline/apt-cache.cc:176 +msgid "Dependencies: " +msgstr "Dependencias: " + +#: cmdline/apt-cache.cc:185 cmdline/apt-cache.cc:926 +msgid "Provides: " +msgstr "Suministros: " + +#: cmdline/apt-cache.cc:193 +msgid "Reverse Provides: " +msgstr "Suministros inversos: " + +#: cmdline/apt-cache.cc:207 +msgid "Total Package Names : " +msgstr "Total Nombres de Paquetes : " + +#: cmdline/apt-cache.cc:247 +msgid " Normal Packages: " +msgstr " Paquetes normales: " + +#: cmdline/apt-cache.cc:248 +msgid " Pure Virtual Packages: " +msgstr " Paquetes virtuales puros: " + +#: cmdline/apt-cache.cc:249 +msgid " Single Virtual Packages: " +msgstr " Paquetes virtuales simples: " + +#: cmdline/apt-cache.cc:250 +msgid " Mixed Virtual Packages: " +msgstr " Paquetes virtuales mixtos: " + +#: cmdline/apt-cache.cc:251 +msgid " Missing: " +msgstr " Faltando: " + +#: cmdline/apt-cache.cc:253 +msgid "Total Distinct Versions: " +msgstr "Total de versiones diferentes: " + +#: cmdline/apt-cache.cc:255 +msgid "Total Dependencies: " +msgstr "Total de dependencias: " + +#: cmdline/apt-cache.cc:258 +msgid "Total Ver/File relations: " +msgstr "Total de relaciones versiуn/archivo: " + +#: cmdline/apt-cache.cc:260 +msgid "Total Provides Mappings: " +msgstr "Total Relaciones de suministros: " + +#: cmdline/apt-cache.cc:272 +msgid "Total Globbed Strings: " +msgstr "Total de strings casados: " + +#: cmdline/apt-cache.cc:277 +msgid "Total Slack space: " +msgstr "Espacio temporal total: " + +#: cmdline/apt-cache.cc:285 +msgid "Total Space Accounted for: " +msgstr "Espacio total contabilizado para: " + +#: cmdline/apt-cache.cc:300 +msgid "Bad section " +msgstr "Secciуn no vбlida " + +#: cmdline/apt-cache.cc:306 +msgid "Bad prio " +msgstr "Prioridad no vбlida " + +#: cmdline/apt-cache.cc:323 cmdline/apt-cache.cc:339 +msgid " Version: " +msgstr " Versiуn: " + +#: cmdline/apt-cache.cc:324 +msgid " File: " +msgstr " Archivo: " + +#: cmdline/apt-cache.cc:326 +msgid " Depends: " +msgstr " Dependencias: " + +#: cmdline/apt-cache.cc:332 +msgid "File: " +msgstr "Archivo: " + +#: cmdline/apt-cache.cc:333 +msgid " Size: " +msgstr " Tamaсo: " + +#: cmdline/apt-cache.cc:334 +msgid " ID: " +msgstr " ID: " + +#: cmdline/apt-cache.cc:335 +msgid " Flags: " +msgstr " Flags: " + +#: cmdline/apt-cache.cc:336 +msgid " Time: " +msgstr " Hora: " + +#: cmdline/apt-cache.cc:337 +msgid " Archive: " +msgstr " Archivo: " + +#: cmdline/apt-cache.cc:338 +msgid " Component: " +msgstr " Componente: " + +#: cmdline/apt-cache.cc:340 +msgid " Origin: " +msgstr " Origen: " + +#: cmdline/apt-cache.cc:341 +msgid " Label: " +msgstr " Etiqueta: " + +#: cmdline/apt-cache.cc:342 +msgid " Architecture: " +msgstr " Arquitectura: " + +#: cmdline/apt-cache.cc:669 +msgid "You must give at least one file name" +msgstr "Debe dar por lo menos un nombre de archivo" + +#: cmdline/apt-cache.cc:688 +msgid "Generating cache" +msgstr "Generando cachй" + +#: apt-pkg/systemfactory.cc:188 cmdline/apt-cache.cc:696 +#, c-format +msgid "Problem opening %s" +msgstr "Problema al abrir %s" + +#: cmdline/apt-cache.cc:699 +msgid "Problem with SelectFile" +msgstr "Problema en SelectFile" + +#: cmdline/apt-cache.cc:702 +msgid "Problem with MergeList" +msgstr "Problema en MergeList" + +#: cmdline/apt-cache.cc:806 +msgid "Oh shit!" +msgstr "ЎCaramba!" + +#: cmdline/apt-cache.cc:841 +#, c-format +msgid "Package: %s\n" +msgstr "Paquete: %s\n" + +#: cmdline/apt-cache.cc:844 +#, c-format +msgid "Section: %s\n" +msgstr "Secciуn: %s\n" + +#: cmdline/apt-cache.cc:847 +#, c-format +msgid "Installed Size: %i\n" +msgstr "Tamaсo instalado: %i\n" + +#: cmdline/apt-cache.cc:854 +#, c-format +msgid "Maintainer: %s\n" +msgstr "Mantenedor: %s\n" + +#: cmdline/apt-cache.cc:858 +#, c-format +msgid "Version: %i:%s" +msgstr "Versiуn: %i:%s" + +#: cmdline/apt-cache.cc:860 +#, c-format +msgid "Version: %s" +msgstr "Versiуn: %s" + +#: cmdline/apt-cache.cc:894 +msgid "Pre-Depends: " +msgstr "Predependencias: " + +#: cmdline/apt-cache.cc:907 +msgid "Depends: " +msgstr "Dependencias: " + +#: cmdline/apt-cache.cc:920 +msgid "Conflicts: " +msgstr "Conflictos: " + +#: cmdline/apt-cache.cc:932 +msgid "Obsoletes: " +msgstr "Obsoletos: " + +#: cmdline/apt-cache.cc:937 +#, c-format +msgid "Architecture: %s\n" +msgstr "Arquitectura: %s\n" + +#: cmdline/apt-cache.cc:940 +#, c-format +msgid "Size: %d\n" +msgstr "Tamaсo: %d\n" + +#: cmdline/apt-cache.cc:943 +#, c-format +msgid "MD5sum: %s\n" +msgstr "MD5sum: %s\n" + +#: cmdline/apt-cache.cc:946 +#, c-format +msgid "Filename: %s\n" +msgstr "Nombre de archivo: %s\n" + +#: cmdline/apt-cache.cc:949 +#, c-format +msgid "Description: %s\n" +msgstr "Descripciуn: %s\n" + +#: cmdline/apt-cache.cc:1038 +msgid "You must give exactly one pattern" +msgstr "Debe escribir exactamente un patrуn" + +#: cmdline/apt-cache.cc:1044 +msgid "Regex compilation error" +msgstr "Error de compilaciуn de Regex" + +#: cmdline/apt-cache.cc:1195 +msgid "Usage: apt-cache [options] command" +msgstr "Uso: apt-cache [opciones] comando" + +#: cmdline/apt-cache.cc:1196 +msgid " apt-cache [options] add file1 [file1 ...]" +msgstr " apt-cache [opciones] aсadir archivo1 [archivo1 ...]" + +#: cmdline/apt-cache.cc:1197 +msgid " apt-cache [options] showpkg pkg1 [pkg2 ...]" +msgstr " apt-cache [opciones] showpkg paq1 [paq2 ...]" + +#: cmdline/apt-cache.cc:1199 +msgid "apt-cache is a low-level tool used to manipulate APT's binary" +msgstr "apt-cache es una herramienta a bajo nivel usada para manipular el binario de APT" + +#: cmdline/apt-cache.cc:1200 +msgid "cache files stored in " +msgstr "archivos de cachй almacenados en " + +#: cmdline/apt-cache.cc:1201 +msgid "It is not meant for ordinary use only as a debug aide." +msgstr "No estб hecho para uso corriente, mбs biйn es una ayuda para depuraciуn." + +#: cmdline/apt-cache.cc:1204 +msgid " add - Add an package file to the source cache" +msgstr " add - Aсade un archivo de paquete al cache fuente" + +#: cmdline/apt-cache.cc:1205 +msgid " gencaches - Build both the package and source cache" +msgstr " gencaches - Construye el paquete y el cachй fuente" + +#: cmdline/apt-cache.cc:1206 +msgid " showpkg - Show some general information for a single package" +msgstr " showpkg - Muestra la informaciуn general de un paquete" + +#: cmdline/apt-cache.cc:1207 +msgid " stats - Show some basic statistics" +msgstr " stats - Muestra algunos datos estadнsticos bбsicos" + +#: cmdline/apt-cache.cc:1208 +msgid " dump - Show the entire file in a terse form" +msgstr " dump - Muestra todo el archivo de una forma resumida" + +#: cmdline/apt-cache.cc:1209 +msgid " dumpavail - Print an available file to stdout" +msgstr " dumpavail - Imprime un archivo disponible para la salida estбndar" + +#: cmdline/apt-cache.cc:1210 +msgid " unmet - Show unmet dependencies" +msgstr " unmet - Muestra dependencias no resueltas" + +#: cmdline/apt-cache.cc:1211 +msgid " check - Check the cache a bit" +msgstr " check - Verifica el cachй" + +#: cmdline/apt-cache.cc:1212 +msgid " search - Search the package list for a regex pattern" +msgstr " search - Busca en la lista de paquetes un patrуn regex" + +#: cmdline/apt-cache.cc:1213 +msgid " show - Show a readable record for the package" +msgstr " show - Muestra un registro legible para el paquete" + +#: cmdline/apt-cache.cc:1214 +msgid " depends - Show raw dependency information for a package" +msgstr " depends - Muestra, a grosso modo, info de dependencias para un paquete dado" + +#: cmdline/apt-cache.cc:1215 +msgid " pkgnames - List the names of all packages" +msgstr " pkgnames - Enumera los nombres de todos los paquetes" + +#: cmdline/apt-cache.cc:1216 +msgid " dotty - Generate package graphs for GraphVis" +msgstr " dotty - Genera grбficas de paquete para GraphVis" + +#: cmdline/apt-cache.cc:1219 cmdline/apt-config.cc:84 +msgid " -h This help text." +msgstr " -h Este texto de ayuda." + +#: cmdline/apt-cache.cc:1220 +msgid " -p=? The package cache. [" +msgstr " -p=? El cachй de paquete. [" + +#: cmdline/apt-cache.cc:1221 +msgid " -s=? The source cache. [" +msgstr " -s=? El cachй fuente. [" + +#: cmdline/apt-cache.cc:1222 +msgid " -q Disable progress indicator." +msgstr " -q Deshabilita indicador de progreso" + +#: cmdline/apt-cache.cc:1223 +msgid " -i Show only important deps for the unmet command." +msgstr " -i Muestra sуlo las dependencias importantes para el comando unmet." + +#: cmdline/apt-cache.cc:1226 +msgid "See the apt-cache(8) and apt.conf(5) manual pages for more information." +msgstr "" +"Consulte las manpages de apt-get(8) y apt.conf(5) para mбs informaciуn." + +#: cmdline/apt-config.cc:37 +msgid "Arguments not in pairs" +msgstr "Los argumentos no estбn en pares" + +#: cmdline/apt-config.cc:75 +msgid "Usage: apt-config [options] command" +msgstr "Uso: apt-config [opciones] comando" + +#: cmdline/apt-config.cc:77 +msgid "apt-config is a simple tool to read the APT config file" +msgstr "" +"apt-config es una herramienta simple para leer el archivo de configuraciуn " +"de APT" + +#: cmdline/apt-config.cc:80 +msgid " shell - Shell mode" +msgstr " shell - Modo Shell" + +#: cmdline/apt-config.cc:81 +msgid " dump - Show the configuration" +msgstr " dump - Muestra la configuraciуn" + +#: apt-pkg/acquire-item.cc:142 +#, c-format +msgid "Size of %s did not match what's in the hashfile and was redownloaded." +msgstr "El tamaсo de %s no coincide con lo que dice el archivo hash y se descargу de nuevo." + +#: apt-pkg/acquire-item.cc:154 +#, c-format +msgid "MD5 of %s did not match what's int the hashfile and was redownloaded." +msgstr "El MD5 de %s no coincide con lo que dice el archivo hash y se descargу de nuevo." + +#: apt-pkg/acquire-item.cc:426 +msgid "Hashfile signer is not who it's supposed to be (expected " +msgstr "El firmante del archivo hash no es quien deberнa ser (esperado " + +#: apt-pkg/acquire-item.cc:428 +msgid ", got " +msgstr ", obtuve " + +#: apt-pkg/acquire-worker.cc:108 +#, c-format +msgid "The method driver %s could not be found." +msgstr "No se pudo encontrar el mecanismo de bъsqueda %s." + +#: apt-pkg/acquire-worker.cc:117 +msgid "Failed to create IPC pipe to subprocess" +msgstr "Fallу al crear un pipe IPC para el subproceso" + +#: apt-pkg/acquire-worker.cc:160 +#, c-format +msgid "Method %s did not start correctly" +msgstr "El mйtodo %s no se iniciу correctamente" + +#: apt-pkg/acquire-worker.cc:197 +#, c-format +msgid "Invalid message from method %s: %s" +msgstr "Mensaje no vбlido del mйtodo %s: %s" + +#: apt-pkg/acquire-worker.cc:210 +#, c-format +msgid "Unable to process Capabilities message from %s" +msgstr "Imposible procesar mensaje de Capacidades de %s" + +#: apt-pkg/acquire-worker.cc:229 +msgid "Method gave invalid 200 URI Start message" +msgstr "El mйtodo produjo el mensaje invalid 200 URI Start" + +#: apt-pkg/acquire-worker.cc:268 +#, c-format +msgid "Bizzar Error - File size is not what the server reported %s %u" +msgstr "Error anуmalo - El tamaсo del archivo no es el que informу el servidor %s %u" + +#: apt-pkg/acquire-worker.cc:297 +msgid "Method gave invalid 400 URI Failure message" +msgstr "El mйtodo produjo el mensaje 400 URI Failure" + +#: apt-pkg/acquire-worker.cc:319 +#, c-format +msgid "Method %s General failure: %s" +msgstr "Falla general del mйtodo %s: %s" + +#: apt-pkg/acquire-worker.cc:503 +#, c-format +msgid "Method %s has died unexpectedly!" +msgstr "ЎEl mйtodo %s terminу inesperadamente!" + +#: apt-pkg/acquire.cc:58 +#, c-format +msgid "Lists directory %spartial is missing." +msgstr "Falta directorio de listas %spartial." + +#: apt-pkg/acquire.cc:62 +#, c-format +msgid "Archive directory %spartial is missing." +msgstr "Falta directorio de archivos %spartial." + +#: apt-pkg/acquire.cc:557 +msgid "Tried to dequeue a fetching object" +msgstr "Se intentу quitar de la cola un objeto en carga." + +#: apt-pkg/cachefile.cc:83 +msgid "The package lists or status file could not be parsed or opened." +msgstr "No se pudo abrir o analizar la lista de paquetes o el archivo de estado." + +#: apt-pkg/cachefile.cc:85 +msgid "You may want to run apt-get update to correct these missing files" +msgstr "Tal vez quiera ejecutar apt-get update para corregir estos archivos perdidos." + +#: apt-pkg/clean.cc:44 +msgid "Unable to change to " +msgstr "Imposible alterar para " + +#: apt-pkg/clean.cc:58 +#, c-format +msgid "Unable to stat %s." +msgstr "Imposible leer %s." + +#: apt-pkg/depcache.cc:61 apt-pkg/depcache.cc:90 +msgid "Building Dependency Tree" +msgstr "Construyendo бrbol de dependencias" + +#: apt-pkg/depcache.cc:62 +msgid "Candidate Versions" +msgstr "Versiones propuestas" + +#: apt-pkg/depcache.cc:91 +msgid "Dependency Generation" +msgstr "Generaciуn de dependencias" + +#: apt-pkg/packagemanager.cc:397 +#, c-format +msgid "" +"This installation run will require temporarily removing the essential " +"package %s due to a Conflicts/Pre-Depends loop. This is often bad, but if " +"you really want to do it, activate the APT::Force-LoopBreak option." +msgstr "La ejecuciуn de esta instalaciуn tendrб que eliminar el paquete esencial %s temporalmente, debido a bucles con Conflictos/Dependencias. Generalmente no es bueno, pero si realmente quiere hacerlo, active la opciуn APT::Force-LoopBreak." + +#: apt-pkg/pkgcache.cc:125 +msgid "The package cache file is corrupted" +msgstr "El archivo de cachй del paquete estб corrompido" + +#: apt-pkg/pkgcache.cc:130 +msgid "The package cache file is an incompatible version" +msgstr "El archivo de cachй del paquete pertenece a una versiуn incompatible" + +#: apt-pkg/pkgcachegen.cc:90 +#, c-format +msgid "Error occured while processing %s (NewPackage)" +msgstr "Error ocurrido al procesar %s (NewPackage)" + +#: apt-pkg/pkgcachegen.cc:102 +#, c-format +msgid "Error occured while processing %s (UsePackage1)" +msgstr "Error ocurrido al procesar %s (UsePackage1)" + +#: apt-pkg/pkgcachegen.cc:124 +#, c-format +msgid "Error occured while processing %s (UsePackage2)" +msgstr "Error ocurrido al procesar %s (UsePackage2)" + +#: apt-pkg/pkgcachegen.cc:127 +#, c-format +msgid "Error occured while processing %s (NewFileVer1)" +msgstr "Error ocurrido al procesar %s (NewFileVer1)" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "WARNING: '" +msgstr "AVISO: '" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "' has 2 packages with same version but different dependencies. " +msgstr "' tiene 2 paquetes con la misma versiуn pero dependencias diferentes." + +#: apt-pkg/pkgcachegen.cc:139 +msgid "That usually means a packaging bug." +msgstr "Esto significa, por lo general, un error al empaquetar." + +#: apt-pkg/pkgcachegen.cc:158 +#, c-format +msgid "Error occured while processing %s (NewVersion1)" +msgstr "Error ocurrido al procesar %s (NewVersion1)" + +#: apt-pkg/pkgcachegen.cc:161 +#, c-format +msgid "Error occured while processing %s (UsePackage3)" +msgstr "Error ocurrido al procesar %s (UsePackage3)" + +#: apt-pkg/pkgcachegen.cc:164 +#, c-format +msgid "Error occured while processing %s (NewVersion2)" +msgstr "Error ocurrido al procesar %s (NewVersion2)" + +#: apt-pkg/sourcelist.cc:76 +#, c-format +msgid "Block %s is invalid" +msgstr "El bloque %s no es vбlido" + +#: apt-pkg/sourcelist.cc:121 +#, c-format +msgid "Malformed line %u in source list %s (type)" +msgstr "Lнnea %u equivocada en la lista fuente %s (tipo)" + +#: apt-pkg/sourcelist.cc:123 apt-pkg/sourcelist.cc:135 +#, c-format +msgid "Malformed line %u in source list %s (URI)" +msgstr "Lнnea %u equivocada en la lista fuente %s (URI)" + +#: apt-pkg/sourcelist.cc:130 +#, c-format +msgid "Malformed line %u in source list %s (vendor ID)" +msgstr "Lнnea %u equivocada en la lista fuente %s (ID de fabricante)" + +#: apt-pkg/sourcelist.cc:141 +#, c-format +msgid "Malformed line %u in source list %s (dist)" +msgstr "Lнnea %u equivocada en la lista fuente %s (dist)" + +#: apt-pkg/sourcelist.cc:145 +#, c-format +msgid "Malformed line %u in source list %s (bad vendor ID)" +msgstr "Lнnea %u equivocada en la lista fuente %s (ID de fabricante errуnea)" + +#: apt-pkg/sourcelist.cc:148 +#, c-format +msgid "Malformed line %u in source list %s (bad type)" +msgstr "Lнnea %u equivocada en la lista fuente %s (tipo errуneo)" + +#: apt-pkg/sourcelist.cc:151 +#, c-format +msgid "Malformed line %u in source list %s (bad URI)" +msgstr "Lнnea %u equivocada en la lista fuente %s (URI errуnea)" + +#: apt-pkg/sourcelist.cc:161 +#, c-format +msgid "Malformed line %u in source list %s (Absolute dist)" +msgstr "Lнnea %u equivocada en la lista fuente %s (dist absoluta)" + +#: apt-pkg/sourcelist.cc:174 +#, c-format +msgid "Malformed line %u in source list %s (dist parse)" +msgstr "Lнnea %u equivocada en la lista fuente %s (anбlisis de dist)" + +#: apt-pkg/sourcelist.cc:353 +msgid "could not open hash index" +msgstr "no se pudo abrir нndice hash" + +#: apt-pkg/sourcelist.cc:363 +msgid "No MD5SUM data in hashfile" +msgstr "No hay datos de MD5SUM en el archivo hash" + +#: apt-pkg/sourcelist.cc:377 +msgid "Error parsing MD5 hash record" +msgstr "Error al analizar el registro de MD5 hash" + +#: apt-pkg/sourcelist.cc:400 +#, c-format +msgid "" +"Repository entry in sources.list contains extra components that are not " +"listed in the signed hash file: %s" +msgstr "La entrada del repositorio en sources.list contiene componentes extra que no estбn enumerados en el archivo hash firmado: %s" + +#: apt-pkg/srcrecords.cc:47 +msgid "Sorry, you must put some 'source' uris in your sources.list" +msgstr "Lo siento, debe poner algunas uris 'fuente' en su sources.list" + +#: apt-pkg/systemfactory.cc:72 +#, c-format +msgid "Failed to rename %s to %s" +msgstr "Fallу al cambiar de nombre de %s para %s" + +#: apt-pkg/systemfactory.cc:77 +#, c-format +msgid "Couldn't stat source package list '%s' (%s)" +msgstr "No se pudo leer la lista de paquetes '%s' (%s)" + +#. Mostly from MakeStatusCache.. +#: apt-pkg/systemfactory.cc:184 apt-pkg/systemfactory.cc:240 +#: apt-pkg/systemfactory.cc:272 apt-pkg/systemfactory.cc:273 +#: apt-pkg/systemfactory.cc:280 apt-pkg/systemfactory.cc:350 +#: apt-pkg/systemfactory.cc:386 +msgid "Reading Package Lists" +msgstr "Leyendo listas de paquetes" + +#: apt-pkg/systemfactory.cc:196 +#, c-format +msgid "Problem with SelectFile %s" +msgstr "Problema con SelectFile %s" + +#: apt-pkg/systemfactory.cc:201 +#, c-format +msgid "Problem with MergeList %s" +msgstr "Problema con MergeList %s" + +#: apt-pkg/systemfactory.cc:263 +msgid "IO Error saving source cache" +msgstr "Error de E/S al guardar el cachй fuente" + +#: apt-pkg/tagfile.cc:59 +#, c-format +msgid "Unable to parse package file %s (1)" +msgstr "Imposible analizar el paquete %s (1)" + +#: apt-pkg/tagfile.cc:142 +#, c-format +msgid "Unable to parse package file %s (2)" +msgstr "Imposible analizar el paquete %s (2)" diff --git a/apt/po/it_IT.po b/apt/po/it_IT.po new file mode 100644 index 0000000..6230abd --- /dev/null +++ b/apt/po/it_IT.po @@ -0,0 +1,1473 @@ +# Italian messages for apt. +# Copyright (C) 2000 Free Software Foundation, Inc. +# Stefano Corsi , 2001. +# +msgid "" +msgstr "" +"Project-Id-Version: apt\n" +"POT-Creation-Date: 2001-01-10 13:40-0200\n" +"PO-Revision-Date: 2001-01-11 15:40-02:00\n" +"Last-Translator: Stefano Corsi \n" +"Language-Team: Italian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8 bit\n" + +#. Yes/No +#: cmdline/apt-get.cc:129 +msgid "Y" +msgstr "S" + +#: cmdline/apt-get.cc:129 +msgid "y" +msgstr "s" + +#: cmdline/apt-get.cc:215 +msgid "Sorry, but the following packages have unmet dependencies:" +msgstr "Purtroppo i seguenti pacchetti non soddisfano tutte le dipendenze:" + +#: cmdline/apt-get.cc:275 +msgid " but " +msgstr " ma " + +#: cmdline/apt-get.cc:278 +msgid " is installed" +msgstr " и installato" + +#: cmdline/apt-get.cc:278 +msgid " is to be installed" +msgstr " dovrа essere installato" + +#: cmdline/apt-get.cc:284 +msgid "it is not installable" +msgstr "non и installabile" + +#: cmdline/apt-get.cc:286 +msgid "it is a virtual package" +msgstr "и un pacchetto virtuale" + +#: cmdline/apt-get.cc:289 +msgid "it is not installed" +msgstr "non и installato" + +#: cmdline/apt-get.cc:289 +msgid "it is not going to be installed" +msgstr "non verrа installato" + +#: cmdline/apt-get.cc:294 +msgid " or" +msgstr " o" + +#: cmdline/apt-get.cc:320 +msgid "The following NEW packages will be installed:" +msgstr "Saranno installati i seguenti pacchetti NUOVI:" + +#: cmdline/apt-get.cc:343 +msgid "The following packages will be REMOVED:" +msgstr "Verranno ELIMINATI i seguenti pacchetti:" + +#: cmdline/apt-get.cc:363 +msgid "The following packages have been kept back" +msgstr "I seguenti pacchetti sono stati mantenuti" + +#: cmdline/apt-get.cc:383 +msgid "The following packages will be upgraded" +msgstr "Verranno aggiornati i seguenti pacchetti" + +#: cmdline/apt-get.cc:415 +msgid "The following packages can be upgraded:" +msgstr "I seguenti pacchetti possono essere aggiornati:" + +#: cmdline/apt-get.cc:426 +msgid " from " +msgstr " da " + +#: cmdline/apt-get.cc:427 +msgid " to " +msgstr " per " + +#: cmdline/apt-get.cc:429 +msgid " Importance: " +msgstr " Importanza: " + +#: cmdline/apt-get.cc:430 +msgid " Date: " +msgstr " Data: " + +#: cmdline/apt-get.cc:450 +msgid "The following held packages will be changed:" +msgstr "Verranno cambiati i seguenti pacchetti:" + +#: cmdline/apt-get.cc:500 +#, c-format +msgid "%s (due to %s) " +msgstr "%s (dovuto a %s) " + +#: cmdline/apt-get.cc:508 +msgid "WARNING: The following essential packages will be removed" +msgstr "AVVISO: i seguenti pacchetti essenziali verranno eliminati" + +#: cmdline/apt-get.cc:509 +msgid "This should NOT be done unless you know exactly what you are doing!" +msgstr "Questo NON dovrebbe essere fatto a meno di non sapere esattamente quello che si sta facendo!" + +#: cmdline/apt-get.cc:531 +msgid " packages upgraded, " +msgstr " pacchetti aggiornati, " + +#: cmdline/apt-get.cc:532 +msgid " newly installed, " +msgstr " installati recentemente, " + +#: cmdline/apt-get.cc:534 +msgid " reinstalled, " +msgstr " reinstallati, " + +#: cmdline/apt-get.cc:535 +msgid " to remove and " +msgstr " da eliminare e " + +#: cmdline/apt-get.cc:536 +msgid " not upgraded." +msgstr " non aggiornati." + +#: cmdline/apt-get.cc:539 +msgid " packages not fully installed or removed." +msgstr " pacchetti non completamente installati o rimossi." + +#: apt-pkg/pkgrecords.cc:36 cmdline/apt-cache.cc:364 cmdline/apt-cache.cc:970 +#: cmdline/apt-cache.cc:1005 cmdline/apt-get.cc:555 +#, c-format +msgid "Package file %s is out of sync." +msgstr "Il pacchetto %s non и sincronizzato." + +#: cmdline/apt-get.cc:672 +msgid "Correcting dependencies..." +msgstr "Correzione delle dipendenze..." + +#: cmdline/apt-get.cc:675 +msgid " failed." +msgstr " fallito." + +#: cmdline/apt-get.cc:678 +msgid "Unable to correct dependencies" +msgstr "Impossibile correggere le dipendenze" + +#: cmdline/apt-get.cc:681 +msgid "Unable to minimize the upgrade set" +msgstr "Impossibile ridurre il gruppo da aggiornare" + +#: cmdline/apt-get.cc:683 +msgid " Done" +msgstr " Fatto" + +#: cmdline/apt-get.cc:687 +msgid "You might want to run `apt-get -f install' to correct these." +msgstr "Potresti eseguire `apt-get -f install' per correggerli." + +#: cmdline/apt-get.cc:690 +msgid "Unmet dependencies. Try using -f." +msgstr "Dipendenze irrisolte. Prova ad usare -f." + +#: cmdline/apt-get.cc:743 +msgid "Internal Error, InstallPackages was called with broken packages!" +msgstr "Errore interno, InstallPackages chiamato con un pacchetto Broken" + +#: cmdline/apt-get.cc:752 +msgid "Packages need to be removed but No Remove was specified." +msgstr "Devono essere eliminati dei pacchetti ma и stato specificato No Remove." + +#: cmdline/apt-get.cc:762 +msgid "Internal Error, Ordering didn't finish" +msgstr "Errore interno, L' ordinamento non и terminato" + +#: cmdline/apt-get.cc:777 cmdline/apt-get.cc:1536 cmdline/apt-get.cc:1569 +msgid "Unable to lock the download directory" +msgstr "Impossible bloccare lo scaricamento della directory" + +#: apt-pkg/cachefile.cc:73 cmdline/apt-get.cc:787 cmdline/apt-get.cc:1619 +msgid "The list of sources could not be read." +msgstr "Non и possibile leggere la lista delle fonti." + +#: cmdline/apt-get.cc:804 +msgid "How odd.. The sizes didn't match, email apt@packages.debian.org" +msgstr "Che strano... Le dimensioni non coincidono, spedisci un messaggio a apt@packages.debian.org" + +#. Number of bytes +#: cmdline/apt-get.cc:808 cmdline/apt-get.cc:1752 +msgid "Need to get " +msgstr "Bisogna conseguire " + +#: cmdline/apt-get.cc:814 +msgid " of archives. After unpacking " +msgstr " degli archivi. Dopo lo spacchettamento, " + +#: cmdline/apt-get.cc:818 +msgid "B will be used." +msgstr "verrа usato B." + +#: cmdline/apt-get.cc:820 +msgid "B will be freed." +msgstr "verrа liberato B." + +#: cmdline/apt-get.cc:832 cmdline/apt-get.cc:1745 +#, c-format +msgid "Couldn't determine free space in %s" +msgstr "Non si puт determinare spazio libero in %s" + +#: cmdline/apt-get.cc:835 +#, c-format +msgid "Sorry, you don't have enough free space in %s to hold all packages." +msgstr "Peccato, non c'и spazio libero sufficiente in %s per contenere tutti i pacchetti." + +#: cmdline/apt-get.cc:844 +msgid "There are problems and -y was used without --force-yes" +msgstr "Ci sono dei problemi e -y и stato usato senza --force-yes" + +#: cmdline/apt-get.cc:850 cmdline/apt-get.cc:867 +msgid "Trivial Only specified but this is not a trivial operation." +msgstr "E' stato specificato `Solo triviale' ma questa non и un'operazione triviale." + +#: cmdline/apt-get.cc:852 +msgid "You are about to do something potentially harmful" +msgstr "Sei sul punto di commettere un'azione potenzialmente dannosa" + +#: cmdline/apt-get.cc:853 +msgid "To continue type in the phrase 'Yes, I understand this may be bad'" +msgstr "Per continuare digita la frase 'Sм, capisco che questo possa essere pericoloso'" +#cattivo? +#: cmdline/apt-get.cc:854 +msgid " ?] " +msgstr " ?] " + +#: cmdline/apt-get.cc:855 +msgid "Yes, I understand this may be bad" +msgstr "Si, capisco che questo possa essere pericoloso" +#cattivo? +#: cmdline/apt-get.cc:857 cmdline/apt-get.cc:876 +msgid "Aborted." +msgstr "Terminato." + +#: cmdline/apt-get.cc:872 +msgid "Do you want to continue? [Y/n] " +msgstr "Vuoi proseguire? [S/n] " + +#: cmdline/apt-get.cc:936 cmdline/apt-get.cc:1196 cmdline/apt-get.cc:1788 +msgid "Failed to fetch " +msgstr "Recupero fallito" + +#: cmdline/apt-get.cc:954 +msgid "Some files failed to download" +msgstr "Scaricamento di alcuni file fallito" + +#: cmdline/apt-get.cc:960 +msgid "Unable to fetch some archives, maybe try with --fix-missing?" +msgstr "Recupero di alcuni archivi impossibile. E provare con --fix-missing?" +#forse? +#: cmdline/apt-get.cc:964 +msgid "--fix-missing and media swapping is not currently supported" +msgstr "al momento --fix-missing e il cambio di supporto non sono supportati" +# media swapping? +#: cmdline/apt-get.cc:969 +msgid "Unable to correct missing packages." +msgstr "Impossible correggere i pacchetti persi." + +#: cmdline/apt-get.cc:970 +msgid "Aborting Install." +msgstr "Installazione in fase di interruzione." + +#: cmdline/apt-get.cc:1001 +msgid "Note, selecting " +msgstr "Nota, selezionando " + +#: cmdline/apt-get.cc:1001 +msgid " instead of " +msgstr " invece di " + +#: cmdline/apt-get.cc:1010 +msgid "Skipping " +msgstr "Omettendo " + +#: cmdline/apt-get.cc:1010 +msgid ", it is already installed and no-upgrade is set." +msgstr ", и giа installato e l'opzione no-upgrade и abilitata." + +#: cmdline/apt-get.cc:1020 +#, c-format +msgid "Package %s is not installed" +msgstr "Il pacchetto %s non и installato" + +#: cmdline/apt-cache.cc:116 cmdline/apt-get.cc:1030 cmdline/apt-get.cc:1050 +msgid "Package " +msgstr "Pacchetto " + +#: cmdline/apt-get.cc:1030 +msgid " is a virtual package provided by:" +msgstr " и un pacchetto virtuale fornito da:" + +#: cmdline/apt-get.cc:1041 +msgid " [Installed]" +msgstr " [Installato]" + +#: cmdline/apt-get.cc:1046 +msgid "You should explicitly select one to install." +msgstr "Bisognerebbe esplicitarne uno per installarlo." + +#: cmdline/apt-get.cc:1050 +msgid " has no available version, but exists in the database." +msgstr " non ha una versione disponibile, ma esiste nel database." +#o database? +#: cmdline/apt-get.cc:1051 +msgid "" +"This typically means that the package was mentioned in a dependency and " +msgstr "Questo significa che il pacchetto и stato menzionato in una dipendenza " + +#: cmdline/apt-get.cc:1052 +msgid "" +"never uploaded, has been obsoleted or is not available with the contents " +msgstr "mai stato caricato, divenuto obsoleto o non disponibile con tali contenuti" + +#: cmdline/apt-get.cc:1053 +msgid "of sources.list" +msgstr "di sources.list" + +#: cmdline/apt-get.cc:1064 +msgid "However the following packages replace it:" +msgstr "Comunque, i pacchetti seguenti lo sostituiscono:" + +#: cmdline/apt-get.cc:1067 +#, c-format +msgid "Package %s has no installation candidate" +msgstr "Il pacchetto %s non ha alcun candidato di installazione" + +#: cmdline/apt-get.cc:1087 +msgid "Sorry, re-installation of " +msgstr "Purtroppo, la reinstallazione di " + +#: cmdline/apt-get.cc:1087 +msgid " is not possible, it cannot be downloaded" +msgstr " non и possibile, non si puт scaricarlo" + +#: cmdline/apt-get.cc:1094 +msgid "Sorry, " +msgstr "Purtroppo, " + +#: cmdline/apt-get.cc:1094 +msgid " is already the newest version" +msgstr " и giа la versione più nuova" + +#: cmdline/apt-get.cc:1123 +msgid "Unable to lock the list directory" +msgstr "Impossibile bloccare la directory di lista" + +#: cmdline/apt-get.cc:1148 +msgid "Could not retrieve digitally signed hash file" +msgstr "Non и stato possible reperire l' archivio hash con firma digitale" + +#: cmdline/apt-get.cc:1160 +msgid "Failed to fetch hash file: " +msgstr "Recupero dell' archivio hash fallito:" + +#: cmdline/apt-get.cc:1168 +msgid "" +"Some of the signed hash files could not be retrieved. Aborting operation." +msgstr "Non si sono potuti recuperare alcuni archivi hash firmati. Operazione in fase di interruzione." + +#: cmdline/apt-get.cc:1210 +msgid "Some of the index files had mismatching MD5 sums!" +msgstr "Alcuni archivi di indice riportavano MD5sum non combacianti!" +#o MD5sum, come in 1051? +#: cmdline/apt-get.cc:1218 +msgid "" +"Some index files failed to download, they have been ignored, or old ones " +"used instead." +msgstr "Lo scaricamento di alcuni archivi di indice non и riuscito, sono stati ignorati, o al loro posto sono stati utilizzati i vecchi." + +#: cmdline/apt-get.cc:1223 +msgid " will not be authenticated." +msgstr " non verrа autenticato." + +#: cmdline/apt-get.cc:1244 +msgid "Internal Error, AllUpgrade broke stuff" +msgstr "Errore interno, AllUpgrade si и rotto" + +#: cmdline/apt-get.cc:1313 cmdline/apt-get.cc:1346 +#, c-format +msgid "Couldn't find package %s" +msgstr "Il pacchetto %s non и stato trovato" + +#: cmdline/apt-get.cc:1326 +msgid "Regex compilation error:" +msgstr "Errore nella compilazione di espressioni regolari:" +#o regex, come in 1066? +#: cmdline/apt-get.cc:1360 +msgid "You might want to run `apt-get -f install' to correct these:" +msgstr "Potresti eseguire `apt-get -f install' per correggerli:" + +#: cmdline/apt-get.cc:1363 +msgid "" +"Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a " +"solution)." +msgstr "Dipendenze non soddisfatte. Prova 'apt-get -f install' senza pacchetti (o specifica una soluzione)." + +#: cmdline/apt-get.cc:1374 +msgid "Some packages could not be installed. This may mean that you have" +msgstr "Alcuni pacchetti non possono essere installati. Questo puт significare che и stata" + +#: cmdline/apt-get.cc:1375 +msgid "requested an impossible situation or if you are using the unstable" +msgstr "richiesta una situazione impossibile o che si sta usando una distribuzione" + +#: cmdline/apt-get.cc:1376 +msgid "distribution that some required packages have not yet been created" +msgstr "instabile, che alcuni pacchetti non sono stati ancora creati" + +#: cmdline/apt-get.cc:1377 +msgid "or been moved out of Incoming." +msgstr "o che sono stati rimossi dall' Entrata." + +#: cmdline/apt-get.cc:1381 +msgid "Since you only requested a single operation it is extremely likely that" +msgstr "Dal momento che hai richiesto un' operazione singola и molto probabile che" + +#: cmdline/apt-get.cc:1382 +msgid "the package is simply not installable and a bug report against" +msgstr "il pacchetto sia semplicemente non installabile e" + +#: cmdline/apt-get.cc:1383 +msgid "that package should be filed." +msgstr "che debba essere inviato un bug report per il pacchetto." + +#: cmdline/apt-get.cc:1386 +msgid "The following information may help to resolve the situation:" +msgstr "La seguente informazione ti puт aiutare a risolvere il problema:" + +#: cmdline/apt-get.cc:1389 +msgid "Sorry, broken packages" +msgstr "Spiacente, pacchetti danneggiati" + +#: cmdline/apt-get.cc:1412 +msgid "The following extra packages will be installed:" +msgstr "Verranno installati i seguenti pacchetti extra: " + +#: cmdline/apt-get.cc:1431 +msgid "Calculating Upgrade... " +msgstr "Calcolo dell'aggiornamento... " + +#: cmdline/apt-get.cc:1434 +msgid "Failed" +msgstr "Fallito" + +#: cmdline/apt-get.cc:1439 +msgid "Done" +msgstr "Fatto" + +#: cmdline/apt-get.cc:1504 cmdline/apt-get.cc:1512 +msgid "Internal Error, problem resolver broke stuff" +msgstr "Errore interno, il problem solver si e' rotto" + +#: cmdline/apt-get.cc:1614 +msgid "Must specify at least one package to fetch source for" +msgstr "Devi specificare almeno un pacchetto per cui recuperare il sorgente" + +#: cmdline/apt-get.cc:1688 +#, c-format +msgid "Unable to find a source package for %s" +msgstr "Impossibile trovare un pacchetto sorgente per %s" + +#: cmdline/apt-get.cc:1748 +#, c-format +msgid "Sorry, you don't have enough free space in %s" +msgstr "Peccato, non hai spazio sufficiente in %s" + +#: cmdline/apt-get.cc:1757 +msgid " of source archives." +msgstr " di archivi sorgente." + +#: cmdline/apt-get.cc:1762 +msgid "Fetch Source " +msgstr "Download del sorgente" + +#: cmdline/apt-get.cc:1793 +msgid "Failed to fetch some archives." +msgstr "Impossibile recuperare alcuni archivi." + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1859 +msgid "Build command '" +msgstr "Comando di Build '" + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1842 cmdline/apt-get.cc:1859 +msgid "' failed." +msgstr "' fallito." + +#: cmdline/apt-get.cc:1831 +msgid "Skipping unpack of already unpacked source in " +msgstr "Non spacchetto. Sorgente gia' scompattato in " + +#: cmdline/apt-get.cc:1842 +msgid "Unpack command '" +msgstr "Comando di spacchettamento '" + +#: cmdline/apt-get.cc:1875 +msgid "Couldn't wait for subprocess" +msgstr "Impossibile attendere il sottoprocesso" + +#: cmdline/apt-get.cc:1879 +msgid "Child process failed" +msgstr "Fallito il processo figlio" + +#: cmdline/apt-get.cc:1895 +msgid "Usage: apt-get [options] command" +msgstr "Uso: apt-get [opzioni] comando" + +#: cmdline/apt-get.cc:1896 +msgid " apt-get [options] install pkg1 [pkg2 ...]" +msgstr " apt-get [opzioni] install pacch1 [pacch2 ...]" + +#: cmdline/apt-get.cc:1898 +msgid "apt-get is a simple command line interface for downloading and" +msgstr "apt-get и una semplice interfaccia a comandi per scaricare e" + +#: cmdline/apt-get.cc:1899 +msgid "installing packages. The most frequently used commands are update" +msgstr "installare pacchetti. I comandi piщ usati sono update" + +#: cmdline/apt-get.cc:1900 +msgid "and install." +msgstr "e install." + +#: cmdline/apt-cache.cc:1203 cmdline/apt-cdrom.cc:864 cmdline/apt-config.cc:79 +#: cmdline/apt-get.cc:1902 +msgid "Commands:" +msgstr "Comandi:" + +#: cmdline/apt-get.cc:1903 +msgid " update - Retrieve new lists of packages" +msgstr " update - Aggiorna le liste di pacchetti" + +#: cmdline/apt-get.cc:1904 +msgid " upgrade - Perform an upgrade" +msgstr " upgrade - Aggiorna i pacchetti" + +#: cmdline/apt-get.cc:1905 +msgid " install - Install new packages" +msgstr " install - Installa nuovi pacchetti" + +#: cmdline/apt-get.cc:1906 +msgid " remove - Remove packages" +msgstr " remove - Elimina pacchetti" + +#: cmdline/apt-get.cc:1907 +msgid " source - Download source archives" +msgstr " source - Scarica archivi di sorgenti" + +#: cmdline/apt-get.cc:1908 +msgid " dist-upgrade - Distribution upgrade, see apt-get(8)" +msgstr " dist-upgrade - Aggiorna la distirbuzione, vedi apt-get(8)" + +#. cout << " dselect-upgrade - Follow dselect selections" << endl; +#: cmdline/apt-get.cc:1910 +msgid " clean - Erase downloaded archive files" +msgstr " clean - Elimina gli archivi scaricati" + +#: cmdline/apt-get.cc:1911 +msgid " autoclean - Erase old downloaded archive files" +msgstr " autoclean - Elimina i vecchi archivi" + +#: cmdline/apt-get.cc:1912 +msgid " check - Verify that there are no broken dependencies" +msgstr " check - Verifica che non ci siano dipendenze insoddisfatte" + +#: cmdline/apt-cache.cc:1218 cmdline/apt-cdrom.cc:867 cmdline/apt-config.cc:83 +#: cmdline/apt-get.cc:1914 +msgid "Options:" +msgstr "Opzioni:" + +#: cmdline/apt-get.cc:1915 +msgid " -h This help text." +msgstr " -h Questo testo di aiuto." + +#: cmdline/apt-get.cc:1916 +msgid " -q Loggable output - no progress indicator" +msgstr " -q Output normale - senza indicatore di avanzamento" + +#: cmdline/apt-get.cc:1917 +msgid " -qq No output except for errors" +msgstr " -qq Nessun messaggio, a parte gli errori" + +#: cmdline/apt-get.cc:1918 +msgid " -S Show summary for upgrade operation and quit" +msgstr " -S Mostra il sommario delle operazioni di aggiornamento e termina" + +#: cmdline/apt-get.cc:1919 +msgid " -d Download only - do NOT install or unpack archives" +msgstr " -d Solo download - Non installa o spacchetta gli archivi" + +#: cmdline/apt-get.cc:1920 +msgid " -s No-act. Perform ordering simulation" +msgstr " -s Nessuna azione. Simula l'ordinamento" + +#: cmdline/apt-get.cc:1921 +msgid " -y Assume Yes to all queries and do not prompt" +msgstr " -y Rispondi automaticamente sì a tutte le domande" + +#: cmdline/apt-get.cc:1922 +msgid " -f Attempt to continue if the integrity check fails" +msgstr " -f Prova a continuare anche se fallisce il controllo d'integrità" + +#: cmdline/apt-get.cc:1923 +msgid " -m Attempt to continue if archives are unlocatable" +msgstr " -m Prova a continuare se non si trovano gli archivi" + +#: cmdline/apt-get.cc:1924 +msgid " -u Show a list of upgraded packages as well" +msgstr " -u Mostra anche una lista di pacchetti aggiornati" + +#: cmdline/apt-get.cc:1925 +msgid " -b Build the source package after fetching it" +msgstr " -b Produci il binario dopo aver recuperato il sorgente" + +#: cmdline/apt-cache.cc:1224 cmdline/apt-cdrom.cc:874 cmdline/apt-config.cc:85 +#: cmdline/apt-get.cc:1926 +msgid " -c=? Read this configuration file" +msgstr " -c=? Leggi questo file di configurazione" + +#: cmdline/apt-cache.cc:1225 cmdline/apt-cdrom.cc:875 cmdline/apt-config.cc:86 +#: cmdline/apt-get.cc:1927 +msgid " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" +msgstr " -o=? Imposta un'opzione di configurazione arbitraria, p.ex -o dir::cache=/tmp" + +#: cmdline/apt-get.cc:1928 +msgid "See the apt-get(8), sources.list(5) and apt.conf(5) manual" +msgstr "Consulta le manpage di apt-get(8), sources.list(5) e apt.conf(5)" + +#: cmdline/apt-get.cc:1929 +msgid "pages for more information and options." +msgstr "per maggiori informazioni ed altre opzioni." + +#: cmdline/apt-cdrom.cc:76 cmdline/apt-cdrom.cc:144 cmdline/apt-cdrom.cc:189 +#: cmdline/apt-cdrom.cc:258 +#, c-format +msgid "Unable to change to %s" +msgstr "Impossibile cambiare a %s" + +#: apt-pkg/clean.cc:38 cmdline/apt-cdrom.cc:88 cmdline/apt-cdrom.cc:221 +#, c-format +msgid "Unable to read %s" +msgstr "Impossibile leggere %s" + +#: cmdline/apt-cdrom.cc:451 cmdline/apt-cdrom.cc:507 +#, c-format +msgid "Failed to open %s.new" +msgstr "Impossibile aprire %s.new" + +#: cmdline/apt-cdrom.cc:478 cmdline/apt-cdrom.cc:605 +#, c-format +msgid "Failed to rename %s.new to %s" +msgstr "Impossibile rinominare %s.new in %s" + +#: cmdline/apt-cdrom.cc:552 cmdline/apt-cdrom.cc:586 cmdline/apt-cdrom.cc:806 +#: cmdline/apt-cdrom.cc:824 +msgid "Internal error" +msgstr "Errore interno" + +#: cmdline/apt-cdrom.cc:650 +msgid "Using CD-ROM mount point " +msgstr "Utilizzo del punto di montaggio del CD-ROM " + +#: cmdline/apt-cdrom.cc:658 +#, c-format +msgid "Unable to read the cdrom database %s" +msgstr "Impossibile leggere la base dati %s" + +#: cmdline/apt-cdrom.cc:665 +msgid "Unmounting CD-ROM" +msgstr "Smontaggio del CD-ROM" + +#. Mount the new CDROM +#: cmdline/apt-cdrom.cc:669 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Prego, inserire un Disco nel drive e premere enter" + +#: cmdline/apt-cdrom.cc:670 +msgid "Mounting CD-ROM" +msgstr "Montaggio del CD-ROM" + +#: cmdline/apt-cdrom.cc:672 +msgid "Failed to mount the cdrom." +msgstr "Impossibile montare CD-ROM." + +#. Hash the CD to get an ID +#: cmdline/apt-cdrom.cc:676 +msgid "Identifying.. " +msgstr "Identificazione.. " + +#: cmdline/apt-cdrom.cc:686 +msgid "Scanning Disc for index files.. " +msgstr "Ricerca di file di indice nel Disco.. " + +#: cmdline/apt-cdrom.cc:702 +msgid "I found (binary):" +msgstr "Trovato (binario):" + +#: cmdline/apt-cdrom.cc:705 +msgid "I found (source):" +msgstr "Trovato (sorgente):" + +#: cmdline/apt-cdrom.cc:718 +msgid "Found " +msgstr "Trovato " + +#: cmdline/apt-cdrom.cc:718 +msgid " package indexes and " +msgstr " indici di pacchetti e " + +#: cmdline/apt-cdrom.cc:719 +msgid " source indexes." +msgstr " indici di sorgenti." + +#: cmdline/apt-cdrom.cc:724 +msgid "Unable to locate any package files, perhaps this is not a Debian Disc" +msgstr "Impossibile trovare pacchetti, forse non si tratta di un disco predisposto per apt." + +#: cmdline/apt-cdrom.cc:726 +msgid "" +"Unable to locate any package files, perhaps this is not a Conectiva Disc" +msgstr "Impossibile trovare pacchetti, forse non si tratta di un disco predisposto per apt." + +#: cmdline/apt-cdrom.cc:743 +msgid "Found label '" +msgstr "Incontrata l'etichetta '" + +#: cmdline/apt-cdrom.cc:751 +msgid "Please provide a name for this Disc, such as 'MyDistro 6.0 Disk 1'" +msgstr "Proponi un nome per questo disco, come 'Miadistro 4.0 disco 1'" + +#: cmdline/apt-cdrom.cc:761 +msgid "That is not a valid name, try again " +msgstr "Nome non valido, prova ancora " + +#: cmdline/apt-cdrom.cc:775 +msgid "This Disc is called:" +msgstr "Il nome di questo disco и:" + +#: cmdline/apt-cdrom.cc:794 +msgid "Writing new source list" +msgstr "Scrittura della nuova lista di sorgenti" + +#. Print the sourcelist entries +#: cmdline/apt-cdrom.cc:801 +msgid "Source List entries for this Disc are:" +msgstr "Le liste di sorgenti per questo Disco sono:" + +#: cmdline/apt-cdrom.cc:838 +msgid "Repeat this process for the rest of the CDs in your set." +msgstr "Ripetere questo procedimento per gli altri CD nel tuo set." + +#: cmdline/apt-cdrom.cc:858 +msgid "Usage: apt-cdrom [options] command" +msgstr "Uso: apt-cdrom [opzioni] comando" + +#: cmdline/apt-cdrom.cc:860 +msgid "apt-cdrom is a tool to add CDROM's to APT's source list. The " +msgstr "apt-cdrom и un tool per aggiungere CDROM alla lista di sorgenti per APT" +#: cmdline/apt-cdrom.cc:861 +msgid "CDROM mount point and device information is taken from apt.conf" +msgstr "Il punto di montaggio del CDROM e le informazioni sul device sono prese da apt.conf" + +#: cmdline/apt-cdrom.cc:862 +msgid "and /etc/fstab." +msgstr "e /etc/fstab." + +#: cmdline/apt-cdrom.cc:865 +msgid " add - Add a CDROM" +msgstr " add - Aggiunge un CD-ROM" + +#: cmdline/apt-cdrom.cc:868 +msgid " -h This help text" +msgstr " -h Questo testo di aiuto" + +#: cmdline/apt-cdrom.cc:869 +msgid " -d CD-ROM mount point" +msgstr " -d punto di montaggio del CD-ROM" + +#: cmdline/apt-cdrom.cc:870 +msgid " -r Rename a recognized CD-ROM" +msgstr " -r Cambia il nome di un CD-ROM riconosciuto" + +#: cmdline/apt-cdrom.cc:871 +msgid " -m No mounting" +msgstr " -m Senza montaggio" + +#: cmdline/apt-cdrom.cc:872 +msgid " -f Fast mode, don't check package files" +msgstr " -f Modo veloce, non verifica gli archivi" + +#: cmdline/apt-cdrom.cc:873 +msgid " -a Thorough scan mode" +msgstr " -a Modo di ricerca approfondita" + +#: cmdline/apt-cdrom.cc:876 +msgid "See fstab(5)" +msgstr "Vedi fstab(5)" + +#: cmdline/apt-cache.cc:116 +msgid " version " +msgstr " versione " + +#: cmdline/apt-cache.cc:117 +msgid " has an unmet dep:" +msgstr " ha una dipendenza irrisolta:" + +#: cmdline/apt-cache.cc:156 cmdline/apt-cache.cc:410 cmdline/apt-cache.cc:534 +#: cmdline/apt-cache.cc:1089 +#, c-format +msgid "Unable to locate package %s" +msgstr "Impossibile trovare il pacchetto %s" + +#: cmdline/apt-cache.cc:160 cmdline/apt-cache.cc:320 +msgid "Package: " +msgstr "Pacchetto: " + +#: cmdline/apt-cache.cc:161 +msgid "Versions: " +msgstr "Versioni: " + +#: cmdline/apt-cache.cc:172 +msgid "Reverse Depends: " +msgstr "Dipendenze invertite: " + +#: cmdline/apt-cache.cc:176 +msgid "Dependencies: " +msgstr "Dipendenze: " + +#: cmdline/apt-cache.cc:185 cmdline/apt-cache.cc:926 +msgid "Provides: " +msgstr "Forniture (Provides): " + +#: cmdline/apt-cache.cc:193 +msgid "Reverse Provides: " +msgstr "Forniture invertite: " + +#: cmdline/apt-cache.cc:207 +msgid "Total Package Names : " +msgstr "Numero totale di pacchetti : " + +#: cmdline/apt-cache.cc:247 +msgid " Normal Packages: " +msgstr " Pacchetti normali: " + +#: cmdline/apt-cache.cc:248 +msgid " Pure Virtual Packages: " +msgstr " Pacchetti virtuali puri: " + +#: cmdline/apt-cache.cc:249 +msgid " Single Virtual Packages: " +msgstr " Pacchetti virtuali semplici: " + +#: cmdline/apt-cache.cc:250 +msgid " Mixed Virtual Packages: " +msgstr " Pacchetti virtuali misti: " + +#: cmdline/apt-cache.cc:251 +msgid " Missing: " +msgstr " Mancanti: " + +#: cmdline/apt-cache.cc:253 +msgid "Total Distinct Versions: " +msgstr "Versioni differenti totali: " + +#: cmdline/apt-cache.cc:255 +msgid "Total Dependencies: " +msgstr "Dipendenze totali: " + +#: cmdline/apt-cache.cc:258 +msgid "Total Ver/File relations: " +msgstr "Totale relazioni versioni/file: " + +#: cmdline/apt-cache.cc:260 +msgid "Total Provides Mappings: " +msgstr "Mappatura totale delle forniture: " + +#: cmdline/apt-cache.cc:272 +msgid "Total Globbed Strings: " +msgstr "Totale stringhe 'globbed': " + +#: cmdline/apt-cache.cc:277 +msgid "Total Slack space: " +msgstr "Totale lasso di tempo: " + +#: cmdline/apt-cache.cc:285 +msgid "Total Space Accounted for: " +msgstr "Spazio totale occupato: " + +#: cmdline/apt-cache.cc:300 +msgid "Bad section " +msgstr "Sezione non valida " + +#: cmdline/apt-cache.cc:306 +msgid "Bad prio " +msgstr "Prioritа non valida " + +#: cmdline/apt-cache.cc:323 cmdline/apt-cache.cc:339 +msgid " Version: " +msgstr " Versione: " + +#: cmdline/apt-cache.cc:324 +msgid " File: " +msgstr " File: " + +#: cmdline/apt-cache.cc:326 +msgid " Depends: " +msgstr " Dipendenze: " + +#: cmdline/apt-cache.cc:332 +msgid "File: " +msgstr "File: " + +#: cmdline/apt-cache.cc:333 +msgid " Size: " +msgstr " Dimensione: " + +#: cmdline/apt-cache.cc:334 +msgid " ID: " +msgstr " ID: " + +#: cmdline/apt-cache.cc:335 +msgid " Flags: " +msgstr " Flags: " + +#: cmdline/apt-cache.cc:336 +msgid " Time: " +msgstr " Ora: " + +#: cmdline/apt-cache.cc:337 +msgid " Archive: " +msgstr " File: " + +#: cmdline/apt-cache.cc:338 +msgid " Component: " +msgstr " Componente: " + +#: cmdline/apt-cache.cc:340 +msgid " Origin: " +msgstr " Origine: " + +#: cmdline/apt-cache.cc:341 +msgid " Label: " +msgstr " Etichetta: " + +#: cmdline/apt-cache.cc:342 +msgid " Architecture: " +msgstr " Architettura: " + +#: cmdline/apt-cache.cc:669 +msgid "You must give at least one file name" +msgstr "Occorre immettere almeno un nome di file" + +#: cmdline/apt-cache.cc:688 +msgid "Generating cache" +msgstr "Generazione della cache" + +#: apt-pkg/systemfactory.cc:188 cmdline/apt-cache.cc:696 +#, c-format +msgid "Problem opening %s" +msgstr "Problema nell'apertura di %s" + +#: cmdline/apt-cache.cc:699 +msgid "Problem with SelectFile" +msgstr "Problema in SelectFile" + +#: cmdline/apt-cache.cc:702 +msgid "Problem with MergeList" +msgstr "Problema in MergeList" + +#: cmdline/apt-cache.cc:806 +msgid "Oh shit!" +msgstr "Perdindirindina!" + +#: cmdline/apt-cache.cc:841 +#, c-format +msgid "Package: %s\n" +msgstr "Pacchetto: %s\n" + +#: cmdline/apt-cache.cc:844 +#, c-format +msgid "Section: %s\n" +msgstr "Sezione: %s\n" + +#: cmdline/apt-cache.cc:847 +#, c-format +msgid "Installed Size: %i\n" +msgstr "Dimensione installata: %i\n" + +#: cmdline/apt-cache.cc:854 +#, c-format +msgid "Maintainer: %s\n" +msgstr "Manutentore: %s\n" + +#: cmdline/apt-cache.cc:858 +#, c-format +msgid "Version: %i:%s" +msgstr "Versione: %i:%s" + +#: cmdline/apt-cache.cc:860 +#, c-format +msgid "Version: %s" +msgstr "Versione: %s" + +#: cmdline/apt-cache.cc:894 +msgid "Pre-Depends: " +msgstr "Pre-dipendenze: " + +#: cmdline/apt-cache.cc:907 +msgid "Depends: " +msgstr "Dipendenze: " + +#: cmdline/apt-cache.cc:920 +msgid "Conflicts: " +msgstr "Conflitti: " + +#: cmdline/apt-cache.cc:932 +msgid "Obsoletes: " +msgstr "Obsoleti: " + +#: cmdline/apt-cache.cc:937 +#, c-format +msgid "Architecture: %s\n" +msgstr "Architettura: %s\n" + +#: cmdline/apt-cache.cc:940 +#, c-format +msgid "Size: %d\n" +msgstr "Dimensione: %d\n" + +#: cmdline/apt-cache.cc:943 +#, c-format +msgid "MD5sum: %s\n" +msgstr "MD5sum: %s\n" + +#: cmdline/apt-cache.cc:946 +#, c-format +msgid "Filename: %s\n" +msgstr "Nome file: %s\n" + +#: cmdline/apt-cache.cc:949 +#, c-format +msgid "Description: %s\n" +msgstr "Descrizione: %s\n" + +#: cmdline/apt-cache.cc:1038 +msgid "You must give exactly one pattern" +msgstr "Devi fornire esattamente un modello" + +#: cmdline/apt-cache.cc:1044 +msgid "Regex compilation error" +msgstr "Errore di compilazione dell'espressione regolare" + +#: cmdline/apt-cache.cc:1195 +msgid "Usage: apt-cache [options] command" +msgstr "Uso: apt-cache [opzioni] comando" + +#: cmdline/apt-cache.cc:1196 +msgid " apt-cache [options] add file1 [file1 ...]" +msgstr " apt-cache [opzioni] add file1 [file1 ...]" + +#: cmdline/apt-cache.cc:1197 +msgid " apt-cache [options] showpkg pkg1 [pkg2 ...]" +msgstr " apt-cache [opciones] showpkg pacch1 [pacch2 ...]" + +#: cmdline/apt-cache.cc:1199 +msgid "apt-cache is a low-level tool used to manipulate APT's binary" +msgstr "apt-cache и un tool di basso livello per manipolare il binario di APT" + +#: cmdline/apt-cache.cc:1200 +msgid "cache files stored in " +msgstr "file di cache salvati in " + +#: cmdline/apt-cache.cc:1201 +msgid "It is not meant for ordinary use only as a debug aide." +msgstr "Non и per uso corrente, ma solo come mezzo di debug." + +#: cmdline/apt-cache.cc:1204 +msgid " add - Add an package file to the source cache" +msgstr " add - Aggiunge un pacchetto alla cache dei sorgenti" + +#: cmdline/apt-cache.cc:1205 +msgid " gencaches - Build both the package and source cache" +msgstr " gencaches - Effettua un build del pacchetto e della cache del sorgente" + +#: cmdline/apt-cache.cc:1206 +msgid " showpkg - Show some general information for a single package" +msgstr " showpkg - Mostra informazioni generali su un pacchetto" + +#: cmdline/apt-cache.cc:1207 +msgid " stats - Show some basic statistics" +msgstr " stats - Mostra statistiche di base" + +#: cmdline/apt-cache.cc:1208 +msgid " dump - Show the entire file in a terse form" +msgstr " dump - Mostra tutto il file in una forma chiara" + +#: cmdline/apt-cache.cc:1209 +msgid " dumpavail - Print an available file to stdout" +msgstr " dumpavail - Stampa un file su stdout" + +#: cmdline/apt-cache.cc:1210 +msgid " unmet - Show unmet dependencies" +msgstr " unmet - Mostra le dipendenze irrisolte" + +#: cmdline/apt-cache.cc:1211 +msgid " check - Check the cache a bit" +msgstr " check - Verifica la cache" + +#: cmdline/apt-cache.cc:1212 +msgid " search - Search the package list for a regex pattern" +msgstr " search - Cerca una regex nella lista di pacchetti" + +#: cmdline/apt-cache.cc:1213 +msgid " show - Show a readable record for the package" +msgstr " show - Mostra un record leggibile per il pacchetto" + +#: cmdline/apt-cache.cc:1214 +msgid " depends - Show raw dependency information for a package" +msgstr " depends - Mostra le informazioni di dipendenza di un pacchetto" + +#: cmdline/apt-cache.cc:1215 +msgid " pkgnames - List the names of all packages" +msgstr " pkgnames - Mostra i nomi di tutti i pacchetti" + +#: cmdline/apt-cache.cc:1216 +msgid " dotty - Generate package graphs for GraphVis" +msgstr " dotty - Genera grafici di pacchetti per GraphVis" + +#: cmdline/apt-cache.cc:1219 cmdline/apt-config.cc:84 +msgid " -h This help text." +msgstr " -h Questo testo di aiuto." + +#: cmdline/apt-cache.cc:1220 +msgid " -p=? The package cache. [" +msgstr " -p=? La cache di pacchetti. [" + +#: cmdline/apt-cache.cc:1221 +msgid " -s=? The source cache. [" +msgstr " -s=? La cache di sorgenti. [" + +#: cmdline/apt-cache.cc:1222 +msgid " -q Disable progress indicator." +msgstr " -q Disabilita l'indicatore di avanzamento" + +#: cmdline/apt-cache.cc:1223 +msgid " -i Show only important deps for the unmet command." +msgstr " -i Mostra solo le dip. importanti per il comando unmet." + +#: cmdline/apt-cache.cc:1226 +msgid "See the apt-cache(8) and apt.conf(5) manual pages for more information." +msgstr "Vedi le manpage di apt-get(8) e apt.conf(5) per maggiori informazioni." + +#: cmdline/apt-config.cc:37 +msgid "Arguments not in pairs" +msgstr "Argomenti non in coppia" + +#: cmdline/apt-config.cc:75 +msgid "Usage: apt-config [options] command" +msgstr "Uso: apt-config [opzioni] comando" + +#: cmdline/apt-config.cc:77 +msgid "apt-config is a simple tool to read the APT config file" +msgstr "apt-config и un tool semplice per leggere il file di configurazione" + +#: cmdline/apt-config.cc:80 +msgid " shell - Shell mode" +msgstr " shell - Modo Shell" + +#: cmdline/apt-config.cc:81 +msgid " dump - Show the configuration" +msgstr " dump - Mostra la configurazione" + +#: apt-pkg/acquire-item.cc:142 +#, c-format +msgid "Size of %s did not match what's in the hashfile and was redownloaded." +msgstr "La dimensione di %s non coincide con quello che dice il file hash. Viene ripetuto il download" + +#: apt-pkg/acquire-item.cc:154 +#, c-format +msgid "MD5 of %s did not match what's int the hashfile and was redownloaded." +msgstr "L'MD5 di %s non coincide con quello che dice il file hash. Viene ripetuto il download." + +#: apt-pkg/acquire-item.cc:426 +msgid "Hashfile signer is not who it's supposed to be (expected " +msgstr "Chi ha firmato l'archivio non и chi ci si aspettava (atteso " + +#: apt-pkg/acquire-item.cc:428 +msgid ", got " +msgstr ", ottenuto " + +#: apt-pkg/acquire-worker.cc:108 +#, c-format +msgid "The method driver %s could not be found." +msgstr "Impossibile trovare il driver di metodo %s." + +#: apt-pkg/acquire-worker.cc:117 +msgid "Failed to create IPC pipe to subprocess" +msgstr "Impossibile creare una pipe IPC per il subprocesso" + +#: apt-pkg/acquire-worker.cc:160 +#, c-format +msgid "Method %s did not start correctly" +msgstr "Il metodo %s non si e' avviato correttamente" + +#: apt-pkg/acquire-worker.cc:197 +#, c-format +msgid "Invalid message from method %s: %s" +msgstr "Messaggio non valido dal metodo %s: %s" + +#: apt-pkg/acquire-worker.cc:210 +#, c-format +msgid "Unable to process Capabilities message from %s" +msgstr "Impossibile processare il messaggio sulle Capacitа da %s" + + +#: apt-pkg/acquire-worker.cc:229 +msgid "Method gave invalid 200 URI Start message" +msgstr "Il metodo ha restituito il messaggio non valido 200 URI Start" + +#: apt-pkg/acquire-worker.cc:268 +#, c-format +msgid "Bizzar Error - File size is not what the server reported %s %u" +msgstr "Errore anomalo - La dimensione del file non и quella riportata dal server %s %u" + +#: apt-pkg/acquire-worker.cc:297 +msgid "Method gave invalid 400 URI Failure message" +msgstr "Il metodo ha restituito il messaggio non valido 400 URI Failure" + +#: apt-pkg/acquire-worker.cc:319 +#, c-format +msgid "Method %s General failure: %s" +msgstr "Errore generale del metodo %s: %s" + +#: apt-pkg/acquire-worker.cc:503 +#, c-format +msgid "Method %s has died unexpectedly!" +msgstr "Il metodo %s и terminato inaspettatamente!" + +#: apt-pkg/acquire.cc:58 +#, c-format +msgid "Lists directory %spartial is missing." +msgstr "La lista di directory %spartial и mancante." + +#: apt-pkg/acquire.cc:62 +#, c-format +msgid "Archive directory %spartial is missing." +msgstr "La lista di file %spartial è mancante." + +#: apt-pkg/acquire.cc:557 +msgid "Tried to dequeue a fetching object" +msgstr "Si и tentato di interrompere lo scaricamento di un oggetto." + +#: apt-pkg/cachefile.cc:83 +msgid "The package lists or status file could not be parsed or opened." +msgstr "Non и stato possibile aprire la lista di pacchetti o il file di status." + +#: apt-pkg/cachefile.cc:85 +msgid "You may want to run apt-get update to correct these missing files" +msgstr "Dovresti eseguire apt-get update per correggere questi file mancanti." + +#: apt-pkg/clean.cc:44 +msgid "Unable to change to " +msgstr "Impossibile cambiare a " + +#: apt-pkg/clean.cc:58 +#, c-format +msgid "Unable to stat %s." +msgstr "Impossibile leggere %s." + +#: apt-pkg/depcache.cc:61 apt-pkg/depcache.cc:90 +msgid "Building Dependency Tree" +msgstr "Calcolo dell'albero delle dipendenze" + +#: apt-pkg/depcache.cc:62 +msgid "Candidate Versions" +msgstr "Versioni proposte" + +#: apt-pkg/depcache.cc:91 +msgid "Dependency Generation" +msgstr "Generazione delle dipendenze" + +#: apt-pkg/packagemanager.cc:397 +#, c-format +msgid "" +"This installation run will require temporarily removing the essential " +"package %s due to a Conflicts/Pre-Depends loop. This is often bad, but if " +"you really want to do it, activate the APT::Force-LoopBreak option." +msgstr "L'esecuzione di questa installazione costringerа a rimuovere temporaneamnete il pacchetto essenziale %s per un loop di Conflitti/Dipendenze. Questo spesso и un brutto segno, ma se veramente vuoi farlo attiva l'opzione APT::Force-LoopBreak." + +#: apt-pkg/pkgcache.cc:125 +msgid "The package cache file is corrupted" +msgstr "Il file della cache и corrotto" + +#: apt-pkg/pkgcache.cc:130 +msgid "The package cache file is an incompatible version" +msgstr "Il file della cache ha una versione incompatibile" + +#: apt-pkg/pkgcachegen.cc:90 +#, c-format +msgid "Error occured while processing %s (NewPackage)" +msgstr "Errore nel processare %s (NewPackage)" + +#: apt-pkg/pkgcachegen.cc:102 +#, c-format +msgid "Error occured while processing %s (UsePackage1)" +msgstr "Errore nel processare %s (UsePackage1)" + +#: apt-pkg/pkgcachegen.cc:124 +#, c-format +msgid "Error occured while processing %s (UsePackage2)" +msgstr "Errore nel processare %s (UsePackage2)" + +#: apt-pkg/pkgcachegen.cc:127 +#, c-format +msgid "Error occured while processing %s (NewFileVer1)" +msgstr "Errore nel processare %s (NewFileVer1)" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "WARNING: '" +msgstr "AVVISO: '" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "' has 2 packages with same version but different dependencies. " +msgstr "' contiene 2 pacchetti con la stessa versione ma dipendenze differenti. " + +#: apt-pkg/pkgcachegen.cc:139 +msgid "That usually means a packaging bug." +msgstr "Questo sta a indicare, di solito, un errore nel pacchetto." + +#: apt-pkg/pkgcachegen.cc:158 +#, c-format +msgid "Error occured while processing %s (NewVersion1)" +msgstr "Errore nel processare %s (NewVersion1)" + +#: apt-pkg/pkgcachegen.cc:161 +#, c-format +msgid "Error occured while processing %s (UsePackage3)" +msgstr "Errore nel processare %s (UsePackage3)" + +#: apt-pkg/pkgcachegen.cc:164 +#, c-format +msgid "Error occured while processing %s (NewVersion2)" +msgstr "Errore nel processare %s (NewVersion2)" + +#: apt-pkg/sourcelist.cc:76 +#, c-format +msgid "Block %s is invalid" +msgstr "Il blocco %s non и valido" + +#: apt-pkg/sourcelist.cc:121 +#, c-format +msgid "Malformed line %u in source list %s (type)" +msgstr "Linea %u errata nella lista di sorgenti %s (tipo)" + +#: apt-pkg/sourcelist.cc:123 apt-pkg/sourcelist.cc:135 +#, c-format +msgid "Malformed line %u in source list %s (URI)" +msgstr "Linea %u errata nella lista di sorgenti %s (URI)" + +#: apt-pkg/sourcelist.cc:130 +#, c-format +msgid "Malformed line %u in source list %s (vendor ID)" +msgstr "Linea %u errata nella lista di sorgenti %s (ID del produttore)" + +#: apt-pkg/sourcelist.cc:141 +#, c-format +msgid "Malformed line %u in source list %s (dist)" +msgstr "Linea %u errata nella lista di sorgenti %s (dist)" + +#: apt-pkg/sourcelist.cc:145 +#, c-format +msgid "Malformed line %u in source list %s (bad vendor ID)" +msgstr "Linea %u errata nella lista di sorgenti %s (ID del produttore errato)" + +#: apt-pkg/sourcelist.cc:148 +#, c-format +msgid "Malformed line %u in source list %s (bad type)" +msgstr "Linea %u errata nella lista di sorgenti %s (tipo errato)" + +#: apt-pkg/sourcelist.cc:151 +#, c-format +msgid "Malformed line %u in source list %s (bad URI)" +msgstr "Linea %u errata nella lista di sorgenti %s (URI errato)" + +#: apt-pkg/sourcelist.cc:161 +#, c-format +msgid "Malformed line %u in source list %s (Absolute dist)" +msgstr "Linea %u errata nella lista di sorgenti %s (dist assoluta)" + +#: apt-pkg/sourcelist.cc:174 +#, c-format +msgid "Malformed line %u in source list %s (dist parse)" +msgstr "Linea errata %u nella lista di sorgenti %s (analisi di dist)" + +#: apt-pkg/sourcelist.cc:353 +msgid "could not open hash index" +msgstr "Impossibile aprire l'indice hash" + +#: apt-pkg/sourcelist.cc:363 +msgid "No MD5SUM data in hashfile" +msgstr "Non ci sono dati MD5SUM nel file di hash" + +#: apt-pkg/sourcelist.cc:377 +msgid "Error parsing MD5 hash record" +msgstr "Errore nell'analisi del record hash MD5" + +#: apt-pkg/sourcelist.cc:400 +#, c-format +msgid "" +"Repository entry in sources.list contains extra components that are not " +"listed in the signed hash file: %s" +msgstr "La voce della repository in sources.list contiene componenti addizionali che non sono enumerati nell'archivio Hash firmato: %s" + +#: apt-pkg/srcrecords.cc:47 +msgid "Sorry, you must put some 'source' uris in your sources.list" +msgstr "Purtroppo и necessario inserire qualche 'uri' sorgente nella tua sources.list" + +#: apt-pkg/systemfactory.cc:72 +#, c-format +msgid "Failed to rename %s to %s" +msgstr "Impossibile rinominare %s in %s" + +#: apt-pkg/systemfactory.cc:77 +#, c-format +msgid "Couldn't stat source package list '%s' (%s)" +msgstr "Impossile la lettura della lista di pacchetti '%s' (%s)" + +#. Mostly from MakeStatusCache.. +#: apt-pkg/systemfactory.cc:184 apt-pkg/systemfactory.cc:240 +#: apt-pkg/systemfactory.cc:272 apt-pkg/systemfactory.cc:273 +#: apt-pkg/systemfactory.cc:280 apt-pkg/systemfactory.cc:350 +#: apt-pkg/systemfactory.cc:386 +msgid "Reading Package Lists" +msgstr "Lettura della lista di pacchetti" + +#: apt-pkg/systemfactory.cc:196 +#, c-format +msgid "Problem with SelectFile %s" +msgstr "Problema con SelectFile %s" + +#: apt-pkg/systemfactory.cc:201 +#, c-format +msgid "Problem with MergeList %s" +msgstr "Problema con la MergeList %s" + +#: apt-pkg/systemfactory.cc:263 +msgid "IO Error saving source cache" +msgstr "Errore I/O nel salvare la cache sorgente" + +#: apt-pkg/tagfile.cc:59 +#, c-format +msgid "Unable to parse package file %s (1)" +msgstr "Impossibile analizzare il pacchetto %s (1)" + +#: apt-pkg/tagfile.cc:142 +#, c-format +msgid "Unable to parse package file %s (2)" +msgstr "Impossibile analizzare il pacchetto %s (2)" diff --git a/apt/po/pt_BR.po b/apt/po/pt_BR.po new file mode 100644 index 0000000..aee2d47 --- /dev/null +++ b/apt/po/pt_BR.po @@ -0,0 +1,1500 @@ +# Portuguese messages for apt. +# Copyright (C) 2000 Free Software Foundation, Inc. +# Marcia Norie Nakaza , 2001. +# +msgid "" +msgstr "" +"Project-Id-Version: apt\n" +"POT-Creation-Date: 2001-01-10 13:40-0200\n" +"PO-Revision-Date: 2001-01-16 17:50-0200\n" +"Last-Translator: Marcia Norie Nakaza \n" +"Language-Team: Brazilian Portuguese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO-8859-1\n" +"Content-Transfer-Encoding: 8 bit\n" + +#. Yes/No +#: cmdline/apt-get.cc:129 +msgid "Y" +msgstr "S" + +#: cmdline/apt-get.cc:129 +msgid "y" +msgstr "s" + +#: cmdline/apt-get.cc:215 +msgid "Sorry, but the following packages have unmet dependencies:" +msgstr "Sinto muito, mas os pacotes a seguir tкm dependкncias nгo resolvidas:" + +#: cmdline/apt-get.cc:275 +msgid " but " +msgstr " mas " + +#: cmdline/apt-get.cc:278 +msgid " is installed" +msgstr " estб instalado" + +#: cmdline/apt-get.cc:278 +msgid " is to be installed" +msgstr " serб instalado" + +#: cmdline/apt-get.cc:284 +msgid "it is not installable" +msgstr "nгo й instalбvel" + +#: cmdline/apt-get.cc:286 +msgid "it is a virtual package" +msgstr "й um pacote virtual" + +#: cmdline/apt-get.cc:289 +msgid "it is not installed" +msgstr "nгo estб instalado" + +#: cmdline/apt-get.cc:289 +msgid "it is not going to be installed" +msgstr "nгo serб instalado" + +#: cmdline/apt-get.cc:294 +msgid " or" +msgstr " ou" + +#: cmdline/apt-get.cc:320 +msgid "The following NEW packages will be installed:" +msgstr "Os NOVOS pacotes a seguir serгo instalados:" + +#: cmdline/apt-get.cc:343 +msgid "The following packages will be REMOVED:" +msgstr "Os pacotes a seguir serгo REMOVIDOS:" + +#: cmdline/apt-get.cc:363 +msgid "The following packages have been kept back" +msgstr "Os pacotes a seguir serгo mantidos" + +#: cmdline/apt-get.cc:383 +msgid "The following packages will be upgraded" +msgstr "Os pacotes a seguir serгo atualizados" + +#: cmdline/apt-get.cc:415 +msgid "The following packages can be upgraded:" +msgstr "Os pacotes a seguir podem ser atualizados:" + +#: cmdline/apt-get.cc:426 +msgid " from " +msgstr " de " + +#: cmdline/apt-get.cc:427 +msgid " to " +msgstr " para " + +#: cmdline/apt-get.cc:429 +msgid " Importance: " +msgstr " Importвncia: " + +#: cmdline/apt-get.cc:430 +msgid " Date: " +msgstr " Data: " + +#: cmdline/apt-get.cc:450 +msgid "The following held packages will be changed:" +msgstr "Os pacotes a seguir serгo alterados:" + +#: cmdline/apt-get.cc:500 +#, c-format +msgid "%s (due to %s) " +msgstr "%s (devido a %s) " + +#: cmdline/apt-get.cc:508 +msgid "WARNING: The following essential packages will be removed" +msgstr "AVISO: Os seguintes pacotes essenciais serгo removidos" + +#: cmdline/apt-get.cc:509 +msgid "This should NOT be done unless you know exactly what you are doing!" +msgstr "" +"Isto NГO deve ser feito a menos que vocк saiba exatamente o que estб fazendo!" + +#: cmdline/apt-get.cc:531 +msgid " packages upgraded, " +msgstr " pacotes atualizados, " + +#: cmdline/apt-get.cc:532 +msgid " newly installed, " +msgstr " instalados agora, " + +#: cmdline/apt-get.cc:534 +msgid " reinstalled, " +msgstr " reinstalados, " + +#: cmdline/apt-get.cc:535 +msgid " to remove and " +msgstr " a serem removidos e " + +#: cmdline/apt-get.cc:536 +msgid " not upgraded." +msgstr " nгo atualizados." + +#: cmdline/apt-get.cc:539 +msgid " packages not fully installed or removed." +msgstr " pacotes nгo instalados totalmente ou removidos." + +#: apt-pkg/pkgrecords.cc:36 cmdline/apt-cache.cc:364 cmdline/apt-cache.cc:970 +#: cmdline/apt-cache.cc:1005 cmdline/apt-get.cc:555 +#, c-format +msgid "Package file %s is out of sync." +msgstr "O arquivo do pacote %s estб fora de sincronia." + +#: cmdline/apt-get.cc:672 +msgid "Correcting dependencies..." +msgstr "Corrigindo dependкncias..." + +#: cmdline/apt-get.cc:675 +msgid " failed." +msgstr " falhou." + +#: cmdline/apt-get.cc:678 +msgid "Unable to correct dependencies" +msgstr "Impossнvel corrigir dependкncias" + +#: cmdline/apt-get.cc:681 +msgid "Unable to minimize the upgrade set" +msgstr "Impossнvel minimizar o grupo de atualizaзгo" + +#: cmdline/apt-get.cc:683 +msgid " Done" +msgstr " Pronto" + +#: cmdline/apt-get.cc:687 +msgid "You might want to run `apt-get -f install' to correct these." +msgstr "Vocк pode executar `apt-get -f install' para corrigi-los." + +#: cmdline/apt-get.cc:690 +msgid "Unmet dependencies. Try using -f." +msgstr "Dependкncias nгo resolvidas. Tente usar -f." + +#: cmdline/apt-get.cc:743 +msgid "Internal Error, InstallPackages was called with broken packages!" +msgstr "Erro interno, InstallPackages foi chamado com pacotes corrompidos!" + +#: cmdline/apt-get.cc:752 +msgid "Packages need to be removed but No Remove was specified." +msgstr "Pacotes precisam ser removidos mas Nгo Remover foi especificado." + +#: cmdline/apt-get.cc:762 +msgid "Internal Error, Ordering didn't finish" +msgstr "Erro interno, a ordenaзгo nгo terminou" + +#: cmdline/apt-get.cc:777 cmdline/apt-get.cc:1536 cmdline/apt-get.cc:1569 +msgid "Unable to lock the download directory" +msgstr "Impossнvel criar lock no diretуrio de download" + +#: apt-pkg/cachefile.cc:73 cmdline/apt-get.cc:787 cmdline/apt-get.cc:1619 +msgid "The list of sources could not be read." +msgstr "A lista de fontes nгo pфde ser lida." + +#: cmdline/apt-get.cc:804 +msgid "How odd.. The sizes didn't match, email apt@packages.debian.org" +msgstr "" +"Os tamanhos nгo sгo iguais, envie um e-mail para apt@packages.debian.org" + +#. Number of bytes +#: cmdline/apt-get.cc:808 cmdline/apt-get.cc:1752 +msgid "Need to get " +msgstr "Й necessбria a obtenзгo de " + +#: cmdline/apt-get.cc:814 +msgid " of archives. After unpacking " +msgstr " para os arquivos. Apуs desempacotar, " + +#: cmdline/apt-get.cc:818 +msgid "B will be used." +msgstr "B serгo usados." + +#: cmdline/apt-get.cc:820 +msgid "B will be freed." +msgstr "B serгo liberados." + +#: cmdline/apt-get.cc:832 cmdline/apt-get.cc:1745 +#, c-format +msgid "Couldn't determine free space in %s" +msgstr "Nгo foi possнvel determinar espaзo livre em %s" + +#: cmdline/apt-get.cc:835 +#, c-format +msgid "Sorry, you don't have enough free space in %s to hold all packages." +msgstr "" +"Sinto muito, vocк nгo tem espaзo livre suficiente em %s para manter todos os " +"pacotes." + +#: cmdline/apt-get.cc:844 +msgid "There are problems and -y was used without --force-yes" +msgstr "Nгo hб problemas e -y foi usado sem --force-yes" + +#: cmdline/apt-get.cc:850 cmdline/apt-get.cc:867 +msgid "Trivial Only specified but this is not a trivial operation." +msgstr "Apenas trivial foi especificado mas esta nгo й uma operaзгo trivial." + +#: cmdline/apt-get.cc:852 +msgid "You are about to do something potentially harmful" +msgstr "Vocк estб prestes a fazer algo realmente danoso" + +#: cmdline/apt-get.cc:853 +msgid "To continue type in the phrase 'Yes, I understand this may be bad'" +msgstr "Para continuar digite a frase 'Sim, eu sei que isso pode ser ruim'" + +#: cmdline/apt-get.cc:854 +msgid " ?] " +msgstr " ?] " + +#: cmdline/apt-get.cc:855 +msgid "Yes, I understand this may be bad" +msgstr "Sim, eu sei que isso pode ser ruim" + +#: cmdline/apt-get.cc:857 cmdline/apt-get.cc:876 +msgid "Aborted." +msgstr "Abortado." + +#: cmdline/apt-get.cc:872 +msgid "Do you want to continue? [Y/n] " +msgstr "Vocк quer continuar? [S/n] " + +#: cmdline/apt-get.cc:936 cmdline/apt-get.cc:1196 cmdline/apt-get.cc:1788 +msgid "Failed to fetch " +msgstr "Falhou ao obter " + +#: cmdline/apt-get.cc:954 +msgid "Some files failed to download" +msgstr "Houve falha ao baixar alguns arquivos" + +#: cmdline/apt-get.cc:960 +msgid "Unable to fetch some archives, maybe try with --fix-missing?" +msgstr "Impossнvel obter alguns arquivos, tentar talvez com --fix-missing?" + +#: cmdline/apt-get.cc:964 +msgid "--fix-missing and media swapping is not currently supported" +msgstr "--fix-missing e troca de meio nгo sгo atualmente suportados" + +#: cmdline/apt-get.cc:969 +msgid "Unable to correct missing packages." +msgstr "Impossнvel corrigir pacotes perdidos." + +#: cmdline/apt-get.cc:970 +msgid "Aborting Install." +msgstr "Cancelando a instalaзгo." + +#: cmdline/apt-get.cc:1001 +msgid "Note, selecting " +msgstr "Nota, selecionando " + +#: cmdline/apt-get.cc:1001 +msgid " instead of " +msgstr " em vez de " + +#: cmdline/apt-get.cc:1010 +msgid "Skipping " +msgstr "Omitindo " + +#: cmdline/apt-get.cc:1010 +msgid ", it is already installed and no-upgrade is set." +msgstr ", jб estб instalado e a opзгo no-upgrade estб habilitada." + +#: cmdline/apt-get.cc:1020 +#, c-format +msgid "Package %s is not installed" +msgstr "O pacote %s nгo estб instalado" + +#: cmdline/apt-cache.cc:116 cmdline/apt-get.cc:1030 cmdline/apt-get.cc:1050 +msgid "Package " +msgstr "Pacote " + +#: cmdline/apt-get.cc:1030 +msgid " is a virtual package provided by:" +msgstr " й um pacote virtual fornecido por:" + +#: cmdline/apt-get.cc:1041 +msgid " [Installed]" +msgstr " [Instalado]" + +#: cmdline/apt-get.cc:1046 +msgid "You should explicitly select one to install." +msgstr "Vocк deve selecionar de forma explнcita um para ser instalado." + +#: cmdline/apt-get.cc:1050 +msgid " has no available version, but exists in the database." +msgstr " nгo tem versгo disponнvel, mas existe no banco de dados." + +#: cmdline/apt-get.cc:1051 +msgid "" +"This typically means that the package was mentioned in a dependency and " +msgstr "Isto significa que o pacote foi mencionado em uma dependкncia e " + +#: cmdline/apt-get.cc:1052 +msgid "" +"never uploaded, has been obsoleted or is not available with the contents " +msgstr "nunca foi carregado, se tornou obsoleto ou nгo estб disponнvel com os conteъdos " + +#: cmdline/apt-get.cc:1053 +msgid "of sources.list" +msgstr "de sources.list" + +#: cmdline/apt-get.cc:1064 +msgid "However the following packages replace it:" +msgstr "No entanto, os pacotes a seguir o substituem:" + +#: cmdline/apt-get.cc:1067 +#, c-format +msgid "Package %s has no installation candidate" +msgstr "O pacote %s nгo tem candidato a instalaзгo" + +#: cmdline/apt-get.cc:1087 +msgid "Sorry, re-installation of " +msgstr "Sinto, a reinstalaзгo de " + +#: cmdline/apt-get.cc:1087 +msgid " is not possible, it cannot be downloaded" +msgstr " nгo й possнvel, este nгo pode ser carregado" + +#: cmdline/apt-get.cc:1094 +msgid "Sorry, " +msgstr "Sinto, " + +#: cmdline/apt-get.cc:1094 +msgid " is already the newest version" +msgstr " jб й a versгo mais nova" + +#: cmdline/apt-get.cc:1123 +msgid "Unable to lock the list directory" +msgstr "Impossнvel bloquear o diretуrio list" + +#: cmdline/apt-get.cc:1148 +msgid "Could not retrieve digitally signed hash file" +msgstr "Nгo foi possнvel recuperar arquivo hash assinado digitalmente" + +#: cmdline/apt-get.cc:1160 +msgid "Failed to fetch hash file: " +msgstr "Falhou ao obter arquivo hash: " + +#: cmdline/apt-get.cc:1168 +msgid "" +"Some of the signed hash files could not be retrieved. Aborting operation." +msgstr "" +"Alguns dos arquivos hash assinados nгo puderam ser recuperados. Cancelando a " +"operaзгo." + +#: cmdline/apt-get.cc:1210 +msgid "Some of the index files had mismatching MD5 sums!" +msgstr "Alguns do arquivos de нndice tinham somas MD5 incompatнveis!" + +#: cmdline/apt-get.cc:1218 +msgid "" +"Some index files failed to download, they have been ignored, or old ones " +"used instead." +msgstr "" +"Houve falha de download de alguns arquivos de нndice, eles sгo ignorados ou " +"os antigos serгo usados." + +#: cmdline/apt-get.cc:1223 +msgid " will not be authenticated." +msgstr " nгo serб autenticado." + +#: cmdline/apt-get.cc:1244 +msgid "Internal Error, AllUpgrade broke stuff" +msgstr "Erro interno no AllUpgrade" + +#: cmdline/apt-get.cc:1313 cmdline/apt-get.cc:1346 +#, c-format +msgid "Couldn't find package %s" +msgstr "Nгo foi possнvel encontrar o pacote %s" + +#: cmdline/apt-get.cc:1326 +msgid "Regex compilation error:" +msgstr "Erro de compilaзгo de Regex:" + +#: cmdline/apt-get.cc:1360 +msgid "You might want to run `apt-get -f install' to correct these:" +msgstr "Vocк pode querer executar `apt-get -f install' para corrigir estas:" + +#: cmdline/apt-get.cc:1363 +msgid "" +"Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a " +"solution)." +msgstr "" +"dependкncias nгo resolvidas. Tente 'apt-get -f install' sem pacotes (ou " +"especifique uma soluзгo)." + +#: cmdline/apt-get.cc:1374 +msgid "Some packages could not be installed. This may mean that you have" +msgstr "" +"Alguns pacotes podem nгo ter sido instalados. Isto pode significar que vocк" + +#: cmdline/apt-get.cc:1375 +msgid "requested an impossible situation or if you are using the unstable" +msgstr "solicitou uma situaзгo impossнvel ou vocк estб usando a distribuiзгo" + +#: cmdline/apt-get.cc:1376 +msgid "distribution that some required packages have not yet been created" +msgstr "instбvel onde alguns pacotes necessбrios ainda nгo foram criados" + +#: cmdline/apt-get.cc:1377 +msgid "or been moved out of Incoming." +msgstr "ou foram movidos de Entrada." + +#: cmdline/apt-get.cc:1381 +msgid "Since you only requested a single operation it is extremely likely that" +msgstr "" +"Uma vez que vocк solicitou apenas uma operaзгo simples й extremamente " +"provбvel que" + +#: cmdline/apt-get.cc:1382 +msgid "the package is simply not installable and a bug report against" +msgstr "o pacote simplesmente nгo esteja instalado e um relatуrio de bug" + +#: cmdline/apt-get.cc:1383 +msgid "that package should be filed." +msgstr "deste pacote deve ser preenchido." + +#: cmdline/apt-get.cc:1386 +msgid "The following information may help to resolve the situation:" +msgstr "A informaзгo a seguir pode ajudar a solucionar a situaзгo:" + +#: cmdline/apt-get.cc:1389 +msgid "Sorry, broken packages" +msgstr "Sinto, pacotes corrompidos" + +#: cmdline/apt-get.cc:1412 +msgid "The following extra packages will be installed:" +msgstr "Os seguintes pacotes extras serгo instalados:" + +#: cmdline/apt-get.cc:1431 +msgid "Calculating Upgrade... " +msgstr "Calculando atualizaзгo... " + +#: cmdline/apt-get.cc:1434 +msgid "Failed" +msgstr "Falhou" + +#: cmdline/apt-get.cc:1439 +msgid "Done" +msgstr "Pronto" + +#: cmdline/apt-get.cc:1504 cmdline/apt-get.cc:1512 +msgid "Internal Error, problem resolver broke stuff" +msgstr "Erro interno no solucionador de problemas" + +#: cmdline/apt-get.cc:1614 +msgid "Must specify at least one package to fetch source for" +msgstr "Deve-se especificar pelo menos um pacote para buscar fonte para" + +#: cmdline/apt-get.cc:1688 +#, c-format +msgid "Unable to find a source package for %s" +msgstr "Impossнvel encontrar um pacote-fonte para %s" + +#: cmdline/apt-get.cc:1748 +#, c-format +msgid "Sorry, you don't have enough free space in %s" +msgstr "Sinto, vocк nгo tem espaзo livre suficiente em %s" + +#: cmdline/apt-get.cc:1757 +msgid " of source archives." +msgstr " de arquivos-fonte." + +#: cmdline/apt-get.cc:1762 +msgid "Fetch Source " +msgstr "Obter fonte" + +#: cmdline/apt-get.cc:1793 +msgid "Failed to fetch some archives." +msgstr "Falhou ao obter alguns arquivos." + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1859 +msgid "Build command '" +msgstr "Construir comando '" + +#: cmdline/apt-get.cc:1813 cmdline/apt-get.cc:1842 cmdline/apt-get.cc:1859 +msgid "' failed." +msgstr "' falhou." + +#: cmdline/apt-get.cc:1831 +msgid "Skipping unpack of already unpacked source in " +msgstr "Omitindo o desempacotamento de fonte jб desempacotado em " + +#: cmdline/apt-get.cc:1842 +msgid "Unpack command '" +msgstr "O comando de desempacotamento '" + +#: cmdline/apt-get.cc:1875 +msgid "Couldn't wait for subprocess" +msgstr "Nгo foi possнvel esperar por subprocesso" + +#: cmdline/apt-get.cc:1879 +msgid "Child process failed" +msgstr "Processo-filho falhou" + +#: cmdline/apt-get.cc:1895 +msgid "Usage: apt-get [options] command" +msgstr "Uso: apt-get [opзхes] comando" + +#: cmdline/apt-get.cc:1896 +msgid " apt-get [options] install pkg1 [pkg2 ...]" +msgstr " apt-get [opзхes] install pac1 [pac2 ...]" + +#: cmdline/apt-get.cc:1898 +msgid "apt-get is a simple command line interface for downloading and" +msgstr "apt-get й uma interface de linha de comando simples para download e" + +#: cmdline/apt-get.cc:1899 +msgid "installing packages. The most frequently used commands are update" +msgstr "" +"instalaзгo de pacotes. Os comandos usados com mais freqькncia sгo update" + +#: cmdline/apt-get.cc:1900 +msgid "and install." +msgstr "e install." + +#: cmdline/apt-cache.cc:1203 cmdline/apt-cdrom.cc:864 cmdline/apt-config.cc:79 +#: cmdline/apt-get.cc:1902 +msgid "Commands:" +msgstr "Comandos:" + +#: cmdline/apt-get.cc:1903 +msgid " update - Retrieve new lists of packages" +msgstr " update - Recupera listas novas de pacotes" + +#: cmdline/apt-get.cc:1904 +msgid " upgrade - Perform an upgrade" +msgstr " upgrade - Executa um upgrade" + +#: cmdline/apt-get.cc:1905 +msgid " install - Install new packages" +msgstr " install - Instala novos pacotes" + +#: cmdline/apt-get.cc:1906 +msgid " remove - Remove packages" +msgstr " remove - Remove pacotes" + +#: cmdline/apt-get.cc:1907 +msgid " source - Download source archives" +msgstr " source - Baixa arquivos-fonte" + +#: cmdline/apt-get.cc:1908 +msgid " dist-upgrade - Distribution upgrade, see apt-get(8)" +msgstr " dist-upgrade - Upgrade de distribuiзгo, ver apt-get(8)" + +#. cout << " dselect-upgrade - Follow dselect selections" << endl; +#: cmdline/apt-get.cc:1910 +msgid " clean - Erase downloaded archive files" +msgstr " clean - Apaga arquivos baixados" + +#: cmdline/apt-get.cc:1911 +msgid " autoclean - Erase old downloaded archive files" +msgstr " autoclean - Apaga arquivos antigos baixados" + +#: cmdline/apt-get.cc:1912 +msgid " check - Verify that there are no broken dependencies" +msgstr " check - Verifica se nгo hб dependкncias" + +#: cmdline/apt-cache.cc:1218 cmdline/apt-cdrom.cc:867 cmdline/apt-config.cc:83 +#: cmdline/apt-get.cc:1914 +msgid "Options:" +msgstr "Opзхes:" + +#: cmdline/apt-get.cc:1915 +msgid " -h This help text." +msgstr " -h Este texto de ajuda." + +#: cmdline/apt-get.cc:1916 +msgid " -q Loggable output - no progress indicator" +msgstr " -q Saнda acessнvel - nenhum indicador de progresso" + +#: cmdline/apt-get.cc:1917 +msgid " -qq No output except for errors" +msgstr " -qq Sem mensagens, exceto para erros" + +#: cmdline/apt-get.cc:1918 +msgid " -S Show summary for upgrade operation and quit" +msgstr " -S Exibe resumo para operaзгo de upgrade e sai" + +#: cmdline/apt-get.cc:1919 +msgid " -d Download only - do NOT install or unpack archives" +msgstr " -d Apenas download - NГO instala ou desempacota arquivos" + +#: cmdline/apt-get.cc:1920 +msgid " -s No-act. Perform ordering simulation" +msgstr " -s Nenhuma aзгo. Executa simulaзгo de ordenaзгo" + +#: cmdline/apt-get.cc:1921 +msgid " -y Assume Yes to all queries and do not prompt" +msgstr " -y Assume Sim para todas as consultas e nгo exibe" + +#: cmdline/apt-get.cc:1922 +msgid " -f Attempt to continue if the integrity check fails" +msgstr " -f Tenta continuar se falhar a verificaзгo de integridade" + +#: cmdline/apt-get.cc:1923 +msgid " -m Attempt to continue if archives are unlocatable" +msgstr " -m Tenta continuar se arquivos nгo puderem ser localizados" + +#: cmdline/apt-get.cc:1924 +msgid " -u Show a list of upgraded packages as well" +msgstr " -u Exibe uma lista de pacotes atualizados" + +#: cmdline/apt-get.cc:1925 +msgid " -b Build the source package after fetching it" +msgstr " -b Constrуi o pacote-fonte apуs buscб-lo" + +#: cmdline/apt-cache.cc:1224 cmdline/apt-cdrom.cc:874 cmdline/apt-config.cc:85 +#: cmdline/apt-get.cc:1926 +msgid " -c=? Read this configuration file" +msgstr " -c=? Lк este arquivo de configuraзгo" + +#: cmdline/apt-cache.cc:1225 cmdline/apt-cdrom.cc:875 cmdline/apt-config.cc:86 +#: cmdline/apt-get.cc:1927 +msgid " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" +msgstr "" +" -o=? Ajusta uma opзгo de configuraзгo arbitrбria, p.ex -o dir::cache=/tmp" + +#: cmdline/apt-get.cc:1928 +msgid "See the apt-get(8), sources.list(5) and apt.conf(5) manual" +msgstr "Consulte as manpages de apt-get(8), sources.list(5) e apt.conf(5)" + +#: cmdline/apt-get.cc:1929 +msgid "pages for more information and options." +msgstr "para maiores informaзхes e opзхes." + +#: cmdline/apt-cdrom.cc:76 cmdline/apt-cdrom.cc:144 cmdline/apt-cdrom.cc:189 +#: cmdline/apt-cdrom.cc:258 +#, c-format +msgid "Unable to change to %s" +msgstr "Impossнvel alterar para %s" + +#: apt-pkg/clean.cc:38 cmdline/apt-cdrom.cc:88 cmdline/apt-cdrom.cc:221 +#, c-format +msgid "Unable to read %s" +msgstr "Impossнvel ler %s" + +#: cmdline/apt-cdrom.cc:451 cmdline/apt-cdrom.cc:507 +#, c-format +msgid "Failed to open %s.new" +msgstr "Falhou ao abrir %s.new" + +#: cmdline/apt-cdrom.cc:478 cmdline/apt-cdrom.cc:605 +#, c-format +msgid "Failed to rename %s.new to %s" +msgstr "Falhou ao renomear %s.new para %s" + +#: cmdline/apt-cdrom.cc:552 cmdline/apt-cdrom.cc:586 cmdline/apt-cdrom.cc:806 +#: cmdline/apt-cdrom.cc:824 +msgid "Internal error" +msgstr "Erro interno" + +#: cmdline/apt-cdrom.cc:650 +msgid "Using CD-ROM mount point " +msgstr "Usando ponto de montagem do CD-ROM " + +#: cmdline/apt-cdrom.cc:658 +#, c-format +msgid "Unable to read the cdrom database %s" +msgstr "Impossнvel ler o banco de dados %s do CD-ROM" + +#: cmdline/apt-cdrom.cc:665 +msgid "Unmounting CD-ROM" +msgstr "Desmontando o CD-ROM" + +#. Mount the new CDROM +#: cmdline/apt-cdrom.cc:669 +msgid "Please insert a Disc in the drive and press enter" +msgstr "Insira um disco no drive e pressione Enter" + +#: cmdline/apt-cdrom.cc:670 +msgid "Mounting CD-ROM" +msgstr "Montando o CD-ROM" + +#: cmdline/apt-cdrom.cc:672 +msgid "Failed to mount the cdrom." +msgstr "Falhou ao montar o CD-ROM." + +#. Hash the CD to get an ID +#: cmdline/apt-cdrom.cc:676 +msgid "Identifying.. " +msgstr "Identificando.. " + +#: cmdline/apt-cdrom.cc:686 +msgid "Scanning Disc for index files.. " +msgstr "Procurando por arquivos de нndice no disco.. " + +#: cmdline/apt-cdrom.cc:702 +msgid "I found (binary):" +msgstr "Eu encontrei (binбrio):" + +#: cmdline/apt-cdrom.cc:705 +msgid "I found (source):" +msgstr "Eu encontrei (fonte):" + +#: cmdline/apt-cdrom.cc:718 +msgid "Found " +msgstr "Encontrei " + +#: cmdline/apt-cdrom.cc:718 +msgid " package indexes and " +msgstr " нndices de pacotes e " + +#: cmdline/apt-cdrom.cc:719 +msgid " source indexes." +msgstr " нndices de fonte." + +#: cmdline/apt-cdrom.cc:724 +msgid "Unable to locate any package files, perhaps this is not a Debian Disc" +msgstr "" +"Nгo й possнvel localizar nenhum arquivo de pacote, talvez este nгo seja um " +"disco do Debian" + +#: cmdline/apt-cdrom.cc:726 +msgid "" +"Unable to locate any package files, perhaps this is not a Conectiva Disc" +msgstr "" +"Nгo й possнvel localizar nenhum arquivo de pacote, talvez este nгo seja um " +"disco do Conectiva" + +#: cmdline/apt-cdrom.cc:743 +msgid "Found label '" +msgstr "Rуtulo encontrado '" + +#: cmdline/apt-cdrom.cc:751 +msgid "Please provide a name for this Disc, such as 'MyDistro 6.0 Disk 1'" +msgstr "Forneзa um nome para este disco, como 'MinhaDistro 6.0 Disco 1'" + +#: cmdline/apt-cdrom.cc:761 +msgid "That is not a valid name, try again " +msgstr "Este nгo й um nome vбlido, tente novamente " + +#: cmdline/apt-cdrom.cc:775 +msgid "This Disc is called:" +msgstr "Este disco й chamado:" + +#: cmdline/apt-cdrom.cc:794 +msgid "Writing new source list" +msgstr "Gravando nova lista-fonte" + +#. Print the sourcelist entries +#: cmdline/apt-cdrom.cc:801 +msgid "Source List entries for this Disc are:" +msgstr "As entradas de lista-fonte para este disco sгo:" + +#: cmdline/apt-cdrom.cc:838 +msgid "Repeat this process for the rest of the CDs in your set." +msgstr "Repetir este processo para o restante dos CDs em seu conjunto." + +#: cmdline/apt-cdrom.cc:858 +msgid "Usage: apt-cdrom [options] command" +msgstr "Uso: apt-cdrom [opзхes] comando" + +#: cmdline/apt-cdrom.cc:860 +msgid "apt-cdrom is a tool to add CDROM's to APT's source list. The " +msgstr "" +"apt-cdrom й uma ferramenta para adicionar a lista de fontes do CD-ROM para a " +"do APT." + +#: cmdline/apt-cdrom.cc:861 +msgid "CDROM mount point and device information is taken from apt.conf" +msgstr "" +"As informaзхes do ponto de montagem e do dispositivo CD-ROM sгo retiradas do " +"apt.conf" + +#: cmdline/apt-cdrom.cc:862 +msgid "and /etc/fstab." +msgstr "e /etc/fstab." + +#: cmdline/apt-cdrom.cc:865 +msgid " add - Add a CDROM" +msgstr " add - Adicione um CD-ROM" + +#: cmdline/apt-cdrom.cc:868 +msgid " -h This help text" +msgstr " -h Este texto de ajuda" + +#: cmdline/apt-cdrom.cc:869 +msgid " -d CD-ROM mount point" +msgstr " -d Ponto de montagem do CD-ROM" + +#: cmdline/apt-cdrom.cc:870 +msgid " -r Rename a recognized CD-ROM" +msgstr " -r Renomear um CD-ROM reconhecido" + +#: cmdline/apt-cdrom.cc:871 +msgid " -m No mounting" +msgstr " -m Sem montagem" + +#: cmdline/apt-cdrom.cc:872 +msgid " -f Fast mode, don't check package files" +msgstr " -f Modo rбpido, nгo verifica os arquivos de pacote" + +#: cmdline/apt-cdrom.cc:873 +msgid " -a Thorough scan mode" +msgstr " -a Pelo modo scan" + +#: cmdline/apt-cdrom.cc:876 +msgid "See fstab(5)" +msgstr "Veja fstab(5)" + +#: cmdline/apt-cache.cc:116 +msgid " version " +msgstr " versгo " + +#: cmdline/apt-cache.cc:117 +msgid " has an unmet dep:" +msgstr " hб uma dependкncia nгo resolvida:" + +#: cmdline/apt-cache.cc:156 cmdline/apt-cache.cc:410 cmdline/apt-cache.cc:534 +#: cmdline/apt-cache.cc:1089 +#, c-format +msgid "Unable to locate package %s" +msgstr "Impossнvel localizar o pacote %s" + +#: cmdline/apt-cache.cc:160 cmdline/apt-cache.cc:320 +msgid "Package: " +msgstr "Pacote: " + +#: cmdline/apt-cache.cc:161 +msgid "Versions: " +msgstr "Versхes: " + +#: cmdline/apt-cache.cc:172 +msgid "Reverse Depends: " +msgstr "Dependкncias inversas: " + +#: cmdline/apt-cache.cc:176 +msgid "Dependencies: " +msgstr "Dependкncias: " + +#: cmdline/apt-cache.cc:185 cmdline/apt-cache.cc:926 +msgid "Provides: " +msgstr "Provimentos: " + +#: cmdline/apt-cache.cc:193 +msgid "Reverse Provides: " +msgstr "Provimentos reversos: " + +#: cmdline/apt-cache.cc:207 +msgid "Total Package Names : " +msgstr "Total de pacotes : " + +#: cmdline/apt-cache.cc:247 +msgid " Normal Packages: " +msgstr " Pacotes normais: " + +#: cmdline/apt-cache.cc:248 +msgid " Pure Virtual Packages: " +msgstr " Pacotes virtuais puros: " + +#: cmdline/apt-cache.cc:249 +msgid " Single Virtual Packages: " +msgstr " Pacotes virtuais simples: " + +#: cmdline/apt-cache.cc:250 +msgid " Mixed Virtual Packages: " +msgstr " Pacotes virtuais mistos: " + +#: cmdline/apt-cache.cc:251 +msgid " Missing: " +msgstr " Faltando: " + +#: cmdline/apt-cache.cc:253 +msgid "Total Distinct Versions: " +msgstr "Total de versхes distintas: " + +#: cmdline/apt-cache.cc:255 +msgid "Total Dependencies: " +msgstr "Total de dependкncias: " + +#: cmdline/apt-cache.cc:258 +msgid "Total Ver/File relations: " +msgstr "Total de relaзхes versгo/arquivo: " + +#: cmdline/apt-cache.cc:260 +msgid "Total Provides Mappings: " +msgstr "Total de mapeamentos de provimentos: " + +#: cmdline/apt-cache.cc:272 +msgid "Total Globbed Strings: " +msgstr "Total de strings casadas: " + +#: cmdline/apt-cache.cc:277 +msgid "Total Slack space: " +msgstr "Total de espaзo temporбrio: " + +#: cmdline/apt-cache.cc:285 +msgid "Total Space Accounted for: " +msgstr "Espaзo total contabilizado para: " + +#: cmdline/apt-cache.cc:300 +msgid "Bad section " +msgstr "Seзгo invбlida " + +#: cmdline/apt-cache.cc:306 +msgid "Bad prio " +msgstr "Prioridade invбlida " + +#: cmdline/apt-cache.cc:323 cmdline/apt-cache.cc:339 +msgid " Version: " +msgstr " Versгo: " + +#: cmdline/apt-cache.cc:324 +msgid " File: " +msgstr " Arquivo: " + +#: cmdline/apt-cache.cc:326 +msgid " Depends: " +msgstr " Dependкncias: " + +#: cmdline/apt-cache.cc:332 +msgid "File: " +msgstr "Arquivo: " + +#: cmdline/apt-cache.cc:333 +msgid " Size: " +msgstr " Tamanho: " + +#: cmdline/apt-cache.cc:334 +msgid " ID: " +msgstr " ID: " + +#: cmdline/apt-cache.cc:335 +msgid " Flags: " +msgstr " Flags: " + +#: cmdline/apt-cache.cc:336 +msgid " Time: " +msgstr " Hora: " + +#: cmdline/apt-cache.cc:337 +msgid " Archive: " +msgstr " Arquivo: " + +#: cmdline/apt-cache.cc:338 +msgid " Component: " +msgstr " Componente: " + +#: cmdline/apt-cache.cc:340 +msgid " Origin: " +msgstr " Origem: " + +#: cmdline/apt-cache.cc:341 +msgid " Label: " +msgstr " Rуtulo: " + +#: cmdline/apt-cache.cc:342 +msgid " Architecture: " +msgstr " Arquitetura: " + +#: cmdline/apt-cache.cc:669 +msgid "You must give at least one file name" +msgstr "Pelo menos um nome de arquivo deve ser fornecido" + +#: cmdline/apt-cache.cc:688 +msgid "Generating cache" +msgstr "Gerando cache" + +#: apt-pkg/systemfactory.cc:188 cmdline/apt-cache.cc:696 +#, c-format +msgid "Problem opening %s" +msgstr "Problema ao abrir %s" + +#: cmdline/apt-cache.cc:699 +msgid "Problem with SelectFile" +msgstr "Problema em SelecFile" + +#: cmdline/apt-cache.cc:702 +msgid "Problem with MergeList" +msgstr "Problema em MergeList" + +#: cmdline/apt-cache.cc:806 +msgid "Oh shit!" +msgstr "Oh, nгo!" + +#: cmdline/apt-cache.cc:841 +#, c-format +msgid "Package: %s\n" +msgstr "Pacote: %s\n" + +#: cmdline/apt-cache.cc:844 +#, c-format +msgid "Section: %s\n" +msgstr "Seзгo: %s\n" + +#: cmdline/apt-cache.cc:847 +#, c-format +msgid "Installed Size: %i\n" +msgstr "Tamanho instalado: %i\n" + +#: cmdline/apt-cache.cc:854 +#, c-format +msgid "Maintainer: %s\n" +msgstr "Mantenedor: %s\n" + +#: cmdline/apt-cache.cc:858 +#, c-format +msgid "Version: %i:%s" +msgstr "Versгo: %i:%s" + +#: cmdline/apt-cache.cc:860 +#, c-format +msgid "Version: %s" +msgstr "Versгo: %s" + +#: cmdline/apt-cache.cc:894 +msgid "Pre-Depends: " +msgstr "Prй-Dependкncias: " + +#: cmdline/apt-cache.cc:907 +msgid "Depends: " +msgstr "Dependкncias: " + +#: cmdline/apt-cache.cc:920 +msgid "Conflicts: " +msgstr "Conflitos: " + +#: cmdline/apt-cache.cc:932 +msgid "Obsoletes: " +msgstr "Obsoletos: " + +#: cmdline/apt-cache.cc:937 +#, c-format +msgid "Architecture: %s\n" +msgstr "Arquitetura: %s\n" + +#: cmdline/apt-cache.cc:940 +#, c-format +msgid "Size: %d\n" +msgstr "Tamanho: %d\n" + +#: cmdline/apt-cache.cc:943 +#, c-format +msgid "MD5sum: %s\n" +msgstr "MD5sum: %s\n" + +#: cmdline/apt-cache.cc:946 +#, c-format +msgid "Filename: %s\n" +msgstr "Nome de arquivo: %s\n" + +#: cmdline/apt-cache.cc:949 +#, c-format +msgid "Description: %s\n" +msgstr "Descriзгo: %s\n" + +#: cmdline/apt-cache.cc:1038 +msgid "You must give exactly one pattern" +msgstr "Vocк deve fornecer exatamente um padrгo" + +#: cmdline/apt-cache.cc:1044 +msgid "Regex compilation error" +msgstr "Erro de compilaзгo de Regex" + +#: cmdline/apt-cache.cc:1195 +msgid "Usage: apt-cache [options] command" +msgstr "Uso: apt-cache [opзхes] comando" + +#: cmdline/apt-cache.cc:1196 +msgid " apt-cache [options] add file1 [file1 ...]" +msgstr " apt-cache [opзхes] add arquivo1 [arquivo1 ...]" + +#: cmdline/apt-cache.cc:1197 +msgid " apt-cache [options] showpkg pkg1 [pkg2 ...]" +msgstr " apt-cache [opзхes] showpkg pac1 [pac2 ...]" + +#: cmdline/apt-cache.cc:1199 +msgid "apt-cache is a low-level tool used to manipulate APT's binary" +msgstr "" +"apt-cache й uma ferramenta de nнvel baixo usado para manipular o binбrio do " +"APT" + +#: cmdline/apt-cache.cc:1200 +msgid "cache files stored in " +msgstr "arquivo de cache armazenados em " + +#: cmdline/apt-cache.cc:1201 +msgid "It is not meant for ordinary use only as a debug aide." +msgstr "Nгo significa uso comum apenas como uma ajuda para depuraзгo." + +#: cmdline/apt-cache.cc:1204 +msgid " add - Add an package file to the source cache" +msgstr " add - Adiciona um arquivo de pacote ao cache-fonte" + +#: cmdline/apt-cache.cc:1205 +msgid " gencaches - Build both the package and source cache" +msgstr " gencaches - Constrуi o pacote e o cache-fonte" + +#: cmdline/apt-cache.cc:1206 +msgid " showpkg - Show some general information for a single package" +msgstr " showpkg - Exibe algumas informaзхes gerais para um pacote ъnico" + +#: cmdline/apt-cache.cc:1207 +msgid " stats - Show some basic statistics" +msgstr " stats - Exibe alguns dados estatнsticos bбsicos" + +#: cmdline/apt-cache.cc:1208 +msgid " dump - Show the entire file in a terse form" +msgstr " dump - Exibe todo o arquivo em uma forma resumida" + +#: cmdline/apt-cache.cc:1209 +msgid " dumpavail - Print an available file to stdout" +msgstr " dumpavail - Imprime um arquivo disponнvel para a saнda padrгo" + +#: cmdline/apt-cache.cc:1210 +msgid " unmet - Show unmet dependencies" +msgstr " unmet - Exibe dependкncias nгo resolvidas" + +#: cmdline/apt-cache.cc:1211 +msgid " check - Check the cache a bit" +msgstr " check - Verifica o cache" + +#: cmdline/apt-cache.cc:1212 +msgid " search - Search the package list for a regex pattern" +msgstr " search - Procura por lista de pacotes para um padrгo regex" + +#: cmdline/apt-cache.cc:1213 +msgid " show - Show a readable record for the package" +msgstr " show - Exibe um registro legнvel para o pacote" + +#: cmdline/apt-cache.cc:1214 +msgid " depends - Show raw dependency information for a package" +msgstr " depends - Exibe informaзхes de dependкncia brutas para um pacote" + +#: cmdline/apt-cache.cc:1215 +msgid " pkgnames - List the names of all packages" +msgstr " pkgnames - Relaciona os nomes de todos os pacotes" + +#: cmdline/apt-cache.cc:1216 +msgid " dotty - Generate package graphs for GraphVis" +msgstr " dotty - Gera grбficos de pacote para GraphVis" + +#: cmdline/apt-cache.cc:1219 cmdline/apt-config.cc:84 +msgid " -h This help text." +msgstr " -h Este texto de ajuda." + +#: cmdline/apt-cache.cc:1220 +msgid " -p=? The package cache. [" +msgstr " -p=? O cache de pacote. [" + +#: cmdline/apt-cache.cc:1221 +msgid " -s=? The source cache. [" +msgstr " -s=? O cache-fonte. [" + +#: cmdline/apt-cache.cc:1222 +msgid " -q Disable progress indicator." +msgstr " -q Desabilita indicador de progresso." + +#: cmdline/apt-cache.cc:1223 +msgid " -i Show only important deps for the unmet command." +msgstr " -i Exibe apenas as dependкncias importantes para o comando unmet." + +#: cmdline/apt-cache.cc:1226 +msgid "See the apt-cache(8) and apt.conf(5) manual pages for more information." +msgstr "" +"Consulte as manpages do apt-cache(8) e apt.conf(5) para maiores informaзхes." + +#: cmdline/apt-config.cc:37 +msgid "Arguments not in pairs" +msgstr "Os argumentos nгo estгo em pares" + +#: cmdline/apt-config.cc:75 +msgid "Usage: apt-config [options] command" +msgstr "Uso: apt-config [opзхes] comando" + +#: cmdline/apt-config.cc:77 +msgid "apt-config is a simple tool to read the APT config file" +msgstr "" +"apt-config й uma ferramenta simples para ler o arquivo de configuraзгo do APT" + +#: cmdline/apt-config.cc:80 +msgid " shell - Shell mode" +msgstr " shell - Modo shell" + +#: cmdline/apt-config.cc:81 +msgid " dump - Show the configuration" +msgstr " dump - Exibe a configuraзгo" + +#: apt-pkg/acquire-item.cc:142 +#, c-format +msgid "Size of %s did not match what's in the hashfile and was redownloaded." +msgstr "Tamanho de %s nгo corresponde ao que estб no arquivo hash e ao que foi recarregado." + +#: apt-pkg/acquire-item.cc:154 +#, c-format +msgid "MD5 of %s did not match what's int the hashfile and was redownloaded." +msgstr "MD5 de %s nгo corresponde ao que estб no arquivo hash e ao que foi recarregado." + +#: apt-pkg/acquire-item.cc:426 +msgid "Hashfile signer is not who it's supposed to be (expected " +msgstr "O assinante de arquivo hash nгo й quem se supunha ser (esperava-se " + +#: apt-pkg/acquire-item.cc:428 +msgid ", got " +msgstr ", obteve " + +#: apt-pkg/acquire-worker.cc:108 +#, c-format +msgid "The method driver %s could not be found." +msgstr "O mecanismo de busca %s nгo pфde ser encontrado." + +#: apt-pkg/acquire-worker.cc:117 +msgid "Failed to create IPC pipe to subprocess" +msgstr "Falha ao criar pipe IPC para subprocesso" + +#: apt-pkg/acquire-worker.cc:160 +#, c-format +msgid "Method %s did not start correctly" +msgstr "O mйtodo %s nгo iniciou corretamente" + +#: apt-pkg/acquire-worker.cc:197 +#, c-format +msgid "Invalid message from method %s: %s" +msgstr "Mensagem invбlida do mйtodo %s: %s" + +#: apt-pkg/acquire-worker.cc:210 +#, c-format +msgid "Unable to process Capabilities message from %s" +msgstr "Impossнvel processar mensagem de Capacidades de %s" + +#: apt-pkg/acquire-worker.cc:229 +msgid "Method gave invalid 200 URI Start message" +msgstr "O mйtodo forneceu mensagem invбlida 200 URI Start" + +#: apt-pkg/acquire-worker.cc:268 +#, c-format +msgid "Bizzar Error - File size is not what the server reported %s %u" +msgstr "Erro estranho - O tamanho do arquivo nгo й o que o servidor reportou %s %u" + +#: apt-pkg/acquire-worker.cc:297 +msgid "Method gave invalid 400 URI Failure message" +msgstr "O mйtodo forneceu mensagem invбlida 400 URI Failure" + +#: apt-pkg/acquire-worker.cc:319 +#, c-format +msgid "Method %s General failure: %s" +msgstr "Falha geral do mйtodo %s: %s" + +#: apt-pkg/acquire-worker.cc:503 +#, c-format +msgid "Method %s has died unexpectedly!" +msgstr "O mйtodo %s terminou inesperadamente!" + +#: apt-pkg/acquire.cc:58 +#, c-format +msgid "Lists directory %spartial is missing." +msgstr "Diretуrio de listas %spartial estб faltando." + +#: apt-pkg/acquire.cc:62 +#, c-format +msgid "Archive directory %spartial is missing." +msgstr "O diretуrio de arquivos %spartial estб faltando." + +#: apt-pkg/acquire.cc:557 +msgid "Tried to dequeue a fetching object" +msgstr "Tentou tirar da fila um objeto em obtenзгo" + +#: apt-pkg/cachefile.cc:83 +msgid "The package lists or status file could not be parsed or opened." +msgstr "A lista de pacotes ou arquivo de estado nгo pфde ser analisada ou aberta." + +#: apt-pkg/cachefile.cc:85 +msgid "You may want to run apt-get update to correct these missing files" +msgstr "Vocк pode querer executar `apt-get update' para corrigir estes arquivos faltantes." + +#: apt-pkg/clean.cc:44 +msgid "Unable to change to " +msgstr "Impossнvel alterar para " + +#: apt-pkg/clean.cc:58 +#, c-format +msgid "Unable to stat %s." +msgstr "Impossнvel ler %s." + +#: apt-pkg/depcache.cc:61 apt-pkg/depcache.cc:90 +msgid "Building Dependency Tree" +msgstr "Construindo бrvore de dependкncias" + +#: apt-pkg/depcache.cc:62 +msgid "Candidate Versions" +msgstr "Versхes sugeridas" + +#: apt-pkg/depcache.cc:91 +msgid "Dependency Generation" +msgstr "Geraзгo de dependкncia" + +#: apt-pkg/packagemanager.cc:397 +#, c-format +msgid "" +"This installation run will require temporarily removing the essential " +"package %s due to a Conflicts/Pre-Depends loop. This is often bad, but if " +"you really want to do it, activate the APT::Force-LoopBreak option." +msgstr "Esta instalaзгo irб requerer temporariamente a remoзгo do pacote essencial %s devido a um loop de Conflitos/Prй-Dependкncias. Fazer isto normalmente nгo й uma boa idйia, caso queira realmente ir em frente, ative a opзгo APT::Force-LoopBreak." + +#: apt-pkg/pkgcache.cc:125 +msgid "The package cache file is corrupted" +msgstr "O arquivo de cache do pacote estб corrompido" + +#: apt-pkg/pkgcache.cc:130 +msgid "The package cache file is an incompatible version" +msgstr "O arquivo de cache do pacote й uma versгo nгo compatнvel" + +#: apt-pkg/pkgcachegen.cc:90 +#, c-format +msgid "Error occured while processing %s (NewPackage)" +msgstr "Ocorreu um erro durante o processamento de %s (NewPackage)" + +#: apt-pkg/pkgcachegen.cc:102 +#, c-format +msgid "Error occured while processing %s (UsePackage1)" +msgstr "Ocorreu um erro durante o processamento de %s (UsePackage1)" + +#: apt-pkg/pkgcachegen.cc:124 +#, c-format +msgid "Error occured while processing %s (UsePackage2)" +msgstr "Ocorreu um erro durante o processamento de %s (UsePackage2)" + +#: apt-pkg/pkgcachegen.cc:127 +#, c-format +msgid "Error occured while processing %s (NewFileVer1)" +msgstr "Ocorreu um erro durante o processamento de %s (NewFileVer1)" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "WARNING: '" +msgstr "AVISO: '" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "' has 2 packages with same version but different dependencies. " +msgstr "' tem 2 pacotes com a mesma versгo mas dependкncias diferentes. " + +#: apt-pkg/pkgcachegen.cc:139 +msgid "That usually means a packaging bug." +msgstr "Que geralmente significa um bug do pacote." + +#: apt-pkg/pkgcachegen.cc:158 +#, c-format +msgid "Error occured while processing %s (NewVersion1)" +msgstr "Ocorreu um erro durante o processamento de %s (NewVersion1)" + +#: apt-pkg/pkgcachegen.cc:161 +#, c-format +msgid "Error occured while processing %s (UsePackage3)" +msgstr "Ocorreu um erro durante o processamento de %s (UsePackage3)" + +#: apt-pkg/pkgcachegen.cc:164 +#, c-format +msgid "Error occured while processing %s (NewVersion2)" +msgstr "Ocorreu um erro durante o processamento de %s (NewVersion2)" + +#: apt-pkg/sourcelist.cc:76 +#, c-format +msgid "Block %s is invalid" +msgstr "O bloco %s й invбlido" + +#: apt-pkg/sourcelist.cc:121 +#, c-format +msgid "Malformed line %u in source list %s (type)" +msgstr "Linha mal formada %u na lista de fontes %s (type)" + +#: apt-pkg/sourcelist.cc:123 apt-pkg/sourcelist.cc:135 +#, c-format +msgid "Malformed line %u in source list %s (URI)" +msgstr "Linha mal formada %u na lista de fontes %s (URI)" + +#: apt-pkg/sourcelist.cc:130 +#, c-format +msgid "Malformed line %u in source list %s (vendor ID)" +msgstr "Linha mal formada %u na lista de fontes %s (vendor ID)" + +#: apt-pkg/sourcelist.cc:141 +#, c-format +msgid "Malformed line %u in source list %s (dist)" +msgstr "Linha mal formada %u na lista de fontes %s (dist)" + +#: apt-pkg/sourcelist.cc:145 +#, c-format +msgid "Malformed line %u in source list %s (bad vendor ID)" +msgstr "Linha mal formada %u na lista de fontes %s (bad vendor ID)" + +#: apt-pkg/sourcelist.cc:148 +#, c-format +msgid "Malformed line %u in source list %s (bad type)" +msgstr "Linha mal formada %u na lista de fontes %s (bad type)" + +#: apt-pkg/sourcelist.cc:151 +#, c-format +msgid "Malformed line %u in source list %s (bad URI)" +msgstr "Linha mal formada %u na lista de fontes %s (bad URI)" + +#: apt-pkg/sourcelist.cc:161 +#, c-format +msgid "Malformed line %u in source list %s (Absolute dist)" +msgstr "Linha mal formada %u na lista de fontes %s (Absolute dist)" + +#: apt-pkg/sourcelist.cc:174 +#, c-format +msgid "Malformed line %u in source list %s (dist parse)" +msgstr "Linha mal formada %u na lista de fontes %s (dist parse)" + +#: apt-pkg/sourcelist.cc:353 +msgid "could not open hash index" +msgstr "nгo foi possнvel abrir o нndice de hash" + +#: apt-pkg/sourcelist.cc:363 +msgid "No MD5SUM data in hashfile" +msgstr "Nenhum dado MD5SUM no arquivo hash" + +#: apt-pkg/sourcelist.cc:377 +msgid "Error parsing MD5 hash record" +msgstr "Erro ao analisar gravaзгo de hash MD5" + +#: apt-pkg/sourcelist.cc:400 +#, c-format +msgid "" +"Repository entry in sources.list contains extra components that are not " +"listed in the signed hash file: %s" +msgstr "A entrada de repositуrio em sources.list contйm componentes extra que nгo estгo listados no arquivo hash assinado: %s" + +#: apt-pkg/srcrecords.cc:47 +msgid "Sorry, you must put some 'source' uris in your sources.list" +msgstr "Sinto muito, vocк deve colocar alguns uris 'fonte' em sua sources.list" + +#: apt-pkg/systemfactory.cc:72 +#, c-format +msgid "Failed to rename %s to %s" +msgstr "Falhou ao renomear %s para %s" + +#: apt-pkg/systemfactory.cc:77 +#, c-format +msgid "Couldn't stat source package list '%s' (%s)" +msgstr "Nгo foi possнvel ler lista de pacotes de fonte '%s' (%s)" + +#. Mostly from MakeStatusCache.. +#: apt-pkg/systemfactory.cc:184 apt-pkg/systemfactory.cc:240 +#: apt-pkg/systemfactory.cc:272 apt-pkg/systemfactory.cc:273 +#: apt-pkg/systemfactory.cc:280 apt-pkg/systemfactory.cc:350 +#: apt-pkg/systemfactory.cc:386 +msgid "Reading Package Lists" +msgstr "Lendo listas de pacotes" + +#: apt-pkg/systemfactory.cc:196 +#, c-format +msgid "Problem with SelectFile %s" +msgstr "Problema em SelecFile %s" + +#: apt-pkg/systemfactory.cc:201 +#, c-format +msgid "Problem with MergeList %s" +msgstr "Problema em MergeList %s" + +#: apt-pkg/systemfactory.cc:263 +msgid "IO Error saving source cache" +msgstr "Erro E/S salvando cache fonte" + +#: apt-pkg/tagfile.cc:59 +#, c-format +msgid "Unable to parse package file %s (1)" +msgstr "Impossнvel analisar o arquivo de pacote %s (1)" + +#: apt-pkg/tagfile.cc:142 +#, c-format +msgid "Unable to parse package file %s (2)" +msgstr "Impossнvel analisar o arquivo de pacote %s (2)" diff --git a/apt/po/ru.po b/apt/po/ru.po new file mode 100644 index 0000000..6a9b385 --- /dev/null +++ b/apt/po/ru.po @@ -0,0 +1,1706 @@ +# Russian translation for APT. +# Copyright (C) 2001 Free Software Foundation, Inc. +# Alexander Bokovoy , 2001. +# +# +msgid "" +msgstr "" +"Project-Id-Version: apt-0.3.19cnc52-alt5\n" +"POT-Creation-Date: 2001-10-04 19:05+0400\n" +"PO-Revision-Date: 2001-10-04 19:05+0400\n" +"Last-Translator: Dmitry V. Levin \n" +"Language-Team: ALT Linux Team \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=koi8-r\n" +"Content-Transfer-Encoding: 8 bit\n" + +#: cmdline/apt-cache.cc:116 cmdline/apt-get.cc:1060 cmdline/apt-get.cc:1080 +msgid "Package " +msgstr "рБЛЕФ " + +#: cmdline/apt-cache.cc:116 +msgid " version " +msgstr " ЧЕТУЙС " + +#: cmdline/apt-cache.cc:117 +msgid " has an unmet dep:" +msgstr " ЙНЕЕФ ОЕХДПЧМЕФЧПТЕООЩЕ ЪБЧЙУЙНПУФЙ:" + +#: cmdline/apt-cache.cc:156 cmdline/apt-cache.cc:410 cmdline/apt-cache.cc:534 +#: cmdline/apt-cache.cc:1089 +#, c-format +msgid "Unable to locate package %s" +msgstr "оЕЧПЪНПЦОП ОБКФЙ РБЛЕФ %s" + +#: cmdline/apt-cache.cc:160 cmdline/apt-cache.cc:320 +msgid "Package: " +msgstr "рБЛЕФ: " + +#: cmdline/apt-cache.cc:161 +msgid "Versions: " +msgstr "чЕТУЙЙ: " + +#: cmdline/apt-cache.cc:172 +msgid "Reverse Depends: " +msgstr "пВТБФОЩЕ ЪБЧЙУЙНПУФЙ: " + +#: cmdline/apt-cache.cc:176 +msgid "Dependencies: " +msgstr "ъБЧЙУЙНПУФЙ: " + +#: cmdline/apt-cache.cc:185 cmdline/apt-cache.cc:926 +msgid "Provides: " +msgstr "рТЕДПУФБЧМСЕФ: " + +#: cmdline/apt-cache.cc:193 +msgid "Reverse Provides: " +msgstr "пВТБФОЩЕ РТЕДПУФБЧМСЕНЩЕ ЪБЧЙУЙНПУФЙ" + +#: cmdline/apt-cache.cc:207 +msgid "Total Package Names : " +msgstr "йНЈО РБЛЕФПЧ: " + +#: cmdline/apt-cache.cc:247 +msgid " Normal Packages: " +msgstr " оПТНБМШОЩЕ РБЛЕФЩ: " + +#: cmdline/apt-cache.cc:248 +msgid " Pure Virtual Packages: " +msgstr " гЕМЙЛПН ЧЙТФХБМШОЩЕ РБЛЕФЩ: " + +#: cmdline/apt-cache.cc:249 +msgid " Single Virtual Packages: " +msgstr " пДЙОПЮОЩЕ ЧЙТФХБМШОЩЕ РБЛЕФЩ: " + +#: cmdline/apt-cache.cc:250 +msgid " Mixed Virtual Packages: " +msgstr " уНЕЫБООЩЕ ЧЙТФХБМШОЩЕ РБЛЕФЩ: " + +#: cmdline/apt-cache.cc:251 +msgid " Missing: " +msgstr " пФУХФУФЧХАФ: " + +#: cmdline/apt-cache.cc:253 +msgid "Total Distinct Versions: " +msgstr "тБЪМЙЮОЩИ ЧЕТУЙК: " + +#: cmdline/apt-cache.cc:255 +msgid "Total Dependencies: " +msgstr "чУЕЗП ЪБЧЙУЙНПУФЕК: " + +#: cmdline/apt-cache.cc:258 +msgid "Total Ver/File relations: " +msgstr "чУЕЗП ПФОПЫЕОЙК чЕТУЙС/жБКМ: " + +#: cmdline/apt-cache.cc:260 +msgid "Total Provides Mappings: " +msgstr "чУЕЗП УППФЧЕФУФЧЙК УЕТЧЙУПЧ: " + +#: cmdline/apt-cache.cc:272 +msgid "Total Globbed Strings: " +msgstr "чУЕЗП УПЧРБЧЫЙИ УФТПЛ: " + +#: cmdline/apt-cache.cc:277 +msgid "Total Slack space: " +msgstr "чУЕЗП ЪБОСФП НЕУФБ: " + +#: cmdline/apt-cache.cc:285 +msgid "Total Space Accounted for: " +msgstr "чУЕЗП ВХДЕФ ЪБОСФП НЕУФБ: " + +#: cmdline/apt-cache.cc:300 +msgid "Bad section " +msgstr "рМПИБС УЕЛГЙС " + +#: cmdline/apt-cache.cc:306 +msgid "Bad prio " +msgstr "рМПИПК РТЙПТЙФЕФ " + +#: cmdline/apt-cache.cc:323 cmdline/apt-cache.cc:339 +msgid " Version: " +msgstr " чЕТУЙС: " + +#: cmdline/apt-cache.cc:324 +msgid " File: " +msgstr " жБКМ: " + +#: cmdline/apt-cache.cc:326 +msgid " Depends: " +msgstr " ъБЧЙУЙФ ПФ: " + +#: cmdline/apt-cache.cc:332 +msgid "File: " +msgstr "жБКМ: " + +#: cmdline/apt-cache.cc:333 +msgid " Size: " +msgstr " тБЪНЕТ: " + +#: cmdline/apt-cache.cc:334 +msgid " ID: " +msgstr " ID: " + +#: cmdline/apt-cache.cc:335 +msgid " Flags: " +msgstr "жМБЗЙ: " + +#: cmdline/apt-cache.cc:336 +msgid " Time: " +msgstr " чТЕНС: " + +#: cmdline/apt-cache.cc:337 +msgid " Archive: " +msgstr " бТИЙЧ: " + +#: cmdline/apt-cache.cc:338 +msgid " Component: " +msgstr " лПНРПОЕОФ: " + +#: cmdline/apt-cache.cc:340 +msgid " Origin: " +msgstr " йУФПЮОЙЛ: " + +#: cmdline/apt-cache.cc:341 +msgid " Label: " +msgstr " нЕФЛБ: " + +#: cmdline/apt-cache.cc:342 +msgid " Architecture: " +msgstr " бТИЙФЕЛФХТБ: " + +#: apt-pkg/pkgrecords.cc:36 cmdline/apt-cache.cc:364 cmdline/apt-cache.cc:970 +#: cmdline/apt-cache.cc:1005 cmdline/apt-get.cc:578 +#, c-format +msgid "Package file %s is out of sync." +msgstr "жБКМ РБЛЕФБ %s ЧЩЫЕМ ЙЪ РПД ЛПОФТПМС." + +#: cmdline/apt-cache.cc:669 +msgid "You must give at least one file name" +msgstr "оЕПВИПДЙНП ЧЩВТБФШ РП ЛТБКОЕК НЕТЕ ПДОП ЙНС ЖБКМБ" + +#: cmdline/apt-cache.cc:688 +msgid "Generating cache" +msgstr "рПУФТПЕОЙЕ ЛЬЫБ" + +#: apt-pkg/rpm/rpmfactory.cc:192 apt-pkg/rpm/rpmfactory.cc:289 +#: apt-pkg/systemfactory.cc:187 cmdline/apt-cache.cc:696 +#, c-format +msgid "Problem opening %s" +msgstr "пЫЙВЛБ ПФЛТЩФЙС %s" + +#: cmdline/apt-cache.cc:699 +msgid "Problem with SelectFile" +msgstr "пЫЙВЛБ SelectFile" + +#: cmdline/apt-cache.cc:702 +msgid "Problem with MergeList" +msgstr "пЫЙВЛБ MergeList" + +#: cmdline/apt-cache.cc:806 +msgid "Oh shit!" +msgstr "п-П!.." + +#: cmdline/apt-cache.cc:841 +#, c-format +msgid "Package: %s\n" +msgstr "рБЛЕФ: %s\n" + +#: cmdline/apt-cache.cc:844 +#, c-format +msgid "Section: %s\n" +msgstr "уЕЛГЙС: %s\n" + +#: cmdline/apt-cache.cc:847 +#, c-format +msgid "Installed Size: %i\n" +msgstr "тБЪНЕТ ХУФБОПЧМЕООЩИ РБЛЕФПЧ: %i\n" + +#: cmdline/apt-cache.cc:854 +#, c-format +msgid "Maintainer: %s\n" +msgstr "хРБЛПЧЭЙЛ: %s\n" + +#: cmdline/apt-cache.cc:858 +#, c-format +msgid "Version: %i:%s" +msgstr "чЕТУЙС: %i:%s" + +#: cmdline/apt-cache.cc:860 +#, c-format +msgid "Version: %s" +msgstr "чЕТУЙС: %s" + +#: cmdline/apt-cache.cc:894 +msgid "Pre-Depends: " +msgstr "рТЕДЧБТЙФЕМШОЩЕ ЪБЧЙУЙНПУФЙ: " + +#: cmdline/apt-cache.cc:907 +msgid "Depends: " +msgstr "ъБЧЙУЙНПУФЙ: " + +#: cmdline/apt-cache.cc:920 +msgid "Conflicts: " +msgstr "лПОЖМЙЛФЩ: " + +#: cmdline/apt-cache.cc:932 +msgid "Obsoletes: " +msgstr "ъБНЕОСЕФ: " + +#: cmdline/apt-cache.cc:937 +#, c-format +msgid "Architecture: %s\n" +msgstr "бТИЙФЕЛФХТБ: %s\n" + +#: cmdline/apt-cache.cc:940 +#, c-format +msgid "Size: %d\n" +msgstr "тБЪНЕТ: %d\n" + +#: cmdline/apt-cache.cc:943 +#, c-format +msgid "MD5sum: %s\n" +msgstr "MD5-УХННБ: %s\n" + +#: cmdline/apt-cache.cc:946 +#, c-format +msgid "Filename: %s\n" +msgstr "йНС ЖБКМБ: %s\n" + +#: cmdline/apt-cache.cc:949 +#, c-format +msgid "Description: %s\n" +msgstr "пРЙУБОЙЕ: %s\n" + +#: cmdline/apt-cache.cc:1038 +msgid "You must give exactly one pattern" +msgstr "оЕПВИПДЙНП ХЛБЪБФШ ФПМШЛП ПДЙО ПВТБЪЕГ" + +#: cmdline/apt-cache.cc:1044 +msgid "Regex compilation error" +msgstr "пЫЙВЛБ ЛПНРЙМСГЙЙ ТЕЗХМСТОПЗП ЧЩТБЦЕОЙС" + +#: cmdline/apt-cache.cc:1195 +msgid "Usage: apt-cache [options] command" +msgstr "йУРПМШЪПЧБОЙЕ: apt-cache [ПРГЙЙ] ЛПНБОДБ" + +#: cmdline/apt-cache.cc:1196 +msgid " apt-cache [options] add file1 [file1 ...]" +msgstr " apt-cache [ПРГЙЙ] add file1 [file2 ...]" + +#: cmdline/apt-cache.cc:1197 +msgid " apt-cache [options] showpkg pkg1 [pkg2 ...]" +msgstr " apt-cache [ПРГЙЙ] showpkg pkg1 [pkg2 ...]" + +#: cmdline/apt-cache.cc:1199 +msgid "apt-cache is a low-level tool used to manipulate APT's binary" +msgstr "apt-cache -- ЬФП ОЙЪЛПХТПЧОЕЧБС ХФЙМЙФБ ДМС ХРТБЧМЕОЙС" + +#: cmdline/apt-cache.cc:1200 +msgid "cache files stored in " +msgstr "ЧОХФТЕООЙН ЛЬЫЕН APT Ч " + +#: cmdline/apt-cache.cc:1201 +msgid "It is not meant for ordinary use only as a debug aide." +msgstr "ьФБ ХФЙМЙФБ РТЕДОБЪОБЮЕОБ ФПМШЛП ДМС ПФМБДЛЙ APT" + +#: cmdline/apt-cache.cc:1203 cmdline/apt-cdrom.cc:875 cmdline/apt-config.cc:79 +#: cmdline/apt-get.cc:1932 +msgid "Commands:" +msgstr "лПНБОДЩ:" + +#: cmdline/apt-cache.cc:1204 +msgid " add - Add an package file to the source cache" +msgstr " add - дПВБЧЙФШ РБЛЕФ Ч ЛЬЫ ЙУИПДОЩИ ЖБКМПЧ" + +#: cmdline/apt-cache.cc:1205 +msgid " gencaches - Build both the package and source cache" +msgstr " gencaches - рЕТЕУФТПЙФШ ПВБ ЛЬЫБ (РБЛЕФЩ Й ЙУИПДОЙЛЙ)" + +#: cmdline/apt-cache.cc:1206 +msgid " showpkg - Show some general information for a single package" +msgstr " showpkg - пФПВТБЪЙФШ ПВЭХА ЙОЖПТНБГЙА П РБЛЕФЕ" + +#: cmdline/apt-cache.cc:1207 +msgid " stats - Show some basic statistics" +msgstr " stats - пФПВТБЪЙФШ ПВЭХА УФБФЙУФЙЛХ" + +#: cmdline/apt-cache.cc:1208 +msgid " dump - Show the entire file in a terse form" +msgstr " dump - рПЛБЪБФШ ЧЕУШ ЖБКМ Ч УЦБФПН ЧЙДЕ" + +#: cmdline/apt-cache.cc:1209 +msgid " dumpavail - Print an available file to stdout" +msgstr " dumpavail - тБУРЕЮБФБФШ ДПУФХРОЩК ЖБКМ Ч stdout" + +#: cmdline/apt-cache.cc:1210 +msgid " unmet - Show unmet dependencies" +msgstr " unmet - пФПВТБЪЙФШ ОЕХДПЧМЕФЧПТЕООЩЕ ЪБЧЙУЙНПУФЙ" + +#: cmdline/apt-cache.cc:1211 +msgid " check - Check the cache a bit" +msgstr " check - рЕТЕРТПЧЕТЙФШ ЛЬЫ" + +#: cmdline/apt-cache.cc:1212 +msgid " search - Search the package list for a regex pattern" +msgstr "" +" search - йУЛБФШ Ч УРЙУЛЕ РБЛЕФПЧ У ЙУРПМШЪПЧБОЙЕН ТЕЗХМСТОЩИ ЧЩТБЦЕОЙК" + +#: cmdline/apt-cache.cc:1213 +msgid " show - Show a readable record for the package" +msgstr " show - пФПВТБЪЙФШ ЙОЖПТНБГЙА П РБЛЕФЕ Ч РПОСФОПК ЖПТНЕ" + +#: cmdline/apt-cache.cc:1214 +msgid " depends - Show raw dependency information for a package" +msgstr " depends - пФПВТБЪЙФШ ЧУА ЙОЖПТНБГЙА П ЪБЧЙУЙНПУФСИ ДМС РБЛЕФБ" + +#: cmdline/apt-cache.cc:1215 +msgid " pkgnames - List the names of all packages" +msgstr " pkgnames - пФПВТБЪЙФШ ЙНЕОБ ЧУЕИ РБЛЕФПЧ" + +#: cmdline/apt-cache.cc:1216 +msgid " dotty - Generate package graphs for GraphVis" +msgstr "" +" dotty - уЗЕОЕТЙТПЧБФШ ЗТБЖ ЪБЧЙУЙНПУФЕК РБЛЕФПЧ ЛБЛ ДПЛХНЕОФ GraphVis" + +#: cmdline/apt-cache.cc:1218 cmdline/apt-cdrom.cc:878 cmdline/apt-config.cc:83 +#: cmdline/apt-get.cc:1944 +msgid "Options:" +msgstr "пРГЙЙ:" + +#: cmdline/apt-cache.cc:1219 cmdline/apt-config.cc:84 +msgid " -h This help text." +msgstr " -h ьФБ УРТБЧЛБ." + +#: cmdline/apt-cache.cc:1220 +msgid " -p=? The package cache. [" +msgstr " -p=? лЬЫ РБЛЕФПЧ. [" + +#: cmdline/apt-cache.cc:1221 +msgid " -s=? The source cache. [" +msgstr " -s=? лЬЫ ЙУИПДОЙЛПЧ. [" + +#: cmdline/apt-cache.cc:1222 +msgid " -q Disable progress indicator." +msgstr " -q ъБРТЕФЙФШ ЙОДЙЛБФПТ РТПЗТЕУУБ." + +#: cmdline/apt-cache.cc:1223 +msgid " -i Show only important deps for the unmet command." +msgstr " -i пФПВТБЪЙФШ ФПМШЛП ЧБЦОЩЕ ЪБЧЙУЙНПУФЙ ДМС ЛПНБОДЩ unmet" + +#: cmdline/apt-cache.cc:1224 cmdline/apt-cdrom.cc:885 cmdline/apt-config.cc:85 +#: cmdline/apt-get.cc:1956 +msgid " -c=? Read this configuration file" +msgstr " -c=? рТПЮЙФБФШ ХЛБЪБООЩК ЛПОЖЙЗХТБГЙПООЩК ЖБКМ" + +#: cmdline/apt-cache.cc:1225 cmdline/apt-cdrom.cc:886 cmdline/apt-config.cc:86 +#: cmdline/apt-get.cc:1957 +msgid " -o=? Set an arbitary configuration option, eg -o dir::cache=/tmp" +msgstr " -o=? хУФБОПЧЙФШ РТПЙЪЧПМШОХА ПРГЙА, ОБРТЙНЕТ -o dir::cache=/tmp" + +#: cmdline/apt-cache.cc:1226 +msgid "See the apt-cache(8) and apt.conf(5) manual pages for more information." +msgstr "уН. ФБЛЦЕ УФТБОЙГЩ ДПЛХНЕОФБГЙЙ apt-cache(8) Й apt.conf(5)." + +#: cmdline/apt-cdrom.cc:76 cmdline/apt-cdrom.cc:164 cmdline/apt-cdrom.cc:208 +#: cmdline/apt-cdrom.cc:277 +#, c-format +msgid "Unable to change to %s" +msgstr "оЕЧПЪНПЦОП РЕТЕКФЙ Л %s" + +#: apt-pkg/clean.cc:38 cmdline/apt-cdrom.cc:88 cmdline/apt-cdrom.cc:240 +#, c-format +msgid "Unable to read %s" +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ %s" + +#: cmdline/apt-cdrom.cc:470 cmdline/apt-cdrom.cc:526 +#, c-format +msgid "Failed to open %s.new" +msgstr "оЕ ХДБМПУШ ПФЛТЩФШ %s.new" + +#: cmdline/apt-cdrom.cc:497 cmdline/apt-cdrom.cc:616 +#, c-format +msgid "Failed to rename %s.new to %s" +msgstr "оЕ ХДБМПУШ РЕТЕЙНЕОПЧБФШ %s.new Ч %s" + +#: cmdline/apt-cdrom.cc:571 cmdline/apt-cdrom.cc:605 cmdline/apt-cdrom.cc:817 +#: cmdline/apt-cdrom.cc:835 +msgid "Internal error" +msgstr "чОХФТЕООСС ПЫЙВЛБ" + +#: cmdline/apt-cdrom.cc:661 +msgid "Using CD-ROM mount point " +msgstr "йУРПМШЪХЕФУС ФПЮЛБ НПОФЙТПЧБОЙС CD-ROM " + +#: cmdline/apt-cdrom.cc:669 +#, c-format +msgid "Unable to read the cdrom database %s" +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ ВБЪХ ДБООЩИ %s У CD-ROM" + +#: cmdline/apt-cdrom.cc:676 +msgid "Unmounting CD-ROM" +msgstr "тБЪНПОФЙТПЧБОЙЕ CD-ROM" + +#. Mount the new CDROM +#: cmdline/apt-cdrom.cc:680 +msgid "Please insert a Disc in the drive and press enter" +msgstr "рПЦБМХКУФБ, ЧУФБЧШФЕ ДЙУЛ Ч ХУФТПКУФЧП Й ОБЦНЙФЕ " + +#: cmdline/apt-cdrom.cc:681 +msgid "Mounting CD-ROM" +msgstr "нПОФЙТПЧБОЙЕ CD-ROM" + +#: cmdline/apt-cdrom.cc:683 +msgid "Failed to mount the cdrom." +msgstr "оЕ ХДБМПУШ УНПОФЙТПЧБФШ CD-ROM." + +#. Hash the CD to get an ID +#: cmdline/apt-cdrom.cc:687 +msgid "Identifying.. " +msgstr "пРТЕДЕМЕОЙЕ... " + +#: cmdline/apt-cdrom.cc:697 +msgid "Scanning Disc for index files.. " +msgstr "уЛБОЙТПЧБОЙЕ ДЙУЛБ Ч РПЙУЛБИ ЙОДЕЛУОЩИ ЖБКМПЧ... " + +#: cmdline/apt-cdrom.cc:713 +msgid "I found (binary):" +msgstr "оБКДЕОЩ ВЙОБТОЩЕ РБЛЕФЩ:" + +#: cmdline/apt-cdrom.cc:716 +msgid "I found (source):" +msgstr "оБКДЕОЩ ЙУИПДОЩЕ РБЛЕФЩ:" + +#: cmdline/apt-cdrom.cc:729 +msgid "Found " +msgstr "оБКДЕОП " + +#: cmdline/apt-cdrom.cc:729 +msgid " package indexes and " +msgstr " ВЙОБТОЩИ РБЛЕФПЧ Й " + +#: cmdline/apt-cdrom.cc:730 +msgid " source indexes." +msgstr " ЙУИПДОЩИ РБЛЕФПЧ." + +#: cmdline/apt-cdrom.cc:735 +msgid "Unable to locate any package files, perhaps this is not a Debian Disc" +msgstr "оЕЧПЪНПЦОП ПВОБТХЦЙФШ ЖБКМЩ РБЛЕФПЧ, ЧПЪНПЦОП ЬФП ОЕ ДЙУЛ дЕВЙБОБ" + +#: cmdline/apt-cdrom.cc:737 +msgid "" +"Unable to locate any package files, perhaps this is not a ALT Linux Disc" +msgstr "оЕЧПЪНПЦОП ПВОБТХЦЙФШ ЖБКМЩ РБЛЕФПЧ, ЧПЪНПЦОП ЬФП ОЕ ДЙУЛ ALT Linux" + +#: cmdline/apt-cdrom.cc:754 +msgid "Found label '" +msgstr "оБКДЕОБ НЕФЛБ '" + +#: cmdline/apt-cdrom.cc:762 +msgid "Please provide a name for this Disc, such as 'Spring 2001 Disk 1'" +msgstr "" +"рПЦБМХКУФБ, ХЛБЦЙФЕ ЙНС ЬФПЗП ДЙУЛБ, ОБРТЙНЕТ, 'нПК дЙУФТЙВХФЙЧ дЙУЛ 1'" + +#: cmdline/apt-cdrom.cc:772 +msgid "That is not a valid name, try again " +msgstr "ьФП ОЕЧЕТОПЕ ЙНС, РПРТПВХКФЕ УОПЧБ " + +#: cmdline/apt-cdrom.cc:786 +msgid "This Disc is called:" +msgstr "ьФПФ ДЙУЛ ОБЪЩЧБЕФУС " + +#: cmdline/apt-cdrom.cc:805 +msgid "Writing new source list" +msgstr "ъБРЙУШ ОПЧПЗП УРЙУЛБ ЙУФПЮОЙЛПЧ" + +#. Print the sourcelist entries +#: cmdline/apt-cdrom.cc:812 +msgid "Source List entries for this Disc are:" +msgstr "уРЙУПЛ ЙУФПЮОЙЛПЧ ДМС ЬФПЗП ДЙУЛБ:" + +#: cmdline/apt-cdrom.cc:849 +msgid "Repeat this process for the rest of the CDs in your set." +msgstr "рПЧФПТЙФЕ ЬФПФ РТПГЕУУ ДМС ЧУЕИ CD Ч чБЫЕН ОБВПТЕ." + +#: cmdline/apt-cdrom.cc:869 +msgid "Usage: apt-cdrom [options] command" +msgstr "йУРПМШЪПЧБОЙЕ: apt-cdrom [ПРГЙЙ] ЛПНБОДБ" + +#: cmdline/apt-cdrom.cc:871 +msgid "apt-cdrom is a tool to add CDROM's to APT's source list. The " +msgstr "" +"apt-cdrom -- УТЕДУФЧП ДМС ДПВБЧМЕОЙС CD-ДЙУЛПЧ Ч УРЙУПЛ ЙУФПЮОЙЛПЧ APT. " + +#: cmdline/apt-cdrom.cc:872 +msgid "CDROM mount point and device information is taken from apt.conf" +msgstr "" +"фПЮЛБ НПОФЙТПЧБОЙС CD-ROM Й ЙОЖПТНБГЙС ПВ ХУФТПКУФЧЕ ВЕТХФУС ЙЪ apt.conf" + +#: cmdline/apt-cdrom.cc:873 +msgid "and /etc/fstab." +msgstr "Й /etc/fstab" + +#: cmdline/apt-cdrom.cc:876 +msgid " add - Add a CDROM" +msgstr " add - дПВБЧЙФШ CD-ROM" + +#: cmdline/apt-cdrom.cc:879 +msgid " -h This help text" +msgstr " -h ьФБ УРТБЧЛБ" + +#: cmdline/apt-cdrom.cc:880 +msgid " -d CD-ROM mount point" +msgstr " -d фПЮЛБ НПОФЙТПЧБОЙС CD-ROM" + +#: cmdline/apt-cdrom.cc:881 +msgid " -r Rename a recognized CD-ROM" +msgstr " -r рЕТЕЙНЕОПЧБФШ ТБУРПЪОБООЩК CD-ROM" + +#: cmdline/apt-cdrom.cc:882 +msgid " -m No mounting" +msgstr " -m оЕ НПОФЙТПЧБФШ" + +#: cmdline/apt-cdrom.cc:883 +msgid " -f Fast mode, don't check package files" +msgstr " -f вЩУФТЩК ТЕЦЙН, ОЕ РТПЧЕТСФШ ЖБКМЩ РБЛЕФПЧ" + +#: cmdline/apt-cdrom.cc:884 +msgid " -a Thorough scan mode" +msgstr " -a тЕЦЙН РПМОПЗП УЛБОЙТПЧБОЙС" + +#: cmdline/apt-cdrom.cc:887 +msgid "See fstab(5)" +msgstr "уН. fstab(5)" + +#: cmdline/apt-config.cc:37 +msgid "Arguments not in pairs" +msgstr "бТЗХНЕОФЩ ДПМЦОЩ ВЩФШ РБТОЩНЙ" + +#: cmdline/apt-config.cc:75 +msgid "Usage: apt-config [options] command" +msgstr "уЙОФБЛУЙУ: apt-config [ПРГЙЙ] ЛПНБОДБ" + +#: cmdline/apt-config.cc:77 +msgid "apt-config is a simple tool to read the APT config file" +msgstr "apt-config - ЬФП РТПУФЕКЫЕЕ УТЕДУФЧП ДМС ЮФЕОЙС ЛПОЖЙЗХТБГЙЙ APT" + +#: cmdline/apt-config.cc:80 +msgid " shell - Shell mode" +msgstr " shell - ъБРХУФЙФШ ПВПМПЮЛХ" + +#: cmdline/apt-config.cc:81 +msgid " dump - Show the configuration" +msgstr " dump - пФПВТБЪЙФШ ЛПОЖЙЗХТБГЙА" + +#. Yes/No +#: cmdline/apt-get.cc:129 +msgid "Y" +msgstr "Y" + +#: cmdline/apt-get.cc:129 +msgid "y" +msgstr "y" + +#: cmdline/apt-get.cc:215 +msgid "Sorry, but the following packages have unmet dependencies:" +msgstr "йЪЧЙОЙФЕ, ОП УМЕДХАЭЙЕ РБЛЕФЩ ЙНЕАФ ОЕХДПЧМЕФЧПТЕООЩЕ ЪБЧЙУЙНПУФЙ:" + +#: cmdline/apt-get.cc:275 +msgid " but " +msgstr ", ПДОБЛП " + +#: cmdline/apt-get.cc:278 +msgid " is installed" +msgstr " ХУФБОПЧМЕО" + +#: cmdline/apt-get.cc:278 +msgid " is to be installed" +msgstr " ВХДЕФ ХУФБОПЧМЕО" + +#: cmdline/apt-get.cc:284 +msgid "it is not installable" +msgstr "ОЕ НПЦЕФ ВЩФШ ХУФБОПЧМЕО" + +#: cmdline/apt-get.cc:286 +msgid "it is a virtual package" +msgstr "СЧМСЕФУС ЧЙТФХБМШОЩН РБЛЕФПН" + +#: cmdline/apt-get.cc:289 +msgid "it is not installed" +msgstr "ОЕ ХУФБОПЧМЕО" + +#: cmdline/apt-get.cc:289 +msgid "it is not going to be installed" +msgstr "ОЕ ВХДЕФ ХУФБОПЧМЕО" + +#: cmdline/apt-get.cc:294 +msgid " or" +msgstr " ЙМЙ" + +#: cmdline/apt-get.cc:320 +msgid "The following NEW packages will be installed:" +msgstr "уМЕДХАЭЙЕ опчще РБЛЕФЩ ВХДХФ ХУФБОПЧМЕОЩ:" + +#: cmdline/apt-get.cc:348 +msgid "The following packages will be REPLACED:" +msgstr "уМЕДХАЭЙЕ РБЛЕФЩ ВХДХФ ъбнеоеощ:" + +#: cmdline/apt-get.cc:349 +msgid "The following packages will be REMOVED:" +msgstr "уМЕДХАЭЙЕ РБЛЕФЩ ВХДХФ хдбмеощ:" + +#: cmdline/apt-get.cc:369 +msgid "The following packages have been kept back" +msgstr "уМЕДХАЭЙЕ РБЛЕФЩ ВХДХФ упитбоеощ:" + +#: cmdline/apt-get.cc:389 +msgid "The following packages will be upgraded" +msgstr "уМЕДХАЭЙЕ РБЛЕФЩ ВХДХФ пвопчмеощ:" + +#: cmdline/apt-get.cc:421 +msgid "The following packages can be upgraded:" +msgstr "уМЕДХАЭЙЕ РБЛЕФЩ НПЗХФ ВЩФШ пвопчмеощ:" + +#: cmdline/apt-get.cc:432 +msgid " from " +msgstr " ПФ " + +#: cmdline/apt-get.cc:433 +msgid " to " +msgstr " Л " + +#: cmdline/apt-get.cc:435 +msgid " Importance: " +msgstr " чБЦОПУФШ: " + +#: cmdline/apt-get.cc:436 +msgid " Date: " +msgstr " дБФБ: " + +#: cmdline/apt-get.cc:456 +msgid "The following held packages will be changed:" +msgstr "уМЕДХАЭЙЕ РБЛЕФЩ ВХДХФ ЙЪНЕОЕОЩ:" + +#: cmdline/apt-get.cc:523 +#, c-format +msgid "%s (due to %s) " +msgstr "%s (РП РТЙЮЙОЕ %s)" + +#: cmdline/apt-get.cc:531 +msgid "WARNING: The following essential packages will be removed" +msgstr "чОЙНБОЙЕ: УМЕДХАЭЙЕ ВБЪПЧЩЕ РБЛЕФЩ ВХДХФ ХДБМЕОЩ:" + +#: cmdline/apt-get.cc:532 +msgid "This should NOT be done unless you know exactly what you are doing!" +msgstr "" +"ч ПВЩЮОЩИ ХУМПЧЙСИ ЬФПЗП ОЕ ДПМЦОП ВЩМП РТПЙЪПКФЙ, ОБДЕЕНУС, чЩ ФПЮОП " +"РТЕДУФБЧМСЕФЕ, ЮФП ФТЕВХЕФЕ!" + +#: cmdline/apt-get.cc:554 +msgid " packages upgraded, " +msgstr " РБЛЕФПЧ ВХДЕФ ПВОПЧМЕОП, " + +#: cmdline/apt-get.cc:555 +msgid " newly installed, " +msgstr " ВХДЕФ ДПВБЧМЕОП ОПЧЩИ, " + +#: cmdline/apt-get.cc:557 +msgid " reinstalled, " +msgstr " ВХДЕФ РЕТЕХУФБОПЧМЕОП, " + +#: cmdline/apt-get.cc:558 +msgid " to remove(replace) and " +msgstr " ВХДЕФ ХДБМЕОП(ЪБНЕОЕОП) Й " + +#: cmdline/apt-get.cc:559 +msgid " not upgraded." +msgstr " ОЕ ВХДЕФ ПВОПЧМЕОП." + +#: cmdline/apt-get.cc:562 +msgid " packages not fully installed or removed." +msgstr " РБЛЕФПЧ ОЕ ВХДЕФ ХУФБОПЧМЕОП ЙМЙ ХДБМЕОП ГЕМЙЛПН." + +#: cmdline/apt-get.cc:695 +msgid "Correcting dependencies..." +msgstr "йУРТБЧМЕОЙЕ ЪБЧЙУЙНПУФЕК..." + +#: cmdline/apt-get.cc:698 +msgid " failed." +msgstr " ОЕ РПМХЮЙМПУШ." + +#: cmdline/apt-get.cc:701 +msgid "Unable to correct dependencies" +msgstr "оЕЧПЪНПЦОП ЙУРТБЧЙФШ ЪБЧЙУЙНПУФЙ" + +#: cmdline/apt-get.cc:704 +msgid "Unable to minimize the upgrade set" +msgstr "оЕЧПЪНПЦОП ХНЕОШЫЙФШ ЛПМЙЮЕУФЧП ПВОПЧМЕОЙК" + +#: cmdline/apt-get.cc:706 +msgid " Done" +msgstr " ъБЧЕТЫЕОП" + +#: cmdline/apt-get.cc:710 +msgid "You might want to run `apt-get -f install' to correct these." +msgstr "" +"чПЪНПЦОП, чБН РПФТЕВХЕФУС ЪБРХУФЙФШ `apt-get -f install' ДМС ЙУРТБЧМЕОЙС." + +#: cmdline/apt-get.cc:713 +msgid "Unmet dependencies. Try using -f." +msgstr "оЕХДПЧМЕФЧПТЕООЩЕ ЪБЧЙУЙНПУФЙ. рПРТПВХКФЕ ПРГЙА -f." + +#: cmdline/apt-get.cc:766 +msgid "Internal Error, InstallPackages was called with broken packages!" +msgstr "чОХФТЕООСС ПЫЙВЛБ, InstallPackages ЧЩЪЧБОБ ДМС `ВЙФЩИ' РБЛЕФПЧ!" + +#: cmdline/apt-get.cc:775 +msgid "Packages need to be removed but No Remove was specified." +msgstr "" +"рБЛЕФЩ ФТЕВХЕФУС ХДБМЙФШ, ПДОБЛП ВЩМБ ХЛБЪБОБ ПРГЙС No Remove (ОЕ ХДБМСФШ)." + +#: cmdline/apt-get.cc:785 +msgid "Internal Error, Ordering didn't finish" +msgstr "чОХФТЕООСС ПЫЙВЛБ, ХРПТСДПЮЕОЙЕ ОЕ ВЩМП ЪБЧЕТЫЕОП" + +#: cmdline/apt-get.cc:800 cmdline/apt-get.cc:1566 cmdline/apt-get.cc:1599 +msgid "Unable to lock the download directory" +msgstr "оЕЧПЪНПЦОП ТБЪВМПЛЙТПЧБФШ ЧТЕНЕООЩК ЛБФБМПЗ ДМС УЛБЮБООЩИ ЖБКМПЧ" + +#: apt-pkg/cachefile.cc:84 cmdline/apt-get.cc:810 cmdline/apt-get.cc:1649 +msgid "The list of sources could not be read." +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ УРЙУПЛ ЙУИПДОЩИ РБЛЕФПЧ" + +#: cmdline/apt-get.cc:827 +msgid "How odd.. The sizes didn't match, email apt@packages.debian.org" +msgstr "" +"юФП-ФП ОЕ ФБЛ, ТБЪНЕТЩ ОЕ УПЧРБДБАФ, ПФРТБЧШФЕ УППВЭЕОЙЕ ПВ ПЫЙВЛЕ РП БДТЕУХ " +"apt@packages.debian.org" + +#. Number of bytes +#: cmdline/apt-get.cc:831 cmdline/apt-get.cc:1782 +msgid "Need to get " +msgstr "оЕПВИПДЙНП РПМХЮЙФШ " + +#: cmdline/apt-get.cc:837 +msgid " of archives. After unpacking " +msgstr " БТИЙЧПЧ. рПУМЕ ТБУРБЛПЧЛЙ " + +#: cmdline/apt-get.cc:841 +msgid "B will be used." +msgstr "в ВХДЕФ ЙУРПМШЪПЧБОП." + +#: cmdline/apt-get.cc:843 +msgid "B will be freed." +msgstr "в ВХДЕФ ПУЧПВПЦДЕОП." + +#. if (Cache->UsrSize() == 0) +#: cmdline/apt-get.cc:845 +msgid "used disk space will remain the same." +msgstr "ПВЯЕН ЙУРПМШЪПЧБООПЗП ДЙУЛПЧПЗП РТПУФТБОУФЧБ ОЕ ЙЪНЕОЙФУС." + +#: cmdline/apt-get.cc:858 cmdline/apt-get.cc:1775 +#, c-format +msgid "Couldn't determine free space in %s" +msgstr "оЕЧПЪНПЦОП ПРТЕДЕМЙФШ УЧПВПДОПЕ НЕУФП Ч %s" + +#: cmdline/apt-get.cc:861 +#, c-format +msgid "Sorry, you don't have enough free space in %s to hold all packages." +msgstr "" +"йЪЧЙОЙФЕ, ОЕДПУФБФПЮОП УЧПВПДОПЗП НЕУФБ Ч %s ДМС ТБЪНЕЭЕОЙС ЧУЕИ РБЛЕФПЧ." + +#: cmdline/apt-get.cc:870 +msgid "There are problems and -y was used without --force-yes" +msgstr "пВОБТХЦЕОЩ РТПВМЕНЩ, Б ПРГЙС -y ВЩМБ ЙУРПМШЪПЧБОБ ВЕЪ --force-yes" + +#: cmdline/apt-get.cc:876 cmdline/apt-get.cc:893 +msgid "Trivial Only specified but this is not a trivial operation." +msgstr "" +"пРГЙС Trivial Only ВЩМБ ХЛБЪБОБ, ОП УПЧЕТЫБЕНПЕ ДЕКУФЧЙЕ ОЕ СЧМСЕФУС " +"ФТЙЧЙБМШОЩН." + +#: cmdline/apt-get.cc:878 +msgid "You are about to do something potentially harmful" +msgstr "чЩ УПВЙТБЕФЕУШ РТЕДРТЙОСФШ ЮФП-ФП РПФЕОГЙБМШОП ЧТЕДОПЕ" + +#: cmdline/apt-get.cc:879 +msgid "To continue type in the phrase 'Yes, I understand this may be bad'" +msgstr "" +"дМС РТПДПМЦЕОЙС, ОБВЕТЙФЕ РП-БОЗМЙКУЛЙ 'Yes, I understand this may be " +"bad' (дБ, С РПОЙНБА, ЮФП ЬФП НПЦЕФ ВЩФШ РМПИП)." + +#: cmdline/apt-get.cc:880 +msgid " ?] " +msgstr " ?] " + +#: cmdline/apt-get.cc:881 +msgid "Yes, I understand this may be bad" +msgstr "Yes, I understand this may be bad" + +#: cmdline/apt-get.cc:883 cmdline/apt-get.cc:902 +msgid "Aborted." +msgstr "рТЕТЧБОП." + +#: cmdline/apt-get.cc:898 +msgid "Do you want to continue? [Y/n] " +msgstr "рТПДПМЦЙФШ? [Y/n] " + +#: cmdline/apt-get.cc:961 cmdline/apt-get.cc:1226 cmdline/apt-get.cc:1818 +msgid "Failed to fetch " +msgstr "оЕ ХДБМПУШ РПМХЮЙФШ " + +#: cmdline/apt-get.cc:979 +msgid "Some files failed to download" +msgstr "оЕЛПФПТЩЕ ЖБКМЩ ОЕ ХДБМПУШ РПМХЮЙФШ" + +#: cmdline/apt-get.cc:985 +msgid "Unable to fetch some archives, maybe try with --fix-missing?" +msgstr "оЕ ХДБМПУШ РПМХЮЙФШ ОЕЛПФПТЩЕ БТИЙЧЩ, РПРТПВХКФЕ ПРГЙА --fix-missing." + +#: cmdline/apt-get.cc:989 +msgid "--fix-missing and media swapping is not currently supported" +msgstr "" +"--fix-missing Й УНЕОБ ОПУЙФЕМЕК У ЙУИПДОЩНЙ БТИЙЧБНЙ Ч ФЕЛХЭЙК НПНЕОФ ОЕ " +"РПДДЕТЦЙЧБАФУС" + +#: cmdline/apt-get.cc:994 +msgid "Unable to correct missing packages." +msgstr "оЕ ХДБМПУШ ЙУРТБЧЙФШ ПФУХФУФЧХАЭЙЕ РБЛЕФЩ." + +#: cmdline/apt-get.cc:995 +msgid "Aborting Install." +msgstr "рТЕТЩЧБОЙЕ ХУФБОПЧЛЙ." + +#: cmdline/apt-get.cc:1014 +msgid "Run apt-get clean to remove downloaded packages." +msgstr "" +"ъБРХУФЙФЕ apt-get clean ДМС ФПЗП, ЮФПВЩ УФЕТЕФШ УЛБЮБООЩЕ ЖБКМЩ РБЛЕФПЧ." + +#: cmdline/apt-get.cc:1031 +msgid "Note, selecting " +msgstr "ъБНЕЮБОЙЕ, ЧЩВПТ " + +#: cmdline/apt-get.cc:1031 +msgid " instead of " +msgstr " ЧНЕУФП " + +#: cmdline/apt-get.cc:1040 +msgid "Skipping " +msgstr "рТПРХУЛ " + +#: cmdline/apt-get.cc:1040 +msgid ", it is already installed and no-upgrade is set." +msgstr ", ХЦЕ ХУФБОПЧМЕО Й ХЛБЪБОБ ПРГЙС no-upgrade (ОЕ ПВОПЧМСФШ)." + +#: cmdline/apt-get.cc:1050 +#, c-format +msgid "Package %s is not installed" +msgstr "рБЛЕФ %s ОЕ ХУФБОПЧМЕО" + +#: cmdline/apt-get.cc:1060 +msgid " is a virtual package provided by:" +msgstr " СЧМСЕФУС ЧЙТФХБМШОЩН Й РТЕДПУФБЧМСЕФУС " + +#: cmdline/apt-get.cc:1071 +msgid " [Installed]" +msgstr " [хУФБОПЧМЕОП]" + +#: cmdline/apt-get.cc:1076 +msgid "You should explicitly select one to install." +msgstr "оЕПВИПДЙНП ФПЮОП ХЛБЪБФШ, ЮФП ХУФБОБЧМЙЧБФШ." + +#: cmdline/apt-get.cc:1080 +msgid " has no available version, but exists in the database." +msgstr "" +" ОЕ ЙНЕЕФ ДПУФХРОПК ЧЕТУЙЙ, ОП ЪБРЙУШ П ОЕН РТЙУХФУФЧХЕФ Ч ВБЪЕ ДБООЩИ." + +#: cmdline/apt-get.cc:1081 +msgid "" +"This typically means that the package was mentioned in a dependency and " +msgstr "ьФП ПВЩЮОП ПЪОБЮБЕФ, ЮФП РБЛЕФ ВЩМ ХЛБЪБО ЛБЛ ЪБЧЙУЙНПУФШ Й " + +#: cmdline/apt-get.cc:1082 +msgid "" +"never uploaded, has been obsoleted or is not available with the contents " +msgstr "" +"ОЙЛПЗДБ ОЕ РХВМЙЛПЧБМУС, ВПМШЫЕ ОЕ РПДДЕТЦЙЧБЕФУС ЙМЙ ЧППВЭЕ ПФУХФУФЧХЕФ " + +#: cmdline/apt-get.cc:1083 +msgid "of sources.list" +msgstr "Ч ЙУФПЮОЙЛБИ, РЕТЕЮЙУМЕООЩИ Ч sources.list" + +#: cmdline/apt-get.cc:1094 +msgid "However the following packages replace it:" +msgstr "фЕН ОЕ НЕОЕЕ, УМЕДХАЭЙЕ РБЛЕФЩ ЪБНЕОСАФ ЕЗП:" + +#: cmdline/apt-get.cc:1097 +#, c-format +msgid "Package %s has no installation candidate" +msgstr "дМС РБЛЕФБ %s ОЕ ОБКДЕОП РПДИПДСЭЕЗП ЛБОДЙДБФБ ДМС ХУФБОПЧЛЙ" + +#: cmdline/apt-get.cc:1117 +msgid "Sorry, re-installation of " +msgstr "йЪЧЙОЙФЕ, РЕТЕХУФБОПЧЛБ " + +#: cmdline/apt-get.cc:1117 +msgid " is not possible, it cannot be downloaded" +msgstr " ОЕЧПЪНПЦОБ, РБЛЕФ ОЕЧПЪНПЦОП УЛБЮБФШ" + +#: cmdline/apt-get.cc:1124 +msgid "Sorry, " +msgstr "йЪЧЙОЙФЕ, " + +#: cmdline/apt-get.cc:1124 +msgid " is already the newest version" +msgstr " СЧМСЕФУС УБНПК РПУМЕДОЕК ЧЕТУЙЕК" + +#: cmdline/apt-get.cc:1153 +msgid "Unable to lock the list directory" +msgstr "оЕ ХДБМПУШ ЪБВМПЛЙТПЧБФШ ЛБФБМПЗ" + +#: cmdline/apt-get.cc:1178 +msgid "Could not retrieve digitally signed hash file" +msgstr "оЕЧПЪНПЦОП РПМХЮЙФШ ЙОДЕЛУОЩК ЖБКМ У ГЙЖТПЧПК РПДРЙУША" + +#: cmdline/apt-get.cc:1190 +msgid "Failed to fetch hash file: " +msgstr "оЕ ХДБМПУШ РПМХЮЙФШ ЙОДЕЛУОЩК ЖБКМ: " + +#: cmdline/apt-get.cc:1198 +msgid "" +"Some of the signed hash files could not be retrieved. Aborting operation." +msgstr "" +"оЕЛПФПТЩЕ ЙЪ РПДРЙУБООЩИ ГЙЖТПЧПК РПДРЙУША ЙОДЕЛУОЩИ ЖБКМПЧ ОЕЧПЪНПЦОП " +"УЛБЮБФШ. рТЕТЩЧБОЙЕ ПРЕТБГЙЙ." + +#: cmdline/apt-get.cc:1240 +msgid "Some of the index files had mismatching MD5 sums!" +msgstr "" +"оЕЛПФПТЩЕ ЙЪ ЙОДЕЛУОЩИ ЖБКМПЧ ЙНЕМЙ ОЕУПЧРБДБАЭЙЕ ЛПОФТПМШОЩЕ УХННЩ MD5!" + +#: cmdline/apt-get.cc:1248 +msgid "" +"Some index files failed to download, they have been ignored, or old ones " +"used instead." +msgstr "" +"оЕЛПФПТЩЕ ЙОДЕЛУОЩЕ ЖБКМЩ ОЕ ХДБМПУШ УЛБЮБФШ, ПОЙ МЙВП ВЩМЙ РТПЙЗОПТЙТПЧБОЩ, " +"МЙВП ЧНЕУФП ОЙИ ВЩМЙ ЙУРПМШЪПЧБОЩ УФБТЩЕ ЧЕТУЙЙ." + +#: cmdline/apt-get.cc:1253 +msgid " will not be authenticated." +msgstr " ОЕ ВХДЕФ БХФЕОФЙЖЙГЙТПЧБО." + +#: cmdline/apt-get.cc:1274 +msgid "Internal Error, AllUpgrade broke stuff" +msgstr "чОХФТЕООСС ПЫЙВЛБ, ТЕЪХМШФБФ ТБВПФЩ AllUpgrade ЧУЕ ЙУРПТФЙМ" + +#: cmdline/apt-get.cc:1343 cmdline/apt-get.cc:1376 +#, c-format +msgid "Couldn't find package %s" +msgstr "оЕЧПЪНПЦОП ОБКФЙ РБЛЕФ %s" + +#: cmdline/apt-get.cc:1356 +msgid "Regex compilation error:" +msgstr "пЫЙВЛБ ЛПНРЙМСГЙЙ ТЕЗХМСТОПЗП ЧЩТБЦЕОЙС:" + +#: cmdline/apt-get.cc:1390 +msgid "You might want to run `apt-get -f install' to correct these:" +msgstr "" +"чПЪНПЦОП, чБН РПФТЕВХЕФУС ЪБРХУФЙФШ `apt-get -f install' ДМС ЙУРТБЧМЕОЙС:" + +#: cmdline/apt-get.cc:1393 +msgid "" +"Unmet dependencies. Try 'apt-get -f install' with no packages (or specify a " +"solution)." +msgstr "" +"оЕЛПФПТЩЕ ЪБЧЙУЙНПУФЙ ОЕ ВЩМЙ ОБКДЕОЩ. рПРТПВХКФЕ `apt-get -f install' ВЕЪ " +"ХЛБЪБОЙС РБЛЕФПЧ ЙМЙ ХЛБЦЙФЕ РБЛЕФ-ТЕЫЕОЙЕ." + +#: cmdline/apt-get.cc:1404 +msgid "Some packages could not be installed. This may mean that you have" +msgstr "оЕЛПФПТЩЕ РБЛЕФЩ ОЕЧПЪНПЦОП ХУФБОПЧЙФШ. ьФП НПЦЕФ ПЪОБЮБФШ, ЮФП чЩ" + +#: cmdline/apt-get.cc:1405 +msgid "requested an impossible situation or if you are using the unstable" +msgstr "РПФТЕВПЧБМЙ ОЕЧПЪНПЦОПЕ ЙМЙ чЩ ЙУРПМШЪХЕФЕ ОЕУФБВЙМШОХА ЧЕТУЙА" + +#: cmdline/apt-get.cc:1406 +msgid "distribution that some required packages have not yet been created" +msgstr "ДЙУФТЙВХФЙЧБ, ЗДЕ ОЕЛПФПТЩЕ ФТЕВХЕНЩЕ РБЛЕФЩ ЕЭЕ ОЕ УПЪДБОЩ" + +#: cmdline/apt-get.cc:1407 +msgid "or been moved out of Incoming." +msgstr "ЙМЙ ОЕ ВЩМЙ ПРХВМЙЛПЧБОЩ." + +#: cmdline/apt-get.cc:1411 +msgid "Since you only requested a single operation it is extremely likely that" +msgstr "фБЛ ЛБЛ чЩ РПФТЕВПЧБМЙ ПДОХ ПРЕТБГЙА, ФП УЛПТЕЕ ЧУЕЗП РБЛЕФ РТПУФП" + +#: cmdline/apt-get.cc:1412 +msgid "the package is simply not installable and a bug report against" +msgstr "ОЕЧПЪНПЦОП ХУФБОПЧЙФШ Й ФТЕВХЕФУС ПФРТБЧЙФШ УППВЭЕОЙЕ ПВ ПЫЙВЛЕ" + +#: cmdline/apt-get.cc:1413 +msgid "that package should be filed." +msgstr "У ЬФЙН РБЛЕФПН ТБЪТБВПФЮЙЛБН." + +#: cmdline/apt-get.cc:1416 +msgid "The following information may help to resolve the situation:" +msgstr "уМЕДХАЭБС ЙОЖПТНБГЙС НПЦЕФ РПНПЮШ ТБЪТЕЫЙФШ УЙФХБГЙА:" + +#: cmdline/apt-get.cc:1419 +msgid "Sorry, broken packages" +msgstr "йЪЧЙОЙФЕ, `ВЙФЩЕ' РБЛЕФЩ" + +#: cmdline/apt-get.cc:1442 +msgid "The following extra packages will be installed:" +msgstr "уМЕДХАЭЙЕ ДПРПМОЙФЕМШОЩЕ РБЛЕФЩ ВХДХФ ХУФБОПЧМЕОЩ:" + +#: cmdline/apt-get.cc:1461 +msgid "Calculating Upgrade... " +msgstr "рПДУЮЕФ ПВОПЧМЕОЙК... " + +#: cmdline/apt-get.cc:1464 +msgid "Failed" +msgstr "пЫЙВЛБ" + +#: apt-pkg/contrib/progress.cc:136 cmdline/apt-get.cc:1469 +msgid "Done" +msgstr "ъБЧЕТЫЕОП" + +#: cmdline/apt-get.cc:1534 cmdline/apt-get.cc:1542 +msgid "Internal Error, problem resolver broke stuff" +msgstr "чОХФТЕООСС ПЫЙВЛБ, ВМПЛ ТБЪТЕЫЕОЙС РТПВМЕН ЧУЕ ЙУРПТФЙМ" + +#: cmdline/apt-get.cc:1644 +msgid "Must specify at least one package to fetch source for" +msgstr "" +"оЕПВИПДЙНП ХЛБЪБФШ РП ЛТБКОЕК НЕТЕ ПДЙО РБЛЕФ ДМС УЛБЮЙЧБОЙС ЕЗП ЙУИПДОЙЛБ" + +#: cmdline/apt-get.cc:1718 +#, c-format +msgid "Unable to find a source package for %s" +msgstr "оЕЧПЪНПЦОП ОБКФЙ ЙУИПДОЩК РБЛЕФ ДМС %s" + +#: cmdline/apt-get.cc:1778 +#, c-format +msgid "Sorry, you don't have enough free space in %s" +msgstr "йЪЧЙОЙФЕ, ОЕДПУФБФПЮОП УЧПВПДОПЗП НЕУФБ Ч %s" + +#: cmdline/apt-get.cc:1787 +msgid " of source archives." +msgstr " ЙУИПДОЩИ БТИЙЧПЧ." + +#: cmdline/apt-get.cc:1792 +msgid "Fetch Source " +msgstr "рПМХЮЕОЙЕ ЙУИПДОЙЛБ РБЛЕФБ " + +#: cmdline/apt-get.cc:1823 +msgid "Failed to fetch some archives." +msgstr "оЕ ХДБМПУШ УЛБЮБФШ ОЕЛПФПТЩЕ БТИЙЧЩ." + +#: cmdline/apt-get.cc:1843 cmdline/apt-get.cc:1889 +msgid "Build command '" +msgstr "чЩРПМОЕОЙЕ ЛПНБОДЩ УВПТЛЙ РБЛЕФБ '" + +#: cmdline/apt-get.cc:1843 cmdline/apt-get.cc:1872 cmdline/apt-get.cc:1889 +msgid "' failed." +msgstr "' РТПЧБМЙМПУШ." + +#: cmdline/apt-get.cc:1861 +msgid "Skipping unpack of already unpacked source in " +msgstr "рТПРХУЛ ТБУРБЛПЧЛЙ ХЦЕ ТБУРБЛПЧБООЩИ ЙУИПДОЙЛПЧ РБЛЕФБ Ч " + +#: cmdline/apt-get.cc:1872 +msgid "Unpack command '" +msgstr "чЩРПМОЕОЙЕ ЛПНБОДЩ ТБУРБЛПЧЛЙ '" + +#: apt-pkg/rpm/rpmpm.cc:125 apt-pkg/rpm/rpmpm.cc:357 cmdline/apt-get.cc:1905 +msgid "Couldn't wait for subprocess" +msgstr "оЕЧПЪНПЦОП ДПЦДБФШУС ПЛПОЮБОЙС ЧЩРПМОЕОЙС ЧУРПНПЗБФЕМШОПЗП РТПГЕУУБ" + +#: cmdline/apt-get.cc:1909 +msgid "Child process failed" +msgstr "чУРПНПЗБФЕМШОЩК РТПГЕУУ ЪБЧЕТЫЕО ОЕХДБЮОП" + +#: cmdline/apt-get.cc:1925 +msgid "Usage: apt-get [options] command" +msgstr "йУРПМШЪПЧБОЙЕ: apt-get [ПРГЙЙ] ЛПНБОДБ" + +#: cmdline/apt-get.cc:1926 +msgid " apt-get [options] install pkg1 [pkg2 ...]" +msgstr " apt-get [ПРГЙЙ] install РБЛЕФ1 [РБЛЕФ2 ...]" + +#: cmdline/apt-get.cc:1928 +msgid "apt-get is a simple command line interface for downloading and" +msgstr "apt-get -- ЬФП ХФЙМЙФБ ДМС УЛБЮЙЧБОЙС Й ХУФБОПЧЛЙ РБЛЕФПЧ РТПЗТБНН." + +#: cmdline/apt-get.cc:1929 +msgid "installing packages. The most frequently used commands are update" +msgstr " оБЙВПМЕЕ ЮБУФП ЙУРПМШЪХЕНЩЕ ЛПНБОДЩ: ПВОПЧМЕОЙЕ Й ХУФБОПЧЛБ" + +#: cmdline/apt-get.cc:1930 +msgid "and install." +msgstr "РБЛЕФПЧ." + +#: cmdline/apt-get.cc:1933 +msgid " update - Retrieve new lists of packages" +msgstr " update - рПМХЮЙФШ ОПЧЩЕ УРЙУЛЙ РБЛЕФПЧ" + +#: cmdline/apt-get.cc:1934 +msgid " upgrade - Perform an upgrade" +msgstr " upgrade - чЩРПМОЙФШ ПВОПЧМЕОЙЕ" + +#: cmdline/apt-get.cc:1935 +msgid " install - Install new packages" +msgstr " install - хУФБОПЧЙФШ ОПЧЩЕ РБЛЕФЩ" + +#: cmdline/apt-get.cc:1936 +msgid " remove - Remove packages" +msgstr " remove - хДБМЙФШ РБЛЕФЩ" + +#: cmdline/apt-get.cc:1937 +msgid " source - Download source archives" +msgstr " source - уЛБЮБФШ ЙУИПДОЩЕ БТИЙЧЩ" + +#: cmdline/apt-get.cc:1938 +msgid " dist-upgrade - Distribution upgrade, see apt-get(8)" +msgstr " dist-upgrade - пВОПЧМЕОЙЕ ДЙУФТЙВХФЙЧБ, УН.ФЦ. apt-get(8)" + +#. cout << " dselect-upgrade - Follow dselect selections" << endl; +#: cmdline/apt-get.cc:1940 +msgid " clean - Erase downloaded archive files" +msgstr " clean - хДБМЙФШ УЛБЮБООЩЕ БТИЙЧОЩЕ ЖБКМЩ" + +#: cmdline/apt-get.cc:1941 +msgid " autoclean - Erase old downloaded archive files" +msgstr " autoclean - хДБМЙФШ УФБТЩЕ УЛБЮБООЩЕ БТИЙЧОЩЕ ЖБКМЩ" + +#: cmdline/apt-get.cc:1942 +msgid " check - Verify that there are no broken dependencies" +msgstr " check - рТПЧЕТЙФШ ПФУХФУФЧЙЕ ОБТХЫЕООЩИ ЪБЧЙУЙНПУФЕК" + +#: cmdline/apt-get.cc:1945 +msgid " -h This help text." +msgstr " -h ьФБ УРТБЧЛБ." + +#: cmdline/apt-get.cc:1946 +msgid " -q Loggable output - no progress indicator" +msgstr " -q оЕ ЧЩЧПДЙФШ ЙОДЙЛБФПТ РТПГЕУУБ" + +#: cmdline/apt-get.cc:1947 +msgid " -qq No output except for errors" +msgstr " -qq оЕ ЧЩЧПДЙФШ ОЙЮЕЗП, ЛТПНЕ УППВЭЕОЙК ПВ ПЫЙВЛБИ" + +#: cmdline/apt-get.cc:1948 +msgid " -S Show summary for upgrade operation and quit" +msgstr " -S рПЛБЪБФШ ПФЮЕФ ПРЕТБГЙЙ ПВОПЧМЕОЙС Й ЧЩКФЙ" + +#: cmdline/apt-get.cc:1949 +msgid " -d Download only - do NOT install or unpack archives" +msgstr " -d фПМШЛП УЛБЮБФШ БТИЙЧЩ, ОП ое ХУФБОБЧМЙЧБФШ ЙМЙ ТБУРБЛПЧЩЧБФШ ЙИ" + +#: cmdline/apt-get.cc:1950 +msgid " -s No-act. Perform ordering simulation" +msgstr " -s уЙНХМЙТПЧБФШ ХРПТСДПЮЕОЙЕ ЧНЕУФП ТЕБМШОПЗП ЙУРПМОЕОЙС" + +#: cmdline/apt-get.cc:1951 +msgid " -y Assume Yes to all queries and do not prompt" +msgstr " -y оБ ЧУЕ ЧПРТПУЩ ПФЧЕЮБФШ 'дб' БЧФПНБФЙЮЕУЛЙ" + +#: cmdline/apt-get.cc:1952 +msgid " -f Attempt to continue if the integrity check fails" +msgstr " -f рПРЩФБФШУС РТПДПМЦЙФШ Ч УМХЮБЕ РТПЧБМБ РТПЧЕТЛЙ ГЕМПУФОПУФЙ" + +#: cmdline/apt-get.cc:1953 +msgid " -m Attempt to continue if archives are unlocatable" +msgstr " -m рПРЩФБФШУС РТПДПМЦЙФШ Ч УМХЮБЕ ОЕПВОБТХЦЕОЙС РБЛЕФПЧ" + +#: cmdline/apt-get.cc:1954 +msgid " -u Show a list of upgraded packages as well" +msgstr " -u рПЛБЪБФШ ФБЛЦЕ УРЙУПЛ ПВОПЧМЕООЩИ РБЛЕФПЧ" + +#: cmdline/apt-get.cc:1955 +msgid " -b Build the source package after fetching it" +msgstr " -b уПВТБФШ РБЛЕФ РПУМЕ РПМХЮЕОЙС ЕЗП ЙУИПДОЙЛБ" + +#: cmdline/apt-get.cc:1958 +msgid "See the apt-get(8), sources.list(5) and apt.conf(5) manual" +msgstr "уН. ДПЛХНЕОФБГЙА ОБ apt-get(8), sources.list(5) Й apt.conf(5)" + +#: cmdline/apt-get.cc:1959 +msgid "pages for more information and options." +msgstr "ДМС РПМХЮЕОЙС ВПМЕЕ РПДТПВОПК ЙОЖПТНБГЙЙ." + +#: apt-pkg/acquire-item.cc:142 +#, c-format +msgid "Size of %s did not match what's in the hashfile and was redownloaded." +msgstr "" +"рБЛЕФ ЪБЗТХЦЕО РПЧФПТОП, ФБЛ ЛБЛ ТБЪНЕТ РБЛЕФБ %s ОЕ УПЧРБМ У ХЛБЪБООЩН Ч " +"ИЬЫ-ЖБКМЕ." + +#: apt-pkg/acquire-item.cc:154 +#, c-format +msgid "MD5 of %s did not match what's int the hashfile and was redownloaded." +msgstr "" +"рБЛЕФ ЪБЗТХЦЕО РПЧФПТОП, ФБЛ ЛБЛ MD5-УХННБ РБЛЕФБ %s ОЕ УПЧРБМБ У ХЛБЪБООПК " +"Ч ИЬЫ-ЖБКМЕ." + +#: apt-pkg/acquire-item.cc:428 +msgid "Hashfile signer is not who it's supposed to be (expected " +msgstr "" +"бЧФПТУФЧП РПДРЙУЙ ИЬЫ-ЖБКМБ ПФМЙЮБЕФУС ПФ ФПЗП, ЮФП ПЦЙДБМПУШ (ПЦЙДБМБУШ " +"РПДРЙУШ " + +#: apt-pkg/acquire-item.cc:430 +msgid ", got " +msgstr ", Б РПМХЮЕОБ РПДРЙУШ " + +#: apt-pkg/acquire-worker.cc:108 +#, c-format +msgid "The method driver %s could not be found." +msgstr "рТПЗТБННБ ПВТБВПФЛЙ НЕФПДБ %s ОЕ ОБКДЕОБ." + +#: apt-pkg/acquire-worker.cc:117 apt-pkg/rpm/rpmpm.cc:171 +msgid "Failed to create IPC pipe to subprocess" +msgstr "оЕ ХДБМПУШ ХУФБОПЧЙФШ ПВНЕО ДБООЩНЙ У РПДРТПГЕУУПН" + +#: apt-pkg/acquire-worker.cc:160 +#, c-format +msgid "Method %s did not start correctly" +msgstr "рТПЗТБННБ ПВТБВПФЛЙ НЕФПДБ %s ОЕ УНПЗМБ РТБЧЙМШОП ЪБРХУФЙФШУС" + +#: apt-pkg/acquire-worker.cc:197 +#, c-format +msgid "Invalid message from method %s: %s" +msgstr "оЕЧЕТОПЕ УППВЭЕОЙЕ ПФ НЕФПДБ %s: %s" + +#: apt-pkg/acquire-worker.cc:210 +#, c-format +msgid "Unable to process Capabilities message from %s" +msgstr "оЕЧПЪНПЦОП ПВТБВПФБФШ УППВЭЕОЙЕ ПФ %s" + +#: apt-pkg/acquire-worker.cc:229 +msgid "Method gave invalid 200 URI Start message" +msgstr "нЕФПД ЧЕТОХМ УППВЭЕОЙЕ: ПЫЙВЛБ ОБЮБМБ URI (ЛПД 200)" + +#: apt-pkg/acquire-worker.cc:268 +#, c-format +msgid "Bizzar Error - File size is not what the server reported %s %u" +msgstr "" +"хЦБУОБС ПЫЙВЛБ - ТБЪНЕТ ЖБКМБ ОЕ УПЧРБМ У ФЕН, ЮФП УППВЭЙМ УЕТЧЕТ %s %u" + +#: apt-pkg/acquire-worker.cc:297 +msgid "Method gave invalid 400 URI Failure message" +msgstr "нЕФПД ЧЕТОХМ УППВЭЕОЙЕ: УВПК URI (ЛПД 400)" + +#: apt-pkg/acquire-worker.cc:319 +#, c-format +msgid "Method %s General failure: %s" +msgstr "нЕФПД %s, ПВЭБС ПЫЙВЛБ: %s" + +#: apt-pkg/acquire-worker.cc:503 +#, c-format +msgid "Method %s has died unexpectedly!" +msgstr "ч НЕФПДЕ %s РТПЙЪПЫМБ ЖБФБМШОБС ПЫЙВЛБ!" + +#: apt-pkg/acquire.cc:58 +#, c-format +msgid "Lists directory %spartial is missing." +msgstr "дЙТЕЛФПТЙС УП УРЙУЛБНЙ РБЛЕФПЧ %spartial ПФУХФУФЧХЕФ." + +#: apt-pkg/acquire.cc:62 +#, c-format +msgid "Archive directory %spartial is missing." +msgstr "дЙТЕЛФПТЙС У БТИЙЧОЩНЙ РБЛЕФБНЙ %spartial ПФУХФУФЧХЕФ." + +#: apt-pkg/cachefile.cc:94 +msgid "The package lists or status file could not be parsed or opened." +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ УРЙУПЛ РБЛЕФПЧ ЙМЙ ЖБКМ УФБФХУБ." + +# +#: apt-pkg/cachefile.cc:96 +msgid "You may want to run apt-get update to correct these missing files" +msgstr "чПЪНПЦОП, чБН РПФТЕВХЕФУС ЪБРХУФЙФШ `apt-get update' ДМС ЙУРТБЧМЕОЙС." + +# +#: apt-pkg/clean.cc:44 +msgid "Unable to change to " +msgstr "оЕЧПЪНПЦОП РЕТЕКФЙ Л " + +#: apt-pkg/clean.cc:58 +#, c-format +msgid "Unable to stat %s." +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ %s" + +#: apt-pkg/depcache.cc:62 apt-pkg/depcache.cc:91 +msgid "Building Dependency Tree" +msgstr "рПУФТПЕОЙЕ ДЕТЕЧБ ЪБЧЙУЙНПУФЕК" + +#: apt-pkg/depcache.cc:63 +msgid "Candidate Versions" +msgstr "пРТЕДЕМЕОЙЕ ОЕПВИПДЙНЩИ ЧЕТУЙК" + +#: apt-pkg/depcache.cc:92 +msgid "Dependency Generation" +msgstr "зЕОЕТБГЙС ЪБЧЙУЙНПУФЕК" + +#: apt-pkg/packagemanager.cc:401 +#, c-format +msgid "" +"This installation run will require temporarily removing the essential " +"package %s due to a Conflicts/Pre-Depends loop. This is often bad, but if " +"you really want to do it, activate the APT::Force-LoopBreak option." +msgstr "" +"ьФПФ УЕБОУ ХУФБОПЧЛЙ ФТЕВХЕФ ЧТЕНЕООПЗП ХДБМЕОЙС УЙУФЕНОПЗП РБЛЕФБ %s Ч " +"УЧСЪЙ У ЛПОЖМЙЛФПН ЙМЙ ЪБГЙЛМЙЧБОЙЕН РТЕДЧБТЙФЕМШОЩИ ЪБЧЙУЙНПУФЕК. юБЭЕ " +"ЧУЕЗП ЬФП ОЕРТБЧЙМШОП, ОП ЕУМЙ ЧЩ ДЕКУФЧЙФЕМШОП ЬФПЗП ИПФЙФЕ, ФП " +"БЛФЙЧЙЪЙТХКФЕ ПРГЙА APT::Force-LoopBreak." + +#: apt-pkg/pkgcache.cc:125 +msgid "The package cache file is corrupted" +msgstr "жБКМ У ЛЬЫЕН РБЛЕФПЧ РПЧТЕЦДЕО" + +#: apt-pkg/pkgcache.cc:130 +msgid "The package cache file is an incompatible version" +msgstr "жБКМ У ЛЬЫЕН РБЛЕФПЧ УЖПТНЙТПЧБО ОЕУПЧНЕУФЙНПК ЧЕТУЙЕК APT" + +#: apt-pkg/pkgcachegen.cc:90 +#, c-format +msgid "Error occured while processing %s (NewPackage)" +msgstr "рТЙ ПВТБВПФЛЕ %s (NewPackage) ЧПЪОЙЛМБ ПЫЙВЛБ" + +#: apt-pkg/pkgcachegen.cc:102 +#, c-format +msgid "Error occured while processing %s (UsePackage1)" +msgstr "рТЙ ПВТБВПФЛЕ %s (UsePackage1) ЧПЪОЙЛМБ ПЫЙВЛБ" + +#: apt-pkg/pkgcachegen.cc:125 +#, c-format +msgid "Error occured while processing %s (UsePackage2)" +msgstr "рТЙ ПВТБВПФЛЕ %s (UsePackage2) ЧПЪОЙЛМБ ПЫЙВЛБ" + +#: apt-pkg/pkgcachegen.cc:128 +#, c-format +msgid "Error occured while processing %s (NewFileVer1)" +msgstr "рТЙ ПВТБВПФЛЕ %s (NewFileVer1) ЧПЪОЙЛМБ ПЫЙВЛБ" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "WARNING: '" +msgstr "чойнбойе: дМС РБЛЕФБ '" + +#: apt-pkg/pkgcachegen.cc:138 +msgid "' has 2 packages with same version but different dependencies. " +msgstr "' ЙНЕАФУС ДЧЕ ЪБРЙУЙ У ТБЪОЩНЙ ЪБЧЙУЙНПУФСНЙ. " + +#: apt-pkg/pkgcachegen.cc:139 +msgid "That usually means a packaging bug." +msgstr "пВЩЮОП ЬФП ПЪОБЮБЕФ ПЫЙВЛХ ХРБЛПЧЭЙЛБ." + +#: apt-pkg/pkgcachegen.cc:171 +#, c-format +msgid "Error occured while processing %s (NewVersion1)" +msgstr "рТЙ ПВТБВПФЛЕ %s (NewVersion1) ЧПЪОЙЛМБ ПЫЙВЛБ" + +#: apt-pkg/pkgcachegen.cc:174 +#, c-format +msgid "Error occured while processing %s (UsePackage3)" +msgstr "рТЙ ПВТБВПФЛЕ %s (UsePackage2) ЧПЪОЙЛМБ ПЫЙВЛБ" + +#: apt-pkg/pkgcachegen.cc:177 +#, c-format +msgid "Error occured while processing %s (NewVersion2)" +msgstr "рТЙ ПВТБВПФЛЕ %s (NewVersion2) ЧПЪОЙЛМБ ПЫЙВЛБ" + +#: apt-pkg/contrib/progress.cc:134 +msgid "Error!" +msgstr "пЫЙВЛБ!" + +#. Mostly from MakeStatusCache.. +#: apt-pkg/rpm/rpmfactory.cc:190 apt-pkg/systemfactory.cc:183 +#: apt-pkg/systemfactory.cc:239 apt-pkg/systemfactory.cc:271 +#: apt-pkg/systemfactory.cc:272 apt-pkg/systemfactory.cc:279 +#: apt-pkg/systemfactory.cc:349 apt-pkg/systemfactory.cc:385 +msgid "Reading Package Lists" +msgstr "юФЕОЙЕ УРЙУЛПЧ РБЛЕФПЧ" + +#: apt-pkg/rpm/rpmfactory.cc:195 +msgid "Local Package State - " +msgstr "мПЛБМШОПЕ УПУФПСОЙЕ РБЛЕФБ - " + +#: apt-pkg/rpm/rpmfactory.cc:197 apt-pkg/systemfactory.cc:195 +#, c-format +msgid "Problem with SelectFile %s" +msgstr "пЫЙВЛБ SelectFile %s" + +#: apt-pkg/rpm/rpmfactory.cc:200 apt-pkg/systemfactory.cc:200 +#, c-format +msgid "Problem with MergeList %s" +msgstr "пЫЙВЛБ MergeList %s" + +#: apt-pkg/rpm/rpmfactory.cc:273 +msgid "Processing File Dependencies" +msgstr "пВТБВПФЛБ ЖБКМПЧЩИ ЪБЧЙУЙНПУФЕК" + +#: apt-pkg/rpm/rpmfactory.cc:274 +msgid "Looking for file dependencies" +msgstr "рПЙУЛ ЖБКМПЧЩИ ЪБЧЙУЙНПУФЕК" + +#: apt-pkg/rpm/rpminit.cc:92 +#, c-format +msgid "could not open RPM database:%s" +msgstr "ОЕ ХДБМПУШ ПФЛТЩФШ ВБЪХ ДБООЩИ RPM:%s" + +#: apt-pkg/rpm/rpminit.cc:94 +msgid "You need to run it as the root user." +msgstr "ьФХ ПРЕТБГЙА ОЕПВИПДЙНП ЧЩРПМОСФШ У РТБЧБНЙ БДНЙОЙУФТБФПТБ." + +#: apt-pkg/rpm/rpminit.cc:102 +#, c-format +msgid "could not create RPM database iterator:%s" +msgstr "ОЕ ХДБМПУШ УПЪДБФШ ЙФЕТБФПТ ВБЪЩ ДБООЩИ RPM:%s" + +#: apt-pkg/rpm/rpmlistparser.cc:94 +#, c-format +msgid "Bad regular expression '%s' in option RPM::AllowedDupPkgs." +msgstr "" +"оЕДПРХУФЙНПЕ ТЕЗХМСТОПЕ ЧЩТБЦЕОЙЕ '%s' Ч РБТБНЕФТЕ RPM::AllowedDupPkgs." + +#: apt-pkg/rpm/rpmlistparser.cc:104 +msgid "" +"Option RPM::AllowedDupPackages was replaced with RPM::AllowedDupPkgs, which " +"is a list of regular expressions (apt-config dump for an example). Please " +"update." +msgstr "" +"рБТБНЕФТ RPM::AllowedDupPackages ЪБНЕОЕО ДТХЗЙН РБТБНЕФТПН, RPM::" +"AllowedDupPkgs, ЛПФПТЩК СЧМСЕФУС УРЙУЛПН ТЕЗХМСТОЩИ ЧЩТБЦЕОЙК (ДМС РТЙНЕТБ " +"УН. apt-config dump). рПЦБМХКУФБ ПВОПЧЙФЕ ЛПОЖЙЗХТБГЙПООЩК ЖБКМ." + +#: apt-pkg/rpm/rpmlistparser.cc:121 +#, c-format +msgid "Bad regular expression '%s' in option RPM::HoldPackages." +msgstr "оЕДПРХУФЙНПЕ ТЕЗХМСТОПЕ ЧЩТБЦЕОЙЕ %s' Ч РБТБНЕФТЕ RPM::HoldPackages." + +#: apt-pkg/rpm/rpmlistparser.cc:153 +msgid "oh shit, not handled for " +msgstr "ПК, ОЕФ ПВТБВПФЛЙ ДМС " + +#: apt-pkg/rpm/rpmlistparser.cc:153 +msgid " Tag:" +msgstr " фЬЗ:" + +#: apt-pkg/rpm/rpmlistparser.cc:173 +msgid "Corrupt pkglist: no RPMTAG_NAME in header entry" +msgstr "йУРПТЮЕО pkglist: ОЕ ОБКДЕО ФЬЗ RPMTAG_NAME Ч ЪБЗПМПЧПЮОПК ЪБРЙУЙ" + +#: apt-pkg/rpm/rpmlistparser.cc:213 +#, c-format +msgid "" +"There are two or more versions of the package '%s' installed in your system, " +"which is a situation APT can't handle cleanly at the moment.\n" +"Please do one of the following:\n" +"1) Remove the older packages, leaving only one version installed; or\n" +"2) If you do want to have multiple versions of that package, add the package " +"names to the RPM::AllowedDupPkgs option.\n" +msgstr "" +"ч УЙУФЕНЕ ХУФБОПЧМЕОП ДЧЕ ЙМЙ ВПМЕЕ ЧЕТУЙК РБЛЕФБ '%s', ЬФХ УЙФХБГЙА APT " +"УБНПУФПСФЕМШОП ОЕ НПЦЕФ ЛПТТЕЛФОП ПВТБВПФБФШ.\n" +"рПЦБМХКУФБ, ЧЩВЕТЙФЕ ПДЙО ЙЪ ДЧХИ ЧБТЙБОФПЧ:\n" +"1) хДБМЙФШ УФБТЩЕ ДХВМЙТХАЭЙЕУС РБЛЕФЩ, ПУФБЧЙЧ ФПМШЛП ПДОХ ЧЕТУЙА; ЙМЙ\n" +"2) еУМЙ ОЕПВИПДЙНП УПИТБОЙФШ ОЕУЛПМШЛП ЧЕТУЙК РБЛЕФБ, ФП УМЕДХЕФ ДПВБЧЙФШ " +"ЙНЕОБ УППФЧЕФУФЧХАЭЙИ РБЛЕФПЧ Ч УРЙУПЛ ЪОБЮЕОЙК РБТБНЕФТБ RPM::" +"AllowedDupPkgs.\n" + +#: apt-pkg/rpm/rpmlistparser.cc:493 +msgid "Encountered status field in a non-version description" +msgstr "пВОБТХЦЕОП РПМЕ УФБФХУБ Ч ПРЙУБОЙЙ ВЕЪ ЧЕТУЙЙ" + +#: apt-pkg/rpm/rpmlistparser.cc:614 +msgid "not implemented!!!\n" +msgstr "ОЕ ТЕБМЙЪПЧБОП!!!\n" + +#: apt-pkg/rpm/rpmlistparser.cc:814 +msgid "Bad NotAutomatic flag" +msgstr "оЕЧЕТОЩК ЖМБЗ NotAutomatic" + +#: apt-pkg/rpm/rpmpackagedata.cc:20 +#, c-format +msgid "could not open package priority file %s" +msgstr "ОЕ ХДБМПУШ ПФЛТЩФШ ЖБКМ У ПРЙУБОЙЕН РТЙПТЙФЕФПЧ РБЛЕФПЧ %s" + +#: apt-pkg/rpm/rpmpackagedata.cc:28 +#, c-format +msgid "no data in %s" +msgstr "ОЕФ ДБООЩИ Ч %s" + +#: apt-pkg/rpm/rpmpm.cc:53 +#, c-format +msgid "Internal Error, No file name for %s" +msgstr "чОХФТЕООСС ПЫЙВЛБ, оЕ ПРТЕДЕМЕОП ЙНС ЖБКМБ ДМС РБЛЕФБ %s" + +#: apt-pkg/rpm/rpmpm.cc:140 +#, c-format +msgid "Problem executing scripts %s '%s'" +msgstr "пЫЙВЛБ ЧЩРПМОЕОЙС УЛТЙРФПЧ %s '%s'" + +#: apt-pkg/rpm/rpmpm.cc:143 +msgid "Sub-process returned an error code" +msgstr "рПДРТПГЕУУ ЪБЧЕТЫЙМУС У ПЫЙВЛПК" + +#: apt-pkg/rpm/rpmpm.cc:215 apt-pkg/rpm/rpmpm.cc:222 +#, c-format +msgid "Failure running script %s" +msgstr "пЫЙВЛБ ЧЩРПМОЕОЙС УЛТЙРФБ %s" + +#: apt-pkg/rpm/rpmpm.cc:307 +msgid "Executing RPM (" +msgstr "чЩРПМОСЕФУС РТПЗТБННБ RPM (" + +#: apt-pkg/rpm/rpmpm.cc:347 +msgid "Could not exec " +msgstr "оЕ ХДБМПУШ ЪБРХУФЙФШ " + +#: apt-pkg/rpm/rpmpm.cc:368 +#, c-format +msgid "Sub-process %s terminated by signal (%s)" +msgstr "рПДРТПГЕУУ %s РТЕТЧБО УЙЗОБМПН (%s)" + +#: apt-pkg/rpm/rpmpm.cc:371 +#, c-format +msgid "Sub-process %s returned an error code (%u)" +msgstr "рПДРТПГЕУУ %s ЪБЧЕТЫЙМУС У ПЫЙВЛПК (%u)" + +#: apt-pkg/rpm/rpmpm.cc:374 +#, c-format +msgid "Sub-process %s exited unexpectedly" +msgstr "рПДРТПГЕУУ %s ЪБЧЕТЫЙМУС ОЕРТЕДХУНПФТЕООЩН ПВТБЪПН" + +#: apt-pkg/rpm/rpmpm.cc:464 +msgid "UNKNOWN OPERATION!!!!\n" +msgstr "оейъчеуфобс претбгйс!!!!\n" + +#: apt-pkg/rpm/rpmpm.cc:473 +msgid "Rebuilding RPM database (this may take a few minutes)..." +msgstr "пВОПЧМЕОЙЕ ВБЪЩ ДБООЩИ RPM (ЬФП НПЦЕФ ЪБОСФШ ОЕУЛПМШЛП НЙОХФ)..." + +#: apt-pkg/rpm/rpmpm.cc:477 +msgid "could not rebuild RPM database for upgrade of RPM" +msgstr "ОЕ ХДБМПУШ ПВОПЧЙФШ ВБЪХ ДБООЩИ RPM РЕТЕД ПВОПЧМЕОЙЕН УБНПЗП RPM" + +#: apt-pkg/rpm/rpmsrcrecords.cc:74 apt-pkg/rpm/rpmsrcrecords.cc:80 +#: apt-pkg/rpm/rpmsrcrecords.cc:86 +msgid "error parsing file record" +msgstr "ПЫЙВЛБ ТБЪВПТБ ЖБКМПЧПК ЪБРЙУЙ" + +#: apt-pkg/rpm/rpmsrcrecords.cc:223 +msgid "" +"NOT IMPLEMENTED!!!\n" +"\n" +msgstr "" +"ое тебмйъпчбоп!!!\n" +"\n" + +#: apt-pkg/sourcelist.cc:76 +#, c-format +msgid "Block %s is invalid" +msgstr "оЕЧЕТОЩК ВМПЛ %s" + +#: apt-pkg/sourcelist.cc:121 +#, c-format +msgid "Malformed line %u in source list %s (type)" +msgstr "пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (ФЙР ЙУФПЮОЙЛБ)" + +#: apt-pkg/sourcelist.cc:123 apt-pkg/sourcelist.cc:135 +#, c-format +msgid "Malformed line %u in source list %s (URI)" +msgstr "пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (URI)" + +#: apt-pkg/sourcelist.cc:130 +#, c-format +msgid "Malformed line %u in source list %s (vendor ID)" +msgstr "пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (ID РПУФБЧЭЙЛБ)" + +#: apt-pkg/sourcelist.cc:141 +#, c-format +msgid "Malformed line %u in source list %s (dist)" +msgstr "пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (ДЙУФТЙВХФЙЧ)" + +#: apt-pkg/sourcelist.cc:145 +#, c-format +msgid "Malformed line %u in source list %s (bad vendor ID)" +msgstr "" +"пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (РМПИПК ID РПУФБЧЭЙЛБ)" + +#: apt-pkg/sourcelist.cc:148 +#, c-format +msgid "Malformed line %u in source list %s (bad type)" +msgstr "" +"пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (РМПИПК ФЙР ЙУФПЮОЙЛБ)" + +#: apt-pkg/sourcelist.cc:151 +#, c-format +msgid "Malformed line %u in source list %s (bad URI)" +msgstr "пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (РМПИПК URI)" + +#: apt-pkg/sourcelist.cc:161 +#, c-format +msgid "Malformed line %u in source list %s (Absolute dist)" +msgstr "" +"пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (БВУПМАФОЩК ДЙУФТЙВХФЙЧ)" + +#: apt-pkg/sourcelist.cc:174 +#, c-format +msgid "Malformed line %u in source list %s (dist parse)" +msgstr "" +"пЫЙВПЮОБС ЪБРЙУШ Ч УФТПЛЕ %u Ч УРЙУЛЕ ЙУФПЮОЙЛПЧ (ПЫЙВЛБ ТБЪВПТБ " +"ДЙУФТЙВХФЙЧБ)" + +#: apt-pkg/sourcelist.cc:353 +msgid "could not open hash index" +msgstr "ОЕЧПЪНПЦОП ПФЛТЩФШ ЙОДЕЛУОЩК ИЬЫ-ЖБКМ" + +#: apt-pkg/sourcelist.cc:363 +msgid "No MD5SUM data in hashfile" +msgstr "ч ИЬЫ-ЖБКМЕ ПФУХФУФЧХЕФ ЙОЖПТНБГЙС П MD5-УХННБИ" + +#: apt-pkg/sourcelist.cc:377 +msgid "Error parsing MD5 hash record" +msgstr "пЫЙВЛБ ТБЪВПТБ ЪБРЙУЙ MD5 Ч ИЬЫЕ" + +#: apt-pkg/sourcelist.cc:400 +#, c-format +msgid "" +"Repository entry in sources.list contains extra components that are not " +"listed in the signed hash file: %s" +msgstr "" +"тЕРПЪЙФБТЙК, ПРЙУБООЩК Ч sources.list, УПДЕТЦЙФ ДПРПМОЙФЕМШОЩЕ ЛПНРПОЕОФЩ, " +"ОЕ РТЙУХФУФЧХАЭЙЕ Ч РПДРЙУБООПН ИЬЫ-ЖБКМЕ: %s" + +#: apt-pkg/srcrecords.cc:47 +msgid "Sorry, you must put some 'source' uris in your sources.list" +msgstr "" +"йЪЧЙОЙФЕ, ОП Ч sources.list ДПМЦОБ РТЙУХФУФЧПЧБФШ ИПФС ВЩ ПДОБ ЪБРЙУШ ПВ " +"ЙУФПЮОЙЛЕ ТЕРПЪЙФБТЙС." + +#: apt-pkg/systemfactory.cc:72 +#, c-format +msgid "Failed to rename %s to %s" +msgstr "оЕ ХДБМПУШ РЕТЕЙНЕОПЧБФШ %s Ч %s" + +#: apt-pkg/systemfactory.cc:77 +#, c-format +msgid "Couldn't stat source package list '%s' (%s)" +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ УРЙУПЛ РБЛЕФПЧ '%s' (%s)" + +#: apt-pkg/systemfactory.cc:262 +msgid "IO Error saving source cache" +msgstr "пЫЙВЛБ ЧЧПДБ-ЧЩЧПДБ Ч НПНЕОФ УПИТБОЕОЙС ЛЬЫБ ТЕРПЪЙФБТЙС" + +#: apt-pkg/tagfile.cc:59 +#, c-format +msgid "Unable to parse package file %s (1)" +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ ЖБКМ РБЛЕФa %s (1)" + +#: apt-pkg/tagfile.cc:142 +#, c-format +msgid "Unable to parse package file %s (2)" +msgstr "оЕЧПЪНПЦОП РТПЮЙФБФШ ЖБКМ РБЛЕФa %s (2)" diff --git a/apt/po/stamp-cat-id b/apt/po/stamp-cat-id new file mode 100644 index 0000000..9788f70 --- /dev/null +++ b/apt/po/stamp-cat-id @@ -0,0 +1 @@ +timestamp diff --git a/apt/release b/apt/release new file mode 100755 index 0000000..30227ed --- /dev/null +++ b/apt/release @@ -0,0 +1,121 @@ +#!/bin/sh + +abort() { + echo "Abortado." + exit 1 +} + +trap abort 2 + +prerel=0 + +versao=55 +release=1cl + +filename=apt-0.3.19cnc$versao + +#echo "Atualizando potfiles..." +#( +#cd ~kojima/cvs/i18n/apt +#sudo -u kojima cvs update +#cp *.po ~kojima/rapt/po +#chown kojima.kojima ~kojima/rapt/po/* +#) + +today=`LC_ALL= LANG= date '+%a %b %d %Y'` + +if [ $release == 1cl -a $prerel == 0 ]; then + +if ! grep "released version 0.3.19cnc$versao" apt.spec >/dev/null; then +changelog='*'" $today Alfredo K. Kojima \n\ ++ apt-0.3.19cnc$versao-$release\n\ +- released version 0.3.19cnc$versao\n" +fi + +else +changelog="" +fi + +WWWDIR=/home/kojima/www/rapt/ +export CVS_RSH=ssh + +if test `hostname` != minduim; then + echo "This script is only meant for myself. Don't run it!" + exit 1 +fi + +if test $prerel == 1; then + echo "Gerando PRE versao $versao release $release" +else + echo "Gerando versao $versao release $release" +fi + +ver=`grep "#define VERSION" configure|sed -e s/"#define VERSION"//` + + +if test $ver != \"0.3.19cnc$versao\"; then + echo "Versao do configure estб em $ver, atualize para $versao" + exit 1 +fi + + +echo "Criando tarball a partir do cvs" +( +cd tmp +rm -fr rapt +echo -n CVS +cvs -z3 -d kojima@cvs.conectiva.com.br:/home/cvs export -D now rapt +(cd rapt; make -f Makefile startup; make distclean) +rm -fr $filename +mv rapt $filename +tar czf $filename.tar.gz $filename +cp $filename.tar.gz /usr/src/rpm/SOURCES +) + +echo "Gerando apt.spec" + +if [ $release == 1cl -a $prerel -eq 0 ]; then + sed -e s/%changelog/"%changelog\n$changelog"/g apt.spec > tmp.spec + mv -f tmp.spec apt.spec +fi + +sed -e "s/^Version:.*/Version: 0.3.19cnc$versao/" \ + -e "s/^Release:.*/Release: $release/g" apt.spec > tmp.spec +mv -f tmp.spec apt.spec + +vim apt.spec -c /changelog + + +echo "Criando RPM" + +rpm -ba apt.spec + +if test $prerel == 1; then + echo "Prerelease pronto!" + cp /usr/src/rpm/RPMS/i386/$filename-$release* ~kojima/www + exit +fi + +./copy 0.3.19cnc$versao-$release + +echo "apt versao $versao, release $release feito!" + + +echo "Enviar announcement pra lista do apt?" +read res +if test x$res = xy; then + +mail apt-rpm@distro.conectiva.com.br -s "[ANNOUNCE] apt 0.3.19cnc$versao-$release" < + +int main() +{ + char Buffer[4096]; + + while (1) + { + int Res = read(STDIN_FILENO,Buffer,sizeof(Buffer)); + if (Res <= 0) + while (1) sleep(100); + if (write(STDOUT_FILENO,Buffer,Res) != Res) + break; + } + return 0; +} diff --git a/apt/test/scratch.cc b/apt/test/scratch.cc new file mode 100644 index 0000000..c8888a1 --- /dev/null +++ b/apt/test/scratch.cc @@ -0,0 +1,102 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +int main(int argc,char *argv[]) +{ + pkgInitialize(*_config); + +// cout << flNoLink(argv[1]) << endl; + +// #if 0 +/* DynamicMMap *FileMap = new DynamicMMap(MMap::Public); + pkgFLCache *FList = new pkgFLCache(*FileMap); + + char *Name = "/tmp/test"; + pkgFLCache::PkgIterator Pkg(*FList,0); + pkgFLCache::NodeIterator Node = FList->GetNode(Name,Name+strlen(Name),Pkg.Offset(),true,false); + cout << (pkgFLCache::Node *)Node << endl; + Node = FList->GetNode(Name,Name+strlen(Name),Pkg.Offset(),true,false); + cout << (pkgFLCache::Node *)Node << endl; +*/ +// #if 0 + _config->Set("Dir::State::status","/tmp/testing/status"); + + debDpkgDB Db; + + { + OpTextProgress Prog; + + if (Db.ReadyPkgCache(Prog) == false) + cerr << "Error!" << endl; + Prog.Done(); + + if (Db.ReadyFileList(Prog) == false) + cerr << "Error!" << endl; + } + + if (_error->PendingError() == true) + { + _error->DumpErrors(); + return 0; + } + +/* Db.GetFLCache().BeginDiverLoad(); + pkgFLCache::PkgIterator Pkg(Db.GetFLCache(),0); + if (Db.GetFLCache().AddDiversion(Pkg,"/usr/include/linux/kerneld.h","/usr/bin/nslookup") == false) + cerr << "Error!" << endl; + + const char *Tmp = "/usr/include/linux/kerneld.h"; + pkgFLCache::NodeIterator Nde = Db.GetFLCache().GetNode(Tmp,Tmp+strlen(Tmp),0,false,false); + map_ptrloc Loc = Nde->File; + + for (; Nde.end() == false && Nde->File == Loc; Nde++) + cout << Nde->Flags << ',' << Nde->Pointer << ',' << Nde.File() << endl; + Db.GetFLCache().FinishDiverLoad();*/ + +/* unsigned int I = 0; + pkgFLCache &Fl = Db.GetFLCache(); + while (I < Fl.HeaderP->HashSize) + { + cout << I << endl; + pkgFLCache::NodeIterator Node(Fl,Fl.NodeP + Fl.HeaderP->FileHash + I++); + if (Node->Pointer == 0) + continue; + for (; Node.end() == false; Node++) + { + cout << Node.DirN() << '/' << Node.File(); + if (Node->Flags == pkgFLCache::Node::Diversion) + cout << " (div)"; + if (Node->Flags == pkgFLCache::Node::ConfFile) + cout << " (conf)"; + cout << endl; + } + }*/ + + for (int I = 1; I < argc; I++) + { + FileFd F(argv[I],FileFd::ReadOnly); + debDebFile Deb(F); + + if (Deb.ExtractControl(Db) == false) + cerr << "Error!" << endl; + cout << argv[I] << endl; + + pkgCache::VerIterator Ver = Deb.MergeControl(Db); + if (Ver.end() == true) + cerr << "Failed" << endl; + else + cout << Ver.ParentPkg().Name() << ' ' << Ver.VerStr() << endl; + + pkgExtract Extract(Db.GetFLCache(),Ver); + Deb.ExtractArchive(Extract); + } +// #endif +//#endif + _error->DumpErrors(); +} diff --git a/apt/test/versions.lst b/apt/test/versions.lst new file mode 100644 index 0000000..da84284 --- /dev/null +++ b/apt/test/versions.lst @@ -0,0 +1,38 @@ +# List of +# ver1 ver2 ret +# Of versions worth testing +# 1 means that ver1 > ver2 +# -1 means that ver1 < ver2 +# 0 means that ver1 = ver2 +7.6p2-4 7.6-0 1 +1.0.3-3 1.0-1 1 +1.3 1.2.2-2 1 +1.3 1.2.2 1 + +# Important attributes +- . -1 +p - -1 +a - -1 +z - -1 +a . -1 +z . -1 + +# Epochs +1:0.4 10.3 1 +1:1.25-4 1:1.25-8 -1 + +# Junk +1:1.2.13-3 1:1.2.13-3.1 -1 +2.0.7pre1-4 2.0.7r-1 -1 + +# Test some properties of text strings +0-pre 0-pre 0 +0-pre 0-pree -1 + +1.1.6r2-2 1.1.6r-1 1 +2.6b2-1 2.6b-2 1 + +98.1p5-1 98.1-pre2-b6-2 -1 +0.4a6-2 0.4-1 1 + +1:3.0.5-2 1:3.0.5.1 -1 diff --git a/apt/test/versiontest.cc b/apt/test/versiontest.cc new file mode 100644 index 0000000..1e7d82b --- /dev/null +++ b/apt/test/versiontest.cc @@ -0,0 +1,217 @@ +// -*- mode: cpp; mode: fold -*- +// Description /*{{{*/ +// $Id: versiontest.cc,v 1.1.1.1 2000/08/10 12:42:39 kojima Exp $ +/* ###################################################################### + + Version Test - Simple program to run through a file and comare versions. + + Each version is compared and the result is checked against an expected + result in the file. The format of the file is + a b Res + Where Res is -1, 1, 0. dpkg -D=1 --compare-versions a "<" b can be + used to determine what Res should be. # at the start of the line + is a comment and blank lines are skipped + + ##################################################################### */ + /*}}}*/ +#include +#include +#include +#include +#include + +static int verrevcmp(const char *val, const char *ref) +{ + int vc, rc; + long vl, rl; + const char *vp, *rp; + + if (!val) + val = ""; + if (!ref) + ref = ""; + for (;;) + { + vp = val; + while (*vp && !isdigit(*vp)) + vp++; + rp = ref; + while (*rp && !isdigit(*rp)) + rp++; + for (;;) + { + vc= val == vp ? 0 : *val++; + rc= ref == rp ? 0 : *ref++; + if (!rc && !vc) + break; + if (vc && !isalpha(vc)) + vc += 256; /* assumes ASCII character set */ + if (rc && !isalpha(rc)) + rc += 256; + if (vc != rc) + return vc - rc; + } + val = vp; + ref = rp; + vl = 0; + if (isdigit(*vp)) + vl = strtol(val,(char**)&val,10); + rl = 0; + if (isdigit(*rp)) + rl = strtol(ref,(char**)&ref,10); + if (vl != rl) + return vl - rl; + if (!*val && !*ref) + return 0; + if (!*val) + return -1; + if (!*ref) + return +1; + } +} + +#if 0 +static int verrevcmp(const char *val, const char *ref) +{ + int vc, rc; + long vl, rl; + const char *vp, *rp; + + if (!val) val= ""; + if (!ref) ref= ""; + for (;;) + { + vp= val; while (*vp && !isdigit(*vp) && *vp != '~') vp++; + rp= ref; while (*rp && !isdigit(*rp) && *rp != '~') rp++; + for (;;) + { + vc= val == vp ? 0 : *val++; + rc= ref == rp ? 0 : *ref++; + if (!rc && !vc) break; + if (vc && !isalpha(vc)) vc += 256; /* assumes ASCII character set */ + if (rc && !isalpha(rc)) rc += 256; + if (vc != rc) return vc - rc; + } + + val= vp; + ref= rp; + if (*vp == '~') val++; + if (*rp == '~') ref++; + vl=0; if (isdigit(*val)) vl= strtol(val,(char**)&val,10); + rl=0; if (isdigit(*ref)) rl= strtol(ref,(char**)&ref,10); + if (vl == 0 && rl == 0) + { + if (*vp == '~' && *rp != '~') return -1; + if (*vp != '~' && *rp == '~') return +1; + } + if (*vp == '~') + vl *= -1; + if (*rp == '~') + rl *= -1; + if (vl != rl) return vl - rl; + if (!*val && !*ref) return 0; + if (!*val) + { + if (*ref == '~') + return +1; + else + return -1; + } + + if (!*ref) + { + if (*val == '~') + return -1; + else + return +1; + } + } +} +#endif + +bool RunTest(const char *File) +{ + ifstream F(File,ios::in | ios::nocreate); + if (!F != 0) + return false; + + char Buffer[300]; + int CurLine = 0; + + while (1) + { + F.getline(Buffer,sizeof(Buffer)); + CurLine++; + if (F.eof() != 0) + return true; + if (!F != 0) + return _error->Error("Line %u in %s is too long",CurLine,File); + + // Comment + if (Buffer[0] == '#' || Buffer[0] == 0) + continue; + + // First version + char *I; + char *Start = Buffer; + for (I = Buffer; *I != 0 && *I != ' '; I++); + string A(Start, I - Start); + + if (*I == 0) + return _error->Error("Invalid line %u",CurLine); + + // Second version + I++; + Start = I; + for (I = Start; *I != 0 && *I != ' '; I++); + string B(Start,I - Start); + + if (*I == 0 || I[1] == 0) + return _error->Error("Invalid line %u",CurLine); + + // Result + I++; + int Expected = atoi(I); + int Res = pkgVersionCompare(A.c_str(),B.c_str()); + int Res2 = verrevcmp(A.c_str(),B.c_str()); + cout << "'" << A << "' ? '" << B << "' = " << Res << " (= " << Expected << ") " << Res2 << endl; + if (Res != Expected) + _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected); + + // Check the reverse as well + Expected = -1*Expected; + Res = pkgVersionCompare(B.c_str(),A.c_str()); + Res2 = verrevcmp(B.c_str(),A.c_str()); + cout << "'" << B << "' ? '" << A << "' = " << Res << " (= " << Expected << ") " << Res2 << endl; + if (Res != Expected) + _error->Error("Comparison failed on line %u. '%s' ? '%s' %i != %i",CurLine,A.c_str(),B.c_str(),Res,Expected); + } +} + +int main(int argc, char *argv[]) +{ + if (argc <= 1) + { + cerr << "You must specify a test file" << endl; + return 0; + } + + RunTest(argv[1]); + + // Print any errors or warnings found + if (_error->empty() == false) + { + string Err; + while (_error->empty() == false) + { + + bool Type = _error->PopMessage(Err); + if (Type == true) + cout << "E: " << Err << endl; + else + cout << "W: " << Err << endl; + } + + return 0; + } +} diff --git a/apt/tools/CVS/Entries b/apt/tools/CVS/Entries new file mode 100644 index 0000000..8d0dee8 --- /dev/null +++ b/apt/tools/CVS/Entries @@ -0,0 +1,13 @@ +/cached_md5.h/1.1/Tue Aug 7 20:46:03 2001// +/dumprpmdb.c/1.1.1.1/Thu Aug 10 12:42:39 2000// +/hashtable.c/1.1.1.1/Thu Aug 10 12:42:39 2000// +/hashtable.h/1.1.1.1/Thu Aug 10 12:42:39 2000// +/hdlist2pkglist.cc/1.3/Thu Jul 12 21:47:33 2001// +/mkpackages.c/1.4/Thu Sep 28 21:51:57 2000// +/mkstatus.c/1.1.1.1/Thu Aug 10 12:42:39 2000// +/Makefile/1.13/Tue Nov 13 14:24:16 2001// +/cached_md5.cc/1.2/Fri Nov 16 01:13:08 2001// +/genbasedir/1.21/Wed Mar 6 17:17:13 2002// +/genpkglist.cc/1.17/Wed Mar 6 17:17:13 2002// +/gensrclist.cc/1.11/Wed Mar 6 17:17:13 2002// +D diff --git a/apt/tools/CVS/Repository b/apt/tools/CVS/Repository new file mode 100644 index 0000000..b142e5b --- /dev/null +++ b/apt/tools/CVS/Repository @@ -0,0 +1 @@ +rapt/tools diff --git a/apt/tools/CVS/Root b/apt/tools/CVS/Root new file mode 100644 index 0000000..b27282c --- /dev/null +++ b/apt/tools/CVS/Root @@ -0,0 +1 @@ +:pserver:anonymous@cvs.conectiva.com.br:/home/cvs diff --git a/apt/tools/Makefile b/apt/tools/Makefile new file mode 100644 index 0000000..658643d --- /dev/null +++ b/apt/tools/Makefile @@ -0,0 +1,32 @@ + +BASE=.. +SUBDIR=tools + +# Bring in the default rules +include ../buildlib/defaults.mak + +PROGRAM=genpkglist +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = genpkglist.cc cached_md5.cc +include $(PROGRAM_H) + +PROGRAM=gensrclist +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = gensrclist.cc cached_md5.cc +include $(PROGRAM_H) + +PROGRAM=hdlist2pkglist +SLIBS = -lapt-pkg $(RPMLIBS) +LIB_MAKES = apt-pkg/makefile +SOURCE = hdlist2pkglist.cc +include $(PROGRAM_H) + +#PROGRAM=apt-listconfigs +#SLIBS = -lapt-pkg $(RPMLIBS) +#LIB_MAKES = apt-pkg/makefile +#SOURCE = apt-listconfigs.cc +#include $(PROGRAM_H) + + diff --git a/apt/tools/cached_md5.cc b/apt/tools/cached_md5.cc new file mode 100644 index 0000000..55a2ffc --- /dev/null +++ b/apt/tools/cached_md5.cc @@ -0,0 +1,149 @@ +/* + * $Id: cached_md5.cc,v 1.2 2001/11/13 17:32:08 kojima Exp $ + * + * $Log: cached_md5.cc,v $ + * Revision 1.2 2001/11/13 17:32:08 kojima + * Patches from Dmitry Levin + * apt-0.3.19cnc52-configure.patch -- patch for configure to add Russian + * translation and better support of + * RPM4's db3 usage. + * apt-0.3.19cnc52-i18n.patch -- i18n patch. All APT messages now can be + * localized. + * apt-0.3.19cnc52-replace-support.patch + * -- support for Replace option. It is + * better detection whether package is truly + * removed or is going to be replaced by + * package with different name. + * Patch from Ivan Zakharyashev: + * apt-cdrom.newfix_imz.patch -- Fixes apt-cdrom to better manage + * repository search when CD has both RPMS + * and SRPMS. + * Alexander Bokovoy : + * apt-gpg-pubring.patch -- uses --homedir instead of --keyring + * option to GPG. It is generally better + * because you also can specify GPG + * options in + * ${Apt::GPG::PubringPath}/options + * apt-ru.po -- updated Russian translation for APT + * (Dmitry Levin and me). + * + * Revision 1.1 2001/08/07 20:46:03 kojima + * Alexander Bokovoy 's patch for cleaning + * up genpkglist + * + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "cached_md5.h" + +#include +#include +#include +#include + +// from rpmlib +extern "C" { + extern int mdfile( const char *fn, unsigned char *digest ); +}; + +extern const char *__progname; + +CachedMD5::CachedMD5( string DirName ) +{ + string fname = DirName; + for ( string::iterator i = fname.begin(); i != fname.end(); ++i ) + if ( '/' == *i ) + *i = '_'; + + filename = _config->FindDir( "Dir::Cache", "/var/cache/apt" ) + '/' + + __progname + '/' + + fname + ".md5cache"; + + FILE *f = fopen( filename.c_str(), "r" ); + if (!f) { + return; + } + + while (1) { + string file; + FileData data; + char buf[BUFSIZ]; + + if ( !fgets(buf, sizeof(buf), f) ) + break; + + char *p = strchr( buf, ' ' ); + assert(p); + + file = string( buf, p++ ); + + char *pp = strchr( p, ' ' ); + assert(p); + data.md5 = string( p, pp++ ); + + data.timestamp = atol( pp ); + + md5table[file] = data; + } + + fclose(f); +} + + +CachedMD5::~CachedMD5() +{ + FILE *f = fopen( filename.c_str(), "w+" ); + if (!f) + { + // probably running as != root and not a real problem + + //cerr << __progname << ": could not open file " << + //filename << " for writing:" << strerror(errno) << endl; + } else + { + for ( map::const_iterator iter = md5table.begin(); + iter != md5table.end(); + iter++ ) + { + string file = (*iter).first; + const FileData &data = (*iter).second; + + fprintf( f, "%s %s %lu\n", + file.c_str(), + data.md5.c_str(), + data.timestamp ); + } + fclose(f); + } +} + + +void CachedMD5::MD5ForFile( string FileName, time_t timestamp, + unsigned char *buf) +{ + if ( md5table.find(FileName) != md5table.end() + && timestamp == md5table[FileName].timestamp ) + { + strcpy( (char*)buf, md5table[FileName].md5.c_str() ); + return; + } + + FileData data; + + mdfile( FileName.c_str(), buf ); + data.md5 = string( (char*)buf ); + data.timestamp = timestamp; + + md5table[FileName] = data; +} diff --git a/apt/tools/cached_md5.h b/apt/tools/cached_md5.h new file mode 100644 index 0000000..f1d06a1 --- /dev/null +++ b/apt/tools/cached_md5.h @@ -0,0 +1,38 @@ +/* + * $Id: cached_md5.h,v 1.1 2001/08/07 20:46:03 kojima Exp $ + * + * $Log: cached_md5.h,v $ + * Revision 1.1 2001/08/07 20:46:03 kojima + * Alexander Bokovoy 's patch for cleaning + * up genpkglist + * + * + */ + +#ifndef __CACHED_MD5_H__ +#define __CACHED_MD5_H__ + +#include +#include +#include + +class CachedMD5 +{ + string filename; + + struct FileData + { + string md5; + time_t timestamp; + }; + + map md5table; + +public: + void MD5ForFile( string FileName, time_t timestamp, unsigned char *buf ); + + CachedMD5( string DirName ); + ~CachedMD5(); +}; + +#endif /* __CACHED_MD5_H__ */ diff --git a/apt/tools/dumprpmdb.c b/apt/tools/dumprpmdb.c new file mode 100644 index 0000000..7dcc3d5 --- /dev/null +++ b/apt/tools/dumprpmdb.c @@ -0,0 +1,44 @@ + +#include +#include +#include + + + +int main() +{ + rpmdb db; + Header header; + unsigned ofs; + + rpmReadConfigFiles(NULL, NULL); + + if (rpmdbOpen(NULL, &db, O_RDONLY, 0644) != 0) { + puts("couldnt open rpm DB"); + return 0; + } + + + ofs = rpmdbFirstRecNum(db); + + while (ofs!=0) { + int count; + int type; + int num; + char *str; + + header = rpmdbGetRecord(db, ofs); + if (!header) + break; + + headerGetEntry(header, RPMTAG_NAME, &type, (void **)&str, &count); + if (headerGetEntry(header, RPMTAG_SIZE, &type, (void **)&num, &count)) + printf("%s ???\n", str); + else + printf("%s %i\n", str, num); + headerFree(header); + + ofs = rpmdbNextRecNum(db, ofs); + } +} + diff --git a/apt/tools/genbasedir b/apt/tools/genbasedir new file mode 100755 index 0000000..90031d8 --- /dev/null +++ b/apt/tools/genbasedir @@ -0,0 +1,410 @@ +#!/bin/sh +# +# $Id: genbasedir,v 1.21 2001/12/12 14:50:43 kojima Exp $ +# +# This script generates the contents of the base/ directory, by creating +# the pkglists and the hash file. Update the components directory to contain +# the components of your repository. +# +# $Log: genbasedir,v $ +# Revision 1.21 2001/12/12 14:50:43 kojima +# fixed genbasedir for --flat and relative --topdir specifications +# fixed --flat in gensrclist +# +# Revision 1.20 2001/11/30 20:40:27 kojima +# patched --progress stuff from stelian +# +# Revision 1.19 2001/11/09 21:13:25 kojima +# * Skips correctly over empty package directories +# +# * Adds the --bz2only argument which makes genbasedir +# to generate only the .bz2 compressed versions of pkglist +# and srclist (space gain...) +# +# * Doesn't change the timestamps on pkglists/srclists if +# the contents are not modified (making possible for example +# to make several consecutive runs of genbasedir without +# having the apt clients download the indexes again and again). +# +# * Some minor cleanups (remove the temporary files in /tmp +# at the end of the script etc). +# +# Revision 1.18 2001/03/11 14:36:28 claudio +# Added appropriate message at the end of script. +# +# Revision 1.17 2001/01/04 21:26:14 kojima +# fixed some mem leaks +# +# Revision 1.16 2000/12/10 13:42:58 claudio +# Added linefeeds to usage message, replaced spaces for tabs +# +# Revision 1.15 2000/11/08 21:30:00 kojima +# fixed bug in release retrieval code +# +# Revision 1.14 2000/11/08 20:40:23 kojima +# fixed compat prob with bash1 +# +# Revision 1.13 2000/11/06 12:53:49 kojima +# fixed compile errors for RedHat 6.x (with gcc -Wall -Werror) +# +# Revision 1.12 2000/10/31 20:30:42 kojima +# some updates +# +# Revision 1.11 2000/10/30 16:41:18 kojima +# fixed genbasedir +# +# Revision 1.9 2000/10/29 21:49:54 kojima +# fixed gensrclist/pkglist bug +# +# Revision 1.8 2000/10/25 17:17:35 kojima +# *** empty log message *** +# +# Revision 1.7 2000/10/25 15:48:35 kojima +# *** empty log message *** +# +# Revision 1.6 2000/10/23 14:31:57 kojima +# *** empty log message *** +# +# Revision 1.5 2000/10/19 19:32:34 claudio +# Language setting to generate a consistent pkglist. +# + +usage="\ +Usage: genbasedir [] [ ... ]\n\ +Options:\n\ + -s, --sign Generate and sign hashfile\n\ + --hashonly Do hashfile stuff only\n\ + --listonly Generate pkglists/srclists and quit\n\ + --bz2only Generate only compressed lists\n\ + --topdir=dir Top directory of repository\n\ + --progress Show progress bars for genpkglist/gensrclist\n\ + --updateinfo=file Update information file\n" + +basedir=. +signature=0 +listonly=0 +hashonly=0 +updateinfo="" +mapi=0 +bz2only=0 +progress= + +# bloat is necessary for non-Conectiva distros, at least RH, +# because they use file dependencies with a non-predictable +# heuristic. So we can't strip-off paths that will probably +# never appear in dependencies. +bloat="" + + +# flat is for repositories where RPMS and SRPMS are kept in the +# same directory level. +flat="" + +while test $# -gt 0 ; do + case "${1}" in + -h | --help) + echo -e "${usage}" + exit 0 + ;; + --mapi) + # hee hee hee.. + mapi=1 + ;; + --listonly) + listonly=1 + ;; + --hashonly) + hashonly=1 + ;; + --bz2only) + bz2only=1 + ;; + --updateinfo=*) + updateinfo=${1} + ;; + --bloat) + bloat="--bloat" + ;; + --flat) + flat="--flat" + ;; + --topdir=*) + topdir="`echo \"${1}\" | sed -e 's/^[^=]*=//'`" + if [ ! -d $topdir ]; then + echo "Invalid top directory for distribution ${topdir}" 1>&2 + exit 1 + fi + ;; + --progress) + progress="--progress" + ;; + -s | --sign) + signature=1; + ;; + -*) + echo -e "${usage}" 1>&2 + exit 1 + ;; + *) + break + ;; + esac + shift +done + +distro=${1} +shift + +components=$* + +if [ -z "$components" ]; then + echo -e "${usage}" + exit 0 +fi + + +getsize() { + tmp=`wc -c $1` + echo $tmp|cut -f1 -d\ +} + + +phashstuff() { + size=`getsize ${1}` + md5=`md5sum ${1}|cut -f1 -d\ ` + + echo " $md5 $size ${2}" +} + + + +cd ${topdir} + +# this will fix the path if it was relative +topdir=`pwd` + +basedir_=`echo ${distro}/base|tr -s /` +basedir=${topdir}/$basedir_ + + +# release file +# ------------ + +#for comp in ${components}; do +# true > ${basedir}/release.$comp +# +#done + + +if [ $hashonly -ne 1 ]; then +# package lists +# ------------- + +true > /tmp/srcidx.$$ + +for comp in ${components}; do + echo -n "${comp}: " + + echo -n "pkglist " + + # Save older pkglist + if [ -f $basedir/pkglist.$comp ]; then + mv -f $basedir/pkglist.$comp $basedir/pkglist.$comp.old + fi + + if test x$updateinfo = x; then + (cd $basedir; genpkglist $progress $bloat --index /tmp/srcidx.$comp.$$ $topdir/${distro} $comp) + else + (cd $basedir; genpkglist $progress $bloat --index /tmp/srcidx.$comp.$$ --info $updateinfo $topdir/${distro} $comp) + fi + if [ $? -ne 0 ]; then + echo + echo "Error executing genpkglist." + exit 1 + fi + + if [ -f $basedir/pkglist.$comp ]; then + + # Compare with older pkglist. + if [ -f $basedir/pkglist.$comp.old ]; then + if cmp -s $basedir/pkglist.$comp.old $basedir/pkglist.$comp; then + mv -f $basedir/pkglist.$comp.old $basedir/pkglist.$comp + fi + fi + + # Save older compressed pkglist + if [ -f $basedir/pkglist.$comp.bz2 ]; then + mv -f $basedir/pkglist.$comp.bz2 $basedir/pkglist.$comp.bz2.old + fi + + bzip2 -c $basedir/pkglist.$comp > $basedir/pkglist.$comp.bz2 + + # Compare with older compressed pkglist. + if [ -f $basedir/pkglist.$comp.bz2.old ]; then + if cmp -s $basedir/pkglist.$comp.bz2.old $basedir/pkglist.$comp.bz2; then + mv -f $basedir/pkglist.$comp.bz2.old $basedir/pkglist.$comp.bz2 + fi + fi + + if [ $bz2only -eq 1 ]; then + rm -f $basedir/pkglist.$comp + fi + + rm -f $basedir/pkglist.$comp.old + rm -f $basedir/pkglist.$comp.bz2.old + fi + + cat /tmp/srcidx.$comp.$$ >> /tmp/srcidx.$$ + + echo "done" +done + +for comp in ${components}; do + echo -n "${comp}: " + + echo -n "srclist " + + # Save older srclist + if [ -f $basedir/srclist.$comp ]; then + mv -f $basedir/srclist.$comp $basedir/srclist.$comp.old + fi + + + sfix="/.." + if test x$flat != x; then + sfix="" + fi + + if [ $mapi -ne 0 ]; then + (cd $basedir; gensrclist $progress $flat --mapi $topdir/${distro}${sfix} $comp /tmp/srcidx.$comp.$$) + else + (cd $basedir; gensrclist $progress $flat $topdir/${distro}${sfix} $comp /tmp/srcidx.$$) + fi + if [ $? -ne 0 ]; then + echo + echo "Error executing gensrclist." + exit 1 + fi + + + + if [ -f $basedir/srclist.$comp ]; then + + # Compare with older srclist. + if [ -f $basedir/srclist.$comp.old ]; then + if cmp -s $basedir/srclist.$comp.old $basedir/srclist.$comp; then + mv -f $basedir/srclist.$comp.old $basedir/srclist.$comp + fi + fi + + # Save older compressed srclist + if [ -f $basedir/srclist.$comp.bz2 ]; then + mv -f $basedir/srclist.$comp.bz2 $basedir/srclist.$comp.bz2.old + fi + + bzip2 -c $basedir/srclist.$comp > $basedir/srclist.$comp.bz2 + + # Compare with older compressed srclist. + if [ -f $basedir/srclist.$comp.bz2.old ]; then + if cmp -s $basedir/srclist.$comp.bz2.old $basedir/srclist.$comp.bz2; then + mv -f $basedir/srclist.$comp.bz2.old $basedir/srclist.$comp.bz2 + fi + fi + + if [ $bz2only -eq 1 ]; then + rm -f $basedir/srclist.$comp + fi + + rm -f $basedir/srclist.$comp.old + rm -f $basedir/srclist.$comp.bz2.old + fi + + rm -f /tmp/srcidx.$comp.$$ + + echo "done" +done + +fi + +rm -f /tmp/srcidx.$$ + +if [ $listonly -eq 0 ]; then + # Save older hashfile + if [ -f $basedir/hashfile ]; then + mv -f $basedir/hashfile $basedir/hashfile.old + fi + hf=${basedir}/hashfile + true > $hf +else + hf=/dev/null +fi + +echo "MD5SUM:" >> $hf + +pkglist_=${basedir_}/pkglist +srclist_=${basedir_}/srclist +release_=${basedir_}/release +pkglist=${basedir}/pkglist +srclist=${basedir}/srclist +release=${basedir}/release + +for comp in ${components}; do + echo -n "${comp}: " + + echo -n "hashfile " + if [ -f ${pkglist}.$comp ]; then + phashstuff ${pkglist}.$comp ${pkglist_}.$comp >> $hf + fi + if [ -f ${srclist}.$comp ]; then + phashstuff ${srclist}.$comp ${srclist_}.$comp >> $hf + fi + + if [ -f ${pkglist}.$comp.bz2 ]; then + phashstuff ${pkglist}.$comp.bz2 ${pkglist_}.$comp.bz2 >> $hf + fi + if [ -f ${srclist}.$comp.bz2 ]; then + phashstuff ${srclist}.$comp.bz2 ${srclist_}.$comp.bz2 >> $hf + fi + + if [ -f ${release}.$comp ]; then + phashstuff ${release}.$comp ${release_}.$comp >> $hf + fi + + echo "done" +done + +echo >> $hf + +if [ $listonly -eq 0 ]; then + # Compare with older hashfile. + if [ -f $basedir/hashfile.old ]; then + if cmp -s $basedir/hashfile.old $basedir/hashfile; then + mv -f $basedir/hashfile.old $basedir/hashfile + fi + fi +fi + +if [ $signature -ne 0 -a $listonly -eq 0 ]; then + + # Save older hashfile.gpg + if [ -f $basedir/hashfile.gpg ]; then + mv -f $basedir/hashfile.gpg $basedir/hashfile.gpg.old + fi + + gpg -armour -qs --yes $basedir/hashfile + mv -f $basedir/hashfile.asc $basedir/hashfile.gpg + rm -f $basedir/hashfile + + # Compare with older hashfile.gpg + if [ -f $basedir/hashfile.gpg.old ]; then + if cmp -s $basedir/hashfile.gpg.old $basedir/hashfile.gpg; then + mv -f $basedir/hashfile.gpg.old $basedir/hashfile.gpg + fi + fi +fi + +rm -f $basedir/hashfile.old +rm -f $basedir/hashfile.gpg.old + +echo "All your base are belong to us !!" + diff --git a/apt/tools/genpkglist.cc b/apt/tools/genpkglist.cc new file mode 100644 index 0000000..301f5f6 --- /dev/null +++ b/apt/tools/genpkglist.cc @@ -0,0 +1,662 @@ +/* + * $Id: genpkglist.cc,v 1.17 2001/11/30 20:40:27 kojima Exp $ + * + * $Log: genpkglist.cc,v $ + * Revision 1.17 2001/11/30 20:40:27 kojima + * patched --progress stuff from stelian + * + * Revision 1.16 2001/11/09 21:13:08 kojima + * * Corrects the use of 'scandir' and makes genpkglist behave + * correctly when it finds empty RPMS directories (instead of + * dumping core). + * + * * Better package progression indicator. + * + * Revision 1.15 2001/08/07 20:46:03 kojima + * Alexander Bokovoy 's patch for cleaning + * up genpkglist + * + * Revision 1.14 2001/07/12 21:47:33 kojima + * ignore duplicated version/diff deps packages + * new release (cnc51) + * + * Revision 1.13 2001/06/05 12:26:25 kojima + * added fileflags tag to pkglist + * + * Revision 1.12 2001/01/04 21:26:14 kojima + * fixed some mem leaks + * + * Revision 1.11 2000/11/30 18:31:55 kojima + * removed kluges in filelist stripper and added a --bloat flag + * + * Revision 1.10 2000/11/29 20:13:26 kojima + * added lib to filelist + * + * Revision 1.9 2000/11/29 19:48:16 kojima + * include /etc files in list of files in pkglist + * + * Revision 1.8 2000/11/06 12:53:49 kojima + * fixed compile errors for RedHat 6.x (with gcc -Wall -Werror) + * + * Revision 1.7 2000/11/01 21:32:28 kojima + * added manpage + * + * Revision 1.5 2000/10/31 20:30:42 kojima + * some updates + * + * Revision 1.4 2000/10/29 21:49:54 kojima + * fixed gensrclist/pkglist bug + * + * Revision 1.3 2000/10/29 20:25:10 kojima + * added support for source download + * + * Revision 1.2 2000/10/26 21:15:22 kojima + * *** empty log message *** + * + * Revision 1.1 2000/10/22 19:57:19 kojima + * added new c++ genpkglist + * + * Revision 1.13 2000/10/19 19:32:35 claudio + * Language setting to generate a consistent pkglist. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include +#include + +#include "cached_md5.h" + + + +#define CRPMTAG_TIMESTAMP 1012345 + +int tags[] = { + RPMTAG_NAME, + RPMTAG_EPOCH, + RPMTAG_VERSION, + RPMTAG_RELEASE, + RPMTAG_GROUP, + RPMTAG_ARCH, + RPMTAG_PACKAGER, + RPMTAG_SOURCERPM, + RPMTAG_SIZE, + RPMTAG_VENDOR, + + RPMTAG_DESCRIPTION, + RPMTAG_SUMMARY, + + RPMTAG_REQUIREFLAGS, + RPMTAG_REQUIRENAME, + RPMTAG_REQUIREVERSION, + + RPMTAG_CONFLICTFLAGS, + RPMTAG_CONFLICTNAME, + RPMTAG_CONFLICTVERSION, + + RPMTAG_PROVIDENAME, + RPMTAG_PROVIDEFLAGS, + RPMTAG_PROVIDEVERSION, + + RPMTAG_OBSOLETENAME, + RPMTAG_OBSOLETEFLAGS, + RPMTAG_OBSOLETEVERSION, + + RPMTAG_FILEFLAGS +}; +int numTags = sizeof(tags) / sizeof(int); + + + +typedef struct { + string importance; + string date; + string summary; + string url; +} UpdateInfo; + + +static inline int usefullFile(char *a) +{ + int l = strlen(a); + + if (strstr(a, "bin") || strstr(a, "/etc") || strncmp(a, "/lib", 4) == 0) + return 1; + + if (l < 3) + return 0; + + if (strcmp(a + l - 3, ".so") == 0 + || strstr(a, ".so.")) + return 1; + return 0; +} + + +static void copyStrippedFileList(Header header, Header newHeader) +{ + int i; + int i1, i2; + + int type1, type2, type3; + int count1, count2, count3; + char **dirnames = NULL, **basenames = NULL; + int_32 *dirindexes = NULL; + char **dnames, **bnames; + int_32 *dindexes; + int res1, res2, res3; + +#define FREE(a) if (a) free(a); + + res1 = headerGetEntry(header, RPMTAG_DIRNAMES, &type1, + (void**)&dirnames, &count1); + res2 = headerGetEntry(header, RPMTAG_BASENAMES, &type2, + (void**)&basenames, &count2); + res3 = headerGetEntry(header, RPMTAG_DIRINDEXES, &type3, + (void**)&dirindexes, &count3); + + if (res1 != 1 || res2 != 1 || res3 != 1) { + FREE(dirnames); + FREE(basenames); + return; + } + + dnames = dirnames; + bnames = basenames; + dindexes = (int_32*)malloc(sizeof(int_32)*count3); + + i1 = 0; + i2 = 0; + for (i = 0; i < count2 ; i++) + { + int ok = 0; + + ok = usefullFile(basenames[i]); + if (!ok) + ok = usefullFile(dirnames[dirindexes[i]]); + + if (!ok) { + int k = i; + while (dirindexes[i] == dirindexes[k] && i < count2) + i++; + i--; + continue; + } + + + if (ok) + { + int j; + + bnames[i1] = basenames[i]; + for (j = 0; j < i2; j++) + { + if (dnames[j] == dirnames[dirindexes[i]]) + { + dindexes[i1] = j; + break; + } + } + if (j == i2) + { + dnames[i2] = dirnames[dirindexes[i]]; + dindexes[i1] = i2; + i2++; + } + assert(i2 <= count1); + i1++; + } + } + + if (i1 == 0) { + FREE(dirnames); + FREE(basenames); + FREE(dindexes); + return; + } + + headerAddEntry(newHeader, RPMTAG_DIRNAMES, type1, dnames, i2); + + headerAddEntry(newHeader, RPMTAG_BASENAMES, type2, bnames, i1); + + headerAddEntry(newHeader, RPMTAG_DIRINDEXES, type3, dindexes, i1); + + FREE(dirnames); + FREE(basenames); + FREE(dindexes); +} + + + + + +bool loadUpdateInfo(char *path, map &map) +{ + FileFd F(path, FileFd::ReadOnly); + if (_error->PendingError()) + { + return false; + } + + pkgTagFile Tags(F); + pkgTagSection Section; + + while (Tags.Step(Section)) + { + string file = Section.FindS("File"); + UpdateInfo info; + + info.importance = Section.FindS("Importance"); + info.date = Section.FindS("Date"); + info.summary = Section.FindS("Summary"); + info.url = Section.FindS("URL"); + + map[file] = info; + } + return true; +} + + + +bool copyFields(Header h, Header newHeader, + FILE *idxfile, char *filename, unsigned filesize, + map &updateInfo, bool fullFileList) +{ + int i; + int_32 size[1]; + + size[0] = filesize; + + // the std tags + for (i = 0; i < numTags; i++) { + int_32 type, count; + void *data; + int res; + + res = headerGetEntry(h, tags[i], &type, &data, &count); + if (res != 1) { + continue; + } + headerAddEntry(newHeader, tags[i], type, data, count); + } + + if (fullFileList) { + int type1, type2, type3; + int count1, count2, count3; + char **dnames, **bnames, **dindexes; + int res; + + res = headerGetEntry(h, RPMTAG_DIRNAMES, &type1, + (void**)&dnames, &count1); + res = headerGetEntry(h, RPMTAG_BASENAMES, &type2, + (void**)&bnames, &count2); + res = headerGetEntry(h, RPMTAG_DIRINDEXES, &type3, + (void**)&dindexes, &count3); + + if (res == 1) { + headerAddEntry(newHeader, RPMTAG_DIRNAMES, type1, dnames, count1); + headerAddEntry(newHeader, RPMTAG_BASENAMES, type2, bnames, count2); + headerAddEntry(newHeader, RPMTAG_DIRINDEXES, type3, dindexes, count3); + } + } else { + copyStrippedFileList(h, newHeader); + } + + // update index of srpms + if (idxfile) { + int_32 type, count; + char *srpm; + char *name; + int res; + + res = headerGetEntry(h, RPMTAG_NAME, &type, + (void**)&name, &count); + res = headerGetEntry(h, RPMTAG_SOURCERPM, &type, + (void**)&srpm, &count); + if (res == 1) { + fprintf(idxfile, "%s %s\n", srpm, name); + } + } + // our additional tags + headerAddEntry(newHeader, CRPMTAG_FILENAME, RPM_STRING_TYPE, + filename, 1); + headerAddEntry(newHeader, CRPMTAG_FILESIZE, RPM_INT32_TYPE, + size, 1); + + // update description tags + if (updateInfo.find(string(filename)) != updateInfo.end()) { + const char *tmp; + string name = string(filename); + + tmp = updateInfo[name].summary.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_SUMMARY, + RPM_STRING_TYPE, + tmp, 1); + tmp = updateInfo[name].url.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_URL, + RPM_STRING_TYPE, + tmp, 1); + tmp = updateInfo[name].date.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_DATE, + RPM_STRING_TYPE, + tmp, 1); + tmp = updateInfo[name].importance.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_IMPORTANCE, + RPM_STRING_TYPE, + tmp, 1); + } + + return true; +} + + +int selectDirent(const struct dirent *ent) +{ + int state = 0; + const char *p = ent->d_name; + + while (1) { + if (*p == '.') { + state = 1; + } else if (state == 1 && *p == 'r') + state++; + else if (state == 2 && *p == 'p') + state++; + else if (state == 3 && *p == 'm') + state++; + else if (state == 4 && *p == '\0') + return 1; + else if (*p == '\0') + return 0; + else + state = 0; + p++; + } +} + + +void usage() +{ + cerr << "usage: genpkglist []

" << endl; + cerr << "options:" << endl; + cerr << " --index file to write srpm index data to" << endl; + cerr << " --info file to read update info from" << endl; + cerr << " --bloat do not strip the package file list. Needed for some" << endl; + cerr << " distributions that use non-automatically generated" << endl; + cerr << " file dependencies" << endl; + cerr << " --progress show a progress bar" << endl; +} + + + +#ifndef HAVE_SCANDIR +// from glibc 1.09.1 mod'd by jmik, ins'd by asm, fix'd by sbi +int alphasort(const void * a, const void * b) +{ + return strcmp ((*(struct dirent **) a)->d_name, + (*(struct dirent **) b)->d_name); +} + +int scandir(const char * dir, struct dirent *** namelist, + int (* select)(struct dirent *), + int (* cmp)(const void *, const void *)) + +{ + DIR *dp = opendir (dir); + struct dirent **v = NULL; + size_t vsize = 0, i; + struct dirent *d; + int save; + + if (dp == NULL) + return -1; + + save = errno; + errno = 0; + + i = 0; + while ((d = readdir (dp)) != NULL) + { + if (select == NULL || (*select) (d)) + { + if (i == vsize) + { + struct dirent **newv; + if (vsize == 0) + vsize = 10; + else + vsize *= 2; + newv = (struct dirent **) realloc (v, vsize * sizeof (*v)); + if (newv == NULL) + { + lose: + errno = ENOMEM; + break; + } + v = newv; + } + + v[i] = (struct dirent *) malloc (d->d_reclen); + if (v[i] == NULL) + goto lose; + + // *v[i++] = *d; + memcpy(v[i], d, d->d_reclen); + i++; + } + } + + v[i] = NULL; + + if (errno != 0) + { + save = errno; + (void) closedir (dp); + while (i > 0) + free (v[--i]); + free (v); + errno = save; + return -1; + } + + (void) closedir (dp); + errno = save; + + /* Sort the list if we have a comparison function to sort with. */ + if (cmp != NULL) + qsort (v, i, sizeof (struct dirent *), cmp); + + *namelist = v; + return i; +} +// end of new stuff from glibc +#endif /* !HAVE_SCANDIR */ + + +int main(int argc, char ** argv) +{ + string rpmsdir; + string pkglist_path; + FD_t outfd, fd; + struct dirent **dirEntries; + int entry_no, entry_cur; + map updateInfo; + CachedMD5 *md5cache; + char *op_dir; + char *op_suf; + char *op_index = NULL; + char *op_update = NULL; + FILE *idxfile; + int i; + bool fullFileList = false; + bool progressBar = false; + + putenv("LC_ALL="); + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--index") == 0) { + i++; + if (i < argc) { + op_index = argv[i]; + } else { + cout << "genpkglist: filename missing for option --index"< 0) + op_dir = argv[i++]; + else { + usage(); + exit(1); + } + if (argc - i > 0) + op_suf = argv[i++]; + else { + usage(); + exit(1); + } + if (argc != i) { + usage(); + } + + if (op_update) { + if (!loadUpdateInfo(op_update, updateInfo)) { + cerr << "genpkglist: error reading update info from file " << op_update << endl; + _error->DumpErrors(); + exit(1); + } + } + if (op_index) { + idxfile = fopen(op_index, "w+"); + if (!idxfile) { + cerr << "genpkglist: could not open " << op_index << " for writing"; + perror(""); + exit(1); + } + } else { + idxfile = NULL; + } + + { + char cwd[200]; + + getcwd(cwd, 200); + if (*op_dir != '/') { + rpmsdir = string(cwd) + "/" + string(op_dir); + } else { + rpmsdir = string(op_dir); + } + } + pkglist_path = string(rpmsdir); + rpmsdir = rpmsdir + "/RPMS." + string(op_suf); + + entry_no = scandir(rpmsdir.c_str(), &dirEntries, selectDirent, alphasort); + if (entry_no < 0) { + cerr << "genpkglist: error opening directory " << rpmsdir << ":" + << strerror(errno); + return 1; + } + + chdir(rpmsdir.c_str()); + + pkglist_path = pkglist_path + "/base/pkglist." + op_suf; + + unlink(pkglist_path.c_str()); + + outfd = fdOpen(pkglist_path.c_str(), O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (!outfd) { + cerr << "genpkglist: error creating file" << pkglist_path << ":" + << strerror(errno); + return 1; + } + + md5cache = new CachedMD5(string(op_dir) + string(op_suf)); + + for (entry_cur = 0; entry_cur < entry_no; entry_cur++) { + struct stat sb; + int isSource; + + if (progressBar) { + if (entry_cur) + printf("\b\b\b\b\b\b\b\b\b\b"); + printf("%04i/%04i ", entry_cur + 1, entry_no); + fflush(stdout); + } + + if (stat(dirEntries[entry_cur]->d_name, &sb) < 0) { + cerr << dirEntries[entry_cur] << ":"; + perror("stat"); + exit(1); + } + + { + Header h; + int rc; + + fd = fdOpen(dirEntries[entry_cur]->d_name, O_RDONLY, 0666); + + if (!fd) { + cerr << dirEntries[entry_cur]->d_name << ":"; + perror("open"); + exit(1); + } + + rc = rpmReadPackageHeader(fd, &h, &isSource, NULL, NULL); + + if (!rc) { + Header newHeader; + unsigned char md5[34]; + + newHeader = headerNew(); + + copyFields(h, newHeader, idxfile, dirEntries[entry_cur]->d_name, + sb.st_size, updateInfo, fullFileList); + + md5cache->MD5ForFile(string(dirEntries[entry_cur]->d_name), + sb.st_mtime, md5); + headerAddEntry(newHeader, CRPMTAG_MD5, RPM_STRING_TYPE, md5, 1); + + headerWrite(outfd, newHeader, HEADER_MAGIC_YES); + + headerFree(newHeader); + headerFree(h); + } + fdClose(fd); + } + } + + fdClose(outfd); + + delete md5cache; + + return 0; +} diff --git a/apt/tools/gensrclist.cc b/apt/tools/gensrclist.cc new file mode 100644 index 0000000..a370eeb --- /dev/null +++ b/apt/tools/gensrclist.cc @@ -0,0 +1,373 @@ +/* + * $Id: gensrclist.cc,v 1.11 2001/12/12 14:50:43 kojima Exp $ + * + * $Log: gensrclist.cc,v $ + * Revision 1.11 2001/12/12 14:50:43 kojima + * fixed genbasedir for --flat and relative --topdir specifications + * fixed --flat in gensrclist + * + * Revision 1.10 2001/12/11 13:51:03 kojima + * added --flat option to srclist, patched gensrclist with stelian's patch + * + * Revision 1.9 2001/11/09 21:11:46 kojima + * * Use 'scandir' for directory traversal (instead of opendir/ + * readdir) like in genpkglist. + * * Better package progression indicator. + * + * Revision 1.8 2001/08/07 20:46:03 kojima + * Alexander Bokovoy 's patch for cleaning + * up genpkglist + * + * Revision 1.7 2001/07/12 21:47:33 kojima + * ignore duplicated version/diff deps packages + * new release (cnc51) + * + * Revision 1.6 2000/11/06 12:53:49 kojima + * fixed compile errors for RedHat 6.x (with gcc -Wall -Werror) + * + * Revision 1.5 2000/11/01 21:32:28 kojima + * added manpage + * + * Revision 1.3 2000/10/30 02:17:17 kojima + * fixed bugs in source d/l + * + * Revision 1.2 2000/10/29 20:25:10 kojima + * added support for source download + * + * Revision 1.1 2000/10/28 02:23:17 kojima + * started source support + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include +#include + +#include "cached_md5.h" + + + + + +int tags[] = { + RPMTAG_NAME, + RPMTAG_EPOCH, + RPMTAG_VERSION, + RPMTAG_RELEASE, + RPMTAG_GROUP, + RPMTAG_ARCH, + RPMTAG_PACKAGER, + RPMTAG_SOURCERPM, + RPMTAG_SIZE, + RPMTAG_VENDOR, + + RPMTAG_DESCRIPTION, + RPMTAG_SUMMARY, + + RPMTAG_REQUIREFLAGS, + RPMTAG_REQUIRENAME, + RPMTAG_REQUIREVERSION +}; +int numTags = sizeof(tags) / sizeof(int); + +int selectDirent(const struct dirent *ent) +{ + int state = 0; + const char *p = ent->d_name; + + while (1) { + if (*p == '.') { + state = 1; + } else if (state == 1 && *p == 'r') + state++; + else if (state == 2 && *p == 'p') + state++; + else if (state == 3 && *p == 'm') + state++; + else if (state == 4 && *p == '\0') + return 1; + else if (*p == '\0') + return 0; + else + state = 0; + p++; + } +} + +bool readRPMTable(char *file, map* > &table) +{ + FILE *indexf; + char buf[512]; + string srpm; + + indexf = fopen(file, "r"); + if (!indexf) { + cerr << "gensrclist: could not open file " << file << " for reading: " + << strerror(errno) << endl; + return false; + } + + while (fgets(buf, 512, indexf)) { + char *f; + + buf[strlen(buf)-1] = '\0'; + f = strchr(buf, ' '); + *f = '\0'; + f++; + + srpm = string(buf); + + if (table.find(srpm) != table.end()) { + slist *list = table[srpm]; + + list->push_front(strdup(f)); + } else { + slist *list = new slist; + + list->push_front(strdup(f)); + table[srpm] = list; + } + } + + fclose(indexf); + + return true; +} + + +void usage() +{ + cerr << "usage: gensrclist [] " << endl; + cerr << "options:" << endl; +// cerr << " --mapi ???????????????????" << endl; + cerr << " --progress show a progress bar" << endl; + cerr << " --flat use a flat directory structure, where RPMS and SRPMS"<* > rpmTable; // table that maps srpm -> generated rpm + bool mapi = false; + bool progressBar = false; + bool flatStructure = false; + char *arg_dir, *arg_suffix, *arg_srpmindex; + + putenv("LC_ALL="); + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--mapi") == 0) { + mapi = true; + } else if (strcmp(argv[i], "--flat") == 0) { + flatStructure = true; + } else if (strcmp(argv[i], "--progress") == 0) { + progressBar = true; + } else { + break; + } + } + if (argc - i == 3) { + arg_dir = argv[i++]; + arg_suffix = argv[i++]; + arg_srpmindex = argv[i++]; + } + else { + usage(); + exit(1); + } + + if (!readRPMTable(arg_srpmindex, rpmTable)) + exit(1); + + md5cache = new CachedMD5(string(arg_dir)+string(arg_suffix)); + + getcwd(cwd, 200); + if (*arg_dir != '/') { + strcpy(buf, cwd); + strcat(buf, "/"); + strcat(buf, arg_dir); + } else + strcpy(buf, arg_dir); + + strcat(buf, "/SRPMS."); + strcat(buf, arg_suffix); + + srpmdir = "SRPMS." + string(arg_suffix); + if (flatStructure) { + char *prefix; + // add the last component of the directory to srpmdir + // that will cancel the effect of the .. used in sourcelist.cc + // when building the directory from where to fetch srpms in apt + + prefix = strrchr(arg_dir, '/'); + if (!prefix) + prefix = arg_dir; + else + prefix++; + + srpmdir = string(prefix) + '/' + srpmdir; + } + + entry_no = scandir(buf, &dirEntries, selectDirent, alphasort); + if (entry_no < 0) { + cerr << "gensrclist: error opening directory " << buf << ":" + << strerror(errno) << endl; + return 1; + } + + chdir(buf); + + + + sprintf(buf, "%s/srclist.%s", cwd, arg_suffix); + + unlink(buf); + + outfd = fdOpen(buf, O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (!outfd) { + cerr << "gensrclist: error creating file" << buf << ":" + << strerror(errno); + return 1; + } + + for (entry_cur = 0; entry_cur < entry_no; entry_cur++) { + struct stat sb; + + if (progressBar) { + if (entry_cur) + printf("\b\b\b\b\b\b\b\b\b\b"); + printf("%04i/%04i ", entry_cur + 1, entry_no); + fflush(stdout); + } + + if (stat(dirEntries[entry_cur]->d_name, &sb) < 0) { + cerr << dirEntries[entry_cur] << ":"; + perror("stat"); + exit(1); + } + + fd = fdOpen(dirEntries[entry_cur]->d_name, O_RDONLY, 0666); + + if (!fd) { + cerr << dirEntries[entry_cur]->d_name << ":"; + perror("open"); + exit(1); + } + + size[0] = sb.st_size; + + rc = rpmReadPackageInfo(fd, &sigs, &h); + + if (!rc) { + Header newHeader; + int i; + bool foundInIndex; + + newHeader = headerNew(); + + // the std tags + for (i = 0; i < numTags; i++) { + int type, count; + void *data; + int res; + + res = headerGetEntry(h, tags[i], &type, &data, &count); + if (res != 1) { + /* + printf("warning: tag %i not found on header for %s\n", + tags[i], dirEntries[entry_cur]->d_name); + */ + continue; + } + headerAddEntry(newHeader, tags[i], type, data, count); + } + + + // our additional tags + headerAddEntry(newHeader, CRPMTAG_DIRECTORY, RPM_STRING_TYPE, + srpmdir.c_str(), 1); + + headerAddEntry(newHeader, CRPMTAG_FILENAME, RPM_STRING_TYPE, + dirEntries[entry_cur]->d_name, 1); + headerAddEntry(newHeader, CRPMTAG_FILESIZE, RPM_INT32_TYPE, + size, 1); + + { + unsigned char md5[34]; + + md5cache->MD5ForFile(dirEntries[entry_cur]->d_name, sb.st_mtime, md5); + + headerAddEntry(newHeader, CRPMTAG_MD5, RPM_STRING_TYPE, + md5, 1); + } + + foundInIndex = false; + { + int count = 0; + char **list = NULL; + slist *rpmlist = rpmTable[string(dirEntries[entry_cur]->d_name)]; + + if (rpmlist) { + list = new char *[rpmlist->size()]; + + foundInIndex = true; + + for (slist::const_iterator i = rpmlist->begin(); + i != rpmlist->end(); + i++) { + list[count++] = *i; + } + } + + if (count) { + headerAddEntry(newHeader, CRPMTAG_BINARY, + RPM_STRING_ARRAY_TYPE, list, count); + } + } + if (foundInIndex || !mapi) + headerWrite(outfd, newHeader, HEADER_MAGIC_YES); + + headerFree(newHeader); + headerFree(h); + rpmFreeSignature(sigs); + } + fdClose(fd); + } + + fdClose(outfd); + + delete md5cache; + + return 0; +} diff --git a/apt/tools/hashtable.c b/apt/tools/hashtable.c new file mode 100644 index 0000000..bd87719 --- /dev/null +++ b/apt/tools/hashtable.c @@ -0,0 +1,426 @@ + + +#include +#include +#include +#include + +#include "hashtable.h" + + + + +#define INITIAL_CAPACITY 23 + + +#if defined(__GNUC__) && !defined(__STRICT_ANSI__) +# define inline inline +#else +# define inline +#endif + + +typedef struct HashItem { + void *key; + void *data; + + struct HashItem *next; /* collided item list */ +} HashItem; + + +struct _HashTable { + HashTableCallbacks callbacks; + + unsigned itemCount; + unsigned size; /* table size */ + + HashItem **table; +}; + + + + +#define HASH(table, key) (((table)->callbacks.hash ? \ + (*(table)->callbacks.hash)(key) : hashPtr(key)) % (table)->size) + +#define DUPKEY(table, key) ((table)->callbacks.retainKey ? \ + (*(table)->callbacks.retainKey)(key) : (key)) + +#define RELKEY(table, key) if ((table)->callbacks.releaseKey) \ + (*(table)->callbacks.releaseKey)(key) + + + + +static inline unsigned +hashString(const char *key) +{ + unsigned ret = 0; + unsigned ctr = 0; + + while (*key) { + ret ^= *(char*)key++ << ctr; + ctr = (ctr + 1) % sizeof (char *); + } + + return ret; +} + + + +static inline unsigned +hashPtr(const void *key) +{ + return ((size_t)key / sizeof(char*)); +} + + + + +static void +rellocateItem(HashTable *table, HashItem *item) +{ + unsigned h; + + h = HASH(table, item->key); + + item->next = table->table[h]; + table->table[h] = item; +} + + +static void +rebuildTable(HashTable *table) +{ + HashItem *next; + HashItem **oldArray; + int i; + int oldSize; + int newSize; + + oldArray = table->table; + oldSize = table->size; + + newSize = table->size*2; + + table->table = malloc(sizeof(char*)*newSize); + if (!table->table) { + fprintf(stderr, "hashtable: out of memory while rebuilding hash table \n"); + table->table = oldArray; + return; + } + memset(table->table, 0, sizeof(char*)*newSize); + table->size = newSize; + + for (i = 0; i < oldSize; i++) { + while (oldArray[i]!=NULL) { + next = oldArray[i]->next; + rellocateItem(table, oldArray[i]); + oldArray[i] = next; + } + } + free(oldArray); +} + + + +HashTable* +CreateHashTable(HashTableCallbacks callbacks) +{ + HashTable *table; + + table = malloc(sizeof(HashTable)); + if (!table) + return NULL; + memset(table, 0, sizeof(HashTable)); + + table->callbacks = callbacks; + + table->size = INITIAL_CAPACITY; + + table->table = malloc(sizeof(HashItem*)*table->size); + if (!table->table) { + table->table = NULL; + return NULL; + } + memset(table->table, 0, sizeof(HashItem*)*table->size); + + return table; +} + + +void +ResetHashTable(HashTable *table) +{ + HashItem *item, *tmp; + int i; + + for (i = 0; i < table->size; i++) { + item = table->table[i]; + while (item) { + tmp = item->next; + RELKEY(table, item); + free(item); + item = tmp; + } + } + + table->itemCount = 0; + + if (table->size > INITIAL_CAPACITY) { + void *tmp = table->table; + table->table = malloc(sizeof(HashItem*)*INITIAL_CAPACITY); + if (!table->table) { + table->table = tmp; + } else { + table->size = INITIAL_CAPACITY; + free(tmp); + } + } + memset(table->table, 0, sizeof(HashItem*)*table->size); +} + + +void +FreeHashTable(HashTable *table) +{ + HashItem *item, *tmp; + int i; + + for (i = 0; i < table->size; i++) { + item = table->table[i]; + while (item) { + tmp = item->next; + RELKEY(table, item->key); + free(item); + item = tmp; + } + } + free(table->table); + free(table); +} + + + +void* +HashGet(HashTable *table, const void *key) +{ + unsigned h; + HashItem *item; + + h = HASH(table, key); + item = table->table[h]; + + if (table->callbacks.keyIsEqual) { + while (item) { + if ((*table->callbacks.keyIsEqual)(key, item->key)) { + break; + } + item = item->next; + } + } else { + while (item) { + if (key == item->key) { + break; + } + item = item->next; + } + } + if (item) + return item->data; + else + return NULL; +} + + + +void* +HashInsert(HashTable *table, void *key, void *data) +{ + unsigned h; + HashItem *item; + int replacing = 0; + + h = HASH(table, key); + /* look for the entry */ + item = table->table[h]; + if (table->callbacks.keyIsEqual) { + while (item) { + if ((*table->callbacks.keyIsEqual)(key, item->key)) { + replacing = 1; + break; + } + item = item->next; + } + } else { + while (item) { + if (key == item->key) { + replacing = 1; + break; + } + item = item->next; + } + } + + if (replacing) { + void *old; + + old = item->data; + item->data = data; + RELKEY(table, item->key); + item->key = DUPKEY(table, key); + + return old; + } else { + HashItem *nitem; + + nitem = malloc(sizeof(HashItem)); + if (!nitem) { + fprintf(stderr, "hashtable: out of memory while allocating memory for new item\n"); + return NULL; + } + nitem->key = DUPKEY(table, key); + nitem->data = data; + nitem->next = table->table[h]; + table->table[h] = nitem; + + table->itemCount++; + } + + /* OPTIMIZE: put this in an idle handler.*/ + if (table->itemCount > table->size) { +#ifdef DEBUG0 + printf("rebuilding hash table...\n"); +#endif + rebuildTable(table); +#ifdef DEBUG0 + printf("finished rebuild.\n"); +#endif + } + + return NULL; +} + + +static HashItem* +deleteFromList(HashTable *table, HashItem *item, const void *key) +{ + HashItem *next; + + if (item==NULL) + return NULL; + + if ((table->callbacks.keyIsEqual + && (*table->callbacks.keyIsEqual)(key, item->key)) + || (!table->callbacks.keyIsEqual && key==item->key)) { + + next = item->next; + RELKEY(table, item->key); + free(item); + + table->itemCount--; + + return next; + } + + item->next = deleteFromList(table, item->next, key); + + return item; +} + + +void +HashRemove(HashTable *table, const void *key) +{ + unsigned h; + + h = HASH(table, key); + + table->table[h] = deleteFromList(table, table->table[h], key); +} + + +HashEnumerator +EnumerateHashTable(HashTable *table) +{ + HashEnumerator enumerator; + + enumerator.table = table; + enumerator.index = 0; + enumerator.nextItem = table->table[0]; + + return enumerator; +} + + + +void* +NextHashEnumeratorItem(HashEnumerator *enumerator) +{ + void *data = NULL; + + /* this assumes the table doesn't change between + * EnumerateHashTable() and NextHashEnumeratorItem() calls */ + + if (enumerator->nextItem==NULL) { + HashTable *table = enumerator->table; + while (++enumerator->index < table->size) { + if (table->table[enumerator->index]!=NULL) { + enumerator->nextItem = table->table[enumerator->index]; + break; + } + } + } + + if (enumerator->nextItem) { + data = ((HashItem*)enumerator->nextItem)->data; + enumerator->nextItem = ((HashItem*)enumerator->nextItem)->next; + } + + return data; +} + + +unsigned +CountHashTable(HashTable *table) +{ + return table->itemCount; +} + + +static int +compareStrings(const char *key1, const char *key2) +{ + return strcmp(key1, key2)==0; +} + + +typedef unsigned (*hashFunc)(const void*); +typedef int (*isEqualFunc)(const void*, const void*); +typedef void* (*retainFunc)(const void*); +typedef void (*releaseFunc)(const void*); + + +const HashTableCallbacks IntHashCallbacks = { + NULL, + NULL, + NULL, + NULL +}; + +const HashTableCallbacks StringHashCallbacks = { + (hashFunc)hashString, + (isEqualFunc)compareStrings, + (retainFunc)strdup, + (releaseFunc)free +}; + + + +const HashTableCallbacks StringPointerHashCallbacks = { + (hashFunc)hashString, + (isEqualFunc)compareStrings, + NULL, + NULL +}; + diff --git a/apt/tools/hashtable.h b/apt/tools/hashtable.h new file mode 100644 index 0000000..c1504ac --- /dev/null +++ b/apt/tools/hashtable.h @@ -0,0 +1,70 @@ +#ifndef _WUTIL_H_ +#define _WUTIL_H_ + +/* + * Hashtables from WINGs. + * Alfredo K. Kojima (kojima@conectiva.com.br) + */ + +typedef struct _HashTable HashTable; + +/* DO NOT ACCESS THE CONTENTS OF THIS STRUCT */ +typedef struct { + void *table; + void *nextItem; + int index; +} HashEnumerator; + + +typedef struct { + /* NULL is pointer hash */ + unsigned (*hash)(const void *); + /* NULL is pointer compare */ + int (*keyIsEqual)(const void *, const void *); + /* NULL does nothing */ + void* (*retainKey)(const void *); + /* NULL does nothing */ + void (*releaseKey)(const void *); +} HashTableCallbacks; + + + + +HashTable *CreateHashTable(HashTableCallbacks callbacks); + +void FreeHashTable(HashTable *table); + +void ResetHashTable(HashTable *table); + +void *HashGet(HashTable *table, const void *key); + +/* put data in table, replacing already existing data and returning + * the old value */ +void *HashInsert(HashTable *table, void *key, void *data); + +void HashRemove(HashTable *table, const void *key); + +/* warning: do not manipulate the table while using these functions */ +HashEnumerator EnumerateHashTable(HashTable *table); + +void *NextHashEnumeratorItem(HashEnumerator *enumerator); + +unsigned CountHashTable(HashTable *table); + + + + +/* some predefined callback sets */ + +extern const HashTableCallbacks IntHashCallbacks; +/* sizeof(keys) are <= sizeof(void*) */ + +extern const HashTableCallbacks StringHashCallbacks; +/* keys are strings. Strings will be copied with wstrdup() + * and freed with free() */ + +extern const HashTableCallbacks StringPointerHashCallbacks; +/* keys are strings, bug they are not copied */ + + +#endif diff --git a/apt/tools/hdlist2pkglist.cc b/apt/tools/hdlist2pkglist.cc new file mode 100644 index 0000000..95948a8 --- /dev/null +++ b/apt/tools/hdlist2pkglist.cc @@ -0,0 +1,479 @@ +/* + * $Id: hdlist2pkglist.cc,v 1.3 2001/07/12 21:47:33 kojima Exp $ + * + * $Log: hdlist2pkglist.cc,v $ + * Revision 1.3 2001/07/12 21:47:33 kojima + * ignore duplicated version/diff deps packages + * new release (cnc51) + * + * Revision 1.2 2000/11/06 12:53:49 kojima + * fixed compile errors for RedHat 6.x (with gcc -Wall -Werror) + * + * Revision 1.1 2000/11/01 18:27:21 kojima + * added md5 caching to pkglist generators + * + * Revision 1.5 2000/10/31 20:30:42 kojima + * some updates + * + * Revision 1.4 2000/10/29 21:49:54 kojima + * fixed gensrclist/pkglist bug + * + * Revision 1.3 2000/10/29 20:25:10 kojima + * added support for source download + * + * Revision 1.2 2000/10/26 21:15:22 kojima + * *** empty log message *** + * + * Revision 1.1 2000/10/22 19:57:19 kojima + * added new c++ hdlist2pkglist + * + * Revision 1.13 2000/10/19 19:32:35 claudio + * Language setting to generate a consistent pkglist. + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +// from rpmlib +extern "C" { + extern int mdfile(const char *fn, unsigned char *digest); +}; + + + +#define CRPMTAG_TIMESTAMP 1012345 + +int tags[] = { + RPMTAG_NAME, + RPMTAG_EPOCH, + RPMTAG_VERSION, + RPMTAG_RELEASE, + RPMTAG_GROUP, + RPMTAG_ARCH, + RPMTAG_PACKAGER, + RPMTAG_SOURCERPM, + RPMTAG_SIZE, + RPMTAG_VENDOR, + + RPMTAG_DESCRIPTION, + RPMTAG_SUMMARY, + + RPMTAG_REQUIREFLAGS, + RPMTAG_REQUIRENAME, + RPMTAG_REQUIREVERSION, + + RPMTAG_CONFLICTFLAGS, + RPMTAG_CONFLICTNAME, + RPMTAG_CONFLICTVERSION, + + RPMTAG_PROVIDENAME, + RPMTAG_PROVIDEFLAGS, + RPMTAG_PROVIDEVERSION, + + RPMTAG_OBSOLETENAME, + RPMTAG_OBSOLETEFLAGS, + RPMTAG_OBSOLETEVERSION +}; +int numTags = sizeof(tags) / sizeof(int); + + + +typedef struct { + string importance; + string date; + string summary; + string url; +} UpdateInfo; + + +static inline int usefullFile(char *a) +{ + int l = strlen(a); + + if (strstr(a, "bin")) + return 1; + + if (l < 3) + return 0; + + if (strcmp(a + l - 2, ".a") == 0 + || strcmp(a + l - 3, ".so") == 0 + || strstr(a, ".so.")) + return 1; + return 0; +} + + +static void copyStrippedFileList(Header header, Header newHeader) +{ + int i; + int i1, i2; + + int type1, type2, type3; + int count1, count2, count3; + char **dirnames = NULL, **basenames = NULL; + int_32 *dirindexes = NULL; + char **dnames, **bnames; + int_32 *dindexes; + int res1, res2, res3; + +#define FREE(a) if (a) free(a); + + res1 = headerGetEntry(header, RPMTAG_DIRNAMES, &type1, + (void**)&dirnames, &count1); + res2 = headerGetEntry(header, RPMTAG_BASENAMES, &type2, + (void**)&basenames, &count2); + res3 = headerGetEntry(header, RPMTAG_DIRINDEXES, &type3, + (void**)&dirindexes, &count3); + + if (res1 != 1 || res2 != 1 || res3 != 1) { + FREE(dirnames); + FREE(basenames); + return; + } + + dnames = dirnames; + bnames = basenames; + dindexes = (int_32*)malloc(sizeof(int_32)*count3); + + + i1 = 0; + i2 = 0; + for (i = 0; i < count2 ; i++) + { + int ok = 0; + + ok = usefullFile(basenames[i]); + if (!ok) + ok = usefullFile(dirnames[dirindexes[i]]); + + if (!ok) { + int k = i; + while (dirindexes[i] == dirindexes[k] && i < count2) + i++; + i--; + continue; + } + + + if (ok) + { + int j; + + bnames[i1] = basenames[i]; + for (j = 0; j < i2; j++) + { + if (dnames[j] == dirnames[dirindexes[i]]) + { + dindexes[i1] = j; + break; + } + } + if (j == i2) + { + dnames[i2] = dirnames[dirindexes[i]]; + dindexes[i1] = i2; + i2++; + } + assert(i2 <= count1); + i1++; + } + } + + if (i1 == 0) { + FREE(dirnames); + FREE(basenames); + FREE(dindexes); + return; + } + + headerAddEntry(newHeader, RPMTAG_DIRNAMES, type1, dnames, i2); + + headerAddEntry(newHeader, RPMTAG_BASENAMES, type2, bnames, i1); + + headerAddEntry(newHeader, RPMTAG_DIRINDEXES, type3, dindexes, i1); + + FREE(dirnames); + FREE(basenames); + FREE(dindexes); +} + + + + + +bool loadUpdateInfo(char *path, map &map) +{ + FileFd F(path, FileFd::ReadOnly); + if (_error->PendingError()) + { + return false; + } + + pkgTagFile Tags(F); + pkgTagSection Section; + + while (Tags.Step(Section)) + { + string file = Section.FindS("File"); + UpdateInfo info; + + info.importance = Section.FindS("Importance"); + info.date = Section.FindS("Date"); + info.summary = Section.FindS("Summary"); + info.url = Section.FindS("URL"); + + map[file] = info; + } + return true; +} + + + +bool copyFields(Header h, Header newHeader, + FILE *idxfile, char *filename, unsigned filesize, + map &updateInfo) +{ + int i; + int_32 size[1]; + + size[0] = filesize; + + // the std tags + for (i = 0; i < numTags; i++) { + int_32 type, count; + void *data; + int res; + + res = headerGetEntry(h, tags[i], &type, &data, &count); + if (res != 1) { + continue; + } + headerAddEntry(newHeader, tags[i], type, data, count); + } + + copyStrippedFileList(h, newHeader); + + // update index of srpms + if (idxfile) { + int_32 type, count; + char *srpm; + char *name; + int res; + + res = headerGetEntry(h, RPMTAG_NAME, &type, + (void**)&name, &count); + res = headerGetEntry(h, RPMTAG_SOURCERPM, &type, + (void**)&srpm, &count); + if (res == 1) { + fprintf(idxfile, "%s %s\n", srpm, name); + } + } + // our additional tags + headerAddEntry(newHeader, CRPMTAG_FILENAME, RPM_STRING_TYPE, + filename, 1); + headerAddEntry(newHeader, CRPMTAG_FILESIZE, RPM_INT32_TYPE, + size, 1); + + { + unsigned char md5[34]; + + mdfile(filename, md5); + + headerAddEntry(newHeader, CRPMTAG_MD5, RPM_STRING_TYPE, + md5, 1); + } + + // update description tags + if (updateInfo.find(string(filename)) != updateInfo.end()) { + const char *tmp; + string name = string(filename); + + tmp = updateInfo[name].summary.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_SUMMARY, + RPM_STRING_TYPE, + tmp, 1); + tmp = updateInfo[name].url.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_URL, + RPM_STRING_TYPE, + tmp, 1); + tmp = updateInfo[name].date.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_DATE, + RPM_STRING_TYPE, + tmp, 1); + tmp = updateInfo[name].importance.c_str(); + headerAddEntry(newHeader, CRPMTAG_UPDATE_IMPORTANCE, + RPM_STRING_TYPE, + tmp, 1); + } + return true; +} + + +void usage() +{ + cerr << "usage: hdlist2pkglist [] " << endl; + cerr << "options:" << endl; + cerr << " --index file to write srpm index data to" << endl; + cerr << " --info file to read update info from" << endl; +} + + +int main(int argc, char ** argv) +{ + FD_t outfd; + FD_t hdlist; + map updateInfo; + char *op_dir; + char *op_hdlist; + char *op_pkglist; + char *op_update = NULL; + char *op_index = NULL; + + FILE *idxfile; + int i; + + putenv("LC_ALL="); + + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "--index") == 0) { + i++; + if (i < argc) { + op_index = argv[i]; + } else { + cout << "hdlist2pkglist: filename missing for option --index"< 0) + dir = argv[i++]; + else { + usage(); + exit(1); + } + if (argc - i > 0) + suffix = argv[i++]; + else { + usage(); + exit(1); + } + + sprintf(buf, "%s/RPMS.%s", dir, suffix); + op_dir = strdup(buf); + + sprintf(buf, "%s/base/hdlist.%s", dir, suffix); + op_hdlist = strdup(buf); + + sprintf(buf, "%s/base/pkglist.%s", dir, suffix); + op_pkglist = strdup(buf); + } + + if (argc != i) { + usage(); + } + + if (op_update) { + if (!loadUpdateInfo(op_update, updateInfo)) { + cerr << "hdlist2pkglist: error reading update info from file " << op_update << endl; + _error->DumpErrors(); + exit(1); + } + } + if (op_index) { + idxfile = fopen(op_index, "w+"); + if (!idxfile) { + cerr << "hdlist2pkglist: could not open " << op_index << " for writing"; + perror(""); + exit(1); + } + } else { + idxfile = NULL; + } + + hdlist = fdOpen(op_hdlist, O_RDONLY, 0644); + if (!hdlist) { + cerr << "hdlist2pkglist: error opening file" << op_hdlist << ":" + << strerror(errno); + return 1; + } + + unlink(op_pkglist); + + outfd = fdOpen(op_pkglist, O_WRONLY | O_TRUNC | O_CREAT, 0644); + if (!outfd) { + cerr << "hdlist2pkglist: error creating file" << op_pkglist << ":" + << strerror(errno); + return 1; + } + + chdir(op_dir); + + + while (1) { + struct stat sb; + Header h; + Header newHeader; + char *package; + int type, count; + + h = headerRead(hdlist, HEADER_MAGIC_YES); + if (!h) + break; + + if (headerGetEntry(h, CRPMTAG_FILENAME, &type, (void**)&package, &count)!=1) { + cerr << "hdlist2pkglist: could not get CRPMTAG_FILENAME from header in hdlist"<< endl; + exit(1); + } + + if (stat(package, &sb) < 0) { + cerr << package << ":" << strerror(errno); + exit(1); + } + + + newHeader = headerNew(); + + copyFields(h, newHeader, idxfile, package, sb.st_size, updateInfo); + + headerWrite(outfd, newHeader, HEADER_MAGIC_YES); + + headerFree(newHeader); + headerFree(h); + } + + fdClose(hdlist); + fdClose(outfd); + + return 0; +} diff --git a/apt/tools/mkpackages.c b/apt/tools/mkpackages.c new file mode 100644 index 0000000..380d634 --- /dev/null +++ b/apt/tools/mkpackages.c @@ -0,0 +1,443 @@ + +#include +#include +#include +#include +#include +#include + +#include + +#include "hashtable.h" + + +HashTable *table; + +typedef struct llist { + struct llist *next; + char *s; +} llist; + + +llist *lappend(llist *l, char *s) +{ + llist *b; + + b = malloc(sizeof(llist)); + assert(b!=NULL); + + b->s = (char*)strdup(s); + b->next = l; + + return b; +} + + + +#define CRPMTAG_FILENAME 1000000 +#define CRPMTAG_FILESIZE 1000001 + + + +void pstrarray(FILE *f, char **str, int count) +{ + if (!count) + return; + + fprintf(f, "%s", *str++); + count--; + while (count--) { + fprintf(f, ", %s", *str++); + } + fprintf(f, "\n"); +} + +void pstr(FILE *f, char **data, int count, int type) +{ + if (type == RPM_STRING_TYPE) { + fprintf(f, "%s\n", (char*)data); + } else if (type == RPM_STRING_ARRAY_TYPE) { + pstrarray(f, data, count); + } else { + puts("Oh shit!"); + abort(); + } +} + + +void pitem(FILE *f, char *file, char *version, int flags) +{ + fputs(file, f); + if (*version) { + int c = 0; + fputs(" (", f); + /* + * For some reason, debian ppl decided that: + * > and < are the same as >=, <= + * >> and << is the same as >, < + */ + if (flags & RPMSENSE_LESS) { + fputc('<', f); + c = '<'; + } + if (flags & RPMSENSE_GREATER) { + fputc('>', f); + c = '>'; + } + if (flags & RPMSENSE_EQUAL) { + fputc('=', f); + } else { + if (c) + fputc(c, f); + } + fprintf(f, " %s)", version); + } +} + + +void ptuplearray(FILE *f, char **str1, char **str2, int *flags, int count) +{ + int first = 1; + if (!count) + return; + + while (count--) { + if (1||strcmp(*str1, "rpmlib(VersionedDependencies)")!=0) { + if (!first) + fputs(", ", f); + first = 0; + pitem(f, *str1, *str2, *flags); + } else { + puts("ignoring: rpmlib(VersionedDependencies)"); + } + str1++; str2++; flags++; + } + fputc('\n', f); +} + +void pdepend(FILE *f, char **data1, char **data2, int *flags, int count, + int type) +{ + if (type == RPM_STRING_TYPE) { + pitem(f, (char*)data1, (char*)data2, *flags); + fprintf(f, "\n"); + } else if (type == RPM_STRING_ARRAY_TYPE) { + ptuplearray(f, data1, data2, flags, count); + } else { + puts("Oh shit!"); + abort(); + } +} + + +void dumpDescription(FILE *f, char *descr) +{ + int nl; + + nl = 1; + while (*descr) { + if (nl) { + fputc(' ', f); + nl = 0; + } + if (*descr=='\n') { + nl = 1; + } + fputc(*descr++, f); + } + fputc('\n', f); +} + + + +void showHeader(FILE *f, Header hdr, char *dir) +{ + int type, type2, type3, count; + char *str; + char **strv; + char **strv2; + char **strv3; + int num; + int_32 *numv; + + headerGetEntry(hdr, RPMTAG_NAME, &type, (void **)&str, &count); + fprintf(f, "Package: %s\n", str); + + headerGetEntry(hdr, RPMTAG_SIZE, &type, (void **)&str, &count); + fprintf(f, "Version: %s\n", str); + headerGetEntry(hdr, RPMTAG_ARCHIVESIZE, &type, (void **)&str, &count); + fprintf(f, "Version: %s\n", str); + + + return; + headerGetEntry(hdr, RPMTAG_VERSION, &type, (void **)&str, &count); + fprintf(f, "Version: %s\n", str); + + headerGetEntry(hdr, RPMTAG_RELEASE, &type, (void **)&str, &count); + fprintf(f, "Release: %s\n", str); + + headerGetEntry(hdr, RPMTAG_GROUP, &type, (void **)&str, &count); + fprintf(f, "Section: %s\n", str); + + headerGetEntry(hdr, RPMTAG_PACKAGER, &type, (void **)&str, &count); + if (str) + fprintf(f, "Maintainer: %s\n", str); + + headerGetEntry(hdr, RPMTAG_REQUIRENAME, &type, (void **)&strv, &count); + headerGetEntry(hdr, RPMTAG_REQUIREVERSION, &type2, (void **)&strv2, &count); + headerGetEntry(hdr, RPMTAG_REQUIREFLAGS, &type3, (void **)&numv, &count); + if (count > 0) { + char **dn, **dv; + int *df; + int i, j; + + dn = (char**)malloc(sizeof(char*)*count); + dv = (char**)malloc(sizeof(char*)*count); + df = (int*)malloc(sizeof(int)*count); + + if (!dn || !dv || !df) { + puts("could not malloc"); + exit(1); + } + + for (j = i = 0; i < count; i++) { + if ((numv[i] & RPMSENSE_PREREQ) && *strv[i]!='/') {//XXX + dn[j] = strv[i]; + dv[j] = strv2[i]; + df[j] = numv[i]; + j++; + } + } + if (j > 0) { + fprintf(f, "Pre-Depends: "); + pdepend(f, dn, dv, df, j, type); + } + + for (j = i = 0; i < count; i++) { + if (!(numv[i] & RPMSENSE_PREREQ) && *strv[i]!='/') {//XXX + dn[j] = strv[i]; + dv[j] = strv2[i]; + df[j] = numv[i]; + j++; + } + } + if (j > 0) { + fprintf(f, "Depends: "); + pdepend(f, dn, dv, df, j, type); + } + + free(dn); + free(dv); + free(df); + } + + headerGetEntry(hdr, RPMTAG_CONFLICTNAME, &type, (void **)&strv, &count); + headerGetEntry(hdr, RPMTAG_CONFLICTVERSION, &type2, (void **)&strv2, &count); + headerGetEntry(hdr, RPMTAG_CONFLICTFLAGS, &type3, (void **)&numv, &count); + if (count > 0) { + fprintf(f, "Conflicts: "); + pdepend(f, strv, strv2, numv, count, type); + } + + headerGetEntry(hdr, RPMTAG_PROVIDENAME, &type, (void **)&strv, &count); + if (count > 0) { + fprintf(f, "Provides: "); + pstr(f, strv, count, type); + } + + headerGetEntry(hdr, RPMTAG_OBSOLETENAME, &type, (void **)&strv, &count); + if (count > 0) { + fprintf(f, "Replaces: ");//akk?? + pstr(f, strv, count, type); + } + + + headerGetEntry(hdr, RPMTAG_ARCH, &type, (void **)&str, &count); + fprintf(f, "Architecture: %s\n", str); + +// if (headerGetEntry(hdr, RPMTAG_SIZE, &type, (void **)&num, &count)!=0) +// puts("nao tem archive size"); + + + headerGetEntry(hdr, CRPMTAG_FILENAME, &type, (void **)&str, &count); + { + struct stat stbuf; + char buf[1024]; + + sprintf(buf, "%s/%s", dir, str); + if (stat(buf, &stbuf) < 0) { + perror(buf); + } + num = stbuf.st_size; + } + fprintf(f, "Size: %i\n", num / 1000); + + + fprintf(f, "Filename: %s\n", str); + + if (headerGetEntry(hdr, RPMSIGTAG_MD5, &type, (void **)&str, &count)==0) + printf("MD5sum: %s\n", str); + + headerGetEntry(hdr, RPMTAG_SUMMARY, &type, (void **)&str, &count); + fprintf(f, "Description: %s\n", str); + + headerGetEntry(hdr, RPMTAG_DESCRIPTION, &type, (void **)&str, &count); + dumpDescription(f, str); + + if (headerGetEntry(hdr, RPMTAG_SIZE, &type, (void **)&num, &count)) + fprintf(f, "installed-size: %i ???\n", num/1024); + else + fprintf(f, "installed-size: %i (%i)\n", num/1024, type); + + fputc('\n', f); +} + + +int convert(char *dir, char *ifile, char *ofile) +{ + int fd; + Header h; + FILE *fout; + + + fd = open(ifile, O_RDONLY); + if (fd < 0) { + puts("cant open hdlist."); + perror(ifile); + exit(1); + } + + fout = fopen(ofile, "w+"); + + while (1) { + FD_t fdt = fdDup(fd); + h = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + if (!h) + break; + showHeader(fout, h, dir); + + } + fclose(fout); + + close(fd); +} + + + +void findFileRequires(Header hdr) +{ + int type, count; + char *name; + char **strv; + int i; + + headerGetEntry(hdr, RPMTAG_NAME, &type, (void **)&name, &count); + + headerGetEntry(hdr, RPMTAG_REQUIRENAME, &type, (void **)&strv, &count); + for (i = 0; i < count; i++) { + char *s; + + s = strv[i]; + if (*s == '/') { + HashInsert(table, s, s); + } + } +} + + + + +void findFileProviders(Header hdr) +{ + int type, count; + char *name; + const char **strv; + int i; + + headerGetEntry(hdr, RPMTAG_NAME, &type, (void **)&name, &count); + + rpmBuildFileList(hdr, &strv, &count); + for (i = 0; i < count; i++) { + const char *s; + + s = strv[i]; + if (HashGet(table, s)) { + HashInsert(table, (char*)s, name); + } + } +} + + + +void preprocess(char *ifile) +{ + int fd; + Header h; + + fd = open(ifile, O_RDONLY); + if (fd < 0) { + puts("cant open hdlist."); + perror(ifile); + exit(1); + } + + + + while (1) { + FD_t fdt = fdDup(fd); + h = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + if (!h) + break; + findFileRequires(h); + } + + close(fd); + fd = open(ifile, O_RDONLY); + + while (1) { + FD_t fdt = fdDup(fd); + h = headerRead(fdt, HEADER_MAGIC_YES); + fdClose(fdt); + if (!h) + break; + findFileProviders(h); + } + + close(fd); +} + + + + +int main(int argc, char **argv) +{ + if (argc < 2) { + puts("you need to supply a list of hdlists"); + } else { + int i; + char fname[512], fname2[512], dir[512]; + + + for (i = 1; i < argc; i++) { + table = CreateHashTable(StringHashCallbacks); + + // look for file dependencies +// preprocess(argv[i]); + + // convert the files + sprintf(fname, "%s/hdlist.001", argv[i]); + sprintf(fname2, "%s/Packages.001", argv[i]); + sprintf(dir, "%s/../RPMS.001", argv[i]); + convert(dir, fname, fname2); + + sprintf(fname, "%s/hdlist.002", argv[i]); + sprintf(fname2, "%s/Packages.002", argv[i]); + sprintf(dir, "%s/../RPMS.002", argv[i]); + convert(dir, fname, fname2); + + FreeHashTable(table); + } + } +} diff --git a/apt/tools/mkstatus.c b/apt/tools/mkstatus.c new file mode 100644 index 0000000..290f172 --- /dev/null +++ b/apt/tools/mkstatus.c @@ -0,0 +1,54 @@ +#include + +#include +#include +#include + +#include + + + + + +int convert(char *ofile) +{ + rpmdb db; + unsigned int offset; + Header hdr; + FILE *f; + char *rootdir = "/"; + + f = fopen(ofile, "w+"); + if (!f) { + perror(ofile); + return 0; + } + + rpmdbInit(rootdir, 0644); + + if (rpmdbOpen("/", &db, O_RDONLY, 0644)) { + fclose(f); + puts("could not open rpmdb"); + return 0; + } + + for (offset = rpmdbFirstRecNum(db); + offset > 0; + offset = rpmdbNextRecNum(db, offset)) { + hdr = rpmdbGetRecord(db, offset); + + + } + + rpmdbClose(db); + fclose(f); + + return 1; +} + + + +int main() +{ + convert("status"); +} diff --git a/rpmpriorities b/rpmpriorities new file mode 100644 index 0000000..e9b8ea5 --- /dev/null +++ b/rpmpriorities @@ -0,0 +1,113 @@ +Important: + sh + basesystem + bash + bdflush + bzip2 + bzlib + chkconfig + console-tools + dev + e2fsprogs + ed + etcskel + filesystem + fileutils + findutils + gawk + glib + glibc-core + grep + gzip + info + initscripts + libncurses + libpam + libpopt + libreadline + losetup + mingetty + mkinitrd + mktemp + modutils + mount + ncurses + pam + passwd + procps + psmisc + reiserfs-utils + rootfiles + rpm + sed + setup + shadow-utils + sh-utils + stat + SysVinit + tar + terminfo + textutils + util-linux + zlib +Required: + apt + at + cpio + cpp + crontabs + dhcp + eject + file + finger + ftp + gdbm + groff + isapnptools + less + libpng + libstdc++ + libtermcap + libutempter + lilo + logrotate + mailcap + man + mkbootdisk + mtools + net-tools + libnewt + pciutils + portmap + raidtools + slang + slocate + sysklogd + tcp_wrappers + telnet + termcap + timeconfig + tmpwatch + vim-common + vim-minimal + vixie-cron + which + zip +Standard: + bind-utils + dhcpcd + diffutils + gmp + gpm + ncftp + nfs-utils + openssl + openssh + perl + pidentd + python + rsh + rsync + tcsh + timeconfig + unzip