int url_connect(const char *url) { const char *ptr; char *helper_argv[2]; int count; ptr = strstr(url, "//"); if (!ptr) return -1; if (strncmp("dir:", url, ptr - url) == 0 || strncmp("ssh:", url, ptr - url) == 0) { ptr = session_getcfg(CFGKEY_HARMONY_HOME); if (!ptr) return -1; count = snprintf_grow(&buf, &buflen, "%s/libexec/codegen-helper", ptr); if (count < 0) return -1; helper_argv[0] = buf; helper_argv[1] = NULL; return socket_launch(buf, helper_argv, NULL); } else if (strncmp("tcp:", url, ptr - url) == 0) { /* Not implemented yet. */ } return -1; }
int harmony_launch(hdesc_t *hdesc, const char *host, int port) { int i; /* Sanity check input */ if (hdesc->sess.sig.range_len < 1) { hdesc->errstr = "No tuning variables defined"; errno = EINVAL; return -1; } if (!host && !getenv("HARMONY_S_HOST")) { char *path; const char *home; /* Provide a default name, if one isn't defined. */ if (!hdesc->sess.sig.name) { if (hsignature_name(&hdesc->sess.sig, "NONAME")) return -1; } /* Find the Active Harmony installation. */ home = getenv("HARMONY_HOME"); if (!home) { hdesc->errstr = "No host or HARMONY_HOME specified"; return -1; } if (hcfg_set(hdesc->sess.cfg, CFGKEY_HARMONY_HOME, home) != 0) { hdesc->errstr = "Could not set " CFGKEY_HARMONY_HOME; return -1; } /* Fork a local tuning session. */ path = sprintf_alloc("%s/libexec/session-core", home); hdesc->socket = socket_launch(path, NULL, NULL); free(path); } else { hdesc->socket = tcp_connect(host, port); } if (hdesc->socket < 0) { hdesc->errstr = strerror(errno); return -1; } /* Prepare a default client id, if necessary. */ if (hdesc->id == NULL) hdesc->id = default_id(hdesc->socket); hdesc->state = HARMONY_STATE_CONNECTED; /* Apply argv configuration directives now, if necessary. */ for (i = 0; i < hdesc->cmd_len; ++i) { char *key, *val, *cpy; cpy = stralloc(hdesc->cmd[i]); if (hcfg_parse(cpy, &key, &val) == NULL) { /* This should never fail, but just in case. */ hdesc->errstr = "Internal error parsing argv config directive."; return -1; } if (hcfg_set(hdesc->sess.cfg, key, val) != 0) { hdesc->errstr = "Internal error applying argv config directive."; return -1; } free(cpy); } /* Prepare a Harmony message. */ hmesg_scrub(&hdesc->mesg); hsession_init(&hdesc->mesg.data.session); hsession_copy(&hdesc->mesg.data.session, &hdesc->sess); return send_request(hdesc, HMESG_SESSION); }
char *call_omega_calc(const char *cmd) { static char *buf = NULL; static int buf_cap = 4096; char *child_argv[2]; char *ptr; pid_t oc_pid; int fd, count; if (buf == NULL) { buf = (char *) malloc(sizeof(char) * buf_cap); if (!buf) return NULL; } child_argv[0] = (char *) omega_bin; child_argv[1] = NULL; fd = socket_launch(omega_bin, child_argv, &oc_pid); if (!fd) { session_error("Could not launch Omega Calculator"); return NULL; } if (socket_write(fd, cmd, strlen(cmd)) < 0) { session_error("Could not send command to Omega Calculator"); return NULL; } if (shutdown(fd, SHUT_WR) != 0) { session_error("Internal error: Could not shutdown write to Omega"); return NULL; } ptr = buf; while ( (count = socket_read(fd, ptr, buf_cap - (buf - ptr))) > 0) { ptr += count; if (ptr == buf + buf_cap) { if (array_grow(&buf, &buf_cap, sizeof(char)) != 0) { session_error("Internal error: Could not grow buffer for" " Omega Calculator input"); return NULL; } ptr = buf + strlen(buf); } *ptr = '\0'; } if (count < 0) { session_error("Could not read output from Omega Calculator"); return NULL; } if (close(fd) != 0) { session_error("Internal error: Could not close Omega socket"); return NULL; } if (waitpid(oc_pid, NULL, 0) != oc_pid) { session_error("Internal error: Could not reap Omega process"); return NULL; } return buf; }