#include #include #include #include #include #include #include #include #include #include #include static char *ascii(const char16_t *wstr, bool translate_slashes) { size_t len = 0; for (const char16_t *wp = wstr; *wp; wp++) len++; char *ret = malloc(len + 1); char *p = ret; for (const char16_t *wp = wstr; *wp; wp++) *p++ = (*wp == '\\' && translate_slashes ? '/' : *wp < 0x80 ? *wp : '?'); *p = '\0'; return ret; } static void system_argv(const char *cmd, ...) { int nargs, nchars; const char *word; va_list ap; va_start(ap, cmd); nargs = 1; /* terminating NULL */ nchars = 0; for (word = cmd; word; word = va_arg(ap, const char *)) { nargs++; nchars += 1 + strlen(word); } va_end(ap); char *args[nargs], chars[nchars]; char **argp = args, *charp = chars; va_start(ap, cmd); for (word = cmd; word; word = va_arg(ap, const char *)) { *argp++ = charp; strcpy(charp, word); charp += 1 + strlen(word); } va_end(ap); *argp++ = NULL; pid_t pid = fork(); if (pid < 0) err(1, "fork"); if (pid == 0) { execvp(args[0], args); warn("execvp"); _exit(127); } int status; if (waitpid(pid, &status, 0) != pid) err(1, "waitpid"); if (!(WIFEXITED(status) && WEXITSTATUS(status) == 0)) errx(1, "subcommand failed"); } uint32_t HashPublicKeyInfo(void *pCertContext, void *rgbSubjectKeyIdentifier, uint32_t *pcbSubjectKeyIndentifier) { errx(1, "HashPublicKeyInfo NYI"); } uint32_t ResetAcls(const char16_t **pwzFiles, uint32_t cFiles) { return 0; } uint32_t CreateCabBegin(const char16_t *wzCab, const char16_t *wzCabDir, uint32_t dwMaxFiles, uint32_t dwMaxSize, uint32_t dwMaxThresh, int compression, void **out_ctx) { fprintf(stderr, "CreateCabBegin(\"%s\", \"%s\", ...)!\n", ascii(wzCab, true), ascii(wzCabDir, true)); return 0; } uint32_t CreateCabAddFile(const char16_t *wzFile, const char16_t *wzToken, void *pmfHash, void *ctx) { fprintf(stderr, "CreateCabAddFile!\n"); return 0; } uint32_t CreateCabAddFiles(const char16_t *const *pwzFiles, const char16_t *const *pwzTokens, void *pmfHash, uint32_t cFiles, void *hContext) { fprintf(stderr, "CreateCabAddFiles!\n"); return 0; } uint32_t CreateCabFinish(void *hContext, void *newCabNamesCallBackAddress) { /* FIXME: newCabNamesCallBackAddress is actually a fn ptr of some kind */ fprintf(stderr, "CabCFinish(%p,%p)!\n", hContext, newCabNamesCallBackAddress); return 0; } void CreateCabCancel(void *hContext) { fprintf(stderr, "CabCCancel(%p)!\n", hContext); } uint32_t ExtractCabBegin(void) { return 0; } uint32_t ExtractCab(const char16_t *wzCabinet, const char16_t *wzExtractDir) { char *cab = ascii(wzCabinet, true), *dir = ascii(wzExtractDir, true); fprintf(stderr, "ExtractCab(\"%s\", \"%s\"\n", cab, dir); system_argv("cabextract", "-d", dir, cab, (const char *)NULL); return 0; } void ExtractCabFinish(void) { } uint32_t EnumerateCabBegin(void) { return 0; } uint32_t EnumerateCab(const char16_t *wzCabinet, void *pfnNotify) { /* FIXME: fpnNotify looks like a fn ptr again */ fprintf(stderr, "EnumerateCab!\n"); return 0; } void EnumerateCabFinish(void) { }