/fig2dev/dev/readpics.c

https://gitlab.com/aschmidt-berlin/fig2dev · C · 156 lines · 94 code · 12 blank · 50 comment · 26 complexity · d9ed0407d1d064cc37a888317ec1d49b MD5 · raw file

  1. /*
  2. * Fig2dev: Translate Fig code to various Devices
  3. * Copyright (c) 1991 by Micah Beck
  4. * Parts Copyright (c) 1985-1988 by Supoj Sutanthavibul
  5. * Parts Copyright (c) 1989-2015 by Brian V. Smith
  6. * Parts Copyright (c) 2015-2019 by Thomas Loimer
  7. *
  8. * Any party obtaining a copy of these files is granted, free of charge, a
  9. * full and unrestricted irrevocable, world-wide, paid up, royalty-free,
  10. * nonexclusive right and license to deal in this software and documentation
  11. * files (the "Software"), including without limitation the rights to use,
  12. * copy, modify, merge, publish, distribute, sublicense and/or sell copies
  13. * of the Software, and to permit persons who receive copies from any such
  14. * party to do so, with the only requirement being that the above copyright
  15. * and this permission notice remain intact.
  16. *
  17. */
  18. /*
  19. * readpics.c: read image files
  20. *
  21. */
  22. #ifdef HAVE_CONFIG_H
  23. #include "config.h"
  24. #endif
  25. #include <stdio.h>
  26. #include <stdlib.h>
  27. #include <string.h>
  28. #include <sys/stat.h>
  29. #include <limits.h>
  30. #include "fig2dev.h" /* includes "bool.h" */
  31. /*
  32. * Open the file 'name' and return its type (real file=0, pipe=1) in 'type'.
  33. * Return the full name in the buffer pointed to by 'retname'.
  34. * The caller must free(*retname) after calling open_picfile()!
  35. * 'retname' will have a .gz, .z or .Z if the file is zipped/compressed. If the
  36. * caller cannot take a pipe (pipeok=false), and the file is compressed,
  37. * uncompress and return name with .z, .Z or .gz stripped.
  38. * The return value is the FILE stream.
  39. */
  40. FILE *
  41. open_picfile(char *name, int *type, bool pipeok, char **retname)
  42. {
  43. char *unc; /* temp buffer for gunzip command */
  44. FILE *fstream; /* handle on file */
  45. struct stat status;
  46. size_t len;
  47. size_t pos;
  48. *type = 0;
  49. len = strlen(name);
  50. *retname = malloc(len + 4);
  51. // *retname[0] = '\0';
  52. if (pipeok) {
  53. unc = malloc(len + 17); /* "gunzip -q -c " name ".gz" */
  54. strcpy(unc, "gunzip -q -c "); /* tell gunzip to output to stdout */
  55. } else {
  56. unc = malloc(len + 14); /* "gunzip -q " name ".gz" */
  57. strcpy(unc, "gunzip -q ");
  58. }
  59. pos = strlen(unc);
  60. if (!stat(name, &status)) {
  61. /* see if the filename ends with .Z or .z or .gz */
  62. if ((len > 3 && !strcmp(".gz", name + (len-3))) ||
  63. (len > 2 && (!strcmp(".z", name + (len-2)) ||
  64. !strcmp(".Z", name + (len-2))))) {
  65. /* yes, make command to uncompress it */
  66. memcpy(unc + pos, name, len + 1); /* strcat(unc, name) */
  67. *type = 1;
  68. } else {
  69. /* use straight name */
  70. *type = 0;
  71. }
  72. memcpy(*retname, name, len + 1); /* strcpy(*retname, name) */
  73. } else {
  74. /* no, see if the file with .gz, .z or .Z appended exists */
  75. /* failing that, if there is an absolute path, strip it and
  76. look in current directory */
  77. /* check for .gz */
  78. memcpy(*retname, name, len);
  79. memcpy(*retname + len, ".gz", (size_t) 4); /* retname = name".gz" */
  80. if (!stat(*retname, &status)) {
  81. /* yes, found with .gz */
  82. memcpy(unc + pos, *retname, len + 4);
  83. *type = 1;
  84. } else {
  85. /* no, check for .z */
  86. memcpy(*retname + len, ".z", (size_t) 3);
  87. if (!stat(*retname, &status)) {
  88. /* yes, found with .z */
  89. memcpy(unc + pos, *retname, len + 3);
  90. *type = 1;
  91. } else {
  92. /* no, check for .Z */
  93. memcpy(*retname + len, ".Z", (size_t) 3);
  94. if (!stat(*retname, &status)) {
  95. /* yes, found with .Z */
  96. memcpy(unc + pos, *retname, len + 3);
  97. *type = 1;
  98. } else {
  99. char *p;
  100. /* can't find it, if there is a path,
  101. strip it and look in current directory */
  102. if ((p = strrchr(name, '/'))) {
  103. /* yes, strip it off */
  104. /* strcpy(*retname, p + 1); */
  105. memcpy(*retname, p + 1, len -= (p - name));
  106. if (!stat(*retname, &status)) {
  107. *type = 0;
  108. memcpy(name, *retname, len);
  109. } else {
  110. /* All is lost */
  111. free(unc);
  112. return NULL;
  113. }
  114. }
  115. }
  116. }
  117. }
  118. }
  119. /* if a pipe, but the caller needs a file, uncompress the file now */
  120. if (*type == 1 && !pipeok) {
  121. char *p;
  122. system(unc);
  123. if ((p = strrchr(*retname,'.'))) {
  124. *p = '\0'; /* terminate name before last .gz, .z or .Z */
  125. }
  126. strcpy(name, *retname);
  127. /* force to plain file now */
  128. *type = 0;
  129. }
  130. if (*type == 0)
  131. fstream = fopen(name, "rb");
  132. else /* *type == 1 */
  133. fstream = popen(unc, "r");
  134. free(unc);
  135. return fstream;
  136. }
  137. void
  138. close_picfile(FILE *file, int type)
  139. {
  140. if (type == 0)
  141. fclose(file);
  142. else
  143. pclose(file);
  144. }