-
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SOL - Added network check for URL, and (localurl="...")
- Loading branch information
Sam Lantinga
committed
Dec 1, 1999
1 parent
e039e64
commit 51da914
Showing
7 changed files
with
329 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
|
||
/* Network functions for the Loki Setup program */ | ||
|
||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <sys/types.h> | ||
#include <sys/time.h> | ||
#include <sys/wait.h> | ||
#include <sys/socket.h> | ||
#include <netinet/in.h> | ||
#include <arpa/inet.h> | ||
#include <netdb.h> | ||
#include <unistd.h> | ||
#include <string.h> | ||
#include <signal.h> | ||
|
||
#ifndef TEST_MAIN | ||
#include "install.h" | ||
#include "install_log.h" | ||
#endif | ||
#include "network.h" | ||
|
||
/* This is the structure we pass back as a lookup handle */ | ||
struct _URLlookup { | ||
int pid; | ||
int fd; | ||
}; | ||
|
||
/* Utility function to connect to a URL and return a status */ | ||
int connect_url(const char *url) | ||
{ | ||
char *proto; | ||
char *host; | ||
char *string; | ||
char *bufp; | ||
int sock; | ||
struct sockaddr_in socka; | ||
short portnum; | ||
|
||
/* Copy the string */ | ||
string = strdup(url); | ||
|
||
/* Check for protocol and set default ports */ | ||
proto = NULL; | ||
bufp = strstr(string, "://"); | ||
portnum = 0; | ||
if ( bufp ) { | ||
proto = string; | ||
*bufp = '\0'; | ||
string = bufp+3; | ||
if ( strcasecmp(proto, "ftp") == 0 ) { | ||
portnum = 21; | ||
} | ||
} | ||
|
||
/* We can always read files ... */ | ||
if ( (string[0] == '/') || | ||
(proto && (strcasecmp(proto, "file") == 0)) ) { | ||
return(0); | ||
} | ||
|
||
/* Strip the file part of the URL */ | ||
bufp = strchr(string, '/'); | ||
if ( bufp ) { | ||
*bufp = '\0'; | ||
} | ||
|
||
/* Extract any port number */ | ||
bufp = strchr(string, ':'); | ||
if ( bufp ) { | ||
*bufp++ = '\0'; | ||
portnum = atoi(bufp); | ||
} | ||
if ( portnum == 0 ) { | ||
portnum = 80; | ||
} | ||
|
||
/* The rest of the string should be the hostname - resolve it */ | ||
host = string; | ||
#ifdef TEST_MAIN | ||
printf("Resolving %s port %d\n", host, portnum); | ||
#endif | ||
socka.sin_addr.s_addr = inet_addr(host); | ||
if ( socka.sin_addr.s_addr == INADDR_NONE ) { | ||
struct hostent *hp; | ||
|
||
hp = gethostbyname(host); | ||
if ( hp ) { | ||
memcpy(&socka.sin_addr.s_addr,hp->h_addr,hp->h_length); | ||
} else { | ||
#ifdef TEST_MAIN | ||
printf("Resolving failed!\n"); | ||
#endif | ||
return(-1); | ||
} | ||
} | ||
socka.sin_port = htons(portnum); | ||
socka.sin_family = AF_INET; | ||
|
||
/* Now try to create a socket and connect */ | ||
#ifdef TEST_MAIN | ||
printf("Connecting to remote host\n"); | ||
#endif | ||
sock = socket(AF_INET, SOCK_STREAM, 0); | ||
if ( sock < 0 ) { | ||
return(-1); | ||
} | ||
if ( connect(sock, (struct sockaddr *)&socka, sizeof(socka)) < 0 ) { | ||
#ifdef TEST_MAIN | ||
printf("Connect failed!\n"); | ||
#endif | ||
return(-1); | ||
} | ||
close(sock); | ||
|
||
/* Hey, we successfully connected! */ | ||
#ifdef TEST_MAIN | ||
printf("Connect succeeded!\n"); | ||
#endif | ||
return(0); | ||
} | ||
|
||
/* This does a non-blocking network check of a URL | ||
It returns a socket file descriptor which is passed to wait_network(), | ||
or -1 if an error occurred while setting up the network check. | ||
*/ | ||
#ifdef TEST_MAIN | ||
URLlookup *open_lookup(const char *url) | ||
#else | ||
URLlookup *open_lookup(install_info *info, const char *url) | ||
#endif | ||
{ | ||
URLlookup *lookup; | ||
int pipe_fds[2]; | ||
|
||
/* Allocate a network lookup handle */ | ||
lookup = (URLlookup *)malloc(sizeof *lookup); | ||
if ( lookup == NULL ) { | ||
#ifdef TEST_MAIN | ||
fprintf(stderr, "Out of memory, no network check\n"); | ||
#else | ||
log_warning(info, "Out of memory, no network check"); | ||
#endif | ||
return(NULL); | ||
} | ||
|
||
/* Create a pipe for IPC */ | ||
if ( pipe(pipe_fds) < 0 ) { | ||
#ifdef TEST_MAIN | ||
fprintf(stderr, "Unable to create pipe, no network check\n"); | ||
#else | ||
log_warning(info, "Unable to create pipe, no network check"); | ||
#endif | ||
free(lookup); | ||
return(NULL); | ||
} | ||
lookup->fd = pipe_fds[0]; | ||
|
||
/* Fork and do a lookup and connect */ | ||
lookup->pid = fork(); | ||
switch (lookup->pid) { | ||
case -1: /* Error... */ | ||
#ifdef TEST_MAIN | ||
fprintf(stderr, "Fork failed, no network check\n"); | ||
#else | ||
log_warning(info, "Fork failed, no network check"); | ||
#endif | ||
close(pipe_fds[0]); | ||
close(pipe_fds[1]); | ||
lookup->fd = -1; | ||
break; | ||
|
||
case 0: /* Child, do lookup and connect */ | ||
close(pipe_fds[0]); | ||
if ( connect_url(url) < 0 ) { | ||
write(pipe_fds[1], "n", 1); | ||
} else { | ||
write(pipe_fds[1], "y", 1); | ||
} | ||
exit(0); | ||
|
||
default: /* Parent, return okay */ | ||
close(pipe_fds[1]); | ||
break; | ||
} | ||
if ( lookup->fd < 0 ) { | ||
free(lookup); | ||
lookup = NULL; | ||
} | ||
return lookup; | ||
} | ||
|
||
/* This checks the status of a URL lookup */ | ||
int poll_lookup(URLlookup *handle) | ||
{ | ||
char response; | ||
fd_set fdset; | ||
struct timeval tv; | ||
int ready; | ||
int status; | ||
|
||
/* Check to see if the child process is ready */ | ||
FD_ZERO(&fdset); | ||
FD_SET(handle->fd, &fdset); | ||
memset(&tv, 0, (sizeof tv)); | ||
if ( select(handle->fd+1, &fdset, NULL, NULL, &tv) == 1 ) { | ||
ready = 1; | ||
} else { | ||
ready = 0; | ||
} | ||
#ifdef TEST_MAIN | ||
printf("URL check is %s\n", ready ? "ready" : "not ready"); | ||
#endif | ||
status = 0; | ||
|
||
/* See whether the lookup has succeeded */ | ||
if ( ready ) { | ||
if ( read(handle->fd, &response, 1) == 1 ) { | ||
if ( response == 'y' ) { | ||
status = 1; | ||
} | ||
} | ||
} | ||
return status; | ||
} | ||
|
||
/* This closes a previously opened URL lookup */ | ||
void close_lookup(URLlookup *handle) | ||
{ | ||
close(handle->fd); | ||
kill(handle->pid, SIGTERM); | ||
wait(NULL); | ||
free(handle); | ||
} | ||
|
||
#ifdef TEST_MAIN | ||
|
||
int main(int argc, char *argv[]) | ||
{ | ||
URLlookup *lookup; | ||
|
||
if ( argc != 3 ) { | ||
fprintf(stderr, "Usage: %s <delay> <url>\n", argv[0]); | ||
exit(1); | ||
} | ||
|
||
lookup = open_lookup(argv[2]); | ||
if ( lookup == NULL ) { | ||
fprintf(stderr, "Couldn't set up network check\n"); | ||
exit(2); | ||
} | ||
sleep(atoi(argv[1])); | ||
|
||
printf("Checking URL... \n"); | ||
if ( poll_lookup(lookup) ) { | ||
printf("URL okay\n"); | ||
} else { | ||
printf("URL not okay\n"); | ||
} | ||
close_lookup(lookup); | ||
exit(0); | ||
} | ||
|
||
#endif |
Oops, something went wrong.