2 * dselect - Debian GNU/Linux package maintenance user interface
3 * main.cc - main program
5 * Copyright (C) 1994,1995 Ian Jackson <iwj10@cus.cam.ac.uk>
7 * This is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2,
10 * or (at your option) any later version.
12 * This is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
17 * You should have received a copy of the GNU General Public
18 * License along with dpkg; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 #include <sys/types.h>
50 const char thisname
[]= DSELECT
;
51 const char printforhelp
[]= "Type " DPKG
" --help for help.";
53 modstatdb_rw readwrite
;
54 const char *admindir
= ADMINDIR
;
57 static keybindings
packagelistbindings(packagelist_kinterps
,packagelist_korgbindings
);
65 static const menuentry menuentries
[]= {
66 { "access", "Choose the access method to use.", &urq_setup
},
67 { "update", "Update list of available packages, if possible.", &urq_update
},
68 { "select", "Request which packages you want on your system.", &urq_list
},
69 { "install", "Install and upgrade wanted packages.", &urq_install
},
70 { "config", "Configure any packages that are unconfigured.", &urq_config
},
71 { "remove", "Remove unwanted software.", &urq_remove
},
72 { "quit", "Quit dselect.", &urq_quit
},
73 { "menu", 0, &urq_menu
},
77 static const char programdesc
[]=
78 "Debian Linux `" DSELECT
"' package handling frontend.";
80 static const char copyrightstring
[]=
81 "Version " DPKG_VERSION_ARCH
". Copyright (C) 1994-1996 Ian Jackson. This is\n"
82 "free software; see the GNU General Public Licence version 2 or later for\n"
83 "copying conditions. There is NO warranty. See dselect --licence for details.\n";
85 static void printversion(void) {
86 if (fprintf(stdout
,"%s\n%s",programdesc
,copyrightstring
) == EOF
) werr("stdout");
89 static void usage(void) {
91 ("Usage: dselect [options]\n"
92 " dselect [options] action ...\n"
93 "Options: --admindir <directory> (default is /var/lib/dpkg)\n"
94 " --help --version --licence --debug <file> | -D<file> | -D\n"
95 "Actions: access update select install config remove quit menu\n",
96 stdout
)) werr("stdout");
99 /* These are called by C code, so need to have C calling convention */
102 static void helponly(const struct cmdinfo
*, const char*) {
105 static void versiononly(const struct cmdinfo
*, const char*) {
106 printversion(); exit(0);
109 static void setdebug(const struct cmdinfo
*, const char *v
) {
111 if (!debug
) ohshite("couldn't open debug file `%.255s'\n",v
);
112 setvbuf(debug
,0,_IONBF
,0);
115 } /* End of extern "C" */
117 static const struct cmdinfo cmdinfos
[]= {
118 { "admindir", 0, 1, 0, &admindir
, 0 },
119 { "debug", 'D', 1, 0, 0, setdebug
},
120 { "help", 'h', 0, 0, 0, helponly
},
121 { "version", 0, 0, 0, 0, versiononly
},
122 { "licence", 0, 0, 0, 0, showcopyright
}, /* UK spelling */
123 { "license", 0, 0, 0, 0, showcopyright
}, /* US spelling */
127 static int cursesareon
= 0;
130 const char *cup
, *smso
;
132 cup
= tigetstr("cup");
133 smso
= tigetstr("smso");
137 fputs("Terminal does not appear to support cursor addressing.\n",stderr
);
139 fputs("Terminal does not appear to support highlighting.\n",stderr
);
140 fputs("Set your TERM variable correctly, use a better terminal,\n"
141 "or make do with the per-package management tool " DPKG
".\n",stderr
);
142 ohshit("terminal lacks necessary features, giving up");
157 extern void *operator new(size_t size
) {
164 extern void operator delete(void *p
) {
168 urqresult
urq_list(void) {
169 readwrite
= modstatdb_init(admindir
,msdbrw_writeifposs
);
173 packagelist
*l
= new packagelist(&packagelistbindings
);
178 modstatdb_shutdown();
183 void dme(int i
, int so
) {
185 const menuentry
*me
= &menuentries
[i
];
186 sprintf(buf
," %c %d. [%c]%-10.10s %-80.80s ",
188 toupper(me
->option
[0]), me
->option
+1,
192 getmaxyx(stdscr
,y
,x
);
194 attrset(so
? A_REVERSE
: A_NORMAL
);
195 mvaddnstr(i
+2,0, buf
,x
-1);
199 int refreshmenu(void) {
200 curseson(); cbreak(); noecho(); nonl(); keypad(stdscr
,TRUE
);
203 getmaxyx(stdscr
,y
,x
);
207 mvaddnstr(0,0, programdesc
,x
-1);
210 const struct menuentry
*mep
; int i
;
211 for (mep
=menuentries
, i
=0; mep
->option
&& mep
->menuent
; mep
++, i
++)
216 "Use ^P and ^N, cursor keys, initial letters, or digits to select;\n"
217 "Press ENTER to confirm selection. ^L to redraw screen.\n\n");
220 addstr(copyrightstring
);
225 urqresult
urq_menu(void) {
226 #define C(x) ((x)-'a'+1)
228 entries
= refreshmenu();
233 c
= getch(); if (c
==ERR
) ohshite("failed to getch in main menu");
234 if (c
==C('n') || c
==KEY_DOWN
|| c
==' ') {
235 dme(cursor
,0); cursor
++; cursor
%= entries
; dme(cursor
,1);
236 } else if (c
==C('p') || c
==KEY_UP
|| c
==C('h') ||
237 c
==KEY_BACKSPACE
|| c
==KEY_DC
) {
238 dme(cursor
,0); cursor
+= entries
-1; cursor
%= entries
; dme(cursor
,1);
239 } else if (c
=='\n' || c
=='\r' || c
==KEY_ENTER
) {
241 switch (menuentries
[cursor
].fn()) { /* fixme: trap errors in urq_... */
243 return urqr_quitmenu
;
245 cursor
++; cursor
%= entries
;
249 internerr("unknown menufn");
251 refreshmenu(); dme(cursor
,1);
252 } else if (c
==C('l')) {
253 clearok(stdscr
,TRUE
); clear(); refreshmenu(); dme(cursor
,1);
254 } else if (isdigit(c
)) {
255 char buf
[2]; buf
[0]=c
; buf
[1]=0; c
=atoi(buf
);
257 dme(cursor
,0); cursor
=c
; dme(cursor
,1);
261 } else if (isalpha(c
)) {
263 for (i
=0; i
<entries
&& menuentries
[i
].option
[0] != c
; i
++);
265 dme(cursor
,0); cursor
=i
; dme(cursor
,1);
275 urqresult
urq_quit(void) {
276 return urqr_quitmenu
;
277 /* fixme: check packages OK */
280 int main(int, const char *const *argv
) {
283 if (setjmp(ejbuf
)) { /* expect warning about possible clobbering of argv */
285 error_unwind(ehflag_bombout
); exit(2);
287 push_error_handler(&ejbuf
,print_error_fatal
,0);
289 myopt(&argv
,cmdinfos
);
293 while ((a
= *argv
++) != 0) {
295 for (me
= menuentries
; me
->option
&& strcmp(me
->option
,a
); me
++);
296 if (!me
->option
) badusage("unknown action string `%.50s'",a
);
304 set_error_display(0,0);
305 error_unwind(ehflag_normaltidy
);