/* * Searches for the var named "name", and if not found * allocates it. The then extracts the var_string from * the var named "string" and copies it into the var_string * of the var "name", after first allocating a piece of * interprocess shared string memory. If the var "name" * cannot be found or allocated, or the var "string" cannot * be found, the routine returns -1, otherwise it returns 0. */ int var_assign_var(char *name, char *string) { var_t *var; var_string_t str; name += 1; if ((var = var_find(name)) == NULL) var = var_alloc(name); if (var == NULL) { filebench_log(LOG_ERROR, "Cannot assign variable %s", name); return (-1); } if ((str = var_ref_string(string)) == NULL) return (-1); if ((var->var_string = ipc_stralloc(*str)) == NULL) { filebench_log(LOG_ERROR, "Cannot assign variable %s", name); return (-1); } filebench_log(LOG_VERBOSE, "Assign string %s=%s", name, string); return (0); }
struct variable * var_alloc_bool(char *name, bool value, struct variable *next) { struct variable *v = var_alloc(name, next); var_set_bool(v, value); return v; }
/** The meter-create command */ int cmd_meter_create (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } if (OPTIONS.meter[0] == 0) { fprintf (stderr, "%% No meter provided\n"); return 1; } var *req = var_alloc(); var *req_meter = var_get_dict_forkey (req, "meter"); var_set_str_forkey (req_meter, "type", OPTIONS.type); if (OPTIONS.description[0]) { var_set_str_forkey (req_meter, "description", OPTIONS.description); } if (OPTIONS.unit[0]) { var_set_str_forkey (req_meter, "unit", OPTIONS.unit); } var *apires = api_call ("POST",req,"/%s/meter/%s", OPTIONS.tenant, OPTIONS.meter); var_free (req); var_free (apires); return 0; }
/** The watcher-delete command */ int cmd_watcher_delete (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } if (OPTIONS.meter[0] == 0) { fprintf (stderr, "%% No meter provided\n"); return 1; } var *req = var_alloc(); var *apires; if (OPTIONS.host[0]) { apires = api_call ("DELETE", req, "/%s/host/%s/watcher/%s", OPTIONS.tenant, OPTIONS.host, OPTIONS.meter); } else { apires = api_call ("DELETE", req, "/%s/watcher/%s", OPTIONS.tenant, OPTIONS.meter); } var_free (req); var_free (apires); return 0; }
struct variable * var_alloc_vlist(char *name, struct variable * value, struct variable *next) { struct variable *v = var_alloc(name, next); var_set_vlist(v, value); return v; }
struct variable * var_alloc_num(char *name, int value, struct variable *next) { struct variable *v = var_alloc(name, next); var_set_num(v, value); return v; }
struct variable * var_alloc_real(char *name, double value, struct variable *next) { struct variable *v = var_alloc(name, next); var_set_real(v, value); return v; }
void saffire_do_assign(char *var_name, char *val) { //printf("assign(%s => %s)\n", var_name, val); char type = VT_STRING; char *endptr; long num = strtol(val, &endptr, 10); if (endptr == val+strlen(val)) { type = VT_LONG; } t_var *var = var_find(var_name); if (var == NULL) { printf("Initial assign\n"); var = var_alloc(type, var_name, type == VT_STRING ? (void *)val : (void *)num); } else { if (var->type != type) { printf("We cannot switch types!"); exit(1); } if (type == VT_STRING) { var->val.str = strdup(val); } else if (type = VT_LONG) { var->val.num = num; } } //print_var(var); }
struct variable * var_alloc_string(char *name, char * value, struct variable *next) { struct variable *v = var_alloc(name, next); var_set_string(v, value); return v; }
/* * Like var_assign_integer, only this routine copies the * supplied "string" into the var named "name". If the var * named "name" cannot be found then it is first allocated * before the copy. Space for the string in the var comes * from interprocess shared memory. If the var "name" * cannot be found or allocated, or the memory for the * var_string copy of "string" cannot be allocated, the * routine returns -1, otherwise it returns 0. */ int var_assign_string(char *name, char *string) { var_t *var; name += 1; if ((var = var_find(name)) == NULL) var = var_alloc(name); if (var == NULL) { filebench_log(LOG_ERROR, "Cannot assign variable %s", name); return (-1); } if ((var->var_string = ipc_stralloc(string)) == NULL) { filebench_log(LOG_ERROR, "Cannot assign variable %s", name); return (-1); } filebench_log(LOG_DEBUG_SCRIPT, "Assign string %s=%s", name, string); return (0); }
/** The watcher-set command */ int cmd_watcher_set (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } if (OPTIONS.meter[0] == 0) { fprintf (stderr, "%% No meter provided\n"); return 1; } if (OPTIONS.match[0] == 0) { fprintf (stderr, "%% No match provided\n"); return 1; } if (OPTIONS.value[0] == 0) { fprintf (stderr, "%% No value provided\n"); return 1; } var *mdef = api_get ("/%s/meter", OPTIONS.tenant); if (! mdef) return 1; var *mdef_m = var_get_dict_forkey (mdef, "meter"); var *mde_meter = var_get_dict_forkey (mdef_m, OPTIONS.meter); const char *inftype = var_get_str_forkey (mde_meter, "type"); var *req = var_alloc(); var *req_watcher = var_get_dict_forkey (req, "watcher"); var *reql = var_get_dict_forkey (req_watcher, OPTIONS.level); if (OPTIONS.host[0] == 0) { var_set_str_forkey (reql, "cmp", OPTIONS.match); } if (strcmp (inftype, "integer") == 0) { var_set_int_forkey (reql, "val", strtoull (OPTIONS.value, NULL, 10)); } else if (strcmp (inftype, "frac") == 0) { var_set_double_forkey (reql, "val", atof (OPTIONS.value)); } else { var_set_str_forkey (reql, "val", OPTIONS.value); } var_set_double_forkey (reql, "weight", atof (OPTIONS.weight)); var *apires; if (OPTIONS.host[0]) { apires = api_call ("POST", req, "/%s/host/%s/watcher/%s", OPTIONS.tenant, OPTIONS.host, OPTIONS.meter); } else { apires = api_call ("POST", req, "/%s/watcher/%s", OPTIONS.tenant, OPTIONS.meter); } var_free (mdef); var_free (req); var_free (apires); return 0; }
/** Add a double value to an array var. * \param self The array * \param nval The integer to add. */ void var_add_double (var *self, double nval) { if (self->type != VAR_ARRAY) return; var *nvar = var_alloc(); nvar->type = VAR_DOUBLE; nvar->id[0] = 0; nvar->hashcode = 0; nvar->value.dval = nval; var_link (nvar, self); }
var *get_default_meterdef (void) { if (! PARSED_DEFMETERS) { PARSED_DEFMETERS = var_alloc(); if (! var_parse_json (PARSED_DEFMETERS, DEFMETERS)) { log_error ("Parse error: %s", parse_error()); } } return PARSED_DEFMETERS; }
var *get_default_summarydef (void) { if (! PARSED_DEFSUMMARY) { PARSED_DEFSUMMARY = var_alloc(); if (! var_parse_json (PARSED_DEFSUMMARY, DEFSUMMARY)) { log_error ("Parse error (defsum): %s", parse_error()); } } return PARSED_DEFSUMMARY; }
/** Add a string value to an array var. * \param self The array * \param nval The string to add (will be copied). */ void var_add_str (var *self, const char *nval) { if (self->type != VAR_ARRAY) return; var *nvar = var_alloc(); nvar->type = VAR_STR; nvar->id[0] = 0; nvar->hashcode = 0; nvar->value.sval = strdup (nval); var_link (nvar, self); }
/** Add an integer value to an array var. * \param self The array * \param nval The integer to add. */ void var_add_int (var *self, uint64_t nval) { if (self->type != VAR_ARRAY) return; var *nvar = var_alloc(); nvar->type = VAR_INT; nvar->id[0] = 0; nvar->hashcode = 0; nvar->value.ival = nval; var_link (nvar, self); }
var *tenant_overview (tenant *t) { var *res = var_alloc(); var *ov = var_get_dict_forkey (res, "overview"); host *h = t->first; while (h) { host_to_overview (h, ov); h = h->next; } return res; }
/** Get a hold of a keyed sub-var of a dictionary var, whether it exists * or not. Newly created nodes will initialize to type VAR_NULL. * \param self The parent dict. * \param key The key to look up. * \return The var found or created. */ var *var_get_or_make (var *self, const char *key, vartype tp) { var *res = var_find_key (self, key); if (! res) { res = var_alloc(); strncpy (res->id, key, 127); res->id[127] = 0; res->hashcode = hash_token (key); var_link (res, self); } return res; }
/** The tenant-delete command */ int cmd_tenant_delete (int argc, const char *argv[]) { /* Avoid using the default tenant in this case */ disregard_default_tenant(); if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } var *req = var_alloc(); var *apires = api_call ("DELETE", req, "/%s", OPTIONS.tenant); var_free (req); var_free (apires); return 0; }
/** Find, or create, an array node inside a dictionary var. * \param self The var to look into * \param key The key of the alleged/desired dict node. * \return var The dict node, or NULL if we ran into a conflict. */ var *var_get_array_forkey (var *self, const char *key) { var *res = var_find_key (self, key); if (! res) { res = var_alloc(); res->type = VAR_ARRAY; res->value.arr.first = res->value.arr.last = NULL; res->value.arr.count = 0; res->value.arr.cachepos = -1; strncpy (res->id, key, 127); res->id[127] = 0; res->hashcode = hash_token (key); var_link (res, self); } if (res->type == VAR_ARRAY) return res; return NULL; }
/** The meter-delete command */ int cmd_meter_delete (int argc, const char *argv[]) { if (OPTIONS.tenant[0] == 0) { fprintf (stderr, "%% No tenantid provided\n"); return 1; } if (OPTIONS.meter[0] == 0) { fprintf (stderr, "%% No meter provided\n"); return 1; } var *p = var_alloc(); var *apires = api_call ("DELETE", p, "/%s/meter/%s", OPTIONS.tenant, OPTIONS.meter); var_free (p); var_free (apires); return 0; }
/** Add an empty dictionary to an array var. * \param self The parent array. * \return The new empty dictionary (or NULL). */ var *var_add_dict (var *self) { if (self->type == VAR_NULL) { self->type = VAR_ARRAY; self->value.arr.first = self->value.arr.last = NULL; self->value.arr.count = 0; self->value.arr.cachepos = -1; } if (self->type != VAR_ARRAY) return NULL; var *nvar = var_alloc(); nvar->type = VAR_DICT; nvar->id[0] = 0; nvar->hashcode = 0; nvar->value.arr.first = nvar->value.arr.last = NULL; nvar->value.arr.count = 0; nvar->value.arr.cachepos = -1; var_link (nvar, self); return nvar; }
/** The tenant-create command */ int cmd_tenant_create (int argc, const char *argv[]) { uuid tenant; /* Avoid using the default tenant in this case */ disregard_default_tenant(); if (OPTIONS.tenant[0] == 0) { tenant = uuidgen(); OPTIONS.tenant = (const char *) malloc (40); uuid2str (tenant, (char *) OPTIONS.tenant); } else { tenant = mkuuid (OPTIONS.tenant); } var *req = var_alloc(); var *req_tenant = var_get_dict_forkey (req, "tenant"); if (OPTIONS.key[0]) { var_set_str_forkey (req_tenant, "key", OPTIONS.key); } if (OPTIONS.name[0]) { var_set_str_forkey (req_tenant, "name", OPTIONS.name); } var *apires = api_call ("POST", req, "/%s", OPTIONS.tenant); if (apires) { var *r = var_get_dict_forkey (apires, "tenant"); printf ("Tenant created:\n" "---------------------------------------------" "-----------------------------------\n" " Name: %s\n" " UUID: %s\n" " AES Key: %s\n" "---------------------------------------------" "-----------------------------------\n", var_get_str_forkey (r, "name"), OPTIONS.tenant, var_get_str_forkey (r, "key")); } var_free (req); var_free (apires); return 0; }
void _do_incdec(char *var_name, int inc) { t_var *var = var_find(var_name); if (var == NULL) { printf("Warning: var is not initialized."); var = var_alloc(VT_LONG, var_name, 0); } if (var->type != VT_LONG) { printf("Warning: var is not a number"); return; } if (inc) { var->val.num++; } else { var->val.num--; } //print_var(var); }
/* * Searches for the named var, and if found returns a pointer * to the var's var_integer. If not found, attempts to allocate * a var named "name" and returns a pointer to it's (zeroed) * var_integer. If the var cannot be found or allocated, an * error is logged and the run is terminated. */ vinteger_t * var_ref_integer(char *name) { var_t *var; name += 1; if ((var = var_find(name)) == NULL) var = var_find_dynamic(name); if (var == NULL) var = var_alloc(name); if (var == NULL) { filebench_log(LOG_ERROR, "Invalid variable $%s", name); filebench_shutdown(1); } return (&var->var_integer); }
/* * Searches for the named var, and, if found, sets its * var_integer's value to that of the supplied integer. * If not found, the routine allocates a new var and sets * its var_integers's value to that of the supplied * integer. If the named var cannot be found or allocated * the routine returns -1, otherwise it returns 0. */ int var_assign_integer(char *name, vinteger_t integer) { var_t *var; name += 1; if ((var = var_find(name)) == NULL) var = var_alloc(name); if (var == NULL) { filebench_log(LOG_ERROR, "Cannot assign variable %s", name); return (-1); } var->var_integer = integer; filebench_log(LOG_DEBUG_SCRIPT, "Assign integer %s=%lld", name, integer); return (0); }
/** Application main. Handles configuration and command line flags, * then daemonizes. */ int main (int _argc, const char *_argv[]) { int argc = _argc; const char **argv = cliopt_dispatch (CLIOPT, _argv, &argc); if (! argv) return 1; opticonf_add_reaction ("collector/address", conf_collector_address); opticonf_add_reaction ("collector/port", conf_collector_port); opticonf_add_reaction ("collector/key", conf_collector_key); opticonf_add_reaction ("collector/tenant", conf_tenant); opticonf_add_reaction ("collector/host", conf_host); opticonf_add_reaction ("probes/*", conf_probe); APP.transport = outtransport_create_udp(); APP.codec = codec_create_pkt(); APP.conf = var_alloc(); if (! var_load_json (APP.conf, APP.confpath)) { log_error ("Error loading %s: %s\n", APP.confpath, parse_error()); return 1; } opticonf_handle_config (APP.conf); if (! outtransport_setremote (APP.transport, APP.collectoraddr, APP.collectorport)) { log_error ("Error setting remote address"); return 1; } if (! daemonize (APP.pidfile, argc, argv, daemon_main, APP.foreground)) { log_error ("Error spawning"); return 1; } return 0; }
int main (int argc, const char *argv[]) { const char *tstr = NULL; var *env = var_alloc(); var *env_collector = var_get_dict_forkey (env, "collector"); var *env_colors = var_get_array_forkey (env, "colors"); var_set_int_forkey (env_collector, "listenport", 3333); var_set_str_forkey (env_collector, "address", "127.0.0.1"); var_set_str_forkey (env_collector, "key", "secret"); var_clear_array (env_colors); var_add_str (env_colors, "red"); var_add_str (env_colors, "green"); var_add_str (env_colors, "blue"); assert (var_get_int_forkey (env_collector, "listenport") == 3333); assert (tstr = var_get_str_forkey (env_collector, "address")); assert (strcmp (tstr, "127.0.0.1") == 0); assert (tstr = var_get_str_forkey (env_collector, "key")); assert (strcmp (tstr, "secret") == 0); assert (var_get_count (env_collector) == 3); assert (tstr = var_get_str_atindex (env_colors, 0)); assert (strcmp (tstr, "red") == 0); assert (tstr = var_get_str_atindex (env_colors, 1)); assert (strcmp (tstr, "green") == 0); assert (tstr = var_get_str_atindex (env_colors, 2)); assert (strcmp (tstr, "blue") == 0); time_t tnow = time (NULL); var_set_time_forkey (env, "nowtime", tnow); assert (var_get_time_forkey (env, "nowtime") == tnow); var_set_unixtime_forkey (env, "unixtime", tnow); assert (var_get_time_forkey (env, "unixtime") == tnow); uuid uuid_in = uuidgen(); var_set_uuid_forkey (env, "myuuid", uuid_in); uuid uuid_out = var_get_uuid_forkey (env, "myuuid"); assert (uuidcmp (uuid_in, uuid_out)); var_new_generation (env); var_set_int_forkey (env_collector, "listenport", 3333); var_set_str_forkey (env_collector, "address", "192.168.1.1"); var_clear_array (env_colors); var_add_str (env_colors, "red"); var_add_str (env_colors, "green"); var_add_str (env_colors, "blue"); var *lport, *addr, *key; lport = var_find_key (env_collector, "listenport"); addr = var_find_key (env_collector, "address"); key = var_find_key (env_collector, "key"); assert (lport); assert (addr); assert (key); /* collector.listenport should be unchanged from first generation */ assert (lport->generation == env->generation); assert (lport->lastmodified < env->generation); assert (lport->firstseen == lport->lastmodified); /* collector.addr should be changed this generation */ assert (addr->generation == env->generation); assert (addr->lastmodified == env->generation); assert (addr->firstseen == env->firstseen); /* colors should be changed this generation */ assert (env_colors->generation == env->generation); assert (env_colors->lastmodified == env->generation); assert (env_colors->firstseen == env->firstseen); /* collector.key should be stale */ assert (key->generation < env->generation); var_clean_generation (env); /* collector.key should now be deleted */ key = var_find_key (env_collector, "key"); assert (key == NULL); return 0; }
/*}}}*/ }; static int psize = sizeof (parseable) / sizeof (parseable[0]); tag_t * tag_alloc (void) /*{{{*/ { tag_t *t; if (t = (tag_t *) malloc (sizeof (tag_t))) { t -> name = xmlBufferCreate (); t -> cname = NULL; t -> hash = 0; t -> type = NULL; t -> topt = NULL; t -> value = xmlBufferCreate (); t -> parm = NULL; t -> used = false; t -> next = NULL; if ((! t -> name) || (! t -> value)) t = tag_free (t); } return t; }/*}}}*/ tag_t * tag_free (tag_t *t) /*{{{*/ { if (t) { if (t -> name) xmlBufferFree (t -> name); if (t -> cname) free (t -> cname); if (t -> type) free (t -> type); if (t -> value) xmlBufferFree (t -> value); if (t -> parm) var_free_all (t -> parm); free (t); } return NULL; }/*}}}*/ tag_t * tag_free_all (tag_t *t) /*{{{*/ { tag_t *tmp; while (tmp = t) { t = t -> next; tag_free (tmp); } return NULL; }/*}}}*/ static void xmlSkip (xmlChar **ptr, int *len) /*{{{*/ { int n; while (*len > 0) { n = xmlCharLength (**ptr); if ((n == 1) && isspace (**ptr)) { *(*ptr)++ = '\0'; *len -= 1; while ((*len > 0) && (xmlCharLength (**ptr) == 1) && isspace (**ptr)) ++(*ptr); break; } else { *ptr += n; *len -= n; } } }/*}}}*/ static int mkRFCdate (char *dbuf, size_t dlen) /*{{{*/ { time_t now; struct tm *tt; time (& now); if (tt = gmtime (& now)) { const char *weekday[] = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" }, *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" }; return sprintf (dbuf, "%s, %2d %s %d %02d:%02d:%02d GMT", weekday[tt -> tm_wday], tt -> tm_mday, month[tt -> tm_mon], tt -> tm_year + 1900, tt -> tm_hour, tt -> tm_min, tt -> tm_sec) > 0; } return 0; }/*}}}*/ static const char * find_default (tag_t *t) /*{{{*/ { const char *dflt = NULL; var_t *run; for (run = t -> parm; run; run = run -> next) if (! strcmp (run -> var, "default")) { dflt = run -> val; break; } return dflt; }/*}}}*/ void tag_parse (tag_t *t, blockmail_t *blockmail) /*{{{*/ { xmlBufferPtr temp; if (t -> name && (xmlBufferLength (t -> name) > 0) && (temp = xmlBufferCreateSize (xmlBufferLength (t -> name) + 1))) { xmlChar *ptr; xmlChar *name; int len; int tid; xmlBufferAdd (temp, xmlBufferContent (t -> name), xmlBufferLength (t -> name)); ptr = (xmlChar *) xmlBufferContent (temp); len = xmlBufferLength (temp); if ((xmlCharLength (*ptr) == 1) && (*ptr == '[')) { ++ptr; --len; if ((len > 0) && (xmlStrictCharLength (*(ptr + len - 1)) == 1) && (*(ptr + len - 1) == ']')) { --len; if ((len > 0) && (xmlStrictCharLength (*(ptr + len - 1)) == 1) && (*(ptr + len - 1) == '/')) --len; ptr[len] = '\0'; } } name = ptr; xmlSkip (& ptr, & len); if (t -> type) { for (tid = 0; tid < psize; ++tid) if (! strcmp (t -> type, parseable[tid].tname)) break; } else tid = psize; if (tid == psize) for (tid = 0; tid < psize; ++tid) if (! xmlstrcmp (name, parseable[tid].tname)) break; if (tid < psize) { var_t *cur, *prev; xmlChar *var, *val; int n; for (prev = t -> parm; prev && prev -> next; prev = prev -> next) ; while (len > 0) { var = ptr; while (len > 0) { n = xmlCharLength (*ptr); if ((n == 1) && (*ptr == '=')) { *ptr++ = '\0'; len -= 1; break; } else { ptr += n; len -= n; } } if (len > 0) { if ((xmlCharLength (*ptr) == 1) && (*ptr == '"')) { ++ptr; --len; val = ptr; while (len > 0) { n = xmlCharLength (*ptr); if ((n == 1) && (*ptr == '"')) { *ptr++ = '\0'; len -= 1; xmlSkip (& ptr, & len); break; } else { ptr += n; len -= n; } } } else { val = ptr; xmlSkip (& ptr, & len); } if (cur = var_alloc (xml2char (var), xml2char (val))) { if (prev) prev -> next = cur; else t -> parm = cur; prev = cur; } } } switch ((enum PType) tid) { case P_Sysinfo: for (cur = t -> parm; cur; cur = cur -> next) if (! strcmp (cur -> var, "name")) { if (! strcmp (cur -> val, "FQDN")) { const char *dflt; if (blockmail -> fqdn) { xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, blockmail -> fqdn); } else if (dflt = find_default (t)) { xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, dflt); } } else if (! strcmp (cur -> val, "RFCDATE")) { char dbuf[128]; if (mkRFCdate (dbuf, sizeof (dbuf))) { xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, dbuf); } } else if (! strcmp (cur -> val, "EPOCH")) { time_t now; char dbuf[64]; time (& now); sprintf (dbuf, "%ld", (long) now); xmlBufferEmpty (t -> value); xmlBufferCCat (t -> value, dbuf); } } break; } } xmlBufferFree (temp); } }/*}}}*/
/* Set a variable. */ void cp_vset(char *varname, enum cp_types type, void *value) { struct variable *v, *u, *w; int i; bool alreadythere = FALSE, v_free = FALSE; char *copyvarname; /* varname = cp_unquote(varname); DG: Memory leak old varname is lost*/ copyvarname = cp_unquote(varname); w = NULL; for (v = variables; v; v = v->va_next) { if (eq(copyvarname, v->va_name)) { alreadythere = TRUE; break; } w = v; } if (alreadythere) { if (v->va_type == CP_LIST) free_struct_variable(v->va_vlist); if (v->va_type == CP_STRING) tfree(v->va_string); } if (!v) { v = var_alloc(copy(copyvarname), NULL); v_free = TRUE; } switch (type) { case CP_BOOL: if (* ((bool *) value) == FALSE) { cp_remvar(copyvarname); if (v_free) { tfree(v->va_name); tfree(v); } tfree(copyvarname); return; } else { var_set_bool(v, TRUE); } break; case CP_NUM: var_set_num(v, * (int *) value); break; case CP_REAL: var_set_real(v, * (double *) value); break; case CP_STRING: var_set_string(v, copy((char*) value)); break; case CP_LIST: var_set_vlist(v, (struct variable *) value); break; default: fprintf(cp_err, "cp_vset: Internal Error: bad variable type %d.\n", type); tfree(copyvarname); return; } /* Now, see if there is anything interesting going on. We * recognise these special variables: noglob, nonomatch, history, * echo, noclobber, prompt, and verbose. cp_remvar looks for these * variables too. The host program will get any others. */ if (eq(copyvarname, "noglob")) cp_noglob = TRUE; else if (eq(copyvarname, "nonomatch")) cp_nonomatch = TRUE; else if (eq(copyvarname, "history") && (type == CP_NUM)) cp_maxhistlength = v->va_num; else if (eq(copyvarname, "history") && (type == CP_REAL)) cp_maxhistlength = (int)floor(v->va_real + 0.5); else if (eq(copyvarname, "noclobber")) cp_noclobber = TRUE; else if (eq(varname, "echo")) /*CDHW*/ cp_echo = TRUE; /*CDHW*/ else if (eq(copyvarname, "prompt") && (type == CP_STRING)) cp_promptstring = v->va_string; else if (eq(copyvarname, "ignoreeof")) cp_ignoreeof = TRUE; else if (eq(copyvarname, "cpdebug")) { cp_debug = TRUE; #ifndef CPDEBUG fprintf(cp_err, "Warning: program not compiled with cshpar debug messages\n"); #endif } switch (i = cp_usrset(v, TRUE)) { case US_OK: /* Normal case. */ if (!alreadythere) { v->va_next = variables; variables = v; } else if (v_free) free_struct_variable(v); break; case US_DONTRECORD: /* 'curplot' 'curplotname' 'curplottitle' 'curplotdate' */ /* Do nothing... */ if (alreadythere) { fprintf(cp_err, "cp_vset: Internal Error: " "%s already there, but 'dont record'\n", v->va_name); } if (v_free) free_struct_variable(v); break; case US_READONLY: /* 'plots' and any var in plot_cur->pl_env */ fprintf(cp_err, "Error: %s is a read-only variable.\n", v->va_name); if (alreadythere) fprintf(cp_err, "cp_vset: Internal Error: " "it was already there too!!\n"); break; case US_SIMVAR: /* variables processed by if_option(ft_curckt->ci_ckt, ...) */ if (alreadythere) { /* somehow it got into the front-end list of variables */ if (w) { w->va_next = v->va_next; } else { variables = v->va_next; } } alreadythere = FALSE; if (ft_curckt) { for (u = ft_curckt->ci_vars; u; u = u->va_next) if (eq(copyvarname, u->va_name)) { alreadythere = TRUE; break; } if (!alreadythere) { v->va_next = ft_curckt->ci_vars; ft_curckt->ci_vars = v; } else { if (u->va_type == CP_STRING) tfree(u->va_string); else if (u->va_type == CP_LIST) tfree(u->va_vlist); u->va_V = v->va_V; u->va_type = v->va_type; /* va_name is the same string */ tfree(u->va_name); u->va_name = v->va_name; /* va_next left unchanged */ tfree(v); } } break; case US_NOSIMVAR: /* variables processed by if_option(NULL, ...) */ /* What do you do? */ free_struct_variable(v); break; default: fprintf(cp_err, "cp_vset: Internal Error: bad US val %d\n", i); break; } tfree(copyvarname); }