123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- #include <stdio.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <netdb.h> /* getprotobyname */
- #include <netinet/in.h>
- #include <stdbool.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <sys/time.h>
- #include <unistd.h>
- #define HOST_DNS_NAME "ifconfig.me"
- #define LENGHT_OF_SUBTRACT_STRING 14
- #define _XOPEN_SOURCE 255
- #define TIMEOUT_SECONDS 0.01
- #define DEBUG_MODE false
- #define ERROR_MODE false
- #define TIME_IN_SLEEP 0.01
- #define TIME_LIVE_LOOP_SLEEP 0.01
- void printStringWithOffset(const char* str, int start, int end) {
- int i = 0;
- for (i = start; i < end; i++) {
- write(STDERR_FILENO, &str[i], 1);
- }
- write(STDERR_FILENO, "\n", 2);
- }
- int
- request(char *hostname_arg) {
- char buffer[BUFSIZ];
- enum CONSTEXPR { MAX_REQUEST_LEN = 1024 };
- char request[MAX_REQUEST_LEN];
- char request_template[] = "GET / HTTP/1.1\r\nHost: %s\r\n\r\n";
- struct protoent *protoent;
- char *hostname = hostname_arg; // HOST_DNS_NAME
- in_addr_t in_addr;
- int request_len;
- int socket_file_descriptor;
- ssize_t nbytes_total, nbytes_last;
- struct hostent *hostent;
- struct sockaddr_in sockaddr_in;
- unsigned short server_port = 80;
- #if 0
- if (argc > 1)
- hostname = argv[1];
- if (argc > 2)
- server_port = strtoul(argv[2], NULL, 10);
- #endif
- request_len = snprintf(request, MAX_REQUEST_LEN, request_template, hostname);
- if (request_len >= MAX_REQUEST_LEN) {
- #if ERROR_MODE
- fprintf(stderr, "request length large: %d\n", request_len);
- #endif
- exit(EXIT_FAILURE);
- }
- // Set timeout for the socket
- struct timeval timeout;
- timeout.tv_sec = TIMEOUT_SECONDS;
- timeout.tv_usec = 0;
- setsockopt(socket_file_descriptor, SOL_SOCKET, SO_RCVTIMEO, (char *)&timeout,
- sizeof(timeout));
- /* Build the socket. */
- protoent = getprotobyname("tcp");
- if (protoent == NULL) {
- perror("getprotobyname");
- return -3;
- // exit(EXIT_FAILURE);
- }
- socket_file_descriptor = socket(AF_INET, SOCK_STREAM, protoent->p_proto);
- if (socket_file_descriptor == -1) {
- perror("socket");
- return -3;
- // exit(EXIT_FAILURE);
- }
- /* Build the address. */
- hostent = gethostbyname(hostname);
- if (hostent == NULL) {
- #if ERROR_MODE
- fprintf(stderr, "error: gethostbyname(\"%s\")\n", hostname);
- #endif
- return -3;
- // exit(EXIT_FAILURE);
- }
- in_addr = inet_addr(inet_ntoa(*(struct in_addr *)*(hostent->h_addr_list)));
- if (in_addr == (in_addr_t)-1) {
- #if ERROR_MODE
- fprintf(stderr, "error: inet_addr(\"%s\")\n", *(hostent->h_addr_list));
- #endif
- return -3;
- // exit(EXIT_FAILURE);
- }
- sockaddr_in.sin_addr.s_addr = in_addr;
- sockaddr_in.sin_family = AF_INET;
- sockaddr_in.sin_port = htons(server_port);
- /* Actually connect. */
- if (connect(socket_file_descriptor, (struct sockaddr *)&sockaddr_in,
- sizeof(sockaddr_in)) == -1) {
- perror("connect");
- return -3;
- // exit(EXIT_FAILURE);
- }
- /* Send HTTP request. */
- nbytes_total = 0;
- while (nbytes_total < request_len) {
- nbytes_last = write(socket_file_descriptor, request + nbytes_total,
- request_len - nbytes_total);
- if (nbytes_last == -1) {
- perror("write");
- return -3;
- // exit(EXIT_FAILURE);
- }
- nbytes_total += nbytes_last;
- }
- /* Read the response. */
- #if DEBUG_MODE
- fprintf(stderr, "debug: before first read\n");
- #endif
- // while ((nbytes_total = read(socket_file_descriptor, buffer, BUFSIZ)) > 0) {
- while (true) {
- fd_set read_fds;
- FD_ZERO(&read_fds);
- FD_SET(socket_file_descriptor, &read_fds);
- int select_result =
- select(socket_file_descriptor + 1, &read_fds, NULL, NULL, NULL);
- if (select_result == -1) {
- perror("Error in select");
- break;
- } else if (select_result == 0) {
- // Timeout or no data available
- break;
- }
- // Read from the socket
- nbytes_total = read(socket_file_descriptor, buffer, BUFSIZ);
- if (nbytes_total > 0) {
- #if DEBUG_MODE
- fprintf(stderr, "debug: after a read\n");
- #endif
- // write(STDOUT_FILENO, buffer, nbytes_total);
- printStringWithOffset(buffer, (nbytes_total-LENGHT_OF_SUBTRACT_STRING),nbytes_total);
- write(STDOUT_FILENO, "\n", 2);
- break;
- } else if (nbytes_total == 0) {
- // End of file reached
- break;
- } else {
- #if ERROR_MODE
- perror("Failed to read from the socket");
- #endif
- break;
- }
- // fprintf(stderr, "debug: after a read\n");
- // write(STDOUT_FILENO, buffer, nbytes_total);
- }
- #if DEBUG_MODE
- fprintf(stderr, "debug: after last read\n");
- #endif
- if (nbytes_total == -1) {
- perror("read");
- return 0;
- // exit(EXIT_FAILURE);
- }
- close(socket_file_descriptor);
- return 0;
- // exit(EXIT_SUCCESS);
- }
- int
- in_live_loop() {
- int i = 0;
- while(true) {
- request(HOST_DNS_NAME);
- sleep((unsigned int)TIME_IN_SLEEP);
- }
- return 0;
- }
- int
- live_loop() {
- int i = 0;
- for (i = 0; i < 10; i++) {
- request(HOST_DNS_NAME);
- sleep((unsigned int)TIME_LIVE_LOOP_SLEEP);
- }
- return 0;
- }
- int
- main () {
- in_live_loop();
- // live_loop();
- return 0;
- }
|