2 * dselect - Debian package maintenance user interface
3 * method.cc - access method handling
5 * Copyright © 1995 Ian Jackson <ian@chiark.greenend.org.uk>
6 * Copyright © 2001,2002 Wichert Akkerman <wakkerma@debian.org>
8 * This is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <http://www.gnu.org/licenses/>.
25 #include <sys/types.h>
42 #include <dpkg/i18n.h>
43 #include <dpkg/dpkg.h>
44 #include <dpkg/dpkg-db.h>
45 #include <dpkg/subproc.h>
46 #include <dpkg/command.h>
51 static const char *const methoddirectories
[]= {
52 LIBDIR
"/" METHODSDIR
,
53 LOCALLIBDIR
"/" METHODSDIR
,
57 static char *methodlockfile
= 0;
58 static int methlockfd
= -1;
61 sthfailed(const char * reasoning
)
67 sprintf(buf
,_("\n\n%s: %s\n"),DSELECT
,reasoning
);
70 addstr(_("\nPress <enter> to continue."));
75 static void cu_unlockmethod(int, void**) {
78 assert(methodlockfile
);
80 fl
.l_type
=F_UNLCK
; fl
.l_whence
= SEEK_SET
; fl
.l_start
=fl
.l_len
=0;
81 if (fcntl(methlockfd
,F_SETLK
,&fl
) == -1)
82 sthfailed("unable to unlock access method area");
85 static enum urqresult
ensureoptions(void) {
86 const char *const *ccpp
;
87 dselect_option
*newoptions
;
93 for (ccpp
= methoddirectories
; *ccpp
; ccpp
++)
94 readmethods(*ccpp
, &newoptions
, &nread
);
96 sthfailed("no access methods are available");
105 static enum urqresult
lockmethod(void) {
108 if (!methodlockfile
) {
111 methodlockfile
= new char[l
+sizeof(METHLOCKFILE
)+2];
112 strcpy(methodlockfile
,admindir
);
113 strcpy(methodlockfile
+l
, "/" METHLOCKFILE
);
115 if (methlockfd
== -1) {
116 methlockfd
= open(methodlockfile
, O_RDWR
|O_CREAT
|O_TRUNC
, 0660);
117 if (methlockfd
== -1) {
118 if ((errno
== EPERM
) || (errno
== EACCES
)) {
119 sthfailed("requested operation requires superuser privilege");
122 sthfailed("unable to open/create access method lockfile");
126 fl
.l_type
=F_WRLCK
; fl
.l_whence
=SEEK_SET
; fl
.l_start
=fl
.l_len
=0;
127 if (fcntl(methlockfd
,F_SETLK
,&fl
) == -1) {
128 if (errno
== EWOULDBLOCK
|| errno
== EAGAIN
) {
129 sthfailed("the access method area is already locked");
132 sthfailed("unable to lock access method area");
135 push_cleanup(cu_unlockmethod
,~0, 0,0, 0);
140 falliblesubprocess(struct command
*cmd
)
147 subproc_signals_setup(cmd
->name
);
151 subproc_signals_cleanup(0, 0);
155 status
= subproc_wait(c1
, cmd
->name
);
157 pop_cleanup(ehflag_normaltidy
);
159 if (WIFEXITED(status
) && !WEXITSTATUS(status
)) {
163 fprintf(stderr
, "\n%s ", cmd
->name
);
164 if (WIFEXITED(status
)) {
165 i
= WEXITSTATUS(status
);
166 fprintf(stderr
,_("returned error exit status %d.\n"),i
);
167 } else if (WIFSIGNALED(status
)) {
170 fprintf(stderr
,_("was interrupted.\n"));
172 fprintf(stderr
,_("was terminated by a signal: %s.\n"),strsignal(i
));
174 if (WCOREDUMP(status
))
175 fprintf(stderr
,_("(It left a coredump.)\n"));
177 fprintf(stderr
,_("failed with an unknown wait return code %d.\n"),status
);
179 fprintf(stderr
,_("Press <enter> to continue.\n"));
180 m_output(stderr
, _("<standard error>"));
181 do { c
= fgetc(stdin
); } while ((c
== ERR
&& errno
==EINTR
) || ((c
!= '\n') && c
!= EOF
));
182 if ((c
== ERR
) || (c
== EOF
))
183 ohshite(_("error reading acknowledgement of program failure message"));
187 static urqresult
runscript(const char *exepath
, const char *name
) {
190 ur
= ensureoptions(); if (ur
!= urqr_normal
) return ur
;
191 ur
=lockmethod(); if (ur
!= urqr_normal
) return ur
;
197 strcpy(coption
->meth
->pathinmeth
,exepath
);
199 command_init(&cmd
, coption
->meth
->path
, name
);
200 command_add_args(&cmd
, exepath
, admindir
, coption
->meth
->name
,
201 coption
->name
, NULL
);
202 ur
= falliblesubprocess(&cmd
);
203 command_destroy(&cmd
);
205 sthfailed("no access method is selected/configured");
208 pop_cleanup(ehflag_normaltidy
);
213 urqresult
urq_update(void) {
214 return runscript(METHODUPDATESCRIPT
,_("update available list script"));
217 urqresult
urq_install(void) {
218 return runscript(METHODINSTALLSCRIPT
,_("installation script"));
221 static urqresult
rundpkgauto(const char *name
, const char *dpkgmode
) {
225 command_init(&cmd
, DPKG
, name
);
226 command_add_args(&cmd
, DPKG
, "--admindir", admindir
, "--pending",
230 printf("running dpkg --pending %s ...\n",dpkgmode
);
232 ur
= falliblesubprocess(&cmd
);
233 command_destroy(&cmd
);
238 urqresult
urq_remove(void) {
239 return rundpkgauto("dpkg --remove","--remove");
242 urqresult
urq_config(void) {
243 return rundpkgauto("dpkg --configure","--configure");
246 urqresult
urq_setup(void) {
250 ur
= ensureoptions(); if (ur
!= urqr_normal
) return ur
;
251 ur
=lockmethod(); if (ur
!= urqr_normal
) return ur
;
255 methodlist
*l
= new methodlist();
259 if (qa
== qa_quitchecksave
) {
262 strcpy(coption
->meth
->pathinmeth
,METHODSETUPSCRIPT
);
264 command_init(&cmd
, coption
->meth
->path
, _("query/setup script"));
265 command_add_args(&cmd
, METHODSETUPSCRIPT
, admindir
, coption
->meth
->name
,
266 coption
->name
, NULL
);
267 ur
= falliblesubprocess(&cmd
);
268 command_destroy(&cmd
);
269 if (ur
== urqr_normal
) writecurrentopt();
274 pop_cleanup(ehflag_normaltidy
);