123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880 |
- /*
- * CDE - Common Desktop Environment
- *
- * Copyright (c) 1993-2012, The Open Group. All rights reserved.
- *
- * These libraries and programs are free software; you can
- * redistribute them and/or modify them under the terms of the GNU
- * Lesser General Public License as published by the Free Software
- * Foundation; either version 2 of the License, or (at your option)
- * any later version.
- *
- * These libraries and programs are distributed in the hope that
- * they will be useful, but WITHOUT ANY WARRANTY; without even the
- * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- * PURPOSE. See the GNU Lesser General Public License for more
- * details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with these libraries and programs; if not, write
- * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
- * Floor, Boston, MA 02110-1301 USA
- */
- /* @(#)$TOG: remote.c /main/9 1998/04/06 13:36:26 mgreess $ */
- #include "xims.h"
- #include <signal.h>
- #include <sys/wait.h>
- #include <netdb.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <sys/socket.h>
- #include <sys/errno.h>
- #include <setjmp.h>
- #include <fcntl.h>
- #include <limits.h>
- #include <X11/Xproto.h> /* for X_ChangeHosts */
- #include <X11/Xatom.h> /* for XA_STRING */
- #if !defined(__linux__) && !defined(CSRG_BASED)
- extern char *sys_errlist[];
- #endif
- static char *conf_msg_id = STR_CONFDATA;
- #define CONF_MSG_ID_LEN strlen(conf_msg_id)
- #define CONF_MSG_DATASIZE_LEN 8
- #define CONF_MSG_HEADER_LEN (CONF_MSG_ID_LEN + CONF_MSG_DATASIZE_LEN)
- #define CONF_MSG_SIZE_MAX (8*1024 - 64) /* < PIPE_BUF (PIPSIZ) */
- static int mk_remote_conf(/* list, locale, ims_name, status, confbuf, conflen */);
- static char *mk_ims_ent(/* bp, idx, ent */);
- static int parse_ims_list(/* ptr, list */);
- static int parse_remote_conf(/* listp, locale, confbuf, conflen */);
- static int prepare_action(/* act_typ, av, ac */);
- static int read_property(/* prop, type, format, remove, datapp, lenp */);
- #if 0 /* README */
- Atom:
- _DTIMSSTART_MAIN _DTIMSSTART_STATUS _DTIMSSTART_DATA
- Property:
- _DTIMSSTART_STATUS (format: 32) _DTIMSSTART_DATA (format: 8)
- ClientMessage:
- message_type: _DTIMSSTART_STATUS
- format: 32
- data.l[0]: _REMOTE_CONF or _REMOTE_RUN
- data.l[1]: ErrorCode
- data.l[2-4]: 0 (unused)
- Status:
- _NONE _INIT _REMOTE_CONF _REMOTE_RUN
- Actions:
- DtImsGetRemoteConf DtImsRunRemoteIms
- Procedure:
-
- <initialization>
- * own _MAIN property
- * set _STATUS property to _INIT
- * set _DATA property to _INIT
- <get remote configuratuon (DtImsGetRemoteConf)>
- * clear _DATA property
- * change _STATUS property to _REMOTE_CONF
- * set additional command line options to _DATA property
- * invoke DtImsGetRemoteConf action
- [on remote dtimsstart]
- - collect data
- - check _STATUS property whether its value is _REMOTE_CONF
- - set collected data to _DATA property of owner of _MAIN (Replace)
- - send ClientMessage of ErrorCode to owner of _MAIN
- - exit
- * receive ClientMessage from remote dtimsstart (or action finished)
- * change _STATUS property to _INIT
- * read data from _DATA property (Delete)
- * parse ErrCode and data (conf data or ErrorPath)
- * update selection window
- <run IMS on remote host (DtImsRunRemoteIms)>
- * change _STATUS property to _REMOTE_RUN
- * set additional command line options to _DATA property
- * invoke DtImsRunRemoteIms action
- * popdown selection window (if sucessfully invoked)
- [on remote dtimsstart]
- - check _STATUS property whether its value is _REMOTE_RUN
- - invoke IMS and wait its preparation
- - set ErrorPath to _DATA property of owner of _MAIN (Replace)
- - send ClientMessage of ErrorCode to owner of _MAIN
- - exit
- * receive ClientMessage from remote dtimsstart (or action finished)
- * change _STATUS property to _INIT
- * parse ErrCode and data (ErrorPath)
- <termination>
- * disown _MAIN property
- * exit
- #endif /* README */
- #ifdef NEED_STRCASECMP
- /*
- * In case strcasecmp is not provided by the system here is one
- * which does the trick.
- */
- static int
- strcasecmp(const char *s1,
- const char *s2)
- {
- int c1, c2;
- while (*s1 && *s2) {
- c1 = isupper(*s1) ? tolower(*s1) : *s1;
- c2 = isupper(*s2) ? tolower(*s2) : *s2;
- if (c1 != c2)
- return (c1 - c2);
- s1++;
- s2++;
- }
- return (int) (*s1 - *s2);
- }
- #endif
- int put_remote_conf(char *locale, char *ims_name)
- {
- int ret;
- int msg_status = NoError;
- int conflen;
- char confbuf[CONF_MSG_SIZE_MAX];
- ImsList *list = (ImsList *) 0;
- DPR(("put_remote_conf(locale=%s, ims=%s)\n", locale, ims_name));
- ret = get_ims_list(&list, NULL, True);
- msg_status = ret;
- ret = mk_remote_conf(list, locale, ims_name, msg_status, confbuf, &conflen);
- if (list) {
- clear_ImsList(list);
- FREE(list);
- }
- ret = set_remote_confdata(confbuf, conflen);
- send_dtims_msg(WIN_ST_REMOTE_CONF, ret);
- #if 0
- NotifyErrCode(NoError);
- (void) fwrite((void *)confbuf, (size_t)conflen, (size_t)1, stdout);
- fflush(stdout);
- #endif
- return ret;
- }
- int get_remote_conf(ImsList **listp, char *hostname, char *locale, char *ims_name)
- {
- int ret = NoError;
- int conflen = 0;
- char *confbuf = 0;
- char *opts[16];
- int n, num_opts;
- char *CDE_locale = NULL;
- if (!locale)
- locale = userEnv.real_locale ? userEnv.real_locale : userEnv.locale;
- CDE_locale = userEnv.CDE_locale;
- if (CDE_locale)
- DPR2(("get_remote_conf(%s, %s, %s)\n",
- hostname, CDE_locale, ims_name ? ims_name : "<all>"));
- else
- DPR2(("get_remote_conf(%s, %s, %s)\n",
- hostname, locale, ims_name ? ims_name : "<all>"));
- n = 0;
- /* Try to first use the CDE locale, else fallback to the locale. */
- if (CDE_locale) {
- opts[n++] = "-CDE_locale";
- opts[n++] = CDE_locale;
- }
- else {
- if (locale) {
- opts[n++] = "-locale";
- opts[n++] = locale;
- }
- }
- if (ims_name) {
- opts[n++] = "-ims";
- opts[n++] = ims_name;
- }
- #ifdef DEBUG
- if (DebugLvl >= 1) {
- int i;
- for (i = 0; i < DebugLvl; i++) opts[n++] = "-debug";
- }
- #endif
- opts[n] = NULL;
- num_opts = n;
- ret = prepare_action(ACT_GETREMCONF, opts, num_opts);
- if (ret != NoError) return ret;
- ret = invoke_action(Conf.action[ACT_GETREMCONF], hostname);
- change_window_status(WIN_ST_INIT);
- if (ret != NoError) return ret;
- ret = read_remote_confdata(&confbuf, &conflen);
- if (ret != NoError) return ret;
- if (ret == NoError) {
- ret = parse_remote_conf(listp, locale, confbuf, conflen);
- FREE(confbuf);
- if (ims_name && ret == ErrRemoteNoIms)
- ret = ErrRemoteMissIms;
- }
- return ret;
- }
- #define PUT_DATA(nm, val) *bp++ = ' ', bp = strcpyx(bp, (nm)), \
- *bp++ = '=', bp = strcpyx(bp, (val)), *bp++ = '\n'
- static int mk_remote_conf(ImsList *list, char *locale,
- char *ims_name, int status,
- char *confbuf, int *conflen)
- {
- int num_ent;
- int i, j;
- char *bp;
- int len;
- int data_sz;
- char sz_ptr[20];
- ImsEnt *ent;
- char var[20];
- DPR(("mk_remote_conf(locale=%s, ims=%s)\n", locale, ims_name));
- #ifdef DEBUG
- if (DebugLvl >= 2 && list) pr_ImsList(list);
- #endif
- bp = confbuf + CONF_MSG_HEADER_LEN;
- num_ent = 0;
- if (status == NoError) {
- for (i = 0; i < list->num_ent; i++) {
- ent = list->elist[i];
- if ((ims_name && strcmp(ent->name, ims_name))
- || (ent->ims && (ent->ims->flags & F_NO_REMOTE)))
- ent->status = ErrRemoteIms;
- else
- num_ent++;
- }
- if (num_ent <= 0)
- status = ErrRemoteNoIms;
- }
- bp = strcpyx(bp, "ImsList: "); bp = strcpyx(bp, locale); *bp++ = '\n';
- sprintf(var, "%ld", (long) status);
- PUT_DATA("ST", var);
- if (num_ent > 0) {
- sprintf(var, "%ld", (long) num_ent);
- PUT_DATA("ne", var);
- if (list->elist[list->default_idx]->status != ErrRemoteIms) {
- PUT_DATA("df", list->elist[list->default_idx]->name);
- }
- sprintf(var, "%ld", (long) (list->def_selmode));
- PUT_DATA("sm", var);
- for (i = j = 0; i < list->num_ent; i++)
- if (list->elist[i]->status != ErrRemoteIms)
- bp = mk_ims_ent(bp, j++, list->elist[i]);
- }
- bp = strcpyx(bp, "END"); *bp++ = '\n';
- data_sz = bp - (confbuf + CONF_MSG_HEADER_LEN);
- /* header (conf_msg_id & data_sz) */
- bp = confbuf;
- memset((void *) bp, (int) ' ', (size_t) CONF_MSG_HEADER_LEN);
- memcpy((void *) bp, conf_msg_id, CONF_MSG_ID_LEN);
- sprintf(sz_ptr, "%ld", (long) data_sz);
- len = strlen(sz_ptr);
- bp = confbuf + CONF_MSG_HEADER_LEN - 1 - len;
- memcpy((void *) bp, (void *) sz_ptr, (size_t) len);
- confbuf[CONF_MSG_HEADER_LEN - 1] = '\n';
- *conflen = CONF_MSG_HEADER_LEN + data_sz;
- DPR2(("mk_remote_conf(): conflen=%d data_sz=%d\n confbuf=%s",
- *conflen, data_sz, confbuf));
- return NoError;
- }
- static char *mk_ims_ent(char *bp, int idx, ImsEnt *ent)
- {
- ImsConf *ims = ent->ims;
- char val[20];
- sprintf(val, "%ld", (long) idx);
- bp = strcpyx(bp, "Ent-"); bp = strcpyx(bp, val); *bp++ = '\n';
- PUT_DATA("nm", ent->name);
- sprintf(val, "%ld", (long) ent->status);
- PUT_DATA("st", val);
- sprintf(val, "%ld", (long) ims->flags);
- PUT_DATA("fg", val);
- sprintf(val, "%ld", (long) ims->protocols);
- PUT_DATA("pr", val);
- if (ent->label) { PUT_DATA("lb", ent->label); }
- if (ims->timeout)
- {
- sprintf(val, "%ld", (long) ims->timeout);
- PUT_DATA("to", val);
- }
- if (ims->interval)
- {
- sprintf(val, "%ld", (long) ims->interval);
- PUT_DATA("it", val);
- }
- if (ims->servername) { PUT_DATA("sn", ims->servername); }
- if (ims->servername2) { PUT_DATA("sN", ims->servername2); }
- if (ims->classname) { PUT_DATA("cn", ims->classname); }
- if (ims->property) { PUT_DATA("pp", ims->property); }
- if (ims->cmd_path) { PUT_DATA("cp", ims->cmd_path); }
- if (ims->cmd_param) { PUT_DATA("cr", ims->cmd_param); }
- if (ims->env_set) { PUT_DATA("es", ims->env_set); }
- if (ims->env_unset) { PUT_DATA("eu", ims->env_unset); }
- if (ims->env_pass) { PUT_DATA("ep", ims->env_pass); }
- return bp;
- }
- #undef PUT_DATA
- static int parse_ims_list(char *ptr, ImsList *list)
- {
- char *bp = ptr;
- char *np, *vp;
- char *def_name;
- int i, num_ent;
- ImsEnt *ent = 0;
- ImsConf *ims;
- CLR(list, ImsList);
- list->default_idx = -1;
- list->def_selmode = SEL_MODE_NOAUTO;
- list->num_ent = 0;
- def_name = NULL;
- num_ent = 0;
- while (np = strchr(bp, '\n')) {
- if (np == bp) {
- bp++;
- continue;
- }
- *np = 0;
- if (strncmp(bp, "Ent-", 4) == 0) {
- #ifdef DEBUG
- if (list->num_ent <= 0) {
- DPR(("parse_ims_list(): ImsEnt: list->num_ent=%d\n", list->num_ent));
- }
- #endif
- if (!list->elist)
- list->elist = ALLOC(list->num_ent, ImsEnt *);
- if (num_ent >= list->num_ent) {
- DPR(("parse_ims_list(): too many entry: '%s'\n", bp));
- break;
- }
- ent = list->elist[num_ent] = ALLOC(1, ImsEnt);
- ims = ent->ims = ALLOC(1, ImsConf);
- num_ent++;
- } else if (strncmp(bp, "END", 3) == 0) {
- break;
- } else if (bp[0] == ' ' && bp[3] == '=') {
- bp++; vp = bp + 3;
- /*list */
- if (strncmp(bp, "ST", 2) == 0) list->status = atoi(vp);
- else if (strncmp(bp, "ne", 2) == 0) list->num_ent = atoi(vp);
- else if (strncmp(bp, "df", 2) == 0) def_name = vp;
- else if (strncmp(bp, "sm", 2) == 0) list->def_selmode = atoi(vp);
- #ifdef DEBUG
- else if (!ent) {
- DPR(("parse_ims_list(): ImsEnt: list->elist[%d]=%%x\n", num_ent, ent));
- }
- #endif
- /* ent */
- else if (strncmp(bp, "nm", 2) == 0) { RENEWSTR(ent->name, vp); }
- else if (strncmp(bp, "lb", 2) == 0) { RENEWSTR(ent->label, vp); }
- else if (strncmp(bp, "st", 2) == 0) { ent->status = atoi(vp); }
- else if (strncmp(bp, "fg", 2) == 0) { ims->flags = atoi(vp); }
- else if (strncmp(bp, "pr", 2) == 0) { ims->protocols = atoi(vp); }
- else if (strncmp(bp, "to", 2) == 0) { ims->timeout = atoi(vp); }
- else if (strncmp(bp, "it", 2) == 0) { ims->interval = atoi(vp); }
- else if (strncmp(bp, "sn", 2) == 0) { RENEWSTR(ims->servername, vp); }
- else if (strncmp(bp, "sN", 2) == 0) { RENEWSTR(ims->servername2, vp); }
- else if (strncmp(bp, "cn", 2) == 0) { RENEWSTR(ims->classname, vp); }
- else if (strncmp(bp, "pp", 2) == 0) { RENEWSTR(ims->property, vp); }
- else if (strncmp(bp, "cp", 2) == 0) { RENEWSTR(ims->cmd_path, vp); }
- else if (strncmp(bp, "cr", 2) == 0) { RENEWSTR(ims->cmd_param, vp); }
- else if (strncmp(bp, "es", 2) == 0) { RENEWSTR(ims->env_set, vp); }
- else if (strncmp(bp, "eu", 2) == 0) { RENEWSTR(ims->env_unset, vp); }
- else if (strncmp(bp, "ep", 2) == 0) { RENEWSTR(ims->env_pass, vp); }
- else {
- DPR(("parse_ims_list(): invalid line '%s'\n", bp - 1));
- }
- } else {
- DPR(("parse_ims_list(): invalid line '%s'\n", bp));
- }
- bp = np + 1;
- }
- #ifdef DEBUG
- if (num_ent != list->num_ent) {
- DPR(("parse_ims_list(): num_ent(%d) != list->num_ent(%d)\n",
- num_ent, list->num_ent));
- }
- #endif
- list->num_ent = num_ent;
- list->default_idx = -1;
- if (num_ent > 0) {
- for (i = 0; i < num_ent; i++) { /* check indispensable entry */
- ent = list->elist[i];
- if (ent->status == NoError)
- ent->status = check_ims_conf(ent->ims, ent->name);
- }
- if (def_name) { /* set default_idx */
- for (i = 0; i < num_ent; i++)
- if (strcmp(list->elist[i]->name, def_name) == 0) {
- list->default_idx = i;
- break;
- }
- }
- }
- return list->status;
- }
- static int parse_remote_conf(ImsList **listp, char *locale, char *confbuf, int conflen)
- {
- int ret = NoError;
- char *bp = confbuf;
- ImsList *list;
- int data_sz = 0;
- DPR(("parse_remote_conf(%s)\n", locale));
- if (conflen < (int) CONF_MSG_HEADER_LEN /* check header */
- || strncmp(confbuf, conf_msg_id, CONF_MSG_ID_LEN)) {
- ret = ErrNoImsstart;
- } else {
- confbuf[CONF_MSG_HEADER_LEN - 1] = 0; /* <= '\n' */
- bp = confbuf + CONF_MSG_ID_LEN;
- while (*bp == ' ') bp++;
- if (!str_to_int(bp, &data_sz) || data_sz < 0) {
- ret = ErrNoImsstart;
- } else if (conflen < data_sz + (int) CONF_MSG_HEADER_LEN) {
- DPR(("\tconflen(%d) != data_sz(%d) + HDR\n", conflen, data_sz));
- data_sz = conflen - CONF_MSG_HEADER_LEN;
- ret = ErrNoImsstart;
- }
- }
- #ifdef DEBUG
- if (ret != NoError && conflen > (int) CONF_MSG_HEADER_LEN) {
- if (!confbuf[CONF_MSG_HEADER_LEN - 1])
- confbuf[CONF_MSG_HEADER_LEN - 1] = '@';
- confbuf[conflen] = 0;
- DPR(("\tinvalid header[len=%d]: %s\n", conflen, confbuf));
- }
- #endif
- if (ret != NoError) return ErrRemoteAction;
- bp = confbuf + CONF_MSG_HEADER_LEN;
- bp[data_sz] = 0;
- if (strncmp(bp, "ImsList:", 8)
- /* || strncmp(bp + 9, locale, strlen(locale)) */
- || !(bp = strchr(bp, '\n'))) {
- return ErrRemoteAction;
- }
- /* confbuf[conflen] = 0; */
- list = ALLOC(1, ImsList);
- ret = parse_ims_list(bp, list);
- if (ret != NoError || list->num_ent == 0) {
- clear_ImsList(list);
- FREE(list);
- list = (ImsList *) 0;
- ret = ErrRemoteNoIms;
- }
- *listp = list;
- return ret;
- }
- int exec_remote_ims(UserSelection *sel)
- {
- int ret = NoError;
- int n, num_opts, binc;
- char *bp, *np;
- char envbuf[BUFSIZ];
- char tmpbuf[BUFSIZ];
- char *opts[32];
- char **av;
- int ac;
- char *ims_name = sel->name;
- ImsConf *ims = sel->ent->ims;
- char val[20];
- DPR(("exec_remote_ims(): '%s' on %s\n", ims_name, sel->hostname));
- /* build options */
- n = 0;
- bp = tmpbuf; tmpbuf[0] = 0;
- opts[n++] = "-ims"; opts[n++] = ims_name;
- opts[n++] = "-notify";
- opts[n++] = "-nosave";
- opts[n++] = "-nowindow";
- #if 0
- binc = expand_string(bp, "%L", BUFSIZ, 0);
- opts[n++] = "-locale";
- opts[n++] = bp; bp += binc + 1;
- binc = expand_string(bp, "%d.%s", BUFSIZ, 0);
- opts[n++] = "-display";
- opts[n++] = bp; bp += binc = 1;
- #endif
- #ifdef DEBUG
- if (DebugLvl >= 1) {
- int i;
- for (i = 0; i < DebugLvl; i++) opts[n++] = "-debug";
- }
- #endif
- /* options */
- if (OpFlag & FLAG_NOWAIT) opts[n++] = "-nowait";
- if (OpFlag & FLAG_NOTIMEOUT) opts[n++] = "-notimeout";
- if (OpFlag & FLAG_CONNECT) opts[n++] = "-connect";
- if (Opt.Timeout > 0) {
- sprintf(val, "%ld", (long)Opt.Timeout);
- np = strcpyx(bp, val);
- opts[n++] = "-timeout";
- opts[n++] = bp; bp = np + 1;
- }
- if (Opt.Interval > 0) {
- sprintf(val, "%ld", (long)Opt.Interval);
- np = strcpyx(bp, val);
- opts[n++] = "-interval";
- opts[n++] = bp; bp = np + 1;
- }
- if (mk_ims_option(bp, sel)) {
- sprintf(val, "%ld", (long)Opt.Interval);
- np = strcpyx(bp, val);
- opts[n++] = "-imsopt";
- opts[n++] = bp; bp = np + 1;
- }
- bp = NULL;
- opts[n] = NULL;
- num_opts = n;
- /* env variables */
- set_remote_env(envbuf, ims->env_pass);
- ret = prepare_action(ACT_RUNREMIMS, opts, num_opts);
- if (ret != NoError) return ret;
- ret = invoke_action(Conf.action[ACT_RUNREMIMS], sel->hostname);
- change_window_status(WIN_ST_INIT);
- if (ret != NoError) return ret;
- ac = 0;
- av = NULL;
- ret = get_window_data(&ac, &av);
- put_xims_log("'%s' started for %s on %s.",
- sel->name, userEnv.displayname, sel->hostname);
- DPR2(("exec_remote_ims(): ret=%s[%d]\n", error_name(ret), ret));
- return ret;
- }
- int check_hostname(char *hostname)
- {
- int host_type = HOST_UNKNOWN;
- char *local = userEnv.hostname;
- struct hostent *hp;
- unsigned long addr = 0L;
- static unsigned long local_addr = 0L;
- if (!hostname || !*hostname || strcasecmp(hostname, "local") == 0
- || strcasecmp(hostname, userEnv.hostname) == 0) {
- host_type = HOST_LOCAL;
- } else { /* compare inet address */
- if (!local_addr) {
- if ((hp = gethostbyname(local)) && hp->h_addrtype == AF_INET) {
- local_addr = *((unsigned long *) hp->h_addr_list[0]);
- } else {
- DPR(("check_hostname(%s)\tgethostbyname() failed\n", local));
- host_type = HOST_REMOTE;
- }
- }
- if (host_type == HOST_UNKNOWN) {
- if ((hp = gethostbyname(hostname)) && hp->h_addrtype == AF_INET) {
- addr = *((unsigned long *) hp->h_addr_list[0]);
- if (addr == local_addr)
- host_type = HOST_LOCAL;
- else
- host_type = HOST_REMOTE;
- } else {
- DPR(("check_hostname(%s)\tunknown\n", hostname));
- host_type = HOST_UNKNOWN;
- }
- }
- }
- DPR(("check_hostname(%s): [%s] addr=%#x, local=%#x\n", hostname,
- host_type == HOST_LOCAL ? "LOCAL" :
- (host_type == HOST_REMOTE ? "REMOTE" : "UNKNOWN"),
- addr, local_addr));
- return host_type;
- }
- int set_remote_confdata(char *confbuf, int conflen)
- {
- char *av[2];
- av[0] = confbuf; av[1] = NULL;
- return set_window_data(1, av);
- }
- int read_remote_confdata(char **confbuf, int *conflen)
- {
- char **av = NULL;
- int ac = 0;
- int ret;
- ret = get_window_data(&ac, &av);
- /* if (ac != 1) { FREE av[i]; return ErrBabData; } */
- *confbuf = av[0];
- *conflen = strlen(av[0]);
- return NoError;
- }
- static int prepare_action(int act_typ, char **av, int ac)
- {
- int ret;
- ret = init_window_env();
- if (ret != NoError) return ret;
- switch (act_typ) {
- case ACT_GETREMCONF:
- change_window_status(WIN_ST_REMOTE_CONF);
- break;
- case ACT_RUNREMIMS:
- change_window_status(WIN_ST_REMOTE_RUN);
- break;
- default: return ErrInternal;
- }
- ret = set_window_data(ac, av);
- return NoError;
- }
- int get_window_status(void)
- {
- long *datap;
- int len = 0;
- int win_st;
- if (winEnv.atom_status == None || winEnv.atom_owner == None)
- return WIN_ST_NONE;
- if (winEnv.atom_owner == None) return WIN_ST_NONE;
- #if 0
- if (winEnv.atom_owner == XtWindow(winEnv.TopW))
- return winEnv.status;
- #endif
- win_st = WIN_ST_NONE;
- if (read_property(winEnv.atom_status, XA_INTEGER, 32, False,
- (char **)&datap, &len) == True && len > 0) {
- win_st = datap[0];
- FREE(datap);
- }
- return win_st;
- }
- int change_window_status(int status)
- {
- if (winEnv.atom_status == None || winEnv.atom_owner == None)
- return ErrInternal;
- winEnv.status = status;
- (void)XChangeProperty(winEnv.Dpy, winEnv.atom_owner,
- winEnv.atom_status, XA_INTEGER,
- 32, PropModeReplace, (unsigned char *)&status, 1);
- XSync(winEnv.Dpy, False);
- DPR(("change_window_status(): new status=%d\n", status));
- return NoError;
- }
- int set_window_data(int ac, char **av)
- {
- int i;
- int nbytes;
- char *buf, *bp;
- if (winEnv.atom_data == None || winEnv.atom_owner == None)
- return ErrInternal;
- #ifdef DEBUG
- if (DebugLvl >= 1) {
- int i;
- printf("set_window_data() av[%d] = { ", ac);
- for (i = 0; i < ac; i++)
- printf("\"%s\", ", av[i]);
- printf("}\n");
- }
- #endif
- for (i = 0, nbytes = 1; i < ac; i++)
- nbytes += strlen(av[i]) + 1;
- if (bp = buf = XtMalloc(nbytes)) { /* copy args into single buffer */
- for (i = 0; i < ac; i++) {
- if (av[i]) {
- (void) strcpy(bp, av[i]);
- bp += strlen(av[i]) + 1;
- } else
- *bp++ = '\0';
- }
- (void)XChangeProperty(winEnv.Dpy, winEnv.atom_owner,
- winEnv.atom_data, XA_STRING, 8,
- PropModeReplace, (unsigned char *)buf, nbytes);
- XSync(winEnv.Dpy, False);
- XtFree(buf);
- }
- DPR(("set_window_data(): len=%d data=\"%s\"\n", nbytes, buf));
- return NoError;
- }
- int get_window_data(int *acp, char ***avp)
- {
- int ac;
- char *data;
- char **av;
- int len = 0;
- int i, j;
- if (winEnv.atom_data == None || winEnv.atom_owner == None)
- return ErrInternal;
- if (read_property(winEnv.atom_data, XA_STRING, 8, True, &data, &len) != True) {
- *acp = 0;
- *avp = NULL;
- return ErrRemoteData;
- }
- ac = 0; av = NULL;
- if (len > 0) {
- for (i = 1; i < len - 1; i++) if (data[i] == '\0') ac++;
- av = (char **) ALLOC(ac + 1, char *);
- j = 0;
- if (ac == 1) {
- av[j++] = data;
- } else {
- av[j++] = NEWSTR(data);
- for (i = 1; i < len - 1; i++)
- if (data[i] == '\0') {
- av[j++] = NEWSTR(data + i + 1);
- }
- FREE(data);
- }
- av[j] = NULL;
- }
- #ifdef DEBUG
- if (DebugLvl >= 2) {
- int i;
- printf("get_window_data() av[%d] = { ", ac);
- for (i = 0; i < ac; i++)
- printf("\"%s\", ", av[i]);
- printf("}\n");
- }
- #endif
- *acp = ac;
- *avp = av;
- return NoError;
- }
- static int read_property(Atom prop, Atom type, int format,
- int del_flag, unsigned char **datapp,
- unsigned long *lenp)
- {
- Atom realtype;
- int realformat;
- unsigned long bytesafter;
- *datapp = NULL;
- (void)XGetWindowProperty(winEnv.Dpy, winEnv.atom_owner,
- prop, 0L, 1000000L, del_flag, type,
- &realtype, &realformat, lenp,
- &bytesafter, datapp);
- if (realtype == None) {
- return False;
- } else if (realtype != type) { /* wrong type */
- return False;
- } else if (realformat != format) { /* wrong format */
- if (*datapp != NULL) XtFree((char *)*datapp);
- *datapp = NULL;
- return False;
- }
- return True;
- }
|