make mymem* macros if available in libc
[rofl0r-hexedit0r.git] / file.c
blob20a25e2585e06d03e4945841658f10be975d08db
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"
18 #include <libgen.h>
20 void openFile(void)
22 struct stat st;
24 if (!is_file(fileName)) {
25 fprintf(stderr, "%s: %s: Not a file.\n", progName, fileName);
26 exit(1);
29 /* edited should be cleaned here (assert(edited == NULL)) */
30 if ((fd = open(fileName, O_RDWR)) == -1) {
31 isReadOnly = TRUE;
32 if ((fd = open(fileName, O_RDONLY)) == -1) {
33 if (page) exitCurses();
34 if (fileName[0] == '-') DIE(usage);
35 fprintf(stderr, "%s: ", progName);
36 perror(fileName);
37 exit(1);
39 } else isReadOnly = FALSE;
40 baseName = basename(fileName);
41 mark_set = FALSE;
42 lastEditedLoc = base = cursor = cursorOffset = 0;
44 /* 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. */
45 if (fstat(fd, &st) != -1 && st.st_size > 0)
46 fileSize = st.st_size;
47 else {
48 #ifdef BLKGETSIZE
49 unsigned long i;
50 if (ioctl(fd, BLKGETSIZE, &i) == 0)
51 fileSize = (off_t) i * 512;
52 else
53 #endif
54 fileSize = 0;
56 biggestLoc = fileSize;
59 void readFile(void)
61 typePage *p;
62 off_t i;
64 memset(buffer, 0, page * sizeof(*buffer));
66 LSEEK(fd, base);
67 nbBytes = read(fd, buffer, page);
68 if (nbBytes < 0)
69 nbBytes = 0;
70 else if (nbBytes && base + nbBytes > biggestLoc)
71 biggestLoc = base + nbBytes;
72 memset(bufferAttr, A_NORMAL, page * sizeof(*bufferAttr));
73 for (p = edited; p; p = p->next) {
74 for (i = MAX(base, p->base); i < MIN(p->base + p->size, base + page); i++) {
75 if (buffer[i - base] != p->vals[i - p->base]) {
76 buffer[i - base] = p->vals[i - p->base];
77 bufferAttr[i - base] |= MODIFIED;
80 if (p->base + p->size > base + nbBytes) { /* Check for modifications past EOF */
81 for(; p->base + p->size > base + nbBytes && nbBytes < page; nbBytes++)
82 bufferAttr[nbBytes] |= MODIFIED;
85 if (mark_set) markSelectedRegion();
89 int findFile(void)
91 char *p, tmp[BLOCK_SEARCH_SIZE];
92 p = lastFindFile ? strdup(lastFindFile) : NULL;
93 if (!displayMessageAndGetString("File name: ", &p, tmp, sizeof(tmp))) return FALSE;
94 if (!is_file(tmp)) return FALSE;
95 FREE(lastFindFile); lastFindFile = fileName;
96 fileName = p;
97 return TRUE;
101 off_t getfilesize(void)
103 return MAX(lastEditedLoc, biggestLoc);
107 /* tryloc:
108 * returns TRUE if loc is an apropriate location to place the cursor
109 * assumes the file won't shrink.
110 * returns TRUE if the cursor is one past EOF to allow appending
113 int tryloc(off_t loc)
115 char c;
116 if (loc < 0)
117 return FALSE;
118 if (loc <= lastEditedLoc)
119 return TRUE;
121 if (loc <= biggestLoc)
122 return TRUE;
124 if (LSEEK_(fd, loc - 1) != -1 && /* don't have to worry about loc - 1 < 0 */
125 read(fd, &c, 1) == 1) {
126 biggestLoc = loc;
127 return TRUE;
129 return FALSE;
132 int is_file(char *name)
134 struct stat st;
135 return stat(name, &st) != -1 && !S_ISDIR(st.st_mode);