1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sal.hxx" 26 27 #include <pwd.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <time.h> 31 #include <pthread.h> 32 #include <netdb.h> 33 #include <sys/socket.h> 34 #include <netinet/in.h> 35 #include <arpa/inet.h> 36 #ifndef NETBSD 37 #include <shadow.h> 38 #endif 39 40 /* exercises some reentrant libc-fucntions */ 41 42 extern "C" 43 { 44 struct tm *localtime_r(const time_t *timep, struct tm *buffer); 45 struct passwd* getpwnam_r(char*, struct passwd*, char *, int); 46 struct spwd* getspnam_r(char*, struct spwd*, char *, int); 47 struct hostent *gethostbyname_r(const char *name, struct hostent *result, 48 char *buffer, int buflen, int *h_errnop); 49 } 50 51 static int go; 52 53 54 55 extern "C" void *workfunc1(void*) 56 { 57 char buffer[256]; 58 struct tm sttm; 59 time_t nepoch; 60 struct passwd stpwd; 61 struct hostent sthostent; 62 int nerr; 63 64 printf("starting thread 1 ...\n"); 65 while (go) { 66 getpwnam_r("hr", &stpwd, buffer, sizeof(buffer)); 67 gethostbyname_r("blauwal", &sthostent, buffer, sizeof(buffer), &nerr); 68 time(&nepoch); 69 localtime_r(&nepoch, &sttm); 70 } 71 return 0; 72 } 73 74 extern "C" void *workfunc2(void*) 75 { 76 char buffer[256]; 77 struct tm sttm; 78 time_t nepoch; 79 struct passwd stpwd; 80 struct hostent sthostent; 81 int nerr; 82 83 printf("starting thread 2 ...\n"); 84 while(go) { 85 getpwnam_r("mh", &stpwd, buffer, sizeof(buffer)); 86 gethostbyname_r("hr-1242", &sthostent, buffer, sizeof(buffer), &nerr); 87 time(&nepoch); 88 localtime_r(&nepoch, &sttm); 89 } 90 return 0; 91 } 92 93 94 extern int h_errno; 95 96 int main(int argc, char *argv[]) 97 { 98 char buffer[256]; 99 struct tm *ptm; 100 time_t nepoch; 101 struct passwd *pwd, *pres1; 102 #ifndef NETBSD 103 struct spwd *spwd, *pres2; 104 #endif 105 struct hostent *phostent, *pres3; 106 char **p; 107 108 pthread_t tid1,tid2; 109 int res1,res2; 110 111 go = 1; 112 113 pthread_create(&tid1, NULL, workfunc1, &res1); 114 pthread_create(&tid2, NULL, workfunc2, &res2); 115 116 pwd = (struct passwd*)malloc(sizeof(struct passwd)); 117 118 pres1 = getpwnam_r("hr", pwd, buffer, sizeof(buffer)); 119 120 sleep(3); 121 122 if (pres1) { 123 printf("Name: %s\n", pwd->pw_name); 124 printf("Passwd: %s\n", pwd->pw_passwd); 125 printf("Uid: %d\n", pwd->pw_uid); 126 printf("Gid: %d\n", pwd->pw_gid); 127 #ifdef NETBSD 128 printf("Change: %s", ctime(&pwd->pw_change)); 129 printf("Class: %s\n", pwd->pw_class); 130 #else 131 printf("Age: %s\n", pwd->pw_age); 132 printf("Comment: %s\n", pwd->pw_comment); 133 #endif 134 printf("Gecos: %s\n", pwd->pw_gecos); 135 printf("Dir: %s\n", pwd->pw_dir); 136 printf("Shell: %s\n", pwd->pw_shell); 137 } 138 else 139 printf("getpwnam_r() failed!\n"); 140 141 free(pwd); 142 143 #ifndef NETBSD 144 spwd = (struct spwd*)malloc(sizeof(struct spwd)); 145 146 pres2 = getspnam_r("hr", spwd, buffer, sizeof(buffer)); 147 148 if (pres2) { 149 printf("Name: %s\n", spwd->sp_namp); 150 printf("Passwd: %s\n", spwd->sp_pwdp); 151 printf("Last Change: %ld\n", spwd->sp_lstchg); 152 printf("Min: %ld\n", spwd->sp_min); 153 printf("Max: %ld\n", spwd->sp_max); 154 } 155 else 156 printf("getspnam_r() failed!\n"); 157 158 free(spwd); 159 #endif 160 161 ptm = (struct tm*)malloc(sizeof(struct tm)); 162 163 time(&nepoch); 164 localtime_r(&nepoch, ptm); 165 166 printf("Seconds: %d\n", ptm->tm_sec); 167 printf("Minutes: %d\n", ptm->tm_min); 168 printf("Hour: %d\n", ptm->tm_hour); 169 printf("Day of Month: %d\n", ptm->tm_mday); 170 printf("Month: %d\n", ptm->tm_mon); 171 printf("Year: %d\n", ptm->tm_year); 172 printf("Day of week: %d\n", ptm->tm_wday); 173 printf("Day in the year: %d\n", ptm->tm_yday); 174 printf("Daylight saving time: %d\n", ptm->tm_isdst); 175 #ifdef NETBSD 176 printf("Timezone: %s\n", ptm->tm_zone); 177 #else 178 printf("Timezone: %s\n", ptm->tm_name); 179 #endif 180 181 free(ptm); 182 183 phostent = (struct hostent*)malloc(sizeof(struct hostent)); 184 185 pres3 = gethostbyname_r("blauwal", phostent, buffer, sizeof(buffer), h_errno); 186 187 if (pres3) { 188 printf("Official Hostname: %s\n", phostent->h_name); 189 for ( p = phostent->h_aliases; *p != NULL; p++ ) 190 printf("Alias: %s\n", *p); 191 printf("Addresstype: %d\n", phostent->h_addrtype); 192 printf("Address length: %d\n", phostent->h_length); 193 if ( phostent->h_addrtype == AF_INET ) { 194 for ( p = phostent->h_addr_list; *p != NULL; *p++ ) 195 printf("Address: %s\n", inet_ntoa(**((in_addr**)p))); 196 } 197 } 198 199 200 /* test boundary conditions */ 201 char smallbuf[23]; /* buffer to small */ 202 pres3 = gethostbyname_r("blauwal", phostent, smallbuf, sizeof(smallbuf), h_errno); 203 if (!pres3) { 204 perror("Expect ERANGE"); 205 } 206 else 207 { 208 printf("ERROR: Check for buffersize went wrong\n"); 209 } 210 211 #ifdef NETBSD 212 char exactbuf[35]; 213 #else 214 char exactbuf[24]; /* should be exact the necessary size */ 215 #endif 216 pres3 = gethostbyname_r("blauwal", phostent, exactbuf, sizeof(exactbuf), &h_errno); 217 if (!pres3) { 218 perror("Check with exact buffersize"); 219 } 220 else 221 { 222 printf("Boundary check ok\n"); 223 } 224 225 /* test error conditions */ 226 pres3 = gethostbyname_r("nohost", phostent, buffer, sizeof(buffer), &h_errno); 227 if (!pres3) { 228 herror("Expect HOST_NOT_FOUND"); 229 } 230 else 231 { 232 printf("failed to detect non existant host\n"); 233 } 234 235 free(phostent); 236 go = 0; /* atomic enough for our purposes */ 237 238 pthread_join(tid1, NULL); 239 pthread_join(tid2, NULL); 240 241 exit(0); 242 } 243 244 245