Fixed or handling bug
[ntk/apt.git] / apt-pkg / deb / dpkginit.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: dpkginit.cc,v 1.5 1999/08/03 05:21:19 jgg Exp $
4 /* ######################################################################
5
6 DPKG init - Initialize the dpkg stuff
7
8 This class provides the locking mechanism used by dpkg for its
9 database area. It does the proper consistency checks and acquires the
10 correct kind of lock.
11
12 ##################################################################### */
13 /*}}}*/
14 // Includes /*{{{*/
15 #ifdef __GNUG__
16 #pragma implementation "apt-pkg/dpkginit.h"
17 #endif
18 #include <apt-pkg/dpkginit.h>
19 #include <apt-pkg/error.h>
20 #include <apt-pkg/configuration.h>
21 #include <apt-pkg/fileutl.h>
22
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <dirent.h>
26 /*}}}*/
27
28 // DpkgLock::pkgDpkgLock - Constructor /*{{{*/
29 // ---------------------------------------------------------------------
30 /* */
31 pkgDpkgLock::pkgDpkgLock(bool WithUpdates)
32 {
33 LockFD = -1;
34 GetLock(WithUpdates);
35 }
36 /*}}}*/
37 // DpkgLock::~pkgDpkgLock - Destructor /*{{{*/
38 // ---------------------------------------------------------------------
39 /* */
40 pkgDpkgLock::~pkgDpkgLock()
41 {
42 Close();
43 }
44 /*}}}*/
45 // DpkgLock::GetLock - Get the lock /*{{{*/
46 // ---------------------------------------------------------------------
47 /* This mirrors the operations dpkg does when it starts up. Note the
48 checking of the updates directory. */
49 bool pkgDpkgLock::GetLock(bool WithUpdates)
50 {
51 // Disable file locking
52 if (_config->FindB("Debug::NoLocking",false) == true)
53 return true;
54
55 Close();
56
57 // Create the lockfile
58 string AdminDir = flNotFile(_config->Find("Dir::State::status"));
59 LockFD = ::GetLock(AdminDir + "lock");
60 if (LockFD == -1)
61 return _error->Error("Unable to lock the administration directory, "
62 "are you root?");
63
64 // See if we need to abort with a dirty journal
65 if (WithUpdates == true && CheckUpdates() == true)
66 {
67 Close();
68 return _error->Error("dpkg was interrupted, you must manually "
69 "run 'dpkg --configure -a' to correct the problem. ");
70 }
71
72 return true;
73 }
74 /*}}}*/
75 // DpkgLock::Close - Close the lock /*{{{*/
76 // ---------------------------------------------------------------------
77 /* */
78 void pkgDpkgLock::Close()
79 {
80 close(LockFD);
81 LockFD = -1;
82 }
83 /*}}}*/
84 // DpkgLock::CheckUpdates - Check if the updates dir is dirty /*{{{*/
85 // ---------------------------------------------------------------------
86 /* This does a check of the updates directory to see if it has any entries
87 in it. */
88 bool pkgDpkgLock::CheckUpdates()
89 {
90 // Check for updates.. (dirty)
91 string File = flNotFile(_config->Find("Dir::State::status")) + "updates/";
92 DIR *DirP = opendir(File.c_str());
93 if (DirP == 0)
94 return false;
95
96 /* We ignore any files that are not all digits, this skips .,.. and
97 some tmp files dpkg will leave behind.. */
98 bool Damaged = false;
99 for (struct dirent *Ent = readdir(DirP); Ent != 0; Ent = readdir(DirP))
100 {
101 Damaged = true;
102 for (unsigned int I = 0; Ent->d_name[I] != 0; I++)
103 {
104 // Check if its not a digit..
105 if (isdigit(Ent->d_name[I]) == 0)
106 {
107 Damaged = false;
108 break;
109 }
110 }
111 if (Damaged == true)
112 break;
113 }
114 closedir(DirP);
115
116 return Damaged;
117 }
118 /*}}}*/
119