#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <zlib.h>
#include <sys/utsname.h>
#include <sys/wait.h>

#include "cpio.h"

/* hack */
int insmod_main(int argc, char ** argv);

/* librpm.a provides this */
int cpioInstallArchive(gzFile stream, void * mappings,
		       int numMappings, void * cb, void * cbData,
		       char ** failedFile);


int ourInsmodCommand(int argc, char ** argv) {
    char * file;
    char finalName[100];
    char * chptr;
    gzFile stream; 
    int rc, rmObj = 0;
    int sparc64 = 0;
#ifdef __sparc__
    struct utsname u;

    if (!uname(&u) && !strcmp(u.machine, "sparc64"))
    	sparc64 = 1;
#endif

    if (argc < 2) {
	fprintf(stderr, "usage: insmod <module>.o [params]\n");
	return 1;
    }

    file = argv[1];
    if (access(file, R_OK)) {
	/* it might be having a ball */
	stream = gzopen(sparc64 ? "/modules/modules64.cgz" : "/modules/modules.cgz", "r");
	if (!stream) {
	    return 1;
	}

	chptr = strrchr(file, '/');
	if (chptr) file = chptr + 1;
	sprintf(finalName, "/tmp/%s", file);

	if (installCpioFile(stream, file, finalName, 0))
	    return 1;

	rmObj = 1;
	file = finalName;
    }

    argv[1] = file;

#ifdef __sparc__
    if (sparc64) {
    	int pid, status;
    	
    	if (!(pid = fork())) {
    	    execv("/bin/insmod64", argv);
    	    exit(-1);
    	}
    	waitpid(pid, &status, 0);
	if (WIFEXITED(status))
	    rc = WEXITSTATUS(status);
	else
	    rc = -1;
    } else
#endif
    	rc = insmod_main(argc, argv);
    if (rmObj) unlink(file);

    return rc;
}
