Пример #1
0
int handle_run(uint64_t con_id, struct message_request *request,
    char *pluginkey, struct api_error *error)
{
  uint64_t callid;
  array *meta = NULL;
  string function_name;
  char *targetpluginkey;

  struct message_object args_object;

  if (!error || !request)
    return (-1);

  /* check params size */
  if (request->params.size != 3) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. Invalid params size");
    return (-1);
  }

  if (request->params.obj[0].type == OBJECT_TYPE_ARRAY)
    meta = &request->params.obj[0].data.params;
  else {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. meta params has wrong type");
    return (-1);
  }

  if (!meta) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. meta params is NULL");
    return (-1);
  }

  /* meta = [targetpluginkey, nil]*/
  if (meta->size != 2) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. Invalid meta params size");
    return (-1);
  }

  /* extract meta information */
  if (meta->obj[0].type != OBJECT_TYPE_STR) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. meta elements have wrong type");
    return (-1);
  }

  if (!meta->obj[0].data.string.str ||
    meta->obj[0].data.string.length+1 != PLUGINKEY_STRING_SIZE) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. Invalid meta params size");
    return (-1);
  }

  targetpluginkey = meta->obj[0].data.string.str;
  to_upper(targetpluginkey);

  if (meta->obj[1].type != OBJECT_TYPE_NIL) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. meta elements have wrong type");
    return (-1);
  }

  if (request->params.obj[1].type != OBJECT_TYPE_STR) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. function string has wrong type");
    return (-1);
  }

  if (!request->params.obj[1].data.string.str) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching register API request. Invalid meta params size");
    return (-1);
  }

  function_name = request->params.obj[1].data.string;

  if (request->params.obj[2].type != OBJECT_TYPE_ARRAY) {
    error_set(error, API_ERROR_TYPE_VALIDATION,
        "Error dispatching run API request. function string has wrong type");
    return (-1);
  }

  args_object = request->params.obj[2];
  callid = (uint64_t) randommod(281474976710656LL);
  LOG_VERBOSE(VERBOSE_LEVEL_1, "generated callid %lu\n", callid);
  hashmap_put(uint64_t, ptr_t)(callids, callid, pluginkey);

  if (api_run(targetpluginkey, function_name, callid, args_object, con_id,
      request->msgid, error) == -1) {
    if (false == error->isset)
      error_set(error, API_ERROR_TYPE_VALIDATION,
         "Error executing run API request.");
    return (-1);
  }

  return (0);
}
Пример #2
0
void l_ref_put(hashmap_p hash, char *name, LValue **ref) {
    hashmap_put(hash, name, ref, sizeof(ref));
}
Пример #3
0
static int curl_glue_socket_callback(CURLM *curl, curl_socket_t s, int action, void *userdata, void *socketp) {
        sd_event_source *io;
        CurlGlue *g = userdata;
        uint32_t events = 0;
        int r;

        assert(curl);
        assert(g);

        io = hashmap_get(g->ios, FD_TO_PTR(s));

        if (action == CURL_POLL_REMOVE) {
                if (io) {
                        int fd;

                        fd = sd_event_source_get_io_fd(io);
                        assert(fd >= 0);

                        sd_event_source_set_enabled(io, SD_EVENT_OFF);
                        sd_event_source_unref(io);

                        hashmap_remove(g->ios, FD_TO_PTR(s));
                        hashmap_remove(g->translate_fds, FD_TO_PTR(fd));

                        safe_close(fd);
                }

                return 0;
        }

        r = hashmap_ensure_allocated(&g->ios, &trivial_hash_ops);
        if (r < 0) {
                log_oom();
                return -1;
        }

        r = hashmap_ensure_allocated(&g->translate_fds, &trivial_hash_ops);
        if (r < 0) {
                log_oom();
                return -1;
        }

        if (action == CURL_POLL_IN)
                events = EPOLLIN;
        else if (action == CURL_POLL_OUT)
                events = EPOLLOUT;
        else if (action == CURL_POLL_INOUT)
                events = EPOLLIN|EPOLLOUT;

        if (io) {
                if (sd_event_source_set_io_events(io, events) < 0)
                        return -1;

                if (sd_event_source_set_enabled(io, SD_EVENT_ON) < 0)
                        return -1;
        } else {
                _cleanup_close_ int fd = -1;

                /* When curl needs to remove an fd from us it closes
                 * the fd first, and only then calls into us. This is
                 * nasty, since we cannot pass the fd on to epoll()
                 * anymore. Hence, duplicate the fds here, and keep a
                 * copy for epoll which we control after use. */

                fd = fcntl(s, F_DUPFD_CLOEXEC, 3);
                if (fd < 0)
                        return -1;

                if (sd_event_add_io(g->event, &io, fd, events, curl_glue_on_io, g) < 0)
                        return -1;

                (void) sd_event_source_set_description(io, "curl-io");

                r = hashmap_put(g->ios, FD_TO_PTR(s), io);
                if (r < 0) {
                        log_oom();
                        sd_event_source_unref(io);
                        return -1;
                }

                r = hashmap_put(g->translate_fds, FD_TO_PTR(fd), FD_TO_PTR(s));
                if (r < 0) {
                        log_oom();
                        hashmap_remove(g->ios, FD_TO_PTR(s));
                        sd_event_source_unref(io);
                        return -1;
                }

                fd = -1;
        }

        return 0;
}
Пример #4
0
int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
        _cleanup_closedir_ DIR *d = NULL;
        struct stat exclude_st;
        int r;

        if (keep_free == 0 && max_use == 0)
                return 0;

        if (exclude_fd >= 0) {
                if (fstat(exclude_fd, &exclude_st) < 0)
                        return log_error_errno(errno, "Failed to fstat(): %m");
        }

        /* This algorithm will keep deleting the oldest file of the
         * user with the most coredumps until we are back in the size
         * limits. Note that vacuuming for journal files is different,
         * because we rely on rate-limiting of the messages there,
         * to avoid being flooded. */

        d = opendir("/var/lib/systemd/coredump");
        if (!d) {
                if (errno == ENOENT)
                        return 0;

                log_error_errno(errno, "Can't open coredump directory: %m");
                return -errno;
        }

        for (;;) {
                _cleanup_(vacuum_candidate_hasmap_freep) Hashmap *h = NULL;
                struct vacuum_candidate *worst = NULL;
                struct dirent *de;
                uint64_t sum = 0;

                rewinddir(d);

                FOREACH_DIRENT(de, d, goto fail) {
                        struct vacuum_candidate *c;
                        struct stat st;
                        uid_t uid;
                        usec_t t;

                        r = uid_from_file_name(de->d_name, &uid);
                        if (r < 0)
                                continue;

                        if (fstatat(dirfd(d), de->d_name, &st, AT_NO_AUTOMOUNT|AT_SYMLINK_NOFOLLOW) < 0) {
                                if (errno == ENOENT)
                                        continue;

                                log_warning("Failed to stat /var/lib/systemd/coredump/%s", de->d_name);
                                continue;
                        }

                        if (!S_ISREG(st.st_mode))
                                continue;

                        if (exclude_fd >= 0 &&
                            exclude_st.st_dev == st.st_dev &&
                            exclude_st.st_ino == st.st_ino)
                                continue;

                        r = hashmap_ensure_allocated(&h, NULL);
                        if (r < 0)
                                return log_oom();

                        t = timespec_load(&st.st_mtim);

                        c = hashmap_get(h, UINT32_TO_PTR(uid));
                        if (c) {

                                if (t < c->oldest_mtime) {
                                        char *n;

                                        n = strdup(de->d_name);
                                        if (!n)
                                                return log_oom();

                                        free(c->oldest_file);
                                        c->oldest_file = n;
                                        c->oldest_mtime = t;
                                }

                        } else {
                                _cleanup_(vacuum_candidate_freep) struct vacuum_candidate *n = NULL;

                                n = new0(struct vacuum_candidate, 1);
                                if (!n)
                                        return log_oom();

                                n->oldest_file = strdup(de->d_name);
                                if (!n->oldest_file)
                                        return log_oom();

                                n->oldest_mtime = t;

                                r = hashmap_put(h, UINT32_TO_PTR(uid), n);
                                if (r < 0)
                                        return log_oom();

                                c = n;
                                n = NULL;
                        }

                        c->n_files++;

                        if (!worst ||
                            worst->n_files < c->n_files ||
                            (worst->n_files == c->n_files && c->oldest_mtime < worst->oldest_mtime))
                                worst = c;

                        sum += st.st_blocks * 512;
                }

                if (!worst)
                        break;

                r = vacuum_necessary(dirfd(d), sum, keep_free, max_use);
                if (r <= 0)
                        return r;

                if (unlinkat(dirfd(d), worst->oldest_file, 0) < 0) {

                        if (errno == ENOENT)
                                continue;

                        log_error_errno(errno, "Failed to remove file %s: %m", worst->oldest_file);
                        return -errno;
                } else
                        log_info("Removed old coredump %s.", worst->oldest_file);
        }

        return 0;

