void send_ack(PACKET file_packet [], PACKET* ack_packet, int sock, struct sockaddr_in *serv_addr, int *getp, int need) { struct sockaddr_in from_addr; int from_addr_len; PACKET *rec_packet; int seq; rec_packet = (PACKET *) malloc (sizeof (*rec_packet)); from_addr_len = sizeof(from_addr); seq = ack_packet->sequence; while (need > 0) { ack_packet->control = RETR; ack_packet->sequence = (getp[need]); if (sendto(sock, ack_packet, sizeof(*ack_packet), 0, (struct sockaddr *) serv_addr, sizeof(*serv_addr)) <= 0) die_with_error("send error"); if (recvfrom(sock, rec_packet, sizeof(*rec_packet), 0, (struct sockaddr *) &from_addr, &from_addr_len) <= 0) die_with_error("recvfrom() error"); file_packet[(getp[need]) % 5] = *rec_packet; need--; } ack_packet->control = (ACK); ack_packet->sequence = seq; strcpy(ack_packet->data, "ack"); ack_packet->loadsize = (strlen("ack")); if (sendto(sock, ack_packet, sizeof(*ack_packet), 0, (struct sockaddr *) serv_addr, sizeof(*serv_addr)) <= 0) die_with_error("send error"); } /* send_ack(PACKET*, int) */
/***************************************************************************** * @name * @description * @param * @return */ void send_sip_invite(sip_session_t *session) { int l; char *s; struct sockaddr_in addr; s = gen_call_id(session); session->call->id = (char *) malloc(strlen(s)*sizeof(char)); memcpy(session->call->id,s,strlen(s)); session->call->socket = open_udp_socket(session->localip,0); l = sizeof(addr); if(getsockname(session->call->socket,(struct sockaddr *) &addr,(socklen_t *) &l)) die_with_error("getsockname() failed"); session->call->sport = ntohs(addr.sin_port); s = mk_sip_msg(session,0,INVITE); if((l =sendto(session->socket,s,strlen(s)+1,0,(struct sockaddr *) &(session->addr), sizeof(session->addr)) ) != strlen(s)+1) die_with_error("sendto() failed"); session->prev_state = REGISTERED; session->curr_state = INVITING; }
int main(int argc, char **argv) { int server_sock; int client_sock; pthread_t thread_id; struct thread_args_t *thread_args; server_sock = create_server_socket(SERVERPORT); for (;;) { client_sock = accept_connection(server_sock); // Create separate memory for client argument if ((thread_args = (struct thread_args_t *)malloc(sizeof(struct thread_args_t))) == 0) die_with_error("malloc() failed"); thread_args->client_sock = client_sock; // Create client thread if (pthread_create(&thread_id, 0, thread_main, (void *)thread_args) != 0) die_with_error("pthread_create() failed"); printf("...with thread %lu\n", (unsigned long)thread_id); } /* This point is never reached. */ return 0; }
int create_server_socket(unsigned short port) { int sock; struct sockaddr_in serv_addr; // Create socket if ((sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) die_with_error("socket() failed"); // Setup local address structure memset(&serv_addr, 0, sizeof(serv_addr)); serv_addr.sin_family = AF_INET; serv_addr.sin_addr.s_addr = htonl(INADDR_ANY); serv_addr.sin_port = htons(port); // Bind socket to local address structure if (bind(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) die_with_error("bind() failed"); // Make socket listen for incoming connections if (listen(sock, MAXPENDING) < 0) die_with_error("listen() failed"); return sock; }
void WSTask(){ int s; int suspended = 0; int counter = 0; long read,total; INT8U err; alt_u16 buff[BUFFER_SIZE]; //Setup connection to server struct sockaddr_in result; memset(&result, 0, sizeof(struct sockaddr_in)); result.sin_family = AF_INET; result.sin_port = htons(MY_PORT); net_aton("198.23.158.70", &(result.sin_addr)); //Test the connection s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { sendToLCD("Client: cannot open socket"); die_with_error(""); } if (connect(s, (struct sockaddr *) &result, sizeof(result))) { sendToLCD("No connection"); die_with_error(""); } close(s); while (1) { if (counter >= BUFFER_SIZE){ s = socket(AF_INET, SOCK_STREAM, 0); if (s < 0) { sendToLCD("Client: cannot open socket"); OSTaskDel(HTTP_PRIO); } if (connect(s, (struct sockaddr *) &result, sizeof(result))) { die_with_error(""); OSTaskDel(HTTP_PRIO); } read = write(s,buff, counter); total += read; if( read < 0 ){ sendToLCD("Lost connection"); die_with_error(""); } printf("Sent %d bytes to client. Total: %d\n", read, total); close(s); counter = 0; } int fill_level; while((fill_level = altera_avalon_fifo_read_level(INTERNET_FIFO_OUT_BASE)) > 0 && counter < BUFFER_SIZE){ buff[counter] = (alt_u16) altera_avalon_fifo_read_fifo(INTERNET_FIFO_OUT_BASE,INTERNET_FIFO_IN_CSR_BASE); counter++; } } }
/* This is pid 1 in the app sandbox. It is needed because we're using * pid namespaces, and someone has to reap zombies in it. We also detect * when the initial process (pid 2) dies and report its exit status to * the monitor so that it can return it to the original spawner. * * When there are no other processes in the sandbox the wait will return * ECHILD, and we then exit pid 1 to clean up the sandbox. */ static int do_init (int event_fd, pid_t initial_pid) { int initial_exit_status = 1; LockFile *lock; for (lock = lock_files; lock != NULL; lock = lock->next) { int fd = open (lock->path, O_RDONLY | O_CLOEXEC); struct flock l = {0}; if (fd == -1) die_with_error ("Unable to open lock file %s", lock->path); l.l_type = F_RDLCK; l.l_whence = SEEK_SET; l.l_start = 0; l.l_len = 0; if (fcntl (fd, F_SETLK, &l) < 0) die_with_error ("Unable to lock file %s", lock->path); /* Keep fd open to hang on to lock */ } while (TRUE) { pid_t child; int status; child = wait (&status); if (child == initial_pid && event_fd != -1) { uint64_t val; int res UNUSED; if (WIFEXITED (status)) initial_exit_status = WEXITSTATUS(status); val = initial_exit_status + 1; res = write (event_fd, &val, 8); /* Ignore res, if e.g. the parent died and closed event_fd we don't want to error out here */ } if (child == -1 && errno != EINTR) { if (errno != ECHILD) die_with_error ("init wait()"); break; } } return initial_exit_status; }
int main(int argc, char *argv[]) { int srv_sock, clnt_sock = 0; unsigned int clnt_len; struct sockaddr_in srv_addr, clnt_addr; struct client_handler_data *next_clnt; // Create our listen socket if((srv_sock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) die_with_error("socket() failed!"); // Create the address structure memset(&srv_addr, 0, sizeof(srv_addr)); srv_addr.sin_family = AF_INET; srv_addr.sin_addr.s_addr = htonl(INADDR_ANY); srv_addr.sin_port = htons(DID_DEFAULT_PORT); // Bind to the address we just specified if((bind(srv_sock, (struct sockaddr *)(&srv_addr), sizeof(srv_addr)) < 0)) die_with_error("bind() failed!\n"); // Listen for connections if((listen(srv_sock, MAX_PENDING) < 0)) die_with_error("listen() failed!"); for(;;) { // When we receive a connection from a a client, make a new thread to handle them clnt_len = sizeof(clnt_addr); if((clnt_sock = accept(srv_sock, (struct sockaddr *)(&clnt_addr), &clnt_len)) < 0) die_with_error("accept() failed!"); next_clnt = (struct client_handler_data *)malloc(sizeof(struct client_handler_data)); next_clnt->sock = clnt_sock; if(curr_clients++ < MAX_CLIENTS) { pthread_create(&(next_clnt->thread), NULL, handle_client, (void *)next_clnt); } else printf("Client refused! Too many clients are connected!"); } // We should never reach this. Yet. pthread_exit(NULL); exit(0); }
static void child(int pty_master_fd, int pty_child_fd) { if (close(pty_master_fd) == -1) { die_with_error("close[master]"); } struct termios term_settings; if (tcgetattr(pty_child_fd, &term_settings) == -1) { die_with_error("tcgetattr"); } cfmakeraw(&term_settings); if(tcsetattr(pty_child_fd, TCSANOW, &term_settings) == -1) { die_with_error("tcsetattr"); } if (dup2(pty_child_fd, 0) == -1) { die_with_error("dup2 [stdin]"); } if (dup2(pty_child_fd, 1) == -1) { die_with_error("dup2 [stdout]"); } if (dup2(pty_child_fd, 2) == -1) { die_with_error("dup2 [stderr]"); } if (close(pty_child_fd) == -1) { die_with_error("close[child]"); } if (setsid() == -1) { die_with_error("setsid"); } if (ioctl(0, TIOCSCTTY, 1) == -1) { die_with_error("ioctl"); } const char * shell = get_shell(); char * const * args = calloc(0, sizeof(char *)); if (execv(shell, args) == -1) { die_with_error("execv"); } }
void send_file(FILE * fid, char * f_name, int sock, struct sockaddr_in *serv_addr) { PACKET * packet; PACKET * data_packet; packet = (PACKET *) malloc (sizeof(*packet)); data_packet = (PACKET *) malloc (sizeof(*data_packet)); int count = 0; struct sockaddr_in from_addr; int from_addr_len = sizeof(from_addr); packet->control = PUT; strcpy(packet->data, f_name); packet->loadsize = strlen(f_name); packet->sequence = 0; //printf("%s", packet->data); if (sendto(sock, packet, sizeof(*packet), 0, (struct sockaddr *) serv_addr, sizeof(*serv_addr)) <= 0) die_with_error("send error"); if (recvfrom(sock, packet, sizeof(*packet), 0, (struct sockaddr *) &from_addr, &from_addr_len) <= 0) die_with_error("recvfrom error"); char line[30]; while (fgets(line, sizeof(line), fid) != NULL) { count++; data_packet->control = DATA; memcpy(data_packet->data, line, sizeof(line)); //strcpy(data_packet->data, line); data_packet->loadsize = strlen(line); data_packet->sequence = count; if (sendto(sock, data_packet, sizeof(*data_packet), 0, (struct sockaddr *) serv_addr, sizeof(*serv_addr)) <= 0) die_with_error("send error"); //printf("%s", line); //count++; if (count % 5 == 0) { if (recvfrom(sock, packet, sizeof(*packet), 0, (struct sockaddr *) &from_addr, &from_addr_len) <= 0) die_with_error("recvfrom error"); } } packet->control = ACK; if (sendto(sock, packet, sizeof(*packet), 0, (struct sockaddr *) serv_addr, sizeof(*serv_addr)) <= 0) die_with_error("recvfrom error"); }
static uint32_t read_priv_sec_op (int read_socket, void *buffer, size_t buffer_size, uint32_t *flags, const char **arg1, const char **arg2) { const PrivSepOp *op = (const PrivSepOp *)buffer; ssize_t rec_len; do rec_len = read (read_socket, buffer, buffer_size - 1); while (rec_len == -1 && errno == EINTR); if (rec_len < 0) die_with_error ("Can't read from unprivileged helper"); if (rec_len < sizeof (PrivSepOp)) die ("Invalid size %zd from unprivileged helper", rec_len); /* Guarantee zero termination of any strings */ ((char *)buffer)[rec_len] = 0; *flags = op->flags; *arg1 = resolve_string_offset (buffer, rec_len, op->arg1_offset); *arg2 = resolve_string_offset (buffer, rec_len, op->arg2_offset); return op->op; }
void* handle_tcp_client(void *client_socket_ptr) { int client_socket = *((int *) client_socket_ptr); free(client_socket_ptr); /* malloc was made before starting this thread */ char square_buffer[RCVBUFSIZE]; /* Buffer for square string */ int recv_msg_size; /* Size of received message */ while (TRUE) { /* Receive message from client */ recv_msg_size = recv(client_socket, square_buffer, RCVBUFSIZE - 1, 0); handle_error(recv_msg_size, "recv() failed", PROCESS_EXIT); if (recv_msg_size == 0) { /* zero indicates end of transmission */ break; } square_buffer[recv_msg_size] = '\000'; /* Send received string and receive again until end of transmission */ /* Square message and send it back to client */ int x = atoi(square_buffer); int y = x*x; sprintf(square_buffer, "%12d", y); int send_msg_size = strlen(square_buffer); ssize_t sent_size = send(client_socket, square_buffer, send_msg_size, 0); if (sent_size != recv_msg_size) { die_with_error("send() failed"); } /* See if there is more data to receive in the next round...*/ } close(client_socket); /* Close client socket */ return NULL; }
static void parent(int pty_master_fd, int pty_child_fd) { if (close(pty_child_fd) == -1) { die_with_error("close [child]"); } // TODO start up sdl, gl and madness! }
VkResult wait_for_event(VkEvent event, u64 timeout) { u64 t = 0; while (true) { switch (const auto status = vkGetEventStatus(*g_current_renderer, event)) { case VK_EVENT_SET: return VK_SUCCESS; case VK_EVENT_RESET: break; default: die_with_error(HERE, status); return status; } if (timeout) { if (!t) { t = get_system_time(); continue; } if ((get_system_time() - t) > timeout) { LOG_ERROR(RSX, "[vulkan] vk::wait_for_event has timed out!"); return VK_TIMEOUT; } } //std::this_thread::yield(); _mm_pause(); } }
static void acquire_caps (void) { struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 }; struct __user_cap_data_struct data[2] = { { 0 } }; if (capget (&hdr, data) < 0) die_with_error ("capget failed"); if (((data[0].effective & REQUIRED_CAPS_0) == REQUIRED_CAPS_0) && ((data[0].permitted & REQUIRED_CAPS_0) == REQUIRED_CAPS_0) && ((data[1].effective & REQUIRED_CAPS_1) == REQUIRED_CAPS_1) && ((data[1].permitted & REQUIRED_CAPS_1) == REQUIRED_CAPS_1)) is_privileged = TRUE; if (getuid () != geteuid ()) { /* Tell kernel not clear capabilities when dropping root */ if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) die_with_error ("prctl(PR_SET_KEEPCAPS) failed"); /* Drop root uid, but retain the required permitted caps */ if (setuid (getuid ()) < 0) die_with_error ("unable to drop privs"); } if (is_privileged) { /* Drop all non-require capabilities */ data[0].effective = REQUIRED_CAPS_0; data[0].permitted = REQUIRED_CAPS_0; data[0].inheritable = 0; data[1].effective = REQUIRED_CAPS_1; data[1].permitted = REQUIRED_CAPS_1; data[1].inheritable = 0; if (capset (&hdr, data) < 0) die_with_error ("capset failed"); } /* Else, we try unprivileged user namespaces */ /* We need the process to be dumpable, or we can't access /proc/self/uid_map */ if (prctl (PR_SET_DUMPABLE, 1, 0, 0, 0) < 0) die_with_error ("prctl(PR_SET_DUMPABLE) failed"); }
int main(int argc, char **argv) { int ret, config_defined = 0; char *config_file, *data_file; queue_t *data; if (argc < 2) usage(); while ((ret = getopt(argc, argv, "c:h")) != -1) { switch (ret) { case 'c': config_file = optarg; config_defined = 1; break; case 'h': usage(); break; default: die(1, "use -h for help\n"); } } if (config_defined) { if (argc == 2 || (argc == 3 && !strcmp(argv[1], "-c"))) usage(); } else config_file = CONFIG_FILE; data_file = argv[--argc]; if (!parse_config(config_file)) die(2, "could not parse config file\n"); ret = read_data(data_file, &data); if (ret) die_with_error(ret); ret = insert_data(config, data); if (ret) die_with_error(ret); exit(0); }
static void unblock_sigchild (void) { sigset_t mask; sigemptyset (&mask); sigaddset (&mask, SIGCHLD); if (sigprocmask (SIG_UNBLOCK, &mask, NULL) == -1) die_with_error ("sigprocmask"); }
static void drop_caps (void) { struct __user_cap_header_struct hdr = { _LINUX_CAPABILITY_VERSION_3, 0 }; struct __user_cap_data_struct data[2] = { { 0 } }; if (!is_privileged) return; if (capset (&hdr, data) < 0) die_with_error ("capset failed"); }
/** * handle_client: Main application layer thread for each client * @author ndemarinis (Basic implementation) */ void *handle_client(void *data) { struct client_handler_data *clnt = (struct client_handler_data *)data; int pipes[2]; // Make a pipe to connect to the layer stack int to_read, bytes_written; char read_buffer[PIPE_BUFFER_SIZE]; struct packet* pkt_in; pid_t clnt_pid; // PID we receive from the cilent before startup struct layer_stack *stack; // Work data for layer stack implementation memset(read_buffer, 0, PIPE_BUFFER_SIZE); // Receive the client's PID for use as an identifier. if((recv(clnt->sock, &clnt_pid, sizeof(pid_t), 0) != sizeof(pid_t))) die_with_error("Error receiving PID from client!"); stack = create_layer_stack(clnt->sock, clnt_pid, pipes); // Initialize all of our layer threads sleep(1); // Wait for the layer stack creation to settle for(;;) { // Just try and echo a message for now. printf("%d: APP: Starting a test read.\n\n", clnt_pid); // Grab a string if((to_read = read(pipe_read(pipes), read_buffer, PIPE_BUFFER_SIZE)) <= 0) { printf("%d: APP: Read 0 bytes from socket. Terminating!\n", clnt_pid); break; } pkt_in = (struct packet *)read_buffer; printf("%d: APP: Read packet of %d bytes with payload of %d bytes\n", clnt_pid, to_read, pkt_in->length); // Send it straight back printf("%d: APP: Sending packet of %d bytes back to client\n", clnt_pid, to_read); if((bytes_written = write(pipe_write(pipes), read_buffer, to_read)) <= 0) { printf("%d: APP: Wrote %d bytes, socket must have closed. Terminating!\n", clnt_pid, bytes_written); break; } } printf("%d: Client successfully terminated!\n", clnt_pid); pthread_exit(NULL); }
/***************************************************************************** * @name * @description * @param * @return */ void send_sip_register(sip_session_t *session, int exp) { int n; char *msg; msg = mk_sip_msg(session, exp, REGISTER); if ((n = sendto(session->socket, msg, strlen(msg) + 1, 0, (struct sockaddr *) &(session->addr), sizeof(session->addr))) != strlen(msg) + 1) die_with_error("sendto() failed"); free(msg); }
static void write_uid_gid_map (uid_t sandbox_uid, uid_t parent_uid, uid_t sandbox_gid, uid_t parent_gid, bool deny_groups) { cleanup_free char *uid_map = NULL; cleanup_free char *gid_map = NULL; uid_map = xasprintf ("%d %d 1\n", sandbox_uid, parent_uid); if (write_file_at (proc_fd, "self/uid_map", uid_map) != 0) die_with_error ("setting up uid map"); if (deny_groups && write_file_at (proc_fd, "self/setgroups", "deny\n") != 0) die_with_error ("error writing to setgroups"); gid_map = xasprintf ("%d %d 1\n", sandbox_gid, parent_gid); if (write_file_at (proc_fd, "self/gid_map", gid_map) != 0) die_with_error ("setting up gid map"); }
void die_unless_label_valid (const char *label) { #ifdef HAVE_SELINUX if (is_selinux_enabled () == 1) { if (security_check_context ((security_context_t) label) < 0) die_with_error ("invalid label %s", label); return; } #endif die ("labeling not supported on this system"); }
/***************************************************************************** * @name * @description * @param * @return */ void send_sip_bye(sip_session_t *session) { int n; char *s; s = mk_sip_msg(session,0,BYE); if((n =sendto(session->socket,s,strlen(s)+1,0,(struct sockaddr *) &(session->addr), sizeof(session->addr)) ) != strlen(s)+1) die_with_error("sendto() failed"); close(session->call->socket); session->prev_state = ONCALL; session->curr_state = BYE; }
int main (int argc, char *argv[]) { int fd; int skip_lines; off_t tar_start; nvidia_major_version = atoi (NVIDIA_VERSION); fd = open (NVIDIA_BASENAME, O_RDONLY); if (fd == -1) die_with_error ("open extra data"); skip_lines = find_skip_lines (fd); tar_start = find_line_offset (fd, skip_lines); if (lseek (fd, tar_start, SEEK_SET)!= tar_start) die ("Can't seek to tar"); extract (fd); close (fd); unlink (NVIDIA_BASENAME); if (nvidia_major_version > 367) { /* GLVND */ /* Default to nvidia */ symlink ("libGLX_nvidia.so." NVIDIA_VERSION, "libGLX_indirect.so.0"); /* unversioned */ symlink ("libEGL_nvidia.so." NVIDIA_VERSION, "libEGL_nvidia.so.0"); symlink ("libGLESv2_nvidia.so." NVIDIA_VERSION, "libGLESv2_nvidia.so.2"); symlink ("libGLX_nvidia.so." NVIDIA_VERSION, "libGLX_nvidia.so.0"); } else { /* Non GLVND */ symlink ("libEGL.so." NVIDIA_VERSION, "libEGL.so.1"); symlink ("libGL.so." NVIDIA_VERSION, "libGL.so.1"); symlink ("libglx.so." NVIDIA_VERSION, "libglx.so.1"); symlink ("libGLESv2.so." NVIDIA_VERSION, "libGLESv2.so.1"); } return 0; }
int accept_connection(int server_socket) { int client_sock; struct sockaddr_in client_addr; unsigned int client_len; client_len = sizeof(client_addr); // Wait for connection from some client if ((client_sock = accept(server_socket, (struct sockaddr *)&client_addr, &client_len)) < 0) die_with_error("accept() failed"); printf("Handling client %s\n", inet_ntoa(client_addr.sin_addr)); return client_sock; }
static int find_skip_lines (int fd) { char buffer[1024]; ssize_t size; char *line_start, *line_end, *buffer_end; char *skip_str = NULL; int skip_lines; size = pread (fd, buffer, sizeof buffer - 1, 0); if (size == -1) die_with_error ("read extra data"); buffer[size] = 0; /* Ensure zero termination */ buffer_end = buffer + size; line_start = buffer; while (line_start < buffer_end) { line_end = strchr (line_start, '\n'); if (line_end != NULL) { *line_end = 0; line_end += 1; } else line_end = buffer_end; if (has_prefix (line_start, "skip=")) { skip_str = line_start + 5; break; } line_start = line_end; } if (skip_str == NULL) die ("Can't find skip size"); skip_lines = atoi (skip_str); if (skip_lines == 0) die ("Can't parse skip=%s", skip_str); return skip_lines; }
static const char * get_shell() { char * shell = NULL; shell = getenv("SHELL"); if (shell != NULL) { return shell; } errno = 0; struct passwd * pw_ent = getpwent(); if (pw_ent == NULL && errno != 0) { die_with_error("getpwent"); } if (pw_ent != NULL && pw_ent->pw_shell != NULL) { return pw_ent->pw_shell; } return "/bin/sh"; }
/* Allocate memory for processes' argument lists. * @num_of_ps: number of processes */ void prepare_arg_lists(int num_of_ps) { int i; if (arr_ps_infos) { free(arr_ps_infos); arr_ps_infos = (PS_INFO *) NULL; } if (num_of_ps) { arr_ps_infos = (PS_INFO *) malloc(num_of_ps*sizeof(PS_INFO)); if (!arr_ps_infos) die_with_error("malloc"); /* initialize arr_ps_infos */ for (i = 0; i < num_of_ps; i++) { arr_ps_infos[i].argc = 0; arr_ps_infos[i].argv = (char **) NULL; } } }
VkResult wait_for_fence(VkFence fence, u64 timeout) { if (timeout) { return vkWaitForFences(*g_current_renderer, 1, &fence, VK_FALSE, timeout * 1000ull); } else { while (auto status = vkGetFenceStatus(*g_current_renderer, fence)) { switch (status) { case VK_NOT_READY: continue; default: die_with_error(HERE, status); return status; } } return VK_SUCCESS; } }
static off_t find_line_offset (int fd, int skip_lines) { off_t offset, buf_offset; int n_lines; ssize_t size; char buffer[16*1024]; offset = 0; buf_offset = 0; n_lines = 1; while (1) { size = pread (fd, buffer, sizeof buffer, offset); if (size == -1) die_with_error ("read data"); buf_offset = 0; while (buf_offset < size) { if (buffer[buf_offset] == '\n') { n_lines ++; if (n_lines == skip_lines) return offset + buf_offset + 1; } buf_offset++; } offset += size; } /* Should not happen */ return 0; }
ssize_t recv_header(int sockfd, char dest[]) { ssize_t bytes_rcvd = 0; ssize_t total_bytes_rcvd = 0; bool cr_flag = false; bool crlf_flag = false; char cbuf = '\0'; do { bytes_rcvd = recv(sockfd, &cbuf, 1, 0); if (bytes_rcvd < 0) die_with_error("recv() failed"); total_bytes_rcvd += bytes_rcvd; if (bytes_rcvd > 0) // Do a "-1" to account for the zero-indexed char array. dest[total_bytes_rcvd - 1] = cbuf; else break; if (cbuf != '\n') cr_flag = false; if (cbuf == '\r') cr_flag = true; if (cr_flag && cbuf == '\n') { dest[total_bytes_rcvd] = '\0'; crlf_flag = true; } } while (!crlf_flag); return total_bytes_rcvd; }