static const char* find_adobe_dng_converter() { static char adobe_dng_path[1000] = ""; /* valid path from previous attempt? just return it */ if (adobe_dng_path[0]) return adobe_dng_path; /* let's try some usual paths */ int i; for (i = 0; i < COUNT(search_path); i++) { int is_win_path = (search_path[i][strlen(search_path[i])-1] == '\\'); if (is_win_path) { #if defined(WIN32) || defined(_WIN32) snprintf(adobe_dng_path, sizeof(adobe_dng_path), "%s%s", search_path[i], "Adobe DNG Converter.exe"); if (can_exec(adobe_dng_path)) return adobe_dng_path; #else /* let's try Wine */ snprintf(adobe_dng_path, sizeof(adobe_dng_path), "winepath \"%s%s\"", search_path[i], "Adobe DNG Converter.exe"); FILE* f = popen(adobe_dng_path, "r"); if (f) { int ok = fgets(adobe_dng_path, sizeof(adobe_dng_path), f) != 0; pclose(f); if (ok) { strtok(adobe_dng_path, "\n"); if (can_exec(adobe_dng_path)) return adobe_dng_path; } } #endif } else { #if !defined(WIN32) && !defined(_WIN32) snprintf(adobe_dng_path, sizeof(adobe_dng_path), "%s%s", search_path[i], "Adobe DNG Converter"); if (can_exec(adobe_dng_path)) return adobe_dng_path; #endif } } /* nothing found */ adobe_dng_path[0] = 0; return 0; }
/** * init our tcpdump handle using the given pcap handle * Basically, this starts up tcpdump as a child and communicates * to it via a pair of sockets (stdout/stdin) */ int tcpdump_open(tcpdump_t *tcpdump, pcap_t *pcap) { assert(tcpdump); assert(pcap); if (tcpdump->pid != 0) { warn("tcpdump process already running"); return FALSE; } /* is tcpdump executable? */ if (! can_exec(TCPDUMP_BINARY)) { errx(-1, "Unable to execute tcpdump binary: %s", TCPDUMP_BINARY); } #ifdef DEBUG strlcpy(tcpdump->debugfile, TCPDUMP_DEBUG, sizeof(tcpdump->debugfile)); if (debug >= 5) { dbgx(5, "Opening tcpdump debug file: %s", tcpdump->debugfile); if ((tcpdump->debugfd = open(tcpdump->debugfile, O_WRONLY|O_CREAT|O_TRUNC, S_IREAD|S_IWRITE|S_IRGRP|S_IROTH)) == -1) { errx(-1, "Error opening tcpdump debug file: %s\n%s", tcpdump->debugfile, strerror(errno)); } } #endif /* copy over the args */ dbg(2, "Prepping tcpdump options..."); tcpdump_fill_in_options(tcpdump->args); dbg(2, "Starting tcpdump..."); /* create our pipe to send packet data to tcpdump via */ if (pipe(tcpdump->pipes[PARENT_READ_PIPE]) < 0 || pipe(tcpdump->pipes[PARENT_WRITE_PIPE]) < 0) errx(-1, "Unable to create pipe: %s", strerror(errno)); if ((tcpdump->pid = fork() ) < 0) errx(-1, "Fork failed: %s", strerror(errno)); dbgx(2, "tcpdump pid: %d", tcpdump->pid); if (tcpdump->pid > 0) { /* parent - we're still in tcpreplay */ /* close fds not required by parent */ dbgx(2, "[parent] closing child read/write fd %d/%d", CHILD_READ_FD, CHILD_WRITE_FD); close(CHILD_READ_FD); close(CHILD_WRITE_FD); CHILD_READ_FD = 0; CHILD_WRITE_FD = 0; /* send the pcap file header to tcpdump */ FILE *writer = fdopen(PARENT_WRITE_FD, "w"); if ((pcap_dump_fopen(pcap, writer)) == NULL) { warnx("[parent] pcap_dump_fopen(): %s", pcap_geterr(pcap)); return FALSE; } pcap_dump_flush((pcap_dumper_t*)writer); if (fcntl(PARENT_WRITE_FD, F_SETFL, O_NONBLOCK) < 0) warnx("[parent] Unable to fcntl write pipe:\n%s", strerror(errno)); if (fcntl(PARENT_READ_FD, F_SETFL, O_NONBLOCK) < 0) warnx("[parent] Unable to fnctl read pip:\n%s", strerror(errno)); } else { dbg(2, "[child] started the kid"); /* we're in the child process - run "tcpdump <options> -r -" */ if (dup2(CHILD_READ_FD, STDIN_FILENO) != STDIN_FILENO) { errx(-1, "[child] Unable to duplicate socket to stdin: %s", strerror(errno)); } if (dup2(CHILD_WRITE_FD, STDOUT_FILENO) != STDOUT_FILENO) { errx(-1, "[child] Unable to duplicate socket to stdout: %s", strerror(errno)); } /* * Close sockets not required by child. The exec'ed program must * not know that they ever existed. */ dbgx(2, "[child] closing in fds %d/%d/%d/%d", CHILD_READ_FD, CHILD_WRITE_FD, PARENT_READ_FD, PARENT_WRITE_FD); close(CHILD_READ_FD); close(CHILD_WRITE_FD); close(PARENT_READ_FD); close(PARENT_WRITE_FD); /* exec tcpdump */ dbg(2, "[child] Exec'ing tcpdump..."); if (execv(TCPDUMP_BINARY, options_vec) < 0) errx(-1, "Unable to exec tcpdump: %s", strerror(errno)); dbg(2, "[child] tcpdump done!"); } return TRUE; }