Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

getOpsFromSelf() (Long Post)

42 views
Skip to first unread message

Mike Sanders

unread,
Feb 20, 2024, 1:56:20 AMFeb 20
to

Just thinking aloud... Imagining here allowing more advanced users of
my app to modify a string of digits residing at the end of my project's
binary/exe. When the app loads, it reads in those digits. So far (knock
on wood), I've not run up against a single case where the code below has
failed to work under multiple OSs. A method mostly for power user's.

The user simply opens the compiled project in their favorite hex editor
& modifies the pre-existing string, a pseudo bitmask of sorts. Certainly
the user could unwittingly add/remove bytes rather than only modifying the
bytes, still its a nifty idea. But practical? I'm not so sure on that point.

Any other gotchas of note?

int main(int argc, char *argv[]) {

#ifdef WIN
getOpsFromSelf(NULL);
#else
getOpsFromSelf(argv[0]);
#endif

// work

return 0;

}

void getOpsFromSelf(char *fname) {

#ifdef WIN
char path[MAX_PATH];
GetModuleFileName(NULL, path, MAX_PATH);
#else
char path[PATH_MAX];
char *tmp = getpath(fname);
strncpy(path, tmp, sizeof(path));
path[sizeof(path) - 1] = '\0';
free(tmp);
#endif

FILE *bin = fopen(path, "rb");
if (bin == NULL) return; // return if file cant be opened

fseek(bin, -3, SEEK_END); // jump 3 bytes before end of file
unsigned char bytes[3];
fread(bytes, 1, 3, bin);
fclose(bin);

// ensure last 3 bytes are digits, else return
for (int i = 0; i < 2; i++) if (!isdigit(bytes[i])) return;

// assign values from bytes
ops.x = (bytes[0] == '1' || bytes[0] == '2') ? bytes[0] - '0' : 1; // 1-2
ops.y = (bytes[1] == '1') ? bytes[1] - '0' : 0; // 0-1
ops.z = (bytes[2] == '1') ? bytes[2] - '0' : 0; // 0-1

}

#ifdef NIX

char *getpath(char *fname) {

const char *PATH_SEPARATOR = ":"; // unix-like
const char *DIR_SEPARATOR = "/"; // unix-like
const int MAX_SIZE = 1024;

struct stat buffer;

if (stat(fname, &buffer) == 0) {
char *result = strdup(fname);
if (!result) return NULL; // memory allocation error <--
return result;
}

char *path_env = getenv("PATH");
if (!path_env) return NULL;

char path_env_copy[MAX_SIZE];
strncpy(path_env_copy, path_env, sizeof(path_env_copy));
path_env_copy[sizeof(path_env_copy) - 1] = '\0';

char full_path[MAX_SIZE];
char *dir = strtok(path_env_copy, PATH_SEPARATOR);

while (dir) {
snprintf(full_path, sizeof(full_path), "%s%s%s", dir,
(dir[strlen(dir) - 1] == DIR_SEPARATOR[0] ? "" :
DIR_SEPARATOR), fname);
if (stat(full_path, &buffer) == 0) {
char *result = strdup(full_path);
if (!result) return NULL; // memory allocation error <--
return result;
}
dir = strtok(NULL, PATH_SEPARATOR);
}

return NULL;
}

#endif

--
:wq
Mike Sanders

0 new messages