/isomd5sum-1.0.9/checkisomd5.c

# · C · 178 lines · 123 code · 34 blank · 21 comment · 18 complexity · fbc5f1f8cdf18bb7035afb6f20a3f38c MD5 · raw file

  1. /*
  2. * checkosmd5 - simple program to check implanted md5sum
  3. * Copyright (C) 2001-2007 Red Hat, Inc.
  4. * Michael Fulbright <msf@redhat.com>
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  19. */
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22. #include <string.h>
  23. #include <popt.h>
  24. #include <termios.h>
  25. #include "md5.h"
  26. #include "libcheckisomd5.h"
  27. struct progressCBData {
  28. int verbose;
  29. int gauge;
  30. int gaugeat;
  31. };
  32. int user_bailing_out() {
  33. int retval = 0;
  34. struct timeval timev;
  35. fd_set rfds;
  36. char ch;
  37. FD_ZERO(&rfds);
  38. FD_SET(0,&rfds);
  39. timev.tv_sec = 0;
  40. timev.tv_usec = 0;
  41. if (select(1, &rfds, NULL, NULL, &timev))
  42. if ((ch = getchar()) == 27)
  43. retval = 1;
  44. return retval;
  45. }
  46. static int outputCB(void *co, long long offset, long long total) {
  47. struct progressCBData *data = co;
  48. int gaugeval = -1;
  49. if (data->verbose) {
  50. printf("\rChecking: %05.1f%%", (100.0*offset)/(total));
  51. fflush(stdout);
  52. }
  53. if (data->gauge) {
  54. gaugeval = (100.0*offset)/(total);
  55. if (gaugeval != data->gaugeat) {
  56. printf("%d\n", gaugeval);
  57. fflush(stdout);
  58. data->gaugeat = gaugeval;
  59. }
  60. }
  61. return user_bailing_out();
  62. }
  63. static void usage(void) {
  64. fprintf(stderr, "Usage: checkisomd5 [--md5sumonly] [--verbose] [--gauge] <isofilename>|<blockdevice>\n\n");
  65. exit(1);
  66. }
  67. /* Process the result code and return the proper exit status value
  68. */
  69. int processExitStatus(int rc) {
  70. char * result;
  71. switch (rc) {
  72. case ISOMD5SUM_CHECK_FAILED:
  73. result = "FAIL.\n\nIt is not recommended to use this media.";
  74. break;
  75. case ISOMD5SUM_CHECK_ABORTED:
  76. result = "UNKNOWN.\n\nThe media check was aborted.";
  77. break;
  78. case ISOMD5SUM_CHECK_NOT_FOUND:
  79. result = "NA.\n\nNo checksum information available, unable to verify media.";
  80. break;
  81. case ISOMD5SUM_FILE_NOT_FOUND:
  82. result = "NA.\n\nFile not found.";
  83. break;
  84. case ISOMD5SUM_CHECK_PASSED:
  85. result = "PASS.\n\nIt is OK to use this media.";
  86. break;
  87. default:
  88. result = "checkisomd5 ERROR - bad return value";
  89. break;
  90. }
  91. fprintf(stderr, "\nThe media check is complete, the result is: %s\n", result);
  92. return(rc != ISOMD5SUM_CHECK_PASSED);
  93. }
  94. int main(int argc, char **argv) {
  95. int rc;
  96. const char **args;
  97. int md5only;
  98. int help;
  99. struct progressCBData data;
  100. poptContext optCon;
  101. memset(&data, 0, sizeof(struct progressCBData));
  102. md5only = 0;
  103. help = 0;
  104. data.verbose = 0;
  105. data.gauge = 0;
  106. struct poptOption options[] = {
  107. { "md5sumonly", 'o', POPT_ARG_NONE, &md5only, 0 },
  108. { "verbose", 'v', POPT_ARG_NONE, &data.verbose, 0 },
  109. { "gauge", 'g', POPT_ARG_NONE, &data.gauge, 0},
  110. { "help", 'h', POPT_ARG_NONE, &help, 0},
  111. { 0, 0, 0, 0, 0}
  112. };
  113. static struct termios oldt, newt;
  114. optCon = poptGetContext("checkisomd5", argc, (const char **)argv, options, 0);
  115. if ((rc = poptGetNextOpt(optCon)) < -1) {
  116. fprintf(stderr, "bad option %s: %s\n",
  117. poptBadOption(optCon, POPT_BADOPTION_NOALIAS),
  118. poptStrerror(rc));
  119. exit(1);
  120. }
  121. if (help)
  122. usage();
  123. args = poptGetArgs(optCon);
  124. if (!args || !args[0] || !args[0][0])
  125. usage();
  126. if (md5only|data.verbose) {
  127. rc = printMD5SUM((char *)args[0]);
  128. if (rc < 0) {
  129. exit(processExitStatus(rc));
  130. }
  131. }
  132. if (md5only)
  133. exit(0);
  134. printf("Press [Esc] to abort check.\n");
  135. tcgetattr(0, &oldt);
  136. newt = oldt;
  137. newt.c_lflag &= ~(ICANON | ECHO | ECHONL | ISIG | IEXTEN);
  138. tcsetattr(0, TCSANOW, &newt);
  139. rc = mediaCheckFile((char *)args[0], outputCB, &data);
  140. tcsetattr(0, TCSANOW, &oldt);
  141. if (data.verbose)
  142. printf("\n");
  143. exit(processExitStatus(rc));
  144. }