You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

228 lines
5.9 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007 by Dominic Rath *
  3. * Dominic.Rath@gmx.de *
  4. * *
  5. * Copyright (C) 2007,2008 Øyvind Harboe *
  6. * oyvind.harboe@zylin.com *
  7. * *
  8. * Copyright (C) 2008 by Spencer Oliver *
  9. * spen@spen-soft.co.uk *
  10. * *
  11. * This program is free software; you can redistribute it and/or modify *
  12. * it under the terms of the GNU General Public License as published by *
  13. * the Free Software Foundation; either version 2 of the License, or *
  14. * (at your option) any later version. *
  15. * *
  16. * This program is distributed in the hope that it will be useful, *
  17. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  18. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  19. * GNU General Public License for more details. *
  20. * *
  21. * You should have received a copy of the GNU General Public License *
  22. * along with this program; if not, write to the *
  23. * Free Software Foundation, Inc., *
  24. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
  25. ***************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. #include "config.h"
  28. #endif
  29. #include "log.h"
  30. #include "configuration.h"
  31. #include "fileio.h"
  32. static inline int fileio_open_local(fileio_t *fileio)
  33. {
  34. char access[4];
  35. switch (fileio->access)
  36. {
  37. case FILEIO_READ:
  38. strcpy(access, "r");
  39. break;
  40. case FILEIO_WRITE:
  41. strcpy(access, "w");
  42. break;
  43. case FILEIO_READWRITE:
  44. strcpy(access, "w+");
  45. break;
  46. case FILEIO_APPEND:
  47. strcpy(access, "a");
  48. break;
  49. case FILEIO_APPENDREAD:
  50. strcpy(access, "a+");
  51. break;
  52. default:
  53. LOG_ERROR("BUG: access neither read, write nor readwrite");
  54. return ERROR_INVALID_ARGUMENTS;
  55. }
  56. /* win32 always opens in binary mode */
  57. #ifndef _WIN32
  58. if (fileio->type == FILEIO_BINARY)
  59. #endif
  60. {
  61. strcat(access, "b");
  62. }
  63. if (!(fileio->file = open_file_from_path (fileio->url, access)))
  64. {
  65. LOG_ERROR("couldn't open %s", fileio->url);
  66. return ERROR_FILEIO_OPERATION_FAILED;
  67. }
  68. if ((fileio->access != FILEIO_WRITE) || (fileio->access == FILEIO_READWRITE))
  69. {
  70. /* NB! Here we use fseek() instead of stat(), since stat is a
  71. * more advanced operation that might not apply to e.g. a disk path
  72. * that refers to e.g. a tftp client */
  73. int result, result2;
  74. result = fseek(fileio->file, 0, SEEK_END);
  75. fileio->size = ftell(fileio->file);
  76. result2 = fseek(fileio->file, 0, SEEK_SET);
  77. if ((fileio->size < 0)||(result < 0)||(result2 < 0))
  78. {
  79. fileio_close(fileio);
  80. return ERROR_FILEIO_OPERATION_FAILED;
  81. }
  82. }
  83. else
  84. {
  85. fileio->size = 0x0;
  86. }
  87. return ERROR_OK;
  88. }
  89. int fileio_open(fileio_t *fileio, const char *url, enum fileio_access access, enum fileio_type type)
  90. {
  91. int retval = ERROR_OK;
  92. fileio->type = type;
  93. fileio->access = access;
  94. fileio->url = strdup(url);
  95. retval = fileio_open_local(fileio);
  96. return retval;
  97. }
  98. static inline int fileio_close_local(fileio_t *fileio)
  99. {
  100. int retval;
  101. if ((retval = fclose(fileio->file)) != 0)
  102. {
  103. if (retval == EBADF)
  104. {
  105. LOG_ERROR("BUG: fileio_local->file not a valid file descriptor");
  106. }
  107. else
  108. {
  109. LOG_ERROR("couldn't close %s: %s", fileio->url, strerror(errno));
  110. }
  111. return ERROR_FILEIO_OPERATION_FAILED;
  112. }
  113. return ERROR_OK;
  114. }
  115. int fileio_close(fileio_t *fileio)
  116. {
  117. int retval;
  118. retval = fileio_close_local(fileio);
  119. free(fileio->url);
  120. fileio->url = NULL;
  121. return retval;
  122. }
  123. int fileio_seek(fileio_t *fileio, uint32_t position)
  124. {
  125. int retval;
  126. if ((retval = fseek(fileio->file, position, SEEK_SET)) != 0)
  127. {
  128. LOG_ERROR("couldn't seek file %s: %s", fileio->url, strerror(errno));
  129. return ERROR_FILEIO_OPERATION_FAILED;
  130. }
  131. return ERROR_OK;
  132. }
  133. static inline int fileio_local_read(fileio_t *fileio, uint32_t size, uint8_t *buffer, uint32_t *size_read)
  134. {
  135. *size_read = fread(buffer, 1, size, fileio->file);
  136. return ERROR_OK;
  137. }
  138. int fileio_read(fileio_t *fileio, uint32_t size, uint8_t *buffer, uint32_t *size_read)
  139. {
  140. return fileio_local_read(fileio, size, buffer, size_read);
  141. }
  142. int fileio_read_u32(fileio_t *fileio, uint32_t *data)
  143. {
  144. uint8_t buf[4];
  145. uint32_t size_read;
  146. int retval;
  147. if ((retval = fileio_local_read(fileio, 4, buf, &size_read)) != ERROR_OK)
  148. return retval;
  149. *data = be_to_h_u32(buf);
  150. return ERROR_OK;
  151. }
  152. static inline int fileio_local_fgets(fileio_t *fileio, uint32_t size, char *buffer)
  153. {
  154. if (fgets(buffer, size, fileio->file) == NULL)
  155. return ERROR_FILEIO_OPERATION_FAILED;
  156. return ERROR_OK;
  157. }
  158. int fileio_fgets(fileio_t *fileio, uint32_t size, char *buffer)
  159. {
  160. return fileio_local_fgets(fileio, size, buffer);
  161. }
  162. static inline int fileio_local_write(fileio_t *fileio, uint32_t size, const uint8_t *buffer, uint32_t *size_written)
  163. {
  164. *size_written = fwrite(buffer, 1, size, fileio->file);
  165. return ERROR_OK;
  166. }
  167. int fileio_write(fileio_t *fileio, uint32_t size, const uint8_t *buffer, uint32_t *size_written)
  168. {
  169. int retval;
  170. retval = fileio_local_write(fileio, size, buffer, size_written);
  171. if (retval == ERROR_OK)
  172. fileio->size += *size_written;
  173. return retval;;
  174. }
  175. int fileio_write_u32(fileio_t *fileio, uint32_t data)
  176. {
  177. uint8_t buf[4];
  178. uint32_t size_written;
  179. int retval;
  180. h_u32_to_be(buf, data);
  181. if ((retval = fileio_local_write(fileio, 4, buf, &size_written)) != ERROR_OK)
  182. return retval;
  183. return ERROR_OK;
  184. }