Esempio n. 1
0
/**
 * Function: main
 *
 * The calling convention for this function is:
 *
 * wl2kax25 -c targetcall -a ax25port -t timeoutsecs -e emailaddress
 *
 * The parameters are:
 * mycall :  my call sign, which MUST be set in wl2k.conf
 * targetcall: callsign for the RMS
 * ax25port: name of the ax25 port to use (e.g., sm0)
 * timeoutsecs: timeout in seconds
 * emailaddress: email address where the retrieved message will be sent via sendmail
 *
 * The targetcall parameter does not support a path yet.
 */
int
main(int argc, char *argv[])
{
  int s;
  FILE *fp;
  unsigned int addrlen = 0;
  union {
    struct full_sockaddr_ax25 ax25;
    struct sockaddr_rose rose;
  } sockaddr;
  char *dev;
  pid_t procID;
  int sv[2];
  int ready;
  struct pollfd fds[2];
  ssize_t len;
  unsigned char *pbuf;
  ssize_t byteswritten;
  static cfg_t cfg;

  loadconfig(argc, argv, &cfg);

  g_mime_init(0);

  setlinebuf(stdout);

  if (socketpair(PF_UNIX, SOCK_STREAM, 0, sv))
  {
    perror("socketpair");
    exit(EXIT_FAILURE);
  }

  // Begin AX25 socket code
  if (ax25_config_load_ports() == 0)
    fprintf(stderr, "wl2kax25: no AX.25 port data configured\n");

  if (cfg.ax25port != NULL) {
    if ((dev = ax25_config_get_dev(cfg.ax25port)) == NULL) {
      fprintf(stderr, "wl2kax25: invalid port name - %s\n",
              cfg.ax25port);
      return(EXIT_FAILURE);
    }
  }

  if ((s = socket(AF_AX25, SOCK_SEQPACKET, 0)) == -1) {
    perror("socket");
    printf("%d\n", __LINE__);
    exit(EXIT_FAILURE);
  }
  ax25_aton(ax25_config_get_addr(cfg.ax25port), &sockaddr.ax25);
  ax25_aton(cfg.mycall, &sockaddr.ax25);
  if (sockaddr.ax25.fsa_ax25.sax25_ndigis == 0) {
    ax25_aton_entry(ax25_config_get_addr(cfg.ax25port),
                    sockaddr.ax25.fsa_digipeater[0].
                    ax25_call);
    sockaddr.ax25.fsa_ax25.sax25_ndigis = 1;
  }
  sockaddr.ax25.fsa_ax25.sax25_family = AF_AX25;
  addrlen = sizeof(struct full_sockaddr_ax25);

  if (bind(s, (struct sockaddr *) &sockaddr, addrlen) == -1) {
    perror("bind");
    close(s);
    exit(EXIT_FAILURE);
  }


  if (ax25_aton(cfg.targetcall, &sockaddr.ax25) < 0) {
    close(s);
    perror("ax25_aton()");
    exit(EXIT_FAILURE);
  }
  sockaddr.rose.srose_family = AF_AX25;
  addrlen = sizeof(struct full_sockaddr_ax25);

  settimeout(cfg.timeoutsecs);
  if (connect(s, (struct sockaddr *) &sockaddr, addrlen) != 0) {
    close(s);
    perror("connect()");
    exit(EXIT_FAILURE);
  }
  unsettimeout();

  printf("Connected to AX.25 stack\n"); fflush(stdout);
  // End AX25 socket code

	// Fork a process
		if ((procID = fork())) {
		// Parent processing
			if (-1 == procID) {
				fprintf(stderr, "fork\n");
				exit(EXIT_FAILURE);
			}

			close(sv[1]);

    fds[0].fd = s;
    fds[0].events = POLLIN;
    fds[1].fd = sv[0];
    fds[1].events = POLLIN;

    // poll here and feed to the ax25 socket.
    // Data must be chunked to the appropriate size
    for (;;) {
      ready = poll(fds, sizeof(fds)/sizeof(struct pollfd), -1);

      if (-1 == ready) {
        if (EINTR == errno)
					break;
				close(s);
        perror("poll");
        exit(EXIT_FAILURE);
      }

      // Inbound
      if (fds[0].revents & POLLIN) {

        len = read(fds[0].fd, axread, sizeof(axread));
        if ( len > 0 ) {

          pbuf = axread;

          while(len > 0) {
            byteswritten = write(fds[1].fd, pbuf, MIN(paclen, (size_t)len));

            if (byteswritten == 0 || (byteswritten < 0 && errno != EAGAIN)) {
              fprintf(stderr,"%s error on inbound write: %s)\n",
                getprogname(), strerror(errno));
              break;
            }
            pbuf += byteswritten;
            len -=    byteswritten;
          }

				} else if (len == 0) {
					close(s);
          printf("EOF on ax25 socket, exiting...\n");
          exit(EXIT_FAILURE);
        }
      }

      // Outbound
      if (fds[1].revents & POLLIN) {

        len = read(fds[1].fd, axwrite, sizeof(axwrite));
        if (len > 0 ) {

          pbuf = axwrite;

          while(len > 0) {
            byteswritten = write(fds[0].fd, pbuf, MIN(paclen, (size_t)len));
            if (byteswritten == 0 || (byteswritten < 0 && errno != EAGAIN)) {
              fprintf(stderr,"%s error on outbound write: %s)\n",
                getprogname(), strerror(errno));
              break;
            }
            pbuf += byteswritten;
            len -=    byteswritten;
          }

        }   else if (len == 0) {
          printf("EOF on child fd, terminating communications loop.\n");
          break;
        }
      }
    }

    printf("Closing ax25 connection\n");
#if 1
    {
      time_t start_time, current_time;
      bool bax25conn;

      start_time = time(NULL); /* get current time in seconds */

      if ((bax25conn=isax25connected(s)) == TRUE) {
        printf("Waiting for AX25 peer ... ");
        while(isax25connected(s)){
          current_time = time(NULL);
          if (difftime(current_time, start_time) > 5) {
            break;
          }
        }
        if (isax25connected(s)) {
          printf("timeout\n");
        }else {
          printf("disconnected\n");
        }
      }
    }
#endif

    g_mime_shutdown();
    close(sv[0]);
    close(s);
    exit(EXIT_SUCCESS);
    return 1;
  }
  else
  {
    // Child processing
    printf("Child process\n");
    close(sv[0]);

    if ((fp = fdopen(sv[1], "r+b")) == NULL) {
      close(sv[1]);
      perror("fdopen()");
      _exit(EXIT_FAILURE);
    }

    /* set buf size to paclen */
    setvbuf(fp, NULL, _IOFBF, paclen);

    /*
     * The messages are exchanged in this call
     *
     * TODO: The sid sent by the client should contain an NXX,
     *       where NXX represents N followed by two digits of SSID.
     *       This allows the RMS to find the correct registered
     *       user in case the SSID has been changed in the network.
     */

    if(cfg.bVerbose) {
            printf("Child process calling wl2kexchange()\n");
    }
    settimeout(cfg.timeoutsecs);
    wl2kexchange(cfg.mycall, cfg.targetcall, fp, fp, cfg.emailaddr);
    fclose(fp);
    printf("Child process exiting\n");
    _exit(EXIT_SUCCESS);
  }
}
Esempio n. 2
0
File: flexd.c Progetto: ve7fet/fpac
int read_conf(void)
{
	FILE *fp, *fgt;
	char buf[512], line[1024], *cp;
	int i = 0, k;
	char digipath[AX25_MAX_DIGIS * 10];
	if ((fp = fopen(FLEXD_CONF_FILE, "r")) == NULL) {
		fprintf(stderr, "flexd config: Cannot open config file: %s\n",
				FLEXD_CONF_FILE);
		return -1;
	}
	if ((fgt = fopen(FLEX_GT_FILE, "w")) == NULL) {
		fprintf(stderr,
				"flexd config: Cannot open flexnet gateways file: %s\n",
				FLEX_GT_FILE);
		fclose(fp);
		return -1;
	}

	fputs("addr  callsign  dev  digipeaters\n", fgt);

	while (fgets(buf, sizeof(buf), fp)) {
		if (*buf == '#' || *buf == ' ')
			continue;			/* comment line/empty line */
		cp = strchr(buf, '#');
		if (cp)
			*cp = '\0';
		cp = strtok(buf, " \t\n\r");
		if (cp == NULL)
			continue;			/* empty line */

		if (strcasecmp(cp, "pollinterval") == 0) {	/* set poll interval */
			cp = strtok(NULL, " \t\n\r");
			if (cp == NULL) {
				fprintf(stderr,
						"flexd config: PollInterval needs an argument\n");
				fclose(fp);
				fclose(fgt);
				return -1;
			}
			poll_time = safe_atoi(cp);
			if (poll_time < MINIMUM_POLL_TIME)
				poll_time = MINIMUM_POLL_TIME;
		}
		if (strcasecmp(cp, "mycall") == 0) {	/* set connect call for download */
			cp = strtok(NULL, " \t\n\r");
			if (cp == NULL) {
				fprintf(stderr,
						"flexd config: MyCall needs an argument\n");
				fclose(fp);
				fclose(fgt);
				return -1;
			}
			safe_strncpy(mycall, cp, 9);
		}
		if (strcasecmp(cp, "flexgate") == 0) {	/* set flexnet gateway */
			cp = strtok(NULL, " \t\n\r");
			if (cp == NULL) {
				fprintf(stderr,
						"flexd config: FlexGate needs an argument\n");
				fclose(fp);
				fclose(fgt);
				return -1;
			}
			safe_strncpy(flexgate, cp, 9);
/*	strcat(cp,"\0");*/
			gw = find_route(flexgate, NULL);
			if (gw == NULL) {
				fprintf(stderr,
						"flexd config: FlexGate %s not found in file: %s\n",
						flexgate, AX_ROUTES_FILE);
				fclose(fp);
				fclose(fgt);
				return -1;
			} else {
				*digipath = '\0';
				for (k = 0; k < AX25_MAX_DIGIS; k++) {
					if (gw->digis[k] == NULL)
						break;
					strcat(digipath, " ");
					strcat(digipath, gw->digis[k]);
				}
                                if ((ax25_config_get_dev(gw->dev)) == NULL )
                                    sprintf(line, "%05d %-8s %5s %s\n",i++, gw->dest_call, gw->dev, digipath);
				else
                                    /* ax25 device */
                                    sprintf(line, "%05d %-8s %4s %s\n",i++, gw->dest_call, ax25_config_get_dev(gw->dev), digipath);
                                fputs(line, fgt);
			}
		}
	}
	fclose(fgt);
	fclose(fp);
return 0;
}
Esempio n. 3
0
int main(int argc, char **argv)
{
	unsigned char buffer[BUFSIZE];
	int dumpstyle = ASCII;
	int size;
	int s;
	char *port = NULL, *dev = NULL;
	struct sockaddr sa;
	socklen_t asize = sizeof(sa);
	struct ifreq ifr;
	int proto = ETH_P_AX25;
	int exit_code = EXIT_SUCCESS;

	timestamp = 0;

	while ((s = getopt(argc, argv, "8achip:rtv")) != -1) {
		switch (s) {
		case '8':
			sevenbit = 0;
			break;
		case 'a':
			proto = ETH_P_ALL;
			break;
		case 'c':
			color = 1;
			break;
		case 'h':
			dumpstyle = HEX;
			break;
		case 'i':
			ibmhack = 1;
			break;
		case 'p':
			port = optarg;
			break;
		case 'r':
			dumpstyle = READABLE;
			break;
		case 't':
			timestamp = 1;
			break;
		case 'v':
			printf("listen: %s\n", VERSION);
			return 0;
		case ':':
			fprintf(stderr,
				"listen: option -p needs a port name\n");
			return 1;
		case '?':
			fprintf(stderr,
				"Usage: listen [-8] [-a] [-c] [-h] [-i] [-p port] [-r] [-t] [-v]\n");
			return 1;
		}
	}

	if (ax25_config_load_ports() == 0)
		fprintf(stderr, "listen: no AX.25 port data configured\n");

	if (port != NULL) {
		if ((dev = ax25_config_get_dev(port)) == NULL) {
			fprintf(stderr, "listen: invalid port name - %s\n",
				port);
			return 1;
		}
	}

	if ((sock = socket(PF_PACKET, SOCK_PACKET, htons(proto))) == -1) {
		perror("socket");
		return 1;
	}

	if (color) {
		color = initcolor();	/* Initialize color support */
		if (!color)
			printf("Could not initialize color support.\n");
	}

	setservent(1);

	while (!sigint) {
		asize = sizeof(sa);

		signal(SIGINT, handle_sigint);
		signal(SIGTERM, handle_sigint);
		if ((size =
		     recvfrom(sock, buffer, sizeof(buffer), 0, &sa,
			      &asize)) == -1) {
			/*
			 * Signals are cared for by the handler, and we
			 * don't want to abort on SIGWINCH
			 */
			if (errno == EINTR) {
				refresh();
				continue;
			} else if (!(errno == EBADF && sigint)) {
				perror("recv");
				exit_code = errno;
			}
			break;
		}
		signal(SIGINT, SIG_DFL);
		signal(SIGTERM, SIG_DFL);
		if (sock == -1 || sigint)
			break;

		if (dev != NULL && strcmp(dev, sa.sa_data) != 0)
			continue;

		if (proto == ETH_P_ALL) {
			strcpy(ifr.ifr_name, sa.sa_data);
			signal(SIGINT, handle_sigint);
			signal(SIGTERM, handle_sigint);
			if (ioctl(sock, SIOCGIFHWADDR, &ifr) == -1) {
				if (!(errno == EBADF && sigint)) {
					perror("SIOCGIFHWADDR");
					exit_code = errno;
					break;
				}
			}
			signal(SIGINT, SIG_DFL);
			signal(SIGTERM, SIG_DFL);
			if (sock == -1 || sigint)
				break;
			if (ifr.ifr_hwaddr.sa_family == AF_AX25) {
				display_port(sa.sa_data);
#ifdef NEW_AX25_STACK
				ax25_dump(buffer, size, dumpstyle);
#else
				ki_dump(buffer, size, dumpstyle);
#endif
/*				lprintf(T_DATA, "\n");  */
			}
		} else {
			display_port(sa.sa_data);
#ifdef NEW_AX25_STACK
			ax25_dump(buffer, size, dumpstyle);
#else
			ki_dump(buffer, size, dumpstyle);
#endif
/*                      lprintf(T_DATA, "\n");  */
		}
		if (color)
			refresh();
	}
	if (color)
		endwin();

	return exit_code;
}