2 * dselect - Debian package maintenance user interface
3 * method.cc - access method handling
5 * Copyright © 1995 Ian Jackson <ijackson@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 <https://www.gnu.org/licenses/>.
25 #include <sys/types.h>
40 #include <dpkg/i18n.h>
41 #include <dpkg/dpkg.h>
42 #include <dpkg/dpkg-db.h>
43 #include <dpkg/subproc.h>
44 #include <dpkg/command.h>
49 static const char *const methoddirectories
[]= {
50 LIBDIR
"/" METHODSDIR
,
51 LOCALLIBDIR
"/" METHODSDIR
,
55 static char *methodlockfile
= nullptr;
56 static int methlockfd
= -1;
59 sthfailed(const char * reasoning
)
63 printw("\n\n%s: %s\n", DSELECT
, reasoning
);
65 addstr(_("\nPress <enter> to continue."));
70 static void cu_unlockmethod(int, void**) {
73 if (methodlockfile
== nullptr)
74 internerr("method lock file is nullptr");
76 internerr("method lock fd is %d < 0", methlockfd
);
77 fl
.l_type
=F_UNLCK
; fl
.l_whence
= SEEK_SET
; fl
.l_start
=fl
.l_len
=0;
78 if (fcntl(methlockfd
,F_SETLK
,&fl
) == -1)
79 sthfailed(_("cannot unlock access method area"));
82 static enum urqresult
ensureoptions(void) {
83 dselect_option
*newoptions
;
89 for (const char *const *ccpp
= methoddirectories
; *ccpp
; ccpp
++)
90 readmethods(*ccpp
, &newoptions
, &nread
);
92 sthfailed(_("no access methods are available"));
101 static enum urqresult
lockmethod(void) {
104 if (methodlockfile
== nullptr)
105 methodlockfile
= dpkg_db_get_path(METHLOCKFILE
);
107 if (methlockfd
== -1) {
108 methlockfd
= open(methodlockfile
, O_RDWR
|O_CREAT
|O_TRUNC
, 0660);
109 if (methlockfd
== -1) {
110 if ((errno
== EPERM
) || (errno
== EACCES
)) {
111 sthfailed(_("requested operation requires superuser privilege"));
114 sthfailed(_("cannot open or create access method lockfile"));
118 fl
.l_type
=F_WRLCK
; fl
.l_whence
=SEEK_SET
; fl
.l_start
=fl
.l_len
=0;
119 if (fcntl(methlockfd
,F_SETLK
,&fl
) == -1) {
120 if (errno
== EACCES
|| errno
== EAGAIN
) {
121 sthfailed(_("the access method area is already locked"));
124 sthfailed(_("cannot lock access method area"));
127 push_cleanup(cu_unlockmethod
, ~0, 0);
132 falliblesubprocess(struct command
*cmd
)
139 subproc_signals_ignore(cmd
->name
);
141 pid
= subproc_fork();
143 subproc_signals_cleanup(0, nullptr);
147 fprintf(stderr
, "\n");
149 i
= subproc_reap(pid
, cmd
->name
, SUBPROC_WARN
);
151 subproc_signals_restore();
157 fprintf(stderr
,_("Press <enter> to continue.\n"));
158 m_output(stderr
, _("<standard error>"));
161 } while ((c
== EOF
&& errno
== EINTR
) || (c
!= '\n' && c
!= EOF
));
163 ohshite(_("error reading acknowledgement of program failure message"));
167 static urqresult
runscript(const char *exepath
, const char *name
) {
170 ur
= ensureoptions(); if (ur
!= urqr_normal
) return ur
;
171 ur
=lockmethod(); if (ur
!= urqr_normal
) return ur
;
177 strcpy(coption
->meth
->pathinmeth
,exepath
);
179 command_init(&cmd
, coption
->meth
->path
, name
);
180 command_add_args(&cmd
, exepath
, dpkg_db_get_dir(),
181 coption
->meth
->name
, coption
->name
, nullptr);
182 ur
= falliblesubprocess(&cmd
);
183 command_destroy(&cmd
);
185 sthfailed(_("no access method is selected or configured"));
188 pop_cleanup(ehflag_normaltidy
);
193 urqresult
urq_update(void) {
194 return runscript(METHODUPDATESCRIPT
,_("update available list script"));
197 urqresult
urq_install(void) {
198 return runscript(METHODINSTALLSCRIPT
,_("installation script"));
201 static urqresult
rundpkgauto(const char *name
, const char *dpkgmode
) {
205 command_init(&cmd
, DPKG
, name
);
206 command_add_args(&cmd
, DPKG
, "--admindir", dpkg_db_get_dir(), "--pending",
210 printf(_("running %s %s ...\n"), "dpkg --pending", dpkgmode
);
212 ur
= falliblesubprocess(&cmd
);
213 command_destroy(&cmd
);
218 urqresult
urq_remove(void) {
219 return rundpkgauto("dpkg --remove","--remove");
222 urqresult
urq_config(void) {
223 return rundpkgauto("dpkg --configure","--configure");
226 urqresult
urq_setup(void) {
230 ur
= ensureoptions(); if (ur
!= urqr_normal
) return ur
;
231 ur
=lockmethod(); if (ur
!= urqr_normal
) return ur
;
235 methodlist
*l
= new methodlist();
239 if (qa
== qa_quitchecksave
) {
242 strcpy(coption
->meth
->pathinmeth
,METHODSETUPSCRIPT
);
244 command_init(&cmd
, coption
->meth
->path
, _("query/setup script"));
245 command_add_args(&cmd
, METHODSETUPSCRIPT
, dpkg_db_get_dir(),
246 coption
->meth
->name
, coption
->name
, nullptr);
247 ur
= falliblesubprocess(&cmd
);
248 command_destroy(&cmd
);
249 if (ur
== urqr_normal
) writecurrentopt();
254 pop_cleanup(ehflag_normaltidy
);