xref: /aosp_15_r20/external/tcpdump/missing/getservent.c (revision 05b00f6010a2396e3db2409989fc67270046269f)
1*05b00f60SXin Li /*
2*05b00f60SXin Li  * Copyright (c) 1983, 1993	The Regents of the University of California.
3*05b00f60SXin Li  * Copyright (c) 1993 Digital Equipment Corporation.
4*05b00f60SXin Li  * Copyright (c) 2012 G. Vanem <[email protected]>.
5*05b00f60SXin Li  * Copyright (c) 2017 Ali Abdulkadir <[email protected]>.
6*05b00f60SXin Li  * All rights reserved.
7*05b00f60SXin Li  *
8*05b00f60SXin Li  * Redistribution and use in source and binary forms, with or without
9*05b00f60SXin Li  * modification, are permitted provided that the following conditions
10*05b00f60SXin Li  * are met:
11*05b00f60SXin Li  * 1. Redistributions of source code must retain the above copyright
12*05b00f60SXin Li  *    notice, this list of conditions and the following disclaimer.
13*05b00f60SXin Li  * 2. Redistributions in binary form must reproduce the above copyright
14*05b00f60SXin Li  *    notice, this list of conditions and the following disclaimer in the
15*05b00f60SXin Li  *    documentation and/or other materials provided with the distribution.
16*05b00f60SXin Li  * 3. All advertising materials mentioning features or use of this software
17*05b00f60SXin Li  *    must display the following acknowledgement:
18*05b00f60SXin Li  *	This product includes software developed by the University of
19*05b00f60SXin Li  *	California, Berkeley and its contributors.
20*05b00f60SXin Li  * 4. Neither the name of the University nor the names of its contributors
21*05b00f60SXin Li  *    may be used to endorse or promote products derived from this software
22*05b00f60SXin Li  *    without specific prior written permission.
23*05b00f60SXin Li  *
24*05b00f60SXin Li  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25*05b00f60SXin Li  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26*05b00f60SXin Li  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27*05b00f60SXin Li  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28*05b00f60SXin Li  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29*05b00f60SXin Li  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30*05b00f60SXin Li  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31*05b00f60SXin Li  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32*05b00f60SXin Li  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33*05b00f60SXin Li  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34*05b00f60SXin Li  * SUCH DAMAGE.
35*05b00f60SXin Li  */
36*05b00f60SXin Li 
37*05b00f60SXin Li #ifdef HAVE_CONFIG_H
38*05b00f60SXin Li #include <config.h>
39*05b00f60SXin Li #endif
40*05b00f60SXin Li 
41*05b00f60SXin Li #include <netdissect-stdinc.h>
42*05b00f60SXin Li #include <getservent.h>
43*05b00f60SXin Li 
44*05b00f60SXin Li static FILE *servf = NULL;
45*05b00f60SXin Li static char line[BUFSIZ+1];
46*05b00f60SXin Li static struct servent serv;
47*05b00f60SXin Li static char *serv_aliases[MAXALIASES];
48*05b00f60SXin Li int _serv_stayopen;
49*05b00f60SXin Li const char *etc_path(const char *file);
50*05b00f60SXin Li 
51*05b00f60SXin Li /*
52*05b00f60SXin Li * Check if <file> exists in the current directory and, if so, return it.
53*05b00f60SXin Li * Else return either "%SYSTEMROOT%\System32\drivers\etc\<file>"
54*05b00f60SXin Li * or $PREFIX/etc/<file>.
55*05b00f60SXin Li * "<file>" is aka __PATH_SERVICES (aka "services" on Windows and
56*05b00f60SXin Li * "/etc/services" on other platforms that would need this).
57*05b00f60SXin Li */
etc_path(const char * file)58*05b00f60SXin Li const char *etc_path(const char *file)
59*05b00f60SXin Li {
60*05b00f60SXin Li     const char *env = getenv(__PATH_SYSROOT);
61*05b00f60SXin Li     static char path[_MAX_PATH];
62*05b00f60SXin Li 
63*05b00f60SXin Li     /* see if "<file>" exists locally or whether __PATH_SYSROOT is valid */
64*05b00f60SXin Li     if (fopen(file, "r") || !env)
65*05b00f60SXin Li         return (file);
66*05b00f60SXin Li     else
67*05b00f60SXin Li #ifdef _WIN32
68*05b00f60SXin Li     snprintf(path, sizeof(path), "%s%s%s", env, __PATH_ETC_INET, file);
69*05b00f60SXin Li #else
70*05b00f60SXin Li     snprintf(path, sizeof(path), "%s%s", env, file);
71*05b00f60SXin Li #endif
72*05b00f60SXin Li     return (path);
73*05b00f60SXin Li }
74*05b00f60SXin Li 
75*05b00f60SXin Li void
setservent(int f)76*05b00f60SXin Li setservent(int f)
77*05b00f60SXin Li {
78*05b00f60SXin Li     if (servf == NULL)
79*05b00f60SXin Li         servf = fopen(etc_path(__PATH_SERVICES), "r");
80*05b00f60SXin Li     else
81*05b00f60SXin Li         rewind(servf);
82*05b00f60SXin Li     _serv_stayopen |= f;
83*05b00f60SXin Li }
84*05b00f60SXin Li 
85*05b00f60SXin Li void
endservent(void)86*05b00f60SXin Li endservent(void)
87*05b00f60SXin Li {
88*05b00f60SXin Li     if (servf) {
89*05b00f60SXin Li         fclose(servf);
90*05b00f60SXin Li         servf = NULL;
91*05b00f60SXin Li     }
92*05b00f60SXin Li     _serv_stayopen = 0;
93*05b00f60SXin Li }
94*05b00f60SXin Li 
95*05b00f60SXin Li struct servent *
getservent(void)96*05b00f60SXin Li getservent(void)
97*05b00f60SXin Li {
98*05b00f60SXin Li     char *p;
99*05b00f60SXin Li     char *cp, **q;
100*05b00f60SXin Li 
101*05b00f60SXin Li     if (servf == NULL && (servf = fopen(etc_path(__PATH_SERVICES), "r")) == NULL)
102*05b00f60SXin Li         return (NULL);
103*05b00f60SXin Li 
104*05b00f60SXin Li again:
105*05b00f60SXin Li     if ((p = fgets(line, BUFSIZ, servf)) == NULL)
106*05b00f60SXin Li         return (NULL);
107*05b00f60SXin Li     if (*p == '#')
108*05b00f60SXin Li         goto again;
109*05b00f60SXin Li     cp = strpbrk(p, "#\n");
110*05b00f60SXin Li     if (cp == NULL)
111*05b00f60SXin Li         goto again;
112*05b00f60SXin Li     *cp = '\0';
113*05b00f60SXin Li     serv.s_name = p;
114*05b00f60SXin Li     p = strpbrk(p, " \t");
115*05b00f60SXin Li     if (p == NULL)
116*05b00f60SXin Li         goto again;
117*05b00f60SXin Li     *p++ = '\0';
118*05b00f60SXin Li     while (*p == ' ' || *p == '\t')
119*05b00f60SXin Li         p++;
120*05b00f60SXin Li     cp = strpbrk(p, ",/");
121*05b00f60SXin Li     if (cp == NULL)
122*05b00f60SXin Li         goto again;
123*05b00f60SXin Li     *cp++ = '\0';
124*05b00f60SXin Li     serv.s_port = htons((u_short)atoi(p));
125*05b00f60SXin Li     serv.s_proto = cp;
126*05b00f60SXin Li     q = serv.s_aliases = serv_aliases;
127*05b00f60SXin Li     cp = strpbrk(cp, " \t");
128*05b00f60SXin Li     if (cp != NULL)
129*05b00f60SXin Li         *cp++ = '\0';
130*05b00f60SXin Li     while (cp && *cp) {
131*05b00f60SXin Li         if (*cp == ' ' || *cp == '\t') {
132*05b00f60SXin Li             cp++;
133*05b00f60SXin Li             continue;
134*05b00f60SXin Li         }
135*05b00f60SXin Li         if (q < &serv_aliases[MAXALIASES - 1])
136*05b00f60SXin Li             *q++ = cp;
137*05b00f60SXin Li         cp = strpbrk(cp, " \t");
138*05b00f60SXin Li         if (cp != NULL)
139*05b00f60SXin Li             *cp++ = '\0';
140*05b00f60SXin Li     }
141*05b00f60SXin Li     *q = NULL;
142*05b00f60SXin Li     return (&serv);
143*05b00f60SXin Li }
144