fail:
        log_error_errno(errno, "Failed to read directory: %m");
        return -errno;
}
Пример #5
0
void hashmap_iput(hashmap *hm, unsigned int key, void *value, unsigned int value_len) {
    hashmap_put(hm, (char*)&key, sizeof(unsigned int), value, value_len);
}
Пример #6
0
int
main(int argc, char *argv[])
{
	char **args;
	char *type = "jcifs";
	int verbose = 0;
	char *filename = NULL, *outname = NULL;
	char symtabpath[PATH_MAX + 1], *sp;
	struct hashmap macros;

	if (argc < 2) {
usage:
		fprintf(stderr, "usage: %s [-v|-d] [-s <symtab>] [-t jcifs|java|samba|c] [-o outfile] [-Dmacro=defn] <filename>\n", argv[0]);
		return EXIT_FAILURE;
	}

	errno = 0;

	if (hashmap_init(&macros, 0, hash_text, cmp_text, NULL, NULL) == -1) {
		MMSG("");
		return EXIT_FAILURE;
	}

	args = argv;
	args++; argc--;

	sp = symtabpath;
#ifdef _DATADIR
	sp += sprintf(sp, "%s%c", _DATADIR, SEP);
#endif
	sprintf(sp, "symtab%s.txt", type);

	while (argc) {
		if (strcmp(*args, "-v") == 0) {
			verbose++;
		} else if (strcmp(*args, "-d") == 0) {
			verbose += 2;
		} else if (strcmp(*args, "-s") == 0) {
			args++; argc--;
			if (!argc) {
				MMSG("-s requires a symtab path");
				goto usage;
			}
			strncpy(symtabpath, *args, PATH_MAX);
		} else if (strcmp(*args, "-t") == 0) {
			args++; argc--;
			if (!argc) {
				MMSG("-t requires a type");
				goto usage;
			}

			sp = symtabpath;
#ifdef _DATADIR
			sp += sprintf(sp, "%s%c", _DATADIR, SEP);
#endif
			type = *args;
			sprintf(sp, "symtab%s.txt", type);
		} else if (strncmp(*args, "-D", 2) == 0) {
			char *p, *macro, *defn = NULL;

			p = macro = (*args) + 2;

			for ( ;; p++) {
				if (*p == '\0') {
					if (p == macro) {
						macro = NULL;
					} else if (defn == NULL) {
						defn = "1";
					}
					break;
				} else if (defn == NULL && isspace(*p)) {
					MMSG("invalid macro: %s", *args);
					goto usage;
				} else if (*p == '=') {
					if (p == macro) {
						MMSG("invalid macro: %s", *args);
						goto usage;
					}
					*p = '\0';
					defn = p + 1;
				}
			}
			if (macro && hashmap_put(&macros, macro, defn) == -1) {
				MMSG("");
				return EXIT_FAILURE;
			}
		} else if (strcmp(*args, "-o") == 0) {
			args++; argc--;
			if (!argc) {
				MMSG("-o requires a filename");
				goto usage;
			}
			outname = *args;
		} else if (filename || **args == '-') {
			MMSG("Invalid argument: %s", *args);
			goto usage;
		} else {
			filename = *args;
		}
		args++; argc--;
	}
	if (!filename) {
		MMSG("A filename must be specified");
		goto usage;
	}

	if (run(argc, argv, filename, outname, type, symtabpath, &macros, verbose) == -1) {
		MMSG("");
		return EXIT_FAILURE;
	}

	return EXIT_SUCCESS;
}
Пример #7
0
static int process(const char *controller, const char *path, Hashmap *a, Hashmap *b, unsigned iteration) {
        Group *g;
        int r;
        FILE *f;
        pid_t pid;
        unsigned n;

        assert(controller);
        assert(path);
        assert(a);

        g = hashmap_get(a, path);
        if (!g) {
                g = hashmap_get(b, path);
                if (!g) {
                        g = new0(Group, 1);
                        if (!g)
                                return -ENOMEM;

                        g->path = strdup(path);
                        if (!g->path) {
                                group_free(g);
                                return -ENOMEM;
                        }

                        r = hashmap_put(a, g->path, g);
                        if (r < 0) {
                                group_free(g);
                                return r;
                        }
                } else {
                        assert_se(hashmap_move_one(a, b, path) == 0);
                        g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false;
                }
        }

        /* Regardless which controller, let's find the maximum number
         * of processes in any of it */

        r = cg_enumerate_tasks(controller, path, &f);
        if (r < 0)
                return r;

        n = 0;
        while (cg_read_pid(f, &pid) > 0)
                n++;
        fclose(f);

        if (n > 0) {
                if (g->n_tasks_valid)
                        g->n_tasks = MAX(g->n_tasks, n);
                else
                        g->n_tasks = n;

                g->n_tasks_valid = true;
        }

        if (streq(controller, "cpuacct")) {
                uint64_t new_usage;
                char *p, *v;
                struct timespec ts;

                r = cg_get_path(controller, path, "cpuacct.usage", &p);
                if (r < 0)
                        return r;

                r = read_one_line_file(p, &v);
                free(p);
                if (r < 0)
                        return r;

                r = safe_atou64(v, &new_usage);
                free(v);
                if (r < 0)
                        return r;

                assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);

                if (g->cpu_iteration == iteration - 1) {
                        uint64_t x, y;

                        x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) -
                                ((uint64_t) g->cpu_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->cpu_timestamp.tv_nsec);

                        y = new_usage - g->cpu_usage;

                        if (y > 0) {
                                g->cpu_fraction = (double) y / (double) x;
                                g->cpu_valid = true;
                        }
                }

                g->cpu_usage = new_usage;
                g->cpu_timestamp = ts;
                g->cpu_iteration = iteration;

        } else if (streq(controller, "memory")) {
                char *p, *v;

                r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
                if (r < 0)
                        return r;

                r = read_one_line_file(p, &v);
                free(p);
                if (r < 0)
                        return r;

                r = safe_atou64(v, &g->memory);
                free(v);
                if (r < 0)
                        return r;

                if (g->memory > 0)
                        g->memory_valid = true;

        } else if (streq(controller, "blkio")) {
                char *p;
                uint64_t wr = 0, rd = 0;
                struct timespec ts;

                r = cg_get_path(controller, path, "blkio.io_service_bytes", &p);
                if (r < 0)
                        return r;

                f = fopen(p, "re");
                free(p);

                if (!f)
                        return -errno;

                for (;;) {
                        char line[LINE_MAX], *l;
                        uint64_t k, *q;

                        if (!fgets(line, sizeof(line), f))
                                break;

                        l = strstrip(line);
                        l += strcspn(l, WHITESPACE);
                        l += strspn(l, WHITESPACE);

                        if (first_word(l, "Read")) {
                                l += 4;
                                q = &rd;
                        } else if (first_word(l, "Write")) {
                                l += 5;
                                q = &wr;
                        } else
                                continue;

                        l += strspn(l, WHITESPACE);
                        r = safe_atou64(l, &k);
                        if (r < 0)
                                continue;

                        *q += k;
                }

                fclose(f);

                assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);

                if (g->io_iteration == iteration - 1) {
                        uint64_t x, yr, yw;

                        x = ((uint64_t) ts.tv_sec * 1000000000ULL + (uint64_t) ts.tv_nsec) -
                                ((uint64_t) g->io_timestamp.tv_sec * 1000000000ULL + (uint64_t) g->io_timestamp.tv_nsec);

                        yr = rd - g->io_input;
                        yw = wr - g->io_output;

                        if (yr > 0 || yw > 0) {
                                g->io_input_bps = (yr * 1000000000ULL) / x;
                                g->io_output_bps = (yw * 1000000000ULL) / x;
                                g->io_valid = true;

                        }
                }

                g->io_input = rd;
                g->io_output = wr;
                g->io_timestamp = ts;
                g->io_iteration = iteration;
        }

        return 0;
}
Пример #8
0
#include <c_hashmap/hashmap.h>


// All tests in this file adapted from example code in the original c_hashmap
// package's main.c


FEATURE(hashmap_put, "Hashmap put")
	SCENARIO("Put one value")
		GIVEN("a new hashmap")
			map_t map = hashmap_new();

		WHEN("I put a new value in")
			int value = 42;
			int error = hashmap_put(map, "somekey", &value);

		THEN("the operation should be successful");
			SHOULD_INT_EQUAL(error, (int)MAP_OK);

		hashmap_free(map);
	SCENARIO_END
FEATURE_END

FEATURE(hashmap_get, "Hashmap get")
	SCENARIO("Get an existing value")
		GIVEN("a hashmap with a value")
			map_t map = hashmap_new();
			int value = 42;
			hashmap_put(map, "somekey", &value);
Пример #9
0
static int lldp_add_neighbor(sd_lldp *lldp, sd_lldp_neighbor *n) {
        _cleanup_(sd_lldp_neighbor_unrefp) sd_lldp_neighbor *old = NULL;
        bool keep;
        int r;

        assert(lldp);
        assert(n);
        assert(!n->lldp);

        keep = lldp_keep_neighbor(lldp, n);

        /* First retrieve the old entry for this MSAP */
        old = hashmap_get(lldp->neighbor_by_id, &n->id);
        if (old) {
                sd_lldp_neighbor_ref(old);

                if (!keep) {
                        lldp_neighbor_unlink(old);
                        lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, old);
                        return 0;
                }

                if (lldp_neighbor_equal(n, old)) {
                        /* Is this equal, then restart the TTL counter, but don't do anyting else. */
                        lldp_start_timer(lldp, old);
                        lldp_callback(lldp, SD_LLDP_EVENT_REFRESHED, old);
                        return 0;
                }

                /* Data changed, remove the old entry, and add a new one */
                lldp_neighbor_unlink(old);

        } else if (!keep)
                return 0;

        /* Then, make room for at least one new neighbor */
        lldp_make_space(lldp, 1);

        r = hashmap_put(lldp->neighbor_by_id, &n->id, n);
        if (r < 0)
                goto finish;

        r = prioq_put(lldp->neighbor_by_expiry, n, &n->prioq_idx);
        if (r < 0) {
                assert_se(hashmap_remove(lldp->neighbor_by_id, &n->id) == n);
                goto finish;
        }

        n->lldp = lldp;

        lldp_start_timer(lldp, n);
        lldp_callback(lldp, old ? SD_LLDP_EVENT_UPDATED : SD_LLDP_EVENT_ADDED, n);

        return 1;

