/* -*- mode: c; c-file-style: "openbsd" -*- */ /* * Copyright (c) 2015 Vincent Bernat * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include #include #include #include #include "../lldpctl.h" #include "../../log.h" #include "../atom.h" #include "../helpers.h" static int _lldpctl_atom_new_interfaces_list(lldpctl_atom_t *atom, va_list ap) { struct _lldpctl_atom_interfaces_list_t *iflist = (struct _lldpctl_atom_interfaces_list_t *)atom; iflist->ifs = va_arg(ap, struct lldpd_interface_list *); return 1; } static void _lldpctl_atom_free_interfaces_list(lldpctl_atom_t *atom) { struct _lldpctl_atom_interfaces_list_t *iflist = (struct _lldpctl_atom_interfaces_list_t *)atom; struct lldpd_interface *iface, *iface_next; for (iface = TAILQ_FIRST(iflist->ifs); iface != NULL; iface = iface_next) { /* Don't TAILQ_REMOVE, this is not a real list! */ iface_next = TAILQ_NEXT(iface, next); free(iface->name); free(iface); } free(iflist->ifs); } static lldpctl_atom_iter_t * _lldpctl_atom_iter_interfaces_list(lldpctl_atom_t *atom) { struct _lldpctl_atom_interfaces_list_t *iflist = (struct _lldpctl_atom_interfaces_list_t *)atom; return (lldpctl_atom_iter_t *)TAILQ_FIRST(iflist->ifs); } static lldpctl_atom_iter_t * _lldpctl_atom_next_interfaces_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) { return (lldpctl_atom_iter_t *)TAILQ_NEXT((struct lldpd_interface *)iter, next); } static lldpctl_atom_t * _lldpctl_atom_value_interfaces_list(lldpctl_atom_t *atom, lldpctl_atom_iter_t *iter) { struct lldpd_interface *iface = (struct lldpd_interface *)iter; return _lldpctl_new_atom(atom->conn, atom_interface, iface->name); } static int _lldpctl_atom_new_interface(lldpctl_atom_t *atom, va_list ap) { struct _lldpctl_atom_interface_t *port = (struct _lldpctl_atom_interface_t *)atom; port->name = strdup(va_arg(ap, char *)); return (port->name != NULL); } static void _lldpctl_atom_free_interface(lldpctl_atom_t *atom) { struct _lldpctl_atom_interface_t *port = (struct _lldpctl_atom_interface_t *)atom; free(port->name); } static const char * _lldpctl_atom_get_str_interface(lldpctl_atom_t *atom, lldpctl_key_t key) { struct _lldpctl_atom_interface_t *port = (struct _lldpctl_atom_interface_t *)atom; switch (key) { case lldpctl_k_interface_name: return port->name; default: SET_ERROR(atom->conn, LLDPCTL_ERR_NOT_EXIST); return NULL; } } static struct atom_builder interfaces_list = { atom_interfaces_list, sizeof(struct _lldpctl_atom_interfaces_list_t), .init = _lldpctl_atom_new_interfaces_list, .free = _lldpctl_atom_free_interfaces_list, .iter = _lldpctl_atom_iter_interfaces_list, .next = _lldpctl_atom_next_interfaces_list, .value = _lldpctl_atom_value_interfaces_list }; static struct atom_builder interface = { atom_interface, sizeof(struct _lldpctl_atom_interface_t), .init = _lldpctl_atom_new_interface, .free = _lldpctl_atom_free_interface, .get_str = _lldpctl_atom_get_str_interface }; ATOM_BUILDER_REGISTER(interfaces_list, 2); ATOM_BUILDER_REGISTER(interface, 3);