11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 61dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions of source code must retain the above copyright 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * * Redistributions in binary form must reproduce the above copyright 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * the documentation and/or other materials provided with the 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * distribution. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/cdefs.h> 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <sys/types.h> 30a90528ad3420c571987f2124955646dae88007b6Chih-Wei Huang#include <endian.h> 3105fc1d7050d5451aea08dc5f504d2670287b2d43Elliott Hughes#include <malloc.h> 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <netdb.h> 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "servent.h" 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include "services.h" 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectsetservent(int f) 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 391dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_static rs = __res_get_static(); 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (rs) { 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent_ptr = NULL; 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectvoid 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectendservent(void) 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* nothing to do */ 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct servent * 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgetservent_r( res_static rs ) 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const char* p; 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project const char* q; 561dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int namelen; 571dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int nn,count; 581dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int total = 0; 592735b33519595da5d51b79757ccce730021a9228David 'Digit' Turner int port; 601dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project char* p2; 611dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 621dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p = rs->servent_ptr; 631dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (p == NULL) 641dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p = _services; 651dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project else if (p[0] == 0) 661dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return NULL; 671dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 681dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* first compute the total size */ 691dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project namelen = p[0]; 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project total += namelen + 1; 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project q = p + 1 + namelen + 3; /* skip name + port + proto */ 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project count = q[0]; /* get aliascount */ 731dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project q += 1; 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project total += (count+1)*sizeof(char*); 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (nn = 0; nn < count; nn++) { 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int len2 = q[0]; 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project total += 1 + len2; 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project q += 1 + len2; 801dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* reallocate the thread-specific servent struct */ 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p2 = realloc( (char*)rs->servent.s_aliases, total ); 841dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (p2 == NULL) 851dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return NULL; 861dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 871dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* now write to it */ 881dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent.s_aliases = (char**) p2; 891dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p2 += (count+1)*sizeof(char*); 901dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent.s_name = p2; 911dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p2 += namelen + 1; 921dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent.s_proto = p2; 931dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 941dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* copy name + port + setup protocol */ 951dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memcpy( rs->servent.s_name, p+1, namelen ); 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent.s_name[namelen] = 0; 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p += 1 + namelen; 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 992735b33519595da5d51b79757ccce730021a9228David 'Digit' Turner /* s_port must be in network byte order */ 1002735b33519595da5d51b79757ccce730021a9228David 'Digit' Turner port = ((((unsigned char*)p)[0] << 8) | 1012735b33519595da5d51b79757ccce730021a9228David 'Digit' Turner ((unsigned char*)p)[1]); 1022735b33519595da5d51b79757ccce730021a9228David 'Digit' Turner 1032735b33519595da5d51b79757ccce730021a9228David 'Digit' Turner rs->servent.s_port = htons(port); 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent.s_proto = p[2] == 't' ? "tcp" : "udp"; 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p += 4; /* skip port(2) + proto(1) + aliascount(1) */ 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project for (nn = 0; nn < count; nn++) { 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project int len2 = p[0]; 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent.s_aliases[nn] = p2; 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project memcpy( p2, p+1, len2 ); 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p2[len2] = 0; 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p2 += len2 + 1; 1131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project p += len2 + 1; 1141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project } 1151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent.s_aliases[nn] = NULL; 1161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project rs->servent_ptr = p; 1181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return &rs->servent; 1201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 1211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectstruct servent * 1231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectgetservent(void) 1241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project{ 1251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project res_static rs = __res_get_static(); 1261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project if (rs == NULL) return NULL; 1281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project return getservent_r(rs); 1301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project} 131