147 lines
4.8 KiB
C
Executable File
147 lines
4.8 KiB
C
Executable File
/* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
|
|
* vim:expandtab:shiftwidth=8:tabstop=8:
|
|
*/
|
|
/******************************************************************************\
|
|
* *
|
|
* Copyright (c) 2006, The Regents of the University of California *
|
|
* See the file COPYRIGHT for a complete copyright notice and license. *
|
|
* *
|
|
********************************************************************************
|
|
*
|
|
* Purpose:
|
|
* Changes a specific Byte offset In File
|
|
*
|
|
\******************************************************************************/
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
#include "config.h"
|
|
#endif
|
|
|
|
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
#define ERR(MSG) do { \
|
|
fprintf(stdout, "** error **\n"); \
|
|
fprintf(stdout, "ERROR in %s (line %d): %s.\n", \
|
|
__FILE__, __LINE__, MSG); \
|
|
fprintf(stdout, "ERROR: %s\n", strerror(errno)); \
|
|
fprintf(stdout, "** exiting **\n"); \
|
|
fflush(stdout); \
|
|
exit(1); \
|
|
} while (0)
|
|
|
|
#define BYTE_BOUNDARY 8
|
|
|
|
#ifndef open64 /* necessary for TRU64 -- */
|
|
# define open64 open /* unlikely, but may pose */
|
|
#endif /* not open64 */ /* conflicting prototypes */
|
|
|
|
#ifndef lseek64 /* necessary for TRU64 -- */
|
|
# define lseek64 lseek /* unlikely, but may pose */
|
|
#endif /* not lseek64 */ /* conflicting prototypes */
|
|
|
|
int
|
|
main(int argc, char **argv)
|
|
{
|
|
int i;
|
|
int fd;
|
|
int value;
|
|
unsigned char oldBuffer[BYTE_BOUNDARY];
|
|
unsigned char newBuffer[BYTE_BOUNDARY];
|
|
char *fileName;
|
|
long long int offset;
|
|
long long int alignedOffset;
|
|
long long int bufferIndex;
|
|
long long int indexMask = (long long int)(BYTE_BOUNDARY - 1);
|
|
long long int alignedMask = (long long int)(BYTE_BOUNDARY - 1)
|
|
^ (long long int)(-1);
|
|
|
|
/* check usage */
|
|
if (argc != 3 && argc !=4) {
|
|
printf("Usage: %s <filename> <offset> [<newValue>]\n", argv[0]);
|
|
printf("Returns value of byte offset, or modifies to new value.\n");
|
|
exit(1);
|
|
}
|
|
|
|
/* gather arguments */
|
|
fileName = argv[1];
|
|
sscanf(argv[2], "%lld", &offset);
|
|
alignedOffset = offset & alignedMask;
|
|
bufferIndex = offset & indexMask;
|
|
if (argc == 4) {
|
|
sscanf(argv[3], "%d", &value);
|
|
if (value < 0 || value > 255) ERR("ERROR: <value> must be 0-255");
|
|
}
|
|
|
|
/* open file */
|
|
fd = open64(fileName, O_RDWR);
|
|
if (fd < 0) ERR("ERROR: Unable to open file");
|
|
|
|
/* seek to offset */
|
|
if (lseek64(fd, alignedOffset, SEEK_SET) == -1)
|
|
ERR("ERROR: Unable to seek to file offset");
|
|
|
|
/* read into buffer */
|
|
if (read(fd, &oldBuffer, BYTE_BOUNDARY) <= 0)
|
|
ERR("ERROR: Unable to read file offset");
|
|
|
|
if (argc == 4) {
|
|
/* write from buffer */
|
|
/* update buffer with new value */
|
|
memcpy(newBuffer, oldBuffer, BYTE_BOUNDARY);
|
|
newBuffer[bufferIndex] = (unsigned char)value;
|
|
|
|
/* seek to offset */
|
|
if (lseek64(fd, alignedOffset, SEEK_SET) == -1)
|
|
ERR("ERROR: Unable to seek to file offset");
|
|
|
|
/* write buffer */
|
|
if (write(fd, &newBuffer, BYTE_BOUNDARY) != BYTE_BOUNDARY)
|
|
ERR("ERROR: Unable to write to file offset");
|
|
}
|
|
|
|
/* print data */
|
|
/* print header */
|
|
if (argc == 3) {
|
|
fprintf(stdout, "offset: original value: \n");
|
|
fprintf(stdout, "------------------ ------------------\n");
|
|
} else {
|
|
fprintf(stdout,
|
|
"offset: original value: new value: \n");
|
|
fprintf(stdout,
|
|
"------------------ ------------------ ------------------\n");
|
|
}
|
|
|
|
/* next hex, multiple bytes */
|
|
fprintf(stdout, "0x%016llx 0x", alignedOffset);
|
|
for (i = 0; i < BYTE_BOUNDARY; i++) {
|
|
fprintf(stdout, "%02x", oldBuffer[i]);
|
|
}
|
|
if (argc == 4) {
|
|
fprintf(stdout, " 0x");
|
|
for (i = 0; i < BYTE_BOUNDARY; i++) {
|
|
fprintf(stdout, "%02x", newBuffer[i]);
|
|
}
|
|
}
|
|
fprintf(stdout, "\n");
|
|
|
|
/* finally decimal, single byte */
|
|
fprintf(stdout, "%-16lld %-3d (0x%02x)", offset,
|
|
oldBuffer[bufferIndex], oldBuffer[bufferIndex]);
|
|
if (argc == 4) {
|
|
fprintf(stdout, " %-3d (0x%02x)\n",
|
|
newBuffer[bufferIndex], newBuffer[bufferIndex]);
|
|
}
|
|
fprintf(stdout, "\n");
|
|
|
|
/* finished */
|
|
fflush(stdout);
|
|
close(fd);
|
|
return(0);
|
|
|
|
} /* main() */
|