LCOV - code coverage report
Current view: top level - source3/lib - avahi.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 0 116 0.0 %
Date: 2021-09-23 10:06:22 Functions: 0 11 0.0 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Connect avahi to lib/tevents
       4             :    Copyright (C) Volker Lendecke 2009
       5             : 
       6             :    This program is free software; you can redistribute it and/or modify
       7             :    it under the terms of the GNU General Public License as published by
       8             :    the Free Software Foundation; either version 3 of the License, or
       9             :    (at your option) any later version.
      10             : 
      11             :    This program is distributed in the hope that it will be useful,
      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14             :    GNU General Public License for more details.
      15             : 
      16             :    You should have received a copy of the GNU General Public License
      17             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      18             : */
      19             : 
      20             : #include "includes.h"
      21             : 
      22             : #include <avahi-common/watch.h>
      23             : 
      24             : struct avahi_poll_context {
      25             :         struct tevent_context *ev;
      26             :         AvahiWatch **watches;
      27             :         AvahiTimeout **timeouts;
      28             : };
      29             : 
      30             : struct AvahiWatch {
      31             :         struct avahi_poll_context *ctx;
      32             :         struct tevent_fd *fde;
      33             :         int fd;
      34             :         AvahiWatchEvent latest_event;
      35             :         AvahiWatchCallback callback;
      36             :         void *userdata;
      37             : };
      38             : 
      39             : struct AvahiTimeout {
      40             :         struct avahi_poll_context *ctx;
      41             :         struct tevent_timer *te;
      42             :         AvahiTimeoutCallback callback;
      43             :         void *userdata;
      44             : };
      45             : 
      46           0 : static uint16_t avahi_flags_map_to_tevent(AvahiWatchEvent event)
      47             : {
      48           0 :         return ((event & AVAHI_WATCH_IN) ? TEVENT_FD_READ : 0)
      49           0 :                 | ((event & AVAHI_WATCH_OUT) ? TEVENT_FD_WRITE : 0);
      50             : }
      51             : 
      52             : static void avahi_fd_handler(struct tevent_context *ev,
      53             :                              struct tevent_fd *fde, uint16_t flags,
      54             :                              void *private_data);
      55             : 
      56           0 : static AvahiWatch *avahi_watch_new(const AvahiPoll *api, int fd,
      57             :                                    AvahiWatchEvent event,
      58             :                                    AvahiWatchCallback callback,
      59             :                                    void *userdata)
      60             : {
      61           0 :         struct avahi_poll_context *ctx = talloc_get_type_abort(
      62             :                 api->userdata, struct avahi_poll_context);
      63           0 :         int num_watches = talloc_array_length(ctx->watches);
      64             :         AvahiWatch **tmp, *watch_ctx;
      65             : 
      66           0 :         tmp = talloc_realloc(ctx, ctx->watches, AvahiWatch *, num_watches + 1);
      67           0 :         if (tmp == NULL) {
      68           0 :                 return NULL;
      69             :         }
      70           0 :         ctx->watches = tmp;
      71             : 
      72           0 :         watch_ctx = talloc(tmp, AvahiWatch);
      73           0 :         if (watch_ctx == NULL) {
      74           0 :                 goto fail;
      75             :         }
      76           0 :         ctx->watches[num_watches] = watch_ctx;
      77             : 
      78           0 :         watch_ctx->ctx = ctx;
      79           0 :         watch_ctx->fde = tevent_add_fd(ctx->ev, watch_ctx, fd,
      80             :                                        avahi_flags_map_to_tevent(event),
      81             :                                        avahi_fd_handler, watch_ctx);
      82           0 :         if (watch_ctx->fde == NULL) {
      83           0 :                 goto fail;
      84             :         }
      85           0 :         watch_ctx->callback = callback;
      86           0 :         watch_ctx->userdata = userdata;
      87           0 :         return watch_ctx;
      88             : 
      89           0 :  fail:
      90           0 :         TALLOC_FREE(watch_ctx);
      91           0 :         ctx->watches = talloc_realloc(ctx, ctx->watches, AvahiWatch *,
      92             :                                       num_watches);
      93           0 :         return NULL;
      94             : }
      95             : 
      96           0 : static void avahi_fd_handler(struct tevent_context *ev,
      97             :                              struct tevent_fd *fde, uint16_t flags,
      98             :                              void *private_data)
      99             : {
     100           0 :         AvahiWatch *watch_ctx = talloc_get_type_abort(private_data, AvahiWatch);
     101             : 
     102           0 :         watch_ctx->latest_event =
     103           0 :                 ((flags & TEVENT_FD_READ) ? AVAHI_WATCH_IN : 0)
     104           0 :                 | ((flags & TEVENT_FD_WRITE) ? AVAHI_WATCH_OUT : 0);
     105             : 
     106           0 :         watch_ctx->callback(watch_ctx, watch_ctx->fd, watch_ctx->latest_event,
     107             :                             watch_ctx->userdata);
     108           0 : }
     109             : 
     110           0 : static void avahi_watch_update(AvahiWatch *w, AvahiWatchEvent event)
     111             : {
     112           0 :         tevent_fd_set_flags(w->fde, avahi_flags_map_to_tevent(event));
     113           0 : }
     114             : 
     115           0 : static AvahiWatchEvent avahi_watch_get_events(AvahiWatch *w)
     116             : {
     117           0 :         return w->latest_event;
     118             : }
     119             : 
     120           0 : static void avahi_watch_free(AvahiWatch *w)
     121             : {
     122             :         int i, num_watches;
     123           0 :         AvahiWatch **watches = w->ctx->watches;
     124             :         struct avahi_poll_context *ctx;
     125             : 
     126           0 :         num_watches = talloc_array_length(watches);
     127             : 
     128           0 :         for (i=0; i<num_watches; i++) {
     129           0 :                 if (w == watches[i]) {
     130           0 :                         break;
     131             :                 }
     132             :         }
     133           0 :         if (i == num_watches) {
     134           0 :                 return;
     135             :         }
     136           0 :         ctx = w->ctx;
     137           0 :         TALLOC_FREE(w);
     138           0 :         memmove(&watches[i], &watches[i+1],
     139           0 :                 sizeof(*watches) * (num_watches - i - 1));
     140           0 :         ctx->watches = talloc_realloc(ctx, watches, AvahiWatch *,
     141             :                                       num_watches - 1);
     142             : }
     143             : 
     144             : static void avahi_timeout_handler(struct tevent_context *ev,
     145             :                                   struct tevent_timer *te,
     146             :                                   struct timeval current_time,
     147             :                                   void *private_data);
     148             : 
     149           0 : static AvahiTimeout *avahi_timeout_new(const AvahiPoll *api,
     150             :                                        const struct timeval *tv,
     151             :                                        AvahiTimeoutCallback callback,
     152             :                                        void *userdata)
     153             : {
     154           0 :         struct avahi_poll_context *ctx = talloc_get_type_abort(
     155             :                 api->userdata, struct avahi_poll_context);
     156           0 :         int num_timeouts = talloc_array_length(ctx->timeouts);
     157             :         AvahiTimeout **tmp, *timeout_ctx;
     158             : 
     159           0 :         tmp = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
     160             :                              num_timeouts + 1);
     161           0 :         if (tmp == NULL) {
     162           0 :                 return NULL;
     163             :         }
     164           0 :         ctx->timeouts = tmp;
     165             : 
     166           0 :         timeout_ctx = talloc(tmp, AvahiTimeout);
     167           0 :         if (timeout_ctx == NULL) {
     168           0 :                 goto fail;
     169             :         }
     170           0 :         ctx->timeouts[num_timeouts] = timeout_ctx;
     171             : 
     172           0 :         timeout_ctx->ctx = ctx;
     173           0 :         if (tv == NULL) {
     174           0 :                 timeout_ctx->te = NULL;
     175             :         } else {
     176           0 :                 timeout_ctx->te = tevent_add_timer(ctx->ev, timeout_ctx,
     177             :                                                    *tv, avahi_timeout_handler,
     178             :                                                    timeout_ctx);
     179           0 :                 if (timeout_ctx->te == NULL) {
     180           0 :                         goto fail;
     181             :                 }
     182             :         }
     183           0 :         timeout_ctx->callback = callback;
     184           0 :         timeout_ctx->userdata = userdata;
     185           0 :         return timeout_ctx;
     186             : 
     187           0 :  fail:
     188           0 :         TALLOC_FREE(timeout_ctx);
     189           0 :         ctx->timeouts = talloc_realloc(ctx, ctx->timeouts, AvahiTimeout *,
     190             :                                        num_timeouts);
     191           0 :         return NULL;
     192             : }
     193             : 
     194           0 : static void avahi_timeout_handler(struct tevent_context *ev,
     195             :                                   struct tevent_timer *te,
     196             :                                   struct timeval current_time,
     197             :                                   void *private_data)
     198             : {
     199           0 :         AvahiTimeout *timeout_ctx = talloc_get_type_abort(
     200             :                 private_data, AvahiTimeout);
     201             : 
     202           0 :         TALLOC_FREE(timeout_ctx->te);
     203           0 :         timeout_ctx->callback(timeout_ctx, timeout_ctx->userdata);
     204           0 : }
     205             : 
     206           0 : static void avahi_timeout_update(AvahiTimeout *t, const struct timeval *tv)
     207             : {
     208           0 :         TALLOC_FREE(t->te);
     209             : 
     210           0 :         if (tv == NULL) {
     211             :                 /*
     212             :                  * Disable this timer
     213             :                  */
     214           0 :                 return;
     215             :         }
     216             : 
     217           0 :         t->te = tevent_add_timer(t->ctx->ev, t, *tv, avahi_timeout_handler, t);
     218             :         /*
     219             :          * No failure mode defined here
     220             :          */
     221           0 :         SMB_ASSERT(t->te != NULL);
     222             : }
     223             : 
     224           0 : static void avahi_timeout_free(AvahiTimeout *t)
     225             : {
     226             :         int i, num_timeouts;
     227           0 :         AvahiTimeout **timeouts = t->ctx->timeouts;
     228             :         struct avahi_poll_context *ctx;
     229             : 
     230           0 :         num_timeouts = talloc_array_length(timeouts);
     231             : 
     232           0 :         for (i=0; i<num_timeouts; i++) {
     233           0 :                 if (t == timeouts[i]) {
     234           0 :                         break;
     235             :                 }
     236             :         }
     237           0 :         if (i == num_timeouts) {
     238           0 :                 return;
     239             :         }
     240           0 :         ctx = t->ctx;
     241           0 :         TALLOC_FREE(t);
     242           0 :         memmove(&timeouts[i], &timeouts[i+1],
     243           0 :                 sizeof(*timeouts) * (num_timeouts - i - 1));
     244           0 :         ctx->timeouts = talloc_realloc(ctx, timeouts, AvahiTimeout *,
     245             :                                        num_timeouts - 1);
     246             : }
     247             : 
     248           0 : struct AvahiPoll *tevent_avahi_poll(TALLOC_CTX *mem_ctx,
     249             :                                     struct tevent_context *ev)
     250             : {
     251             :         struct AvahiPoll *result;
     252             :         struct avahi_poll_context *ctx;
     253             : 
     254           0 :         result = talloc(mem_ctx, struct AvahiPoll);
     255           0 :         if (result == NULL) {
     256           0 :                 return result;
     257             :         }
     258           0 :         ctx = talloc_zero(result, struct avahi_poll_context);
     259           0 :         if (ctx == NULL) {
     260           0 :                 TALLOC_FREE(result);
     261           0 :                 return NULL;
     262             :         }
     263           0 :         ctx->ev = ev;
     264             : 
     265           0 :         result->watch_new            = avahi_watch_new;
     266           0 :         result->watch_update         = avahi_watch_update;
     267           0 :         result->watch_get_events     = avahi_watch_get_events;
     268           0 :         result->watch_free           = avahi_watch_free;
     269           0 :         result->timeout_new          = avahi_timeout_new;
     270           0 :         result->timeout_update               = avahi_timeout_update;
     271           0 :         result->timeout_free         = avahi_timeout_free;
     272           0 :         result->userdata             = ctx;
     273             : 
     274           0 :         return result;
     275             : }

Generated by: LCOV version 1.13