File: utils.c

package info (click to toggle)
ser2net 2.5-1%2Blenny1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 1,596 kB
  • ctags: 321
  • sloc: sh: 8,944; ansic: 4,325; makefile: 10
file content (108 lines) | stat: -rw-r--r-- 2,631 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
/*
 *  ser2net - A program for allowing telnet connection to serial ports
 *  Copyright (C) 2001  Corey Minyard <minyard@acm.org>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/* This file holds basic utilities used by the ser2net program. */

#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "utils.h"

/* Scan for a positive integer, and return it.  Return -1 if the
   integer was invalid. */
int
scan_int(char *str)
{
    int rv = 0;

    if (*str == '\0') {
	return -1;
    }

    for (;;) {
	switch (*str) {
	case '0': case '1': case '2': case '3': case '4':
	case '5': case '6': case '7': case '8': case '9':
	    rv = (rv * 10) + ((*str) - '0');
	    break;

	case '\0':
	    return rv;

	default:
	    return -1;
	}

	str++;
    }

    return rv;
}

/* Scan for a TCP port in the form "[x.x.x.x,]x" where the first part is
   the IP address (options, defaults to INADDR_ANY) and the second part
   is the port number (required). */
int
scan_tcp_port(char *str, struct sockaddr_in *addr)
{
    char *strtok_data;
    char *ip;
    char *port;
    int  port_num;

    ip = strtok_r(str, ",", &strtok_data);
    port = strtok_r(NULL, "", &strtok_data);
    if (port == NULL) {
	port = ip;
	ip = NULL;
	addr->sin_addr.s_addr = INADDR_ANY;
	port_num = scan_int(port);
	if (port_num == -1) {
	    return -1;
	}
	addr->sin_port = htons(port_num);
    } else {
	/* Both an IP and port were specified. */
	addr->sin_addr.s_addr = inet_addr(ip);
	if (addr->sin_addr.s_addr == INADDR_NONE) {
	    struct hostent *hp;

	    hp = gethostbyname(ip);
	    if (hp == NULL) {
		return -1;
	    }
	    if (hp->h_addrtype != AF_INET) {
		return -1;
	    }
	    memcpy(&addr->sin_addr, hp->h_addr_list[0], hp->h_length);
	}

	port_num = scan_int(port);
	if (port_num == -1) {
	    return -1;
	}
	addr->sin_port = htons(port_num);
    }
    addr->sin_family = AF_INET;

    return 0;
}