Browse Source

My changes:

* Added support for task description files.
  * Read in /usr/share/tasksel/debian-tasks.desc as a task description
    file.
  * Added makedesc.pl, a program to generate a task description file from
    a set of task descriptions.
  * Got rid of all the name prettification code since it is no longer used
    anyway.
  * Killed filterdescription, the task packages in woody actually don't
    have that problem anymore.
  * Don't move cursor to the right after a task is selected.
  * Removed unused tasksel.man from source package (keep pod).
  * Fixed an obscure bug if a task package happened to be the last thing in
    the available file.
  * Enable debug mode by default, but turn it off when building from the
    rules file.

Aj's changes:
  * Use "Section:" fields to break tasks into different sections. Have a
    hardcoded list of default sections, with a defined order; remaining
    sections get added to the end, in alphabetical order. Sections that
    don't match "tasks-*" are ignored.
  * "tasksel install foo bar baz" as a replacement for "apt-get install
    task-foo task-bar task-baz"
  * Increase the size of the "apt-get install" command line buffer.
tags/debian_version_1_4
Joey Hess 20 years ago
parent
commit
9aadd503b5
16 changed files with 530 additions and 363 deletions
  1. +18
    -5
      Makefile
  2. +12
    -6
      README
  3. +2
    -2
      TODO
  4. +132
    -74
      data.c
  5. +7
    -6
      data.h
  6. +34
    -0
      debian/changelog
  7. +1
    -1
      debian/control
  8. +1
    -0
      debian/dirs
  9. +1
    -1
      debian/rules
  10. +57
    -0
      makedesc.pl
  11. +212
    -37
      slangui.c
  12. +11
    -0
      tasks/demo
  13. +11
    -0
      tasks/demo2
  14. +29
    -4
      tasksel.c
  15. +0
    -226
      tasksel.man
  16. +2
    -1
      tasksel.pod

+ 18
- 5
Makefile View File

@@ -1,8 +1,17 @@
PROGRAM=tasksel
VERSION=\"1.0\"
TASKDESC=debian-tasks.desc
DESCDIR=tasks/
VERSION=1.3
CC=gcc
CFLAGS=-g -Wall #-Os
DEFS=-DVERSION=$(VERSION) -DPACKAGE=\"$(PROGRAM)\" -DLOCALEDIR=\"/usr/share/locale\" -DDEBUG
DEBUG=1
ifeq (0,$(DEBUG))
DEFS=-DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PROGRAM)\" -DLOCALEDIR=\"/usr/share/locale\" \
-DTASKDESC=\"/usr/share/tasksel/$(TASKDESC)\"
else
DEFS=-DVERSION=\"$(VERSION)\" -DPACKAGE=\"$(PROGRAM)\" -DLOCALEDIR=\"/usr/share/locale\" \
-DTASKDESC=\"$(TASKDESC)\" -DDEBUG
endif
LIBS=-lslang #-lccmalloc -ldl
OBJS=tasksel.o slangui.o data.o util.o strutl.o
LANGS=cs de hu ja sv pl ru
@@ -11,7 +20,10 @@ LOCALEDIR=$(DESTDIR)/usr/share/locale
COMPILE = $(CC) $(CFLAGS) $(DEFS) -c
LINK = $(CC) $(CFLAGS) $(DEFS) -o

all: $(PROGRAM)
all: $(PROGRAM) $(TASKDESC)

$(TASKDESC):
perl makedesc.pl $(DESCDIR) $(TASKDESC)

%.o: %.c
$(COMPILE) $<
@@ -24,7 +36,8 @@ $(PROGRAM): $(OBJS) po/build_stamp

install:
install -m 755 tasksel $(DESTDIR)/usr/bin
pod2man --center "Debian specific manpage" tasksel.pod | gzip -9c > $(DESTDIR)/usr/share/man/man8/tasksel.8.gz
install -m 0644 $(TASKDESC) $(DESTDIR)/usr/share/tasksel
pod2man --center "Debian specific manpage" --release $(VERSION) tasksel.pod | gzip -9c > $(DESTDIR)/usr/share/man/man8/tasksel.8.gz
for lang in $(LANGS); do \
[ ! -d $(LOCALEDIR)/$$lang/LC_MESSAGES/ ] && mkdir -p $(LOCALEDIR)/$$lang/LC_MESSAGES/; \
install -m 644 po/$$lang.mo $(LOCALEDIR)/$$lang/LC_MESSAGES/$(PROGRAM).mo; \
@@ -34,6 +47,6 @@ test:
$(MAKE) -C scratch

clean:
rm -f $(PROGRAM) *.o *~
rm -f $(PROGRAM) $(TASKDESC) *.o *~
$(MAKE) -C po clean


+ 12
- 6
README View File

@@ -1,4 +1,4 @@
$Id: README,v 1.1 1999/11/21 22:01:04 tausq Exp $
$Id: README,v 1.2 2001/05/18 02:02:02 joeyh Rel $
Task Selection UI v0.1
Nov 20, 1999
Randolph Chung <tausq@debian.org>
@@ -8,11 +8,17 @@ Here's a first cut at a task selection user interface.
The interface GUI is based on libslang. It has no other special library
dependencies.

On startup, the tasksel program will read /var/lib/dpkg/available to
identify task packages (matching "task-*"). These packages will be
presented in a simple list selection screen with their short descriptions.
Users can drill down into the task packages to see detailed descriptions and
some information about the packages in the task.
On startup, the tasksel program will read
/usr/share/tasksel/debian-tasks.desc for information about what tasks are
available and their descriptions and sections. Next it will read
/var/lib/dpkg/available. Task: fields in that file can be used to state
that a package belongs to a task or tasks. Also, the package names are used
to identify task packages (matching "task-*").

The tasks will be presented in a simple list selection screen with
their short descriptions. Users can drill down into the tasks to
see detailed descriptions and some information about the packages in the
task.

On exit, tasksel executes the appropriate apt-get command to install the
selected packages. If the -t option is given, then tasksel prints out the


+ 2
- 2
TODO View File