finish:
        if (old)
                lldp_callback(lldp, SD_LLDP_EVENT_REMOVED, n);

        return r;
}
Пример #10
0
void SetProperty(char* key, void * value){
	if (!prop_map) prop_map = hashmap_new();
	int error = hashmap_put(prop_map, key, value);
    assert(error==MAP_OK);
}
Пример #11
0
int main(int argc, char *argv[]) {
        _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
        _cleanup_endmntent_ FILE *f = NULL;
        struct mntent* me;
        int r;

        if (argc > 1) {
                log_error("This program takes no argument.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        f = setmntent("/etc/fstab", "r");
        if (!f) {
                if (errno == ENOENT) {
                        r = 0;
                        goto finish;
                }

                r = log_error_errno(errno, "Failed to open /etc/fstab: %m");
                goto finish;
        }

        pids = hashmap_new(NULL);
        if (!pids) {
                r = log_oom();
                goto finish;
        }

        while ((me = getmntent(f))) {
                pid_t pid;
                int k;
                char *s;

                /* Remount the root fs, /usr and all API VFS */
                if (!mount_point_is_api(me->mnt_dir) &&
                    !path_equal(me->mnt_dir, "/") &&
                    !path_equal(me->mnt_dir, "/usr"))
                        continue;

                log_debug("Remounting %s", me->mnt_dir);

                pid = fork();
                if (pid < 0) {
                        r = log_error_errno(errno, "Failed to fork: %m");
                        goto finish;
                }

                if (pid == 0) {
                        /* Child */

                        (void) reset_all_signal_handlers();
                        (void) reset_signal_mask();
                        (void) prctl(PR_SET_PDEATHSIG, SIGTERM);

                        execv(MOUNT_PATH, STRV_MAKE(MOUNT_PATH, me->mnt_dir, "-o", "remount"));

                        log_error_errno(errno, "Failed to execute " MOUNT_PATH ": %m");
                        _exit(EXIT_FAILURE);
                }

                /* Parent */

                s = strdup(me->mnt_dir);
                if (!s) {
                        r = log_oom();
                        goto finish;
                }

                k = hashmap_put(pids, PID_TO_PTR(pid), s);
                if (k < 0) {
                        free(s);
                        r = log_oom();
                        goto finish;
                }
        }

        r = 0;
        while (!hashmap_isempty(pids)) {
                siginfo_t si = {};
                char *s;

                if (waitid(P_ALL, 0, &si, WEXITED) < 0) {

                        if (errno == EINTR)
                                continue;

                        r = log_error_errno(errno, "waitid() failed: %m");
                        goto finish;
                }

                s = hashmap_remove(pids, PID_TO_PTR(si.si_pid));
                if (s) {
                        if (!is_clean_exit(si.si_code, si.si_status, EXIT_CLEAN_COMMAND, NULL)) {
                                if (si.si_code == CLD_EXITED)
                                        log_error(MOUNT_PATH " for %s exited with exit status %i.", s, si.si_status);
                                else
                                        log_error(MOUNT_PATH " for %s terminated by signal %s.", s, signal_to_string(si.si_status));

                                r = -ENOEXEC;
                        }

                        free(s);
                }
        }

finish:
        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
Пример #12
0
static int process(
                const char *controller,
                const char *path,
                Hashmap *a,
                Hashmap *b,
                unsigned iteration,
                Group **ret) {

        Group *g;
        int r;

        assert(controller);
        assert(path);
        assert(a);

        g = hashmap_get(a, path);
        if (!g) {
                g = hashmap_get(b, path);
                if (!g) {
                        g = new0(Group, 1);
                        if (!g)
                                return -ENOMEM;

                        g->path = strdup(path);
                        if (!g->path) {
                                group_free(g);
                                return -ENOMEM;
                        }

                        r = hashmap_put(a, g->path, g);
                        if (r < 0) {
                                group_free(g);
                                return r;
                        }
                } else {
                        r = hashmap_move_one(a, b, path);
                        if (r < 0)
                                return r;

                        g->cpu_valid = g->memory_valid = g->io_valid = g->n_tasks_valid = false;
                }
        }

        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES)) {
                _cleanup_fclose_ FILE *f = NULL;
                pid_t pid;

                r = cg_enumerate_processes(controller, path, &f);
                if (r == -ENOENT)
                        return 0;
                if (r < 0)
                        return r;

                g->n_tasks = 0;
                while (cg_read_pid(f, &pid) > 0) {

                        if (arg_count == COUNT_USERSPACE_PROCESSES && is_kernel_thread(pid) > 0)
                                continue;

                        g->n_tasks++;
                }

                if (g->n_tasks > 0)
                        g->n_tasks_valid = true;

        } else if (streq(controller, "pids") && arg_count == COUNT_PIDS) {
                _cleanup_free_ char *p = NULL, *v = NULL;

                r = cg_get_path(controller, path, "pids.current", &p);
                if (r < 0)
                        return r;

                r = read_one_line_file(p, &v);
                if (r == -ENOENT)
                        return 0;
                if (r < 0)
                        return r;

                r = safe_atou64(v, &g->n_tasks);
                if (r < 0)
                        return r;

                if (g->n_tasks > 0)
                        g->n_tasks_valid = true;

        } else if (streq(controller, "cpuacct") && cg_unified() <= 0) {
                _cleanup_free_ char *p = NULL, *v = NULL;
                uint64_t new_usage;
                nsec_t timestamp;

                r = cg_get_path(controller, path, "cpuacct.usage", &p);
                if (r < 0)
                        return r;

                r = read_one_line_file(p, &v);
                if (r == -ENOENT)
                        return 0;
                if (r < 0)
                        return r;

                r = safe_atou64(v, &new_usage);
                if (r < 0)
                        return r;

                timestamp = now_nsec(CLOCK_MONOTONIC);

                if (g->cpu_iteration == iteration - 1 &&
                    (nsec_t) new_usage > g->cpu_usage) {

                        nsec_t x, y;

                        x = timestamp - g->cpu_timestamp;
                        if (x < 1)
                                x = 1;

                        y = (nsec_t) new_usage - g->cpu_usage;
                        g->cpu_fraction = (double) y / (double) x;
                        g->cpu_valid = true;
                }

                g->cpu_usage = (nsec_t) new_usage;
                g->cpu_timestamp = timestamp;
                g->cpu_iteration = iteration;

        } else if (streq(controller, "memory")) {
                _cleanup_free_ char *p = NULL, *v = NULL;

                if (cg_unified() <= 0)
                        r = cg_get_path(controller, path, "memory.usage_in_bytes", &p);
                else
                        r = cg_get_path(controller, path, "memory.current", &p);
                if (r < 0)
                        return r;

                r = read_one_line_file(p, &v);
                if (r == -ENOENT)
                        return 0;
                if (r < 0)
                        return r;

                r = safe_atou64(v, &g->memory);
                if (r < 0)
                        return r;

                if (g->memory > 0)
                        g->memory_valid = true;

        } else if ((streq(controller, "io") && cg_unified() > 0) ||
                   (streq(controller, "blkio") && cg_unified() <= 0)) {
                _cleanup_fclose_ FILE *f = NULL;
                _cleanup_free_ char *p = NULL;
                bool unified = cg_unified() > 0;
                uint64_t wr = 0, rd = 0;
                nsec_t timestamp;

                r = cg_get_path(controller, path, unified ? "io.stat" : "blkio.io_service_bytes", &p);
                if (r < 0)
                        return r;

                f = fopen(p, "re");
                if (!f) {
                        if (errno == ENOENT)
                                return 0;
                        return -errno;
                }

                for (;;) {
                        char line[LINE_MAX], *l;
                        uint64_t k, *q;

                        if (!fgets(line, sizeof(line), f))
                                break;

                        /* Trim and skip the device */
                        l = strstrip(line);
                        l += strcspn(l, WHITESPACE);
                        l += strspn(l, WHITESPACE);

                        if (unified) {
                                while (!isempty(l)) {
                                        if (sscanf(l, "rbytes=%" SCNu64, &k))
                                                rd += k;
                                        else if (sscanf(l, "wbytes=%" SCNu64, &k))
                                                wr += k;

                                        l += strcspn(l, WHITESPACE);
                                        l += strspn(l, WHITESPACE);
                                }
                        } else {
                                if (first_word(l, "Read")) {
                                        l += 4;
                                        q = &rd;
                                } else if (first_word(l, "Write")) {
                                        l += 5;
                                        q = &wr;
                                } else
                                        continue;

                                l += strspn(l, WHITESPACE);
                                r = safe_atou64(l, &k);
                                if (r < 0)
                                        continue;

                                *q += k;
                        }
                }

                timestamp = now_nsec(CLOCK_MONOTONIC);

                if (g->io_iteration == iteration - 1) {
                        uint64_t x, yr, yw;

                        x = (uint64_t) (timestamp - g->io_timestamp);
                        if (x < 1)
                                x = 1;

                        if (rd > g->io_input)
                                yr = rd - g->io_input;
                        else
                                yr = 0;

                        if (wr > g->io_output)
                                yw = wr - g->io_output;
                        else
                                yw = 0;

                        if (yr > 0 || yw > 0) {
                                g->io_input_bps = (yr * 1000000000ULL) / x;
                                g->io_output_bps = (yw * 1000000000ULL) / x;
                                g->io_valid = true;
                        }
                }

                g->io_input = rd;
                g->io_output = wr;
                g->io_timestamp = timestamp;
                g->io_iteration = iteration;
        }

        if (ret)
                *ret = g;

        return 0;
}
Пример #13
0
/**
 * Add one pair to the dom
 * @param p the pair to add
 * @param p_parent the pair parent ("pairs")
 * @param parents a hashmap of parents looking for children
 * @param orphans a hashmap of children looking for parents
 * @param id VAR param: parent ID to update
 * @return 1 if it worked OK else 0
 */
int write_one_pair( pair *p, dom_item *p_parent, hashmap *parents,
                    hashmap *orphans, int *id )
{
    int res = 1;
    dom_item *p_element = dom_object_create( "pair" );
    if ( p_element != NULL )
    {
        if ( pair_is_parent(p) )
        {
            char id_str[32];
            char p_key[32];
            UChar u_key[32];
            snprintf( id_str, 32, "%d", *id );
            dom_add_attribute( p_element, dom_attribute_create("id",id_str) );
            snprintf( p_key, 32, "%lx",(long)p );
            ascii_to_uchar( p_key, u_key, 32 );
            hashmap_put( parents, u_key, id_str );
            (*id)++;
            // check if any orphans belong to this parent
            link_node *ln = hashmap_get( orphans, u_key );
            if ( ln != NULL )
            {
                char *id_str = hashmap_get( parents, u_key );
                dom_item *child = link_node_obj( ln );
                while ( child != NULL )
                {
                    dom_add_attribute( child, dom_attribute_create("parent",
                                       id_str) );
                    ln = link_node_next( ln );
                    if ( ln != NULL )
                        child = link_node_obj( ln );
                    else
                        child = NULL;
                }
                hashmap_remove( orphans, u_key, NULL );
                link_node_dispose( ln );
            }
        }
        else if ( pair_is_child(p) )
        {
            UChar u_key[32];
            char p_key[32];
            snprintf( p_key, 32, "%lx",(long)pair_parent(p) );
            ascii_to_uchar( p_key, u_key, 32 );
            char *id_str = hashmap_get( parents, u_key );
            if ( id_str != NULL )
                dom_add_attribute( p_element, dom_attribute_create("parent",
                                   id_str) );
            else
            {
                link_node *children = hashmap_get( orphans, u_key );
                if ( children == NULL )
                {
                    children = link_node_create();
                    if ( children != NULL )
                    {
                        link_node_set_obj( children, p_element );
                        res = hashmap_put( orphans, u_key, children );
                    }
                }
                else
                {
                    link_node *ln = link_node_create();
                    if ( ln != NULL )
                    {
                        link_node_set_obj( ln, p_element );
                        link_node_append( children, ln );
                    }
                    else
                        res = 0;
                }
            }
        }
        if ( res )
        {
            if ( pair_is_hint(p) )
            {
                dom_add_attribute( p_element,
                                   dom_attribute_create("hint","true") );
            }
            int bytes = bitset_allocated(pair_versions(p))*8;
            char *bit_str = calloc( bytes+1, 1 );
            if ( bit_str != NULL )
            {
                bitset_tostring( pair_versions(p), bit_str, bytes );
                res = dom_add_attribute( p_element,
                                         dom_attribute_create("versions",bit_str) );
                free( bit_str );
            }
            if ( res && !pair_is_child(p) )
            {
                char *utf8_data = to_utf8( pair_data(p), pair_len(p) );
                if ( utf8_data != NULL )
                {
                    res = dom_add_text( p_element, utf8_data );
                    free( utf8_data );
                }
            }
            dom_add_child( p_parent, p_element );
        }
    }
    else
        res = 0;
    return res;
}
Пример #14
0
void dispatch_table_put(string method, dispatch_info info)
{
  hashmap_put(string, dispatch_info)(dispatch_table, method, info);
}
Пример #15
0
/*
 * Read stdin line by line and print result of commands to stdout:
 *
 * hash key -> strhash(key) memhash(key) strihash(key) memihash(key)
 * put key value -> NULL / old value
 * get key -> NULL / value
 * remove key -> NULL / old value
 * iterate -> key1 value1\nkey2 value2\n...
 * size -> tablesize numentries
 *
 * perfhashmap method rounds -> test hashmap.[ch] performance
 */
int main(int argc, char *argv[])
{
	char line[1024];
	struct hashmap map;
	int icase;

	/* init hash map */
	icase = argc > 1 && !strcmp("ignorecase", argv[1]);
	hashmap_init(&map, (hashmap_cmp_fn) (icase ? test_entry_cmp_icase
			: test_entry_cmp), 0);

	/* process commands from stdin */
	while (fgets(line, sizeof(line), stdin)) {
		char *cmd, *p1 = NULL, *p2 = NULL;
		int l1 = 0, l2 = 0, hash = 0;
		struct test_entry *entry;

		/* break line into command and up to two parameters */
		cmd = strtok(line, DELIM);
		/* ignore empty lines */
		if (!cmd || *cmd == '#')
			continue;

		p1 = strtok(NULL, DELIM);
		if (p1) {
			l1 = strlen(p1);
			hash = icase ? strihash(p1) : strhash(p1);
			p2 = strtok(NULL, DELIM);
			if (p2)
				l2 = strlen(p2);
		}

		if (!strcmp("hash", cmd) && l1) {

			/* print results of different hash functions */
			printf("%u %u %u %u\n", strhash(p1), memhash(p1, l1),
					strihash(p1), memihash(p1, l1));

		} else if (!strcmp("add", cmd) && l1 && l2) {

			/* create entry with key = p1, value = p2 */
			entry = alloc_test_entry(hash, p1, l1, p2, l2);

			/* add to hashmap */
			hashmap_add(&map, entry);

		} else if (!strcmp("put", cmd) && l1 && l2) {

			/* create entry with key = p1, value = p2 */
			entry = alloc_test_entry(hash, p1, l1, p2, l2);

			/* add / replace entry */
			entry = hashmap_put(&map, entry);

			/* print and free replaced entry, if any */
			puts(entry ? get_value(entry) : "NULL");
			free(entry);

		} else if (!strcmp("get", cmd) && l1) {

			/* lookup entry in hashmap */
			entry = hashmap_get_from_hash(&map, hash, p1);

			/* print result */
			if (!entry)
				puts("NULL");
			while (entry) {
				puts(get_value(entry));
				entry = hashmap_get_next(&map, entry);
			}

		} else if (!strcmp("remove", cmd) && l1) {

			/* setup static key */
			struct hashmap_entry key;
			hashmap_entry_init(&key, hash);

			/* remove entry from hashmap */
			entry = hashmap_remove(&map, &key, p1);

			/* print result and free entry*/
			puts(entry ? get_value(entry) : "NULL");
			free(entry);

		} else if (!strcmp("iterate", cmd)) {

			struct hashmap_iter iter;
			hashmap_iter_init(&map, &iter);
			while ((entry = hashmap_iter_next(&iter)))
				printf("%s %s\n", entry->key, get_value(entry));

		} else if (!strcmp("size", cmd)) {

			/* print table sizes */
			printf("%u %u\n", map.tablesize, map.size);

		} else if (!strcmp("intern", cmd) && l1) {

			/* test that strintern works */
			const char *i1 = strintern(p1);
			const char *i2 = strintern(p1);
			if (strcmp(i1, p1))
				printf("strintern(%s) returns %s\n", p1, i1);
			else if (i1 == p1)
				printf("strintern(%s) returns input pointer\n", p1);
			else if (i1 != i2)
				printf("strintern(%s) != strintern(%s)", i1, i2);
			else
				printf("%s\n", i1);

		} else if (!strcmp("perfhashmap", cmd) && l1 && l2) {

			perf_hashmap(atoi(p1), atoi(p2));

		} else {

			printf("Unknown command %s\n", cmd);

		}
	}

	hashmap_free(&map, 1);
	return 0;
}
int main(int argc, char *argv[]) {
        int ret = EXIT_FAILURE;
        _cleanup_endmntent_ FILE *f = NULL;
        struct mntent* me;
        Hashmap *pids = NULL;

        if (argc > 1) {
                log_error("This program takes no argument.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        f = setmntent("/etc/fstab", "r");
        if (!f) {
                if (errno == ENOENT)
                        return EXIT_SUCCESS;

                log_error_errno(errno, "Failed to open /etc/fstab: %m");
                return EXIT_FAILURE;
        }

        pids = hashmap_new(NULL);
        if (!pids) {
                log_error("Failed to allocate set");
                goto finish;
        }

        ret = EXIT_SUCCESS;

        while ((me = getmntent(f))) {
                pid_t pid;
                int k;
                char *s;

                /* Remount the root fs, /usr and all API VFS */
                if (!mount_point_is_api(me->mnt_dir) &&
                    !path_equal(me->mnt_dir, "/") &&
                    !path_equal(me->mnt_dir, "/usr"))
                        continue;

                log_debug("Remounting %s", me->mnt_dir);

                pid = fork();
                if (pid < 0) {
                        log_error_errno(errno, "Failed to fork: %m");
                        ret = EXIT_FAILURE;
                        continue;
                }

                if (pid == 0) {
                        const char *arguments[5];
                        /* Child */

                        arguments[0] = "/bin/mount";
                        arguments[1] = me->mnt_dir;
                        arguments[2] = "-o";
                        arguments[3] = "remount";
                        arguments[4] = NULL;

                        execv("/bin/mount", (char **) arguments);

                        log_error_errno(errno, "Failed to execute /bin/mount: %m");
                        _exit(EXIT_FAILURE);
                }

                /* Parent */

                s = strdup(me->mnt_dir);
                if (!s) {
                        log_oom();
                        ret = EXIT_FAILURE;
                        continue;
                }


                k = hashmap_put(pids, UINT_TO_PTR(pid), s);
                if (k < 0) {
                        log_error_errno(k, "Failed to add PID to set: %m");
                        ret = EXIT_FAILURE;
                        continue;
                }
        }

        while (!hashmap_isempty(pids)) {
                siginfo_t si = {};
                char *s;

                if (waitid(P_ALL, 0, &si, WEXITED) < 0) {

                        if (errno == EINTR)
                                continue;

                        log_error_errno(errno, "waitid() failed: %m");
                        ret = EXIT_FAILURE;
                        break;
                }

                s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
                if (s) {
                        if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
                                if (si.si_code == CLD_EXITED)
                                        log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
                                else
                                        log_error("/bin/mount for %s terminated by signal %s.", s, signal_to_string(si.si_status));

                                ret = EXIT_FAILURE;
                        }

                        free(s);
                }
        }

finish:

        if (pids)
                hashmap_free_free(pids);

        return ret;
}
Пример #17
0
static int do_execute(char **directories, usec_t timeout, char *argv[]) {
        _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
        _cleanup_set_free_free_ Set *seen = NULL;
        char **directory;

        /* We fork this all off from a child process so that we can
         * somewhat cleanly make use of SIGALRM to set a time limit */

        (void) reset_all_signal_handlers();
        (void) reset_signal_mask();

        assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);

        pids = hashmap_new(NULL);
        if (!pids)
                return log_oom();

        seen = set_new(&string_hash_ops);
        if (!seen)
                return log_oom();

        STRV_FOREACH(directory, directories) {
                _cleanup_closedir_ DIR *d;
                struct dirent *de;

                d = opendir(*directory);
                if (!d) {
                        if (errno == ENOENT)
                                continue;

                        return log_error_errno(errno, "Failed to open directory %s: %m", *directory);
                }

                FOREACH_DIRENT(de, d, break) {
                        _cleanup_free_ char *path = NULL;
                        pid_t pid;
                        int r;

                        if (!dirent_is_file(de))
                                continue;

                        if (set_contains(seen, de->d_name)) {
                                log_debug("%1$s/%2$s skipped (%2$s was already seen).", *directory, de->d_name);
                                continue;
                        }

                        r = set_put_strdup(seen, de->d_name);
                        if (r < 0)
                                return log_oom();

                        path = strjoin(*directory, "/", de->d_name, NULL);
                        if (!path)
                                return log_oom();

                        if (null_or_empty_path(path)) {
                                log_debug("%s is empty (a mask).", path);
                                continue;
                        }

                        pid = fork();
                        if (pid < 0) {
                                log_error_errno(errno, "Failed to fork: %m");
                                continue;
                        } else if (pid == 0) {
                                char *_argv[2];

                                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);

                                if (!argv) {
                                        _argv[0] = path;
                                        _argv[1] = NULL;
                                        argv = _argv;
                                } else
                                        argv[0] = path;

                                execv(path, argv);
                                return log_error_errno(errno, "Failed to execute %s: %m", path);
                        }

                        log_debug("Spawned %s as " PID_FMT ".", path, pid);

                        r = hashmap_put(pids, PID_TO_PTR(pid), path);
                        if (r < 0)
                                return log_oom();
                        path = NULL;
                }
        }
Пример #18
0
static int dracut_install(const char *src, const char *dst, bool isdir, bool resolvedeps, bool hashdst)
{
        struct stat sb, db;
        _cleanup_free_ char *fulldstpath = NULL;
        _cleanup_free_ char *fulldstdir = NULL;
        int ret;
        bool src_exists = true;
        char *i = NULL;
        char *existing;

        log_debug("dracut_install('%s', '%s')", src, dst);

        existing = hashmap_get(items_failed, src);
        if (existing) {
                if (strcmp(existing, src) == 0) {
                        log_debug("hash hit items_failed for '%s'", src);
                        return 1;
                }
        }

        if (hashdst) {
                existing = hashmap_get(items, dst);
                if (existing) {
                        if (strcmp(existing, dst) == 0) {
                                log_debug("hash hit items for '%s'", dst);
                                return 0;
                        }
                }
        }

        if (lstat(src, &sb) < 0) {
                src_exists = false;
                if (!isdir) {
                        i = strdup(src);
                        hashmap_put(items_failed, i, i);
                        /* src does not exist */
                        return 1;
                }
        }

        i = strdup(dst);
        if (!i)
                return -ENOMEM;

        hashmap_put(items, i, i);

        ret = asprintf(&fulldstpath, "%s%s", destrootdir, dst);
        if (ret < 0) {
                log_error("Out of memory!");
                exit(EXIT_FAILURE);
        }

        ret = stat(fulldstpath, &sb);

        if (ret != 0 && (errno != ENOENT)) {
                log_error("ERROR: stat '%s': %m", fulldstpath);
                return 1;
        }

        if (ret == 0) {
                if (resolvedeps && S_ISREG(sb.st_mode) && (sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))) {
                        log_debug("'%s' already exists, but checking for any deps", fulldstpath);
                        ret = resolve_deps(src);
                } else
                        log_debug("'%s' already exists", fulldstpath);

                /* dst does already exist */
                return ret;
        }

        /* check destination directory */
        fulldstdir = strdup(fulldstpath);
        fulldstdir[dir_len(fulldstdir)] = '\0';

        ret = stat(fulldstdir, &db);

        if (ret < 0) {
                _cleanup_free_ char *dname = NULL;

                if (errno != ENOENT) {
                        log_error("ERROR: stat '%s': %m", fulldstdir);
                        return 1;
                }
                /* create destination directory */
                log_debug("dest dir '%s' does not exist", fulldstdir);
                dname = strdup(dst);
                if (!dname)
                        return 1;

                dname[dir_len(dname)] = '\0';
                ret = dracut_install(dname, dname, true, false, true);

                if (ret != 0) {
                        log_error("ERROR: failed to create directory '%s'", fulldstdir);
                        return 1;
                }
        }

        if (isdir && !src_exists) {
                log_info("mkdir '%s'", fulldstpath);
                ret = mkdir(fulldstpath, 0755);
                return ret;
        }

        /* ready to install src */

        if (S_ISDIR(sb.st_mode)) {
                log_info("mkdir '%s'", fulldstpath);
                ret = mkdir(fulldstpath, sb.st_mode | S_IWUSR);
                return ret;
        }

        if (S_ISLNK(sb.st_mode)) {
                _cleanup_free_ char *abspath = NULL;

                abspath = realpath(src, NULL);

                if (abspath == NULL)
                        return 1;

                if (dracut_install(abspath, abspath, false, resolvedeps, hashdst)) {
                        log_debug("'%s' install error", abspath);
                        return 1;
                }

                if (lstat(abspath, &sb) != 0) {
                        log_debug("lstat '%s': %m", abspath);
                        return 1;
                }

                if (lstat(fulldstpath, &sb) != 0) {
                        _cleanup_free_ char *absdestpath = NULL;

                        ret = asprintf(&absdestpath, "%s%s", destrootdir, abspath);
                        if (ret < 0) {
                                log_error("Out of memory!");
                                exit(EXIT_FAILURE);
                        }

                        ln_r(absdestpath, fulldstpath);
                }

                if (arg_hmac) {
                        /* copy .hmac files also */
                        hmac_install(src, dst, NULL);
                }

                return 0;
        }

        if (sb.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)) {
                if (resolvedeps)
                        ret += resolve_deps(src);
                if (arg_hmac) {
                        /* copy .hmac files also */
                        hmac_install(src, dst, NULL);
                }
        }

        log_debug("dracut_install ret = %d", ret);
        log_info("cp '%s' '%s'", src, fulldstpath);

        if (arg_hostonly)
                mark_hostonly(dst);

        ret += cp(src, fulldstpath);
        if (ret == 0 && logfile_f)
                dracut_log_cp(src);

        log_debug("dracut_install ret = %d", ret);

        return ret;
}
Пример #19
0
int main(char* argv, int argc)
{
    int index;
    int error;
    map_t mymap;
    char key_string[KEY_MAX_LENGTH];
    data_struct_t* value;

    fprintf(stderr, "start...\n");
    mymap = hashmap_new();

    /* First, populate the hash map with ascending values */
    for (index=0; index<KEY_COUNT; index+=1)
    {
        /* Store the key string along side the numerical value so we can free it later */
        value = malloc(sizeof(data_struct_t));
        //snprintf(value->key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        snprintf(value->key_string, KEY_MAX_LENGTH, "%s", strings[index]);
        value->number = index;
        //fprintf(stderr, "value->key_string=%s, value->number=%d\n",
        //        value->key_string, value->number);

        error = hashmap_put(mymap, value->key_string, value);
        assert(error==MAP_OK);
    }

    /* Now, check all of the expected values are there */
    for (index=0; index<KEY_COUNT; index+=1)
    {
        //snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        snprintf(key_string, KEY_MAX_LENGTH, "%s", strings[index]);

        error = hashmap_get(mymap, key_string, (void**)(&value));
        //fprintf(stderr, "error=%d, value->number=%d, index=(%d)\n", error, value->number, index);

        /* Make sure the value was both found and the correct number */
        assert(error==MAP_OK);
        assert(value->number==index);
    }

    /* Make sure that a value that wasn't in the map can't be found */
    snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, KEY_COUNT);
    //snprintf(key_string, KEY_MAX_LENGTH, "%s", KEY_COUNT);

    error = hashmap_get(mymap, key_string, (void**)(&value));
    fprintf(stderr, "error=%d\n", error);

    /* Make sure the value was not found */
    assert(error==MAP_MISSING);

    /* Free all of the values we allocated and remove them from the map */
    for (index=0; index<KEY_COUNT; index+=1)
    {
        //snprintf(key_string, KEY_MAX_LENGTH, "%s%d", KEY_PREFIX, index);
        snprintf(key_string, KEY_MAX_LENGTH, "%s", strings[index]);

        error = hashmap_get(mymap, key_string, (void**)(&value));
        assert(error==MAP_OK);

        error = hashmap_remove(mymap, key_string);
        assert(error==MAP_OK);

        free(value);
    }

    /* Now, destroy the map */
    hashmap_free(mymap);

    return 1;
}
Пример #20
0
/**
 * 和客户交互
 * @param  sockfd [description]
 * @param  i      [description]
 * @return        [description]
 */
