]>
git.saurik.com Git - apt.git/blob - apt-pkg/contrib/cdromutl.cc
1 // -*- mode: cpp; mode: fold -*-
3 // $Id: cdromutl.cc,v 1.2 1999/03/28 01:37:26 jgg Exp $
4 /* ######################################################################
6 CDROM Utilities - Some functions to manipulate CDROM mounts.
8 These are here for the cdrom method and apt-cdrom.
10 ##################################################################### */
12 // Include Files /*{{{*/
14 #pragma implementation "apt-pkg/cdromutl.h"
16 #include <apt-pkg/cdromutl.h>
17 #include <apt-pkg/error.h>
18 #include <apt-pkg/md5.h>
19 #include <apt-pkg/fileutl.h>
22 #include <sys/errno.h>
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
)
37 if (Path
.empty() == true)
40 // Need that trailing slash for directories
41 if (Path
[Path
.length() - 1] != '/')
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. */
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());
52 if (Buf
.st_dev
== Buf2
.st_dev
)
57 return _error
->Errno("fork","Failed to fork");
62 // Make all the fds /dev/null
63 for (int I
= 0; I
!= 10; I
++)
65 for (int I
= 0; I
!= 3; I
++)
66 dup2(open("/dev/null",O_RDWR
),I
);
70 Args
[1] = Path
.c_str();
72 execvp(Args
[0],(char **)Args
);
78 while (waitpid(Child
,&Status
,0) != Child
)
82 return _error
->Errno("waitpid","Couldn't wait for subprocess");
85 // Check for an error code.
86 if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0)
91 // MountCdrom - Mount a cdrom /*{{{*/
92 // ---------------------------------------------------------------------
93 /* We fork mount and drop all messages */
94 bool MountCdrom(string Path
)
98 return _error
->Errno("fork","Failed to fork");
103 // Make all the fds /dev/null
104 for (int I
= 0; I
!= 10; I
++)
106 for (int I
= 0; I
!= 3; I
++)
107 dup2(open("/dev/null",O_RDWR
),I
);
109 const char *Args
[10];
111 Args
[1] = Path
.c_str();
113 execvp(Args
[0],(char **)Args
);
119 while (waitpid(Child
,&Status
,0) != Child
)
123 return _error
->Errno("waitpid","Couldn't wait for subprocess");
126 // Check for an error code.
127 if (WIFEXITED(Status
) == 0 || WEXITSTATUS(Status
) != 0)
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
)
140 string StartDir
= SafeGetCWD();
141 if (chdir(CD
.c_str()) != 0)
142 return _error
->Errno("chdir","Unable to change to %s",CD
.c_str());
144 DIR *D
= opendir(".");
146 return _error
->Errno("opendir","Unable to read %s",CD
.c_str());
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.. */
152 for (struct dirent
*Dir
= readdir(D
); Dir
!= 0; Dir
= readdir(D
))
155 if (strcmp(Dir
->d_name
,".") == 0 ||
156 strcmp(Dir
->d_name
,"..") == 0)
159 sprintf(S
,"%lu",Dir
->d_ino
);
161 Hash
.Add(Dir
->d_name
);
164 chdir(StartDir
.c_str());
167 // Some stats from the fsys
169 if (statfs(CD
.c_str(),&Buf
) != 0)
170 return _error
->Errno("statfs","Failed to stat the cdrom");
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));
177 Res
= Hash
.Result().Value();