@@ -1,5 +1,5 @@
$Id: TODO,v 1.6 2000/01/16 02:55:30 tausq Exp $
$Id: TODO,v 1.7 2001/05/18 02:02:02 joeyh Rel $
- fix screen resize code (in dialogs, it doesn't work right)
- figure out how to fix get the help text i18n'ized
- figure out how to properly install the i18n stuff
- show already installed task packages
- show already installed tasks

+ 132
- 74
data.c View File

@@ -1,4 +1,4 @@
/* $Id: data.c,v 1.9 2001/04/24 06:35:07 tausq Exp $ */
/* $Id: data.c,v 1.10 2001/05/18 02:02:02 joeyh Exp $ */
/* data.c - encapsulates functions for reading a package listing like dpkg's available file
* Internally, packages are stored in a binary tree format to faciliate search operations
*/
@@ -21,6 +21,7 @@
#define SUGGESTSFIELD "Suggests: "
#define DESCRIPTIONFIELD "Description: "
#define PRIORITYFIELD "Priority: "
#define SECTIONFIELD "Section: "
#define STATUSFIELD "Status: "
#define AVAILABLEFILE "/var/lib/dpkg/available"
#define STATUSFILE "/var/lib/dpkg/status"
@@ -68,6 +69,7 @@ static void tasks_walk_enumerate(const void *nodep, const VISIT order, const int
}
}


