static int rpt_rxtx(void) { int i; char *cp; FILE *file; char buf[256]; file= fopen(DEV_FILE, "r"); if (!file) { report_err("unable to open '%s'", DEV_FILE); return 1; } /* Skip two lines */ if (fgets(buf, sizeof(buf), file) == NULL || fgets(buf, sizeof(buf), file) == NULL) { report_err("unable to read from '%s'", DEV_FILE); fclose(file); return 1; } /* Copy two line */ for (i= 0; i<2; i++) { if (fgets(buf, sizeof(buf), file) == NULL) { report_err("unable to read from '%s'", DEV_FILE); fclose(file); return 1; } if (do_atlas) { /* Get rid of newline */ cp= strchr(buf, '\n'); if (cp) *cp= '\0'; if (i != 0) printf(" NEWLINE "); } fputs(buf, stdout); } fclose(file); return 0; }
THREAD_PROC client_writer(void *arg) { Client *C = (Client*) arg; EZS *E = C->E; char *msg; int rc; int no = C->no; THREAD_DETACH; THREAD_OKCANCEL; C->state++; tot_wt++; if (debug>1) fprintf(stderr, "new client_writer\n"); while (C->state) { msg = get_client_msg(C); if (msg) { rc = ezs_write(E, msg, strlen(msg)); if (debug) printf("[%d] sent %d bytes: %s\n", C->no, rc, msg); if (rc<=0) { report_err(E, "write"); if (ezs_geterror(E, NULL)==EZS_ERR_NO_CONNECTION) break; } } else sleep(1); } if (C->state==0) { ezs_disconnect(E); free_client(C); } else C->state = 0; tot_wt--; }
THREAD_PROC client_reader(void *arg) { Client *C = (Client*) arg; EZS *E = C->E; char rbuf[4096]; int nb; THREAD_DETACH; THREAD_OKCANCEL; C->state++; tot_rt++; if (debug>1) fprintf(stderr, "new client_thread\n"); while (C->state && ((nb=ezs_read(E, rbuf, 4095))>0)) { rbuf[nb] = '\0'; if (debug) printf("[%d] recv %d bytes: %s\n", C->no, nb, rbuf); } if ( nb<=0) report_err(E, "read"); /* THREAD_CANCEL(C->writer); */ if (C->state==0) { ezs_disconnect(E); free_client(C); } else C->state = 0; tot_rt--; }
/* server reader */ THREAD_PROC server_thread(void *arg) { EZS *E = (EZS*) arg; char rbuf[4096]; int nb; FILE *sp; THREAD_DETACH; fprintf(stderr, "server_reader\n"); ssl_session = ezs_get_session(E); if (ssl_session) { fprintf(stderr, "saving session\n"); sp = fopen("session.pem", "w"); fputs(ssl_session, sp); fclose(sp); } while ((nb=ezs_read(E, rbuf, 4095))>0) { rbuf[nb] = '\0'; printf("recv %d bytes: %s\n", nb, rbuf); if (!strncmp(rbuf, "#file ", 6)) { if (!receive_file(E, rbuf+6)) break; } } report_err(E, "read"); }
/* switch on user selected type, * if file type matches selected type, return non zero * this file matches */ int filter_type(char type, mode_t mode) { int matches = EXIT_FAILURE; switch (type) { case 'f': matches = S_ISREG(mode); break; case 'd': matches = S_ISDIR(mode); break; case 'b': matches = S_ISBLK(mode); break; case 'c': matches = S_ISCHR(mode); break; case 'p': matches = S_ISFIFO(mode); break; case 'l': matches = S_ISLNK(mode); break; case 's': matches = S_ISSOCK(mode); break; default: report_err("filter_type", &type); } return matches; }
static int rpt_ipv6(char *cache_name) { FILE *file; char *cp; char buf[256]; file= fopen(cache_name, "r"); if (!file) { report_err("unable to open '%s'", cache_name); return 1; } /* Copy all lines */ while (fgets(buf, sizeof(buf), file) != NULL) { if (do_atlas) { /* Get rid of newline */ cp= strchr(buf, '\n'); if (cp) *cp= '\0'; printf(" NEWLINE "); } fputs(buf, stdout); } fclose(file); return 0; }
int main(int argc, char *argv[]) { Connection conn; char filename[MAX_FILENAME]; int ctrl, first = TRUE; pid_t child; if (argc != 3) { fprintf(stderr, "syntax: %s <address> <port>\n", argv[0]); exit(-1); } //if (checkaddress(argv[1])) return -1; conn = conn_connect(argv[1], checkport(argv[2])); signal(SIGCHLD, signalHandler); signal(SIGINT, signalHandler); printf("Insert filename or <quit> to close the connection\n"); while (TRUE) { readline(filename, MAX_FILENAME); if (!strcmp(filename, "Q") || !strcmp(filename, "q")) { printf("Terminating connection with server...\n"); ctrl = conn_sends(conn, "QUIT\r\n"); if (ctrl == -1) return -1; ctrl = conn_close(conn); if (ctrl == -1) return -1; return 0; } if (!strcmp(filename, "A") || !strcmp(filename, "a")) { printf("Aborting connection with server...\n"); if (kill(child, SIGKILL)) report_err("Cannot terminate a child"); ctrl = conn_close(conn); if (ctrl == -1) return -1; return 0; } if (!first) wait(NULL); else first = FALSE; child = fork(); if (!child) { ctrl = requestFile(conn, filename); if (ctrl == -1) return -1; return 0; } } return 0; }
/** * filter on name and type * @param opts * @param currpath * @param num_glob_call */ void filter_results(struct opt_info * opts, char *currpath, int *num_glob_call) { glob_t gbuf; int typematches = 1; memset(&gbuf, 0, sizeof ( gbuf)); if (((*num_glob_call) == 0) && glob(opts->name_arg, 0, NULL, &gbuf) == 0) { for (size_t i = 0; i < gbuf.gl_pathc; i++) { if (opts->type_flag) { /* looking for type? */ struct stat pstat; /* make sure you can open the file */ if (stat(gbuf.gl_pathv[i], &pstat) < 0) { report_err("stat", gbuf.gl_pathv[i]); continue; } typematches = filter_type(opts->type_arg, pstat.st_mode); } if (typematches) { printf("%s/%s\n", currpath, gbuf.gl_pathv[i]); } } } (*num_glob_call)++; }
void fatal_err(EZS *E, char *msg) { report_err(E, msg); exit (1); }
static void dump_content (gchar * fname, gint ennum, gchar * enpage) { GRG_KEY key; glong len; gint err, fd; gchar *txt; #ifndef HAVE_TCGETATTR fprintf (stderr, "%s: %s\n", _("Warning"), _ ("it isn't possible to hide password typing; be extremely careful!")); #endif fd = grg_safe_open (fname); if (fd < 3) report_err (_("The selected file doesn't exists"), 0, 1, NULL); if (fd == GRG_OPEN_FILE_IRREGULAR) report_err (_("You've selected a directory or a symlink"), 0, 1, NULL); err = grg_validate_file_direct (gctx, fd); switch (err) { case GRG_OK: break; case GRG_MEM_ALLOCATION_ERR: report_err ("error: malloc failed. Probably this indicates a memory " "problem, such as resource exhaustion. Attempting " "to exit cleanly...", 0, 1, NULL); case GRG_ARGUMENT_ERR: report_err (_ ("Gringotts internal error. Cannot finish operation."), 0, 1, NULL); case GRG_READ_MAGIC_ERR: case GRG_READ_UNSUPPORTED_VERSION: report_err (_ ("This file doesn't seem to be a valid Gringotts one!"), 0, 1, NULL); case GRG_READ_FILE_ERR: report_err (_("Uh-oh! I can't read from the file!"), 0, 1, NULL); case GRG_READ_CRC_ERR: case GRG_READ_COMP_ERR: report_err (_("The file appears to be corrupted!"), 0, 1, NULL); #ifdef GRG_READ_TOO_BIG_ERR case GRG_READ_TOO_BIG_ERR: report_err (_("File is too big"), 0, 1, NULL); #endif default: if (err < 0) report_err (_ ("Gringotts internal error. Cannot finish operation."), 0, 1, NULL); } while (TRUE) { key = grg_get_cmdline_key (); if (!key) { report_err (_("You must enter a valid password!"), 0, 0, NULL); continue; } { guchar *unsigned_txt; err = grg_decrypt_file_direct (gctx, key, fd, &unsigned_txt, &len); txt = (gchar*)unsigned_txt; } grg_key_free (gctx, key); switch (err) { case GRG_OK: break; case GRG_MEM_ALLOCATION_ERR: report_err ("error: malloc failed. Probably this indicates a memory " "problem, such as resource exhaustion. Attempting " "to exit cleanly...", 0, 1, NULL); case GRG_ARGUMENT_ERR: report_err (_("Gringotts internal error. Cannot finish operation."), 0, 1, NULL); case GRG_READ_PWD_ERR: report_err (_("Wrong password! Re-enter it"), 0, 0, NULL); continue; case GRG_READ_ENC_INIT_ERR: report_err (_ ("Problem with libmcrypt, probably a faulty installation"), 0, 1, NULL); /*just to be sure... */ default: if (err < 0) report_err (_("Gringotts internal error. Cannot finish operation."), 0, 1, NULL); } if (!g_utf8_validate (txt, len, NULL)) { GRGFREE (txt, len); report_err (_ ("Saved data contain invalid UTF-8 chars"), 0, 1, NULL); } break; } close (fd); grg_entries_load_from_string (txt, NULL, FALSE); GRGFREE (txt, len); grg_entries_print (ennum, enpage); grg_entries_free (); }
void grg_parse_argv (gint argc, gchar * argv[], gchar ** filename, gboolean * rootCheck) { poptContext optCon; gchar *wipe, *etit; gint passes, ennum; gboolean dump, help, strongRnd; struct poptOption optionsTable[] = { {"help", 'h', POPT_ARG_NONE, &help, 1, _("shows the help"), NULL}, {"input-file", 'f', POPT_ARG_STRING, filename, 0, _("specify the input file to open"), _("FILE")}, #ifndef ROOT_FILTER {"allow-root", 's', POPT_ARG_NONE, rootCheck, 1, _("allow usage as root -- DANGEROUS"), NULL}, #endif {"strong-random", 'R', POPT_ARG_NONE, &strongRnd, 0, _("force use of /dev/random -- slower"), NULL}, {"dump", 'd', POPT_ARG_NONE, &dump, 0, _("dump the content of a file"), NULL}, {"entry-num", 0, POPT_ARG_INT, &ennum, 0, _("index of the entry to dump"), _("NUM")}, {"entry-title", 0, POPT_ARG_STRING, &etit, 0, _("title of the entry to dump"), _("TXT")}, {"wipe-file", 'w', POPT_ARG_STRING, &wipe, 0, _("securely wipe a file"), _("FILE")}, {"wipe-passes", 0, POPT_ARG_INT, &passes, 0, _("passes in file wiping"), _("NUM")}, {NULL, 0, 0, NULL, 0} }; *filename = NULL; wipe = NULL; etit = NULL; passes = 0; ennum = -1; *rootCheck = FALSE; strongRnd = FALSE; dump = FALSE; help = FALSE; optCon = poptGetContext (NULL, argc, (const char **) argv, optionsTable, 0); while (poptGetNextOpt (optCon) >= 0) ; if (help) { poptPrintHelp (optCon, stdout, 0); poptFreeContext (optCon); exit_freeing_ctx (1); } poptFreeContext (optCon); if (strongRnd) grg_ctx_set_security_lvl (gctx, GRG_SEC_PARANOIA); /*quite cerebrotic, I know. The idea is: to ensure that stdin isn't exploitable, the best way is to close and reopen it, so that any "abnormal" setting is wasted. Since it isn't possible to do this atomically, I check that the former file descriptor hasn't been opened in the while by someone that could pretend to "be" stdin.*/ if (!(wipe || dump)) { int canary; close (STDIN); canary = open ("/dev/null", O_RDONLY); if (canary != STDIN) exit_freeing_ctx (1); return; } /*wipe and dump operations are processed without returning to main() */ /*FIXME this should be in grg_safe.c */ #ifdef HAVE_ISATTY if (!isatty (STDIN)) { g_critical ("%s", _ ("It isn't possible to redirect data to stdin, as it is a potential security flaw.")); exit_freeing_ctx (1); } #endif if (!grg_security_filter (*rootCheck)) exit_freeing_ctx (1); if (wipe) { gint res; gchar c; if (!g_file_test (wipe, G_FILE_TEST_IS_REGULAR)) report_err (_("The file does not exist"), 0, 1, NULL); printf ("%s (y/n)", _("Are you sure you want to wipe this file?\n" "Its content will be securely erased, so no\n" "recover is possible.")); if (passes < 0 || passes > 32) passes = 8; c = getchar (); if (c != 'y' && c != 'Y') exit_freeing_ctx (0); res = grg_file_shred (wipe, passes); if (res < 0) report_err (_("File wiping failed"), 0, 1, NULL); exit_freeing_ctx (0); } if (dump) { if (!*filename) report_err (_ ("You must specify a file to dump (with the -f switch)"), 0, 1, NULL); dump_content (*filename, ennum, etit); exit_freeing_ctx (0); } }
/* recurse through starting directory * print out matching resources/types */ void search_dir(char *parentdir, char * dirname, struct opt_info * opts) { DIR *dir_ptr; /* an actual directory */ char currpath[PATH_MAX + 1]; int num_glob_call = 0; /* keep glob from running too many times */ if (parentdir != NULL && parentdir[0] != '\0') { /* keep current full path */ sprintf(currpath, "%s/%s", parentdir, dirname); } else { strcpy(currpath, dirname); } /* open the directory with name dirname, if not report and return * not necessarily a failure */ dir_ptr = opendir(dirname); if (!dir_ptr) { report_func_err(dirname); return; } int cherr = chdir(dirname); if (cherr != 0) { report_err("chdir", dirname); closedir(dir_ptr); // don't care about errors return; } for (;;) { struct dirent entry; struct dirent *next_dir; char *name; int err = readdir_r(dir_ptr, &entry, &next_dir); if (err != 0) { continue; } if (next_dir == NULL) { break; } name = next_dir->d_name; if ((strcmp(name, ".") == 0) || (strcmp(name, "..") == 0)) { continue; /* skip self and parents */ } else { filter_results(opts, currpath, &num_glob_call); } if (next_dir->d_type == DT_DIR) { /* only recurse thru directories */ search_dir(currpath, name, opts); /* RECURSION!!! */ } } closedir(dir_ptr); cherr = chdir(".."); if (cherr != 0) { report_err("chdir", ".."); return; } }
static int setup_ipv6_rpt(char *cache_name, int *need_report) { int i, r; char *cp, *cp1; char filename[80]; char buf1[1024]; char buf2[1024]; FILE *in_file, *out_file, *cache_file; *need_report= 0; if (strlen(cache_name) + strlen(SUFFIX) + 1 > sizeof(filename)) { report("cache name '%s' too long", cache_name); return 1; } strlcpy(filename, cache_name, sizeof(filename)); strlcat(filename, SUFFIX, sizeof(filename)); out_file= fopen(filename, "w"); if (out_file == NULL) { report_err("unable to create '%s'", filename); return 1; } /* Copy IF_INET6_FILE */ in_file= fopen(IF_INET6_FILE, "r"); if (in_file == NULL) { report_err("unable to open '%s'", IF_INET6_FILE); fclose(out_file); return 1; } while (r= fread(buf1, 1, sizeof(buf1), in_file), r > 0) { if (fwrite(buf1, 1, r, out_file) != r) { report_err("error writing to '%s'", filename); fclose(in_file); fclose(out_file); return 1; } } if (ferror(in_file)) { report_err("error reading from '%s'", IF_INET6_FILE); fclose(in_file); fclose(out_file); return 1; } fclose(in_file); /* Copy IPV6_ROUTE_FILE */ in_file= fopen(IPV6_ROUTE_FILE, "r"); if (in_file == NULL) { report_err("unable to open '%s'", IPV6_ROUTE_FILE); fclose(out_file); return 1; } while (fgets(buf1, sizeof(buf1), in_file) != NULL) { /* Cut out Ref and Use fields */ cp= buf1; for (i= 0; i<6; i++) { if (cp && cp[0] != '\0') cp= strchr(cp+1, ' '); } if (!cp && cp[0] == '\0') { report("bad data in '%s'", IPV6_ROUTE_FILE); fclose(in_file); fclose(out_file); return 1; } cp++; /* Find the end of the two fields */ cp1= cp; for (i= 0; i<2; i++) { if (cp1 && cp1[0] != '\0') cp1= strchr(cp1+1, ' '); } if (!cp1 && cp1[0] == '\0') { report("bad data in '%s'", IPV6_ROUTE_FILE); fclose(in_file); fclose(out_file); return 1; } cp1++; /* And delete the two fields */ memmove(cp, cp1, strlen(cp1)+1); if (fputs(buf1, out_file) == -1) { report_err("error writing to '%s'", filename); fclose(in_file); fclose(out_file); return 1; } } if (ferror(in_file)) { report_err("error reading from '%s'", IPV6_ROUTE_FILE); fclose(in_file); fclose(out_file); return 1; } fclose(in_file); /* Now check if the new file is different from the cache one */ fclose(out_file); cache_file= fopen(cache_name, "r"); if (cache_file == NULL) { /* Assume that any kind of error here calls for reporting */ *need_report= 1; } if (cache_file) { in_file= fopen(filename, "r"); if (in_file == NULL) { report_err("unable to open '%s'", filename); fclose(cache_file); return 1; } /* Compare them */ while (r= fread(buf1, 1, sizeof(buf1), cache_file), r > 0) { if (fread(buf2, 1, sizeof(buf2), in_file) != r) { /* Ignore errors, just report */ *need_report= 1; break; } if (memcmp(buf1, buf2, r) != 0) { /* Something changed, report */ *need_report= 1; break; } } /* Maybe something got added */ if (!*need_report) { if (fread(buf2, 1, sizeof(buf2), in_file) != 0) { *need_report= 1; } } fclose(cache_file); fclose(in_file); } if (*need_report) { if (rename(filename, cache_name) == -1) { report_err("renaming '%s' to '%s' failed", filename, cache_name); return 1; } } else { if (unlink(filename) == -1) { report_err("unlinking '%s' failed", filename); } } return 0; }
struct input_file *read_file_list (int argc, char **argv, int *nf_r, char *errstr) { struct input_file *list = (struct input_file *) NULL; FILE *fp = (FILE *) NULL; char line[16384], *av, *p, *s; int a, f, nf = 0; #ifndef _WIN32 glob_t gbuf; int rv, op; /* Init */ gbuf.gl_pathv = (char **) NULL; #endif int is_zip; #ifdef ZIPSUPPORT zip_t *z = (zip_t *) NULL; zip_error_t ze; struct zip_stat sb; int zerrno; int ent, nent; const char *name; int namelen; zip_uint8_t opsys; zip_uint32_t extattr; #endif /* Loop over arguments */ for(a = 0; a < argc; a++) { av = argv[a]; if(*av == '@') { /* @list form */ av++; /* skip past the @ */ is_zip = is_zip_file(av, errstr); if(is_zip < 0) goto error; if(is_zip) { #ifdef ZIPSUPPORT z = zip_open(av, 0, &zerrno); if(!z) { zip_error_init_with_code(&ze, zerrno); report_err(errstr, "zip_open: %s: %s", av, zip_error_strerror(&ze)); zip_error_fini(&ze); goto error; } nent = zip_get_num_entries(z, 0); if(nent < 0) { report_err(errstr, "zip_get_num_entries: %s", zip_strerror(z)); goto error; } for(ent = 0; ent < nent; ent++) { if(zip_stat_index(z, ent, 0, &sb)) { report_err(errstr, "zip_stat_index(%d): %s\n", ent, zip_strerror(z)); goto error; } if(zip_file_get_external_attributes(z, ent, 0, &opsys, &extattr)) { report_err(errstr, "zip_get_external_attributes(%d): %s\n", ent, zip_strerror(z)); goto error; } name = sb.name; namelen = strlen(name); if((opsys != ZIP_OPSYS_AMIGA && extattr & 0x10) || (namelen > 0 && name[namelen-1] == '/')) /* Is directory */ continue; /* Otherwise, add to list */ list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } s = strdup(name); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[nf].filename = s; list[nf].ient = ent; list[nf].iarg = a; list[nf].arg = av; nf++; } if(zip_close(z)) { report_err(errstr, "zip_close: %s", zip_strerror(z)); goto error; } z = (zip_t *) NULL; #else report_err(errstr, "not compiled with zip support"); goto error; #endif } else { fp = fopen(av, "r"); if(!fp) { report_syserr(errstr, "open: %s", av); goto error; } while(fgets(line, sizeof(line), fp)) { p = sstrip(line); if(*p) { list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } s = strdup(p); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[nf].filename = s; list[nf].ient = -1; list[nf].iarg = a; list[nf].arg = av; nf++; } } if(ferror(fp)) { report_syserr(errstr, "read: %s", av); goto error; } fclose(fp); fp = (FILE *) NULL; } } else { /* glob or single filename */ #ifndef _WIN32 rv = glob(av, 0, NULL, &gbuf); if(rv == 0) { /* succeeded */ /* Allocate block */ list = (struct input_file *) realloc(list, (nf+gbuf.gl_pathc) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } /* Zero out the new pointers */ memset(list+nf, 0, gbuf.gl_pathc * sizeof(struct input_file)); /* Record so we know to free them */ op = nf; nf += gbuf.gl_pathc; for(f = 0; f < gbuf.gl_pathc; f++) { s = strdup(gbuf.gl_pathv[f]); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[op].filename = s; list[op].ient = -1; list[op].iarg = a; list[op].arg = av; op++; } globfree(&gbuf); gbuf.gl_pathv = (char **) NULL; } else if(rv == GLOB_NOMATCH) { /* no match */ #endif /* _WIN32 */ /* Assume it's a single entry. */ list = (struct input_file *) realloc(list, (nf+1) * sizeof(struct input_file)); if(!list) { report_syserr(errstr, "realloc"); goto error; } s = strdup(av); if(!s) { report_syserr(errstr, "strdup"); goto error; } list[nf].filename = s; list[nf].ient = -1; list[nf].iarg = a; list[nf].arg = av; nf++; #ifndef _WIN32 } else { report_err(errstr, "glob error: %s", av); goto error; } #endif } } *nf_r = nf; return(list); error: if(fp) fclose(fp); #ifndef _WIN32 if(gbuf.gl_pathv) globfree(&gbuf); #endif #ifdef ZIPSUPPORT if(z) { zip_close(z); z = (zip_t *) NULL; } #endif if(list) { for(f = 0; f < nf; f++) if(list[f].filename) free((void *) list[f].filename); free((void *) list); } return((struct input_file *) NULL); }
int requestFile(Connection conn, char * filename) { char * request; char header[6]; int str_len = strlen(filename), fd, ctrl; uint32_t file_dim = 0, timestamp = 0; uint32_t file_dim_net = 0, timestamp_net = 0; XDR xdrsIn; FILE * streamIn; printf("\trequested file: %s\n", filename); request = malloc((str_len+6)*sizeof(*request)); sprintf(request, "GET %s\r\n", filename); ctrl = conn_sends(conn, request); free(request); if (ctrl == -1) return -1; ctrl = conn_recvn(conn, header, 1); if (ctrl == -1) return -1; if (*header == '+') { ctrl = conn_recvs(conn, header+1, 4, "\r\n"); if (ctrl == -1) return -1; ctrl = conn_recvn(conn, &file_dim_net, sizeof(file_dim)); if (ctrl == -1) return -1; ctrl = conn_recvn(conn, ×tamp_net, sizeof(timestamp)); if (ctrl == -1) return -1; file_dim = ntohl(file_dim_net); timestamp = ntohl(timestamp_net); printf("Received file dim: %u B\n", file_dim); printf("Received timestamp: %u\n", timestamp); fd = open(filename, O_RDWR | O_CREAT, 0644); if (fd == -1) { report_err("Cannot open the file"); return -1; } /* Receive the file */ streamIn = fdopen(dup(conn.sock), "r"); xdrstdio_create(&xdrsIn, streamIn, XDR_DECODE); ctrl = xdr_recvfile(&xdrsIn, fd, file_dim); if (ctrl == -1) return -1; xdr_destroy(&xdrsIn); fclose(streamIn); } else if (*header == '-') { ctrl = conn_recvs(conn, header+1, 5, "\r\n"); if (ctrl == -1) return -1; printf("Server response: [%s]\nTerminate.\n", header); return -1; } else { fprintf(stderr, "Response not recognized, terminate.\n"); return -1; } close(fd); return 0; }