1/*
2 * tclIOSock.c --
3 *
4 *	Common routines used by all socket based channel types.
5 *
6 * Copyright (c) 1995-1997 Sun Microsystems, Inc.
7 *
8 * See the file "license.terms" for information on usage and redistribution
9 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
10 *
11 * RCS: @(#) $Id: tclIOSock.c,v 1.7 2002/07/29 16:54:41 rmax Exp $
12 */
13
14#include "tclInt.h"
15#include "tclPort.h"
16
17/*
18 *---------------------------------------------------------------------------
19 *
20 * TclSockGetPort --
21 *
22 *	Maps from a string, which could be a service name, to a port.
23 *	Used by socket creation code to get port numbers and resolve
24 *	registered service names to port numbers.
25 *
26 * Results:
27 *	A standard Tcl result.  On success, the port number is returned
28 *	in portPtr. On failure, an error message is left in the interp's
29 *	result.
30 *
31 * Side effects:
32 *	None.
33 *
34 *---------------------------------------------------------------------------
35 */
36
37int
38TclSockGetPort(interp, string, proto, portPtr)
39    Tcl_Interp *interp;
40    char *string;		/* Integer or service name */
41    char *proto;		/* "tcp" or "udp", typically */
42    int *portPtr;		/* Return port number */
43{
44    struct servent *sp;		/* Protocol info for named services */
45    Tcl_DString ds;
46    CONST char *native;
47
48    if (Tcl_GetInt(NULL, string, portPtr) != TCL_OK) {
49	/*
50	 * Don't bother translating 'proto' to native.
51	 */
52
53	native = Tcl_UtfToExternalDString(NULL, string, -1, &ds);
54	sp = getservbyname(native, proto);		/* INTL: Native. */
55	Tcl_DStringFree(&ds);
56	if (sp != NULL) {
57	    *portPtr = ntohs((unsigned short) sp->s_port);
58	    return TCL_OK;
59	}
60    }
61    if (Tcl_GetInt(interp, string, portPtr) != TCL_OK) {
62	return TCL_ERROR;
63    }
64    if (*portPtr > 0xFFFF) {
65        Tcl_AppendResult(interp, "couldn't open socket: port number too high",
66                (char *) NULL);
67	return TCL_ERROR;
68    }
69    return TCL_OK;
70}
71
72/*
73 *----------------------------------------------------------------------
74 *
75 * TclSockMinimumBuffers --
76 *
77 *	Ensure minimum buffer sizes (non zero).
78 *
79 * Results:
80 *	A standard Tcl result.
81 *
82 * Side effects:
83 *	Sets SO_SNDBUF and SO_RCVBUF sizes.
84 *
85 *----------------------------------------------------------------------
86 */
87
88int
89TclSockMinimumBuffers(sock, size)
90    int sock;			/* Socket file descriptor */
91    int size;			/* Minimum buffer size */
92{
93    int current;
94    socklen_t len;
95
96    len = sizeof(int);
97    getsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&current, &len);
98    if (current < size) {
99	len = sizeof(int);
100	setsockopt(sock, SOL_SOCKET, SO_SNDBUF, (char *)&size, len);
101    }
102    len = sizeof(int);
103    getsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&current, &len);
104    if (current < size) {
105	len = sizeof(int);
106	setsockopt(sock, SOL_SOCKET, SO_RCVBUF, (char *)&size, len);
107    }
108    return TCL_OK;
109}
110