int ipc_send(key_t key, long mtype, char *mtext) { struct nmsgbuf buf; int id; if ((id = msgget(key, S_IRWXU)) == -1) { node_perror("ipc_send: Could not get transmit channel", errno); if (User.ul_type == AF_NETROM) { node_msg(""); } return -1; } buf.mtype = mtype; strncpy(buf.mtext, mtext, M_LEN); if (msgsnd(id, (struct msgbuf *)&buf, M_LEN, 0) == -1) { node_perror("ipc_send: Could not send message", errno); if (User.ul_type == AF_NETROM) { node_msg(""); } return -1; } if (User.ul_type == AF_NETROM) { node_msg(""); } return 0; }
int ipc_open(void) { key_t key = FIRST_KEY; do { key++; ipc_id = msgget(key, S_IRWXU | IPC_CREAT | IPC_EXCL); } while ((ipc_id == -1) && (key != LAST_KEY)); if (ipc_id == -1) node_perror("ipc_open: Could not get an IPC channel", errno); #if 0 node_msg("debug: ipc_id=%d key=%d", ipc_id, key); #endif User.ipc_key = key; if (key != -1) signal(SIGUSR2, usr2_handler); else signal(SIGUSR2, SIG_IGN); return 0; }
static void usr2_handler(int sig) { struct nmsgbuf buf; if (msgrcv(ipc_id, (struct msgbuf *)&buf, M_LEN, 0, IPC_NOWAIT|MSG_NOERROR) != -1) { node_msg("%s", buf.mtext); if (User.ul_type != AF_NETROM) { node_prompt(); } if (User.ul_type == AF_NETROM) { node_msg(""); } axio_flush(NodeIo); } else node_log(LOGLVL_ERROR, "usr2_handler: Caught SIGUSR2, but couldn't receive a message"); signal(SIGUSR2, usr2_handler); /* Restore handler */ }
int do_links(int argc, char **argv) { struct ax_routes *axrt, *p; char digipath[AX25_MAX_DIGIS*10]; char tipoconn[9]; int i=0; axio_puts("",NodeIo); if (User.ul_type == AF_NETROM) { axio_printf(NodeIo,"%s} ", NodeId); } if ((axrt=read_ax_routes()) == NULL) { if (errno) node_perror("do_links: read_ax_routes", errno); else axio_printf(NodeIo,"No known links"); if (User.ul_type == AF_NETROM) { node_msg(""); } return 0; } /* "links" */ if (check_perms(PERM_ANSI, 0L) != -1) { axio_printf(NodeIo, "\e[01;33m"); }
/* * Initiate a AX.25, NET/ROM, ROSE or TCP connection to the host * specified by `address'. */ static ax25io *connect_to(char **addr, int family, int escape, int compr) { int fd; ax25io *riop; fd_set read_fdset; fd_set write_fdset; int salen; union { struct full_sockaddr_ax25 ax; #ifdef HAVE_ROSE struct sockaddr_rose rs; #endif struct sockaddr_in in; } sa; char call[10], path[20], *cp, *eol; int ret, retlen = sizeof(int); int paclen; struct hostent *hp; struct servent *sp; struct user u; #ifdef HAVE_NETROM struct proc_nr_nodes *np; #endif strcpy(call, User.call); /* * Fill in protocol spesific stuff. */ switch (family) { #ifdef HAVE_ROSE case AF_ROSE: if (aliascmd==0) { if (check_perms(PERM_ROSE, 0L) == -1) { axio_printf(NodeIo,"Permission denied"); if (User.ul_type == AF_NETROM) { node_msg(""); } node_log(LOGLVL_GW, "Permission denied: rose"); return NULL; } } if ((fd = socket(AF_ROSE, SOCK_SEQPACKET, 0)) < 0) { node_perror("connect_to: socket", errno); return NULL; } sa.rs.srose_family = AF_ROSE; sa.rs.srose_ndigis = 0; ax25_aton_entry(call, sa.rs.srose_call.ax25_call); rose_aton(rs_config_get_addr(NULL), sa.rs.srose_addr.rose_addr); salen = sizeof(struct sockaddr_rose); if (bind(fd, (struct sockaddr *)&sa, salen) == -1) { node_perror("connect_to: bind", errno); close(fd); return NULL; } memset(path, 0, 11); memcpy(path, rs_config_get_addr(NULL), 4); salen = strlen(addr[1]); if ((salen != 6) && (salen != 10)) { axio_printf(NodeIo,"Invalid ROSE address"); if (User.ul_type == AF_NETROM) { node_msg(""); } return(NULL); } memcpy(path + (10-salen), addr[1], salen); sprintf(User.dl_name, "%s @ %s", addr[0], path); sa.rs.srose_family = AF_ROSE; sa.rs.srose_ndigis = 0; if (ax25_aton_entry(addr[0], sa.rs.srose_call.ax25_call) < 0) { close(fd); return NULL; } if (rose_aton(path, sa.rs.srose_addr.rose_addr) < 0) { close(fd); return NULL; } if (addr[2] != NULL) { if (ax25_aton_entry(addr[2], sa.rs.srose_digi.ax25_call) < 0) { close(fd); return NULL; } sa.rs.srose_ndigis = 1; } salen = sizeof(struct sockaddr_rose); paclen = rs_config_get_paclen(NULL); eol = ROSE_EOL; /* Uncomment the below if you wish to have the node show a 'Trying' state */ /* node_msg("%s Trying %s... Type <RETURN> to abort", User.dl_name); */ break; #endif #ifdef HAVE_NETROM case AF_NETROM: if (aliascmd==0) { if (check_perms(PERM_NETROM, 0L) == -1) { axio_printf(NodeIo,"Permission denied"); if (User.ul_type == AF_NETROM) { node_msg(""); } node_log(LOGLVL_GW, "Permission denied: netrom"); return NULL; } } if ((fd = socket(AF_NETROM, SOCK_SEQPACKET, 0)) < 0) { node_perror("connect_to: socket", errno); return NULL; } /* Why on earth is this different from ax.25 ????? */ sprintf(path, "%s %s", nr_config_get_addr(NrPort), call); ax25_aton(path, &sa.ax); sa.ax.fsa_ax25.sax25_family = AF_NETROM; salen = sizeof(struct full_sockaddr_ax25); if (bind(fd, (struct sockaddr *)&sa, salen) == -1) { node_perror("connect_to: bind", errno); close(fd); return NULL; } if ((np = find_node(addr[0], NULL)) == NULL) { axio_printf(NodeIo,"No such node"); if (User.ul_type == AF_NETROM) { node_msg(""); } return NULL; } strcpy(User.dl_name, print_node(np->alias, np->call)); if (ax25_aton(np->call, &sa.ax) == -1) { close(fd); return NULL; } sa.ax.fsa_ax25.sax25_family = AF_NETROM; salen = sizeof(struct sockaddr_ax25); paclen = nr_config_get_paclen(NrPort); eol = NETROM_EOL; /* Uncomment the below if you wish the node to show a 'Trying' state */ if (check_perms(PERM_ANSI, 0L) != -1) { if (User.ul_type == AF_NETROM) { break; } node_msg("\e[01;36mTrying %s... hit <Enter> to abort", User.dl_name); } break; #endif #ifdef HAVE_AX25 case AF_FLEXNET: case AF_AX25: if (aliascmd==0) { if (check_perms(PERM_AX25, 0L) == -1 || (is_hidden(addr[0]) && check_perms(PERM_HIDDEN, 0L) == -1)) { axio_printf(NodeIo,"Permission denied"); if (User.ul_type == AF_NETROM) { node_msg(""); } node_log(LOGLVL_GW, "Permission denied: ax.25 port %s", addr[0]); return NULL; } } if (ax25_config_get_addr(addr[0]) == NULL) { if (User.ul_type == AF_NETROM) { axio_printf(NodeIo,"%s} ", NodeId); } axio_printf(NodeIo,"Invalid port"); if (User.ul_type == AF_NETROM) { node_msg(""); } return NULL; } if ((fd = socket(AF_AX25, SOCK_SEQPACKET, 0)) < 0) { node_perror("connect_to: socket", errno); return NULL; } /* * Invert the SSID only if user is coming in with AX.25 * and going out on the same port he is coming in via. */ if (User.ul_type == AF_AX25 && !strcasecmp(addr[0], User.ul_name)) invert_ssid(call, User.call); sprintf(path, "%s %s", call, ax25_config_get_addr(addr[0])); ax25_aton(path, &sa.ax); sa.ax.fsa_ax25.sax25_family = AF_AX25; salen = sizeof(struct full_sockaddr_ax25); if (bind(fd, (struct sockaddr *)&sa, salen) < 0) { node_perror("connect_to: bind", errno); close(fd); return NULL; } if (ax25_aton_arglist((const char **)addr+1, &sa.ax) < 0) { close(fd); return NULL; } strcpy(User.dl_name, strupr(addr[1])); strcpy(User.dl_port, strlwr(addr[0])); sa.ax.fsa_ax25.sax25_family = AF_AX25; salen = sizeof(struct full_sockaddr_ax25); paclen = ax25_config_get_paclen(addr[0]); eol = AX25_EOL; /* Uncomment the below if you wish the node to show a 'Trying' state */ /* if (family==AF_FLEXNET) node_msg("Trying %s via FlexNet... Type <RETURN> to abort", User.dl_name); */ if ((family==AF_FLEXNET) || (family == AF_AX25)) { if (!strcmp(User.dl_port,User.ul_name)) { if (check_perms(PERM_ANSI, 0L) != -1) { axio_printf(NodeIo, "\e[05;31m"); } axio_printf(NodeIo,"\aLoop detected on "); } if (check_perms(PERM_ANSI, 0L) != -1) { axio_printf(NodeIo, "\e[0;m"); } if (User.ul_type == AF_NETROM) { axio_printf(NodeIo, "%s} ", NodeId); } if (check_perms(PERM_ANSI, 0L) != -1) { axio_printf(NodeIo, "\e[01;33m"); }
int do_sysop(int argc, char **argv) { int i, len; char *p; int net_pos[5]; time_t md5key; char md5str[40]; char source[256]; char netrom[6]; md5key = time(NULL); srandom(md5key); len = strlen (cfg.password); for (i = 0; i < 5; i++) { net_pos[i] = (random () % len); netrom[i] = cfg.password[net_pos[i]]; } netrom[i] = '\0'; node_msg("%s> %d %d %d %d %d [%010ld]", cfg.alt_callsign, net_pos[0] + 1, net_pos[1] + 1, net_pos[2] + 1, net_pos[3] + 1, net_pos[4] + 1, md5key); sprintf(source, "%010ld%s", md5key, cfg.password); MD5String(md5str, source); usflush(User.fd); User.state = STATE_IDLE; time(&User.cmdtime); update_user(); alarm(IdleTimeout); for (;;) { if ((p = readline(User.fd)) == NULL) { if (errno == EINTR) continue; logout("User disconnected"); } break; } /* Plain text */ if (strcasecmp(p, cfg.password) == 0) { sys_mode = 1; node_msg("Pass OK"); } /* NetRom */ else if (strcasecmp(p, netrom) == 0) { sys_mode = 1; node_msg("Nrom OK"); } /* MD5 */ else if (strcasecmp(p, md5str) == 0) { sys_mode = 1; node_msg("MD5 OK"); } return(0); }
int do_msg(int argc, char **argv) { FILE *f; struct user u; char call[10]; char mtext[M_LEN]; int i, hits = 0, sent = 0; if (argc < 3) { node_msg("Usage: msg <call> <your text msg>"); if (User.ul_type == AF_NETROM) { node_msg(""); } return 0; } if ((f = fopen(DATA_NODE_LOGIN_FILE, "r")) == NULL) { node_perror(DATA_NODE_LOGIN_FILE, errno); return 0; } sprintf(mtext, "*** Msg from %s:\n\a", User.call); for (i = 2; i < argc; i++) { strncat(mtext, argv[i], M_LEN - strlen(mtext)); strncat(mtext, " ", M_LEN - strlen(mtext)); } strncat(mtext, "\n*** End of msg.", M_LEN - strlen(mtext)); mtext[M_LEN - 1] = 0; strncpy(call, argv[1], 9); call[9] = 0; while (fread(&u, sizeof(u), 1, f) == 1) { if (u.pid == -1 || (kill(u.pid, 0) == -1 && errno == ESRCH)) continue; if (!strcasecmp(u.call, call)) { hits++; if (u.ipc_key != -1 && u.state == STATE_IDLE) { ipc_send(u.ipc_key, 1, mtext); kill(u.pid, SIGUSR2); sent++; } } } fclose(f); if (hits == 0) { if (User.ul_type == AF_NETROM) { axio_printf(NodeIo, "%s} ", NodeId); } axio_printf(NodeIo, "%s is not on the node now.\a", call); if (User.ul_type == AF_NETROM) { node_msg(""); } } else if (sent == 0) { if (User.ul_type == AF_NETROM) { axio_printf(NodeIo, "%s} ", NodeId); } axio_printf(NodeIo, "%s is busy and not accepting msgs now.\a", call); if (User.ul_type == AF_NETROM) { node_msg(""); } } else if (sent != 0) { if (User.ul_type == AF_NETROM) { axio_printf(NodeIo, "%s} ", NodeId); } axio_printf(NodeIo, "Msg sent to %s.\a", call); } if (User.ul_type == AF_NETROM) { node_msg(""); } axio_flush(NodeIo); return 0; }