]> git.saurik.com Git - apt.git/blob - apt-pkg/contrib/cdromutl.cc
Changed ie to eg
[apt.git] / apt-pkg / contrib / cdromutl.cc
1 // -*- mode: cpp; mode: fold -*-
2 // Description /*{{{*/
3 // $Id: cdromutl.cc,v 1.2 1999/03/28 01:37:26 jgg Exp $
4 /* ######################################################################
5
6 CDROM Utilities - Some functions to manipulate CDROM mounts.
7
8 These are here for the cdrom method and apt-cdrom.
9
10 ##################################################################### */
11 /*}}}*/
12 // Include Files /*{{{*/
13 #ifdef __GNUG__
14 #pragma implementation "apt-pkg/cdromutl.h"
15 #endif
16 #include <apt-pkg/cdromutl.h>
17 #include <apt-pkg/error.h>
18 #include <apt-pkg/md5.h>
19 #include <apt-pkg/fileutl.h>
20
21 #include <sys/wait.h>
22 #include <sys/errno.h>
23 #include <sys/vfs.h>
24 #include <dirent.h>
25 #include <fcntl.h>
26 #include <sys/stat.h>
27 #include <unistd.h>
28 #include <stdio.h>
29 /*}}}*/
30
31 // UnmountCdrom - Unmount a cdrom /*{{{*/
32 // ---------------------------------------------------------------------
33 /* Forking umount works much better than the umount syscall which can
34 leave /etc/mtab inconsitant. We drop all messages this produces. */
35 bool UnmountCdrom(string Path)
36 {
37 if (Path.empty() == true)
38 return false;
39
40 // Need that trailing slash for directories
41 if (Path[Path.length() - 1] != '/')
42 Path += '/';
43
44 /* First we check if the path is actualy mounted, we do this by
45 stating the path and the previous directory (carefull of links!)
46 and comparing their device fields. */
47 struct stat Buf,Buf2;
48 if (stat(Path.c_str(),&Buf) != 0 ||
49 stat((Path + "../").c_str(),&Buf2) != 0)
50 return _error->Errno("stat","Unable to stat the mount point %s",Path.c_str());
51
52 if (Buf.st_dev == Buf2.st_dev)
53 return true;
54
55 int Child = fork();
56 if (Child < -1)
57 return _error->Errno("fork","Failed to fork");
58
59 // The child
60 if (Child == 0)
61 {
62 // Make all the fds /dev/null
63 for (int I = 0; I != 10; I++)
64 close(I);
65 for (int I = 0; I != 3; I++)
66 dup2(open("/dev/null",O_RDWR),I);
67
68 const char *Args[10];
69 Args[0] = "umount";
70 Args[1] = Path.c_str();
71 Args[2] = 0;
72 execvp(Args[0],(char **)Args);
73 exit(100);
74 }
75
76 // Wait for mount
77 int Status = 0;
78 while (waitpid(Child,&Status,0) != Child)
79 {
80 if (errno == EINTR)
81 continue;
82 return _error->Errno("waitpid","Couldn't wait for subprocess");
83 }
84
85 // Check for an error code.
86 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
87 return false;
88 return true;
89 }
90 /*}}}*/
91 // MountCdrom - Mount a cdrom /*{{{*/
92 // ---------------------------------------------------------------------
93 /* We fork mount and drop all messages */
94 bool MountCdrom(string Path)
95 {
96 int Child = fork();
97 if (Child < -1)
98 return _error->Errno("fork","Failed to fork");
99
100 // The child
101 if (Child == 0)
102 {
103 // Make all the fds /dev/null
104 for (int I = 0; I != 10; I++)
105 close(I);
106 for (int I = 0; I != 3; I++)
107 dup2(open("/dev/null",O_RDWR),I);
108
109 const char *Args[10];
110 Args[0] = "mount";
111 Args[1] = Path.c_str();
112 Args[2] = 0;
113 execvp(Args[0],(char **)Args);
114 exit(100);
115 }
116
117 // Wait for mount
118 int Status = 0;
119 while (waitpid(Child,&Status,0) != Child)
120 {
121 if (errno == EINTR)
122 continue;
123 return _error->Errno("waitpid","Couldn't wait for subprocess");
124 }
125
126 // Check for an error code.
127 if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
128 return false;
129 return true;
130 }
131 /*}}}*/
132 // IdentCdrom - Generate a unique string for this CD /*{{{*/
133 // ---------------------------------------------------------------------
134 /* We convert everything we hash into a string, this prevents byte size/order
135 from effecting the outcome. */
136 bool IdentCdrom(string CD,string &Res)
137 {
138 MD5Summation Hash;
139
140 string StartDir = SafeGetCWD();
141 if (chdir(CD.c_str()) != 0)
142 return _error->Errno("chdir","Unable to change to %s",CD.c_str());
143
144 DIR *D = opendir(".");
145 if (D == 0)
146 return _error->Errno("opendir","Unable to read %s",CD.c_str());
147
148 /* Run over the directory, we assume that the reader order will never
149 change as the media is read-only. In theory if the kernel did
150 some sort of wacked caching this might not be true.. */
151 char S[300];
152 for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
153 {
154 // Skip some files..
155 if (strcmp(Dir->d_name,".") == 0 ||
156 strcmp(Dir->d_name,"..") == 0)
157 continue;
158
159 sprintf(S,"%lu",Dir->d_ino);
160 Hash.Add(S);
161 Hash.Add(Dir->d_name);
162 };
163
164 chdir(StartDir.c_str());
165 closedir(D);
166
167 // Some stats from the fsys
168 struct statfs Buf;
169 if (statfs(CD.c_str(),&Buf) != 0)
170 return _error->Errno("statfs","Failed to stat the cdrom");
171
172 // We use a kilobyte block size to advoid overflow
173 sprintf(S,"%u %u",Buf.f_blocks*(Buf.f_bsize/1024),
174 Buf.f_bfree*(Buf.f_bsize/1024));
175 Hash.Add(S);
176
177 Res = Hash.Result().Value();
178 return true;
179 }
180 /*}}}*/