/*
** BINDDJ.C
**
** call : binddj stub-file a.out name.exe
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <malloc.h>

#define STUB_FILE argv[1]
#define AOUT_FILE argv[2]
#define EXE_FILE argv[3]

void search_path(char *, char *);

main(int argc, char **argv)
{
    int hstub, haout, hexe;
    int n_read, n_write;
    char *buf;

    if (argc < 4) {
	printf("usage:%s stub-file a.out name.exe\n", argv[0]);
	printf("stub-file directory is searched in PATH\n");
	return 1;
    }
    if ((buf = malloc(4096)) == NULL) {
	printf("malloc error\n");
	return 1;
    }
    hexe = open(EXE_FILE, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0666);
    if (hexe < 0) {
	perror(EXE_FILE);
	return 1;
    }
    hstub = open(STUB_FILE, O_RDONLY | O_BINARY);
    if (hstub < 0) {
	char filebuf[260];
	search_path(STUB_FILE, filebuf);
	hstub = open(filebuf, O_BINARY);
	if (hstub < 0) {
	    perror(STUB_FILE);
	    return 1;
	}
    }
    haout = open(AOUT_FILE, O_RDONLY | O_BINARY);
    if (hstub < 0) {
	perror(AOUT_FILE);
	return 1;
    }
    while ((n_read = read(hstub, buf, 4096)) > 0) {
	n_write = write(hexe, buf, n_read);
	if (n_write < 0) {
	    perror(EXE_FILE);
	    return 1;
	}
	if (n_write < n_read) {
	    printf("disk full\n");
	    return 1;
	}
    }
    while ((n_read = read(haout, buf, 4096)) > 0) {
	n_write = write(hexe, buf, n_read);
	if (n_write < 0) {
	    perror(EXE_FILE);
	    return 1;
	}
	if (n_write < n_read) {
	    printf("disk full\n");
	    return 1;
	}
    }

    close(hexe);
    close(hstub);
    close(haout);
    return 0;
}

void search_path(char *file, char *path)
{
    char *list, *end;
    int i;

    strcpy(path, file);
    if (access(path, 4) == 0)
	return;
    list = getenv("PATH");
    if (list != NULL)
	for (;;) {
	    while (*list == ' ' || *list == '\t')
		++list;
	    if (*list == 0)
		break;
	    end = list;
	    while (*end != 0 && *end != ';')
		++end;
	    i = end - list;
	    while (i > 0 && (list[i - 1] == ' ' || list[i - 1] == '\t'))
		--i;
	    if (i != 0) {
		memcpy(path, list, i);
		if (list[i - 1] != '/' && list[i - 1] != '\\' && list[i - 1] != ':')
		    path[i++] = '\\';
		strcpy(path + i, file);
		if (access(path, 4) == 0)
		    return;
	    }
	    if (*end == 0)
		break;
	    list = end + 1;
	}
    path[0] = 0;
}