static int taskcompare(const struct task_t *l, const struct task_t *r)
{
return strcmp(l->name, r->name);
@@ -82,7 +84,6 @@ static void tasks_walk_delete(const void *nodep, const VISIT order, const int de
if (order == leaf || order == endorder) {
tdelete((void *)datap, &_tasks_root, taskcompare);
if (datap->name) FREE(datap->name);
if (datap->prettyname) FREE(datap->prettyname);
if (datap->packages) {
for (i = 0; i < datap->packagescount; i++) FREE(datap->packages[i]);
FREE(datap->packages);
@@ -144,19 +145,6 @@ static int splitlinkdesc(const char *desc, char ***array)
return elts;
}

static const char *filterdescription(const char *descin)
{
/* !!!!!TODO!!!!!!!!!
* This is a very ugly hack. It exists here until the package descriptions
* are properly fixed. :-(
*/
if (strstr(descin, "Metapackage for ") || strstr(descin, "metapackage for "))
return (descin+16);
else
return descin;
}


static struct task_t *addtask(
struct tasks_t *tasks,
const char *taskname,
@@ -170,9 +158,6 @@ static struct task_t *addtask(
if (result) {
task = *(struct task_t**)result;
} else {
int space = 1;
char *c;

task = NEW(struct task_t);
task->name = STRDUP(taskname);
task->task_pkg = NULL;
@@ -180,24 +165,6 @@ static struct task_t *addtask(
task->packagesmax = 10;
task->packagescount = 0;
task->selected = 0;
c = task->prettyname = STRDUP(taskname);

/* Prettify name */
while (c[0]) {
if (c[0] == '-') {
c[0] = ' ';
space=1;
}
else if (space) {
c[0] = toupper(c[0]);
space=0;
}
c++;
}
/* Keep track of the longest name. */
if (tasks->maxnamelen < (c - task->prettyname))
tasks->maxnamelen = c - task->prettyname;

tsearch(task, &tasks->tasks, taskcompare);
tasks->count++;
}
@@ -224,46 +191,26 @@ static struct task_t *addtask(
}

static struct package_t *addpackage(
struct packages_t *pkgs,
struct packages_t *pkgs,
const char *name, const char *dependsdesc,
const char *recommendsdesc, const char *suggestsdesc,
const char *shortdesc, const char *longdesc,
const priority_t priority, const int istask)
const priority_t priority)
{
/* Adds package to the package list binary tree */
struct package_t *node = NEW(struct package_t);
void *p;
char *c;
char space=1;
VERIFY(name != NULL);
/* DPRINTF("Adding package %s to list\n", name); */
memset(node, 0, sizeof(struct package_t));
node->name = STRDUP(name);
if (istask) {
c = node->prettyname = STRDUP(name+5);
/* Prettify name */
while (c[0]) {
if (c[0] == '-') {
c[0] = ' ';
space=1;
}
else if (space) {
c[0] = toupper(c[0]);
space=0;
}
c++;
}
/* Keep track of the longest name. */
if (pkgs->maxnamelen < (c - node->prettyname))
pkgs->maxnamelen = c - node->prettyname;
}
node->shortdesc = STRDUP(shortdesc);
node->longdesc = STRDUP(longdesc);
node->priority = priority;
node->section = NULL;
node->pseudopackage = 0;

if (dependsdesc) node->dependscount = splitlinkdesc(dependsdesc, &node->depends);
if (recommendsdesc) node->recommendscount = splitlinkdesc(recommendsdesc, &node->recommends);
@@ -293,6 +240,22 @@ struct package_t *packages_find(const struct packages_t *pkgs, const char *name)
return *(struct package_t **)result;
}

struct task_t *tasks_find(const struct tasks_t *tasks, const char *name)
{
/* Given a task name, returns a pointer to the appropriate task_t
* structure or NULL if none is found */
struct task_t task;
void *result;

task.name = (char *)name;
result = tfind((void *)&task, &tasks->tasks, taskcompare);

if (result == NULL)
return NULL;
else
return *(struct task_t **)result;
}

struct package_t **packages_enumerate(const struct packages_t *packages)
{
/* Converts a packages binary tree into an array */
@@ -318,6 +281,8 @@ struct task_t **tasks_enumerate(const struct tasks_t *tasks)
_tasks_enumcount = 0;
twalk((void *)tasks->tasks, tasks_walk_enumerate);
ASSERT(_tasks_enumcount == tasks->count);
qsort(_tasks_enumbuf, tasks->count, sizeof(struct task_t *),
taskcompare);
return _tasks_enumbuf;
}

@@ -327,13 +292,98 @@ static void walktasks(const void *t, const VISIT which, const int depth)
int i;

if (which == postorder || which == leaf) {
fprintf(stderr, "Task %s:\n", task->prettyname);
fprintf(stderr, "Task %s [%s]:\n", task->name,
(task->task_pkg ? task->task_pkg->section : "misc"));
for (i = 0; i < task->packagescount; i++) {
fprintf(stderr, " %s\n", task->packages[i]);
}
}
}

void taskfile_read(char *fn, struct tasks_t *tasks, struct packages_t *pkgs)
{
/* Reads a task definition file, and populates internal data structures
* with information about the tasks defined therein.
*
* The format of the task definition file is a series of stanzas,
* seperated by blank lines. Each stanza is in rfc-822 format, and
* contains fields named Task, Description (with extended desc), and
* Section. (The information about what packages belong in a task is
* contained in Task fields in the Packages file.) */
FILE *f;
char buf[BUF_SIZE];
char *task, *shortdesc, *longdesc, *section;

if ((f = fopen(fn, "r")) == NULL) PERROR(fn);
while (!feof(f)) {
fgets(buf, BUF_SIZE, f);
CHOMP(buf);
if (MATCHFIELD(buf, TASKFIELD)) {
shortdesc = longdesc = section = NULL;
task = STRDUP(FIELDDATA(buf, TASKFIELD));
VERIFY(task != NULL);
while (!feof(f)) {
fgets(buf, BUF_SIZE, f);
CHOMP(buf);
if (buf[0] == 0) break;

if (MATCHFIELD(buf, SECTIONFIELD)) {
section = STRDUP(FIELDDATA(buf, SECTIONFIELD));
} else if (MATCHFIELD(buf, DESCRIPTIONFIELD)) {
shortdesc = STRDUP(FIELDDATA(buf, DESCRIPTIONFIELD));
VERIFY(shortdesc != NULL);
do {
if (fgets(buf, BUF_SIZE, f) == 0)
break;
if (buf[0] != ' ') break;
if (buf[1] == '.') buf[1] = ' ';
if (longdesc == NULL) {
longdesc = (char *)MALLOC(strlen(buf) + 1);
strcpy(longdesc, buf + 1);
} else {
longdesc = realloc(longdesc, strlen(longdesc) + strlen(buf) + 1);
strcat(longdesc, buf + 1);
}
} while (buf[0] != '\n' && !feof(f));
break;
}
}
/* packages_readlist must be called before this function, so we can
* tell if any packages are in this task, and ignore it if none are. */
if (tasks_find(tasks, task)) {
struct package_t *p;
struct task_t *t;
char *package;

/* This is a fake package to go with the task. I add the task-
* prefix to the package name to ensure that adding this fake
* package stomps on the toes of no real package. */
/* FIXME: It should not be necessary to do this; instead task_t
* should include description and section fields and not need an
* associated package. */
package = MALLOC(strlen(task) + 6);
package = STRDUP("task-");
strcat(package, task);
p = addpackage(pkgs, package, NULL, NULL, NULL, shortdesc, longdesc,
PRIORITY_UNKNOWN);
p->section = STRDUP(section);
p->pseudopackage = 1;
t = addtask(tasks, task, "");
t->task_pkg = p;
};

if (task != NULL) FREE(task);
if (shortdesc != NULL) FREE(shortdesc);
if (longdesc != NULL) FREE(longdesc);
if (section != NULL) FREE(section);
}
}
fclose(f);
}
void packages_readlist(struct tasks_t *tasks, struct packages_t *pkgs)
{
/* Populates internal data structures with information from an available
@@ -342,21 +392,16 @@ void packages_readlist(struct tasks_t *tasks, struct packages_t *pkgs)
char buf[BUF_SIZE];
char *name, *shortdesc, *longdesc;
char *dependsdesc, *recommendsdesc, *suggestsdesc, *prioritydesc, *taskdesc;
char *section;
priority_t priority;
VERIFY(pkgs != NULL); VERIFY(tasks != NULL);
/* Initialization */
memset(pkgs, 0, sizeof(struct packages_t));
memset(tasks, 0, sizeof(struct tasks_t));

if ((f = fopen(AVAILABLEFILE, "r")) == NULL) PERROR(AVAILABLEFILE);
while (!feof(f)) {
fgets(buf, BUF_SIZE, f);
CHOMP(buf);
if (MATCHFIELD(buf, PACKAGEFIELD)) {
/*DPRINTF("Package = %s\n", FIELDDATA(buf, PACKAGEFIELD)); */
name = shortdesc = longdesc = taskdesc = dependsdesc = recommendsdesc = suggestsdesc = NULL;
name = shortdesc = longdesc = taskdesc = dependsdesc = recommendsdesc = suggestsdesc = section = NULL;
priority = PRIORITY_UNKNOWN;
name = STRDUP(FIELDDATA(buf, PACKAGEFIELD));
@@ -380,6 +425,8 @@ void packages_readlist(struct tasks_t *tasks, struct packages_t *pkgs)
} else if (MATCHFIELD(buf, SUGGESTSFIELD)) {
suggestsdesc = STRDUP(FIELDDATA(buf, SUGGESTSFIELD));
VERIFY(suggestsdesc != NULL);
} else if (MATCHFIELD(buf, SECTIONFIELD)) {
section = STRDUP(FIELDDATA(buf, SECTIONFIELD));
} else if (MATCHFIELD(buf, PRIORITYFIELD)) {
prioritydesc = FIELDDATA(buf, PRIORITYFIELD);
if (strcmp(prioritydesc, "required") == 0) {
@@ -397,7 +444,8 @@ void packages_readlist(struct tasks_t *tasks, struct packages_t *pkgs)
shortdesc = STRDUP(FIELDDATA(buf, DESCRIPTIONFIELD));
VERIFY(shortdesc != NULL);
do {
fgets(buf, BUF_SIZE, f);
if (fgets(buf, BUF_SIZE, f) == 0)
break;
if (buf[0] != ' ') break;
if (buf[1] == '.') buf[1] = ' ';
if (longdesc == NULL) {
@@ -414,14 +462,23 @@ void packages_readlist(struct tasks_t *tasks, struct packages_t *pkgs)

if (strncmp(name, "task-", 5) != 0) {
addpackage(pkgs, name, NULL, NULL, NULL, shortdesc,
NULL, priority, 0);
NULL, priority);
} else {
struct package_t *p;
struct task_t *t;
int i;
p = addpackage(pkgs, name, dependsdesc, recommendsdesc,
suggestsdesc, filterdescription(shortdesc),
longdesc, priority, 0);
suggestsdesc, shortdesc,
longdesc, priority);
#if 1
if (strncmp(section, "tasks-", 6) == 0) {
p->section = STRDUP(section+6);
} else {
p->section = "junk";
}
#else
p->section = STRDUP(section);
#endif
t = addtask(tasks, name+5, "");
t->task_pkg = p;
for (i = 0; i < p->dependscount; i++) {
@@ -449,16 +506,17 @@ void packages_readlist(struct tasks_t *tasks, struct packages_t *pkgs)
if (taskdesc != NULL) FREE(taskdesc);
if (shortdesc != NULL) FREE(shortdesc);
if (longdesc != NULL) FREE(longdesc);
if (section != NULL) FREE(section);
}
};
fclose(f);

twalk(tasks->tasks, walktasks);
/*twalk(tasks->tasks, walktasks);*/
}

void packages_free(struct tasks_t *tasks, struct packages_t *pkgs)
{
/* Frees up memory allocated by packages_readlist */
/* Frees up memory allocated by taskfile_read and packages_readlist */
_tasks_root = tasks->tasks;
twalk(tasks->tasks, tasks_walk_delete);


+ 7
- 6
data.h View File

@@ -1,4 +1,4 @@
/* $Id: data.h,v 1.5 2001/04/24 06:35:07 tausq Exp $ */
/* $Id: data.h,v 1.6 2001/05/18 02:02:02 joeyh Exp $ */
#ifndef _DATA_H
#define _DATA_H

@@ -13,7 +13,6 @@ typedef enum {

struct package_t {
char *name;
char *prettyname;
char *shortdesc;
char *longdesc;
int dependscount;
@@ -22,19 +21,19 @@ struct package_t {
char **recommends;
int suggestscount;
char **suggests;
char *section;
priority_t priority;
int selected;
int pseudopackage;
};

struct packages_t {
int count;
int maxnamelen;
void *packages;
};

struct task_t {
char *name;
char *prettyname;
struct package_t *task_pkg;
char **packages;
int packagescount;
@@ -44,16 +43,18 @@ struct task_t {

struct tasks_t {
int count;
int maxnamelen;
void *tasks;
};

/* Reads in a list of package and package descriptions */
/* Reads in a list of tasks from task description file */
void taskfile_read(char *fn, struct tasks_t *tasks, struct packages_t *pkgs);
/* Reads in a list of package and package descriptions from available file */
void packages_readlist(struct tasks_t *tasks, struct packages_t *packages);
/* free memory allocated to store packages */
void packages_free(struct tasks_t *tasks, struct packages_t *packages);

struct package_t *packages_find(const struct packages_t *packages, const char *name);
struct task_t *tasks_find(const struct tasks_t *tasks, const char *name);
struct package_t **packages_enumerate(const struct packages_t *packages);
struct task_t **tasks_enumerate(const struct tasks_t *tasks);



+ 34
- 0
debian/changelog View File

@@ -1,3 +1,37 @@
tasksel (1.3-1) unstable; urgency=low

* Added support for task description files.
* Read in /usr/share/tasksel/debian-tasks.desc as a task description
file.
* Added makedesc.pl, a program to generate a task description file from
a set of task descriptions.
* Got rid of all the name prettification code since it is no longer used
anyway.
* Killed filterdescription, the task packages in woody actually don't
have that problem anymore.
* Don't move cursor to the right after a task is selected.
* Removed unused tasksel.man from source package (keep pod).
* Fixed an obscure bug if a task package happened to be the last thing in
the available file.
* Enable debug mode by default, but turn it off when building from the
rules file.

-- Joey Hess <joeyh@debian.org> Thu, 17 May 2001 14:47:06 -0400

tasksel (1.2-1) unstable; urgency=low

* Use "Section:" fields to break tasks into different sections. Have a
hardcoded list of default sections, with a defined order; remaining
sections get added to the end, in alphabetical order. Sections that
don't match "tasks-*" are ignored.

* "tasksel install foo bar baz" as a replacement for "apt-get install
task-foo task-bar task-baz"

* Increase the size of the "apt-get install" command line buffer.

-- Anthony Towns <aj@azure.humbug.org.au> Tue, 15 May 2001 15:02:01 +1000

tasksel (1.1-1) unstable; urgency=low

* Support "Task:" headers to include a package in a task.


+ 1
- 1
debian/control View File

@@ -2,7 +2,7 @@ Source: tasksel
Section: base
Priority: optional
Maintainer: Randolph Chung <tausq@debian.org>
Standards-Version: 3.0.1.1
Standards-Version: 3.5.4.0

Package: tasksel
Architecture: any


+ 1
- 0
debian/dirs View File

@@ -1,3 +1,4 @@
usr/bin
usr/share/man/man8
usr/share/locale
usr/share/tasksel

+ 1
- 1
debian/rules View File

@@ -21,7 +21,7 @@ build-stamp:
dh_testdir

# Add here commands to compile the package.
$(MAKE)
$(MAKE) DEBUG=0

touch build-stamp



+ 57
- 0
makedesc.pl View File

@@ -0,0 +1,57 @@
#!/usr/bin/perl
#
# makedesc directory file
#
# Scan the directory for files, and use the files to generate a task
# description file. The format of the task description file is described in
# tata.c. The format of the input files is:
#
# Task: desktop
# Section: user
# Description: Provide a basic GUI system
# This task provides functionality for a basic desktop; whether Gnome
# based, KDE based or customised. With this task, your system will boot
# into a graphical login screen, at which point you can choose which of
# these desktops you wish to use on a per-user basis. You can further
# customise your desktop once installed.
# Packages:
# kdebase
# gdm
# ...
#
# Hash-comments are allowed in the files, but must be on their own lines.

my $dir=shift or die "no directory specified\n";
my $file=shift or die "no file specified\n";

open (OUT, ">$file") or die ">$file: $!";

use File::Find;
find(\&processfile, $dir);

sub processfile {
return unless /^[-_.A-Za-z0-9]+$/ and -f $_;
open (IN, $_) or die "$_: $!";
my %fields;
my $field="";
while (<IN>) {
chomp;
next if /^\s*#/;

if (/^\s/) {
$fields{$field}.="\n$_";
}
else {
($field, my $value)=split(/:\s*/, $_, 2);
$field=lc($field);
$fields{$field}=$value;
}
}
close IN;

print OUT map { ucfirst($_).": ".$fields{$_}."\n" }
qw{task section description};
print OUT "\n";
}

close OUT;

+ 212
- 37
slangui.c View File

@@ -1,4 +1,4 @@
/* $Id: slangui.c,v 1.20 2001/04/24 06:35:07 tausq Exp $ */
/* $Id: slangui.c,v 1.21 2001/05/18 02:02:02 joeyh Exp $ */
/* slangui.c - SLang user interface routines */
/* TODO: the redraw code is a bit broken, also this module is using way too many
* global vars */
@@ -15,7 +15,10 @@
#include "strutl.h"
#include "macros.h"

#define TASK_PKG(t,f,d) ((t)->task_pkg ? (t)->task_pkg->f : (d))
#define TASK_SHORTDESC(t) ((t)->task_pkg ? (t)->task_pkg->shortdesc : "(no description)")
#define TASK_LONGDESC(t) ((t)->task_pkg ? (t)->task_pkg->longdesc : "(no description)")

#define TASK_SECTION(t) ((t)->task_pkg && (t)->task_pkg->section ? (t)->task_pkg->section : "misc")

/* Slang object number mapping */
#define DEFAULTOBJ 0
@@ -65,11 +68,106 @@ static int _initialized = 0;
static struct packages_t *_packages = NULL;
static struct tasks_t *_tasks = NULL;
static struct task_t **_tasksary = NULL;
static int *_displayhint = NULL;
static int _displaylines;

struct { char *section, *desc; } sectiondesc[] = {
{ "user", "End-user Tools" },
{ "server", "Servers" },
{ "devel", "Development" },
{ "l10n", "Localisation" },
{ "hware", "Hardware Support" },
{ "misc", "Miscellaneous" },
{0}
};

static char *getsectiondesc(char *sec) {
int i;
for (i = 0; sectiondesc[i].section; i++)
if (strcmp(sec, sectiondesc[i].section) == 0)
return sectiondesc[i].desc;

return sec;
}

static void initdisplayhints(void) {
int i, j, k;
char *lastsec;

_displaylines = 0;
for (i = 0; i < _tasks->count; i++) {
char *sec = TASK_SECTION(_tasksary[i]);
if (lastsec == NULL || strcmp(lastsec, sec) != 0) {
_displaylines++;
lastsec = sec;
}
_displaylines++;
}

_displayhint = MALLOC(sizeof(int)*_displaylines);
k = 0;

for (i = 0; sectiondesc[i].section; i++) {
for (j = 0; j < _tasks->count; j++) {
char *sec = TASK_SECTION(_tasksary[j]);
if (strcmp(sec, sectiondesc[i].section) == 0) {
_displayhint[k++] = -1;
for (j; j < _tasks->count; j++) {
char *sec = TASK_SECTION(_tasksary[j]);
if (strcmp(sec, sectiondesc[i].section) == 0) {
_displayhint[k++] = j;
}
}
break;
}
}
}

lastsec = NULL;
for (i = 0; i < _tasks->count; i++) {
char *sec = TASK_SECTION(_tasksary[i]);
for (j = 0; sectiondesc[j].section; j++) {
if (strcmp(sectiondesc[j].section, sec) == 0) {
j = -1; break;
}
}
if (j == -1) continue;
if (lastsec == NULL || strcmp(lastsec, sec) != 0) {
_displayhint[k++] = -1;
lastsec = sec;
}
_displayhint[k++] = i;
}
}

int taskseccompare(const struct task_t **pl, const struct task_t **pr)
{
struct task_t *l = *pl, *r = *pr;
char *ls = NULL, *rs = NULL;
int y = strcmp(l->name, r->name);
if (y == 0) return 0;

if (l->task_pkg && l->task_pkg->section) ls = l->task_pkg->section;
if (r->task_pkg && r->task_pkg->section) rs = r->task_pkg->section;
if (ls && rs) {
int x = strcmp(ls, rs);
if (x != 0) return x;
} else if (ls) {
return -1;
} else if (rs) {
return 1;
}
return y;
}

void ui_init(int argc, char * const argv[], struct tasks_t *tasks, struct packages_t *pkgs)
{

_tasks = tasks;
_tasksary = tasks_enumerate(tasks);
qsort(_tasksary, _tasks->count, sizeof(_tasksary[0]), taskseccompare);

initdisplayhints();

_packages = pkgs;
@@ -79,7 +177,7 @@ void ui_init(int argc, char * const argv[], struct tasks_t *tasks, struct packag
SLtt_set_color(DEFAULTOBJ, NULL, "white", "blue");
SLtt_set_color(SHADOWOBJ, NULL, "gray", "black");
SLtt_set_color(CHOOSEROBJ, NULL, "black", "lightgray");
SLtt_set_color(CURSOROBJ, NULL, "lightgray", "blue");
SLtt_set_color(CURSOROBJ, NULL, "blue", "lightgray");
SLtt_set_color(DESCOBJ, NULL, "black", "cyan");
SLtt_set_color(STATUSOBJ, NULL, "yellow", "blue");
SLtt_set_color(DIALOGOBJ, NULL, "black", "lightgray");
@@ -132,7 +230,7 @@ void ui_resize(void)

snprintf(buf, 160, "%s v%s - %s",
_("Debian Task Installer"), VERSION,
_("(c) 1999-2000 SPI and others"));
_("(c) 1999-2001 SPI and others"));
SLsmg_gotorc(0, 0);
SLsmg_write_nstring(buf, strlen(buf));
@@ -169,7 +267,7 @@ int ui_eventloop(void)
if (_chooserinfo.index > 0)
_chooserinfo.index--;
else
_chooserinfo.index = _tasks->count - 1;
_chooserinfo.index = _displaylines - 1;
ui_redrawcursor(_chooserinfo.index);
break;
@@ -180,7 +278,7 @@ int ui_eventloop(void)
case SL_KEY_DOWN:
ui_clearcursor(_chooserinfo.index);
if (_chooserinfo.index < _tasks->count - 1)
if (_chooserinfo.index < _displaylines - 1)
_chooserinfo.index++;
else
_chooserinfo.index = 0;
@@ -197,8 +295,8 @@ int ui_eventloop(void)
case SL_KEY_NPAGE:
ui_clearcursor(_chooserinfo.index);
_chooserinfo.index += _chooserinfo.height;
if (_chooserinfo.index >= _tasks->count - 1)
_chooserinfo.index = _tasks->count - 1;
if (_chooserinfo.index > _displaylines - 1)
_chooserinfo.index = _displaylines - 1;
ui_redrawcursor(_chooserinfo.index);
break;
@@ -320,6 +418,8 @@ int ui_cycleselection(int amount)
if (whichsel > 0)
_drawbutton(whichsel, 1);
ui_redrawcursor(_chooserinfo.index);
return whichsel;
}

@@ -334,7 +434,7 @@ int ui_drawscreen(void)
_("Select task packages to install"));
for (i = _chooserinfo.topindex; i < _chooserinfo.topindex + _chooserinfo.height; i++)
if (i < _tasks->count) ui_drawchooseritem(i);
ui_drawchooseritem(i);

ui_vscrollbar(_chooserinfo.rowoffset, _chooserinfo.coloffset + _chooserinfo.width - 1, _chooserinfo.height, 0);
@@ -534,7 +634,7 @@ void ui_dialog(int row, int col, int height, int width, char *title,
break;
case SL_KEY_NPAGE:
topline += (height-5);
if (topline > numlines - 1) topline = numlines-1;
if (topline > numlines - 1) topline = numlines - 1;
redraw = 1;
break;
@@ -549,28 +649,43 @@ void ui_dialog(int row, int col, int height, int width, char *title,
if (reflow) FREE(reflowbuf);
}

void ui_drawchooseritem(int index)
void ui_drawsection(int row, int index)
{
char buf[1024];
int spot;

ASSERT(_tasks != NULL);
if (index >= _tasks->count)
DIE("Index out of bounds: %d >= %d", index, _tasks->count);
if (index < _chooserinfo.topindex) return;
SLsmg_set_color(CHOOSEROBJ);
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex,
_chooserinfo.coloffset + 1);
snprintf(buf, 1024, "[%c] %s",
(_tasksary[index]->selected == 0 ? ' ' : '*'),
_tasksary[index]->prettyname);
/* I fear the 1 below is an off-by-one error somewhere -- Joeyh */
SLsmg_gotorc(row, _chooserinfo.coloffset + 1);
SLsmg_draw_hline( 2 );
SLsmg_gotorc(row, _chooserinfo.coloffset + 1 + 2);
snprintf(buf, 1024, " %s ", getsectiondesc(TASK_SECTION(_tasksary[index])));
SLsmg_write_nstring(buf, _chooserinfo.width - 1 - 2);
spot = 1 + 2 + strlen(buf);
if (spot > _chooserinfo.width / 2 - 3) spot = _chooserinfo.width / 2 - 3;
SLsmg_gotorc(row, _chooserinfo.coloffset + spot);
SLsmg_draw_hline( _chooserinfo.width / 2 - spot );
}

void ui_drawtask(int row, int index)
{
char buf[1024];
ASSERT(_tasks != NULL);
if (index >= _tasks->count)
DIE("Index out of bounds: %d >= %d", index, _tasks->count);
SLsmg_set_color(CHOOSEROBJ);
SLsmg_gotorc(row, _chooserinfo.coloffset + 1);

snprintf(buf, 1024, "[%c] %s", (_tasksary[index]->selected == 0 ? ' ' : '*'),
TASK_SHORTDESC(_tasksary[index]));
SLsmg_write_nstring(buf, _chooserinfo.width - 1);
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex,
_chooserinfo.coloffset + _tasks->maxnamelen + 7);
SLsmg_write_nstring(TASK_PKG(_tasksary[index], shortdesc, "(no description)"), _chooserinfo.width - _tasks->maxnamelen - 7);
}

void ui_toggleselection(int index)
void ui_toggletask(int row, int index)
{
ASSERT(_tasks != NULL);
if (index >= _tasks->count)
@@ -581,16 +696,19 @@ void ui_toggleselection(int index)
else
_tasksary[index]->selected = 0;
if (row >= _chooserinfo.rowoffset + _chooserinfo.height) {
return;
}
SLsmg_set_color(CHOOSEROBJ);
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex, _chooserinfo.coloffset + 1);
SLsmg_gotorc(row, _chooserinfo.coloffset + 1);

if (_tasksary[index]->selected == 0)
SLsmg_write_string("[ ]");
else
SLsmg_write_string("[*]");

SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex,
_chooserinfo.coloffset + 3);
SLsmg_gotorc(row, _chooserinfo.coloffset + 3);
SLsmg_refresh();
}

@@ -598,7 +716,7 @@ void ui_redrawchooser(void)
{
int i;
for (i = _chooserinfo.topindex; i < _chooserinfo.topindex + _chooserinfo.height; i++)
if (i < _tasks->count) ui_drawchooseritem(i);
ui_drawchooseritem(i);
}

void ui_redrawcursor(int index)
@@ -609,37 +727,52 @@ void ui_redrawcursor(int index)
_chooserinfo.topindex = index + 1 - _chooserinfo.height;
ui_redrawchooser();
} else if (index < _chooserinfo.topindex) {
_chooserinfo.topindex = 0;
_chooserinfo.topindex = index;
ui_redrawchooser();
}

ui_vscrollbar(_chooserinfo.rowoffset, _chooserinfo.coloffset +
_chooserinfo.width - 1, _chooserinfo.height,
((double)index+1)/_tasks->count);
((double)index+1)/_displaylines);

if (_displayhint[index] >= 0) {
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex, _chooserinfo.coloffset + 2);
SLsmg_set_color(CURSOROBJ);
if (_tasksary[_displayhint[index]]->selected) {
SLsmg_write_string("*");
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex, _chooserinfo.coloffset + 2);
} else {
SLsmg_write_string("#");
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex, _chooserinfo.coloffset + 2);
SLsmg_write_string(_tasksary[index]->selected == 0 ? " " : "*");
SLsmg_write_string(" ");
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex, _chooserinfo.coloffset + 2);
}
} else {
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex, _chooserinfo.coloffset + 4);
}
SLsmg_refresh();
}

