io_posix.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /*
  2. This file is part of ethash.
  3. ethash is free software: you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation, either version 3 of the License, or
  6. (at your option) any later version.
  7. ethash is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with ethash. If not, see <http://www.gnu.org/licenses/>.
  13. */
  14. /** @file io_posix.c
  15. * @author Lefteris Karapetsas <lefteris@ethdev.com>
  16. * @date 2015
  17. */
  18. #include "io.h"
  19. #include <sys/types.h>
  20. #include <sys/stat.h>
  21. #include <errno.h>
  22. #include <libgen.h>
  23. #include <stdio.h>
  24. #include <unistd.h>
  25. #include <stdlib.h>
  26. #include <pwd.h>
  27. FILE* ethash_fopen(char const* file_name, char const* mode)
  28. {
  29. return fopen(file_name, mode);
  30. }
  31. char* ethash_strncat(char* dest, size_t dest_size, char const* src, size_t count)
  32. {
  33. return strlen(dest) + count + 1 <= dest_size ? strncat(dest, src, count) : NULL;
  34. }
  35. bool ethash_mkdir(char const* dirname)
  36. {
  37. int rc = mkdir(dirname, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
  38. return rc != -1 || errno == EEXIST;
  39. }
  40. int ethash_fileno(FILE *f)
  41. {
  42. return fileno(f);
  43. }
  44. char* ethash_io_create_filename(
  45. char const* dirname,
  46. char const* filename,
  47. size_t filename_length
  48. )
  49. {
  50. size_t dirlen = strlen(dirname);
  51. size_t dest_size = dirlen + filename_length + 1;
  52. if (dirname[dirlen] != '/') {
  53. dest_size += 1;
  54. }
  55. char* name = malloc(dest_size);
  56. if (!name) {
  57. return NULL;
  58. }
  59. name[0] = '\0';
  60. ethash_strncat(name, dest_size, dirname, dirlen);
  61. if (dirname[dirlen] != '/') {
  62. ethash_strncat(name, dest_size, "/", 1);
  63. }
  64. ethash_strncat(name, dest_size, filename, filename_length);
  65. return name;
  66. }
  67. bool ethash_file_size(FILE* f, size_t* ret_size)
  68. {
  69. struct stat st;
  70. int fd;
  71. if ((fd = fileno(f)) == -1 || fstat(fd, &st) != 0) {
  72. return false;
  73. }
  74. *ret_size = st.st_size;
  75. return true;
  76. }
  77. bool ethash_get_default_dirname(char* strbuf, size_t buffsize)
  78. {
  79. static const char dir_suffix[] = ".ethash/";
  80. strbuf[0] = '\0';
  81. char* home_dir = getenv("HOME");
  82. if (!home_dir || strlen(home_dir) == 0)
  83. {
  84. struct passwd* pwd = getpwuid(getuid());
  85. if (pwd)
  86. home_dir = pwd->pw_dir;
  87. if (!home_dir)
  88. return false;
  89. }
  90. size_t len = strlen(home_dir);
  91. if (!ethash_strncat(strbuf, buffsize, home_dir, len)) {
  92. return false;
  93. }
  94. if (home_dir[len] != '/') {
  95. if (!ethash_strncat(strbuf, buffsize, "/", 1)) {
  96. return false;
  97. }
  98. }
  99. return ethash_strncat(strbuf, buffsize, dir_suffix, sizeof(dir_suffix));
  100. }