1
0

checksum.c 1.6 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091
  1. #define word char
  2. #include "lib/math.c"
  3. #include "lib/stdlib.c"
  4. #include "lib/sys.c"
  5. #include "lib/brfs.c"
  6. int main()
  7. {
  8. // Read number of arguments
  9. word argc = shell_argc();
  10. if (argc < 2)
  11. {
  12. bdos_println("Usage: checksum <file>");
  13. return 1;
  14. }
  15. // Read filename
  16. char** args = shell_argv();
  17. char* filename = args[1];
  18. char absolute_path[MAX_PATH_LENGTH];
  19. // Check if absolute path
  20. if (filename[0] != '/')
  21. {
  22. char* cwd = fs_getcwd();
  23. strcpy(absolute_path, cwd);
  24. strcat(absolute_path, "/");
  25. strcat(absolute_path, filename);
  26. }
  27. else
  28. {
  29. strcpy(absolute_path, filename);
  30. }
  31. // Get file size
  32. struct brfs_dir_entry* entry = (struct brfs_dir_entry*)fs_stat(absolute_path);
  33. if ((word)entry == -1)
  34. {
  35. bdos_println("File not found");
  36. return 1;
  37. }
  38. word filesize = entry->filesize;
  39. // Open file
  40. word fd = fs_open(absolute_path);
  41. if (fd == -1)
  42. {
  43. bdos_println("File not found");
  44. return 1;
  45. }
  46. // Read file in chunks of 128 words
  47. word checksum = filesize;
  48. word buffer[128];
  49. word read;
  50. word i;
  51. // BUG: this will not work for files smaller than 128 words
  52. // Look at webserv for better way
  53. while (filesize > 0)
  54. {
  55. read = fs_read(fd, (char*)buffer, 128);
  56. for (i = 0; i < read; i++)
  57. {
  58. checksum += buffer[i];
  59. }
  60. filesize -= read;
  61. }
  62. // Close file
  63. fs_close(fd);
  64. // Print checksum
  65. bdos_print("Checksum: ");
  66. bdos_printhex(checksum);
  67. bdos_println("");
  68. return 'q';
  69. }
  70. void interrupt()
  71. {
  72. // Handle all interrupts
  73. word i = get_int_id();
  74. switch(i)
  75. {
  76. case INTID_TIMER1:
  77. timer1Value = 1; // Notify ending of timer1
  78. break;
  79. }
  80. }