/** * as_utils_compare_versions: * * Compare alpha and numeric segments of two versions. * The version compare algorithm is also used by RPM. * * Returns: 1: a is newer than b * 0: a and b are the same version * -1: b is newer than a */ gint as_utils_compare_versions (const gchar* a, const gchar *b) { /* easy comparison to see if versions are identical */ if (g_strcmp0 (a, b) == 0) return 0; if (a == NULL) return -1; if (b == NULL) return 1; gchar oldch1, oldch2; gchar abuf[strlen(a)+1], bbuf[strlen(b)+1]; gchar *str1 = abuf, *str2 = bbuf; gchar *one, *two; int rc; gboolean isnum; strcpy (str1, a); strcpy (str2, b); one = str1; two = str2; /* loop through each version segment of str1 and str2 and compare them */ while (*one || *two) { while (*one && !g_ascii_isalnum (*one) && *one != '~') one++; while (*two && !g_ascii_isalnum (*two) && *two != '~') two++; /* handle the tilde separator, it sorts before everything else */ if (*one == '~' || *two == '~') { if (*one != '~') return 1; if (*two != '~') return -1; one++; two++; continue; } /* If we ran to the end of either, we are finished with the loop */ if (!(*one && *two)) break; str1 = one; str2 = two; /* grab first completely alpha or completely numeric segment */ /* leave one and two pointing to the start of the alpha or numeric */ /* segment and walk str1 and str2 to end of segment */ if (g_ascii_isdigit (*str1)) { while (*str1 && g_ascii_isdigit (*str1)) str1++; while (*str2 && g_ascii_isdigit (*str2)) str2++; isnum = TRUE; } else { while (*str1 && g_ascii_isalpha (*str1)) str1++; while (*str2 && g_ascii_isalpha (*str2)) str2++; isnum = FALSE; } /* save character at the end of the alpha or numeric segment */ /* so that they can be restored after the comparison */ oldch1 = *str1; *str1 = '\0'; oldch2 = *str2; *str2 = '\0'; /* this cannot happen, as we previously tested to make sure that */ /* the first string has a non-null segment */ if (one == str1) return -1; /* arbitrary */ /* take care of the case where the two version segments are */ /* different types: one numeric, the other alpha (i.e. empty) */ /* numeric segments are always newer than alpha segments */ if (two == str2) return (isnum ? 1 : -1); if (isnum) { size_t onelen, twolen; /* this used to be done by converting the digit segments */ /* to ints using atoi() - it's changed because long */ /* digit segments can overflow an int - this should fix that. */ /* throw away any leading zeros - it's a number, right? */ while (*one == '0') one++; while (*two == '0') two++; /* whichever number has more digits wins */ onelen = strlen (one); twolen = strlen (two); if (onelen > twolen) return 1; if (twolen > onelen) return -1; } /* strcmp will return which one is greater - even if the two */ /* segments are alpha or if they are numeric. don't return */ /* if they are equal because there might be more segments to */ /* compare */ rc = strcmp (one, two); if (rc) return (rc < 1 ? -1 : 1); /* restore character that was replaced by null above */ *str1 = oldch1; one = str1; *str2 = oldch2; two = str2; } /* this catches the case where all numeric and alpha segments have */ /* compared identically but the segment sepparating characters were */ /* different */ if ((!*one) && (!*two)) return 0; /* whichever version still has characters left over wins */ if (!*one) return -1; else return 1; }
static GArray * parse_output(const char *output) { GArray *entries; char **lines; char *ftype = NULL; char *fname = NULL; guint i; guint len; int fd = -1; entries = g_array_new(FALSE, FALSE, sizeof(glibtop_open_files_entry)); lines = g_strsplit(output, "\n", 0); len = g_strv_length(lines); for (i = 0; i < len && lines[i]; i++) { glibtop_open_files_entry entry = {0}; if (strlen(lines[i]) < 2) continue; if (!g_str_has_prefix(lines[i], "f") && !g_str_has_prefix(lines[i], "t") && !g_str_has_prefix(lines[i], "n")) continue; if (g_str_has_prefix(lines[i], "f")) { if (!g_ascii_isdigit(*(lines[i] + 1))) i += 2; else fd = atoi(lines[i] + 1); continue; } if (g_str_has_prefix(lines[i], "t")) { ftype = lines[i]; ftype++; continue; } else { fname = lines[i]; fname++; } if (ftype == NULL || fname == NULL) continue; if (!strcmp(ftype, "unix")) { entry.type = GLIBTOP_FILE_TYPE_LOCALSOCKET; g_strlcpy(entry.info.localsock.name, fname, sizeof(entry.info.localsock.name)); } else if (!strcmp(ftype, "PIPE")) { entry.type = GLIBTOP_FILE_TYPE_PIPE; } else if (!strcmp(ftype, "VREG") || !strcmp(ftype, "GDIR") || !strcmp(ftype, "GREG") || !strcmp(ftype, "VCHR") || !strcmp(ftype, "VBLK") || !strcmp(ftype, "DIR") || !strcmp(ftype, "LINK") || !strcmp(ftype, "REG") || !strcmp(ftype, "VDIR")) { entry.type = GLIBTOP_FILE_TYPE_FILE; g_strlcpy(entry.info.file.name, fname, sizeof(entry.info.file.name)); } else if (!strcmp(ftype, "IPv4")) { char **hosts; char **remote_host; if (!strstr(fname, "->")) { remote_host = g_strsplit(fname, ":", 0); } else { hosts = g_strsplit(fname, "->", 0); if (g_strv_length(hosts) < 2) { g_strfreev(hosts); continue; } remote_host = g_strsplit(hosts[1], ":", 0); g_strfreev(hosts); } if (g_strv_length(remote_host) < 2) { g_strfreev(remote_host); continue; } entry.type = GLIBTOP_FILE_TYPE_INETSOCKET; if (!strcmp(remote_host[0], "*")) g_strlcpy(entry.info.sock.dest_host, "0.0.0.0", sizeof(entry.info.sock.dest_host)); else g_strlcpy(entry.info.sock.dest_host, remote_host[0], sizeof(entry.info.sock.dest_host)); entry.info.sock.dest_port = atoi(remote_host[1]); g_strfreev(remote_host); } else if (!strcmp(ftype, "IPv6")) { char **hosts; char **remote_host; if (!strstr(fname, "->")) { remote_host = g_strsplit(fname, ":", 0); } else { hosts = g_strsplit(fname, "->", 0); if (g_strv_length(hosts) < 2) { g_strfreev(hosts); continue; } remote_host = g_strsplit(hosts[1], "]", 0); g_strfreev(hosts); } if (g_strv_length(remote_host) < 2) { g_strfreev(remote_host); continue; } entry.type = GLIBTOP_FILE_TYPE_INET6SOCKET; if (!strcmp(remote_host[0], "*")) g_strlcpy(entry.info.sock.dest_host, "0.0.0.0", sizeof(entry.info.sock.dest_host)); else g_strlcpy(entry.info.sock.dest_host, remote_host[0] + 1, sizeof(entry.info.sock.dest_host)); entry.info.sock.dest_port = atoi(remote_host[1] + 1); g_strfreev(remote_host); } else continue; entry.fd = fd; fd = -1; ftype = NULL; fname = NULL; g_array_append_val(entries, entry); } g_strfreev(lines); return entries; }
int main (int argc, char *argv[]) { GError *error = NULL; GOptionContext *context; GMainLoop *loop; GInetAddress *inet; GSocketAddress *address; GSocketService *listener; char *path, *basename; char *http_address = NULL; char *unixsocket_address = NULL; int http_port = 0; char *ssl_cert = NULL; char *ssl_key = NULL; char *display; int port = 0; const GOptionEntry entries[] = { { "port", 'p', 0, G_OPTION_ARG_INT, &http_port, "Httpd port", "PORT" }, { "address", 'a', 0, G_OPTION_ARG_STRING, &http_address, "Ip address to bind to ", "ADDRESS" }, #ifdef G_OS_UNIX { "unixsocket", 'u', 0, G_OPTION_ARG_STRING, &unixsocket_address, "Unix domain socket address", "ADDRESS" }, #endif { "cert", 'c', 0, G_OPTION_ARG_STRING, &ssl_cert, "SSL certificate path", "PATH" }, { "key", 'k', 0, G_OPTION_ARG_STRING, &ssl_key, "SSL key path", "PATH" }, { NULL } }; setlocale (LC_ALL, ""); context = g_option_context_new ("[:DISPLAY] - broadway display daemon"); g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE); if (!g_option_context_parse (context, &argc, &argv, &error)) { g_printerr ("option parsing failed: %s\n", error->message); exit (1); } display = NULL; if (argc > 1) { if (*argv[1] != ':') { g_printerr ("Usage broadwayd [:DISPLAY]\n"); exit (1); } display = argv[1]; } if (display == NULL) { #ifdef G_OS_UNIX if (g_unix_socket_address_abstract_names_supported ()) display = ":0"; else #endif display = ":tcp"; } if (g_str_has_prefix (display, ":tcp")) { port = strtol (display + strlen (":tcp"), NULL, 10); inet = g_inet_address_new_from_string ("127.0.0.1"); g_print ("Listening on 127.0.0.1:%d\n", port + 9090); address = g_inet_socket_address_new (inet, port + 9090); g_object_unref (inet); } #ifdef G_OS_UNIX else if (display[0] == ':' && g_ascii_isdigit(display[1])) { port = strtol (display + strlen (":"), NULL, 10); basename = g_strdup_printf ("broadway%d.socket", port + 1); path = g_build_filename (g_get_user_runtime_dir (), basename, NULL); g_free (basename); g_print ("Listening on %s\n", path); address = g_unix_socket_address_new_with_type (path, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT); g_free (path); } #endif else { g_printerr ("Failed to parse display %s\n", display); exit (1); } if (http_port == 0) http_port = 8080 + port; if (unixsocket_address != NULL) server = broadway_server_on_unix_socket_new (unixsocket_address, &error); else server = broadway_server_new (http_address, http_port, ssl_cert, ssl_key, &error); if (server == NULL) { g_printerr ("%s\n", error->message); return 1; } listener = g_socket_service_new (); if (!g_socket_listener_add_address (G_SOCKET_LISTENER (listener), address, G_SOCKET_TYPE_STREAM, G_SOCKET_PROTOCOL_DEFAULT, G_OBJECT (server), NULL, &error)) { g_printerr ("Can't listen: %s\n", error->message); return 1; } g_object_unref (address); g_signal_connect (listener, "incoming", G_CALLBACK (incoming_client), NULL); g_socket_service_start (G_SOCKET_SERVICE (listener)); loop = g_main_loop_new (NULL, FALSE); g_main_loop_run (loop); return 0; }
static void numa_node_parse(NumaNodeOptions *node, QemuOpts *opts, Error **errp) { uint16_t nodenr; uint16List *cpus = NULL; if (node->has_nodeid) { nodenr = node->nodeid; } else { nodenr = nb_numa_nodes; } if (nodenr >= MAX_NODES) { error_setg(errp, "Max number of NUMA nodes reached: %" PRIu16 "", nodenr); return; } if (numa_info[nodenr].present) { error_setg(errp, "Duplicate NUMA nodeid: %" PRIu16, nodenr); return; } for (cpus = node->cpus; cpus; cpus = cpus->next) { if (cpus->value > MAX_CPUMASK_BITS) { error_setg(errp, "CPU number %" PRIu16 " is bigger than %d", cpus->value, MAX_CPUMASK_BITS); return; } bitmap_set(numa_info[nodenr].node_cpu, cpus->value, 1); } if (node->has_mem && node->has_memdev) { error_setg(errp, "qemu: cannot specify both mem= and memdev="); return; } if (have_memdevs == -1) { have_memdevs = node->has_memdev; } if (node->has_memdev != have_memdevs) { error_setg(errp, "qemu: memdev option must be specified for either " "all or no nodes"); return; } if (node->has_mem) { uint64_t mem_size = node->mem; const char *mem_str = qemu_opt_get(opts, "mem"); /* Fix up legacy suffix-less format */ if (g_ascii_isdigit(mem_str[strlen(mem_str) - 1])) { mem_size <<= 20; } numa_info[nodenr].node_mem = mem_size; } if (node->has_memdev) { Object *o; o = object_resolve_path_type(node->memdev, TYPE_MEMORY_BACKEND, NULL); if (!o) { error_setg(errp, "memdev=%s is ambiguous", node->memdev); return; } object_ref(o); numa_info[nodenr].node_mem = object_property_get_int(o, "size", NULL); numa_info[nodenr].node_memdev = MEMORY_BACKEND(o); } numa_info[nodenr].present = true; max_numa_nodeid = MAX(max_numa_nodeid, nodenr + 1); }
/** * soup_header_parse_quality_list: * @header: a header value * @unacceptable: (out) (allow-none) (transfer full) (element-type utf8): on * return, will contain a list of unacceptable values * * Parses a header whose content is a list of items with optional * "qvalue"s (eg, Accept, Accept-Charset, Accept-Encoding, * Accept-Language, TE). * * If @unacceptable is not %NULL, then on return, it will contain the * items with qvalue 0. Either way, those items will be removed from * the main list. * * Return value: (transfer full) (element-type utf8): a #GSList of * acceptable values (as allocated strings), highest-qvalue first. **/ GSList * soup_header_parse_quality_list (const char *header, GSList **unacceptable) { GSList *unsorted; QualityItem *array; GSList *sorted, *iter; char *item, *semi; const char *param, *equal, *value; double qval; int n; g_return_val_if_fail (header != NULL, NULL); if (unacceptable) *unacceptable = NULL; unsorted = soup_header_parse_list (header); array = g_new0 (QualityItem, g_slist_length (unsorted)); for (iter = unsorted, n = 0; iter; iter = iter->next) { item = iter->data; qval = 1.0; for (semi = strchr (item, ';'); semi; semi = strchr (semi + 1, ';')) { param = skip_lws (semi + 1); if (*param != 'q') continue; equal = skip_lws (param + 1); if (!equal || *equal != '=') continue; value = skip_lws (equal + 1); if (!value) continue; if (value[0] != '0' && value[0] != '1') continue; qval = (double)(value[0] - '0'); if (value[0] == '0' && value[1] == '.') { if (g_ascii_isdigit (value[2])) { qval += (double)(value[2] - '0') / 10; if (g_ascii_isdigit (value[3])) { qval += (double)(value[3] - '0') / 100; if (g_ascii_isdigit (value[4])) qval += (double)(value[4] - '0') / 1000; } } } *semi = '\0'; break; } if (qval == 0.0) { if (unacceptable) { *unacceptable = g_slist_prepend (*unacceptable, item); } } else { array[n].item = item; array[n].qval = qval; n++; } } g_slist_free (unsorted); qsort (array, n, sizeof (QualityItem), sort_by_qval); sorted = NULL; while (n--) sorted = g_slist_prepend (sorted, array[n].item); g_free (array); return sorted; }
gboolean string_to_decimal_value (const char* str, FieldValue* value) { unsigned left, right, len; unsigned dot; unsigned i; unsigned start, end; char* buf; len = strlen(str); start = 0; end = len -1; left = end; right = start; dot = len; buf = g_strdup (str); if (!buf) { return FALSE; } for (i = 0; i < len; ++i) { switch (buf[i]) { case '-': case '+': start = i+1; break; case '0': break; case '.': if(dot!=len) { return FALSE; } dot = i; break; default: if(!g_ascii_isdigit(buf[i])) { return FALSE; } if (i < left) left = i; if (i > right) right = i; break; } } if (dot <= right) { /* Scoot that memory over. */ memmove (dot+buf, 1+dot+buf, right-dot); right -= 1; } dot -= 1; /* Now sitting on the 10^0 digit. */ value->decimal.exponent = (gint32) dot - (gint32) right; end = 1+right; buf[end] = 0; value->decimal.mantissa = g_ascii_strtoll(buf, NULL, 10); if (0 == value->decimal.mantissa) { /* Our /right/ was never set correctly, could be invalid. * Thus, the exponent may be strange. */ value->decimal.exponent = 0; /* return FALSE; */ } g_free(buf); return TRUE; }
gboolean rspamd_map_add (struct rspamd_config *cfg, const gchar *map_line, const gchar *description, map_cb_t read_callback, map_fin_cb_t fin_callback, void **user_data) { struct rspamd_map *new_map; enum fetch_proto proto; const gchar *def, *p, *hostend; struct file_map_data *fdata; struct http_map_data *hdata; gchar portbuf[6], *cksum_encoded, cksum[BLAKE2B_OUTBYTES]; gint i, s, r; struct addrinfo hints, *res; rspamd_mempool_t *pool; /* First of all detect protocol line */ if (!rspamd_map_check_proto (map_line, (int *)&proto, &def)) { return FALSE; } /* Constant pool */ if (cfg->map_pool == NULL) { cfg->map_pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "map"); memcpy (cfg->map_pool->tag.uid, cfg->cfg_pool->tag.uid, sizeof (cfg->map_pool->tag.uid)); } new_map = rspamd_mempool_alloc0 (cfg->map_pool, sizeof (struct rspamd_map)); new_map->read_callback = read_callback; new_map->fin_callback = fin_callback; new_map->user_data = user_data; new_map->protocol = proto; new_map->cfg = cfg; new_map->id = g_random_int (); new_map->locked = rspamd_mempool_alloc0_shared (cfg->cfg_pool, sizeof (gint)); if (proto == MAP_PROTO_FILE) { new_map->uri = rspamd_mempool_strdup (cfg->cfg_pool, def); def = new_map->uri; } else { new_map->uri = rspamd_mempool_strdup (cfg->cfg_pool, map_line); } if (description != NULL) { new_map->description = rspamd_mempool_strdup (cfg->cfg_pool, description); } /* Now check for each proto separately */ if (proto == MAP_PROTO_FILE) { fdata = rspamd_mempool_alloc0 (cfg->map_pool, sizeof (struct file_map_data)); if (access (def, R_OK) == -1) { if (errno != ENOENT) { msg_err_config ("cannot open file '%s': %s", def, strerror (errno)); return FALSE; } msg_info_config ( "map '%s' is not found, but it can be loaded automatically later", def); /* We still can add this file */ fdata->st.st_mtime = -1; } else { stat (def, &fdata->st); } fdata->filename = rspamd_mempool_strdup (cfg->map_pool, def); new_map->map_data = fdata; } else if (proto == MAP_PROTO_HTTP) { hdata = rspamd_mempool_alloc0 (cfg->map_pool, sizeof (struct http_map_data)); /* Try to search port */ if ((p = strchr (def, ':')) != NULL) { hostend = p; i = 0; p++; while (g_ascii_isdigit (*p) && i < (gint)sizeof (portbuf) - 1) { portbuf[i++] = *p++; } if (*p != '/') { msg_info_config ("bad http map definition: %s", def); return FALSE; } portbuf[i] = '\0'; hdata->port = atoi (portbuf); } else { /* Default http port */ rspamd_snprintf (portbuf, sizeof (portbuf), "80"); hdata->port = 80; /* Now separate host from path */ if ((p = strchr (def, '/')) == NULL) { msg_info_config ("bad http map definition: %s", def); return FALSE; } hostend = p; } hdata->host = rspamd_mempool_alloc (cfg->map_pool, hostend - def + 1); rspamd_strlcpy (hdata->host, def, hostend - def + 1); hdata->path = rspamd_mempool_strdup (cfg->map_pool, p); /* Now try to resolve */ memset (&hints, 0, sizeof (hints)); hints.ai_family = AF_UNSPEC; /* Allow IPv4 or IPv6 */ hints.ai_socktype = SOCK_STREAM; /* Stream socket */ hints.ai_flags = 0; hints.ai_protocol = 0; /* Any protocol */ hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; if ((r = getaddrinfo (hdata->host, portbuf, &hints, &res)) == 0) { hdata->addr = res; rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t)freeaddrinfo, hdata->addr); } else { msg_err_config ("address resolution for %s failed: %s", hdata->host, gai_strerror (r)); return FALSE; } /* Now try to connect */ if ((s = rspamd_socket_tcp (hdata->addr, FALSE, FALSE)) == -1) { msg_info_config ("cannot connect to http server %s: %d, %s", hdata->host, errno, strerror (errno)); return FALSE; } close (s); hdata->conn = rspamd_http_connection_new (http_map_read, http_map_error, http_map_finish, RSPAMD_HTTP_BODY_PARTIAL | RSPAMD_HTTP_CLIENT_SIMPLE, RSPAMD_HTTP_CLIENT, NULL); new_map->map_data = hdata; } /* Temp pool */ blake2b (cksum, new_map->uri, NULL, sizeof (cksum), strlen (new_map->uri), 0); cksum_encoded = rspamd_encode_base32 (cksum, sizeof (cksum)); new_map->pool = rspamd_mempool_new (rspamd_mempool_suggest_size (), "map"); memcpy (new_map->pool->tag.uid, cksum_encoded, sizeof (new_map->pool->tag.uid)); g_free (cksum_encoded); pool = new_map->pool; msg_info_pool ("added map %s", new_map->uri); cfg->maps = g_list_prepend (cfg->maps, new_map); return TRUE; }
static int contains_coord(char *line) { return g_ascii_isdigit(line[0]); }
/* Parse the data section of VCD */ static void parse_contents(FILE *file, const struct sr_dev_inst *sdi, struct context *ctx) { GString *token = g_string_sized_new(32); uint64_t prev_timestamp = 0; uint64_t prev_values = 0; /* Read one space-delimited token at a time. */ while (read_until(file, NULL, 'N') && read_until(file, token, 'W')) { if (token->str[0] == '#' && g_ascii_isdigit(token->str[1])) { /* Numeric value beginning with # is a new timestamp value */ uint64_t timestamp; timestamp = strtoull(token->str + 1, NULL, 10); if (ctx->downsample > 1) timestamp /= ctx->downsample; /* Skip < 0 => skip until first timestamp. * Skip = 0 => don't skip * Skip > 0 => skip until timestamp >= skip. */ if (ctx->skip < 0) { ctx->skip = timestamp; prev_timestamp = timestamp; } else if (ctx->skip > 0 && timestamp < (uint64_t)ctx->skip) { prev_timestamp = ctx->skip; } else if (timestamp == prev_timestamp) { /* Ignore repeated timestamps (e.g. sigrok outputs these) */ } else { if (ctx->compress != 0 && timestamp - prev_timestamp > ctx->compress) { /* Compress long idle periods */ prev_timestamp = timestamp - ctx->compress; } sr_dbg("New timestamp: %" PRIu64, timestamp); /* Generate samples from prev_timestamp up to timestamp - 1. */ send_samples(sdi, prev_values, timestamp - prev_timestamp); prev_timestamp = timestamp; } } else if (token->str[0] == '$' && token->len > 1) { /* This is probably a $dumpvars, $comment or similar. * $dump* contain useful data, but other tags will be skipped until $end. */ if (g_strcmp0(token->str, "$dumpvars") == 0 || g_strcmp0(token->str, "$dumpon") == 0 || g_strcmp0(token->str, "$dumpoff") == 0 || g_strcmp0(token->str, "$end") == 0) { /* Ignore, parse contents as normally. */ } else { /* Skip until $end */ read_until(file, NULL, '$'); } } else if (strchr("bBrR", token->str[0]) != NULL) { /* A vector value. Skip it and also the following identifier. */ read_until(file, NULL, 'N'); read_until(file, NULL, 'W'); } else if (strchr("01xXzZ", token->str[0]) != NULL) { /* A new 1-bit sample value */ int i, bit; GSList *l; struct probe *probe; bit = (token->str[0] == '1'); g_string_erase(token, 0, 1); if (token->len == 0) { /* There was a space between value and identifier. * Read in the rest. */ read_until(file, NULL, 'N'); read_until(file, token, 'W'); } for (i = 0, l = ctx->probes; i < ctx->probecount && l; i++, l = l->next) { probe = l->data; if (g_strcmp0(token->str, probe->identifier) == 0) { sr_dbg("Probe %d new value %d.", i, bit); /* Found our probe */ if (bit) prev_values |= (1 << i); else prev_values &= ~(1 << i); break; } } if (i == ctx->probecount) { sr_dbg("Did not find probe for identifier '%s'.", token->str); } } else { sr_warn("Skipping unknown token '%s'.", token->str); } g_string_truncate(token, 0); } g_string_free(token, TRUE); }
/* * Note: The str will be modified, so in case of error you should * throw it away and start over */ gboolean parse_ss_control_string(char *str, int *ss_type, char **sc, char **sia, char **sib, char **sic, char **sid, char **dn) { int len = strlen(str); int cur = 0; char *c; unsigned int i; gboolean ret = FALSE; /* Minimum is {*,#}SC# */ if (len < 4) goto out; if (str[0] != '*' && str[0] != '#') goto out; cur = 1; if (str[1] != '*' && str[1] != '#' && str[1] > '9' && str[1] < '0') goto out; if (str[0] == '#' && str[1] == '*') goto out; if (str[1] == '#' || str[1] == '*') cur = 2; if (str[0] == '*' && str[1] == '*') *ss_type = SS_CONTROL_TYPE_REGISTRATION; else if (str[0] == '#' && str[1] == '#') *ss_type = SS_CONTROL_TYPE_ERASURE; else if (str[0] == '*' && str[1] == '#') *ss_type = SS_CONTROL_TYPE_QUERY; else if (str[0] == '*') *ss_type = SS_CONTROL_TYPE_ACTIVATION; else *ss_type = SS_CONTROL_TYPE_DEACTIVATION; /* Must have at least one other '#' */ c = strrchr(str+cur, '#'); if (c == NULL) goto out; *dn = c+1; *c = '\0'; if (strlen(*dn) > 0 && !valid_phone_number_format(*dn)) goto out; c = str+cur; NEXT_FIELD(c, *sc); /* * According to 22.030 SC is 2 or 3 digits, there can be * an optional digit 'n' if this is a call setup string, * however 22.030 does not define any SC of length 3 * with an 'n' present */ if (strlen(*sc) < 2 || strlen(*sc) > 3) goto out; for (i = 0; i < strlen(*sc); i++) if (!g_ascii_isdigit((*sc)[i])) goto out; NEXT_FIELD(c, *sia); NEXT_FIELD(c, *sib); NEXT_FIELD(c, *sic); NEXT_FIELD(c, *sid); if (*c == '\0') ret = TRUE; out: return ret; }
GList *get_entries_from_file(gchar *file_name) { gchar *text, *pat; GMappedFile *mf; gsize len; gboolean more = TRUE; gchar lat_buf[32], lon_buf[32]; gchar *s; gint fragment_len; GList *found_places = NULL; found_geoname *geoname = NULL; gchar **found_entries; gchar *entry; int entry_runner; gchar *wikipedia_url = NULL; gchar *thumbnail_url = NULL; lat_buf[0] = lon_buf[0] = '\0'; if ((mf = g_mapped_file_new(file_name, FALSE, NULL)) == NULL) { g_critical(_("couldn't map temp file")); exit(1); } len = g_mapped_file_get_length(mf); text = g_mapped_file_get_contents(mf); if (g_strstr_len(text, len, GEONAMES_SEARCH_NOT_FOUND) != NULL) { more = FALSE; } found_entries = g_strsplit(text, "},", 0); entry_runner = 0; entry = found_entries[entry_runner]; while (entry) { more = TRUE; geoname = new_found_geoname(); if ((pat = g_strstr_len(entry, strlen(entry), GEONAMES_COUNTRY_PATTERN))) { pat += strlen(GEONAMES_COUNTRY_PATTERN); fragment_len = 0; s = pat; while (*pat != '"') { fragment_len++; pat++; } geoname -> country = g_strndup(s, fragment_len); } if ((pat = g_strstr_len(entry, strlen(entry), GEONAMES_LONGITUDE_PATTERN)) == NULL) { more = FALSE; } else { pat += strlen(GEONAMES_LONGITUDE_PATTERN); s = lon_buf; if (*pat == '-') *s++ = *pat++; while ((s < (lon_buf + sizeof(lon_buf))) && (pat < (text + len)) && (g_ascii_isdigit(*pat) || (*pat == '.'))) *s++ = *pat++; *s = '\0'; if ((pat >= (text + len)) || (lon_buf[0] == '\0')) { more = FALSE; } geoname->ll.lon = g_ascii_strtod(lon_buf, NULL); } if ((pat = g_strstr_len(entry, strlen(entry), GEONAMES_NAME_PATTERN))) { pat += strlen(GEONAMES_NAME_PATTERN); fragment_len = 0; s = pat; while (*pat != '"') { fragment_len++; pat++; } geoname -> name = g_strndup(s, fragment_len); } if ((pat = g_strstr_len(entry, strlen(entry), GEONAMES_TITLE_PATTERN))) { pat += strlen(GEONAMES_TITLE_PATTERN); fragment_len = 0; s = pat; while (*pat != '"') { fragment_len++; pat++; } geoname -> name = g_strndup(s, fragment_len); } if ((pat = g_strstr_len(entry, strlen(entry), GEONAMES_WIKIPEDIAURL_PATTERN))) { pat += strlen(GEONAMES_WIKIPEDIAURL_PATTERN); fragment_len = 0; s = pat; while (*pat != '"') { fragment_len++; pat++; } wikipedia_url = g_strndup(s, fragment_len); } if ((pat = g_strstr_len(entry, strlen(entry), GEONAMES_THUMBNAILIMG_PATTERN))) { pat += strlen(GEONAMES_THUMBNAILIMG_PATTERN); fragment_len = 0; s = pat; while (*pat != '"') { fragment_len++; pat++; } thumbnail_url = g_strndup(s, fragment_len); } if ((pat = g_strstr_len(entry, strlen(entry), GEONAMES_LATITUDE_PATTERN)) == NULL) { more = FALSE; } else { pat += strlen(GEONAMES_LATITUDE_PATTERN); s = lat_buf; if (*pat == '-') *s++ = *pat++; while ((s < (lat_buf + sizeof(lat_buf))) && (pat < (text + len)) && (g_ascii_isdigit(*pat) || (*pat == '.'))) *s++ = *pat++; *s = '\0'; if ((pat >= (text + len)) || (lat_buf[0] == '\0')) { more = FALSE; } geoname->ll.lat = g_ascii_strtod(lat_buf, NULL); } if (!more) { if (geoname) { g_free(geoname); } } else { if (wikipedia_url) { if (thumbnail_url) { geoname -> desc = g_strdup_printf("<a href=\"http://%s\" target=\"_blank\"><img src=\"%s\" border=\"0\"/></a>", wikipedia_url, thumbnail_url); } else { geoname -> desc = g_strdup_printf("<a href=\"http://%s\" target=\"_blank\">%s</a>", wikipedia_url, geoname->name); } } if (wikipedia_url) { g_free(wikipedia_url); wikipedia_url = NULL; } if (thumbnail_url) { g_free(thumbnail_url); thumbnail_url = NULL; } found_places = g_list_prepend(found_places, geoname); } entry_runner++; entry = found_entries[entry_runner]; } g_strfreev(found_entries); found_places = g_list_reverse(found_places); g_mapped_file_free(mf); return(found_places); }
/*! * \brief Parse the SVG node from a shape file * * Fill the ShapeInfo display list with GraphicElement each got from * a single node within the shape's SVG part. * * \extends _ShapeInfo */ static void parse_svg_node(ShapeInfo *info, xmlNodePtr node, xmlNsPtr svg_ns, DiaSvgStyle *style, const gchar *filename) { xmlChar *str; /* walk SVG node ... */ for (node = node->xmlChildrenNode; node != NULL; node = node->next) { GraphicElement *el = NULL; DiaSvgStyle s; if (xmlIsBlankNode(node)) continue; if (node->type != XML_ELEMENT_NODE || node->ns != svg_ns) continue; dia_svg_style_init (&s, style); dia_svg_parse_style(node, &s, -1); if (!xmlStrcmp(node->name, (const xmlChar *)"line")) { GraphicElementLine *line = g_new0(GraphicElementLine, 1); el = (GraphicElement *)line; line->type = GE_LINE; str = xmlGetProp(node, (const xmlChar *)"x1"); if (str) { line->p1.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y1"); if (str) { line->p1.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"x2"); if (str) { line->p2.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y2"); if (str) { line->p2.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"polyline")) { GraphicElementPoly *poly; GArray *arr = g_array_new(FALSE, FALSE, sizeof(real)); real val, *rarr; gchar *tmp; int i; str = xmlGetProp(node, (const xmlChar *)"points"); tmp = (gchar *) str; while (tmp[0] != '\0') { /* skip junk */ while (tmp[0] != '\0' && !g_ascii_isdigit(tmp[0]) && tmp[0]!='.'&&tmp[0]!='-') tmp++; if (tmp[0] == '\0') break; val = g_ascii_strtod(tmp, &tmp); g_array_append_val(arr, val); } xmlFree(str); val = 0; if (arr->len % 2 == 1) g_array_append_val(arr, val); poly = g_malloc0(sizeof(GraphicElementPoly) + arr->len/2*sizeof(Point)); el = (GraphicElement *)poly; poly->type = GE_POLYLINE; poly->npoints = arr->len / 2; rarr = (real *)arr->data; for (i = 0; i < poly->npoints; i++) { poly->points[i].x = rarr[2*i]; poly->points[i].y = rarr[2*i+1]; } g_array_free(arr, TRUE); } else if (!xmlStrcmp(node->name, (const xmlChar *)"polygon")) { GraphicElementPoly *poly; GArray *arr = g_array_new(FALSE, FALSE, sizeof(real)); real val, *rarr; char *tmp; int i; str = xmlGetProp(node, (const xmlChar *)"points"); tmp = (char *) str; while (tmp[0] != '\0') { /* skip junk */ while (tmp[0] != '\0' && !g_ascii_isdigit(tmp[0]) && tmp[0]!='.'&&tmp[0]!='-') tmp++; if (tmp[0] == '\0') break; val = g_ascii_strtod(tmp, &tmp); g_array_append_val(arr, val); } xmlFree(str); val = 0; if (arr->len % 2 == 1) g_array_append_val(arr, val); poly = g_malloc0(sizeof(GraphicElementPoly) + arr->len/2*sizeof(Point)); el = (GraphicElement *)poly; poly->type = GE_POLYGON; poly->npoints = arr->len / 2; rarr = (real *)arr->data; for (i = 0; i < poly->npoints; i++) { poly->points[i].x = rarr[2*i]; poly->points[i].y = rarr[2*i+1]; } g_array_free(arr, TRUE); } else if (!xmlStrcmp(node->name, (const xmlChar *)"rect")) { GraphicElementRect *rect = g_new0(GraphicElementRect, 1); real corner_radius = 0.0; el = (GraphicElement *)rect; rect->type = GE_RECT; str = xmlGetProp(node, (const xmlChar *)"x"); if (str) { rect->corner1.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else rect->corner1.x = 0; str = xmlGetProp(node, (const xmlChar *)"y"); if (str) { rect->corner1.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else rect->corner1.y = 0; str = xmlGetProp(node, (const xmlChar *)"width"); if (str) { rect->corner2.x = rect->corner1.x + g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"height"); if (str) { rect->corner2.y = rect->corner1.y + g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"rx"); if (str) { corner_radius = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"ry"); if (str) { if(corner_radius != 0.0) { /* calculate the mean value of rx and ry */ corner_radius = (corner_radius+g_ascii_strtod((gchar *) str, NULL))/2; } else { corner_radius = g_ascii_strtod((gchar *) str, NULL); } xmlFree(str); } rect->corner_radius = corner_radius; } else if (!xmlStrcmp(node->name, (const xmlChar *)"text")) { GraphicElementText *text = g_new(GraphicElementText, 1); el = (GraphicElement *)text; text->type = GE_TEXT; text->object = NULL; str = xmlGetProp(node, (const xmlChar *)"x"); if (str) { text->anchor.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else text->anchor.x = 0; str = xmlGetProp(node, (const xmlChar *)"y"); if (str) { text->anchor.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else text->anchor.y = 0; str = xmlGetProp(node, (const xmlChar *)"font-size"); if (str) { text->s.font_height = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } else text->s.font_height = 0.8; str = xmlNodeGetContent(node); if (str) { text->string = g_strdup((gchar *) str); xmlFree(str); } else text->string = g_strdup(""); } else if (!xmlStrcmp(node->name, (const xmlChar *)"circle")) { GraphicElementEllipse *ellipse = g_new0(GraphicElementEllipse, 1); el = (GraphicElement *)ellipse; ellipse->type = GE_ELLIPSE; str = xmlGetProp(node, (const xmlChar *)"cx"); if (str) { ellipse->center.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"cy"); if (str) { ellipse->center.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"r"); if (str) { ellipse->width = ellipse->height = 2 * g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"ellipse")) { GraphicElementEllipse *ellipse = g_new0(GraphicElementEllipse, 1); el = (GraphicElement *)ellipse; ellipse->type = GE_ELLIPSE; str = xmlGetProp(node, (const xmlChar *)"cx"); if (str) { ellipse->center.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"cy"); if (str) { ellipse->center.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"rx"); if (str) { ellipse->width = 2 * g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"ry"); if (str) { ellipse->height = 2 * g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"path")) { str = xmlGetProp(node, (const xmlChar *)"d"); if (str) { parse_path(info, (char *) str, &s, filename); xmlFree(str); } } else if (!xmlStrcmp(node->name, (const xmlChar *)"image")) { GraphicElementImage *image = g_new0(GraphicElementImage, 1); el = (GraphicElement *)image; image->type = GE_IMAGE; str = xmlGetProp(node, (const xmlChar *)"x"); if (str) { image->topleft.x = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"y"); if (str) { image->topleft.y = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"width"); if (str) { image->width = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"height"); if (str) { image->height = g_ascii_strtod((gchar *) str, NULL); xmlFree(str); } str = xmlGetProp(node, (const xmlChar *)"xlink:href"); if (!str) /* this doesn't look right but it appears to work w/o namespace --hb */ str = xmlGetProp(node, (const xmlChar *)"href"); if (str) { gchar *imgfn = NULL; const char* data = strchr((char *)str, ','); /* first check for inlined data */ if (data) { GdkPixbuf *pixbuf = pixbuf_decode_base64 (data+1); if (pixbuf) { image->image = dia_image_new_from_pixbuf (pixbuf); g_object_unref (pixbuf); } } else { imgfn = g_filename_from_uri((gchar *) str, NULL, NULL); if (!imgfn) /* despite it's name it ensures an absolute filename */ imgfn = custom_get_relative_filename(filename, (gchar *) str); image->image = dia_image_load(imgfn); } if (!image->image) g_debug("failed to load image file %s", imgfn ? imgfn : "(data:)"); g_free(imgfn); xmlFree(str); } /* w/o the image we would crash later */ if (!image->image) image->image = dia_image_get_broken(); } else if (!xmlStrcmp(node->name, (const xmlChar *)"g")) { if (!is_subshape(node)) { /* add elements from the group element */ parse_svg_node(info, node, svg_ns, &s, filename); } else { /* add elements from the group element, but make it a subshape */ GraphicElementSubShape *subshape = g_new0(GraphicElementSubShape, 1); ShapeInfo* tmpinfo = g_new0(ShapeInfo, 1); xmlChar *v_anchor_attr = xmlGetProp(node, (const xmlChar*)"v_anchor"); xmlChar *h_anchor_attr = xmlGetProp(node, (const xmlChar*)"h_anchor"); parse_svg_node(tmpinfo, node, svg_ns, &s, filename); tmpinfo->shape_bounds.top = DBL_MAX; tmpinfo->shape_bounds.left = DBL_MAX; tmpinfo->shape_bounds.bottom = -DBL_MAX; tmpinfo->shape_bounds.right = -DBL_MAX; update_bounds( tmpinfo ); update_bounds( info ); subshape->half_width = (tmpinfo->shape_bounds.right-tmpinfo->shape_bounds.left) / 2.0; subshape->half_height = (tmpinfo->shape_bounds.bottom-tmpinfo->shape_bounds.top) / 2.0; subshape->center.x = tmpinfo->shape_bounds.left + subshape->half_width; subshape->center.y = tmpinfo->shape_bounds.top + subshape->half_height; subshape->type = GE_SUBSHAPE; subshape->display_list = tmpinfo->display_list; subshape->v_anchor_method = OFFSET_METHOD_FIXED; subshape->h_anchor_method = OFFSET_METHOD_FIXED; subshape->default_scale = 0.0; if (!v_anchor_attr || !strcmp((const char*)v_anchor_attr,"fixed.top")) subshape->v_anchor_method = OFFSET_METHOD_FIXED; else if (v_anchor_attr && !strcmp((const char*)v_anchor_attr,"fixed.bottom")) subshape->v_anchor_method = -OFFSET_METHOD_FIXED; else if (v_anchor_attr && !strcmp((const char*)v_anchor_attr,"proportional")) subshape->v_anchor_method = OFFSET_METHOD_PROPORTIONAL; else fprintf( stderr, "illegal v_anchor `%s', defaulting to fixed.top\n", v_anchor_attr ); if (!h_anchor_attr || !strcmp((const char*)h_anchor_attr,"fixed.left")) subshape->h_anchor_method = OFFSET_METHOD_FIXED; else if (h_anchor_attr && !strcmp((const char*)h_anchor_attr,"fixed.right")) subshape->h_anchor_method = -OFFSET_METHOD_FIXED; else if (h_anchor_attr && !strcmp((const char*)h_anchor_attr,"proportional")) subshape->h_anchor_method = OFFSET_METHOD_PROPORTIONAL; else fprintf( stderr, "illegal h_anchor `%s', defaulting to fixed.left\n", h_anchor_attr ); info->subshapes = g_list_append(info->subshapes, subshape); /* gfree( tmpinfo );*/ xmlFree(v_anchor_attr); xmlFree(h_anchor_attr); el = (GraphicElement *)subshape; } } if (el) { el->any.s = s; if (el->any.s.font) el->any.s.font = g_object_ref(s.font); info->display_list = g_list_append(info->display_list, el); } if (s.font) dia_font_unref (s.font); } }
/* Take a string representing one line from a hex dump and converts the * text to binary data. We check the printed offset with the offset * we are passed to validate the record. We place the bytes in the buffer * at the specified offset. * * Returns length parsed if a good hex dump, 0 if bad. */ static guint parse_single_hex_dump_line(char* rec, guint8 *buf, int byte_offset) { int pos, i; int value; /* Check that the record is as least as long as the check offset */ for(i = 0; i < TYPE_CHECK_POS; i++) { if(rec[i] == '\0') { return 0; } } /* determine the format and thus the counter offset and hex dump length */ if(rec[TYPE_CHECK_POS] == TYPE_CHECK_BOTH) { pos = COUNT_POS_BOTH; } else { pos = COUNT_POS_HEX; } /* Check that the record is as least as long as the start position */ while(i < pos) { if(rec[i] == '\0') { return 0; } i++; } /* Get the byte_offset directly from the record */ value = 0; for(i = 0; i < COUNT_SIZE; i++) { if(!g_ascii_isspace(rec[pos])) { if(g_ascii_isdigit(rec[pos])) { value *= 10; value += rec[pos] - '0'; } else { return 0; } } pos++; } if (value != byte_offset) { return 0; } /* find the start of the hex dump */ while(rec[pos] != HEX_DUMP_START) { if(rec[pos] == '\0') { return 0; } pos++; } pos++; return parse_hex_dump(&rec[pos], buf, HEX_DUMP_SPR, HEX_DUMP_END); }
int main(int argc, char *argv[], char *env[]) { int i; ENTER; setlocale(LC_CTYPE, ""); gtk_init(&argc, &argv); XSetLocaleModifiers(""); XSetErrorHandler((XErrorHandler) handle_error); // resolve xatoms resolve_atoms(); p = g_new0(panel, 1); memset(p, 0, sizeof(panel)); p->allign = ALLIGN_CENTER; p->edge = EDGE_BOTTOM; p->widthtype = WIDTH_PERCENT; p->width = PANEL_WIDTH_DEFAULT; p->heighttype = HEIGHT_PIXEL; p->height = PANEL_HEIGHT_DEFAULT; p->setdocktype = 1; p->setstrut = 0; p->transparent = 0; p->icon_spacing = 0; p->alpha = 127; p->tintcolor = 0xFFFFFFFF; p->xtopbg = None; p->monitor = 0; p->margin = 0; p->on_primary = 0; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { usage(); exit(0); } else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) { printf("trayer %s\n", version); exit(0); } else if (!strcmp(argv[i], "-l")) { p->lower = 1; } else if (!strcmp(argv[i], "--edge")) { i++; if (i == argc) { ERR( "trayer: missing edge parameter value\n"); usage(); exit(1); } else { p->edge = str2num(edge_pair, argv[i], EDGE_NONE); } } else if (!strcmp(argv[i], "--align")) { i++; if (i == argc) { ERR( "trayer: missing align parameter value\n"); usage(); exit(1); } else { p->allign = str2num(allign_pair, argv[i], ALLIGN_NONE); } } else if (!strcmp(argv[i], "--margin")) { i++; if (i == argc) { ERR( "trayer: missing margin parameter value\n"); usage(); exit(1); } else { p->margin = atoi(argv[i]); } } else if (!strcmp(argv[i], "--widthtype")) { i++; if (i == argc) { ERR( "trayer: missing widthtype parameter value\n"); usage(); exit(1); } else { p->widthtype = str2num(width_pair, argv[i], WIDTH_NONE); } } else if (!strcmp(argv[i], "--width")) { i++; if (i == argc) { ERR( "trayer: missing width parameter value\n"); usage(); exit(1); } else { p->width = atoi(argv[i]); } } else if (!strcmp(argv[i], "--heighttype")) { i++; if (i == argc) { ERR( "trayer: missing heighttype parameter value\n"); usage(); exit(1); } else { p->heighttype = str2num(height_pair, argv[i], HEIGHT_NONE); } } else if (!strcmp(argv[i], "--height")) { i++; if (i == argc) { ERR( "trayer: missing height parameter value\n"); usage(); exit(1); } else { p->height = atoi(argv[i]); } } else if (!strcmp(argv[i], "--SetDockType")) { i++; if (i == argc) { ERR( "trayer: missing SetDockType parameter value\n"); usage(); exit(1); } else { p->setdocktype = str2num(bool_pair, argv[i], 0); } } else if (!strcmp(argv[i], "--SetPartialStrut")) { i++; if (i == argc) { ERR( "trayer: missing SetPartialStrut parameter value\n"); usage(); exit(1); } else { p->setstrut = str2num(bool_pair, argv[i], 0); } } else if (!strcmp(argv[i], "--transparent")) { i++; if (i == argc) { ERR( "trayer: missing transparent parameter value\n"); usage(); exit(1); } else { p->transparent = str2num(bool_pair, argv[i], 1); } } else if (!strcmp(argv[i], "--alpha")) { i++; if (i == argc) { ERR( "trayer: missing alpha parameter value\n"); usage(); exit(1); } else { p->alpha = atoi(argv[i]); } } else if (!strcmp(argv[i], "--tint")) { i++; if (i == argc) { ERR( "trayer: missing tint parameter value\n"); usage(); exit(1); } else { p->tintcolor = strtoul(argv[i], NULL, 0); } } else if (!strcmp(argv[i], "--distance")) { i++; if (i == argc) { ERR( "trayer: missing distance parameter value\n"); usage(); exit(1); } else { distance = atoi(argv[i]); } } else if (!strcmp(argv[i], "--distancefrom")) { i++; if (i == argc) { ERR( "trayer: missing distancefrom parameter value\n"); usage(); exit(1); } else { distancefrom = str2num(distancefrom_pair, argv[i], DISTANCEFROM_NONE); } } else if (!strcmp(argv[i], "--expand")) { i++; if (i == argc) { ERR( "trayer: missing expand parameter value\n"); usage(); exit(1); } else { expand = str2num(bool_pair, argv[i], 1); } } else if (!strcmp(argv[i], "--padding")) { i++; if (i == argc) { ERR( "trayer: missing padding parameter value\n"); usage(); exit(1); } else { padding = atoi(argv[i]); } } else if (!strcmp(argv[i], "--monitor")) { i++; if (i == argc) { ERR( "trayer: missing monitor parameter value\n"); usage(); exit(1); } else { if (g_ascii_isdigit(argv[i][0])) { p->monitor = atoi(argv[i]); } else if (!strcmp(argv[i], "primary")) { p->on_primary = 1; } } } else if (!strcmp(argv[i], "--iconspacing")) { i++; if (i == argc) { ERR( "trayer: missing icon padding parameter value\n"); usage(); exit(1); } else { p->icon_spacing = atoi(argv[i]); } } else { printf("trayer: unknown option - %s\n", argv[i]); usage(); exit(1); } } g_return_val_if_fail (p != NULL, 1); if (!panel_start(p)) { ERR( "trayer: can't start panel\n"); exit(1); } gtk_main(); panel_stop(p); g_free(p); exit(0); }
/* Insere des retours chariots dans une chaine de caracteres de facon a la faire tenir dans un rectangle donne. */ void cd_rssreader_cut_line (gchar *cLine, PangoLayout *pLayout, int iMaxWidth) { cd_debug ("%s (%s)", __func__, cLine); // on convertit les caracteres internet. gchar *str=cLine, *amp; do { amp = strchr (str, '&'); if (!amp) break; if (amp[1] == '#' && g_ascii_isdigit (amp[2]) && g_ascii_isdigit (amp[3]) && g_ascii_isdigit (amp[4]) && amp[5] == ';') // ' { int i = atoi (amp+2) - 32; cd_debug ("%d", i); if (i >= 0 && i < 256 - 32) { cd_debug ("%d -> %s", i, cExtendedAscii[i]); strcpy (amp, cExtendedAscii[i]); strcpy (amp+strlen (cExtendedAscii[i]), amp+6); } } str = amp + 1; } while (1); // on insere des retours chariot pour tenir dans la largeur donnee. PangoRectangle ink, log; gchar *sp, *last_sp=NULL; double w; int iNbLines = 0; str = cLine; while (*str == ' ') // on saute les espaces en debut de ligne. str ++; sp = str; do { sp = strchr (sp+1, ' '); // on trouve l'espace suivant. if (!sp) // plus d'espace, on quitte. break ; *sp = '\0'; // on coupe a cet espace. pango_layout_set_text (pLayout, str, -1); // on regarde la taille de str a sp. pango_layout_get_pixel_extents (pLayout, &ink, &log); //g_print ("%s => w:%d/%d, x:%d/%d\n", str, log.width, ink.width, log.x, ink.x); w = log.width + log.x; if (w > iMaxWidth) // on deborde. { if (last_sp != NULL) // on coupe au dernier espace connu. { *sp = ' '; // on remet l'espace. *last_sp = '\n'; // on coupe. iNbLines ++; str = last_sp + 1; // on place le debut de ligne apres la coupure. } else // aucun espace, c'est un mot entier. { *sp = '\n'; // on coupe apres le mot. iNbLines ++; str = sp + 1; // on place le debut de ligne apres la coupure. } while (*str == ' ') // on saute les espaces en debut de ligne. str ++; sp = str; last_sp = NULL; } else // ca rentre. { *sp = ' '; // on remet l'espace. last_sp = sp; // on memorise la derniere cesure qui fait tenir la ligne en largeur. sp ++; // on se place apres. while (*sp == ' ') // on saute tous les espaces. sp ++; } } while (sp); // dernier mot. pango_layout_set_text (pLayout, str, -1); // on regarde la taille de str a sp. pango_layout_get_pixel_extents (pLayout, &ink, &log); w = log.width + log.x; if (w > iMaxWidth) // on deborde. { if (last_sp != NULL) // on coupe au dernier espace connu. *last_sp = '\n'; } }
static gboolean google_goto_tool_parse_file_for_latlon(VikGotoTool *self, gchar *file_name, struct LatLon *ll) { gchar *text, *pat; GMappedFile *mf; gsize len; gboolean found = TRUE; gchar lat_buf[32], lon_buf[32]; gchar *s; lat_buf[0] = lon_buf[0] = '\0'; if ((mf = g_mapped_file_new(file_name, FALSE, NULL)) == NULL) { g_critical(_("couldn't map temp file")); exit(1); } len = g_mapped_file_get_length(mf); text = g_mapped_file_get_contents(mf); if (g_strstr_len(text, len, GOOGLE_GOTO_NOT_FOUND) != NULL) { found = FALSE; goto done; } if ((pat = g_strstr_len(text, len, GOOGLE_GOTO_PATTERN_1)) == NULL) { found = FALSE; goto done; } pat += strlen(GOOGLE_GOTO_PATTERN_1); s = lat_buf; if (*pat == '-') *s++ = *pat++; while ((s < (lat_buf + sizeof(lat_buf))) && (pat < (text + len)) && (g_ascii_isdigit(*pat) || (*pat == '.'))) *s++ = *pat++; *s = '\0'; if ((pat >= (text + len)) || (lat_buf[0] == '\0')) { found = FALSE; goto done; } if (strncmp(pat, GOOGLE_GOTO_PATTERN_2, strlen(GOOGLE_GOTO_PATTERN_2))) { found = FALSE; goto done; } pat += strlen(GOOGLE_GOTO_PATTERN_2); s = lon_buf; if (*pat == '-') *s++ = *pat++; while ((s < (lon_buf + sizeof(lon_buf))) && (pat < (text + len)) && (g_ascii_isdigit(*pat) || (*pat == '.'))) *s++ = *pat++; *s = '\0'; if ((pat >= (text + len)) || (lon_buf[0] == '\0')) { found = FALSE; goto done; } ll->lat = g_ascii_strtod(lat_buf, NULL); ll->lon = g_ascii_strtod(lon_buf, NULL); done: g_mapped_file_free(mf); return (found); }
static int str_ascii_isdigit (const char *text) { return g_ascii_isdigit ((gchar) text[0]); }
static FileMatchType file_check_single_magic (const gchar *offset, const gchar *type, const gchar *value, const guchar *file_head, gint headsize, FILE *ifp) { FileMatchType found = FILE_MATCH_NONE; glong offs; gulong num_testval; gulong num_operatorval; gint numbytes, k; const gchar *num_operator_ptr; gchar num_operator; /* Check offset */ if (sscanf (offset, "%ld", &offs) != 1) return FILE_MATCH_NONE; /* Check type of test */ num_operator_ptr = NULL; num_operator = '\0'; if (g_str_has_prefix (type, "byte")) { numbytes = 1; num_operator_ptr = type + strlen ("byte"); } else if (g_str_has_prefix (type, "short")) { numbytes = 2; num_operator_ptr = type + strlen ("short"); } else if (g_str_has_prefix (type, "long")) { numbytes = 4; num_operator_ptr = type + strlen ("long"); } else if (g_str_has_prefix (type, "size")) { numbytes = 5; } else if (strcmp (type, "string") == 0) { numbytes = 0; } else { return FILE_MATCH_NONE; } /* Check numerical operator value if present */ if (num_operator_ptr && (*num_operator_ptr == '&')) { if (g_ascii_isdigit (num_operator_ptr[1])) { if (num_operator_ptr[1] != '0') /* decimal */ sscanf (num_operator_ptr+1, "%lu", &num_operatorval); else if (num_operator_ptr[2] == 'x') /* hexadecimal */ sscanf (num_operator_ptr+3, "%lx", &num_operatorval); else /* octal */ sscanf (num_operator_ptr+2, "%lo", &num_operatorval); num_operator = *num_operator_ptr; } } if (numbytes > 0) /* Numerical test ? */ { gchar num_test = '='; gulong fileval = 0; /* Check test value */ if ((value[0] == '>') || (value[0] == '<')) { num_test = value[0]; value++; } errno = 0; num_testval = strtol (value, NULL, 0); if (errno != 0) return FILE_MATCH_NONE; if (numbytes == 5) /* Check for file size ? */ { struct stat buf; if (fstat (fileno (ifp), &buf) < 0) return FILE_MATCH_NONE; fileval = buf.st_size; } else if (offs >= 0 && (offs + numbytes <= headsize)) /* We have it in memory ? */ { for (k = 0; k < numbytes; k++) fileval = (fileval << 8) | (glong) file_head[offs + k]; } else /* Read it from file */ { gint c = 0; if (fseek (ifp, offs, (offs >= 0) ? SEEK_SET : SEEK_END) < 0) return FILE_MATCH_NONE; for (k = 0; k < numbytes; k++) fileval = (fileval << 8) | (c = getc (ifp)); if (c == EOF) return FILE_MATCH_NONE; } if (num_operator == '&') fileval &= num_operatorval; if (num_test == '<') found = (fileval < num_testval); else if (num_test == '>') found = (fileval > num_testval); else found = (fileval == num_testval); if (found && (numbytes == 5)) found = FILE_MATCH_SIZE; } else if (numbytes == 0) /* String test */ { gchar mem_testval[256]; file_convert_string (value, mem_testval, sizeof (mem_testval), &numbytes); if (numbytes <= 0) return FILE_MATCH_NONE; if (offs >= 0 && (offs + numbytes <= headsize)) /* We have it in memory ? */ { found = (memcmp (mem_testval, file_head + offs, numbytes) == 0); } else /* Read it from file */ { if (fseek (ifp, offs, (offs >= 0) ? SEEK_SET : SEEK_END) < 0) return FILE_MATCH_NONE; found = FILE_MATCH_MAGIC; for (k = 0; found && (k < numbytes); k++) { gint c = getc (ifp); found = (c != EOF) && (c == (gint) mem_testval[k]); } } } return found; }
static int mc_search_regex__process_replace_str (const GString * replace_str, const gsize current_pos, gsize * skip_len, replace_transform_type_t * replace_flags) { int ret = -1; char *tmp_str; const char *curr_str = &(replace_str->str[current_pos]); if (current_pos > replace_str->len) return REPLACE_PREPARE_T_NOTHING_SPECIAL; *skip_len = 0; if ((*curr_str == '$') && (*(curr_str + 1) == '{') && ((*(curr_str + 2) & (char) 0xf0) == 0x30) && (replace_str->len > current_pos + 2)) { if (strutils_is_char_escaped (replace_str->str, curr_str)) { *skip_len = 1; return REPLACE_PREPARE_T_NOTHING_SPECIAL; } for (*skip_len = 0; current_pos + *skip_len + 2 < replace_str->len && (*(curr_str + 2 + *skip_len) & (char) 0xf0) == 0x30; (*skip_len)++); if (*(curr_str + 2 + *skip_len) != '}') return REPLACE_PREPARE_T_NOTHING_SPECIAL; tmp_str = g_strndup (curr_str + 2, *skip_len); if (tmp_str == NULL) return REPLACE_PREPARE_T_NOTHING_SPECIAL; ret = atoi (tmp_str); g_free (tmp_str); *skip_len += 3; /* ${} */ return ret; /* capture buffer index >= 0 */ } if ((*curr_str == '\\') && (replace_str->len > current_pos + 1)) { if (strutils_is_char_escaped (replace_str->str, curr_str)) { *skip_len = 1; return REPLACE_PREPARE_T_NOTHING_SPECIAL; } if (g_ascii_isdigit (*(curr_str + 1))) { ret = g_ascii_digit_value (*(curr_str + 1)); /* capture buffer index >= 0 */ *skip_len = 2; /* \\ and one digit */ return ret; } if (!mc_search_regex__replace_handle_esc_seq (replace_str, current_pos, skip_len, &ret)) return ret; ret = REPLACE_PREPARE_T_REPLACE_FLAG; *skip_len += 2; switch (*(curr_str + 1)) { case 'U': *replace_flags |= REPLACE_T_UPP_TRANSFORM; *replace_flags &= ~REPLACE_T_LOW_TRANSFORM; break; case 'u': *replace_flags |= REPLACE_T_UPP_TRANSFORM_CHAR; break; case 'L': *replace_flags |= REPLACE_T_LOW_TRANSFORM; *replace_flags &= ~REPLACE_T_UPP_TRANSFORM; break; case 'l': *replace_flags |= REPLACE_T_LOW_TRANSFORM_CHAR; break; case 'E': *replace_flags = REPLACE_T_NO_TRANSFORM; break; default: ret = REPLACE_PREPARE_T_NOTHING_SPECIAL; break; } } return ret; }
/** * Automatic attempt to find out where you are using: * 1. http://www.hostip.info ++ * 2. if not specific enough fallback to using the default goto tool with a country name * ++ Using returned JSON information * c.f. with googlesearch.c - similar implementation is used here * * returns: * 0 if failed to locate anything * 1 if exact latitude/longitude found * 2 if position only as precise as a city * 3 if position only as precise as a country * @name: Contains the name of place found. Free this string after use. */ gint a_vik_goto_where_am_i ( VikViewport *vvp, struct LatLon *ll, gchar **name ) { gint result = 0; *name = NULL; gchar *tmpname = a_download_uri_to_tmp_file ( "http://api.hostip.info/get_json.php?position=true", NULL ); //gchar *tmpname = g_strdup ("../test/hostip2.json"); if (!tmpname) { return result; } ll->lat = 0.0; ll->lon = 0.0; gchar *pat; GMappedFile *mf; gchar *ss; gint fragment_len; gchar lat_buf[32], lon_buf[32]; lat_buf[0] = lon_buf[0] = '\0'; gchar *country = NULL; gchar *city = NULL; if ((mf = g_mapped_file_new(tmpname, FALSE, NULL)) == NULL) { g_critical(_("couldn't map temp file")); goto tidy; } gsize len = g_mapped_file_get_length(mf); gchar *text = g_mapped_file_get_contents(mf); if ((pat = g_strstr_len(text, len, HOSTIP_COUNTRY_PATTERN))) { pat += strlen(HOSTIP_COUNTRY_PATTERN); fragment_len = 0; ss = pat; while (*pat != '"') { fragment_len++; pat++; } country = g_strndup(ss, fragment_len); } if ((pat = g_strstr_len(text, len, HOSTIP_CITY_PATTERN))) { pat += strlen(HOSTIP_CITY_PATTERN); fragment_len = 0; ss = pat; while (*pat != '"') { fragment_len++; pat++; } city = g_strndup(ss, fragment_len); } if ((pat = g_strstr_len(text, len, HOSTIP_LATITUDE_PATTERN))) { pat += strlen(HOSTIP_LATITUDE_PATTERN); ss = lat_buf; if (*pat == '-') *ss++ = *pat++; while ((ss < (lat_buf + sizeof(lat_buf))) && (pat < (text + len)) && (g_ascii_isdigit(*pat) || (*pat == '.'))) *ss++ = *pat++; *ss = '\0'; ll->lat = g_ascii_strtod(lat_buf, NULL); } if ((pat = g_strstr_len(text, len, HOSTIP_LONGITUDE_PATTERN))) { pat += strlen(HOSTIP_LONGITUDE_PATTERN); ss = lon_buf; if (*pat == '-') *ss++ = *pat++; while ((ss < (lon_buf + sizeof(lon_buf))) && (pat < (text + len)) && (g_ascii_isdigit(*pat) || (*pat == '.'))) *ss++ = *pat++; *ss = '\0'; ll->lon = g_ascii_strtod(lon_buf, NULL); } if ( ll->lat != 0.0 && ll->lon != 0.0 ) { if ( ll->lat > -90.0 && ll->lat < 90.0 && ll->lon > -180.0 && ll->lon < 180.0 ) { // Found a 'sensible' & 'precise' location result = 1; *name = g_strdup ( _("Locality") ); //Albeit maybe not known by an actual name! } } else { // Hopefully city name is unique enough to lookup position on // Maybe for American places where hostip appends the State code on the end // But if the country code is not appended if could easily get confused // e.g. 'Portsmouth' could be at least // Portsmouth, Hampshire, UK or // Portsmouth, Viginia, USA. // Try city name lookup if ( city ) { g_debug ( "%s: found city %s", __FUNCTION__, city ); if ( strcmp ( city, "(Unknown city)" ) != 0 ) { VikCoord new_center; if ( vik_goto_place ( NULL, vvp, city, &new_center ) ) { // Got something vik_coord_to_latlon ( &new_center, ll ); result = 2; *name = city; goto tidy; } } } // Try country name lookup if ( country ) { g_debug ( "%s: found country %s", __FUNCTION__, country ); if ( strcmp ( country, "(Unknown Country)" ) != 0 ) { VikCoord new_center; if ( vik_goto_place ( NULL, vvp, country, &new_center ) ) { // Finally got something vik_coord_to_latlon ( &new_center, ll ); result = 3; *name = country; goto tidy; } } } } tidy: g_mapped_file_unref ( mf ); g_remove ( tmpname ); g_free ( tmpname ); return result; }
/* * Parse the address and port information in a PORT command or in the * response to a PASV command. Return TRUE if we found an address and * port, and supply the address and port; return FALSE if we didn't find * them. * * We ignore the IP address in the reply, and use the address from which * the request came. * * XXX - are there cases where they differ? What if the FTP server is * behind a NAT box, so that the address it puts into the reply isn't * the address at which you should contact it? Do all NAT boxes detect * FTP PASV replies and rewrite the address? (I suspect not.) * * RFC 959 doesn't say much about the syntax of the 227 reply. * * A proposal from Dan Bernstein at * * http://cr.yp.to/ftp/retr.html * * "recommend[s] that clients use the following strategy to parse the * response line: look for the first digit after the initial space; look * for the fourth comma after that digit; read two (possibly negative) * integers, separated by a comma; the TCP port number is p1*256+p2, where * p1 is the first integer modulo 256 and p2 is the second integer modulo * 256." * * wget 1.5.3 looks for a digit, although it doesn't handle negative * integers. * * The FTP code in the source of the cURL library, at * * http://curl.haxx.se/lxr/source/lib/ftp.c * * says that cURL "now scans for a sequence of six comma-separated numbers * and will take them as IP+port indicators"; it loops, doing "sscanf"s * looking for six numbers separated by commas, stepping the start pointer * in the scanf one character at a time - i.e., it tries rather exhaustively. * * An optimization would be to scan for a digit, and start there, and if * the scanf doesn't find six values, scan for the next digit and try * again; this will probably succeed on the first try. * * The cURL code also says that "found reply-strings include": * * "227 Entering Passive Mode (127,0,0,1,4,51)" * "227 Data transfer will passively listen to 127,0,0,1,4,51" * "227 Entering passive mode. 127,0,0,1,4,51" * * so it appears that you can't assume there are parentheses around * the address and port number. */ static gboolean parse_port_pasv(const guchar *line, int linelen, guint32 *ftp_ip, guint16 *ftp_port, guint32 *pasv_offset, guint *ftp_ip_len, guint *ftp_port_len) { char *args; char *p; guchar c; int i; int ip_address[4], port[2]; gboolean ret = FALSE; /* * Copy the rest of the line into a null-terminated buffer. */ args = wmem_strndup(wmem_packet_scope(), line, linelen); p = args; for (;;) { /* * Look for a digit. */ while ((c = *p) != '\0' && !g_ascii_isdigit(c)) p++; if (*p == '\0') { /* * We ran out of text without finding anything. */ break; } /* * See if we have six numbers. */ i = sscanf(p, "%d,%d,%d,%d,%d,%d", &ip_address[0], &ip_address[1], &ip_address[2], &ip_address[3], &port[0], &port[1]); if (i == 6) { /* * We have a winner! */ *ftp_port = ((port[0] & 0xFF)<<8) | (port[1] & 0xFF); *ftp_ip = g_htonl((ip_address[0] << 24) | (ip_address[1] <<16) | (ip_address[2] <<8) | ip_address[3]); *pasv_offset = (guint32)(p - args); *ftp_port_len = (port[0] < 10 ? 1 : (port[0] < 100 ? 2 : 3 )) + 1 + (port[1] < 10 ? 1 : (port[1] < 100 ? 2 : 3 )); *ftp_ip_len = (ip_address[0] < 10 ? 1 : (ip_address[0] < 100 ? 2 : 3)) + 1 + (ip_address[1] < 10 ? 1 : (ip_address[1] < 100 ? 2 : 3)) + 1 + (ip_address[2] < 10 ? 1 : (ip_address[2] < 100 ? 2 : 3)) + 1 + (ip_address[3] < 10 ? 1 : (ip_address[3] < 100 ? 2 : 3)); ret = TRUE; break; } /* * Well, that didn't work. Skip the first number we found, * and keep trying. */ while ((c = *p) != '\0' && g_ascii_isdigit(c)) p++; } return ret; }
static void _lib_geotagging_calculate_offset_callback(GtkWidget *widget, dt_lib_module_t *self) { dt_lib_geotagging_t *d = (dt_lib_geotagging_t *)self->data; const gchar *gps_time = gtk_entry_get_text(GTK_ENTRY(d->floating_window_entry)); if(gps_time) { gchar **tokens = g_strsplit(gps_time, ":", 0); if(tokens[0] != '\0' && tokens[1] != '\0' && tokens[2] != '\0') { if(g_ascii_isdigit(tokens[0][0]) && g_ascii_isdigit(tokens[0][1]) && tokens[0][2] == '\0' && g_ascii_isdigit(tokens[1][0]) && g_ascii_isdigit(tokens[1][1]) && tokens[1][2] == '\0' && g_ascii_isdigit(tokens[2][0]) && g_ascii_isdigit(tokens[2][1]) && tokens[2][2] == '\0') { int h, m, s; h = (tokens[0][0] - '0') * 10 + tokens[0][1] - '0'; m = (tokens[1][0] - '0') * 10 + tokens[1][1] - '0'; s = (tokens[2][0] - '0') * 10 + tokens[2][1] - '0'; if(h < 24 && m < 60 && s < 60) { // finally a valid time // get imgid int32_t imgid = -1; sqlite3_stmt *stmt; DT_DEBUG_SQLITE3_PREPARE_V2(dt_database_get(darktable.db), "select imgid from selected_images order by imgid asc limit 1", -1, &stmt, NULL); if(sqlite3_step(stmt) == SQLITE_ROW) imgid = sqlite3_column_int(stmt, 0); else // no selection is used, use mouse over id imgid = dt_control_get_mouse_over_id(); sqlite3_finalize(stmt); if(imgid > 0) { const dt_image_t *cimg = dt_image_cache_get(darktable.image_cache, imgid, 'r'); // get the exif_datetime_taken and parse it gint year; gint month; gint day; gint hour; gint minute; gint second; if(sscanf(cimg->exif_datetime_taken, "%d:%d:%d %d:%d:%d", (int *)&year, (int *)&month, (int *)&day, (int *)&hour, (int *)&minute, (int *)&second) == 6) { // calculate the offset long int exif_seconds = hour * 60 * 60 + minute * 60 + second; long int gps_seconds = h * 60 * 60 + m * 60 + s; long int offset = gps_seconds - exif_seconds; // transform the offset back into a string gchar sign = (offset < 0) ? '-' : '+'; offset = labs(offset); gint offset_h = offset / (60 * 60); offset -= offset_h * 60 * 60; gint offset_m = offset / 60; offset -= offset_m * 60; gchar *offset_str = g_strdup_printf("%c%02d:%02d:%02ld", sign, offset_h, offset_m, offset); // write the offset into d->offset_entry gtk_entry_set_text(GTK_ENTRY(d->offset_entry), offset_str); g_free(offset_str); } dt_image_cache_read_release(darktable.image_cache, cimg); } } } } g_strfreev(tokens); } gtk_widget_destroy(d->floating_window); }
/** * soup_headers_parse_request: * @str: the headers (up to, but not including, the trailing blank line) * @len: length of @str * @req_headers: #SoupMessageHeaders to store the header values in * @req_method: (out) (allow-none): if non-%NULL, will be filled in with the * request method * @req_path: (out) (allow-none): if non-%NULL, will be filled in with the * request path * @ver: (out) (allow-none): if non-%NULL, will be filled in with the HTTP * version * * Parses the headers of an HTTP request in @str and stores the * results in @req_method, @req_path, @ver, and @req_headers. * * Beware that @req_headers may be modified even on failure. * * Return value: %SOUP_STATUS_OK if the headers could be parsed, or an * HTTP error to be returned to the client if they could not be. **/ guint soup_headers_parse_request (const char *str, int len, SoupMessageHeaders *req_headers, char **req_method, char **req_path, SoupHTTPVersion *ver) { const char *method, *method_end, *path, *path_end; const char *version, *version_end, *headers; unsigned long major_version, minor_version; char *p; g_return_val_if_fail (str != NULL, SOUP_STATUS_MALFORMED); /* RFC 2616 4.1 "servers SHOULD ignore any empty line(s) * received where a Request-Line is expected." */ while ((*str == '\r' || *str == '\n') && len > 0) { str++; len--; } if (!len) return SOUP_STATUS_BAD_REQUEST; /* RFC 2616 19.3 "[servers] SHOULD accept any amount of SP or * HT characters between [Request-Line] fields" */ method = method_end = str; while (method_end < str + len && *method_end != ' ' && *method_end != '\t') method_end++; if (method_end >= str + len) return SOUP_STATUS_BAD_REQUEST; path = method_end; while (path < str + len && (*path == ' ' || *path == '\t')) path++; if (path >= str + len) return SOUP_STATUS_BAD_REQUEST; path_end = path; while (path_end < str + len && *path_end != ' ' && *path_end != '\t') path_end++; if (path_end >= str + len) return SOUP_STATUS_BAD_REQUEST; version = path_end; while (version < str + len && (*version == ' ' || *version == '\t')) version++; if (version + 8 >= str + len) return SOUP_STATUS_BAD_REQUEST; if (strncmp (version, "HTTP/", 5) != 0 || !g_ascii_isdigit (version[5])) return SOUP_STATUS_BAD_REQUEST; major_version = strtoul (version + 5, &p, 10); if (*p != '.' || !g_ascii_isdigit (p[1])) return SOUP_STATUS_BAD_REQUEST; minor_version = strtoul (p + 1, &p, 10); version_end = p; if (major_version != 1) return SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED; if (minor_version > 1) return SOUP_STATUS_HTTP_VERSION_NOT_SUPPORTED; headers = version_end; while (headers < str + len && (*headers == '\r' || *headers == ' ')) headers++; if (headers >= str + len || *headers != '\n') return SOUP_STATUS_BAD_REQUEST; if (!soup_headers_parse (str, len, req_headers)) return SOUP_STATUS_BAD_REQUEST; if (soup_message_headers_get_expectations (req_headers) & SOUP_EXPECTATION_UNRECOGNIZED) return SOUP_STATUS_EXPECTATION_FAILED; /* RFC 2616 14.10 */ if (minor_version == 0) soup_message_headers_clean_connection_headers (req_headers); if (req_method) *req_method = g_strndup (method, method_end - method); if (req_path) *req_path = g_strndup (path, path_end - path); if (ver) *ver = (minor_version == 0) ? SOUP_HTTP_1_0 : SOUP_HTTP_1_1; return SOUP_STATUS_OK; }
/* try to parse the offset string. returns true if it worked, false otherwise. *if seconds != NULL the offset will be put there in seconds or 0 if it failed. always look at the return *value before using the seconds value! */ static gboolean _lib_geotagging_parse_offset(const char *str, long int *seconds) { const gchar *str_bak = str; long int result = 0; int numbers[3] = { 0, 0, 0 }; int fields = 0; char sign = '+'; if(seconds) *seconds = 0; if(!str) return FALSE; size_t len = strlen(str); // optional sign if(*str == '+' || *str == '-') { sign = *str; str++; len--; } // hh, mm or ss if(len < 2) return FALSE; if(!g_ascii_isdigit(str[0]) || !g_ascii_isdigit(str[1])) return FALSE; else { numbers[fields++] = 10 * (str[0] - '0') + (str[1] - '0'); str += 2; len -= 2; } // : or end if(*str == '\0') goto parse_success; if(*str == ':') { str++; len--; } // mm or ss if(len < 2) return FALSE; if(!g_ascii_isdigit(str[0]) || !g_ascii_isdigit(str[1])) return FALSE; else { numbers[fields++] = 10 * (str[0] - '0') + (str[1] - '0'); str += 2; len -= 2; } // : or end if(*str == '\0') goto parse_success; if(*str == ':') { str++; len--; } // ss if(len < 2) return FALSE; if(!g_ascii_isdigit(str[0]) || !g_ascii_isdigit(str[1])) return FALSE; else { numbers[fields++] = 10 * (str[0] - '0') + (str[1] - '0'); str += 2; // len -= 2; } // end if(*str == '\0') goto parse_success; return FALSE; parse_success: if(seconds) { // assemble the numbers in numbers[] into a single seconds value switch(fields) { case 1: // 0: seconds result = numbers[0]; break; case 2: // 0: minutes, 1: seconds result = 60 * numbers[0] + numbers[1]; break; case 3: // 0: hours, 1: minutes, 2: seconds result = 60 * 60 * numbers[0] + 60 * numbers[1] + numbers[2]; break; default: // shouldn't happen fprintf(stderr, "[geotagging] error: something went terribly wrong while parsing the offset, %d " "fields found in %s\n", fields, str_bak); } if(sign == '-') result *= -1; *seconds = result; } return TRUE; }
static gboolean verify (NMSetting *setting, GSList *all_settings, GError **error) { NMSettingGsmPrivate *priv = NM_SETTING_GSM_GET_PRIVATE (setting); if (priv->number && !priv->number[0]) { g_set_error_literal (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY, _("property is empty")); g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_NUMBER); return FALSE; } if (priv->apn) { guint32 apn_len = strlen (priv->apn); guint32 i; if (apn_len < 1 || apn_len > 64) { g_set_error (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY, _("property value '%s' is empty or too long (>64)"), priv->apn); g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN); return FALSE; } /* APNs roughly follow the same rules as DNS domain names. Allowed * characters are a-z, 0-9, . and -. GSM 03.03 Section 9.1 states: * * The syntax of the APN shall follow the Name Syntax defined in * RFC 2181 [14] and RFC 1035 [15]. The APN consists of one or * more labels. Each label is coded as one octet length field * followed by that number of octets coded as 8 bit ASCII characters. * Following RFC 1035 [15] the labels should consist only of the * alphabetic characters (A-Z and a-z), digits (0-9) and the * dash (-). The case of alphabetic characters is not significant. * * A dot (.) is commonly used to separate parts of the APN, and * apparently the underscore (_) is used as well. RFC 2181 indicates * that no restrictions of any kind are placed on DNS labels, and thus * it would appear that none are placed on APNs either, but many modems * and networks will fail to accept APNs that include odd characters * like space ( ) and such. */ for (i = 0; i < apn_len; i++) { if ( !g_ascii_isalnum (priv->apn[i]) && (priv->apn[i] != '.') && (priv->apn[i] != '_') && (priv->apn[i] != '-')) { g_set_error (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY, _("'%s' contains invalid char(s) (use [A-Za-z._-])"), priv->apn); g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_APN); return FALSE; } } } if (priv->username && !strlen (priv->username)) { g_set_error_literal (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY, _("property is empty")); g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME); return FALSE; } if (priv->password && !strlen (priv->password)) { g_set_error_literal (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY, _("property is empty")); g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_USERNAME); return FALSE; } if (priv->network_id) { guint32 nid_len = strlen (priv->network_id); guint32 i; /* Accept both 5 and 6 digit MCC/MNC codes */ if ((nid_len < 5) || (nid_len > 6)) { g_set_error (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY, _("'%s' length is invalid (should be 5 or 6 digits)"), priv->network_id); g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_NETWORK_ID); return FALSE; } for (i = 0; i < nid_len; i++) { if (!g_ascii_isdigit (priv->network_id[i])) { g_set_error (error, NM_SETTING_GSM_ERROR, NM_SETTING_GSM_ERROR_INVALID_PROPERTY, _("'%s' is not a number"), priv->network_id); g_prefix_error (error, "%s.%s: ", NM_SETTING_GSM_SETTING_NAME, NM_SETTING_GSM_NETWORK_ID); return FALSE; } } } return TRUE; }
static SC_HTMLState sc_html_parse_tag(SC_HTMLParser *parser) { gchar buf[SC_HTMLBUFSIZE]; SC_HTMLTag *tag; sc_html_get_parenthesis(parser, buf, sizeof(buf)); tag = sc_html_get_tag(buf); parser->state = SC_HTML_UNKNOWN; if (!tag) return SC_HTML_UNKNOWN; if (!strcmp(tag->name, "br") || !strcmp(tag->name, "br/")) { parser->space = FALSE; sc_html_append_char(parser, '\n'); parser->state = SC_HTML_BR; } else if (!strcmp(tag->name, "a")) { GList *cur; if (parser->href != NULL) { g_free(parser->href); parser->href = NULL; } for (cur = tag->attr; cur != NULL; cur = cur->next) { if (cur->data && !strcmp(((SC_HTMLAttr *)cur->data)->name, "href")) { g_free(parser->href); parser->href = g_strdup(((SC_HTMLAttr *)cur->data)->value); decode_href(parser); parser->state = SC_HTML_HREF_BEG; break; } } if (parser->href == NULL) parser->href = g_strdup(""); parser->state = SC_HTML_HREF_BEG; } else if (!strcmp(tag->name, "/a")) { parser->state = SC_HTML_HREF; } else if (!strcmp(tag->name, "p")) { parser->space = FALSE; if (!parser->empty_line) { parser->space = FALSE; if (!parser->newline) sc_html_append_char(parser, '\n'); sc_html_append_char(parser, '\n'); } parser->state = SC_HTML_PAR; } else if (!strcmp(tag->name, "pre")) { parser->pre = TRUE; parser->state = SC_HTML_PRE; } else if (!strcmp(tag->name, "/pre")) { parser->pre = FALSE; parser->state = SC_HTML_NORMAL; } else if (!strcmp(tag->name, "hr")) { if (!parser->newline) { parser->space = FALSE; sc_html_append_char(parser, '\n'); } sc_html_append_str(parser, HR_STR, -1); sc_html_append_char(parser, '\n'); parser->state = SC_HTML_HR; } else if (!strcmp(tag->name, "div") || !strcmp(tag->name, "ul") || !strcmp(tag->name, "li") || !strcmp(tag->name, "table") || !strcmp(tag->name, "dd") || !strcmp(tag->name, "tr")) { if (!parser->newline) { parser->space = FALSE; sc_html_append_char(parser, '\n'); } if (!strcmp(tag->name, "li")) { sc_html_append_str(parser, LI_STR, -1); } parser->state = SC_HTML_NORMAL; } else if (tag->name[0] == 'h' && g_ascii_isdigit(tag->name[1])) { if (!parser->newline) { parser->space = FALSE; sc_html_append_char(parser, '\n'); } sc_html_append_char(parser, '\n'); } else if (!strcmp(tag->name, "blockquote")) { parser->state = SC_HTML_NORMAL; parser->indent++; } else if (!strcmp(tag->name, "/blockquote")) { parser->state = SC_HTML_NORMAL; parser->indent--; } else if (!strcmp(tag->name, "/table") || (tag->name[0] == '/' && tag->name[1] == 'h' && g_ascii_isdigit(tag->name[2]))) { if (!parser->empty_line) { parser->space = FALSE; if (!parser->newline) sc_html_append_char(parser, '\n'); sc_html_append_char(parser, '\n'); } parser->state = SC_HTML_NORMAL; } else if (!strcmp(tag->name, "/div") || !strcmp(tag->name, "/ul") || !strcmp(tag->name, "/li")) { if (!parser->newline) { parser->space = FALSE; sc_html_append_char(parser, '\n'); } parser->state = SC_HTML_NORMAL; } sc_html_free_tag(tag); return parser->state; }
/** * utils_handle_output: * @output: buffer containing vpnc output * @server_message: buffer in which to store a message from the VPN server * @server_message_done: flag which is set to %TRUE when a server message is * complete * @prompt_fn: function to call when vpnc (or the server) sends a request for * passwords or more information * @prompt_fn_data: pointer to pass to @prompt_fn * * Parses new vpnc output to extract server messages and detect prompts for * more information. Since vpnc can print variable numbers of bytes at a time, * not necessarily a complete line or block, this function should be called * multiple times on the same buffer. It will return the number of bytes which * it consumed, and that number of bytes should be removed from the start of * @output. If a request for a password or username is parsed, it will call * @prompt_fn with the prompt message. * * Returns: the number of bytes consumed, which should be removed from the * start of @output. **/ gsize utils_handle_output (GString *output, GString *server_message, gboolean *server_message_done, PromptFn prompt_fn, gpointer prompt_fn_data) { guint32 i; g_return_val_if_fail (output != NULL, 0); g_return_val_if_fail (server_message != NULL, 0); g_return_val_if_fail (server_message_done != NULL, 0); g_return_val_if_fail (prompt_fn != NULL, 0); /* vpnc output is loosely formatted, with "blocks of interest" starting with * no leading whitespace, and separated by double newlines, but unfortunately * it doesn't output both newlines at the same time (one newline is printed * at the end of one block and a second at the start of the next block with * variable time in between) and some input prompts don't print newlines at * all. * * S5.4 xauth type check * [2011-06-03 11:11:13] * * Wait for token to change, (server message line #1) * then enter the new tokencode: (server message line #2) * * S5.5 do xauth authentication * [2011-06-03 11:11:13] * Password for VPN [email protected]: (waits for input without newline) * size = 42, blksz = 16, padding = 6 * * So we can't just listen for '\n\n' or we won't react immediately to * input prompts or correctly process service messages. * * Instead we pay attention to any lines that have no leading whitespace * and do not start with "S[1 - 9]". If the line ends with ":" it is an * input prompt. If it doesn't then we cache it and wait for the next line * or newline, in which case it's a server message. */ if (output->len == 0) return 0; /* Find the end of the line or the end of the string; all lines *except* * prompts will be newline terminated, while prompts stop at the end of the * buffer because vpnc is waiting for the input. */ for (i = 0; i < output->len; i++) { if (!output->str[i] || IS_EOL (output->str[i])) break; } /* Decide whether to stop parsing a server message, which is terminated by * a single empty line or some whitespace; it looks like: * * <stuff> * * Wait for token to change, * then enter the new tokencode: * * <more stuff> */ if (server_message->len) { if (g_ascii_isspace (output->str[0]) || IS_EOL (output->str[0])) *server_message_done = TRUE; } if (i < output->len) { /* Lines starting with whitespace are debug output that we don't care * about. */ if (g_ascii_isspace (output->str[0])) return i + 1; } else if (i == output->len) { /* Check for a prompt; it will not begin with whitespace, and will end * with a ':' and no newline, because vpnc will be waiting for the response. */ if (!g_ascii_isspace (output->str[0]) && (i > 2) && (strncmp ((output->str + (i - 2)), ": ", 2) == 0)) { /* Note: if vpnc sent a server message ending with ':' but we * happened to only read up to the ':' but not the EOL, we'll * confuse the server message with an input prompt. vpnc is not * helpful here. */ prompt_fn (output->str, i, prompt_fn_data); return i; } /* No newline and no ending semicolon; probably a partial read so wait * for more output */ return 0; } else g_assert_not_reached (); /* No newline at the end, wait for one */ if (!IS_EOL (output->str[i])) return 0; /* Ignore vpnc version debug output */ if (i >= strlen (VPNC_VERSION_STR) && strncmp (output->str, VPNC_VERSION_STR, strlen (VPNC_VERSION_STR)) == 0) return i + 1; /* Ignore vpnc debug messages like "S1 init_sockaddr" */ if (i > 2 && output->str[0] == 'S' && g_ascii_isdigit (output->str[1])) return i + 1; /* What's left is probably a server message */ if (*server_message_done) { g_string_truncate (server_message, 0); *server_message_done = FALSE; } g_string_append_len (server_message, output->str, i + 1); return i + 1; }
bool sp_svg_transform_read(gchar const *str, Geom::Matrix *transform) { int idx; char keyword[32]; double args[6]; int n_args; size_t key_len; if (str == NULL) return false; Geom::Matrix a(Geom::identity()); idx = 0; while (str[idx]) { /* skip initial whitespace */ while (g_ascii_isspace (str[idx])) idx++; /* parse keyword */ for (key_len = 0; key_len < sizeof (keyword); key_len++) { char c; c = str[idx]; if (g_ascii_isalpha (c) || c == '-') { keyword[key_len] = str[idx++]; } else { break; } } if (key_len >= sizeof (keyword)) return false; keyword[key_len] = '\0'; /* skip whitespace */ while (g_ascii_isspace (str[idx])) idx++; if (str[idx] != '(') return false; idx++; for (n_args = 0; ; n_args++) { char c; char *end_ptr; /* skip whitespace */ while (g_ascii_isspace (str[idx])) idx++; c = str[idx]; if (g_ascii_isdigit (c) || c == '+' || c == '-' || c == '.') { if (n_args == sizeof (args) / sizeof (args[0])) return false; /* Too many args */ args[n_args] = g_ascii_strtod (str + idx, &end_ptr); //printf("took %d chars from '%s' to make %f\n", // end_ptr-(str+idx), // str+idx, // args[n_args]); idx = end_ptr - (char *) str; while (g_ascii_isspace (str[idx])) idx++; /* skip optional comma */ if (str[idx] == ',') idx++; } else if (c == ')') { break; } else { return false; } } idx++; /* ok, have parsed keyword and args, now modify the transform */ if (!strcmp (keyword, "matrix")) { if (n_args != 6) return false; a = (*((Geom::Matrix *) &(args)[0])) * a; } else if (!strcmp (keyword, "translate")) { if (n_args == 1) { args[1] = 0; } else if (n_args != 2) { return false; } a = Geom::Translate(args[0], args[1]) * a; } else if (!strcmp (keyword, "scale")) { if (n_args == 1) { args[1] = args[0]; } else if (n_args != 2) { return false; } a = Geom::Scale(args[0], args[1]) * a; } else if (!strcmp (keyword, "rotate")) { if (n_args != 1 && n_args != 3) { return false; } Geom::Rotate const rot(Geom::deg_to_rad(args[0])); if (n_args == 3) { a = ( Geom::Translate(-args[1], -args[2]) * rot * Geom::Translate(args[1], args[2]) * Geom::Matrix(a) ); } else { a = rot * a; } } else if (!strcmp (keyword, "skewX")) { if (n_args != 1) return false; a = ( Geom::Matrix(1, 0, tan(args[0] * M_PI / 180.0), 1, 0, 0) * a ); } else if (!strcmp (keyword, "skewY")) { if (n_args != 1) return false; a = ( Geom::Matrix(1, tan(args[0] * M_PI / 180.0), 0, 1, 0, 0) * a ); } else { return false; /* unknown keyword */ } /* Skip trailing whitespace */ while (g_ascii_isspace (str[idx])) idx++; } *transform = a; return true; }
static gboolean is_valid_keyname (const gchar *key, GError **error) { gint i; if (key[0] == '\0') { g_set_error_literal (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "empty names are not permitted"); return FALSE; } if (allow_any_name) return TRUE; if (!g_ascii_islower (key[0])) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "invalid name '%s': names must begin " "with a lowercase letter", key); return FALSE; } for (i = 1; key[i]; i++) { if (key[i] != '-' && !g_ascii_islower (key[i]) && !g_ascii_isdigit (key[i])) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "invalid name '%s': invalid character '%c'; " "only lowercase letters, numbers and dash ('-') " "are permitted.", key, key[i]); return FALSE; } if (key[i] == '-' && key[i + 1] == '-') { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "invalid name '%s': two successive dashes ('--') are " "not permitted.", key); return FALSE; } } if (key[i - 1] == '-') { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "invalid name '%s': the last character may not be a " "dash ('-').", key); return FALSE; } if (i > 32) { g_set_error (error, G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, "invalid name '%s': maximum length is 32", key); return FALSE; } return TRUE; }
gint read_cel(gchar *filename, struct model_pak *model) { gchar *line; FILE *fp; int i; gint num_tokens, natom=0; gchar **buff; struct core_pak *core; /* checks */ g_return_val_if_fail(model != NULL, 1); g_return_val_if_fail(filename != NULL, 2); fp = fopen(filename, "rt"); if (!fp) return 3; /* 1st line - cell parameters */ line = file_read_line(fp); if (!line || strlen(line) < 5 || g_ascii_strncasecmp("cell", line, 4) != 0) { printf("The first line should start with the keyword CELL.\n"); return 4; } buff = tokenize(line+4, &num_tokens); g_free(line); if (num_tokens < 6) { g_strfreev(buff); printf("Keyword CELL should be followed by six numbers.\n"); return 5; } for (i=0; i<3; ++i) model->pbc[i] = str_to_float(buff[i]); for (i=3; i<6; ++i) model->pbc[i] = str_to_float(buff[i]) * D2R; g_strfreev(buff); /* next lines - atomic positions */ for (;;) { line = file_read_line(fp); if (!line) /*the end of file*/ { printf("No 'rgnr' symmetry line found.\n"); return 6; } else if (g_ascii_strncasecmp("rgnr", line, 4) == 0) /*no more atomic pos.*/ { break; } else if (g_ascii_strncasecmp("natom", line, 5) == 0)/*number of atoms */ /*some old .cel files have second line with number of atoms eg. "natom 6"*/ { buff = tokenize(line, &num_tokens); if (num_tokens > 1) natom = str_to_float(buff[1]); else printf("Warning: ignoring `natom' line:\n%s\n", line); g_free(line); g_strfreev(buff); } else if (strncmp(" ", line, 4) != 0) /* atomic position */ { buff = tokenize(line, &num_tokens); g_free(line); if (num_tokens < 5) { g_strfreev(buff); continue; } core = new_core(*buff, model); core->atom_label = g_strdup(buff[0]); /* in second column there is either atomic number * or something like "Mg2+" or "K+". The second form is for * " the use of different bonding states of one and the same * element (e.g. Fe2+ and Fe3+ in Fe3O4)" * FIXME how these bonding states can be interpreted in GDIS */ if (g_ascii_isdigit(buff[1][0])) core->atom_code = str_to_float(buff[1]); else { core->atom_code = elem_symbol_test(buff[1]); } for (i=0; i<3; ++i) core->x[i] = str_to_float(buff[2+i]); /* TODO interpret 2 next optional numbers: * so-called multiplied substitution and replacement factor (SOF) * and isotropic Debye-Waller factor * FIXME can they be interpreted by GDIS? -MW */ model->cores = g_slist_prepend(model->cores, core); g_strfreev(buff); } else /* replacement atom */ { /*FIXME replacement atoms are now silently ignored * how can I use this information in GDIS? - MW*/ g_free(line); } } /* last line - symmetry */ buff = tokenize(line, &num_tokens); model->sginfo.spacenum = str_to_float(buff[1]); /* FIXME/TODO how to interpret the second (optional) number? * From fileformat docs: * "sometimes there exists more than one setting of a space-group type. * Thus, a further number must be given if the structure hasn't been described * using a conventional setting (standard setting)." * http://users.omskreg.ru/~kolosov/bam/a_v/v_1/powder/details/strucdat.htm * http://users.omskreg.ru/~kolosov/bam/a_v/v_1/powder/details/setting.htm * Unfortunatelly I'm ignorant about space-groups - MW */ g_free(line); g_strfreev(buff); if (natom>0 && natom != g_slist_length(model->cores)) printf("Warning: expected %i atoms, have %i.", natom, g_slist_length(model->cores)); /* model setup */ model->fractional = TRUE; model->periodic = 3; strcpy(model->filename, filename); g_free(model->basename); model->basename = parse_strip(filename); model_prep(model); return 0; }