/* sqlite callback, record a single value */ int pdb_get_value(void *param, int argc, char **argv, char **colname) { char *value = (char *)param; if (argv != NULL) { XSTRCPY(value, argv[0]); return PDB_OK; } return PDB_ERR; }
void get_pkg_dbdir(void) { char **exec_cmd; if ((exec_cmd = exec_list(PKGTOOLS"/pkg_admin config-var PKG_DBDIR", NULL)) == NULL) strcpy(pkg_dbdir, PKG_DBDIR); else { XSTRCPY(pkg_dbdir, exec_cmd[0]); free_list(exec_cmd); } }
/* * send a certain ftp-command "cmd" to our FTP coprocess, and wait for * "expectstr" to be returned. Return numeric FTP return code or -1 * in case of an error (usually expect() timeout) */ int ftp_cmd(const char *cmd, const char *expectstr) { int rc=0, verbose_ftp=0; int len; /* pkg_select adddon */ char wcmd[MIDLEN], *p; XSTRCPY(wcmd, cmd); if (cmd != NULL && (p = strstr(wcmd, STORE_EXPECT)) != NULL) { p--; /* point to : */ *p = '\0'; store_expect = 1; } else store_expect = 0; if (strstr(wcmd, TAR_CMD) != NULL) use_tar = 1; else use_tar = 0; if (Verbose) verbose_ftp=1; if (verbose_ftp) fprintf(stderr, "\n%sftp> %s%s", bold_on, wcmd, bold_off); fflush(stdout); len = write(ftpio.command, wcmd, strlen(wcmd)); if ((unsigned int)len == strlen(wcmd)) { if (expectstr) { /* set "rc" to the FTP error code: */ if (expect(ftpio.answer, expectstr, &rc) == -1) rc = -1; /* some error occurred */ } } else { if (Verbose) warn("short write"); } return rc; }
/* * expect "str" (a regular expression) on file descriptor "fd", storing * the FTP return code of the command in the integer "ftprc". The "str" * string is expected to match some FTP return codes after a '\n', e.g. * "\n(550|226).*\n" */ static int expect(int fd, const char *str, int *ftprc) { int rc; char *p, buf[90], progress_str[90]; char tmp[MAXLEN]; #if EXPECT_DEBUG char *vstr; #endif /* EXPECT_DEBUG */ regex_t rstr; int done; struct pollfd set[1]; int retval; regmatch_t match; int verbose_expect=0; static int next = 1; #if EXPECT_DEBUG vstr=malloc(2*sizeof(buf)); if (vstr == NULL) err(EXIT_FAILURE, "expect: malloc() failed"); strvis(vstr, str, VIS_NL|VIS_SAFE|VIS_CSTYLE); #endif /* EXPECT_DEBUG */ if (regcomp(&rstr, str, REG_EXTENDED) != 0) err(EXIT_FAILURE, "expect: regcomp() failed"); #if EXPECT_DEBUG if (expect_debug) printf("expecting \"%s\" on fd %d ...\n", vstr, fd); #endif /* EXPECT_DEBUG */ if(0) setbuf(stdout, NULL); memset(buf, '\n', sizeof(buf)); done=0; retval=0; set[0].fd = fd; set[0].events = POLLIN; while(!done) { rc = poll(set, 1, 10*60*1000); /* seconds until next message from tar */ switch (rc) { case -1: if (errno == EINTR) break; warn("expect: poll() failed (probably ftp died because of bad args)"); done = 1; retval = -1; break; case 0: warnx("expect: poll() timeout"); /* need to send ftp coprocess SIGINT to make it stop * downloading into dir that we'll blow away in a second */ kill(ftp_pid, SIGINT); /* Wait until ftp coprocess is responsive again * XXX Entering recursion here! */ rc = ftp_cmd("cd .\n", "\n(550|250).*\n"); if (rc != 250) { /* now we have a really good reason to bail out ;) */ } /* ftp is at command prompt again, and will wait for our * next command. If we were downloading, we can now safely * continue and remove the dir that the tar command was * expanding to */ done = 1; /* hope that's ok */ retval = -1; break; default: if (set[0].revents & POLLHUP) { done = 1; retval = -1; break; } rc = read(fd, &buf[sizeof(buf) - 1], 1); if (rc <= 0) { done = 1; retval = -1; break; } if (verbose_expect) putchar(buf[sizeof(buf)-1]); #if EXPECT_DEBUG { char *v=malloc(2*sizeof(buf)); strvis(v, buf, VIS_NL|VIS_SAFE|VIS_CSTYLE); if (expect_debug) printf("expect=<%s>, buf=<%*s>\n", vstr, strlen(v), v); free(v); } #endif /* EXPECT_DEBUG */ /****************** pkg_select mess ! ******************/ if (store_expect) { int len; memset(tmp, 0, MAXLEN); XSTRCPY(tmp, buf); len = strlen(tmp); /* returned result has 2 lines, separated by a \n * we need the 2d one, pointed by strchr * returned string does not finish with \n\0, e.g. : * '\n' <repeats 78 times>, "---> TYPE A\n\001" */ if ((tmp[len - 2] == '\n') && ((p = strchr(tmp, '\n')) != NULL)) { p++; /* cleanup leading \n */ trimcr(p); /* callback */ fill_store(p); } } /* was not a store request */ /* used for progress bars with tar(1) */ if (use_tar && strncmp(buf, "pkgsrc/", 7) == 0 && (p = strchr(buf, '/')) != NULL) { /* point after pkgsrc/ */ strcpy(progress_str, p); /* /category/blah */ p++; /* category/blah */ if ((p = strchr(p, '/')) != NULL) { if (conf.shell_output) printf("%s\n", progress_str); else if (next) { char msg[MAXLEN]; p++; *p = '\0'; snprintf(msg, MAXLEN, "extracting pkgsrc%s", progress_str); next = progress_bar(pkgsrc_progress, msg, INCREMENTAL); } } /* extract category from path */ } /* strcmp pkgsrc/ (tar progress) */ if (regexec(&rstr, buf, 1, &match, 0) == 0) { #if EXPECT_DEBUG if (expect_debug) printf("Gotcha -> %s!\n", buf+match.rm_so+1); fflush(stdout); #endif /* EXPECT_DEBUG */ if (ftprc && isdigit((unsigned char)buf[match.rm_so+1])) *ftprc = atoi(buf+match.rm_so+1); done=1; retval=0; } memmove(buf, buf+1, sizeof(buf)-1); /* yes, this is non-performant */ break; } /* switch rc */ } #if EXPECT_DEBUG printf("done.\n"); if (str) free(vstr); #endif /* EXPECT_DEBUG */ return retval; }