Mike Sanders
unread,Feb 20, 2024, 1:56:20 AMFeb 20You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
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