int client_interface(struct bufferevent *bev, client_t *client) {
    /*加锁*/
    if (pthread_mutex_lock(&mutex) != 0) {
        perror("pthread_mutex_lock");
        exit(EXIT_FAILURE);
    }

    char data[4096];
    int nbytes;

    //接收数据
    char buffer[MAX_BUF + 1];
    bzero(buffer, MAX_BUF + 1);
    int n = 0;
    int str_len = 0;
    int last_len;
    while ((nbytes = EVBUFFER_LENGTH(bev->input)) > 0) {
        if (nbytes > 4096) nbytes = 4096;
        n += evbuffer_remove(bev->input, data, nbytes);
        str_len = strlen(data);
        last_len = (MAX_BUF - strlen(buffer));
        if (last_len >= str_len) {
            strncat(buffer, data, str_len);
        } else {
            strncat(buffer, data, last_len);
        }
    }

    if (n <= 0) {
        /*解锁锁*/
        if (pthread_mutex_unlock(&mutex) != 0) {
            perror("pthread_mutex_unlock");
            exit(EXIT_FAILURE);
        }

        return 0; //客户端退出时
    }

    //printf("第%d个客户端 IP:%s\n", i + 1, inet_ntoa(_client[i].addr.sin_addr));

    //解析客户端信息
    int flag = 0;

    int ret;
    char key[20];
    sprintf(key, "%d", client->fd);
    client_elem *c_el;
    ret = hashmap_get(client_map, key, (void **)&c_el);
    assert(ret == HMAP_S_OK);

    _RTS_TRANSPORT_DATA _rts_transport_data;
    _rts_transport_data = RTS_transport_data_init();
    if (RTS_transport_data_parse(buffer, &_rts_transport_data) == 0) {
        client_send(client, "{\"code\":\"0001\",\"message\":\"数据格式非法\"}");

        /*解锁锁*/
        if (pthread_mutex_unlock(&mutex) != 0) {
            perror("pthread_mutex_unlock");
            exit(EXIT_FAILURE);
        }

        return 0;
    }

    if (!_rts_transport_data.action) {
        client_send(client, "{\"code\":\"0005\",\"message\":\"参数非法\"}");

        /*解锁锁*/
        if (pthread_mutex_unlock(&mutex) != 0) {
            perror("pthread_mutex_unlock");
            exit(EXIT_FAILURE);
        }

        return 0;
    }

    if (strcmp(_rts_transport_data.action, "login") == 0) { //登录
        if (strlen(_rts_transport_data.name) == 0 || strlen(_rts_transport_data.password) == 0) {
            client_send(client, "{\"code\":\"0005\",\"message\":\"参数非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        //验证用户名密码
        _RTS_USER *_rts_user = user_get(0, _rts_transport_data.name);
        if (_rts_user->id <= 0) {
            client_send(client, "{\"code\":\"0003\",\"message\":\"用户名或密码错误\"}");
            CLIENT_FREE(_rts_user);

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        char *pwdhash = RTS_hash(_rts_transport_data.password, _rts_user->salt);

        if (strcmp(_rts_user->password, pwdhash) != 0) {
            client_send(client, "{\"code\":\"0003\",\"message\":\"用户名或密码错误\"}");
            CLIENT_FREE(pwdhash);
            CLIENT_FREE(_rts_user);

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        //用户名密码验证通过后,判断当前账号是否已登录
        //这时应该已经拿到了用户的id
        if (c_el->token && strlen(c_el->token) > 0) { //该设备已经登录了账号,不能再做登录操作
            client_send(client, "{\"code\":\"1004\",\"message\":\"该设备已经登录了账号,不能再做登录操作\"}");
            CLIENT_FREE(pwdhash);
            CLIENT_FREE(_rts_user);

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 1;
        }

        if (c_el->id == 0 || (c_el->token && strlen(c_el->token) == 0)) { //未登录,直接执行登录赋值操作
            //登录成功,返回认证标示
            char *unique = RTS_unique();
            strncpy(_rts_transport_data.token, unique, MAX_TOKEN_LENGTH);
            CLIENT_FREE(unique);

            //重新设置client_map
            ret = hashmap_remove(client_map, c_el->key, (void **)&c_el);
            assert(ret == HMAP_S_OK);
            client_elem *new_c_el = (client_elem *)malloc(sizeof(client_elem));
            sprintf(new_c_el->key, "%d", client->fd);
            new_c_el->addr = c_el->addr;
            new_c_el->client = client;
            new_c_el->id = _rts_user->id;
            new_c_el->name = (char *)malloc(MAX_NAME_LENGTH + 1);
            strncpy(new_c_el->name, _rts_transport_data.name, MAX_NAME_LENGTH);
            new_c_el->token = (char *)malloc(MAX_TOKEN_LENGTH + 1);
            strncpy(new_c_el->token, _rts_transport_data.token, MAX_TOKEN_LENGTH);
            free_client_elem(c_el, 0);
            ret = hashmap_put(client_map, new_c_el->key, new_c_el);
            assert(ret == HMAP_S_OK);

            //设置client_id_map
            client_id_elem *cid_el = (client_id_elem *)malloc(sizeof(client_id_elem));
            sprintf(cid_el->key, "%d", _rts_user->id);
            cid_el->fd = client->fd;
            ret = hashmap_put(client_id_map, cid_el->key, cid_el);
            assert(ret == HMAP_S_OK);

            RTS_printf("[++登录成功++]: NAME:%s--IP:%s\n", _rts_transport_data.name, inet_ntoa(c_el->addr.sin_addr));
            bzero(buf, MAX_BUF + 1);
            sprintf(buf, "{\"code\":\"0000\",\"message\":\"登录成功\",\"token\":\"%s\",\"id\":%d}", _rts_transport_data.token, _rts_user->id);
            client_send(client, buf);

            //修改登录成功标识
            _RTS_USER _rts_user2 = user_init();
            _rts_user2.id = _rts_user->id;
            _rts_user2.status = 1;
            user_edit(_rts_user2);

            CLIENT_FREE(pwdhash);
            CLIENT_FREE(_rts_user);

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 1;
        }

        client_send(client, "{\"code\":\"1003\",\"message\":\"该用户已经在其他地方成功登录\"}");
        CLIENT_FREE(pwdhash);
        CLIENT_FREE(_rts_user);

        /*解锁锁*/
        if (pthread_mutex_unlock(&mutex) != 0) {
            perror("pthread_mutex_unlock");
            exit(EXIT_FAILURE);
        }

        return 1;

    }

    if (strcmp(_rts_transport_data.action, "message") == 0) { //聊天
        if (strlen(_rts_transport_data.token) == 0 || !_rts_transport_data.toid || !_rts_transport_data.id || wcslen(_rts_transport_data.content) == 0) {
            client_send(client, "{\"code\":\"0005\",\"message\":\"参数非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        //认证信息失败,退出客户端
        if (!c_el->token || (strcmp(_rts_transport_data.token, "bsh_test_$%1KP@'") != 0 && strcmp(_rts_transport_data.token, c_el->token) != 0)) {
            client_send(client, "{\"code\":\"0004\",\"message\":\"token非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        //判断登录者身份
        if (!c_el->id || c_el->id != _rts_transport_data.id) {
            client_send(client, "{\"code\":\"0006\",\"message\":\"用户身份非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        bzero(key, 20);
        sprintf(key, "%d", _rts_transport_data.toid);
        client_id_elem *cid_el;
        ret = hashmap_get(client_id_map, key, (void **)&cid_el);
        

        printf("发给id:%s\n", key);
        if (ret == 0) {
            printf("get_toid:%s ret:%d fd:%d\n", key, ret, cid_el->fd);
        }
        if (ret == HMAP_E_NOTFOUND || !cid_el || !cid_el->fd) {
            client_send(client, "{\"code\":\"1002\",\"message\":\"对方不在线\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 1;
        }

        bzero(key, 20);
        sprintf(key, "%d", cid_el->fd);
        client_elem *to_c_el;
        ret = hashmap_get(client_map, key, (void **)&to_c_el);
        assert(ret == HMAP_S_OK);

        if (to_c_el->id == _rts_transport_data.id) { //如果接受者是自己,则发出警告
            client_send(client, "{\"code\":\"1001\",\"message\":\"不能给自己发消息\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 1;
        }

        bzero(buf, MAX_BUF + 1);
        sprintf(buf, "{\"code\":\"0000\",\"message\":\"发送成功\",\"content\":\"%ls\"}", _rts_transport_data.content);
        client_send(to_c_el->client, buf);

        /*解锁锁*/
        if (pthread_mutex_unlock(&mutex) != 0) {
            perror("pthread_mutex_unlock");
            exit(EXIT_FAILURE);
        }

        return 1;
    }

    if (strcmp(_rts_transport_data.action, "logout") == 0) { //logout
        if (strlen(_rts_transport_data.token) == 0 || !_rts_transport_data.id) {
            client_send(client, "{\"code\":\"0005\",\"message\":\"参数非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        //判断登录者身份
        if (!c_el->id || c_el->id != _rts_transport_data.id) {
            client_send(client, "{\"code\":\"0006\",\"message\":\"用户身份非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        //认证信息失败,退出客户端
        if (c_el->token && strcmp(_rts_transport_data.token, c_el->token) != 0) {
            client_send(client, "{\"code\":\"0004\",\"message\":\"token非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        client_send(client, "{\"code\":\"0000\",\"message\":\"退出成功\"}");

        /*解锁锁*/
        if (pthread_mutex_unlock(&mutex) != 0) {
            perror("pthread_mutex_unlock");
            exit(EXIT_FAILURE);
        }

        return 0;
    }

    if (strcmp(_rts_transport_data.action, "register") == 0) {
        if (strlen(_rts_transport_data.name) == 0 || strlen(_rts_transport_data.password) == 0) {
            client_send(client, "{\"code\":\"0005\",\"message\":\"参数非法\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 0;
        }

        char *salt = RTS_rand();
        char *pwdhash = RTS_hash(_rts_transport_data.password, salt);
        char *datetime = RTS_current_datetime();
        _rts_transport_data.id = user_add(_rts_transport_data.name, pwdhash, salt, inet_ntoa(c_el->addr.sin_addr), datetime, 0);
        CLIENT_FREE(salt);
        CLIENT_FREE(pwdhash);
        CLIENT_FREE(datetime);

        if (_rts_transport_data.id == 0) {
            client_send(client, "{\"code\":\"1005\",\"message\":\"注册失败,该用户名已注册\"}");

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 1;
        }

        if (_rts_transport_data.id > 0) {
            bzero(buf, MAX_BUF + 1);
            sprintf(buf, "{\"code\":\"0000\",\"message\":\"注册成功\",\"id\":%d}", _rts_transport_data.id);
            client_send(client, buf);

            /*解锁锁*/
            if (pthread_mutex_unlock(&mutex) != 0) {
                perror("pthread_mutex_unlock");
                exit(EXIT_FAILURE);
            }

            return 1;
        }

        client_send(client, "{\"code\":\"0007\",\"message\":\"注册失败,未知错误\"}");

        /*解锁锁*/
        if (pthread_mutex_unlock(&mutex) != 0) {
            perror("pthread_mutex_unlock");
            exit(EXIT_FAILURE);
        }

        return 1;
    }

    client_send(client, "{\"code\":\"0002\",\"message\":\"动作非法\"}");

    /*解锁锁*/
    if (pthread_mutex_unlock(&mutex) != 0) {
        perror("pthread_mutex_unlock");
        exit(EXIT_FAILURE);
    }

    return 0;
}
Пример #21
0
static int parse_line(const char *fname, unsigned line, const char *buffer) {
        Item *i, *existing;
        char *mode = NULL, *user = NULL, *group = NULL, *age = NULL;
        char type;
        Hashmap *h;
        int r, n = -1;

        assert(fname);
        assert(line >= 1);
        assert(buffer);

        i = new0(Item, 1);
        if (!i) {
                log_error("Out of memory");
                return -ENOMEM;
        }

        if (sscanf(buffer,
                   "%c "
                   "%ms "
                   "%ms "
                   "%ms "
                   "%ms "
                   "%ms "
                   "%n",
                   &type,
                   &i->path,
                   &mode,
                   &user,
                   &group,
                   &age,
                   &n) < 2) {
                log_error("[%s:%u] Syntax error.", fname, line);
                r = -EIO;
                goto finish;
        }

        if (n >= 0)  {
                n += strspn(buffer+n, WHITESPACE);
                if (buffer[n] != 0 && (buffer[n] != '-' || buffer[n+1] != 0)) {
                        i->argument = unquote(buffer+n, "\"");
                        if (!i->argument) {
                                log_error("Out of memory");
                                return -ENOMEM;
                        }
                }
        }

        switch(type) {

        case CREATE_FILE:
        case TRUNCATE_FILE:
        case CREATE_DIRECTORY:
        case TRUNCATE_DIRECTORY:
        case CREATE_FIFO:
        case IGNORE_PATH:
        case REMOVE_PATH:
        case RECURSIVE_REMOVE_PATH:
        case RELABEL_PATH:
        case RECURSIVE_RELABEL_PATH:
                break;

        case CREATE_SYMLINK:
                if (!i->argument) {
                        log_error("[%s:%u] Symlink file requires argument.", fname, line);
                        r = -EBADMSG;
                        goto finish;
                }
                break;

        case WRITE_FILE:
                if (!i->argument) {
                        log_error("[%s:%u] Write file requires argument.", fname, line);
                        r = -EBADMSG;
                        goto finish;
                }
                break;

        case CREATE_CHAR_DEVICE:
        case CREATE_BLOCK_DEVICE: {
                unsigned major, minor;

                if (!i->argument) {
                        log_error("[%s:%u] Device file requires argument.", fname, line);
                        r = -EBADMSG;
                        goto finish;
                }

                if (sscanf(i->argument, "%u:%u", &major, &minor) != 2) {
                        log_error("[%s:%u] Can't parse device file major/minor '%s'.", fname, line, i->argument);
                        r = -EBADMSG;
                        goto finish;
                }

                i->major_minor = makedev(major, minor);
                break;
        }

        default:
                log_error("[%s:%u] Unknown file type '%c'.", fname, line, type);
                r = -EBADMSG;
                goto finish;
        }

        i->type = type;

        if (!path_is_absolute(i->path)) {
                log_error("[%s:%u] Path '%s' not absolute.", fname, line, i->path);
                r = -EBADMSG;
                goto finish;
        }

        path_kill_slashes(i->path);

        if (arg_prefix && !path_startswith(i->path, arg_prefix)) {
                r = 0;
                goto finish;
        }

        if (user && !streq(user, "-")) {
                const char *u = user;

                r = get_user_creds(&u, &i->uid, NULL, NULL, NULL);
                if (r < 0) {
                        log_error("[%s:%u] Unknown user '%s'.", fname, line, user);
                        goto finish;
                }

                i->uid_set = true;
        }

        if (group && !streq(group, "-")) {
                const char *g = group;

                r = get_group_creds(&g, &i->gid);
                if (r < 0) {
                        log_error("[%s:%u] Unknown group '%s'.", fname, line, group);
                        goto finish;
                }

                i->gid_set = true;
        }

        if (mode && !streq(mode, "-")) {
                unsigned m;

                if (sscanf(mode, "%o", &m) != 1) {
                        log_error("[%s:%u] Invalid mode '%s'.", fname, line, mode);
                        r = -ENOENT;
                        goto finish;
                }

                i->mode = m;
                i->mode_set = true;
        } else
                i->mode =
                        i->type == CREATE_DIRECTORY ||
                        i->type == TRUNCATE_DIRECTORY ? 0755 : 0644;

        if (age && !streq(age, "-")) {
                const char *a = age;

                if (*a == '~') {
                        i->keep_first_level = true;
                        a++;
                }

                if (parse_usec(a, &i->age) < 0) {
                        log_error("[%s:%u] Invalid age '%s'.", fname, line, age);
                        r = -EBADMSG;
                        goto finish;
                }

                i->age_set = true;
        }

        h = needs_glob(i->type) ? globs : items;

        existing = hashmap_get(h, i->path);
        if (existing) {

                /* Two identical items are fine */
                if (!item_equal(existing, i))
                        log_warning("Two or more conflicting lines for %s configured, ignoring.", i->path);

                r = 0;
                goto finish;
        }

        r = hashmap_put(h, i->path, i);
        if (r < 0) {
                log_error("Failed to insert item %s: %s", i->path, strerror(-r));
                goto finish;
        }

        i = NULL;
        r = 0;

finish:
        free(user);
        free(group);
        free(mode);
        free(age);

        if (i)
                item_free(i);

        return r;
}
Пример #22
0
//(DEV_UID *dev_uid, uint32_t device_type, uint32_t device_number)
device_t* ressource_open(DEV_UID *virt_dev_uid, int32_t device_type, int32_t device_number){
	//DEV_UID* real_UID = malloc(sizeof(DEV_UID));
	DEV_UID* temp_UID = malloc(sizeof(DEV_UID));
	virtual_dev_t *virtual_dev = (virtual_dev_t*)malloc(sizeof(virtual_dev_t));
	virtual_dev->real_uid = (DEV_UID*)malloc(sizeof(DEV_UID));
	virtual_dev_t *virtual_temp = NULL;
	device_t* device;
	any_t tmp;

	// virtual_devic zusammen bauen

	switch(device_type){
		case(AP7000_UART_DEVICE):

			device = open_driver(temp_UID, AP7000_UART_DEVICE, device_number);
			virtual_dev->requested_device_type = device;
			virtual_dev->vdev_rxbuf = malloc(sizeof(SerialBuffer));
			virtual_dev->vdev_txbuf = malloc(sizeof(SerialBuffer));
			SerialBuffer_ctor( (SerialBuffer*)(virtual_dev->vdev_rxbuf) );
			SerialBuffer_ctor( (SerialBuffer*)(virtual_dev->vdev_txbuf) );

			uart1_set_rx_and_tx_buffer((SerialBuffer*)virtual_dev->vdev_txbuf,(SerialBuffer*)virtual_dev->vdev_rxbuf);
			break;
		case(AP7000_LED_DEVICE):
			break;
		default:
			break;
	}

	switch (*temp_UID) {
		case DEV_NOT_FREE:
			//generate new virtual UID an add to map
			*virt_dev_uid = generate_Virtual_UID();
			//Find real uid in hashmap with key: device_type|device_number
			//hashmap_get(device_mapm)


			if(hashmap_get(device_to_real_uid_map,device_type|device_number,&tmp) == MAP_OK){
				*temp_UID = *((DEV_UID*)tmp);
				virtual_dev->real_uid = temp_UID;
			}else{
				while(1){}
			}

			if(hashmap_get(device_to_real_uid_map,device_type|device_number,&tmp) == MAP_OK){
				hashmap_put(virt_uid_to_virt_dev_map,*virt_dev_uid, virtual_dev);

			// save pid to virtual_dev
			hashmap_put(pid_to_virt_dev_map, ptrRunningTask->pid, virtual_dev);

			virtual_dev->current_device_type = dev_null;

			return device;

			}else{
				while(1){}
			}

		case DEV_NOT_FOUND:
			//TODO you're f****d...
			break;
	}

	*virt_dev_uid = generate_Virtual_UID();
	*virtual_dev->real_uid = *temp_UID;
	virtual_dev->current_device_type = virtual_dev->requested_device_type;
	//add as first element
	hashmap_put(device_to_real_uid_map,device_type|device_number,(any_t)temp_UID);

	if(hashmap_get(device_to_real_uid_map,device_type|device_number,&tmp) == MAP_OK){
		if(*temp_UID!=*(DEV_UID*)tmp){
			while(1){};
		}
		hashmap_put(virt_uid_to_virt_dev_map,*virt_dev_uid, virtual_dev);
	}else{
		while(1){}
	}


	// save pid to virtual_dev
	hashmap_put(pid_to_virt_dev_map, ptrRunningTask->pid, virtual_dev);

	return device;
}
Пример #23
0
void hashmap_sput(hashmap *hm, const char *key, void *value, unsigned int value_len) {
    hashmap_put(hm, key, strlen(key)+1, value, value_len);
}
Пример #24
0
int bus_verify_polkit_async(
                sd_bus *bus,
                Hashmap **registry,
                sd_bus_message *m,
                const char *action,
                bool interactive,
                sd_bus_error *error,
                sd_bus_message_handler_t callback,
                void *userdata) {

#ifdef ENABLE_POLKIT
        _cleanup_bus_message_unref_ sd_bus_message *pk = NULL;
        AsyncPolkitQuery *q;
        const char *sender;
#endif
        _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
        uid_t uid;
        int r;

        assert(bus);
        assert(registry);
        assert(m);
        assert(action);

#ifdef ENABLE_POLKIT
        q = hashmap_get(*registry, m);
        if (q) {
                int authorized, challenge;

                /* This is the second invocation of this function, and
                 * there's already a response from polkit, let's
                 * process it */
                assert(q->reply);

                if (sd_bus_message_is_method_error(q->reply, NULL)) {
                        const sd_bus_error *e;

                        /* Copy error from polkit reply */
                        e = sd_bus_message_get_error(q->reply);
                        sd_bus_error_copy(error, e);

                        /* Treat no PK available as access denied */
                        if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN))
                                return -EACCES;

                        return sd_bus_error_get_errno(e);
                }

                r = sd_bus_message_enter_container(q->reply, 'r', "bba{ss}");
                if (r >= 0)
                        r = sd_bus_message_read(q->reply, "bb", &authorized, &challenge);

                if (r < 0)
                        return r;

                if (authorized)
                        return 1;

                return -EACCES;
        }
#endif

        r = sd_bus_query_sender_creds(m, SD_BUS_CREDS_UID, &creds);
        if (r < 0)
                return r;

        r = sd_bus_creds_get_uid(creds, &uid);
        if (r < 0)
                return r;

        if (uid == 0)
                return 1;

#ifdef ENABLE_POLKIT
        sender = sd_bus_message_get_sender(m);
        if (!sender)
                return -EBADMSG;

        r = hashmap_ensure_allocated(registry, trivial_hash_func, trivial_compare_func);
        if (r < 0)
                return r;

        r = sd_bus_message_new_method_call(
                        bus,
                        "org.freedesktop.PolicyKit1",
                        "/org/freedesktop/PolicyKit1/Authority",
                        "org.freedesktop.PolicyKit1.Authority",
                        "CheckAuthorization",
                        &pk);
        if (r < 0)
                return r;

        r = sd_bus_message_append(
                        pk,
                        "(sa{sv})sa{ss}us",
                        "system-bus-name", 1, "name", "s", sender,
                        action,
                        0,
                        interactive ? 1 : 0,
                        NULL);
        if (r < 0)
                return r;

        q = new0(AsyncPolkitQuery, 1);
        if (!q)
                return -ENOMEM;

        q->request = sd_bus_message_ref(m);
        q->callback = callback;
        q->userdata = userdata;

        r = hashmap_put(*registry, m, q);
        if (r < 0) {
                async_polkit_query_free(bus, q);
                return r;
        }

        q->registry = *registry;

        r = sd_bus_call_async(bus, pk, async_polkit_callback, q, 0, &q->serial);
        if (r < 0) {
                async_polkit_query_free(bus, q);
                return r;
        }

        return 0;
#endif

        return -EACCES;
}
Пример #25
0
int set_put(Set *s, void *value) {
        return hashmap_put(MAKE_HASHMAP(s), value, value);
}
Пример #26
0
int main(int argc, char *argv[]) {
        int ret = EXIT_FAILURE;
        FILE *f = NULL;
        struct mntent* me;
        Hashmap *pids = NULL;

        if (argc > 1) {
                log_error("This program takes no argument.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_SYSLOG_OR_KMSG);
        log_parse_environment();
        log_open();

        umask(0022);

        if (!(f = setmntent("/etc/fstab", "r"))) {
                log_error("Failed to open /etc/fstab: %m");
                goto finish;
        }

        if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
                log_error("Failed to allocate set");
                goto finish;
        }

        ret = EXIT_SUCCESS;

        while ((me = getmntent(f))) {
                pid_t pid;
                int k;
                char *s;

                if (!mount_point_is_api(me->mnt_dir))
                        continue;

                log_debug("Remounting %s", me->mnt_dir);

                if ((pid = fork()) < 0) {
                        log_error("Failed to fork: %m");
                        ret = 1;
                        continue;
                }

                if (pid == 0) {
                        const char *arguments[5];
                        /* Child */

                        arguments[0] = "/bin/mount";
                        arguments[1] = me->mnt_dir;
                        arguments[2] = "-o";
                        arguments[3] = "remount";
                        arguments[4] = NULL;

                        execv("/bin/mount", (char **) arguments);

                        log_error("Failed to execute /bin/mount: %m");
                        _exit(EXIT_FAILURE);
                }

                /* Parent */

                s = strdup(me->mnt_dir);

                if ((k = hashmap_put(pids, UINT_TO_PTR(pid), s)) < 0) {
                        log_error("Failed to add PID to set: %s", strerror(-k));
                        ret = EXIT_FAILURE;
                        continue;
                }
        }

        while (!hashmap_isempty(pids)) {
                siginfo_t si;
                char *s;

                zero(si);
                if (waitid(P_ALL, 0, &si, WEXITED) < 0) {

                        if (errno == EINTR)
                                continue;

                        log_error("waitid() failed: %m");
                        ret = EXIT_FAILURE;
                        break;
                }

                if ((s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
                        if (!is_clean_exit(si.si_code, si.si_status)) {
                                if (si.si_code == CLD_EXITED)
                                        log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
                                else
                                        log_error("/bin/mount for %s terminated by signal %s.", s, signal_to_string(si.si_status));

                                ret = EXIT_FAILURE;
                        }

                        free(s);
                }
        }

finish:

        if (pids)
                hashmap_free_free(pids);

        if (f)
                endmntent(f);

        return ret;
}
Пример #27
0
static void init_backend(BuxtonConfig *config,
			 BuxtonLayer *layer,
			 BuxtonBackend **backend)
{
	void *handle, *cast;
	_cleanup_free_ char *path = NULL;
	const char *name;
	char *error;
	int r;
	bool rb;
	module_init_func i_func;
	module_destroy_func d_func;
	BuxtonBackend *backend_tmp;

	assert(layer);
	assert(backend);

	if (layer->backend == BACKEND_GDBM) {
		name = "gdbm";
	} else if (layer->backend == BACKEND_MEMORY) {
		name = "memory";
	} else {
		buxton_log("Invalid backend type for layer: %s\n", layer->name);
		abort();
	}

	backend_tmp = hashmap_get(config->backends, name);

	if (backend_tmp) {
		*backend = backend_tmp;
		return;
	}

	backend_tmp = malloc0(sizeof(BuxtonBackend));
	if (!backend_tmp) {
		abort();
	}

	r = asprintf(&path, "%s/%s.so", buxton_module_dir(), name);
	if (r == -1) {
		abort();
	}

	/* Load the module */
	handle = dlopen(path, RTLD_LAZY);

	if (!handle) {
		buxton_log("dlopen(): %s\n", dlerror());
		abort();
	}

	dlerror();
	cast = dlsym(handle, "buxton_module_init");
	if ((error = dlerror()) != NULL || !cast) {
		buxton_log("dlsym(): %s\n", error);
		abort();
	}
	memcpy(&i_func, &cast, sizeof(i_func));
	dlerror();

	cast = dlsym(handle, "buxton_module_destroy");
	if ((error = dlerror()) != NULL || !cast) {
		buxton_log("dlsym(): %s\n", error);
		abort();
	}
	memcpy(&d_func, &cast, sizeof(d_func));

	rb = i_func(backend_tmp);
	if (!rb) {
		buxton_log("buxton_module_init failed\n");
		abort();
	}

	if (!config->backends) {
		config->backends = hashmap_new(trivial_hash_func, trivial_compare_func);
		if (!config->backends) {
			abort();
		}
	}

	r = hashmap_put(config->backends, name, backend_tmp);
	if (r != 1) {
		abort();
	}

	backend_tmp->module = handle;
	backend_tmp->destroy = d_func;

	*backend = backend_tmp;
}
Пример #28
0
Файл: repl.c Проект: ohnx/leo
int main() {
    char *o, *p, *line;
    queue *q;
    double *r, *s;
    double *pi = malloc(sizeof(double));
    double *e  = malloc(sizeof(double));
    double *ans = malloc(sizeof(double));

    *pi = 3.1415926535;
    *e  = 2.7182818285;
    *ans = 0;

    hm = hashmap_new();
    hashmap_put(hm, "pi", pi);
    hashmap_put(hm, "e", e);
    hashmap_put(hm, "ans", ans);

    /* read input using linenoise */
    while((line = linenoise("> ")) != NULL) {
        /* add the line to history */
        linenoiseHistoryAdd(line);

        /* check if there is an equals sign */
        for (p = line; (*p != '\0') && (*p != '='); p++);
        if (*p == '\0') p = line;
        else { /* equals sign present */
            /* check for spaces */
            for (o = line; (*o != ' ') && (*o != '='); o++);
            *o = '\0';

            p++; /* skip equals sign when parsing equation */
        }

        q = syard_run(p);
        if (q == NULL) continue;
#ifdef __DEBUG
        queue_foreach(q, testfunc, NULL);
        printf("\n");
#endif

        r = rpn_calc(q, variable_resolver, func_wl);
        if (r == NULL) continue;

        printf("= %g\n", *r);

        /* store ans */
        *ans = *r;

        if (p != line) {
            /* equals sign present */
            if ((s = hashmap_get(hm, line)) != NULL) {
                /* existing value, just overwrite it */
                *s = *r;
                free(r);
            } else {
                /* new value */
                hashmap_put(hm, line, r);
            }
        } else {
            /* no equals sign, so we're done with the number now */
            free(r);
        }

        /* free storage and stuff */
        linenoiseFree(line);
    }

    hashmap_iterate(hm, hm_cleaner, NULL);
    hashmap_destroy(hm);
    return 0;
}
Пример #29
0
static int enumerate_dir_d(Hashmap *top, Hashmap *bottom, Hashmap *drops, const char *toppath, const char *drop) {
        _cleanup_free_ char *unit = NULL;
        _cleanup_free_ char *path = NULL;
        _cleanup_strv_free_ char **list = NULL;
        char **file;
        char *c;
        int r;

        assert(!endswith(drop, "/"));

        path = strjoin(toppath, "/", drop);
        if (!path)
                return -ENOMEM;

        log_debug("Looking at %s", path);

        unit = strdup(drop);
        if (!unit)
                return -ENOMEM;

        c = strrchr(unit, '.');
        if (!c)
                return -EINVAL;
        *c = 0;

        r = get_files_in_directory(path, &list);
        if (r < 0)
                return log_error_errno(r, "Failed to enumerate %s: %m", path);

        STRV_FOREACH(file, list) {
                Hashmap *h;
                int k;
                char *p;
                char *d;

                if (!endswith(*file, ".conf"))
                        continue;

                p = strjoin(path, "/", *file);
                if (!p)
                        return -ENOMEM;
                d = p + strlen(toppath) + 1;

                log_debug("Adding at top: %s %s %s", d, special_glyph(ARROW), p);
                k = hashmap_put(top, d, p);
                if (k >= 0) {
                        p = strdup(p);
                        if (!p)
                                return -ENOMEM;
                        d = p + strlen(toppath) + 1;
                } else if (k != -EEXIST) {
                        free(p);
                        return k;
                }

                log_debug("Adding at bottom: %s %s %s", d, special_glyph(ARROW), p);
                free(hashmap_remove(bottom, d));
                k = hashmap_put(bottom, d, p);
                if (k < 0) {
                        free(p);
                        return k;
                }

                h = hashmap_get(drops, unit);
                if (!h) {
                        h = hashmap_new(&string_hash_ops);
                        if (!h)
                                return -ENOMEM;
                        hashmap_put(drops, unit, h);
                        unit = strdup(unit);
                        if (!unit)
                                return -ENOMEM;
                }

                p = strdup(p);
                if (!p)
                        return -ENOMEM;

                log_debug("Adding to drops: %s %s %s %s %s",
                          unit, special_glyph(ARROW), basename(p), special_glyph(ARROW), p);
                k = hashmap_put(h, basename(p), p);
                if (k < 0) {
                        free(p);
                        if (k != -EEXIST)
                                return k;
                }
        }
Пример #30
0
static int do_execute(
                char **directories,
                usec_t timeout,
                gather_stdout_callback_t const callbacks[_STDOUT_CONSUME_MAX],
                void* const callback_args[_STDOUT_CONSUME_MAX],
                int output_fd,
                char *argv[],
                char *envp[],
                ExecDirFlags flags) {

        _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
        _cleanup_strv_free_ char **paths = NULL;
        char **path, **e;
        int r;
        bool parallel_execution;

        /* We fork this all off from a child process so that we can somewhat cleanly make
         * use of SIGALRM to set a time limit.
         *
         * We attempt to perform parallel execution if configured by the user, however
         * if `callbacks` is nonnull, execution must be serial.
         */
        parallel_execution = FLAGS_SET(flags, EXEC_DIR_PARALLEL) && !callbacks;

        r = conf_files_list_strv(&paths, NULL, NULL, CONF_FILES_EXECUTABLE|CONF_FILES_REGULAR|CONF_FILES_FILTER_MASKED, (const char* const*) directories);
        if (r < 0)
                return log_error_errno(r, "Failed to enumerate executables: %m");

        if (parallel_execution) {
                pids = hashmap_new(NULL);
                if (!pids)
                        return log_oom();
        }

        /* Abort execution of this process after the timout. We simply rely on SIGALRM as
         * default action terminating the process, and turn on alarm(). */

        if (timeout != USEC_INFINITY)
                alarm(DIV_ROUND_UP(timeout, USEC_PER_SEC));

        STRV_FOREACH(e, envp)
                if (putenv(*e) != 0)
                        return log_error_errno(errno, "Failed to set environment variable: %m");

        STRV_FOREACH(path, paths) {
                _cleanup_free_ char *t = NULL;
                _cleanup_close_ int fd = -1;
                pid_t pid;

                t = strdup(*path);
                if (!t)
                        return log_oom();

                if (callbacks) {
                        fd = open_serialization_fd(basename(*path));
                        if (fd < 0)
                                return log_error_errno(fd, "Failed to open serialization file: %m");
                }

                r = do_spawn(t, argv, fd, &pid);
                if (r <= 0)
                        continue;

                if (parallel_execution) {
                        r = hashmap_put(pids, PID_TO_PTR(pid), t);
                        if (r < 0)
                                return log_oom();
                        t = NULL;
                } else {
                        r = wait_for_terminate_and_check(t, pid, WAIT_LOG);
                        if (FLAGS_SET(flags, EXEC_DIR_IGNORE_ERRORS)) {
                                if (r < 0)
                                        continue;
                        } else if (r > 0)
                                return r;

                        if (callbacks) {
                                if (lseek(fd, 0, SEEK_SET) < 0)
                                        return log_error_errno(errno, "Failed to seek on serialization fd: %m");

                                r = callbacks[STDOUT_GENERATE](fd, callback_args[STDOUT_GENERATE]);
                                fd = -1;
                                if (r < 0)
                                        return log_error_errno(r, "Failed to process output from %s: %m", *path);
                        }
                }
        }