Leaked source code of windows server 2003
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.

299 lines
8.5 KiB

  1. /*
  2. *
  3. * Basic file I/O routines.
  4. */
  5. #include "stevie.h"
  6. #include <io.h>
  7. #include <errno.h>
  8. void
  9. filemess(s)
  10. char *s;
  11. {
  12. smsg("\"%s\" %s", (Filename == NULL) ? "" : Filename, s);
  13. flushbuf();
  14. }
  15. void
  16. renum()
  17. {
  18. LNPTR *p;
  19. unsigned long l = 0;
  20. for (p = Filemem; p != NULL ;p = nextline(p), l += LINEINC)
  21. if (p->linep)
  22. p->linep->num = l;
  23. Fileend->linep->num = 0xffffffff;
  24. }
  25. #define MAXLINE 512 /* maximum size of a line */
  26. bool_t
  27. readfile(fname,fromp,nochangename)
  28. char *fname;
  29. LNPTR *fromp;
  30. bool_t nochangename; /* if TRUE, don't change the Filename */
  31. {
  32. FILE *f;
  33. register LINE *curr;
  34. char buff[MAXLINE], buf2[80];
  35. register int i, c;
  36. register long nchars = 0;
  37. int linecnt = 0;
  38. bool_t wasempty = bufempty();
  39. int nulls = 0; /* count nulls */
  40. bool_t incomplete = FALSE; /* was the last line incomplete? */
  41. bool_t toolong = FALSE; /* a line was too long */
  42. int ctoolong = 0;
  43. bool_t readonly = FALSE; /* file is not writable */
  44. curr = fromp->linep;
  45. if ( ! nochangename ) {
  46. Filename = strsave(fname);
  47. setviconsoletitle();
  48. }
  49. if((_access(fname,2) == -1) && (errno == EACCES)) {
  50. readonly = TRUE;
  51. }
  52. {
  53. char *FixedName = fixname(fname);
  54. if (!FixedName) {
  55. return TRUE;
  56. }
  57. if ( (f=fopen(FixedName,"r")) == NULL )
  58. return TRUE;
  59. }
  60. filemess("");
  61. i = 0;
  62. do {
  63. c = getc(f);
  64. if (c == EOF) {
  65. if (i == 0) /* normal loop termination */
  66. break;
  67. /*
  68. * If we get EOF in the middle of a line, note the
  69. * fact and complete the line ourselves.
  70. */
  71. incomplete = TRUE;
  72. c = NL;
  73. }
  74. /*
  75. * Abort if we get an interrupt, but finished reading the
  76. * current line first.
  77. */
  78. if (got_int && i == 0)
  79. break;
  80. /*
  81. * If we reached the end of the line, OR we ran out of
  82. * space for it, then process the complete line.
  83. */
  84. if (c == NL || i == (MAXLINE-1)) {
  85. LINE *lp;
  86. if (c != NL) {
  87. toolong = TRUE;
  88. ctoolong++;
  89. }
  90. buff[i] = '\0';
  91. if ((lp = newline(strlen(buff))) == NULL)
  92. exit(1);
  93. strcpy(lp->s, buff);
  94. curr->next->prev = lp; /* new line to next one */
  95. lp->next = curr->next;
  96. curr->next = lp; /* new line to prior one */
  97. lp->prev = curr;
  98. curr = lp; /* new line becomes current */
  99. i = 0;
  100. linecnt++;
  101. if (toolong) {
  102. buff[i++] = (char)c;
  103. toolong = FALSE;
  104. }
  105. } else if (c == NUL)
  106. nulls++; /* count and ignore nulls */
  107. else {
  108. buff[i++] = (char)c; /* normal character */
  109. }
  110. nchars++;
  111. } while (!incomplete);
  112. fclose(f);
  113. /*
  114. * If the buffer was empty when we started, we have to go back
  115. * and remove the "dummy" line at Filemem and patch up the ptrs.
  116. */
  117. if (wasempty && nchars != 0) {
  118. LINE *dummy = Filemem->linep; /* dummy line ptr */
  119. free(dummy->s); /* free string space */
  120. Filemem->linep = Filemem->linep->next;
  121. free((char *)dummy); /* free LINE struct */
  122. Filemem->linep->prev = Filetop->linep;
  123. Filetop->linep->next = Filemem->linep;
  124. Curschar->linep = Filemem->linep;
  125. Topchar->linep = Filemem->linep;
  126. }
  127. renum();
  128. if (got_int) {
  129. smsg("\"%s\" Interrupt", fname);
  130. got_int = FALSE;
  131. return FALSE; /* an interrupt isn't really an error */
  132. }
  133. if (ctoolong != 0) {
  134. smsg("\"%s\" %d Line(s) too long - split", fname, ctoolong);
  135. return FALSE;
  136. }
  137. sprintf(buff, "\"%s\" %s%s%d line%s, %ld character%s",
  138. fname,
  139. readonly ? "[Read only] " : "",
  140. incomplete ? "[Incomplete last line] " : "",
  141. linecnt, (linecnt != 1) ? "s" : "",
  142. nchars, (nchars != 1) ? "s" : "");
  143. buf2[0] = NUL;
  144. if (nulls) {
  145. sprintf(buf2, " (%d null)", nulls);
  146. }
  147. strcat(buff, buf2);
  148. msg(buff);
  149. return FALSE;
  150. }
  151. /*
  152. * writeit - write to file 'fname' lines 'start' through 'end'
  153. *
  154. * If either 'start' or 'end' contain null line pointers, the default
  155. * is to use the start or end of the file respectively.
  156. */
  157. bool_t
  158. writeit(fname, start, end)
  159. char *fname;
  160. LNPTR *start, *end;
  161. {
  162. FILE *f;
  163. FILE *fopenb(); /* open in binary mode, where needed */
  164. char *backup;
  165. register char *s;
  166. register long nchars;
  167. register int lines;
  168. register LNPTR *p;
  169. if((_access(fname,2) == -1) && (errno == EACCES)) {
  170. msg("Write access to file is denied");
  171. return FALSE;
  172. }
  173. smsg("\"%s\"", fname);
  174. /*
  175. * Form the backup file name - change foo.* to foo.bak
  176. */
  177. backup = alloc((unsigned) (strlen(fname) + 5));
  178. strcpy(backup, fname);
  179. for (s = backup; *s && *s != '.' ;s++)
  180. ;
  181. *s = NUL;
  182. strcat(backup, ".bak");
  183. /*
  184. * Delete any existing backup and move the current version
  185. * to the backup. For safety, we don't remove the backup
  186. * until the write has finished successfully. And if the
  187. * 'backup' option is set, leave it around.
  188. */
  189. rename(fname, backup);
  190. {
  191. char *FixedName = fixname(fname);
  192. if (!FixedName) {
  193. f= NULL;
  194. } else {
  195. f = P(P_CR) ? fopen(FixedName, "w") : fopenb(FixedName, "w");
  196. }
  197. }
  198. if (f == NULL) {
  199. emsg("Can't open file for writing!");
  200. free(backup);
  201. return FALSE;
  202. }
  203. /*
  204. * If we were given a bound, start there. Otherwise just
  205. * start at the beginning of the file.
  206. */
  207. if (start == NULL || start->linep == NULL)
  208. p = Filemem;
  209. else
  210. p = start;
  211. lines = nchars = 0;
  212. do {
  213. if (p->linep) {
  214. if (fprintf(f, "%s\n", p->linep->s) < 0) {
  215. emsg("Can't write file!");
  216. return FALSE;
  217. }
  218. nchars += strlen(p->linep->s) + 1;
  219. lines++;
  220. }
  221. /*
  222. * If we were given an upper bound, and we just did that
  223. * line, then bag it now.
  224. */
  225. if (end != NULL && end->linep != NULL) {
  226. if (end->linep == p->linep)
  227. break;
  228. }
  229. } while ((p = nextline(p)) != NULL);
  230. fclose(f);
  231. smsg("\"%s\" %d line%s, %ld character%s", fname,
  232. lines, (lines > 1) ? "s" : "",
  233. nchars, (nchars > 1) ? "s" : "");
  234. UNCHANGED;
  235. /*
  236. * Remove the backup unless they want it left around
  237. */
  238. if (!P(P_BK))
  239. remove(backup);
  240. free(backup);
  241. return TRUE;
  242. }