void ui_clearcursor(int index)
{
if (_displayhint[index] >= 0) {
SLsmg_set_color(DIALOGOBJ);
SLsmg_gotorc(_chooserinfo.rowoffset + index - _chooserinfo.topindex, _chooserinfo.coloffset + 2);
SLsmg_write_string(_tasksary[index]->selected == 0 ? " " : "*");
SLsmg_write_string(_tasksary[_displayhint[index]]->selected == 0 ? " " : "*");
}
}

void ui_showhelp(void)
{
_chooserinfo.whichwindow = HELPWINDOW;
ui_dialog(3, 3, ROWS - 7, COLUMNS - 10, _("Help"),
_("Task packages are \"metapackages\" that allow you to quickly install" \
"a selection of packages that performs a given task.\r\rThe main chooser" \
_("Tasks allow you to quickly install " \
"a selection of packages that performs a given task.\r\rThe main chooser " \
"list shows a list of tasks that you can choose to install. The arrow " \
"keys moves the cursor. Pressing ENTER or the SPACEBAR toggles the " \
"selection of the package at the cursor. You can also press A to select " \
"all packages, or N to deselect all packages. Pressing Q will exit this " \
"selection of the task at the cursor. You can also press A to select " \
"all tasks, or N to deselect all tasks. Pressing Q will exit this " \
"program and begin installation of your selected tasks.\r\rThank you for " \
"using Debian.\r\rPress enter to return to the task selection screen"),
1, SCROLLBAR_VERT);
@@ -657,7 +790,9 @@ void ui_showpackageinfo(void)
char shortbuf[256];
char *desc = NULL;
int bufleft;
int index = _chooserinfo.index;
int index = _displayhint[_chooserinfo.index];

if (index < 0) return;
ASSERT(_tasks != NULL);
_chooserinfo.whichwindow = DESCWINDOW;
@@ -666,10 +801,10 @@ void ui_showpackageinfo(void)
tsk = _tasksary[index];
ASSERT(tsk != NULL);
desc = reflowtext(width, TASK_PKG(tsk,longdesc,"(no long description)"));
desc = reflowtext(width, TASK_LONGDESC(tsk));
/* pack buf with package info */
snprintf(buf, sizeof(buf), _("Description:\n%s\n\nDependent packages:\n"), desc);
snprintf(buf, sizeof(buf), _("Description:\n%s\n\nIncluded packages:\n"), desc);
FREE(desc);
bufleft = sizeof(buf) - strlen(buf) - 1;
@@ -687,3 +822,43 @@ void ui_showpackageinfo(void)
ui_drawscreen();
}

void ui_drawchooseritem(int index)
{
int realrow = _chooserinfo.rowoffset + index - _chooserinfo.topindex;
int task;

if (index >= _displaylines) return;

task = _displayhint[index];
if (task == -1) {
task = _displayhint[index+1];
ui_drawsection(realrow, task);
} else {
ui_drawtask(realrow, task);
}
}

void ui_toggleselection(int index)
{
int task = _displayhint[index];
if (task >= 0) {
ui_toggletask(_chooserinfo.rowoffset + index - _chooserinfo.topindex, task);
} else {
int first = index+1, last, setto = 0;
for(;;) {
index++;
if (index >= _displaylines) break;
task = _displayhint[index];
if (task == -1) break;
setto = setto || _tasksary[task]->selected == 0;
}
last = index;
for (index = first; index < last; index++) {
task = _displayhint[index];
if ((!_tasksary[task]->selected) ^ (!setto)) {
ui_toggletask(_chooserinfo.rowoffset + index - _chooserinfo.topindex, task);
}
}
}
}


+ 11
- 0
tasks/demo View File

@@ -0,0 +1,11 @@
# Comment.
Task: demo
Section: misc
Description: demo new style task
This is a demo new style task. It is not intended to ship with debian,
# Let's make sure a comment can go here.
really.
Packages:
kdebase
gdm


+ 11
- 0
tasks/demo2 View File

@@ -0,0 +1,11 @@
# Comment.
Task: demo2
Section: misc
Description: another demo new style task
This is a demo new style task. It is not intended to ship with debian,
# Let's make sure a comment can go here.
really.
Packages:
kdebase
gdm


+ 29
- 4
tasksel.c View File

@@ -1,4 +1,4 @@
/* $Id: tasksel.c,v 1.10 2001/04/24 06:35:07 tausq Exp $ */
/* $Id: tasksel.c,v 1.11 2001/05/18 02:02:02 joeyh Exp $ */
#include "tasksel.h"

#include <stdio.h>
@@ -45,7 +45,7 @@ int doinstall(struct task_t **tasklist, int taskcount,
{
int i, c = 0;
FILE *todpkg;
char buf[8192];
char buf[20480];

if (queueinstalls) {
if (testmode)
@@ -63,7 +63,7 @@ int doinstall(struct task_t **tasklist, int taskcount,
for (i = 0; i < taskcount; i++) {
if (tasklist[i]->selected > 0) {
int j;
if (tasklist[i]->task_pkg) {
if (tasklist[i]->task_pkg && ! tasklist[i]->task_pkg->pseudopackage) {
fprintf(todpkg, "%s install\n", tasklist[i]->task_pkg->name);
}
for (j = 0; j < tasklist[i]->packagescount; j++) {
@@ -92,7 +92,7 @@ int doinstall(struct task_t **tasklist, int taskcount,
if (tasklist[i]->selected > 0) {
int j;
/* TODO check buffer overflow; not likely, but still... */
if (tasklist[i]->task_pkg) {
if (tasklist[i]->task_pkg && ! tasklist[i]->task_pkg->pseudopackage) {
strcat(buf, tasklist[i]->task_pkg->name);
strcat(buf, " ");
}
@@ -149,7 +149,15 @@ int main(int argc, char * const argv[])
}
}
/* Initialization */
memset(&packages, 0, sizeof(struct packages_t));
memset(&tasks, 0, sizeof(struct tasks_t));
/* Must read packages first. */
packages_readlist(&tasks, &packages);
/* TODO: should probably read in all files in a directory. */
taskfile_read(TASKDESC, &tasks, &packages);

if (tasks.count == 0) {
fprintf(stderr, _("No task packages found on this system.\nDid you update your available file?"));
@@ -176,6 +184,23 @@ int main(int argc, char * const argv[])
}

tasklist = tasks_enumerate(&tasks);
if (noninteractive) {
if (optind + 1 < argc && strcmp(argv[optind], "install") == 0) {
for (optind++; optind < argc; optind++) {
/* mark task argv[optind] for install, if it exists */
int i;
for (i = 0; i < tasks.count; i++) {
if (strcmp(tasklist[i]->name, argv[optind]) == 0) break;
}
if (i == tasks.count) {
printf("E: %s: no such task\n", argv[optind]);
} else {
tasklist[i]->selected = 1;
}
}
}
}

if (r == 0) {
r = doinstall(tasklist, tasks.count,
pkglist, (installreqd || installimp || installstd


+ 0
- 226
tasksel.man View File

@@ -1,226 +0,0 @@
.rn '' }`
''' $RCSfile: tasksel.man,v $$Revision: 1.1 $$Date: 1999/12/29 16:10:01 $
'''
''' $Log: tasksel.man,v $
''' Revision 1.1 1999/12/29 16:10:01 tausq
''' man pages, debian packaging scripts
'''
'''
.de Sh
.br
.if t .Sp
.ne 5
.PP
\fB\\$1\fR
.PP
..
.de Sp
.if t .sp .5v
.if n .sp
..
.de Ip
.br
.ie \\n(.$>=3 .ne \\$3
.el .ne 3
.IP "\\$1" \\$2
..
.de Vb
.ft CW
.nf
.ne \\$1
..
.de Ve
.ft R

.fi
..
'''
'''
''' Set up \*(-- to give an unbreakable dash;
''' string Tr holds user defined translation string.
''' Bell System Logo is used as a dummy character.
'''
.tr \(*W-|\(bv\*(Tr
.ie n \{\
.ds -- \(*W-
.ds PI pi
.if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
.if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
.ds L" ""
.ds R" ""
''' \*(M", \*(S", \*(N" and \*(T" are the equivalent of
''' \*(L" and \*(R", except that they are used on ".xx" lines,
''' such as .IP and .SH, which do another additional levels of
''' double-quote interpretation
.ds M" """
.ds S" """
.ds N" """""
.ds T" """""
.ds L' '
.ds R' '
.ds M' '
.ds S' '
.ds N' '
.ds T' '
'br\}
.el\{\
.ds -- \(em\|
.tr \*(Tr
.ds L" ``
.ds R" ''
.ds M" ``
.ds S" ''
.ds N" ``
.ds T" ''
.ds L' `
.ds R' '
.ds M' `
.ds S' '
.ds N' `
.ds T' '
.ds PI \(*p
'br\}
.\" If the F register is turned on, we'll generate
.\" index entries out stderr for the following things:
.\" TH Title
.\" SH Header
.\" Sh Subsection
.\" Ip Item
.\" X<> Xref (embedded
.\" Of course, you have to process the output yourself
.\" in some meaninful fashion.
.if \nF \{
.de IX
.tm Index:\\$1\t\\n%\t"\\$2"
..
.nr % 0
.rr F
.\}
.TH TASKSEL 1 "perl 5.005, patch 03" "15/Dec/1999" "User Contributed Perl Documentation"
.UC
.if n .hy 0
.if n .na
.ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
.de CQ \" put $1 in typewriter font
.ft CW
'if n "\c
'if t \\&\\$1\c
'if n \\&\\$1\c
'if n \&"
\\&\\$2 \\$3 \\$4 \\$5 \\$6 \\$7
'.ft R
..
.\" @(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2
. \" AM - accent mark definitions
.bd B 3
. \" fudge factors for nroff and troff
.if n \{\
. ds #H 0
. ds #V .8m
. ds #F .3m
. ds #[ \f1
. ds #] \fP
.\}
.if t \{\
. ds #H ((1u-(\\\\n(.fu%2u))*.13m)
. ds #V .6m
. ds #F 0
. ds #[ \&
. ds #] \&
.\}
. \" simple accents for nroff and troff
.if n \{\
. ds ' \&
. ds ` \&
. ds ^ \&
. ds , \&
. ds ~ ~
. ds ? ?
. ds ! !
. ds /
. ds q
.\}
.if t \{\
. ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
. ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
. ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
. ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
. ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
. ds ? \s-2c\h'-\w'c'u*7/10'\u\h'\*(#H'\zi\d\s+2\h'\w'c'u*8/10'
. ds ! \s-2\(or\s+2\h'-\w'\(or'u'\v'-.8m'.\v'.8m'
. ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
. ds q o\h'-\w'o'u*8/10'\s-4\v'.4m'\z\(*i\v'-.4m'\s+4\h'\w'o'u*8/10'
.\}
. \" troff and (daisy-wheel) nroff accents
.ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
.ds 8 \h'\*(#H'\(*b\h'-\*(#H'
.ds v \\k:\h'-(\\n(.wu*9/10-\*(#H)'\v'-\*(#V'\*(#[\s-4v\s0\v'\*(#V'\h'|\\n:u'\*(#]
.ds _ \\k:\h'-(\\n(.wu*9/10-\*(#H+(\*(#F*2/3))'\v'-.4m'\z\(hy\v'.4m'\h'|\\n:u'
.ds . \\k:\h'-(\\n(.wu*8/10)'\v'\*(#V*4/10'\z.\v'-\*(#V*4/10'\h'|\\n:u'
.ds 3 \*(#[\v'.2m'\s-2\&3\s0\v'-.2m'\*(#]
.ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
.ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
.ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
.ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
.ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
.ds ae a\h'-(\w'a'u*4/10)'e
.ds Ae A\h'-(\w'A'u*4/10)'E
.ds oe o\h'-(\w'o'u*4/10)'e
.ds Oe O\h'-(\w'O'u*4/10)'E
. \" corrections for vroff
.if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
.if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
. \" for low resolution devices (crt and lpr)
.if \n(.H>23 .if \n(.V>19 \
\{\
. ds : e
. ds 8 ss
. ds v \h'-1'\o'\(aa\(ga'
. ds _ \h'-1'^
. ds . \h'-1'.
. ds 3 3
. ds o a
. ds d- d\h'-1'\(ga
. ds D- D\h'-1'\(hy
. ds th \o'bp'
. ds Th \o'LP'
. ds ae ae
. ds Ae AE
. ds oe oe
. ds Oe OE
.\}
.rm #[ #] #H #V #F C
.SH "NAME"
tasksel \- a user interface for installing task packages
.SH "SYNOPSIS"
tasksel
.SH "DESCRIPTION"
tasksel shows all available task packages and allows to user to select
ones to install
.SH "SEE ALSO"
\fIdpkg\fR\|(8), apt-\fIget\fR\|(8)
.SH "FILES"
\fI/var/lib/dpkg/available\fR
.SH "AUTHOR"
tasksel was written by Randolph Chung <tausq@debian.org>.
.SH "HISTORY"
This document first appeared with tasksel-1.0

.rn }` ''
.IX Title "TASKSEL 1"
.IX Name "tasksel - a user interface for installing task packages"

.IX Header "NAME"

.IX Header "SYNOPSIS"

.IX Header "DESCRIPTION"

.IX Header "SEE ALSO"

.IX Header "FILES"

.IX Header "AUTHOR"

.IX Header "HISTORY"


+ 2
- 1
tasksel.pod View File

@@ -8,7 +8,7 @@ tasksel

=head1 DESCRIPTION

tasksel shows all available task packages and allows to user to select
tasksel shows all available tasks and allows to user to select
ones to install

=head1 SEE ALSO
@@ -17,6 +17,7 @@ dpkg(8), apt-get(8)

=head1 FILES

F</usr/share/tasksel/debian-tasks.desc>
F</var/lib/dpkg/available>

=head1 AUTHOR


Loading…
Cancel
Save