]> arthur.barton.de Git - netatalk.git/blobdiff - etc/atalkd/main.c
Remove bdb env on exit
[netatalk.git] / etc / atalkd / main.c
index b8080c29150a56646de93a5f2b167911a9e1578e..469678d3db9ec13273511e7a2157a426e7624a25 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * $Id: main.c,v 1.22 2009-10-14 02:24:05 didg Exp $
+ * $Id: main.c,v 1.25 2009-12-13 02:21:47 didg Exp $
  *
  * Copyright (c) 1990,1993 Regents of The University of Michigan.
  * All Rights Reserved. See COPYRIGHT.
@@ -164,6 +164,30 @@ static void atalkd_exit(const int i)
   exit(i);
 }
 
+/* XXX need better error handling for gone interfaces, delete routes and so on 
+ * moreover there's no way to put an interface back short of restarting atalkd
+ * thus after the first time, silently fail
+*/
+static ssize_t sendto_iface(struct interface *iface, int sockfd, const void *buf, size_t len, 
+                       const struct sockaddr_at         *dest_addr)
+{
+    ssize_t ret = sendto( sockfd, buf, len, 0, (struct sockaddr *)dest_addr, sizeof( struct sockaddr_at ));
+
+    if (ret < 0 ) {
+        if (!(iface->i_flags & IFACE_ERROR)) {
+            LOG(log_error, logtype_atalkd, "as_timer sendto %u.%u (%u): %s",
+                                   ntohs( dest_addr->sat_addr.s_net ),
+                                   dest_addr->sat_addr.s_node,
+                                   ntohs( iface->i_rt->rt_firstnet ),
+                                   strerror(errno) );
+        }
+        iface->i_flags |= IFACE_ERROR;
+    }
+    else {
+        iface->i_flags &= ~IFACE_ERROR;
+    }
+    return ret;
+}
 
 static void as_timer(int sig _U_)
 {
@@ -183,6 +207,7 @@ static void as_timer(int sig _U_)
     ap=zap=rap=NULL;
 
     memset(&sat, 0, sizeof( struct sockaddr_at ));
+
     for ( iface = interfaces; iface; iface = iface->i_next ) {
        if ( iface->i_flags & IFACE_LOOPBACK ) {
            continue;
@@ -196,8 +221,7 @@ static void as_timer(int sig _U_)
            }
        }
 
-       if (( iface->i_flags & ( IFACE_ADDR|IFACE_CONFIG|IFACE_NOROUTER )) ==
-               IFACE_ADDR ) {
+       if (( iface->i_flags & ( IFACE_ADDR|IFACE_CONFIG|IFACE_NOROUTER )) == IFACE_ADDR ) {
            if ( iface->i_time < 3 ) {
                if ( iface->i_flags & IFACE_PHASE1 ) {
                  if (rtmp_request( iface ) < 0) {
@@ -221,10 +245,8 @@ static void as_timer(int sig _U_)
                         * No seed info, and we've got multiple interfaces.
                         * Wait forever.
                         */
-                       LOG(log_info, logtype_atalkd,
-                               "as_timer multiple interfaces, no seed" );
-                       LOG(log_info, logtype_atalkd, "as_timer can't configure %s",
-                               iface->i_name );
+                       LOG(log_info, logtype_atalkd, "as_timer multiple interfaces, no seed" );
+                       LOG(log_info, logtype_atalkd, "as_timer can't configure %s", iface->i_name );
                        LOG(log_info, logtype_atalkd, "as_timer waiting for router" );
                        iface->i_time = 0;
                        continue;
@@ -235,8 +257,7 @@ static void as_timer(int sig _U_)
                         */
                        iface->i_flags |= IFACE_CONFIG;
                        for ( zt = iface->i_czt; zt; zt = zt->zt_next ) {
-                           if (addzone( iface->i_rt, zt->zt_len, 
-                                        zt->zt_name) < 0) {
+                           if (addzone( iface->i_rt, zt->zt_len, zt->zt_name) < 0) {
                              LOG(log_error, logtype_atalkd, "addzone: %s", strerror(errno));
                              atalkd_exit(1);
                            }
@@ -246,26 +267,20 @@ static void as_timer(int sig _U_)
                            iface->i_rt->rt_flags |= RTMPTAB_HASZONES;
                        }
                        if ( iface->i_flags & IFACE_PHASE1 ) {
-                           LOG(log_info, logtype_atalkd,
-                                   "as_timer configured %s phase 1 from seed",
-                                   iface->i_name );
+                           LOG(log_info, logtype_atalkd, "as_timer configured %s phase 1 from seed", iface->i_name );
                            setaddr( iface, IFACE_PHASE1,
                                    iface->i_caddr.sat_addr.s_net,
                                    iface->i_addr.sat_addr.s_node,
                                    iface->i_caddr.sat_addr.s_net,
                                    iface->i_caddr.sat_addr.s_net );
                        } else {
-                           LOG(log_info, logtype_atalkd,
-                                   "as_timer configured %s phase 2 from seed",
-                                   iface->i_name );
+                           LOG(log_info, logtype_atalkd, "as_timer configured %s phase 2 from seed", iface->i_name );
                        }
 
                        if ( looproute( iface, RTMP_ADD )) { /* -1 or 1 */
-                           LOG(log_error, logtype_atalkd,
-                                   "as_timer: can't route %u.%u to loop: %s",
-                                   ntohs( iface->i_addr.sat_addr.s_net ),
-                                   iface->i_addr.sat_addr.s_node,
-                                   strerror(errno) );
+                           LOG(log_error, logtype_atalkd, "as_timer: can't route %u.%u to loop: %s", 
+                                   ntohs( iface->i_addr.sat_addr.s_net ),
+                                   iface->i_addr.sat_addr.s_node, strerror(errno) );
                            atalkd_exit( 1 );
                        }
                        if ( iface == ciface ) {
@@ -283,16 +298,12 @@ static void as_timer(int sig _U_)
                    if ( iface->i_flags & IFACE_PHASE2 ) {
                        iface->i_rt->rt_firstnet = 0;
                        iface->i_rt->rt_lastnet = htons( STARTUP_LASTNET );
-                       setaddr( iface, IFACE_PHASE2,
-                               iface->i_addr.sat_addr.s_net,
-                               iface->i_addr.sat_addr.s_node,
+                       setaddr( iface, IFACE_PHASE2, iface->i_addr.sat_addr.s_net, iface->i_addr.sat_addr.s_node,
                                0, htons( STARTUP_LASTNET ));
                    }
                    if ( looproute( iface, RTMP_ADD ) ) { /* -1 or 1 */
-                       LOG(log_error, logtype_atalkd,
-                               "as_timer: can't route %u.%u to loopback: %s",
-                               ntohs( iface->i_addr.sat_addr.s_net ),
-                               iface->i_addr.sat_addr.s_node,
+                       LOG(log_error, logtype_atalkd, "as_timer: can't route %u.%u to loopback: %s",
+                               ntohs( iface->i_addr.sat_addr.s_net ), iface->i_addr.sat_addr.s_node,
                                strerror(errno) );
                        atalkd_exit( 1 );
                    }
@@ -324,14 +335,12 @@ static void as_timer(int sig _U_)
             * our zone has gone away.
             */
            if ( ++gate->g_state >= RTMPTAB_BAD ) {
-               LOG(log_info, logtype_atalkd, "as_timer gateway %u.%u down",
-                       ntohs( gate->g_sat.sat_addr.s_net ),
+               LOG(log_info, logtype_atalkd, "as_timer gateway %u.%u down", ntohs( gate->g_sat.sat_addr.s_net ),
                        gate->g_sat.sat_addr.s_node );
                rtmp = gate->g_rt;
                while ( rtmp ) {
                    frtmp = rtmp->rt_next;
-                   if ( rtmp->rt_hops == RTMPHOPS_POISON ||
-                           rtmp->rt_iprev == NULL ) {
+                   if ( rtmp->rt_hops == RTMPHOPS_POISON || rtmp->rt_iprev == NULL ) {
                        rtmp_free( rtmp );
                    } else {
                        rtmp->rt_hops = RTMPHOPS_POISON;
@@ -366,8 +375,7 @@ static void as_timer(int sig _U_)
                 * if we're not a seed router.
                 */
 
-               if ( gate->g_iface->i_gate == NULL && 
-                    ((iface->i_flags & IFACE_SEED) == 0)) {
+               if ( gate->g_iface->i_gate == NULL && ((iface->i_flags & IFACE_SEED) == 0)) {
                    gate->g_iface->i_flags |= IFACE_NOROUTER;
                    gate->g_iface->i_flags &= ~IFACE_CONFIG;
 
@@ -446,8 +454,7 @@ static void as_timer(int sig _U_)
                /*
                 * Do ZIP lookups.
                 */
-               if ( rtmp->rt_iprev &&
-                       ( rtmp->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
+               if ( rtmp->rt_iprev && ( rtmp->rt_flags & RTMPTAB_HASZONES ) == 0 ) {
                    if ( data + sizeof( u_short ) > end || n == 255 ) {
                        /* send what we've got */
                        zh.zh_op = ZIPOP_QUERY;
@@ -457,11 +464,7 @@ static void as_timer(int sig _U_)
                        *data++ = DDPTYPE_ZIP;
                        memcpy( data, &zh, sizeof( struct ziphdr ));
 
-                       if ( sendto( zap->ap_fd, packet, cc, 0,
-                               (struct sockaddr *)&sat,
-                               sizeof( struct sockaddr_at )) < 0 ) {
-                           LOG(log_error, logtype_atalkd, "as_timer sendto: %s", strerror(errno) );
-                       }
+                       sendto_iface(iface,  zap->ap_fd, packet, cc, &sat);
                        sentzipq = 1;
 
                        n = 0;
@@ -479,8 +482,7 @@ static void as_timer(int sig _U_)
                     * ask about, and warn that we can't get it's zone.
                     */
                    if ( rtmp->rt_nzq++ == 3 ) {
-                       LOG(log_info, logtype_atalkd, "as_timer can't get zone for %u",
-                               ntohs( rtmp->rt_firstnet ));
+                       LOG(log_info, logtype_atalkd, "as_timer can't get zone for %u", ntohs( rtmp->rt_firstnet ));
                    }
                    if ( rtmp->rt_nzq > 3 ) {
                        if ( ziptimeout ) {
@@ -507,10 +509,7 @@ static void as_timer(int sig _U_)
                *data++ = DDPTYPE_ZIP;
                memcpy( data, &zh, sizeof( struct ziphdr ));
 
-               if ( sendto( zap->ap_fd, packet, cc, 0, (struct sockaddr *)&sat,
-                       sizeof( struct sockaddr_at )) < 0 ) {
-                   LOG(log_error, logtype_atalkd, "as_timer sendto: %s", strerror(errno) );
-               }
+               sendto_iface( iface, zap->ap_fd, packet, cc, &sat);
            }
        }
        if ( fgate ) {
@@ -582,25 +581,21 @@ static void as_timer(int sig _U_)
                        continue;
                    }
 
+                   /* split horizon */
+                   if (rtmp->rt_iface == iface) {
+                       continue;
+                   }
+
                    if ((( rtmp->rt_flags & RTMPTAB_EXTENDED ) &&
                            data + 2 * SZ_RTMPTUPLE > end ) ||
                            data + SZ_RTMPTUPLE > end ) {
-                       if ( sendto( rap->ap_fd, packet, data - packet, 0,
-                               (struct sockaddr *)&sat,
-                               sizeof( struct sockaddr_at )) < 0 ) {
-                           LOG(log_error, logtype_atalkd, "as_timer sendto %u.%u (%u): %s",
-                                   ntohs( sat.sat_addr.s_net ),
-                                   sat.sat_addr.s_node,
-                                   ntohs( iface->i_rt->rt_firstnet ),
-                                   strerror(errno) );
-                       }
+
+                       sendto_iface(iface,rap->ap_fd, packet, data - packet, &sat);
 
                        if ( iface->i_flags & IFACE_PHASE2 ) {
-                           data = packet + 1 + sizeof( struct rtmp_head ) +
-                                   2 * SZ_RTMPTUPLE;
+                           data = packet + 1 + sizeof( struct rtmp_head ) + 2 * SZ_RTMPTUPLE;
                        } else {
-                           data = packet + 1 + sizeof( struct rtmp_head ) +
-                                   SZ_RTMPTUPLE;
+                           data = packet + 1 + sizeof( struct rtmp_head ) + SZ_RTMPTUPLE;
                        }
                        n = 0;
                    }
@@ -625,15 +620,7 @@ static void as_timer(int sig _U_)
 
            /* send rest */
            if ( n ) {
-               if ( sendto( rap->ap_fd, packet, data - packet, 0,
-                       (struct sockaddr *)&sat,
-                       sizeof( struct sockaddr_at )) < 0 ) {
-                   LOG(log_error, logtype_atalkd, "as_timer sendto %u.%u (%u): %s",
-                           ntohs( sat.sat_addr.s_net ),
-                           sat.sat_addr.s_node,
-                           ntohs( iface->i_rt->rt_firstnet ),
-                           strerror(errno) );
-               }
+               sendto_iface(iface, rap->ap_fd, packet, data - packet, &sat);
            }
        }
     }