- if (num_clients >= MAX_STAT_CLIENTS) {
- PARA_ERROR_LOG("maximal number of stat clients (%d) exceeded\n",
- MAX_STAT_CLIENTS);
- return -E_TOO_MANY_CLIENTS;
- }
- if (!initialized) {
- INIT_LIST_HEAD(&client_list);
- initialized = 1;
- }
- PARA_INFO_LOG("adding client on fd %d\n", fd);
- new_client = para_calloc(sizeof(struct stat_client));
- new_client->fd = fd;
- new_client->item_mask = mask;
- if (parser_friendly)
- new_client->flags = SCF_PARSER_FRIENDLY;
- para_list_add(&new_client->node, &client_list);
- dump_stat_client_list();
- num_clients++;
- return 1;
-}
-/**
- * Write a message to all connected status clients.
- *
- * \param item_num The number of the status item of \a msg.
- *
- * On write errors, remove the status client from the client list and close its
- * file descriptor.
- */
-void stat_client_write_item(int item_num)
-{
- struct stat_client *sc, *tmp;
- struct para_buffer pb = {.flags = 0};
- struct para_buffer pfpb = {.flags = PBF_SIZE_PREFIX};
- const uint64_t one = 1;
-
- if (!initialized)
- return;
- list_for_each_entry_safe(sc, tmp, &client_list, node) {
- int fd = sc->fd, ret;
-
- if (!((one << item_num) & sc->item_mask))
- continue;
- if (write_ok(fd) > 0) {
- struct para_buffer *b =
- (sc->flags & SCF_PARSER_FRIENDLY)? &pfpb : &pb;
- char *msg = stat_item_values[item_num];
- if (!b->buf)
- WRITE_STATUS_ITEM(b, item_num, "%s\n",
- msg? msg : "");
- ret = write(fd, b->buf, b->offset);
- if (ret == b->offset)
- continue;
- }
- /* write error or fd not ready for writing */
- close(fd);
- num_clients--;
- PARA_INFO_LOG("deleting client on fd %d\n", fd);
- list_del(&sc->node);
- free(sc);
- dump_stat_client_list();
- }
- free(pb.buf);
- free(pfpb.buf);
-// if (num_clients)
-// PARA_DEBUG_LOG("%d client(s)\n", num_clients);
-}
-
-/**
- * Check if string is a known status item.
- *
- * \param item Buffer containing the text to check.
- *
- * \return If \a item is a valid status item, the number of that status item is
- * returned. Otherwise, this function returns \p -E_UNKNOWN_STAT_ITEM.
- */
-int stat_item_valid(const char *item)
-{
- int i;
- if (!item || !*item) {
- PARA_ERROR_LOG("%s\n", "no item");
- return -E_UNKNOWN_STAT_ITEM;
- }
- FOR_EACH_STATUS_ITEM(i)
- if (!strcmp(status_item_list[i], item))
- return i;
- PARA_ERROR_LOG("invalid stat item: %s\n", item);
- return -E_UNKNOWN_STAT_ITEM;
-}