Makefile: simplify, and respect DESTDIR and CPPFLAGS
[rofl0r-hexedit0r.git] / file.c
blobb14fa4fbba5892238c308f67b3d4be8196644868
1 /* hexedit -- Hexadecimal Editor for Binary Files
2 Copyright (C) 1998 Pixel (Pascal Rigaux)
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2, or (at your option)
7 any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, write to the Free Software
16 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.*/
17 #include "hexedit.h"
19 void openFile(void)
21 struct stat st;
23 if (!is_file(fileName)) {
24 fprintf(stderr, "%s: %s: Not a file.\n", progName, fileName);
25 exit(1);
28 /* edited should be cleaned here (assert(edited == NULL)) */
29 if ((fd = open(fileName, O_RDWR)) == -1) {
30 isReadOnly = TRUE;
31 if ((fd = open(fileName, O_RDONLY)) == -1) {
32 if (page) exitCurses();
33 if (fileName[0] == '-') DIE(usage);
34 fprintf(stderr, "%s: ", progName);
35 perror(fileName);
36 exit(1);
38 } else isReadOnly = FALSE;
39 baseName = basename(fileName);
40 mark_set = FALSE;
41 lastEditedLoc = base = cursor = cursorOffset = 0;
43 /* check file size- doesn't work on devices. I considered implementing a conquer-and-divide algorithm, but it would unpleasant on tape drives and such. */
44 if (fstat(fd, &st) != -1 && st.st_size > 0)
45 fileSize = st.st_size;
46 else {
47 #ifdef BLKGETSIZE
48 unsigned long i;
49 if (ioctl(fd, BLKGETSIZE, &i) == 0)
50 fileSize = (INT) i * 512;
51 else
52 #endif
53 fileSize = 0;
55 biggestLoc = fileSize;
58 void readFile(void)
60 typePage *p;
61 INT i;
63 memset(buffer, 0, page * sizeof(*buffer));
65 LSEEK(fd, base);
66 nbBytes = read(fd, buffer, page);
67 if (nbBytes < 0)
68 nbBytes = 0;
69 else if (nbBytes && base + nbBytes > biggestLoc)
70 biggestLoc = base + nbBytes;
71 memset(bufferAttr, A_NORMAL, page * sizeof(*bufferAttr));
72 for (p = edited; p; p = p->next) {
73 for (i = MAX(base, p->base); i < MIN(p->base + p->size, base + page); i++) {
74 if (buffer[i - base] != p->vals[i - p->base]) {
75 buffer[i - base] = p->vals[i - p->base];
76 bufferAttr[i - base] |= MODIFIED;
79 if (p->base + p->size > base + nbBytes) { /* Check for modifications past EOF */
80 for(; p->base + p->size > base + nbBytes && nbBytes < page; nbBytes++)
81 bufferAttr[nbBytes] |= MODIFIED;
84 if (mark_set) markSelectedRegion();
88 int findFile(void)
90 char *p, tmp[BLOCK_SEARCH_SIZE];
91 p = lastFindFile ? strdup(lastFindFile) : NULL;
92 if (!displayMessageAndGetString("File name: ", &p, tmp, sizeof(tmp))) return FALSE;
93 if (!is_file(tmp)) return FALSE;
94 FREE(lastFindFile); lastFindFile = fileName;
95 fileName = p;
96 return TRUE;
100 INT getfilesize(void)
102 return MAX(lastEditedLoc, biggestLoc);
106 /* tryloc:
107 * returns TRUE if loc is an apropriate location to place the cursor
108 * assumes the file won't shrink.
109 * returns TRUE if the cursor is one past EOF to allow appending
112 int tryloc(INT loc)
114 char c;
115 if (loc < 0)
116 return FALSE;
117 if (loc <= lastEditedLoc)
118 return TRUE;
120 if (loc <= biggestLoc)
121 return TRUE;
123 if (LSEEK_(fd, loc - 1) != -1 && /* don't have to worry about loc - 1 < 0 */
124 read(fd, &c, 1) == 1) {
125 biggestLoc = loc;
126 return TRUE;
128 return FALSE;
131 int is_file(char *name)
133 struct stat st;
134 return stat(name, &st) != -1 && !S_ISDIR(st.st_mode);