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)
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.*/
24 if (!is_file(fileName
)) {
25 fprintf(stderr
, "%s: %s: Not a file.\n", progName
, fileName
);
29 /* edited should be cleaned here (assert(edited == NULL)) */
30 if ((fd
= open(fileName
, O_RDWR
)) == -1) {
32 if ((fd
= open(fileName
, O_RDONLY
)) == -1) {
33 if (page
) exitCurses();
34 if (fileName
[0] == '-') DIE(usage
);
35 fprintf(stderr
, "%s: ", progName
);
39 } else isReadOnly
= FALSE
;
40 baseName
= basename(fileName
);
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
;
50 if (ioctl(fd
, BLKGETSIZE
, &i
) == 0)
51 fileSize
= (off_t
) i
* 512;
56 biggestLoc
= fileSize
;
64 memset(buffer
, 0, page
* sizeof(*buffer
));
67 nbBytes
= read(fd
, buffer
, page
);
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();
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
;
101 off_t
getfilesize(void)
103 return MAX(lastEditedLoc
, biggestLoc
);
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
)
118 if (loc
<= lastEditedLoc
)
121 if (loc
<= biggestLoc
)
124 if (LSEEK_(fd
, loc
- 1) != -1 && /* don't have to worry about loc - 1 < 0 */
125 read(fd
, &c
, 1) == 1) {
132 int is_file(char *name
)
135 return stat(name
, &st
) != -1 && !S_ISDIR(st
.st_mode
);