int network_init(Module *m) { mod = m; mod->update = update; mod->interrupt = interrupt; mod->term = term; dy = mod->display; /* prepare fields */ memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; sa.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR; /* TODO: up/down events */ /* get file descriptor */ mod->fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); bind(mod->fd, (struct sockaddr *) &sa, sizeof(sa)); /* initial update */ if (ifscan() == 0 && update() == 0) { mod->has_fd = true; return 0; } else { return -1; } }
static int interrupt(void) { char buf[4096]; struct iovec iov = { buf, sizeof(buf) }; struct msghdr msg = { &sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; /* clear buffer */ recvmsg(mod->fd, &msg, 0); return ifscan(); }
/****************** * scan an if instruction * return address of next instruction after else & end addresses * if no else found, set else address to NULL ******************/ static INSTRUCTION *ifscan( register INSTRUCTION *ip, INSTRUCTION **else_adr ) { INSTRUCTION *r = NULL; INSTRUCTION *t; register BYTE c; do { c = *ip; ip = iscan( ip ); if( c == 0x58 ) { /* IF */ ip = ifscan( ip, &t ); } else if( c == 0x1b ) { /* ELSE */ assert( r == NULL ); r = ip; } /* if */ } while( c != 0x59 ); /* EIF */ *else_adr = r; return ip; } /* ifscan() */
static void iif( void ) { INSTRUCTION *end_adr, *else_adr, *stop_adr; iprintf(( "if (%s)\n", stack_ptr[-1]? "TRUE" : "FALSE" )); end_adr = ifscan( ins_ptr, &else_adr ); if( pop() ) { stop_adr = (else_adr!=NULL ? else_adr : end_adr) - 1; assert( *stop_adr == (else_adr ? 0x1b : 0x59 )); /* ELSE, EIF */ interpret( ins_ptr, stop_adr ); assert( ins_ptr == stop_adr ); } else if( else_adr != NULL ) { ins_ptr = else_adr; stop_adr = end_adr-1; assert( *stop_adr == 0x59 ); /* EIF */ interpret( else_adr, stop_adr ); assert( ins_ptr == stop_adr ); } /* if */ iprintf(( "end if\n" )); ins_ptr = end_adr; } /* iif() */