cdromutl.cc 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. // -*- mode: cpp; mode: fold -*-
  2. // Description /*{{{*/
  3. // $Id: cdromutl.cc,v 1.1 1998/11/29 01:19:27 jgg Exp $
  4. /* ######################################################################
  5. CDROM Utilities - Some functions to manipulate CDROM mounts.
  6. These are here for the cdrom method and apt-cdrom.
  7. ##################################################################### */
  8. /*}}}*/
  9. // Include Files /*{{{*/
  10. #ifdef __GNUG__
  11. #pragma implementation "apt-pkg/cdromutl.h"
  12. #endif
  13. #include <apt-pkg/cdromutl.h>
  14. #include <apt-pkg/error.h>
  15. #include <apt-pkg/md5.h>
  16. #include <apt-pkg/fileutl.h>
  17. #include <sys/wait.h>
  18. #include <sys/errno.h>
  19. #include <sys/vfs.h>
  20. #include <dirent.h>
  21. #include <fcntl.h>
  22. #include <unistd.h>
  23. #include <stdio.h>
  24. /*}}}*/
  25. // UnmountCdrom - Unmount a cdrom /*{{{*/
  26. // ---------------------------------------------------------------------
  27. /* Forking umount works much better than the umount syscall which can
  28. leave /etc/mtab inconsitant. We drop all messages this produces. */
  29. bool UnmountCdrom(string Path)
  30. {
  31. int Child = fork();
  32. if (Child < -1)
  33. return _error->Errno("fork","Failed to fork");
  34. // The child
  35. if (Child == 0)
  36. {
  37. // Make all the fds /dev/null
  38. for (int I = 0; I != 10; I++)
  39. close(I);
  40. for (int I = 0; I != 3; I++)
  41. dup2(open("/dev/null",O_RDWR),I);
  42. const char *Args[10];
  43. Args[0] = "umount";
  44. Args[1] = Path.c_str();
  45. Args[2] = 0;
  46. execvp(Args[0],(char **)Args);
  47. exit(100);
  48. }
  49. // Wait for mount
  50. int Status = 0;
  51. while (waitpid(Child,&Status,0) != Child)
  52. {
  53. if (errno == EINTR)
  54. continue;
  55. return _error->Errno("waitpid","Couldn't wait for subprocess");
  56. }
  57. // Check for an error code.
  58. if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
  59. return false;
  60. return true;
  61. }
  62. /*}}}*/
  63. // MountCdrom - Mount a cdrom /*{{{*/
  64. // ---------------------------------------------------------------------
  65. /* We fork mount and drop all messages */
  66. bool MountCdrom(string Path)
  67. {
  68. int Child = fork();
  69. if (Child < -1)
  70. return _error->Errno("fork","Failed to fork");
  71. // The child
  72. if (Child == 0)
  73. {
  74. // Make all the fds /dev/null
  75. for (int I = 0; I != 10; I++)
  76. close(I);
  77. for (int I = 0; I != 3; I++)
  78. dup2(open("/dev/null",O_RDWR),I);
  79. const char *Args[10];
  80. Args[0] = "mount";
  81. Args[1] = Path.c_str();
  82. Args[2] = 0;
  83. execvp(Args[0],(char **)Args);
  84. exit(100);
  85. }
  86. // Wait for mount
  87. int Status = 0;
  88. while (waitpid(Child,&Status,0) != Child)
  89. {
  90. if (errno == EINTR)
  91. continue;
  92. return _error->Errno("waitpid","Couldn't wait for subprocess");
  93. }
  94. // Check for an error code.
  95. if (WIFEXITED(Status) == 0 || WEXITSTATUS(Status) != 0)
  96. return false;
  97. return true;
  98. }
  99. /*}}}*/
  100. // IdentCdrom - Generate a unique string for this CD /*{{{*/
  101. // ---------------------------------------------------------------------
  102. /* We convert everything we hash into a string, this prevents byte size/order
  103. from effecting the outcome. */
  104. bool IdentCdrom(string CD,string &Res)
  105. {
  106. MD5Summation Hash;
  107. string StartDir = SafeGetCWD();
  108. if (chdir(CD.c_str()) != 0)
  109. return _error->Errno("chdir","Unable to change to %s",CD.c_str());
  110. DIR *D = opendir(".");
  111. if (D == 0)
  112. return _error->Errno("opendir","Unable to read %s",CD.c_str());
  113. // Run over the directory
  114. char S[300];
  115. for (struct dirent *Dir = readdir(D); Dir != 0; Dir = readdir(D))
  116. {
  117. // Skip some files..
  118. if (strcmp(Dir->d_name,".") == 0 ||
  119. strcmp(Dir->d_name,"..") == 0)
  120. continue;
  121. sprintf(S,"%lu",Dir->d_ino);
  122. Hash.Add(S);
  123. Hash.Add(Dir->d_name);
  124. };
  125. chdir(StartDir.c_str());
  126. closedir(D);
  127. // Some stats from the fsys
  128. struct statfs Buf;
  129. if (statfs(CD.c_str(),&Buf) != 0)
  130. return _error->Errno("statfs","Failed to stat the cdrom");
  131. sprintf(S,"%u %u",Buf.f_blocks,Buf.f_bfree);
  132. Hash.Add(S);
  133. Res = Hash.Result().Value();
  134. return true;
  135. }
  136. /*}}}*/