* `=' key in dselect really does `hold' rather than `unhold'.
* dselect dependency processing now interacts better with `hold'.
* dselect `I' key (not `i') modifies display of the info window.
* dselect shows unavailable packages as being unavailable.
* dselect main menu headings and many other strings changed to try to
discourage people from deselecting every package and using [R]emove.
Notably, `select' changed to `mark' throughout.
* dselect disk methods now print a few fewer double slashes.
* dselect disk access methods will offer to use dpkg --record-avail
to scan the available packages, if no Packages file is found.
* New dpkg --compare-versions option, for the benefit of scripts &c.
* New dpkg --clear-avail option forgets all available packages info.
* New dpkg --print-avail option, prints `available' data (from Packages, &c).
* dpkg usage message is more informative, but no longer fits on screen.
* dpkg --avail option renamed --record-avail.
* Latest dpkg-name from Erick Branderhorst.
* dpkg-scanpackages has more sensible problem reporting.
* postinst configure now gets null argument (not <unknown> or <none>)
when there is no previously configured version.
* Guidelines say that postinst configure is given previous version.
* Guidelines don't refer to maintainer-script-args.txt in main text.
* Guidelines (Texinfo source) uploaded separately.
* Own version of strcpy (used for debugging) removed.
* Interface to access methods document in source (doc/dselect-methods.txt).
* debian.buildscript moves changes file into parent directory.
-- Ian Jackson <ian@chiark.chu.cam.ac.uk> Wed, 22 May 1996 01:26:31 +0100
* Conflicts << installation ordering
* Version numbers in pre-depends stuff
* Search for all pre-depends things at once, bomb out if any not found
-
-bugs that need to be fixed quickly
- * version numbers not starting digit early.
* check description in dpkg-deb
* field overflow in dpkg --list
* _always_ show section in --yet-to-unpack
* Several things ought to be configurable but aren't.
* Filenames containing newlines. Conffile names containing spaces.
* dpkg --status for virtual packages
- * dselect bottom window too large, and/or resize
* update-alternatives prompting.
* logging, both transcript logs (kept briefly)
and action logs (kept forever?) 957
* remove old docs from /usr/doc/dpkg.
other stuff unlikely to get done soon
+ * understand Replaces in dselect
* provide way for package to declare ownership of files for dpkg -S
and -L without having dpkg act on this
* md5sum component in new .deb files
- * version number comparison option
* diversions list as control archive entry
* single maintainer script, and new package getting there first
* dpkg -s show something for virtual packages
* start-stop-daemon in C. 1670
* dselect per-half focus and keybindings improvements. 1555
* floppy map (where are the files)
- * highlight or pre-sort or something new or changed packages,
- during upgrade selection.
* how to change case of package names
* support for adding files to dpkg's file lists
- * side-by-side version display
* `fake' or `null' packages
* --purge remove empty directories which used too contain conffiles
* conffiles handling options, including `replace removed files'
done
+ * highlight or pre-sort or something new or changed packages,
+ during upgrade selection.
+ * side-by-side version display
+ * version number comparison option
* Pre-Depends installation ordering
* a.out version
* uncomment ELF preinst modification
* Architecture field check
* symlink rename change
* dpkg --listfiles should do better for multi-package files (pkg, pkg: ...)
+
+obsoleted so not done
+ * version numbers not starting digit early.
+ * dselect bottom window too large, and/or resize
+dpkg (1.2.1); priority=MEDIUM
+
+ * `=' key in dselect really does `hold' rather than `unhold'.
+ * dselect dependency processing now interacts better with `hold'.
+ * dselect `I' key (not `i') modifies display of the info window.
+ * dselect shows unavailable packages as being unavailable.
+ * dselect main menu headings and many other strings changed to try to
+ discourage people from deselecting every package and using [R]emove.
+ Notably, `select' changed to `mark' throughout.
+
+ * dselect disk methods now print a few fewer double slashes.
+ * dselect disk access methods will offer to use dpkg --record-avail
+ to scan the available packages, if no Packages file is found.
+
+ * New dpkg --compare-versions option, for the benefit of scripts &c.
+ * New dpkg --clear-avail option forgets all available packages info.
+ * New dpkg --print-avail option, prints `available' data (from Packages, &c).
+ * dpkg usage message is more informative, but no longer fits on screen.
+ * dpkg --avail option renamed --record-avail.
+
+ * Latest dpkg-name from Erick Branderhorst.
+ * dpkg-scanpackages has more sensible problem reporting.
+ * postinst configure now gets null argument (not <unknown> or <none>)
+ when there is no previously configured version.
+
+ * Guidelines say that postinst configure is given previous version.
+ * Guidelines don't refer to maintainer-script-args.txt in main text.
+ * Guidelines (Texinfo source) uploaded separately.
+
+ * Own version of strcpy (used for debugging) removed.
+ * Interface to access methods document in source (doc/dselect-methods.txt).
+ * debian.buildscript moves changes file into parent directory.
+
+ -- Ian Jackson <ian@chiark.chu.cam.ac.uk> Wed, 22 May 1996 01:26:31 +0100
+
dpkg (1.2.0); priority=MEDIUM
* dselect can sort packages by available and installed states, and
really ./debian.rules clean
./debian.rules build
really ./debian.rules binary
+cp doc/guidelines.texi ..
version=`sed -n 's/^version=//p' debian.rules`
perl debian.mkchanges "$version" <debian.changestemplate \
- | pgp-auto -fast >dpkg-$version.`dpkg --print-architecture`.changes
+ | pgp-auto -fast >../dpkg-$version.`dpkg --print-architecture`.changes
+echo
=f:dpkg-=v.=a.deb byhand -
=f:dpkg-=velf.=a.nondebbin.tar.gz byhand -
=f:dpkg-=v.=a.nondebbin.tar.gz byhand -
+ =f:guidelines.texi byhand -
#!/usr/bin/make -f
package=dpkg
-version=1.2.0
+version=1.2.1
archi=$(shell dpkg --print-architecture)
DIR:=$(shell pwd)
--- /dev/null
+From ian Sun May 14 18:21:53 +0100 1995
+To: Debian developers list <debian-devel@pixar.com>
+Subject: dselect installation method scripts
+
+Below is a (somewhat amended) repost of the posting I made a little
+while ago about the interface between dselect and the installation
+scripts it can run to extract packages.
+
+Carl Streeter has some hard disk scripts that look fairly good (I
+haven't tested them). Anyone else looking to write such scripts
+should see his code (Carl, can you upload them please ?).
+
+Howevever, there are a few points to note:
+ * Each set of scripts can support several `options' as they're called
+- this saves having different code for the CD-ROM, hard disk, &c
+methods.
+ * You have to supply a /usr/[local]/lib/dpkg/methods/<method>/names
+file listing the options - see below.
+
+dselect *will* look in /usr/local/lib/dpkg/methods as well as
+/usr/lib. Put your scripts there until you send them to me for
+inclusion in dpkg.
+
+Details if the installation method handling is below, and in
+method-scripts.txt; an example `test' method that just shows you how
+to write a `names' file and how dselect reacts is available as:
+
+ab2022c57a1198838034c5f87ea501b1 dselect-example-test-method.tar
+-rw-rw-r-- 1 ian ian 10240 May 14 18:19 dselect-example-test-method.tar
+
+NB that the code in dselect to select and call installation scripts is
+ALPHA !
+
+Ian.
+
+Each `installation method' will have three scripts:
+
+ * Setup installation parameters.
+ * Update list of available packages.
+ * Unpack.
+
+Which set of scripts is to be used is selectable by the user, from the
+`[S]etup' menu option. Basically, the user hits `Setup', gets
+presented with a menu of choices and picks one.
+
+This (a) sets that `choice' to be the default installation method and
+(b) runs the `setup' script for that choice.
+
+The setup script should prompt the user for parameters like the site
+to NFS-mount or FTP from, the directory to use, or the directory or
+filesystem where the .deb files can be found, or the tape or floppy
+device to install from. It should store the responses under
+/var/lib/dpkg/methods - see below.
+
+The update script should obtain a list of available packages if
+possible (this is the Packages file from the FTP sites), and copy it
+to /var/lib/dpkg/available. Be careful not to overwrite the available
+file if something goes wrong - I'd suggest copying to `available.new'
+and renaming. If no available list is available :-) it should print a
+message saying so.
+
+The unpack script should feed all the available .deb files to
+ dpkg --unpack --no-also-select
+(the --auto option may also be useful here). In the future there will
+be a mechanism to allow (for example) a floppy-based installation
+scheme to tell the user which packages are still to be processed; in
+the meantime you should just keep going until the user says `stop'.
+
+If any of these scripts needs to display a message for the user, it
+should wait for the user to hit `return' before exiting so that
+dselect doesn't immediately rewrite the screen.
+
+If a script gives a non-zero exit status dselect will print a message
+about it and prompt the user for an acknowledgement. If it exits with
+a zero exit status then dselect will immediately go back into curses
+and any message that the script printed just before exiting will not
+be visible.
+
+The scripts will be kept in /usr/lib/dpkg/methods/. Each method
+should have a directory under methods, containing:
+ `names' - a list of `user-visible options', see below.
+ `setup', `update', `unpack' - executable programs.
+ `desc.<option>' - description file.
+
+A method may provide several options on the `main menu' with different
+behaviour. For example, there might be a generic get-packages-by-FTP
+method which might provide entries in the main menu for installation
+directly from one of the Debian mirror sites as well as for
+installation from a user-specified site.
+
+The `setup', `update' and `unpack' will be invoked with three
+arguments.
+
+The first argument is the directory with the dpkg status information,
+usually /var/lib/dpkg. They should $1/methods/<method-name> to store
+their data (remember that the user can give a --admindir option to
+dselect).
+
+The second and third argument are the name of the method and the
+option within that method, respectively. This information is provided
+by dselect (from the user's choice of installation option).
+
+`names' will be formatted as a list of lines, each containing:
+ <sequence> <option> <summary>
+
+<sequence> is a two-digit number that will be used much like rc.d
+prefixes to control the order in the main menu. If in doubt use 50.
+
+<option> is a name which will be passed to `setup', `update' and
+`unpack' as their third argument (see above).
+
+<summary> is the menu entry string.
+
+Each option may have an extended description in `desc.<option>'. This
+should be formatted like a Description: field entry *shifted one
+character to the left*.
+
+/var/lib/dpkg/methods will exist, and a method may use a
+/var/lib/dpkg/methods/<method> directory or file (or <method>.* files)
+to store its state.
+
+<method> and <option> must follow the rules for C identifiers.
+
+-- Ian Jackson 14th May 1995
and after removal, respectively.
They are given arguments which indicate the precise situation and
-action being performed---see @file{maintainer-script-args.txt} for
+action being performed---see
+@pxref{Maintainer script arguments and how dpkg does things} for
details of exactly when each of the scripts is invoked and what its
arguments are. Extra arguments and situations may be added later, so
you should not test the number of arguments to your script to determine
* configuration files -- /etc/skel vs /usr/doc/examples::
* How to write the Description control file field::
* Configuration of init::
-* Maintainer script arguments and how @file{dpkg} does things::
+* Maintainer script arguments and how dpkg does things::
* Mail processing packages::
* Virtual dependencies::
@end menu
networking support, in the form of IP or UUCP.
@end smallexample
-@node Configuration of init, Maintainer script arguments and how @file{dpkg} does things, How to write the Description control file field, Appendix
+@node Configuration of init, Maintainer script arguments and how dpkg does things, How to write the Description control file field, Appendix
@unnumberedsec Configuration of init
The @file{/etc/init.d} directory contains the scripts executed by
Otherwise, the @file{/etc/rc?.d} symbolic links will remain on the system
along with @file{/etc/init.d/acct} script.
-@node Maintainer script arguments and how @file{dpkg} does things, Mail processing packages, Configuration of init, Appendix
-@unnumberedsec Maintainer script arguments and how @file{dpkg} does things
+@node Maintainer script arguments and how dpkg does things, Mail processing packages, Configuration of init, Appendix
+@unnumberedsec Maintainer script arguments and how dpkg does things
This appendix describes exactly how maintainer scripts are called, with
what arguments, in what order, and what @file{dpkg} does in between.
In all cases version numbers are <version>-<revision>, if the package
has both, or just <version>. @code{upgrade} is used even when the new
-version number looks lower than the old.
+version number looks lower than the old. If there is no appropriate
+version then the argument may be the empty string (or, in versions of
+dpkg before 1.2.1, @code{<unknown>}).
@unnumberedsubsec Summary
<new preinst> upgrade <old-version>
<old preinst> abort-upgrade <new-version>
-<postinst> configure
+<postinst> configure <most-recently-configured-version>
<old postinst> abort-upgrade <new version>
<conflictor's postinst> abort-remove in-favour <package> <new version>
<deconfigured's postinst> abort-deconfigure \
@end enumerate
No attempt is made to unwind after errors during removal.
-@node Mail processing packages, Virtual dependencies, Maintainer script arguments and how @file{dpkg} does things, Appendix
+@node Mail processing packages, Virtual dependencies, Maintainer script arguments and how dpkg does things, Appendix
@unnumberedsec Mail processing packages
Debian packages which process electronic mail (whether mail-user-agents
cursorline= index;
if (listpad) {
redrawitemsrange(cursorline,cursorline+1);
- redraw1itemsel(cursorline,1);
+ redraw1itemsel(cursorline, showinfo != 2);
refreshlist();
redrawthisstate();
}
if (sigaction(SIGWINCH,&nsigact,0)) ohshite("failed to set new SIGWINCH sigact");
}
+void baselist::setheights() {
+ int y= ymax - (title_height + colheads_height + thisstate_height);
+ assert(y>=1);
+ if (showinfo==2 && y>=3) {
+ list_height= 1;
+ whatinfo_height= 1;
+ info_height= y-2;
+ } else if (showinfo==1 && y>=10) {
+ list_height= y/2;
+ info_height= (y-1)/2;
+ whatinfo_height= 1;
+ } else {
+ list_height= y;
+ info_height= 0;
+ whatinfo_height= 0;
+ }
+ colheads_row= title_height;
+ list_row= colheads_row + colheads_height;
+ thisstate_row= list_row + list_height;
+ info_row= thisstate_row + thisstate_height;
+ whatinfo_row= ymax - 1;
+}
+
void baselist::startdisplay() {
if (debug) fprintf(debug,"baselist[%p]::startdisplay()\n",this);
cbreak(); noecho(); nonl(); keypad(stdscr,TRUE);
whatinfo_attr= thisstate_attr;
// set up windows and pads, based on screen size
- int y;
getmaxyx(stdscr,ymax,xmax);
title_height= ymax>=6;
colheads_height= ymax>=5;
thisstate_height= ymax>=3;
- whatinfo_height= ymax>=2;
- y= ymax - (title_height + colheads_height +
- thisstate_height + whatinfo_height);
- assert(y>=1);
- y-= list_height + info_height;
- if (y>0) {
- list_height += (y+1)/2;
- info_height += y/2;
- } else if (y<0) {
- list_height -= (-y)/2;
- info_height -= (-y+1)/2;
- }
- colheads_row= title_height;
- list_row= colheads_row + colheads_height;
- thisstate_row= list_row + list_height;
- info_row= thisstate_row + thisstate_height;
- whatinfo_row= info_row + info_height;
+ setheights();
setwidths();
titlewin= newwin(1,xmax, 0,0);
}
void baselist::redraw1item(int index) {
- redraw1itemsel(index, index == cursorline);
+ redraw1itemsel(index, showinfo == 2 ? 0 : index == cursorline);
}
baselist::baselist(keybindings *kb) {
list_height=0; info_height=0;
topofscreen= 0; leftofscreen= 0;
listpad= 0; cursorline= -1;
+ showinfo= 1;
searchstring[0]= 0;
}
{ "scrollback", "Scroll backwards through list" },
// Actions which apply only to lists of packages.
- { "select", "Select package(s) for installation" },
- { "deselect", "Mark package(s) for deinstallation" },
+ { "install", "Mark package(s) for installation" },
+ { "remove", "Mark package(s) for deinstallation" },
{ "purge", "Mark package(s) for deinstall and purge" },
{ "morespecific", "Make highlight more specific" },
{ "lessspecific", "Make highlight less specific" },
static baselist *signallist;
static void sigwinchhandler(int);
- int nitems, ldrawnstart, ldrawnend;
+ int nitems, ldrawnstart, ldrawnend, showinfo;
int topofscreen, leftofscreen, cursorline;
int infotopofscreen, infolines;
varbuf whatinfovb;
char searchstring[50];
+ void setheights();
void unsizes();
void dosearch();
void displayhelp(const struct helpmenuentry *menu, int key);
B, Left-arrow F, Right-arrow pan display by 1/3 screen
^b ^f pan display by 1 character
-Selection for later processing:
+Mark packages for later processing:
+, Insert install or upgrade =, H hold in present state
-, Delete remove :, G unhold: upgrade or leave uninstalled
_ remove & purge config
Miscellaneous:
Quit, exit, overwrite (note capitals!): ?, F1 request help (also Help)
- Return Confirm, quit (check dependencies) i toggle/cycle info displays
+ Return Confirm, quit (check dependencies) i, I toggle/cycle info displays
Q Confirm, quit (override dep.s) o, O cycle through sort options
X, Esc eXit, abandoning any changes made v, V change status display opts
R Revert to state before this list ^l redraw display
U set all to sUggested state / search (Return to cancel)
- D set all to Directly selected state ) \\ repeat last search
+ D set all to Directly requested state \\ repeat last search
@@@ mainintro Introduction to package list
You will be presented with a list of packages which are installed or available
for installation. You can navigate around the list using the cursor keys,
-selecting packages for installation (using `+') or deinstallation (using `-').
+mark packages for installation (using `+') or deinstallation (using `-').
-Packages can be selected either singly or in groups; initially you will see
-that the line `All packages' is highlighted. (De)selecting will affect all the
+Packages can be marked either singly or in groups; initially you will see that
+the line `All packages' is selected. `+', `-' and so on will affect all the
packages described by the highlighted line. Use `o' to change the order of the
list (this also changes which kinds of group selections are possible).
-(Mainly for new installations:) Standard packages will be selected by default.
+(Mainly for new installations:) Standard packages will be requested by default.
Use capital `D' or `R' key to override this - see the keybindings help screen.
Some of your choices will cause conflicts or dependency problems; you will be
@@@ readonlyintro Introduction to package list browser (read-only)
Welcome to dselect's main package listing. Since you do not have the
-privilege necessary to update package selections you are in read-only mode.
+privilege necessary to update package states you are in read-only mode.
Much on-line help is available, please make use of it ! Press `?' for help.
You should read the list of keys and the explanations of the display.
the display shows relevant conflicts and dependencies; use `i' to cycle between
that, the package descriptions and the internal control information.
-A set of `suggested' selections has been calculated, and the initial selections
-in this sub-list have been set to match those, so you can just hit Return to
+A set of `suggested' packages has been calculated, and the initial markings in
+this sub-list have been set to match those, so you can just hit Return to
accept the suggestions if you wish. You may abort the change(s) which caused
the problem(s), and go back to the main list, by pressing capital `X'.
-You can also move around the list and change the selections so that they are
-more like what you want, and you can `reject' my suggestions by using the
-capital `D' or `R' keys (see the keybindings help screen). You can use capital
-`Q' to force me to accept the current selections, in case you want to override
-a recommendation or think that the program is mistaken.
+You can also move around the list and change the markings so that they are more
+like what you want, and you can `reject' my suggestions by using the capital
+`D' or `R' keys (see the keybindings help screen). You can use capital `Q' to
+force me to accept the situation currently displayed, in case you want to
+override a recommendation or think that the program is mistaken.
Press Space to leave help and enter the sub-list; remember: press `?' for help.
@@@ displayexplain1 Display, part 1: package listing and status chars
The top half of the screen shows a list of packages. For each package you see
-four columns for its current status and selected-ness. In terse mode (use `v'
-to toggle verbose display) these are single characters, from left to right:
+four columns for its current status on the system and mark. In terse mode (use
+`v' to toggle verbose display) these are single characters, from left to right:
Hold/error flag: h - you have put the package on Hold - it won't be processed
R - serious error during installation, needs reinstallation;
`u' - unpacked but not yet configured;
`C' - half-configured (an error happened);
`I' - half-installed (an error happened).
- Old selection: whether this package was selected before presenting this list;
- Selection: whether this package is selected for installation:
- `*': selected for installation;
- `-': deselected (selected for removal, but configuration files will remain);
- `_': deselected (purge completely, even remove configuration);
- `n': package is new to this system (appears under `Old selection').
+ Old mark: what was requested for this package before presenting this list;
+ Mark: what is requested for this package:
+ `*': marked for installation;
+ `-': marked for removal, but configuration files will remain;
+ `_': marked for purge completely - even remove configuration;
+ `n': package is new to this system (appears under `Old mark').
Following those four columns are the Priority and Section of the package,
its name (possibly truncated to fit) and the summary description.
@@@ displayexplain2 Display, part 2: list highlight; information display
* Highlight: One line in the package list will be highlighted. It indicates
- which package(s) will be selected/deselected by presses of `+', '-' and `_'.
+ which package(s) will be affected by presses of `+', '-' and `_'.
* The dividing line in the middle of the screen shows a brief explanation of
the status of the currently-highlighted package, or a description of which
};
static const menuentry menuentries[]= {
- { "access", "Choose the access method to use.", &urq_setup },
- { "update", "Update list of available packages, if possible.", &urq_update },
- { "select", "Select which packages to install (or deinstall).", &urq_list },
- { "install", "Install selected software.", &urq_install },
- { "config", "Configure packages that are unconfigured.", &urq_config },
- { "remove", "Remove software selected for deinstallation.", &urq_remove },
- { "quit", "Quit dselect.", &urq_quit },
- { "menu", 0, &urq_menu },
- { 0 }
+ { "access", "Choose the access method to use.", &urq_setup },
+ { "update", "Update list of available packages, if possible.", &urq_update },
+ { "select", "Request which packages you want on your system.", &urq_list },
+ { "install", "Install and upgrade wanted packages.", &urq_install },
+ { "config", "Configure any packages that are unconfigured.", &urq_config },
+ { "remove", "Remove unwanted software.", &urq_remove },
+ { "quit", "Quit dselect.", &urq_quit },
+ { "menu", 0, &urq_menu },
+ { 0 }
};
static const char programdesc[]=
if (recursive) {
redrawitemsrange(cursorline,cursorline+1);
- nw= reallywant(nwarg,table[cursorline]);
- nw= nwarg != pkginfo::want_sentinel ? nwarg :
table[cursorline]->selected= reallywant(nwarg,table[cursorline]);
redraw1item(cursorline);
top= cursorline;
}
void packagelist::kd_select() { setwant(pkginfo::want_install); }
-void packagelist::kd_hold() { setwant(pkginfo::want_hold); }
+void packagelist::kd_hold() { setwant(pkginfo::want_hold); }
void packagelist::kd_deselect() { setwant(pkginfo::want_deinstall); }
-void packagelist::kd_unhold() { setwant(pkginfo::want_sentinel); }
+void packagelist::kd_unhold() { setwant(pkginfo::want_sentinel); }
void packagelist::kd_purge() { setwant(pkginfo::want_purge); }
int would_like_to_install(pkginfo::pkgwant wantvalue, pkginfo *pkg) {
/* Returns: 1 for yes, 0 for no, -1 for if they want to preserve an error condition. */
+ if (debug) fprintf(debug,"would_like_to_install(%d, %s) status %d\n",
+ wantvalue,pkg->name,pkg->status);
+
if (wantvalue == pkginfo::want_install) return 1;
if (wantvalue != pkginfo::want_hold) return 0;
if (pkg->status == pkginfo::stat_installed) return 1;
/* fixme: configurable purge/deselect */
-void packagelist::kd_info() {
- currentinfo++;
- infotopofscreen=0;
+void packagelist::kd_toggleinfo() {
+ showinfo= (showinfo+2) % 3;
+ setheights();
+ if (cursorline >= topofscreen+list_height) topofscreen += list_height;
+ if (topofscreen > nitems - list_height) topofscreen= nitems-list_height;
+ if (topofscreen < 0) topofscreen= 0;
+ infotopofscreen= 0;
+ redraw1item(cursorline);
+ refreshlist();
+ redrawthisstate();
redrawinfo();
}
+
+void packagelist::kd_info() {
+ if (!showinfo) {
+ showinfo= 2; kd_toggleinfo();
+ } else {
+ currentinfo++;
+ infotopofscreen=0;
+ redrawinfo();
+ }
+}
static const int depdebug= 1;
+int packagelist::useavailable(pkginfo *pkg) {
+ if (informative(pkg,&pkg->available) &&
+ pkg->clientdata->selected == pkginfo::want_install &&
+ (pkg->status != pkginfo::stat_installed ||
+ versioncompare(&pkg->available.version,&pkg->installed.version) > 1))
+ return 1;
+ else
+ return 0;
+}
+
+pkginfoperfile *packagelist::findinfo(pkginfo *pkg) {
+ pkginfoperfile *r;
+ r= useavailable(pkg) ? &pkg->available : &pkg->installed;
+ if (!r->valid) blankpackageperfile(r);
+ return r;
+}
+
+int packagelist::checkdependers(pkginfo *pkg, int changemade) {
+ struct deppossi *possi;
+
+ if (pkg->available.valid) {
+ for (possi= pkg->available.depended; possi; possi= possi->nextrev) {
+ if (!useavailable(possi->up->up)) continue;
+ changemade= greaterint(changemade,resolvedepcon(possi->up));
+ }
+ }
+ if (pkg->installed.valid) {
+ for (possi= pkg->installed.depended; possi; possi= possi->nextrev) {
+ if (useavailable(possi->up->up)) continue;
+ changemade= greaterint(changemade,resolvedepcon(possi->up));
+ }
+ }
+ return changemade;
+}
+
int packagelist::resolvesuggest() {
// We continually go around looking for things to change, but we may
// only change the `suggested' value if we also increase the `priority'
fprintf(debug,"packagelist[%p]::resolvesuggest() loop[%i] %s / %d\n",
this, index, table[index]->pkg->name, changemade);
dependency *depends;
- for (depends= table[index]->pkg->available.depends;
+ for (depends= findinfo(table[index]->pkg)->depends;
depends;
- depends= depends->next)
- changemade= greaterint(changemade, resolvedepcon(depends));
- deppossi *possi;
- for (possi= table[index]->pkg->available.depended;
- possi;
- possi= possi->nextrev)
- changemade= greaterint(changemade, resolvedepcon(possi->up));
- for (depends= table[index]->pkg->available.depends;
+ depends= depends->next) {
+ changemade= greaterint(changemade,resolvedepcon(depends));
+ }
+ changemade= checkdependers(table[index]->pkg,changemade);
+ for (depends= findinfo(table[index]->pkg)->depends;
depends;
- depends= depends->next)
- if (depends->type == dep_provides)
- for (possi= depends->list->ed->available.valid
- ? depends->list->ed->available.depended : 0;
- possi;
- possi= possi->nextrev)
- changemade= greaterint(changemade, resolvedepcon(possi->up));
+ depends= depends->next) {
+ if (depends->type != dep_provides) continue;
+ changemade= checkdependers(depends->list->ed,changemade);
+ }
if (depdebug)
fprintf(debug,"packagelist[%p]::resolvesuggest() loop[%i] %s / -> %d\n",
this, index, table[index]->pkg->name, changemade);
// If we haven't found anything yet then this is our best so far.
if (!best) goto yes;
+
+ // If only one of the packages is available, use that one
+ if (!informative(trythis,&trythis->available) &&
+ informative(best->pkg,&best->pkg->available)) return 0;
+ if (informative(trythis,&trythis->available) &&
+ !informative(best->pkg,&best->pkg->available)) goto yes;
// Select the package with the lowest priority (ie, the one of whom
// we were least sure we wanted it deselected).
}
int packagelist::resolvedepcon(dependency *depends) {
- perpackagestate *best;
+ perpackagestate *best, *fixbyupgrade;
deppossi *possi, *provider;
int r, foundany;
}
if (!depends->up->clientdata) return 0;
-
- if (depends->up->clientdata->selected != pkginfo::want_install) return 0;
switch (depends->type) {
case dep_recommends:
case dep_depends:
case dep_predepends:
+
+ if (would_like_to_install(depends->up->clientdata->selected,depends->up) <= 0)
+ return 0;
+
+ fixbyupgrade= 0;
+
for (possi= depends->list;
- possi && !deppossatisfied(possi);
+ possi && !deppossatisfied(possi,&fixbyupgrade);
possi= possi->next);
if (depdebug)
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): depends found %s\n",
- this,depends, possi ? possi->ed->name : "[none]");
+ this,depends,
+ possi ? possi->ed->name : "[none]");
if (possi) return 0;
// Ensures all in the recursive list; adds info strings; ups priorities
if (depends->type == dep_suggests) return r;
- best= 0;
- for (possi= depends->list;
- possi;
- possi= possi->next) {
- foundany= 0;
- if (possi->ed->clientdata) foundany= 1;
- if (dep_update_best_to_change_stop(best, possi->ed)) goto mustdeselect;
- for (provider= possi->ed->available.valid ? possi->ed->available.depended : 0;
- provider;
- provider= provider->nextrev) {
- if (provider->up->type != dep_provides) continue;
- if (provider->up->up->clientdata) foundany= 1;
- if (dep_update_best_to_change_stop(best, provider->up->up)) goto mustdeselect;
- }
- if (!foundany) addunavailable(possi);
- }
-
- if (!best) {
+ if (fixbyupgrade) {
if (depdebug) fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): "
- "mustdeselect nobest\n", this,depends);
- return r;
+ "fixbyupgrade %s\n", this,depends,fixbyupgrade->pkg->name);
+ best= fixbyupgrade;
+ } else {
+ best= 0;
+ for (possi= depends->list;
+ possi;
+ possi= possi->next) {
+ foundany= 0;
+ if (possi->ed->clientdata) foundany= 1;
+ if (dep_update_best_to_change_stop(best, possi->ed)) goto mustdeselect;
+ for (provider= possi->ed->available.valid ? possi->ed->available.depended : 0;
+ provider;
+ provider= provider->nextrev) {
+ if (provider->up->type != dep_provides) continue;
+ if (provider->up->up->clientdata) foundany= 1;
+ if (dep_update_best_to_change_stop(best, provider->up->up)) goto mustdeselect;
+ }
+ if (!foundany) addunavailable(possi);
+ }
+ if (!best) {
+ if (depdebug) fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): "
+ "mustdeselect nobest\n", this,depends);
+ return r;
+ }
}
if (depdebug)
fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): select best=%s{%d}\n",
return 2;
case dep_conflicts:
- if (!deppossatisfied(depends->list)) return 0;
+
+ if (depdebug)
+ fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): conflict\n",
+ this,depends);
+
+ if (would_like_to_install(depends->up->clientdata->selected,depends->up) == 0)
+ return 0;
+
+ if (depdebug)
+ fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): conflict installing 1\n",
+ this,depends);
+
+ if (!deppossatisfied(depends->list,0)) return 0;
+
+ if (depdebug)
+ fprintf(debug,"packagelist[%p]::resolvedepcon([%p]): conflict satisfied - ouch\n",
+ this,depends);
+
if (depends->up != depends->list->ed) {
r= deselect_one_of(depends->up, depends->list->ed, depends); if (r) return r;
}
}
}
-int deppossatisfied(deppossi *possi) {
- if (possi->ed->clientdata &&
- possi->ed->clientdata->selected == pkginfo::want_install &&
- !(possi->up->type == dep_conflicts && possi->up->up == possi->ed)) {
- // If it's installed, then either it's of the right version,
- // and therefore OK, or a version must have been specified,
- // in which case we don't need to look at the rest anyway.
- if (possi->verrel == deppossi::dvr_none) return 1;
- int r= versioncompare(&possi->ed->available.version,&possi->version);
- switch (possi->verrel) {
- case deppossi::dvr_earlierequal: return r <= 0;
- case deppossi::dvr_laterequal: return r >= 0;
- case deppossi::dvr_earlierstrict: return r < 0;
- case deppossi::dvr_laterstrict: return r > 0;
- case deppossi::dvr_exact: return r == 0;
- default: internerr("unknown verrel");
+int packagelist::deppossatisfied(deppossi *possi, perpackagestate **fixbyupgrade) {
+ int would;
+ pkginfo::pkgwant want= pkginfo::want_purge;
+
+ if (possi->ed->clientdata) {
+ want= possi->ed->clientdata->selected;
+ would= would_like_to_install(want,possi->ed);
+ } else {
+ would= 0;
+ }
+
+ if (!(possi->up->type == dep_conflicts && possi->up->up == possi->ed) &&
+ possi->up->type == dep_conflicts ? (would != 0) : (would > 0)) {
+ // If it's to be installed or left installed, then either it's of
+ // the right version, and therefore OK, or a version must have
+ // been specified, in which case we don't need to look at the rest
+ // anyway.
+ if (want == pkginfo::want_hold) {
+ if (versionsatisfied(&possi->ed->installed,possi)) return 1;
+ if (fixbyupgrade && !*fixbyupgrade &&
+ versionsatisfied(&possi->ed->available,possi) &&
+ versioncompare(&possi->ed->available.version,
+ &possi->ed->installed.version) > 1)
+ *fixbyupgrade= possi->ed->clientdata;
+ return 0;
+ } else {
+ assert(want == pkginfo::want_install);
+ return versionsatisfied(&possi->ed->available,possi);
}
}
if (possi->verrel != deppossi::dvr_none) return 0;
deppossi *provider;
- for (provider= possi->ed->available.valid ? possi->ed->available.depended : 0;
- provider;
- provider= provider->nextrev) {
- if (provider->up->type != dep_provides) continue;
- if (provider->up->up->clientdata &&
- would_like_to_install(provider->up->up->clientdata->selected,
- provider->up->up) == 1)
- return 1;
+ if (possi->ed->installed.valid) {
+ for (provider= possi->ed->installed.depended;
+ provider;
+ provider= provider->nextrev) {
+ if (provider->up->type == dep_provides &&
+ provider->up->up->clientdata &&
+ !useavailable(provider->up->up) &&
+ would_like_to_install(provider->up->up->clientdata->selected,
+ provider->up->up))
+ return 1;
+ }
+ }
+ if (possi->ed->available.valid) {
+ for (provider= possi->ed->available.depended;
+ provider;
+ provider= provider->nextrev) {
+ if (provider->up->type != dep_provides ||
+ !provider->up->up->clientdata ||
+ !would_like_to_install(provider->up->up->clientdata->selected,
+ provider->up->up))
+ continue;
+ if (useavailable(provider->up->up))
+ return 1;
+ if (fixbyupgrade && !*fixbyupgrade &&
+ (provider->up->up->status != pkginfo::stat_installed ||
+ versioncompare(&provider->up->up->available.version,
+ &provider->up->up->installed.version) > 1))
+ *fixbyupgrade= provider->up->up->clientdata;
+ }
}
return 0;
}
/* These MUST be in the same order as the corresponding enums in dpkg-db.h */
const char
- *const wantstrings[]= { "new package", "selected", "hold", "remove", "purge", 0 },
+ *const wantstrings[]= { "new package", "install", "hold", "remove", "purge", 0 },
*const eflagstrings[]= { "", "REINSTALL", 0 },
*const statusstrings[]= { "not installed", "unpacked (not set up)",
"failed config", "installed", "half installed",
internerr("bad sort in redrawtitle");
}
}
- const char *helpstring= readwrite ? (verbose ? " +/-=select v=terse ?=help"
- : " +/-=select v=verbose ?=help")
- : (verbose ? " v=terse ?=help"
- : " v=verbose ?=help");
+ const char *helpstring= readwrite ? (verbose ? " mark:+/=/- terse:v help:?"
+ : " mark:+/=/- verbose:v help:?")
+ : (verbose ? " terse:v help:?"
+ : " verbose:v help:?");
int l= strlen(helpstring);
getyx(titlewin,y,x);
if (xmax-l > 0) {
int packagelist::itr_recursive() { return recursive; }
const packagelist::infotype packagelist::infoinfos[]= {
- { itr_recursive, itd_relations },
- { 0, itd_description },
- { 0, itd_controlfile },
- { 0, 0 }
+ { itr_recursive, itd_relations },
+ { 0, itd_description },
+ { 0, itd_statuscontrol },
+ { 0, itd_availablecontrol },
+ { 0, 0 }
};
const packagelist::infotype *const packagelist::baseinfo= infoinfos;
whatinfovb(whatinfoline);
varbuf vb;
vb("The line you have highlighted represents many packages; "
- "if you ask to select or deselect it you will affect all the "
- "packages which match the criterion shown.\n"
+ "if you ask to install, remove, hold, &c it you will affect all "
+ "the packages which match the criterion shown.\n"
"\n"
"If you move the highlight to a line for a particular package "
- "you will see information about that package displayed here.");
+ "you will see information about that package displayed here."
+ "\n"
+ "You can use `o' and `O' to change the sort order and give yourself "
+ "the opportunity to mark packages in different kinds of groups.");
wordwrapinfo(0,vb.string());
}
}
}
-void packagelist::itd_controlfile() {
+void packagelist::itd_statuscontrol() {
+ werase(infopad);
+ if (!table[cursorline]->pkg->name) {
+ severalinfoblurb("currently installed control info");
+ } else {
+ whatinfovb("installed control info for ");
+ whatinfovb(table[cursorline]->pkg->name);
+ varbuf vb;
+ varbufrecord(&vb,table[cursorline]->pkg,&table[cursorline]->pkg->installed);
+ vb.terminate();
+ if (debug)
+ fprintf(debug,"packagelist[%p]::idt_statuscontrol(); `%s'\n",this,vb.string());
+ waddstr(infopad,vb.string());
+ }
+}
+
+void packagelist::itd_availablecontrol() {
werase(infopad);
if (!table[cursorline]->pkg->name) {
- severalinfoblurb("control file information");
+ severalinfoblurb("available version of control file info");
} else {
- whatinfovb("control file information for ");
+ whatinfovb("available version of control info for ");
whatinfovb(table[cursorline]->pkg->name);
varbuf vb;
varbufrecord(&vb,table[cursorline]->pkg,&table[cursorline]->pkg->available);
vb.terminate();
if (debug)
- fprintf(debug,"packagelist[%p]::idt_controlfile(); `%s'\n",this,vb.string());
+ fprintf(debug,"packagelist[%p]::idt_availablecontrol(); `%s'\n",this,vb.string());
waddstr(infopad,vb.string());
}
}
{ "panback", 0, packagelist::kd_panback, qa_noquit },
{ "panon1", 0, packagelist::kd_panon1, qa_noquit },
{ "panback1", 0, packagelist::kd_panback1, qa_noquit },
- { "select", 0, packagelist::kd_select, qa_noquit },
- { "deselect", 0, packagelist::kd_deselect, qa_noquit },
+ { "install", 0, packagelist::kd_select, qa_noquit },
+ { "remove", 0, packagelist::kd_deselect, qa_noquit },
{ "purge", 0, packagelist::kd_purge, qa_noquit },
{ "hold", 0, packagelist::kd_hold, qa_noquit },
{ "unhold", 0, packagelist::kd_unhold, qa_noquit },
{ "info", 0, packagelist::kd_info, qa_noquit },
+ { "toggleinfo", 0, packagelist::kd_toggleinfo, qa_noquit },
{ "verbose", 0, packagelist::kd_verbose, qa_noquit },
{ "versiondisplay", 0, packagelist::kd_versiondisplay, qa_noquit },
{ "help", 0, packagelist::kd_help, qa_noquit },
{ C('b'), "panback1" },
{ C('f'), "panon1" },
- { '+', "select" },
- { KEY_IC, "select" },
- { '-', "deselect" },
- { KEY_DC, "deselect" },
+ { '+', "install" },
+ { KEY_IC, "install" },
+ { '-', "remove" },
+ { KEY_DC, "remove" },
{ '_', "purge" },
{ 'H', "hold" },
- { '=', "unhold" },
+ { '=', "hold" },
{ 'G', "unhold" },
{ '?', "help" },
{ KEY_HELP, "help" },
{ KEY_F(1), "help" },
{ 'i', "info" },
+ { 'I', "toggleinfo" },
{ 'o', "swaporder" },
{ 'O', "swapstatorder" },
{ 'v', "verbose" },
thispkg->clientdata->ssstate,
ssdiff ? "*diff" : "same",
thispkg->priority,
- thispkg->otherpriority ? thispkg->otherpriority : "<null>",
+ thispkg->priority != pkginfo::pri_other ? "<none>"
+ : thispkg->otherpriority ? thispkg->otherpriority
+ : "<null>",
prioritydiff ? "*diff*" : "same",
thispkg->section ? thispkg->section : "<null>",
sectiondiff ? "*diff*" : "same");
table[nitems]= state;
nitems++;
}
- if (!nitems) ohshit("There are no packages to select.");
+ if (!nitems) ohshit("There are no packages.");
recursive= 0;
sortorder= so_priority;
statsortorder= sso_avail;
void itd_recurwelcome();
void itd_relations();
void itd_description();
- void itd_controlfile();
+ void itd_statuscontrol();
+ void itd_availablecontrol();
// Dependency and sublist processing
struct doneent { doneent *next; void *dep; } *depsdone, *unavdone;
int alreadydone(doneent**, void*);
int resolvedepcon(dependency*);
+ int checkdependers(pkginfo*, int changemade); // returns new changemade
int deselect_one_of(pkginfo *er, pkginfo *ed, dependency *display);
// Define these virtuals
pkginfo::pkgwant reallywant(pkginfo::pkgwant, struct perpackagestate*);
int describemany(char buf[], const char *prioritystring, const char *section,
const struct perpackagestate *pps);
+ int deppossatisfied(deppossi *possi, perpackagestate **fixbyupgrade);
void sortmakeheads();
void resortredisplay();
void kd_hold();
void kd_unhold();
void kd_info();
+ void kd_toggleinfo();
void kd_verbose();
void kd_versiondisplay();
void add(pkginfo*, const char *extrainfo, showpriority displayimportance);
int add(dependency*, showpriority displayimportance);
void addunavailable(deppossi*);
+ int useavailable(pkginfo*);
+ pkginfoperfile *findinfo(pkginfo*);
int resolvesuggest();
int deletelessimp_anyleft(showpriority than);
extern const char wantchars[];
const struct pkginfoperfile *i2info(struct pkginfo *pkg);
-int deppossatisfied(deppossi *possi);
extern modstatdb_rw readwrite;
status_status_width);
mvwaddnstr(colheadspad,0,
status_hold_width+status_status_width+2,
- "Old sel.",
+ "Old mark",
status_want_width);
mvwaddnstr(colheadspad,0,
status_hold_width+status_status_width+status_want_width+3,
- "Selection",
+ "Marked for",
status_want_width);
} else {
- mvwaddstr(colheadspad,0,0, "HIOS");
+ mvwaddstr(colheadspad,0,0, "HIOM");
}
mvwaddnstr(colheadspad,0,section_column, "Section", section_width);
mvwaddnstr(colheadspad,0,priority_column, "Priority", priority_width);
/*** from vercmp.c ***/
+int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against);
+int versionsatisfied3(const struct versionrevision *it,
+ const struct versionrevision *ref,
+ enum depverrel verrel);
int versioncompare(const struct versionrevision *version,
const struct versionrevision *refversion);
int epochsdiffer(const struct versionrevision *a,
#ifndef MYOPT_H
#define MYOPT_H
+typedef void (*voidfnp)(void);
+
struct cmdinfo {
const char *olong;
char oshort;
void (*call)(const struct cmdinfo*, const char *value);
int arg;
void *parg;
+ voidfnp farg;
};
void myopt(const char *const **argvp, const struct cmdinfo *cmdinfos);
#include "config.h"
#include "dpkg.h"
-char *strcpy(char *to, const char *from) {
- char *oto= to;
- while ((*to++ = *from++) != 0);
- return oto;
-}
-
#ifndef HAVE_VSNPRINTF
int vsnprintf (char *buf, size_t maxsize, const char *fmt, va_list al) {
static FILE *file= 0;
* whether to display things, and by dump to decide whether to write them
* out.
*/
- if (info == &pkg->installed ?
+ if (info == &pkg->installed &&
((pkg->want != want_unknown && pkg->want != want_purge) ||
pkg->eflag != eflagv_ok ||
pkg->status != stat_notinstalled ||
informativeversion(&pkg->configversion) ||
- pkg->files)
- :
- (nes(pkg->section) ||
- pkg->priority != pri_unknown))
+ pkg->files))
+ /* We ignore Section and Priority, as these tend to hang around. */
return 1;
if (!info->valid) return 0;
if (info->depends ||
if (cstatus != msdbrw_needsuperuserlockonly) {
parsedb(statusfile, pdb_weakclassification, 0,0,0);
- parsedb(statusfile, pdb_recordavailable, 0,0,0);
parsedb(availablefile,
pdb_recordavailable|pdb_rejectstatus|
(cflags & msdbrw_availablepreferversion ? pdb_preferversion : 0),
r= verrevcmp(version->version,refversion->version); if (r) return r;
return verrevcmp(version->revision,refversion->revision);
}
+
+int versionsatisfied3(const struct versionrevision *it,
+ const struct versionrevision *ref,
+ enum depverrel verrel) {
+ int r;
+ if (verrel == dvr_none) return 1;
+ r= versioncompare(it,ref);
+ switch (verrel) {
+ case dvr_earlierequal: return r <= 0;
+ case dvr_laterequal: return r >= 0;
+ case dvr_earlierstrict: return r < 0;
+ case dvr_laterstrict: return r > 0;
+ case dvr_exact: return r == 0;
+ default: internerr("unknown verrel");
+ }
+}
+
+int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) {
+ return versionsatisfied3(&it->version,&against->version,against->verrel);
+}
const char **arglist;
char *p;
+ checkpath();
+
if (f_recursive) {
if (!*argv)
if (maintainer_script_installed(pkg, POSTINSTFILE, "post-installation",
"configure",
- versiondescribe(&pkg->configversion,
- vdew_nonambig),
+ informativeversion(&pkg->configversion)
+ ? versiondescribe(&pkg->configversion,
+ vdew_nonambig)
+ : "",
(char*)0))
putchar('\n');
#include "main.h"
-int versionsatisfied3(const struct versionrevision *it,
- const struct versionrevision *ref,
- enum depverrel verrel) {
- int r;
- if (verrel == dvr_none) return 1;
- r= versioncompare(it,ref);
- switch (verrel) {
- case dvr_earlierequal: return r <= 0;
- case dvr_laterequal: return r >= 0;
- case dvr_earlierstrict: return r < 0;
- case dvr_laterstrict: return r > 0;
- case dvr_exact: return r == 0;
- default: internerr("unknown verrel");
- }
-}
-
-int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against) {
- return versionsatisfied3(&it->version,&against->version,against->verrel);
-}
-
struct cyclesofarlink {
struct cyclesofarlink *back;
struct pkginfo *pkg;
}
break;
+ case act_printavail:
+ if (!informative(pkg,&pkg->available)) {
+ printf("Package `%s' is not available.\n",pkg->name);
+ failures++;
+ } else {
+ writerecord(stdout, "<stdout>", pkg, &pkg->available);
+ }
+ break;
+
case act_listfiles:
switch (pkg->status) {
case stat_notinstalled:
}
}
-void assertsupportpredepends(const char *const *argv) {
+void assertpredep(const char *const *argv) {
static struct versionrevision predepversion = {~0UL,0,0};
struct pkginfo *pkg;
ohshit("compiler libgcc filename not understood: %.250s",why);
}
-void printarchitecture(const char *const *argv) {
+void printinstarch(const char *const *argv) {
+ if (*argv) badusage("--print-installation-architecture does not take any argument");
+
+ if (printf("%s\n",architecture) == EOF) werr("stdout");
+ if (fflush(stdout)) werr("stdout");
+}
+
+void printarch(const char *const *argv) {
static const struct { const char *from, *to; } archtable[]= {
#include "archtable.inc"
{ 0,0 }
ptrdiff_t ll;
char *p, *q;
+ if (*argv) badusage("--print-architecture does not take any argument");
+
ccompiler= getenv("CC");
if (!ccompiler) ccompiler= "gcc";
varbufinit(&vb);
if (printf("%s\n",arch) == EOF) werr("stdout");
if (fflush(stdout)) werr("stdout");
}
+
+void cmpversions(const char *const *argv) {
+ struct relationinfo {
+ const char *string;
+ /* These values are exit status codes, so 0=true, 1=false */
+ int if_lesser, if_equal, if_greater;
+ int if_none_a, if_none_b, if_none_both;
+ };
+
+ static const struct relationinfo relationinfos[]= {
+ /* < = > !a!2!b */
+ { "le", 0,0,1, 0,0,1 },
+ { "lt", 0,1,1, 0,1,1 },
+ { "eq", 1,0,1, 1,0,1 },
+ { "ne", 0,1,0, 0,1,0 },
+ { "ge", 1,0,0, 1,0,0 },
+ { "gt", 1,1,0, 1,1,0 },
+ { "le-nl", 0,0,1, 1,0,0 }, /* Here none
+ { "lt-nl", 0,1,1, 1,1,0 }, * is counted
+ { "ge-nl", 1,0,0, 0,0,1 }, * than any version.
+ { "gt-nl", 1,1,0, 0,1,1 }, */
+ { "<", 0,0,1, 0,0,1 }, /* For compatibility
+ { "<=", 0,0,1, 0,0,1 }, * with dpkg
+ { "<<", 0,1,1, 0,1,1 }, * control file
+ { "=", 1,0,1, 1,0,1 }, * syntax
+ { ">", 1,0,0, 1,0,0 }, */
+ { ">=", 1,0,0, 1,0,0 },
+ { ">>", 1,1,0, 1,1,0 },
+ { 0 }
+ };
+
+ const struct relationinfo *rip;
+ const char *emsg;
+ struct versionrevision a, b;
+ int r;
+
+ if (!argv[0] || !argv[1] || !argv[2] || argv[3])
+ badusage("--cmpversions takes three arguments:"
+ " <version> <relation> <version>");
+
+ for (rip=relationinfos; rip->string && strcmp(rip->string,argv[1]); rip++);
+
+ if (!rip->string) badusage("--cmpversions bad relation");
+
+ if (*argv[0] && strcmp(argv[0],"<unknown>")) {
+ emsg= parseversion(&a,argv[0]);
+ if (emsg) {
+ if (printf("version a has bad syntax: %s\n",emsg) == EOF) werr("stdout");
+ if (fflush(stdout)) werr("stdout");
+ exit(1);
+ }
+ } else {
+ blankversion(&a);
+ }
+ if (*argv[2] && strcmp(argv[2],"<unknown>")) {
+ emsg= parseversion(&b,argv[2]);
+ if (emsg) {
+ if (printf("version b has bad syntax: %s\n",emsg) == EOF) werr("stdout");
+ if (fflush(stdout)) werr("stdout");
+ exit(1);
+ }
+ } else {
+ blankversion(&b);
+ }
+ if (!informativeversion(&a)) {
+ exit(informativeversion(&b) ? rip->if_none_a : rip->if_none_both);
+ } else if (!informativeversion(&b)) {
+ exit(rip->if_none_b);
+ }
+ r= versioncompare(&a,&b);
+ debug(dbg_general,"cmpversions a=`%s' b=`%s' r=%d",
+ versiondescribe(&a,vdew_always),
+ versiondescribe(&b,vdew_always),
+ r);
+ if (r>0) exit(rip->if_greater);
+ else if (r<0) exit(rip->if_lesser);
+ else exit(rip->if_equal);
+}
"conditions. There is NO warranty. See dpkg --licence for details.\n",
stdout)) werr("stdout");
}
-
+/*
+ options that need fixing:
+ " DPKG " --yet-to-unpack \n\
+ */
static void usage(void) {
if (!fputs("\
-Usage: " DPKG " -i|--install <.deb file name> ... | -R|--recursive <dir> ...\n\
- " DPKG " --unpack <.deb file name> ... | -R|--recursive <dir> ...\n\
- " DPKG " -A|--avail <.deb file name> ... | -R|--recursive <dir> ...\n\
- " DPKG " --configure <package name> ... | -a|--pending\n\
- " DPKG " -r|--remove | --purge <package name> ... | -a|--pending\n\
- " DPKG " -s|--status <package-name> ...\n\
- " DPKG " -L|--listfiles <package-name> ...\n\
- " DPKG " -l|--list [<package-name-pattern> ...]\n\
- " DPKG " -S|--search <filename-search-pattern> ...\n\
- " DPKG " -C|--audit | --yet-to-unpack\n\
- " DPKG " --merge-avail | --update-avail <Packages-file>\n\
+Usage: \n\
+ " DPKG " -i|--install <.deb file name> ... | -R|--recursive <dir> ...\n\
+ " DPKG " --unpack <.deb file name> ... | -R|--recursive <dir> ...\n\
+ " DPKG " -A|--record-avail <.deb file name> ... | -R|--recursive <dir> ...\n\
+ " DPKG " --configure <package name> ... | -a|--pending\n\
+ " DPKG " -r|--remove | --purge <package name> ... | -a|--pending\n\
+ " DPKG " --update-avail <Packages-file> replace available packages info\n\
+ " DPKG " --merge-avail <Packages-file> merge with info from file\n\
+ " DPKG " --clear-avail erase existing available info\n\
+ " DPKG " -s|--status <package-name> ... display package status details\n\
+ " DPKG " --print-avail <package-name> ... display available version details\n\
+ " DPKG " -L|--listfiles <package-name> ... list files `owned' by package(s)\n\
+ " DPKG " -l|--list [<pattern> ...] list packages concisely\n\
+ " DPKG " -S|--search <pattern> ... find package(s) owning file(s)\n\
+ " DPKG " -C|--audit check for broken package(s)\n\
+ " DPKG " --print-architecture print target architecture (uses GCC)\n\
+ " DPKG " --print-installation-architecture print host architecture (for inst'n)\n\
+ " DPKG " --compare-versions <a> <rel> <b> compare version numbers - see below\n\
+ " DPKG " --help | --version show this help / version number\n\
+ " DPKG " --force-help | -Dh|--debug=help help on forcing resp. debugging\n\
+ " DPKG " --licence print copyright licencing terms\n\
+\n\
Use " DPKG " -b|--build|-c|--contents|-e|--control|-I|--info|-f|--field|\n\
-x|--extract|-X|--vextract|--fsys-tarfile on archives (type " BACKEND " --help.)\n\
+\n\
For internal use: " DPKG " --assert-support-predepends | --predep-package\n\
\n\
-Options: --help --version --licence --force-help -Dh|--debug=help\n\
- --root=<directory> --admindir=<directory> --instdir=<directory>\n\
- -O|--selected-only -E|--skip-same-version -G=--refuse-downgrade\n\
- -B|--auto-deconfigure --ignore-depends=<package>,...\n\
- -D|--debug=<octal> --force-... --no-force-...|--refuse-...\n\
- --largemem|--smallmem --no-act\n\
+Options:
+ --admindir=<directory> Use <directory> instead of " ADMINDIR "\n\
+ --root=<directory> Install on alternative system rooted elsewhere\n\
+ --instdir=<directory> Change inst'n root without changing admin dir\n\
+ -O|--selected-only Skip packages not selected for install/upgrade\n\
+ -E|--skip-same-version Skip packages whose same version is installed\n\
+ -G=--refuse-downgrade Skip packages with earlier version than installed\n\
+ -B|--auto-deconfigure Install even if it would break some other package\n\
+ --largemem | --smallmem Optimise for large (>4Mb) or small (<4Mb) RAM use\n\
+ --no-act Just say what we would do - don't do it\n\
+ -D|--debug=<octal> Enable debugging - see -Dhelp or --debug=help
+ --ignore-depends=<package>,... Ignore dependencies involving <package>\n\
+ --force-... Override problems - see --force-help\n\
+ --no-force-...|--refuse-... Stop when problems encountered\n\
+\n\
+Comparison operators for --compare-versions are:\n\
+ lt le eq ne ge gt (treat no version as earlier than any version);\n\
+ lt-nl le-nl ge-nl gt-nl (tread no version as later than any version);\n\
+ < << <= = >= >> > (only for compatibility with control file syntax).\n\
\n\
Use `" DSELECT "' for user-friendly package management.\n",
stdout)) werr("stdout");
const char thisname[]= DPKG;
const char architecture[]= ARCHITECTURE;
-const char printforhelp[]=
- "Type " DPKG " --help for help about installing and deinstalling packages;\n"
- "Use " DSELECT " for user-friendly package management;\n"
- "Type " DPKG " -Dhelp for a list of " DPKG " debug flag values;\n"
- "Type " DPKG " --force-help for a list of forcing options;\n"
- "Type " BACKEND " --help for help about manipulating *.deb files.";
+const char printforhelp[]= "\
+Type " DPKG " --help for help about installing and deinstalling packages [*];\n\
+Use " DSELECT " for user-friendly package management;\n\
+Type " DPKG " -Dhelp for a list of " DPKG " debug flag values;\n\
+Type " DPKG " --force-help for a list of forcing options;\n\
+Type " BACKEND " --help for help about manipulating *.deb files;\n\
+Type " DPKG " --licence for copyright licence and lack of warranty (GNU GPL) [*].\n\
+\n\
+Options marked [*] produce a lot of output - pipe it through `less' or `more' !";
const struct cmdinfo *cipaction= 0;
int f_pending=0, f_recursive=0, f_alsoselect=1, f_skipsame=0, f_noact=0;
}
static const char *const passlongopts[]= {
- "build", "contents", "control", "info", "field", "extract",
+ "build", "contents", "control", "info", "field", "extract", "new", "old",
"vextract", "fsys-tarfile", 0
};
static const char okpassshortopts[]= "D";
static const struct cmdinfo cmdinfos[]= {
- { "install", 'i', 0, 0, 0, setaction, act_install },
- { "unpack", 0, 0, 0, 0, setaction, act_unpack },
- { "avail", 'A', 0, 0, 0, setaction, act_avail },
- { "configure", 0, 0, 0, 0, setaction, act_configure },
- { "remove", 'r', 0, 0, 0, setaction, act_remove },
- { "purge", 0, 0, 0, 0, setaction, act_purge },
- { "list", 'l', 0, 0, 0, setaction, act_list },
- { "status", 's', 0, 0, 0, setaction, act_status },
- { "search", 'S', 0, 0, 0, setaction, act_search },
- { "audit", 'C', 0, 0, 0, setaction, act_audit },
- { "listfiles", 'L', 0, 0, 0, setaction, act_listfiles },
- { "update-avail", 0, 0, 0, 0, setaction, act_avreplace },
- { "merge-avail", 0, 0, 0, 0, setaction, act_avmerge },
- { "yet-to-unpack", 0, 0, 0, 0, setaction, act_unpackchk },
- { "assert-support-predepends", 0, 0, 0, 0, setaction, act_assuppredep },
- { "print-architecture", 0, 0, 0, 0, setaction, act_printarch },
- { "print-installation-architecture", 0,0, 0,0, setaction, act_printinstarch },
- { "predep-package", 0, 0, 0, 0, setaction, act_predeppackage },
+ /* This table has both the action entries in it and the normal options.
+ * The action entries are made with the ACTION macro, as they all
+ * have a very similar structure.
+ */
+#define ACTION(longopt,shortopt,code,function) \
+ { longopt, shortopt, 0,0,0, setaction, code, 0, (voidfnp)function }
+ ACTION( "install", 'i', act_install, archivefiles ),
+ ACTION( "unpack", 0, act_unpack, archivefiles ),
+ ACTION( "record-avail", 'A', act_avail, archivefiles ),
+ ACTION( "configure", 0, act_configure, packages ),
+ ACTION( "remove", 'r', act_remove, packages ),
+ ACTION( "purge", 0, act_purge, packages ),
+ ACTION( "listfiles", 'L', act_listfiles, enqperpackage ),
+ ACTION( "status", 's', act_status, enqperpackage ),
+ ACTION( "print-avail", 0, act_printavail, enqperpackage ),
+ ACTION( "update-avail", 0, act_avreplace, updateavailable ),
+ ACTION( "merge-avail", 0, act_avmerge, updateavailable ),
+ ACTION( "clear-avail", 0, act_avclear, updateavailable ),
+ ACTION( "audit", 'C', act_audit, audit ),
+ ACTION( "yet-to-unpack", 0, act_unpackchk, unpackchk ),
+ ACTION( "list", 'l', act_listpackages, listpackages ),
+ ACTION( "search", 'S', act_searchfiles, searchfiles ),
+ ACTION( "print-architecture", 0, act_printarch, printarch ),
+ ACTION( "assert-support-predepends", 0, act_assertpredep, assertpredep ),
+ ACTION( "print-installation-architecture", 0, act_printinstarch, printinstarch ),
+ ACTION( "predep-package", 0, act_predeppackage, predeppackage ),
+ ACTION( "compare-versions", 0, act_cmpversions, cmpversions ),
+
{ "pending", 'a', 0, &f_pending, 0, 0, 1 },
{ "recursive", 'R', 0, &f_recursive, 0, 0, 1 },
{ "no-act", 0, 0, &f_noact, 0, 0, 1 },
{ 0, 'G', 0, &fc_downgrade, 0, 0, /* alias for --refuse */ 0 },
{ "selected-only", 'O', 0, &f_alsoselect, 0, 0, 0 },
- { "no-also-select", 'N', 0, &f_alsoselect, 0, 0, 0 /* fixme: remove eventually */ },
+ { "no-also-select", 'N', 0, &f_alsoselect, 0,0,0 /* fixme: remove sometime */ },
{ "skip-same-version", 'E', 0, &f_skipsame, 0, 0, 1 },
{ "auto-deconfigure", 'B', 0, &f_autodeconf, 0, 0, 1 },
{ "largemem", 0, 0, &f_largemem, 0, 0, 1 },
jmp_buf ejbuf;
int c;
const char *argp, *const *blongopts, *const *argvs;
+ static void (*actionfunction)(const char *const *argv);
if (setjmp(ejbuf)) { /* expect warning about possible clobbering of argv */
error_unwind(ehflag_bombout); exit(2);
setvbuf(stdout,0,_IONBF,0);
filesdbinit();
-
- switch (cipaction->arg) {
- case act_install: case act_unpack: case act_avail:
- checkpath();
- archivefiles(argv);
- break;
- case act_configure: case act_remove: case act_purge:
- checkpath();
- packages(argv);
- break;
- case act_listfiles: case act_status:
- enqperpackage(argv);
- break;
- case act_avreplace:
- availablefrompackages(argv,1);
- break;
- case act_avmerge:
- availablefrompackages(argv,0);
- break;
- case act_audit:
- audit(argv);
- break;
- case act_unpackchk:
- unpackchk(argv);
- break;
- case act_list:
- listpackages(argv);
- break;
- case act_search:
- searchfiles(argv);
- break;
- case act_assuppredep:
- assertsupportpredepends(argv);
- break;
- case act_predeppackage:
- predeppackage(argv);
- break;
- case act_printinstarch:
- if (printf("%s\n",architecture) == EOF) werr("stdout");
- if (fflush(stdout)) werr("stdout");
- break;
- case act_printarch:
- printarchitecture(argv);
- break;
- default:
- internerr("unknown action");
- }
+
+ actionfunction= (void (*)(const char* const*))cipaction->farg;
+
+ actionfunction(argv);
set_error_display(0,0);
error_unwind(ehflag_normaltidy);
};
enum action { act_unset, act_install, act_unpack, act_avail, act_configure,
- act_remove, act_purge, act_list, act_avreplace, act_avmerge,
- act_unpackchk, act_status, act_search, act_audit, act_listfiles,
- act_assuppredep, act_printarch, act_predeppackage,
- act_printinstarch };
+ act_remove, act_purge, act_listpackages, act_avreplace, act_avmerge,
+ act_unpackchk, act_status, act_searchfiles, act_audit, act_listfiles,
+ act_assertpredep, act_printarch, act_predeppackage, act_cmpversions,
+ act_printinstarch, act_compareversions, act_printavail, act_avclear };
enum conffopt {
cfof_prompt = 001,
/* from update.c */
-void availablefrompackages(const char *const *argv, int replace);
+void updateavailable(const char *const *argv);
/* from enquiry.c */
void unpackchk(const char *const *argv);
void searchfiles(const char *const *argv);
void enqperpackage(const char *const *argv);
-void assertsupportpredepends(const char *const *argv);
+void assertpredep(const char *const *argv);
void predeppackage(const char *const *argv);
-void printarchitecture(const char *const *argv);
+void printarch(const char *const *argv);
+void printinstarch(const char *const *argv);
+void cmpversions(const char *const *argv);
/* from packages.c, remove.c and configure.c */
int findbreakcycle(struct pkginfo *pkg, struct cyclesofarlink *sofar);
void describedepcon(struct varbuf *addto, struct dependency *dep);
-int versionsatisfied(struct pkginfoperfile *it, struct deppossi *against);
-int versionsatisfied3(const struct versionrevision *it,
- const struct versionrevision *ref,
- enum depverrel verrel);
-
#endif /* MAIN_H */
const char *thisarg;
int l;
+ checkpath();
modstatdb_init(admindir, f_noact ? msdbrw_readonly : msdbrw_needsuperuser);
if (f_pending) {
struct pkgiterator *it;
struct pkginfo *pkg, *conflictor, *otherpkg, *divpkg;
char *cidir, *cidirrest, *p;
- char pfilenamebuf[50], conffilenamebuf[MAXCONFFILENAME];
+ char pfilenamebuf[35], conffilenamebuf[MAXCONFFILENAME];
const char *pfilename, *newinfofilename;
struct fileinlist *newconff, **newconffileslastp, *newfileslist;
struct fileinlist *cfile;
&pkg,0,0);
if (cipaction->arg == act_avail) {
- printf("Read updated information about %s from %s.\n",pkg->name,pfilename);
+ printf("Recorded info about %s from %s.\n",pkg->name,pfilename);
pop_cleanup(ehflag_normaltidy);
return;
}
#include "main.h"
-void availablefrompackages(const char *const *argv, int replace) {
+void updateavailable(const char *const *argv) {
const char *sourcefile= argv[0];
- int count;
+ int count= 0;
static struct varbuf vb;
-
- if (!sourcefile || argv[1])
+
+ if (cipaction->arg == act_avclear) {
+ if (sourcefile)
+ badusage("--clear-avail takes no arguments");
+ } else if (!sourcefile || argv[1]) {
badusage("--%s needs exactly one Packages file argument", cipaction->olong);
+ }
if (!f_noact) {
if (access(admindir,W_OK)) {
lockdatabase(admindir);
}
- if (replace) {
+ switch (cipaction->arg) {
+ case act_avreplace:
printf("Replacing available packages info, using %s.\n",sourcefile);
- } else {
+ break;
+ case act_avmerge:
printf("Updating available packages info, using %s.\n",sourcefile);
+ break;
+ case act_avclear:
+ break;
+ default:
+ internerr("bad cipaction->arg in update available");
}
varbufaddstr(&vb,admindir);
varbufaddstr(&vb,"/" AVAILFILE);
varbufaddc(&vb,0);
-
- if (!replace)
+
+ if (cipaction->arg == act_avmerge)
parsedb(vb.buf, pdb_recordavailable|pdb_rejectstatus, 0,0,0);
- count= parsedb(sourcefile, pdb_recordavailable|pdb_rejectstatus, 0,0,0);
+ if (cipaction->arg != act_avclear)
+ count+= parsedb(sourcefile, pdb_recordavailable|pdb_rejectstatus, 0,0,0);
if (!f_noact) {
writedb(vb.buf,1,0);
unlockdatabase(admindir);
}
-
- printf("Information about %d package(s) was updated.\n",count);
+
+ if (cipaction->arg != act_avclear)
+ printf("Information about %d package(s) was updated.\n",count);
}
mount -rt nfs "$p_nfs" -o nosuid,nodev "$p_mountpoint"
fi
-case "$p_mountpoint" in
-*/ ) binaryprefix="$p_mountpoint" ;;
-'' ) binaryprefix="" ;;
-* ) binaryprefix="$p_mountpoint/" ;;
-esac
-
predep="$vardir/predep-package"
while true
do
echo
fi
+case "$hierbase" in
+/* ) ;;
+'' ) ;;
+* ) hierbase="/$hierbase" ;;
+esac
+
check_binary () {
# args: area-in-messages directory
- if ! [ -d "$mountpoint/$2" ]
+ if ! [ -d "$mountpoint$2" ]
then
echo "\`$2' does not exist."
return
fi
- if ! find "$mountpoint/$2" -follow -name '*.deb' -print \
+ if ! find "$mountpoint$2" -follow -name '*.deb' -print \
2>/dev/null | head -1 | grep . >/dev/null
then
echo "\`$2' does not contain any *.deb packages. Hmmpf."
defaultbinary="$4"
echo "
Which directory contains the *.deb packages from the $1 distribution
-area (this directory is named \`$3/binary' on the distribution site) ?"
- if [ $2 != main ]
+area (this directory is named \`$3/binary' on the distribution site) ?
+Say \`none' if this area is not available."
+ if [ $2 != main -a -z "$defaultbinary" ]
then
- if [ -z "$defaultbinary" ]
- then
- defaultbinary=none
- fi
- echo \
-"Say \`none' if this area is not available."
+ defaultbinary=none
fi
echo -n \
"Enter _$1_ binary dir. [$4]
then
response="$defaultbinary"
fi
- if [ none = "$response" -a $2 != main ]
+ if [ none = "$response" ]
then
break
fi
return to this installation procedure when you have done so: you will
find one Packages file and one Packages.gz file -- either will do --
in the \`binary' subdirectory of each area on the FTP sites and
-CD-ROMs.
+CD-ROMs. Alternatively (and this will be rather slow) I can scan the
+packages in the distribution area - say \`scan' if you want me to do so.
You need a separate Packages file from each of the distribution areas
you wish to install.
-Where is the _$1_ \`Packages' file (if none is available, say\`none')
+Where is the _$1_ \`Packages' file (if none is available, say \`none')
[$5]
? "
read response
case "$response" in
'') continue ;;
none) break ;;
+ scan) this_packages=scan ;;
/*) this_packages="$response" ;;
*) this_packages="/$response" ;;
esac
mount -rt nfs "$p_nfs" -o nosuid,nodev "$p_mountpoint"
fi
+updatetype=update
+
for f in main ctb nf lcl
do
eval 'this_packages=$p_'$f'_packages'
- if [ -z "$this_packages" ]; then continue; fi
- case "$p_mountpoint" in
- */ ) packagesfile="$p_mountpoint$this_packages" ;;
- '' ) packagesfile="$this_packages" ;;
- * ) packagesfile="$p_mountpoint/$this_packages" ;;
- esac
- case "$packagesfile" in
- *.gz | *.Z | *.GZ | *.z)
- echo -n "Uncompressing $packagesfile ... "
- zcat <"$packagesfile" >packages-$f
- echo done.
- dpkg --merge-avail packages-$f
- ;;
+ case "$this_packages" in
'')
+ continue
+ ;;
+ scan)
+ eval 'this_binary=$p_'$f'_binary'
+ if [ -z "$this_binary" ]; then continue; fi
+ if [ "$updatetype" = update ]
+ then
+ dpkg --clear-avail
+ updatetype=merge
+ fi
+ echo Running dpkg --record-avail -R "$p_mountpoint$this_binary"
+ dpkg --record-avail -R "$p_mountpoint$this_binary"
;;
*)
- dpkg --merge-avail "$packagesfile"
+ packagesfile="$p_mountpoint$this_packages"
+ case "$packagesfile" in
+ *.gz | *.Z | *.GZ | *.z)
+ echo -n "Uncompressing $packagesfile ... "
+ zcat <"$packagesfile" >packages-$f
+ echo done.
+ dpkg --$updatetype-avail packages-$f
+ updatetype=merge
+ ;;
+ '')
+ ;;
+ *)
+ dpkg --$updatetype-avail "$packagesfile"
+ updatetype=merge
+ ;;
+ esac
;;
- esac
+ esac
done
echo -n 'Update OK. Hit RETURN. '
set -e
+# Time-stamp: <96/05/03 13:59:41 root>
prog="`basename \"${0}\"`"
-version="1.1.5"; # This line modified by Makefile
+version="1.1.6"; # This line modified by Makefile
purpose="rename Debian packages to full package names"
license () {
echo "Usage: ${prog} file[s]
${purpose}
file.deb changes to <package>-<version>.<architecture>.deb
+ <package> is y/-/_/ aware
+ -a|--no-architecture No architecture part in filename
+ -o|--overwrite Overwrite if file exists
+ -s|--subdir [dir] Move file into subdir (Use with care)
+ -c|--create-dir Create target dir if not there (Use with care)
-h|--help|-v|--version|-l|--license Show help/version/license"
}
-rename () {
+fileexists () {
if [ -f "$1" ];
then
- if p=`dpkg-deb -f -- "$1" package`;
+ return 0;
+ else
+ stderr "can't find \`"$1"'";
+ return 1;
+ fi
+}
+
+getname () {
+ if p=`dpkg-deb -f -- "$1" package`;
+ then
+ p=`echo $p|sed -e 'y/-/_/'`;
+ v=`dpkg-deb -f -- "$1" version`;
+ r=`dpkg-deb -f -- "$1" revision`;
+ if [ -z "$r" ];
+ then
+ r=`dpkg-deb -f -- "$1" package_revision`;
+ fi
+
+ if [ -n "$r" ];
+ then
+ v=$v-$r;
+ fi
+
+ a=`dpkg-deb -f -- "$1" architecture`;
+ a=`echo $a|sed -e 's/ *//g'`;
+ if [ -z "$a" ]; # architecture field empty
+ then
+ a=`dpkg --print-architecture`;
+ stderr "assuming architecture \`"$a"' for \`"$1"'";
+ fi
+ if [ -z "$noarchitecture" ];
+ then
+ tname=$p-$v.$a.deb;
+ else
+ tname=$p-$v.deb
+ fi
+
+ name=`echo $tname|sed -e 's/ //g'`
+ if [ "$tname" != "$name" ]; # control fields have spaces
+ then
+ stderr "bad package control information for \`"$1"'"
+ fi
+ return 0;
+ fi
+}
+
+getdir () {
+ if [ -z "$destinationdir" ];
+ then
+ dir=`dirname "$1"`;
+ if [ -n "$subdir" ];
then
- p="$p-"`dpkg-deb -f -- "$1" version`;
- r=`dpkg-deb -f -- "$1" revision`;
- if [ -z "$r" ];
+ s=`dpkg-deb -f -- "$1" section`;
+ if [ -z "$s" ];
then
- r=`dpkg-deb -f -- "$1" package_revision`;
+ s="no-section";
+ stderr "assuming section \`"no-section"' for \`"$1"'";
fi
- if [ -n "$r" ];
+ if [ "$s" != "non-free" -a "$s" != "contrib" -a "$s" != "no-section" ];
then
- p=$p-$r;
+ dir=`echo unstable/binary-$a/$s`;
+ else
+ dir=`echo $s/binary-$a`;
fi
- a=`dpkg-deb -f -- "$1" architecture`;
- if [ -z "$a" ];
- then
- a=`dpkg --print-architecture`;
- stderr "assuming "$a" architecture for \`"$1"'";
- fi
- p=`echo \"$p\"|tr -ds -- '- ' _`
- p=`dirname "$1"`"/"$p.$a.deb
- if [ $p -ef "$1" ]; # same device and inode numbers
- then
- stderr "skipping \`"$1"'";
- elif [ -f $p ];
- then
- stderr "can't move \`"$1"' to existing file";
- elif `mv -- "$1" $p`;
+ fi
+ else
+ dir=$destinationdir;
+ fi
+}
+
+move () {
+ if fileexists "$arg";
+ then
+ getname "$arg";
+ getdir "$arg";
+ if [ ! -d "$dir" ];
+ then
+ if [ -n "$createdir" ];
then
- echo "moved \``basename "$1"`' to \`${p}'";
+ if `mkdir -p $dir`;
+ then
+ stderr "created directory \`$dir'";
+ else
+ stderr "failed creating directory \`$dir'";
+ exit 1;
+ fi
else
- stderr "hmm how did this happen?";
+ stderr "no such dir \`$dir'";
+ stderr "try --create-dir (-c) option";
+ exit 1;
fi
fi
- else
- stderr "can't deal with \`"$1"'";
+ newname=`echo $dir/$name`;
+ if [ $newname -ef "$1" ]; # same device and inode numbers
+ then
+ stderr "skipping \`"$1"'";
+ elif [ -f $newname -a -z "$overwrite" ];
+ then
+ stderr "can't move \`"$1"' to existing file";
+ elif `mv -- "$1" $newname`;
+ then
+ echo "moved \``basename "$1"`' to \`$newname'";
+ else
+ stderr "mkdir can be used to create directory";
+ exit 1;
+ fi
fi
}
if [ $# = 0 ]; then usage; exit 0; fi
for arg
do
+ if [ -n "$subdirset" ];
+ then
+ subdirset=0;
+ subdir=1;
+ if [ -d $arg ];
+ then
+ destinationdir=$arg;
+ continue
+ fi
+ fi
case "$arg" in
--version|-v) show_version; exit 0;;
--help|-[h?]) usage; exit 0;;
--licen[cs]e|-l) license; exit 0;;
+ --create-dir|-c) createdir=1;;
+ --subdir|-s) subdirset=1;;
+ --overwrite|-o) overwrite=1 ;;
+ --no-architecture|-a) noarchitecture=1 ;;
--) shift;
for arg
do
- rename "$arg";
+ move "$arg";
done; exit 0;;
- *) rename "$arg";;
+ *) move "$arg";;
esac
done
exit 0;
# Local variables:
# tab-width: 2
# End:
+
+dpkg-name.1:
+.\" This is an -*- nroff -*- source file.
+.\" dpkg-name and this manpage are Copyright 1995,1996 by Erick Branderhorst.
+.\"
+.\" This is free software; see the GNU General Public Licence version 2
+.\" or later for copying conditions. There is NO warranty.
+.\" Time-stamp: <96/05/03 14:00:06 root>
+.TH dpkg-name 1 "April 1996" "Debian Project" "Debian Linux"
+.SH NAME
+dpkg\-name \- rename Debian packages to full package names
+.SH SYNOPSIS
+.B dpkg\-name
+[\-a|\-\-no\-architecture] [\-o|\-\-overwrite] [\-s|\-\-subdir [dir]]
+[\-c|\-\-create\-dir] [\-h|\-\-help] [\-v|\-\-version]
+[\-l|\-\-license] [\-[--] [files]
+.SH DESCRIPTION
+.PP
+This manual page documents the
+.B dpkg\-name
+sh script which provides an easy way to rename
+.B Debian
+packages into their full package names. A full package name consists
+of <package>-<version>.<architecture>.deb as specified in the control
+file of the package. The <package> part of the filename will have
+hyphens "-" replaced by underscores "_". The <version> part of the
+filename consists of the mainstream version information optionally
+followed by a hyphen and the revision information.
+.SH EXAMPLES
+.TP
+.B dpkg-name bar-foo.deb
+The file `bar-foo.deb' will be renamed to bar_foo-1.0-2.i386.deb or
+something similar (depending on whatever information is in the control
+part of `bar-foo.deb').
+.TP
+.B find /root/debian/ \-name '*.deb' | xargs \-n 1 dpkg\-name -a
+All files with the extension `deb' in the directory /root/debian and its
+subdirectory's will be renamed by dpkg\-name if required into names with no
+architecture information.
+.TP
+.B find -name '*.deb' | xargs \-n 1 dpkg-name -a -o -s -c
+.B Don't do this.
+Your archive will be messed up completely because a lot of packages
+don't come with section information.
+.B Don't do this.
+.TP
+.B dpkg --build debian-tmp && dpkg-name -s .. debian-tmp.deb
+This can be used when building new packages.
+.SS OPTIONS
+.TP
+.B "\-a, \-\-no\-architecture"
+The destination filename will not have the architecture information.
+.TP
+.B "\-o, \-\-overwrite"
+Existing files will be overwritten if they have the same name as the
+destination filename.
+.TP
+.B "\-s, \-\-subdir [dir]"
+Files will be moved into subdir. If directory given as argument exists
+the files will be moved into that direcotory otherswise the name of
+the target directory is extracted from the section field in the
+control part of the package. The target directory will be
+`unstable/binary-<architecture>/<section>'. If the section is
+`non-free', `contrib' or no section information is found in the
+control file the target directory is
+`<section>/binary-<architecture>'. The section field isn't required so
+a lot of packages will find their way to the `no-section' area. Use
+this option with care, it's messy.
+.TP
+.B "\-c, \-\-create\-dir"
+This option can used together with the \-s option. If a target
+directory isn't found it will be created automatically.
+.B Use this option with care.
+.TP
+.B "\-h, \-\-help"
+Print a usage message and exit successfully.
+.TP
+.B "\-v, \-\-version"
+Print version information and exit successfully.
+.TP
+.B "\-l, \-\-license"
+Print copyright information and (a reference to GNU) license
+information and exit successfully.
+.SH BUGS?
+Successfully tested on
+.B Debian Linux
+systems only. Some packages don't follow the name structure
+<package>-<version>.<architecture>.deb. Packages renamed by dpkg-name
+will follow this structure. Generally this will have no impact on how
+packages are installed by dselect/dpkg.
+.SH SEE ALSO
+.BR deb (5),
+.BR deb-control (5),
+.BR dpkg (5),
+.BR dpkg (8),
+.BR dpkg-deb (8).
+.SH COPYRIGHT
+Copyright 1995,1996 Erick Branderhorst.
+.B dpkg-name
+is free software; see the GNU General Public Licence version 2 or
+later for copying conditions. There is
+.B no
+warranty.
# The noverride file is a series of lines of the form
# <package> <priority> <section> <maintainer>
# where the <maintainer> field is optional. Fields are separated by
-# whitespace.
+# whitespace. The <maintainer> field may be <old-maintainer> => <new-maintainer>
+# (this is recommended).
-$version= '1.0.10'; # This line modified by Makefile
+$version= '1.0.12'; # This line modified by Makefile
%kmap= ('optional','suggests',
'recommended','recommends',
print(STDERR "\n") || die $!;
}
-@inover=();
@samemaint=();
open(O,"<$override") || die $!;
while(<O>) {
s/\s+$//;
($p,$priority,$section,$maintainer)= split(/\s+/,$_,4);
- if (!defined($p1{$p})) {
- push(@inover,$p);
- next;
- }
+ next unless defined($p1{$p});
if (length($maintainer)) {
- if ($pv{$p,'maintainer'} eq $maintainer) {
+ if ($maintainer =~ m/\s*=\>\s*/) {
+ $oldmaint= $`; $newmaint= $';
+ if ($pv{$p,'maintainer'} ne $oldmaint) {
+ push(@changedmaint,
+ " $p (package says $pv{$p,'maintainer'}, not $oldmaint)\n");
+ } else {
+ $pv{$p,'maintainer'}= $newmaint;
+ }
+ } elsif ($pv{$p,'maintainer'} eq $maintainer) {
push(@samemaint," $p ($maintainer)\n");
} else {
$pv{$p,'maintainer'}= $maintainer;
&writelist("** Packages in archive but missing from override file: **",
@missingover);
-&writelist("++ Packages appearing in override file but not in archive: ++",
- @inover);
+if (@changedmaint) {
+ print(STDERR
+ " ++ Packages in override file with incorrect old maintainer value: ++\n",
+ @changedmaint,
+ "\n") || die $!;
+}
if (@samemaint) {
print(STDERR
" -- Packages specifying same maintainer as override file: --\n",
--- /dev/null
+#!/usr/bin/perl --
+# usage:
+# dpkg-scanpackages .../binary .../noverride pathprefix >.../Packages.new
+# mv .../Packages.new .../Packages
+#
+# This is the core script that generates Packages files (as found
+# on the Debian FTP site and CD-ROMs).
+#
+# The first argument should preferably be a relative filename, so that
+# the Filename field has good information.
+#
+# Any desired string can be prepended to each Filename value by
+# passing it as the third argument.
+#
+# The noverride file is a series of lines of the form
+# <package> <priority> <section> <maintainer>
+# where the <maintainer> field is optional. Fields are separated by
+# whitespace. The <maintainer> field may be <old-maintainer> => <new-maintainer>
+# (this is recommended).
+
+$version= '1.0.12'; # This line modified by Makefile
+
+%kmap= ('optional','suggests',
+ 'recommended','recommends',
+ 'class','priority',
+ 'package_revision','revision');
+
+%pri= ('priority',300,
+ 'section',290,
+ 'maintainer',280,
+ 'version',270,
+ 'depends',250,
+ 'recommends',240,
+ 'suggests',230,
+ 'conflicts',220,
+ 'provides',210,
+ 'filename',200,
+ 'size',180,
+ 'md5sum',170,
+ 'description',160);
+
+@ARGV==3 || die;
+
+$binarydir= shift(@ARGV);
+-d $binarydir || die $!;
+
+$override= shift(@ARGV);
+-e $override || die $!;
+
+$pathprefix= shift(@ARGV);
+
+open(F,"find $binarydir -name '*.deb' -print |") || die $!;
+while (<F>) {
+ chop($fn=$_);
+ substr($fn,0,length($binarydir)) eq $binarydir || die $fn;
+ open(C,"dpkg-deb -I $fn control |") || die "$fn $!";
+ $t=''; while (<C>) { $t.=$_; }
+ $!=0; close(C); $? && die "$fn $? $!";
+ undef %tv;
+ $o= $t;
+ while ($t =~ s/^\n*(\S+):[ \t]*(.*(\n[ \t].*)*)\n//) {
+ $k= $1; $v= $2;
+ $k =~ y/A-Z/a-z/;
+ if (defined($kmap{$k})) { $k= $kmap{$k}; }
+ $v =~ s/\s+$//;
+ $tv{$k}= $v;
+#print STDERR "K>$k V>$v<\n";
+ }
+ $t =~ m/^\n*$/ || die "$fn $o / $t ?";
+ defined($tv{'package'}) || die "$fn $o ?";
+ $p= $tv{'package'}; delete $tv{'package'};
+ defined($p1{$p}) && die "$fn $p repeat";
+ if (defined($tv{'filename'})) {
+ print(STDERR " ! Package $p (filename $fn) has Filename field !\n") || die $!;
+ }
+ $tv{'filename'}= "$pathprefix$fn";
+ open(C,"md5sum <$fn |") || die "$fn $!";
+ chop($_=<C>); m/^[0-9a-f]{32}$/ || die "$fn \`$_' $!";
+ $!=0; close(C); $? && die "$fn $? $!";
+ $tv{'md5sum'}= $_;
+ defined(@stat= stat($fn)) || die "$fn $!";
+ $stat[7] || die "$fn $stat[7]";
+ $tv{'size'}= $stat[7];
+ if (length($tv{'revision'})) {
+ $tv{'version'}.= '-'.$tv{'revision'};
+ delete $tv{'revision'};
+ }
+ for $k (keys %tv) {
+ $pv{$p,$k}= $tv{$k};
+ $k1{$k}= 1;
+ $p1{$p}= 1;
+ }
+ $_= substr($fn,length($binarydir));
+ s#/[^/]+$##; s#^/*##;
+ $psubdir{$p}= $_;
+ $pfilename{$p}= $fn;
+}
+$!=0; close(F); $? && die "$? $!";
+
+select(STDERR); $= = 1000; select(STDOUT);
+
+format STDERR =
+ ^<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
+$packages
+.
+
+sub writelist {
+ $title= shift(@_);
+ return unless @_;
+ print(STDERR " $title\n") || die $!;
+ $packages= join(' ',sort @_);
+ while (length($packages)) { write(STDERR) || die $!; }
+ print(STDERR "\n") || die $!;
+}
+
+@samemaint=();
+
+open(O,"<$override") || die $!;
+while(<O>) {
+ s/\s+$//;
+ ($p,$priority,$section,$maintainer)= split(/\s+/,$_,4);
+ next unless defined($p1{$p});
+ if (length($maintainer)) {
+ if ($maintainer =~ m/\s*=\>\s*/) {
+ $oldmaint= $`; $newmaint= $';
+ if ($pv{$p,'maintainer'} ne $oldmaint) {
+ push(@changedmaint," $p ($pv{$p,'maintainer'}, not $oldmaint)\n");
+ } else {
+ $pv{$p,'maintainer'}= $newmaint;
+ }
+ } elsif ($pv{$p,'maintainer'} eq $maintainer) {
+ push(@samemaint," $p ($maintainer)\n");
+ } else {
+ $pv{$p,'maintainer'}= $maintainer;
+ }
+ }
+ $pv{$p,'priority'}= $priority;
+ $pv{$p,'section'}= $section;
+ if (length($psubdir{$p}) && $section ne $psubdir{$p}) {
+ print(STDERR " !! Package $p has \`Section: $section',".
+ " but file is in \`$psubdir{$p}' !!\n") || die $!;
+ $ouches++;
+ }
+ $o1{$p}= 1;
+}
+close(O);
+
+if ($ouches) { print(STDERR "\n") || die $!; }
+
+$k1{'maintainer'}= 1;
+$k1{'priority'}= 1;
+$k1{'section'}= 1;
+
+@missingover=();
+
+for $p (sort keys %p1) {
+ if (!defined($o1{$p})) {
+ push(@missingover,$p);
+ }
+ $r= "Package: $p\n";
+ for $k (sort { $pri{$b} <=> $pri{$a} } keys %k1) {
+ next unless length($pv{$p,$k});
+ $r.= "$k: $pv{$p,$k}\n";
+ }
+ $r.= "\n";
+ $written++;
+ print(STDOUT $r) || die $!;
+}
+close(STDOUT) || die $!;
+
+&writelist("** Packages in archive but missing from override file: **",
+ @missingover);
+<<<<<<< dpkg-scanpackages.pl
+||||||| /usr/ian-home/junk/u
+&writelist("++ Packages appearing in override file but not in archive: ++",
+ @inover);
+=======
+&writelist("++ Packages appearing in override file but not in archive: ++",
+ @inover);
+if (@changedmaint) {
+ print(STDERR
+ " ++ Packages in override file with incorrect old maintainer value: ++\n",
+ @changedmaint,
+ "\n") || die $!;
+}
+>>>>>>> /usr/ian-home/junk/t
+if (@samemaint) {
+ print(STDERR
+ " -- Packages specifying same maintainer as override file: --\n",
+ @samemaint,
+ "\n") || die $!;
+}
+
+print(STDERR " Wrote $written entries to output Packages file.\n") || die $!;
-#define DPKG_VERSION "1.2.0" /* This line modified by Makefile */
+#define DPKG_VERSION "1.2.1" /* This line modified by Makefile */