void *process_connection(void *ptr) { char *server_ident = _ds_read_attribute(agent_config, "ServerIdent"); THREAD_CTX *TTX = (THREAD_CTX *) ptr; AGENT_CTX *ATX = NULL; char *input, *cmdline = NULL, *token, *ptrptr; buffer *message = NULL; char *parms=NULL, *p=NULL; int i, locked = -1, invalid = 0; int server_mode = SSM_DSPAM; char *argv[64]; char buf[1024]; int tries = 0; int argc = 0; FILE *fd = 0; if (_ds_read_attribute(agent_config, "ServerMode") && !strcasecmp(_ds_read_attribute(agent_config, "ServerMode"), "standard")) { server_mode = SSM_STANDARD; } if (_ds_read_attribute(agent_config, "ServerMode") && !strcasecmp(_ds_read_attribute(agent_config, "ServerMode"), "auto")) { server_mode = SSM_AUTO; } /* Initialize a file descriptor hook for dspam to use as stdout */ fd = fdopen(TTX->sockfd, "w"); if (!fd) { close(TTX->sockfd); goto CLOSE; } setbuf(fd, NULL); TTX->packet_buffer = buffer_create(NULL); if (TTX->packet_buffer == NULL) goto CLOSE; /* * Send greeting banner * in auto mode, we want to look like a regular LMTP server so we don't * cause any compatibility problems. in dspam mode, we can change this. */ snprintf(buf, sizeof(buf), "%d DSPAM %sLMTP %s %s", LMTP_GREETING, (server_mode == SSM_DSPAM) ? "D" : "", VERSION, (server_mode == SSM_DSPAM) ? "Authentication Required" : "Ready"); if (send_socket(TTX, buf)<=0) goto CLOSE; TTX->authenticated = 0; /* LHLO */ input = daemon_expect(TTX, "LHLO"); if (input == NULL) goto CLOSE; if (server_mode == SSM_AUTO && input[4]) { char buff[128]; /* * Auto-detect the server mode based on whether or not the ident is * assigned a password in dspam.conf */ snprintf(buff, sizeof(buff), "ServerPass.%s", input + 5); chomp(buff); if (_ds_read_attribute(agent_config, buff)) server_mode = SSM_DSPAM; else server_mode = SSM_STANDARD; } free(input); /* Advertise extensions */ if (daemon_extension(TTX, (server_ident) ? server_ident : "localhost.localdomain")<=0) goto CLOSE; if (daemon_extension(TTX, "PIPELINING")<=0) goto CLOSE; if (daemon_extension(TTX, "ENHANCEDSTATUSCODES")<=0) goto CLOSE; if (server_mode == SSM_DSPAM) if (daemon_extension(TTX, "DSPAMPROCESSMODE")<=0) goto CLOSE; if (daemon_reply(TTX, LMTP_OK, "", "SIZE")<=0) goto CLOSE; /* Main protocol loop */ while(1) { char processmode[256]; parms = NULL; /* Configure a new agent context for each pass */ ATX = calloc(1, sizeof(AGENT_CTX)); if (ATX == NULL) { LOG(LOG_CRIT, ERR_MEM_ALLOC); daemon_reply(TTX, LMTP_TEMP_FAIL, "4.3.0", ERR_MEM_ALLOC); goto CLOSE; } if (initialize_atx(ATX)) { LOG(LOG_ERR, ERR_AGENT_INIT_ATX); daemon_reply(TTX, LMTP_BAD_CMD, "5.3.0", ERR_AGENT_INIT_ATX); goto CLOSE; } /* MAIL FROM (and authentication, if SSM_DSPAM) */ processmode[0] = 0; while(!TTX->authenticated) { input = daemon_expect(TTX, "MAIL FROM"); if (RSET(input)) goto RSET; if (input == NULL) goto CLOSE; else { char *pass, *ident; chomp(input); if (server_mode == SSM_STANDARD) { TTX->authenticated = 1; ATX->mailfrom[0] = 0; _ds_extract_address(ATX->mailfrom, input, sizeof(ATX->mailfrom)); if (daemon_reply(TTX, LMTP_OK, "2.1.0", "OK")<=0) { free(input); goto CLOSE; } } else { char id[256]; pass = ident = NULL; id[0] = 0; if (!_ds_extract_address(id, input, sizeof(id))) { pass = strtok_r(id, "@", &ptrptr); ident = strtok_r(NULL, "@", &ptrptr); } if (pass && ident) { char *serverpass; char *ptr, *ptr2, *ptr3; snprintf(buf, sizeof(buf), "ServerPass.%s", ident); serverpass = _ds_read_attribute(agent_config, buf); snprintf(buf, sizeof(buf), "ServerPass.%s", ident); if (serverpass && !strcmp(pass, serverpass)) { TTX->authenticated = 1; /* Parse PROCESSMODE service tag */ ptr = strstr(input, "DSPAMPROCESSMODE=\""); if (ptr) { char *mode; int i; ptr2 = strchr(ptr, '"')+1; mode = ptr2; while((ptr3 = strstr(ptr2, "\\\""))) ptr2 = ptr3+2; ptr3 = strchr(ptr2+2, '"'); if (ptr3) ptr3[0] = 0; strlcpy(processmode, mode, sizeof(processmode)); ptr = processmode; for(i=0;ptr[i];i++) { if (ptr[i] == '\\' && ptr[i+1] == '"') { strcpy(ptr+i, ptr+i+1); } } LOGDEBUG("process mode: '%s'", processmode); } if (daemon_reply(TTX, LMTP_OK, "2.1.0", "OK")<=0) { free(input); goto CLOSE; } } } } free(input); if (!TTX->authenticated) { LOGDEBUG("fd %d authentication failure.", TTX->sockfd); if (daemon_reply(TTX, LMTP_AUTH_ERROR, "5.1.0", "Authentication Required")<=0) { free(input); goto CLOSE; } tries++; if (tries>=3) { struct timeval tv; tv.tv_sec = 5; tv.tv_usec = 0; select(0, NULL, NULL, NULL, &tv); goto CLOSE; } } } } /* MAIL FROM response */ snprintf(buf, sizeof(buf), "%d OK", LMTP_OK); argc = 1; argv[0] = "dspam"; argv[1] = 0; /* Load open-LMTP configuration parameters */ if (server_mode == SSM_STANDARD) { parms = _ds_read_attribute(agent_config, "ServerParameters"); if (parms) { p = strdup(parms); if (p) { token = strtok_r(p, " ", &ptrptr); while(token != NULL && argc<63) { argv[argc] = token; argc++; argv[argc] = 0; token = strtok_r(NULL, " ", &ptrptr); } } } } /* RCPT TO */ while(ATX->users->items == 0 || invalid) { free(cmdline); cmdline = daemon_getline(TTX, 300); while(cmdline && (!strncasecmp(cmdline, "RCPT TO:", 8) || !strncasecmp(cmdline, "RSET", 4))) { char username[256]; if (!strncasecmp(cmdline, "RSET", 4)) { snprintf(buf, sizeof(buf), "%d OK", LMTP_OK); if (send_socket(TTX, buf)<=0) goto CLOSE; goto RSET; } if (_ds_extract_address(username, cmdline, sizeof(username)) || username[0] == 0 || username[0] == '-') { daemon_reply(TTX, LMTP_BAD_CMD, "5.1.2", ERR_LMTP_BAD_RCPT); goto GETCMD; } if (_ds_match_attribute(agent_config, "Broken", "case")) lc(username, username); if (server_mode == SSM_DSPAM) { nt_add(ATX->users, username); } else { if (!parms || !strstr(parms, "--user ")) nt_add(ATX->users, username); if (!ATX->recipients) { ATX->recipients = nt_create(NT_CHAR); if (ATX->recipients == NULL) { LOG(LOG_CRIT, ERR_MEM_ALLOC); goto CLOSE; } } nt_add(ATX->recipients, username); } if (daemon_reply(TTX, LMTP_OK, "2.1.5", "OK")<=0) goto CLOSE; GETCMD: free(cmdline); cmdline = daemon_getline(TTX, 300); } if (cmdline == NULL) goto CLOSE; if (!strncasecmp(cmdline, "RSET", 4)) { snprintf(buf, sizeof(buf), "%d OK", LMTP_OK); if (send_socket(TTX, buf)<=0) goto CLOSE; goto RSET; } if (!strncasecmp(cmdline, "quit", 4)) { daemon_reply(TTX, LMTP_OK, "2.0.0", "OK"); goto CLOSE; } /* Parse DSPAMPROCESSMODE input and set up process arguments */ if (server_mode == SSM_DSPAM && processmode[0] != 0) { token = strtok_r(processmode, " ", &ptrptr); while(token != NULL && argc<63) { argv[argc] = token; argc++; argv[argc] = 0; token = strtok_r(NULL, " ", &ptrptr); } } invalid = 0; if (process_arguments(ATX, argc, argv) || apply_defaults(ATX)) { LOG(LOG_ERR, ERR_AGENT_INIT_ATX); daemon_reply(TTX, LMTP_NO_RCPT, "5.1.0", ERR_AGENT_INIT_ATX); invalid = 1; } else if (ATX->users->items == 0) { daemon_reply(TTX, LMTP_NO_RCPT, "5.1.1", ERR_AGENT_USER_UNDEFINED); } } ATX->sockfd = fd; ATX->sockfd_output = 0; /* Something's terribly misconfigured */ if (check_configuration(ATX)) { LOG(LOG_ERR, ERR_AGENT_MISCONFIGURED); daemon_reply(TTX, LMTP_BAD_CMD, "5.3.5", ERR_AGENT_MISCONFIGURED); goto CLOSE; } /* DATA */ if (strncasecmp(cmdline, "DATA", 4)) { if (daemon_reply(TTX, LMTP_BAD_CMD, "5.0.0", "Need DATA Here")<0) goto CLOSE; input = daemon_expect(TTX, "DATA"); if (input == NULL) goto CLOSE; if (RSET(input)) goto RSET; } if (daemon_reply(TTX, LMTP_DATA, "", INFO_LMTP_DATA)<=0) goto CLOSE; /* * Read in the message from a DATA. I personally like to just hang up on * a client stupid enough to pass in a NULL message for DATA, but you're * welcome to do whatever you want. */ message = read_sock(TTX, ATX); if (message == NULL || message->data == NULL || message->used == 0) { daemon_reply(TTX, LMTP_FAILURE, "5.2.0", ERR_LMTP_MSG_NULL); goto CLOSE; } /* * Lock a database handle. We currently use the modulus of the socket * id against the number of database connections in the cache. This * seems to work rather well, as we would need to lock up the entire * cache to wrap back around. And if we do wrap back around, that means * we're busy enough to justify spinning on the current lock (vs. seeking * out a free handle, which there likely are none). */ i = (TTX->sockfd % TTX->DTX->connection_cache); LOGDEBUG("using database handle id %d", i); if (TTX->DTX->flags & DRF_RWLOCK) { if (ATX->operating_mode == DSM_CLASSIFY || ATX->training_mode == DST_NOTRAIN || (ATX->training_mode == DST_TOE && ATX->classification == DSR_NONE)) { pthread_rwlock_rdlock(&TTX->DTX->connections[i]->rwlock); } else { pthread_rwlock_wrlock(&TTX->DTX->connections[i]->rwlock); } } else { pthread_mutex_lock(&TTX->DTX->connections[i]->lock); } LOGDEBUG("handle locked"); ATX->dbh = TTX->DTX->connections[i]->dbh; locked = i; /* Process the message by tying back into the agent functions */ ATX->results = nt_create(NT_PTR); if (ATX->results == NULL) { LOG(LOG_CRIT, ERR_MEM_ALLOC); goto CLOSE; } process_users(ATX, message); /* * Unlock the database handle as soon as we're done. We also need to * refresh our handle index with a new handle if for some reason we * had to re-establish a dewedged connection. */ if (TTX->DTX->connections[locked]->dbh != ATX->dbh) TTX->DTX->connections[locked]->dbh = ATX->dbh; if (TTX->DTX->flags & DRF_RWLOCK) { pthread_rwlock_unlock(&TTX->DTX->connections[locked]->rwlock); } else { pthread_mutex_unlock(&TTX->DTX->connections[locked]->lock); } locked = -1; /* Send a terminating '.' if --stdout in 'dspam' mode */ if (ATX->sockfd_output) { if (!(ATX->flags & DAF_SUMMARY)) if (send_socket(TTX, ".")<=0) goto CLOSE; /* Otherwise, produce standard delivery results */ } else { struct nt_node *node_nt, *node_res = NULL; struct nt_c c_nt; if (ATX->recipients) node_nt = c_nt_first(ATX->recipients, &c_nt); else node_nt = c_nt_first(ATX->users, &c_nt); if (ATX->results) node_res = ATX->results->first; while(node_res && node_nt != NULL) { agent_result_t result = (agent_result_t) node_res->ptr; if (result != NULL && result->exitcode == ERC_SUCCESS) { if (server_mode == SSM_DSPAM) { snprintf(buf, sizeof(buf), "%d 2.6.0 <%s> Message accepted for delivery: %s", LMTP_OK, (char *) node_nt->ptr, (result->classification == DSR_ISSPAM) ? "SPAM" : "INNOCENT"); } else { snprintf(buf, sizeof(buf), "%d 2.6.0 <%s> Message accepted for delivery", LMTP_OK, (char *) node_nt->ptr); } } else { if (result->exitcode == ERC_PERMANENT_DELIVERY) { snprintf(buf, sizeof(buf), "%d 5.3.0 <%s> %s", LMTP_FAILURE, (char *) node_nt->ptr, (result->text[0]) ? result->text : "Permanent error occured"); } else { if (result->text[0]) { snprintf(buf, sizeof(buf), "%d 4.3.0 <%s> %s", LMTP_TEMP_FAIL, (char *) node_nt->ptr, result->text); } else { snprintf(buf, sizeof(buf), "%d 4.3.0 <%s> Error occured during %s", LMTP_TEMP_FAIL, (char *) node_nt->ptr, (result->exitcode == ERC_DELIVERY) ? "delivery" : "processing"); } } } if (send_socket(TTX, buf)<=0) goto CLOSE; if (ATX->recipients) node_nt = c_nt_next(ATX->recipients, &c_nt); else node_nt = c_nt_next(ATX->users, &c_nt); if (node_res) node_res = node_res->next; } } /* Cleanup and get ready for another message */ RSET: fflush(fd); buffer_destroy(message); message = NULL; if (ATX != NULL) { nt_destroy(ATX->users); nt_destroy(ATX->recipients); nt_destroy(ATX->results); free(ATX); ATX = NULL; free(cmdline); cmdline = NULL; TTX->authenticated = 0; argc = 0; } free(p); p = NULL; } /* while(1) */ /* Close connection and return */ CLOSE: if (locked>=0) pthread_mutex_unlock(&TTX->DTX->connections[locked]->lock); if (fd) fclose(fd); buffer_destroy(TTX->packet_buffer); if (message) buffer_destroy(message); if (ATX != NULL) { nt_destroy(ATX->users); nt_destroy(ATX->recipients); nt_destroy(ATX->results); } free(ATX); free(cmdline); free(TTX); decrement_thread_count(); pthread_exit(0); return 0; }
char * make_logname( char *process, char *datestamp) { char *conf_logdir; char *fname = NULL; char *logf; if (datestamp == NULL) datestamp = g_strdup("error-00000000"); conf_logdir = config_dir_relative(getconf_str(CNF_LOGDIR)); fname = g_strjoin(NULL, conf_logdir, "/log", NULL); while (1) { int fd; g_free(logfile); logfile = g_strconcat(fname, ".", datestamp, ".0", NULL); /* try to create it */ fd = open(logfile, O_EXCL | O_CREAT | O_WRONLY, 0600); if (fd > -1) { FILE *file; file = fdopen(fd, "w"); if (file) { gchar *text = g_strdup_printf("INFO %s %s pid %ld\n", process, process, (long)getpid()); fprintf(file, "%s", text); fclose(file); file = fopen(logfile, "r"); if (file) { char line[1000]; if (fgets(line, 1000, file)) { if (g_str_equal(line, text)) { /* the file is for us */ g_free(text); fclose(file); break; } } fclose(file); } g_free(text); } } /* increase datestamp */ datestamp[13]++; if (datestamp[13] == ':') { datestamp[13] = '0'; datestamp[12]++; if (datestamp[12] == '6') { datestamp[12] = '0'; datestamp[11]++; if (datestamp[11] == ':') { datestamp[11] = '0'; datestamp[10]++; if (datestamp[10] == '6') { datestamp[10] = '0'; datestamp[9]++; if (datestamp[9] == ':') { datestamp[9] = '0'; datestamp[8]++; } } } } } } unlink(fname); logf = g_strdup(rindex(logfile,'/')+1); if (symlink(logf, fname) == -1) { g_debug("Can't symlink '%s' to '%s': %s", fname, logf, strerror(errno)); } amfree(logf); amfree(fname); amfree(conf_logdir); return (datestamp); }
/* run a check */ int run_check(char *processed_command, char **ret, char **err) { char *argv[MAX_CMD_ARGS]; FILE *fp; pid_t pid; int pipe_stdout[2], pipe_stderr[2], pipe_rwe[3]; int retval; sigset_t mask; #ifdef EMBEDDEDPERL retval = run_epn_check(processed_command, ret, err); if(retval != GM_NO_EPN) { return retval; } #endif /* check for check execution method (shell or execvp) * command line does not have to contain shell meta characters * and cmd must begin with a /. Otherwise "BLAH=BLUB cmd" would lead * to file not found errors */ if((*processed_command == '/' || *processed_command == '.') && !strpbrk(processed_command,"!$^&*()~[]\\|{};<>?`\"'")) { /* use the fast execvp when there are no shell characters */ gm_log( GM_LOG_TRACE, "using execvp, no shell characters found\n" ); parse_command_line(processed_command,argv); if(!argv[0]) _exit(STATE_UNKNOWN); if(pipe(pipe_stdout)) { gm_log( GM_LOG_ERROR, "error creating pipe: %s\n", strerror(errno)); _exit(STATE_UNKNOWN); } if(pipe(pipe_stderr)) { gm_log( GM_LOG_ERROR, "error creating pipe: %s\n", strerror(errno)); _exit(STATE_UNKNOWN); } if((pid=fork())<0){ gm_log( GM_LOG_ERROR, "fork error\n"); _exit(STATE_UNKNOWN); } else if(!pid){ /* remove all customn signal handler */ sigfillset(&mask); sigprocmask(SIG_UNBLOCK, &mask, NULL); /* child process */ if((dup2(pipe_stdout[1],STDOUT_FILENO)<0)){ gm_log( GM_LOG_ERROR, "dup2 error\n"); _exit(STATE_UNKNOWN); } if((dup2(pipe_stderr[1],STDERR_FILENO)<0)){ gm_log( GM_LOG_ERROR, "dup2 error\n"); _exit(STATE_UNKNOWN); } close(pipe_stdout[1]); close(pipe_stderr[1]); current_child_pid = getpid(); execvp(argv[0], argv); if(errno == 2) _exit(127); if(errno == 13) _exit(126); _exit(STATE_UNKNOWN); } /* parent */ /* prepare stdout pipe reading */ close(pipe_stdout[1]); fp=fdopen(pipe_stdout[0],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *ret = extract_check_result(fp, GM_DISABLED); fclose(fp); /* prepare stderr pipe reading */ close(pipe_stderr[1]); fp=fdopen(pipe_stderr[0],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *err = extract_check_result(fp, GM_ENABLED); fclose(fp); close(pipe_stdout[0]); close(pipe_stderr[0]); if(waitpid(pid,&retval,0)!=pid) retval=-1; } else { /* use the slower popen when there were shell characters */ gm_log( GM_LOG_TRACE, "using popen, found shell characters\n" ); current_child_pid = getpid(); pid = popenRWE(pipe_rwe, processed_command); /* extract check result */ fp=fdopen(pipe_rwe[1],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *ret = extract_check_result(fp, GM_DISABLED); fclose(fp); /* extract check stderr */ fp=fdopen(pipe_rwe[2],"r"); if(!fp){ gm_log( GM_LOG_ERROR, "fdopen error\n"); _exit(STATE_UNKNOWN); } *err = extract_check_result(fp, GM_ENABLED); fclose(fp); /* close the process */ retval=pcloseRWE(pid, pipe_rwe); } return retval; }
int main (void) { const char *tmpdir; char *fname; int fd; FILE *fp; const char outstr[] = "hello world!\n"; char strbuf[sizeof outstr]; char buf[200]; struct stat64 st1; struct stat64 st2; int result = 0; tmpdir = getenv ("TMPDIR"); if (tmpdir == NULL || tmpdir[0] == '\0') tmpdir = "/tmp"; asprintf (&fname, "%s/tst-fseek.XXXXXX", tmpdir); if (fname == NULL) error (EXIT_FAILURE, errno, "cannot generate name for temporary file"); /* Create a temporary file. */ fd = mkstemp (fname); if (fd == -1) error (EXIT_FAILURE, errno, "cannot open temporary file"); fp = fdopen (fd, "w+"); if (fp == NULL) error (EXIT_FAILURE, errno, "cannot get FILE for temporary file"); setbuffer (fp, strbuf, sizeof (outstr) -1); if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1) { puts ("write error"); result = 1; goto out; } /* The EOF flag must be reset. */ if (fgetc (fp) != EOF) { puts ("managed to read at end of file"); result = 1; } else if (! feof (fp)) { puts ("EOF flag not set"); result = 1; } if (fseek (fp, 0, SEEK_CUR) != 0) { puts ("fseek(fp, 0, SEEK_CUR) failed"); result = 1; } else if (feof (fp)) { puts ("fseek() didn't reset EOF flag"); result = 1; } /* Do the same for fseeko(). */ #ifdef USE_IN_LIBIO if (fgetc (fp) != EOF) { puts ("managed to read at end of file"); result = 1; } else if (! feof (fp)) { puts ("EOF flag not set"); result = 1; } if (fseeko (fp, 0, SEEK_CUR) != 0) { puts ("fseek(fp, 0, SEEK_CUR) failed"); result = 1; } else if (feof (fp)) { puts ("fseek() didn't reset EOF flag"); result = 1; } #endif /* Go back to the beginning of the file: absolute. */ if (fseek (fp, 0, SEEK_SET) != 0) { puts ("fseek(fp, 0, SEEK_SET) failed"); result = 1; } else if (fflush (fp) != 0) { puts ("fflush() failed"); result = 1; } else if (lseek (fd, 0, SEEK_CUR) != 0) { puts ("lseek() returned different position"); result = 1; } else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1) { puts ("fread() failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0) { puts ("content after fseek(,,SEEK_SET) wrong"); result = 1; } #ifdef USE_IN_LIBIO /* Now with fseeko. */ if (fseeko (fp, 0, SEEK_SET) != 0) { puts ("fseeko(fp, 0, SEEK_SET) failed"); result = 1; } else if (fflush (fp) != 0) { puts ("fflush() failed"); result = 1; } else if (lseek (fd, 0, SEEK_CUR) != 0) { puts ("lseek() returned different position"); result = 1; } else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1) { puts ("fread() failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0) { puts ("content after fseeko(,,SEEK_SET) wrong"); result = 1; } #endif /* Go back to the beginning of the file: relative. */ if (fseek (fp, -(sizeof (outstr) - 1), SEEK_CUR) != 0) { puts ("fseek(fp, 0, SEEK_SET) failed"); result = 1; } else if (fflush (fp) != 0) { puts ("fflush() failed"); result = 1; } else if (lseek (fd, 0, SEEK_CUR) != 0) { puts ("lseek() returned different position"); result = 1; } else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1) { puts ("fread() failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0) { puts ("content after fseek(,,SEEK_SET) wrong"); result = 1; } #ifdef USE_IN_LIBIO /* Now with fseeko. */ if (fseeko (fp, -(sizeof (outstr) - 1), SEEK_CUR) != 0) { puts ("fseeko(fp, 0, SEEK_SET) failed"); result = 1; } else if (fflush (fp) != 0) { puts ("fflush() failed"); result = 1; } else if (lseek (fd, 0, SEEK_CUR) != 0) { puts ("lseek() returned different position"); result = 1; } else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1) { puts ("fread() failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0) { puts ("content after fseeko(,,SEEK_SET) wrong"); result = 1; } #endif /* Go back to the beginning of the file: from the end. */ if (fseek (fp, -(sizeof (outstr) - 1), SEEK_END) != 0) { puts ("fseek(fp, 0, SEEK_SET) failed"); result = 1; } else if (fflush (fp) != 0) { puts ("fflush() failed"); result = 1; } else if (lseek (fd, 0, SEEK_CUR) != 0) { puts ("lseek() returned different position"); result = 1; } else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1) { puts ("fread() failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0) { puts ("content after fseek(,,SEEK_SET) wrong"); result = 1; } #ifdef USE_IN_LIBIO /* Now with fseeko. */ if (fseeko (fp, -(sizeof (outstr) - 1), SEEK_END) != 0) { puts ("fseeko(fp, 0, SEEK_SET) failed"); result = 1; } else if (fflush (fp) != 0) { puts ("fflush() failed"); result = 1; } else if (lseek (fd, 0, SEEK_CUR) != 0) { puts ("lseek() returned different position"); result = 1; } else if (fread (buf, sizeof (outstr) - 1, 1, fp) != 1) { puts ("fread() failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0) { puts ("content after fseeko(,,SEEK_SET) wrong"); result = 1; } #endif if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1) { puts ("write error 2"); result = 1; goto out; } if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1) { puts ("write error 3"); result = 1; goto out; } if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1) { puts ("write error 4"); result = 1; goto out; } if (fwrite (outstr, sizeof (outstr) - 1, 1, fp) != 1) { puts ("write error 5"); result = 1; goto out; } if (fputc ('1', fp) == EOF || fputc ('2', fp) == EOF) { puts ("cannot add characters at the end"); result = 1; goto out; } /* Check the access time. */ if (fstat64 (fd, &st1) < 0) { puts ("fstat64() before fseeko() failed\n"); result = 1; } else { sleep (1); if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_CUR) != 0) { puts ("fseek() after write characters failed"); result = 1; goto out; } else { time_t t; /* Make sure the timestamp actually can be different. */ sleep (1); t = time (NULL); if (fstat64 (fd, &st2) < 0) { puts ("fstat64() after fseeko() failed\n"); result = 1; } if (st1.st_ctime >= t) { puts ("st_ctime not updated"); result = 1; } if (st1.st_mtime >= t) { puts ("st_mtime not updated"); result = 1; } if (st1.st_ctime >= st2.st_ctime) { puts ("st_ctime not changed"); result = 1; } if (st1.st_mtime >= st2.st_mtime) { puts ("st_mtime not changed"); result = 1; } } } if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp) != 2 + 2 * (sizeof (outstr) - 1)) { puts ("reading 2 records plus bits failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0 || memcmp (&buf[sizeof (outstr) - 1], outstr, sizeof (outstr) - 1) != 0 || buf[2 * (sizeof (outstr) - 1)] != '1' || buf[2 * (sizeof (outstr) - 1) + 1] != '2') { puts ("reading records failed"); result = 1; } else if (ungetc ('9', fp) == EOF) { puts ("ungetc() failed"); result = 1; } else if (fseek (fp, -(2 + 2 * (sizeof (outstr) - 1)), SEEK_END) != 0) { puts ("fseek after ungetc failed"); result = 1; } else if (fread (buf, 1, 2 + 2 * (sizeof (outstr) - 1), fp) != 2 + 2 * (sizeof (outstr) - 1)) { puts ("reading 2 records plus bits failed"); result = 1; } else if (memcmp (buf, outstr, sizeof (outstr) - 1) != 0 || memcmp (&buf[sizeof (outstr) - 1], outstr, sizeof (outstr) - 1) != 0 || buf[2 * (sizeof (outstr) - 1)] != '1') { puts ("reading records for the second time failed"); result = 1; } else if (buf[2 * (sizeof (outstr) - 1) + 1] == '9') { puts ("unget character not ignored"); result = 1; } else if (buf[2 * (sizeof (outstr) - 1) + 1] != '2') { puts ("unget somehow changed character"); result = 1; } out: unlink (fname); return result; }
static Image *ReadURLImage(const ImageInfo *image_info,ExceptionInfo *exception) { #define MaxBufferExtent 8192 char filename[MaxTextExtent]; FILE *file; Image *image; ImageInfo *read_info; int unique_file; image=(Image *) NULL; read_info=CloneImageInfo(image_info); SetImageInfoBlob(read_info,(void *) NULL,0); file=(FILE *) NULL; unique_file=AcquireUniqueFileResource(read_info->filename); if (unique_file != -1) file=fdopen(unique_file,"wb"); if ((unique_file == -1) || (file == (FILE *) NULL)) { ThrowFileException(exception,FileOpenError,"UnableToCreateTemporaryFile", read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } (void) CopyMagickString(filename,image_info->magick,MaxTextExtent); (void) ConcatenateMagickString(filename,":",MaxTextExtent); LocaleLower(filename); (void) ConcatenateMagickString(filename,image_info->filename,MaxTextExtent); if (LocaleCompare(read_info->magick,"file") == 0) { (void) RelinquishUniqueFileResource(read_info->filename); unique_file=(-1); (void) CopyMagickString(read_info->filename,image_info->filename+2, MaxTextExtent); } #if defined(MAGICKCORE_WINDOWS_SUPPORT) && \ !(defined(__MINGW32__) || defined(__MINGW64__)) (void) fclose(file); if (URLDownloadToFile(NULL,filename,read_info->filename,0,NULL) != S_OK) { ThrowFileException(exception,FileOpenError,"UnableToOpenFile", filename); (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); return((Image *) NULL); } #else #if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_FTP_ENABLED) if (LocaleCompare(read_info->magick,"ftp") == 0) { void *context; xmlNanoFTPInit(); context=xmlNanoFTPNewCtxt(filename); if (context != (void *) NULL) { if (xmlNanoFTPConnect(context) >= 0) (void) xmlNanoFTPGet(context,GetFTPData,(void *) file, (char *) NULL); (void) xmlNanoFTPClose(context); } } #endif #if defined(MAGICKCORE_XML_DELEGATE) && defined(LIBXML_HTTP_ENABLED) if (LocaleCompare(read_info->magick,"http") == 0) { char buffer[MaxBufferExtent], *type; int bytes; void *context; type=(char *) NULL; context=xmlNanoHTTPMethod(filename,(const char *) NULL, (const char *) NULL,&type,(const char *) NULL,0); if (context != (void *) NULL) { ssize_t count; while ((bytes=xmlNanoHTTPRead(context,buffer,MaxBufferExtent)) > 0) count=(ssize_t) fwrite(buffer,bytes,1,file); (void) count; xmlNanoHTTPClose(context); xmlFree(type); xmlNanoHTTPCleanup(); } } #endif (void) fclose(file); #endif { ExceptionInfo *sans; ImageInfo *clone_info; /* Guess image format from URL. */ clone_info=CloneImageInfo(image_info); sans=AcquireExceptionInfo(); (void) SetImageInfo(clone_info,0,sans); (void) CopyMagickString(read_info->magick,clone_info->magick,MaxTextExtent); clone_info=DestroyImageInfo(clone_info); sans=DestroyExceptionInfo(sans); } image=ReadImage(read_info,exception); if (unique_file != -1) (void) RelinquishUniqueFileResource(read_info->filename); read_info=DestroyImageInfo(read_info); if (image != (Image *) NULL) GetPathComponent(image_info->filename,TailPath,image->filename); else { (void) ThrowMagickException(exception,GetMagickModule(),CoderError, "NoDataReturned","`%s'",filename); return((Image *) NULL); } return(GetFirstImageInList(image)); }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit() { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(); else out2str("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_out == NULL) goto bad; el = el_init(arg0, el_in, el_out); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); } else { bad: out2str("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }
FileToString() { pipe(FD); input = fdopen(FD[1], "w"); }
/* * This routine renames the temporary control file as received from some * other (remote) host. That file will almost always with `tfA*', because * recvjob.c creates the file by changing `c' to `t' in the original name * for the control file. Now if you read the RFC, you would think that all * control filenames start with `cfA*'. However, it seems there are some * implementations which send control filenames which start with `cf' * followed by *any* letter, so this routine can not assume what the third * letter will (or will not) be. Sigh. * * So this will rewrite the temporary file to `rf*' (correcting any lines * which need correcting), rename that `rf*' file to `cf*', and then remove * the original `tf*' temporary file. * * The *main* purpose of this routine is to be paranoid about the contents * of that control file. It is partially meant to protect against people * TRYING to cause trouble (perhaps after breaking into root of some host * that this host will accept print jobs from). The fact that we're willing * to print jobs from some remote host does not mean that we should blindly * do anything that host tells us to do. * * This is also meant to protect us from errors in other implementations of * lpr, particularly since we may want to use some values from the control * file as environment variables when it comes time to print, or as parameters * to commands which will be exec'ed, or values in statistics records. * * This may also do some "conversions" between how different versions of * lpr or lprNG define the contents of various lines in a control file. * * If there is an error, it returns a pointer to a descriptive error message. * Error messages which are RETURNED (as opposed to syslog-ed) do not include * the printer-queue name. Let the caller add that if it is wanted. */ char * ctl_renametf(const char *ptrname, const char *tfname) { int chk3rd, has_uc, newfd, nogood, res; FILE *newcf; struct cjobinfo *cjinf; char *lbuff, *slash, *cp; char tfname2[NAME_MAX+1], cfname2[NAME_MAX+1]; char errm[CTI_LINEMAX]; #ifdef TRIGGERTEST_FNAME struct stat tstat; res = stat(TRIGGERTEST_FNAME, &tstat); if (res == -1) { /* * if the trigger file does NOT exist in this spool directory, * then do the exact same steps that the pre-ctlinfo code had * been doing. Ie, very little. */ strlcpy(cfname2, tfname, sizeof(cfname2)); cfname2[0] = 'c'; res = link(tfname, cfname2); if (res < 0) { snprintf(errm, sizeof(errm), "ctl_renametf error link(%s,%s): %s", tfname, cfname2, strerror(errno)); return strdup(errm); } unlink(tfname); return NULL; } #endif cjinf = NULL; /* in case of early jump to error_ret */ newcf = NULL; /* in case of early jump to error_ret */ *errm = '\0'; /* in case of early jump to error_ret */ chk3rd = tfname[2]; if ((tfname[0] != 't') || (tfname[1] != 'f') || (!isalpha(chk3rd))) { snprintf(errm, sizeof(errm), "ctl_renametf invalid filename: %s", tfname); goto error_ret; } cjinf = ctl_readcf(ptrname, tfname); if (cjinf == NULL) { snprintf(errm, sizeof(errm), "ctl_renametf error cti_readcf(%s)", tfname); goto error_ret; } /* * This uses open+fdopen instead of fopen because that combination * gives us greater control over file-creation issues. */ strlcpy(tfname2, tfname, sizeof(tfname2)); tfname2[0] = 'r'; /* rf<letter><job><hostname> */ newfd = open(tfname2, O_WRONLY|O_CREAT|O_TRUNC, 0660); if (newfd == -1) { snprintf(errm, sizeof(errm), "ctl_renametf error open(%s): %s", tfname2, strerror(errno)); goto error_ret; } newcf = fdopen(newfd, "w"); if (newcf == NULL) { close(newfd); snprintf(errm, sizeof(errm), "ctl_renametf error fopen(%s): %s", tfname2, strerror(errno)); goto error_ret; } /* * Do extra sanity checks on some key job-attribute fields, and * write them out first (thus making sure they are written in the * order we generally expect them to be in). */ /* * Some lpr implementations on PC's set a null-string for their * hostname. A MacOS 10 system which has not correctly setup * /etc/hostconfig will claim a hostname of 'localhost'. Anything * with blanks in it would be an invalid value for hostname. For * any of these invalid hostname values, replace the given value * with the name of the host that this job is coming from. */ nogood = 0; if (cjinf->cji_accthost == NULL) nogood = 1; else if (strcmp(cjinf->cji_accthost, ".na.") == 0) nogood = 1; else if (strcmp(cjinf->cji_accthost, "localhost") == 0) nogood = 1; else { for (cp = cjinf->cji_accthost; *cp != '\0'; cp++) { if (*cp <= ' ') { nogood = 1; break; } } } if (nogood) fprintf(newcf, "H%s\n", from_host); else fprintf(newcf, "H%s\n", cjinf->cji_accthost); /* * Now do some sanity checks on the 'P' (original userid) value. Note * that the 'P'erson line is the second line which is ALWAYS supposed * to be present in a control file. * * There is no particularly good value to use for replacements, but * at least make sure the value is something reasonable to use in * environment variables and statistics records. Again, some PC * implementations send a null-string for a value. Various Mac * implementations will set whatever string the user has set for * their 'Owner Name', which usually includes blanks, etc. */ nogood = 0; if (cjinf->cji_acctuser == NULL) nogood = 1; else if (strcmp(cjinf->cji_acctuser, ".na.") == 0) ; /* No further checks needed... */ else { has_uc = 0; cp = cjinf->cji_acctuser; if (*cp == '-') *cp++ = '_'; for (; *cp != '\0'; cp++) { if (islowerch(*cp) || isdigitch(*cp)) continue; /* Standard valid characters */ if (strchr(OTHER_USERID_CHARS, *cp) != NULL) continue; /* Some more valid characters */ if (isupperch(*cp)) { has_uc = 1; /* These may be valid... */ continue; } *cp = '_'; } /* * Some Windows hosts send print jobs where the correct userid * has been converted to uppercase, and that can cause trouble * for sites that expect the correct value (for something like * accounting). On the other hand, some sites do use uppercase * in their userids, so we can't blindly convert to lowercase. */ if (has_uc && (getpwnam(cjinf->cji_acctuser) == NULL)) { for (cp = cjinf->cji_acctuser; *cp != '\0'; cp++) { if (isupperch(*cp)) *cp = tolowerch(*cp); } } } if (nogood) fprintf(newcf, "P%s\n", ".na."); else fprintf(newcf, "P%s\n", cjinf->cji_acctuser); /* No need for sanity checks on class, jobname, "literal" user. */ if (cjinf->cji_class != NULL) fprintf(newcf, "C%s\n", cjinf->cji_class); if (cjinf->cji_jobname != NULL) fprintf(newcf, "J%s\n", cjinf->cji_jobname); if (cjinf->cji_headruser != NULL) fprintf(newcf, "L%s\n", cjinf->cji_headruser); /* * This should probably add more sanity checks on mailto value. * Note that if the mailto value is "wrong", then there's no good * way to know what the "correct" value would be, and we should not * semd email to some random address. At least for now, just ignore * any invalid values. */ nogood = 0; if (cjinf->cji_mailto == NULL) nogood = 1; else { for (cp = cjinf->cji_mailto; *cp != '\0'; cp++) { if (*cp <= ' ') { nogood = 1; break; } } } if (!nogood) fprintf(newcf, "M%s\n", cjinf->cji_mailto); /* * Now go thru the old control file, copying all information which * hasn't already been written into the new file. */ ctl_rewindcf(cjinf); lbuff = ctl_getline(cjinf); while (lbuff != NULL) { switch (lbuff[0]) { case 'H': case 'P': case 'C': case 'J': case 'L': case 'M': /* already wrote values for these to the newcf */ break; case 'N': /* see comments under 'U'... */ if (cjinf->cji_dfcount == 0) { /* in this case, 'N's will be done in 'U' */ break; } fprintf(newcf, "%s\n", lbuff); break; case 'U': /* * check for the very common case where the remote * host had to process 'lpr -s -r', but it did not * remove the Unlink line from the control file. * Such Unlink lines will legitimately have a '/' in * them, but it is the original lpr host which would * have done the unlink of such files, and not any * host receiving that job. */ slash = strchr(lbuff, '/'); if (slash != NULL) { break; /* skip this line */ } /* * Okay, another kind of broken lpr implementation * is one which send datafiles, and Unlink's those * datafiles, but never includes any PRINT request * for those files. Experimentation shows that one * copy of those datafiles should be printed with a * format of 'f'. If this is an example of such a * screwed-up control file, fix it here. */ if (cjinf->cji_dfcount == 0) { lbuff++; if (strncmp(lbuff, "df", (size_t)2) == 0) { fprintf(newcf, "f%s\n", lbuff); fprintf(newcf, "U%s\n", lbuff); fprintf(newcf, "N%s\n", lbuff); } break; } fprintf(newcf, "%s\n", lbuff); break; default: fprintf(newcf, "%s\n", lbuff); break; } lbuff = ctl_getline(cjinf); } ctl_freeinf(cjinf); cjinf = NULL; res = fclose(newcf); newcf = NULL; if (res != 0) { snprintf(errm, sizeof(errm), "ctl_renametf error fclose(%s): %s", tfname2, strerror(errno)); goto error_ret; } strlcpy(cfname2, tfname, sizeof(cfname2)); cfname2[0] = 'c'; /* rename new file to 'cfA*' */ res = link(tfname2, cfname2); if (res != 0) { snprintf(errm, sizeof(errm), "ctl_renametf error link(%s,%s): %s", tfname2, cfname2, strerror(errno)); goto error_ret; } /* All the important work is done. Now just remove temp files */ #ifdef LEAVE_TMPCF_FILES { struct stat tfstat; size_t size1; tfstat.st_size = 1; /* certainly invalid value */ res = stat(tfname, &tfstat); size1 = tfstat.st_size; tfstat.st_size = 2; /* certainly invalid value */ res = stat(tfname2, &tfstat); /* * If the sizes do not match, or either stat call failed, * then do not remove the temp files, but just move them * out of the way. This is so I can see what this routine * had changed (and the files won't interfere with some * later job coming in from the same host). In this case, * we don't care if we clobber some previous file. */ if (size1 != tfstat.st_size) { strlcpy(cfname2, tfname, sizeof(cfname2)); strlcat(cfname2, "._T", sizeof(cfname2)); rename(tfname, cfname2); strlcpy(cfname2, tfname2, sizeof(cfname2)); strlcat(cfname2, "._T", sizeof(cfname2)); rename(tfname2, cfname2); return NULL; } } #endif unlink(tfname); unlink(tfname2); return NULL; error_ret: if (cjinf != NULL) ctl_freeinf(cjinf); if (newcf != NULL) fclose(newcf); if (*errm != '\0') return strdup(errm); return strdup("ctl_renametf internal (missed) error"); }
static int do_test (void) { char name[] = "/tmp/tst-freopen.XXXXXX"; const char * const test = "Let's test freopen.\n"; char temp[strlen (test) + 1]; int fd = mkstemp (name); FILE *f; if (fd == -1) { printf ("%u: cannot open temporary file: %m\n", __LINE__); exit (1); } f = fdopen (fd, "w"); if (f == NULL) { printf ("%u: cannot fdopen temporary file: %m\n", __LINE__); exit (1); } fputs (test, f); fclose (f); f = fopen (name, "r"); if (f == NULL) { printf ("%u: cannot fopen temporary file: %m\n", __LINE__); exit (1); } if (fread (temp, 1, strlen (test), f) != strlen (test)) { printf ("%u: couldn't read the file back: %m\n", __LINE__); exit (1); } temp [strlen (test)] = '\0'; if (strcmp (test, temp)) { printf ("%u: read different string than was written:\n%s%s", __LINE__, test, temp); exit (1); } f = freopen (name, "r+", f); if (f == NULL) { printf ("%u: cannot freopen temporary file: %m\n", __LINE__); exit (1); } if (fseek (f, 0, SEEK_SET) != 0) { printf ("%u: couldn't fseek to start: %m\n", __LINE__); exit (1); } if (fread (temp, 1, strlen (test), f) != strlen (test)) { printf ("%u: couldn't read the file back: %m\n", __LINE__); exit (1); } temp [strlen (test)] = '\0'; if (strcmp (test, temp)) { printf ("%u: read different string than was written:\n%s%s", __LINE__, test, temp); exit (1); } fclose (f); unlink (name); exit (0); }
//******************************************************************** Bool32 ROUT_LoadRec6List( const char *rec6AllFilename ) { /* Загрузка файла rec6all.dat, в котором перечислены имена таблиц rec6xxx.dat в виде: 0 rec6.dat 1 rec6grm.dat ... и т.д. Файлы rec6xxx.dat загружяются в таблицу алфавитов: gAT_sizeAlphabet[LANG_TOTAL] gAT_upper[LANG_TOTAL][kMaxSizeAlphabet] gAT_lower[LANG_TOTAL][kMaxSizeAlphabet] gAT_vowels[LANG_TOTAL][kMaxSizeAlphabet] */ ClearError(); // Открыть файл со списком таблиц FILE *f = NULL; char buf[256] = ""; int fd; fd = open_data_file(rec6AllFilename, O_RDONLY); // Was "rt". if(fd == -1) { ERR_LOAD_REC6LIST; return FALSE; } f = fdopen(fd, "rt"); if (!f) { ERR_LOAD_REC6LIST; return FALSE; } while ( fgets(buf,sizeof(buf)-1,f) ) { int language=-1; char theName[_MAX_PATH] = ""; // Пустые строки и строки комментариев, // начинающиеся с точки с запятой, пропускать char *p = buf; while (*p == ' ' || *p == '\t' ) p++; if ( *p == ';' || !*p || *p == 0x0d || *p == 0x0a ) continue; // Номер языка и имя таблицы rec6xxx.dat sscanf(buf, "%d%s", &language, &theName[0]); if (language <0 || language >= PUMA_LANG_TOTAL || !theName[0] || !LoadAlphabet(language, theName) ) { fclose(f); ERR_LOAD_REC6LIST; return FALSE; } } fclose(f); return TRUE; }
//******************************************************************** static Bool LoadAlphabet( long language, char *rec6xxxFilename) { // Загрузка файла REC6.DAT FILE *f = NULL; int fd; char buf[256] = ""; #if defined(WIN32) || defined(__CYGWIN__) const char line_end = '\n'; #else const char line_end = '\r'; #endif ASSERT (language >= 0 && language < PUMA_LANG_TOTAL); long sizeAlphabet = 0; fd = open_data_file(rec6xxxFilename, O_RDONLY); if(fd == -1) return FALSE; f = fdopen(fd, "rt"); if (!f) return FALSE; fgets(buf,sizeof(buf)-1,f); sscanf(buf,"%ld",&sizeAlphabet); if( sizeAlphabet < 1 || sizeAlphabet > kMaxSizeAlphabet ) { fclose(f); ERR_LOAD_ALPHABET; return FALSE; } gAT_sizeAlphabet[language] = sizeAlphabet; char *upper = gAT_upper[language]; char *lower = gAT_lower[language]; char *vowels = gAT_vowels[language]; fgets(upper,kMaxSizeAlphabet,f); fgets(lower,kMaxSizeAlphabet,f); fgets(vowels,kMaxSizeAlphabet,f); fclose(f); f = NULL; char *p1 = strchr(upper, line_end); char *p2 = strchr(lower, line_end); char *p3 = strchr(vowels, line_end); if ( p1 ) *p1 = 0; if ( p2 ) *p2 = 0; if ( p3 ) *p3 = 0; if ( (long)strlen(upper) != sizeAlphabet || (long)strlen(lower) != sizeAlphabet || (long)strlen(vowels)> sizeAlphabet ) { ERR_LOAD_ALPHABET; return FALSE; } return TRUE; }
static int pkg_open_v2(struct pkg **pkg_p, const char *path, struct archive **a, struct archive_entry **ae, struct pkg_manifest_key *keys, int flags) { struct pkg_v2_header hdr; FILE *fs; int fd, ret; if (strncmp(path, "-", 2) == 0) { fd = STDIN_FILENO; } else { fd = open(path, O_RDONLY); } memset(&hdr, 0, sizeof(hdr)); if (fd == -1) { if ((flags & PKG_OPEN_TRY) == 0) { pkg_emit_error("open(%s): %s", path, strerror(errno)); } return (EPKG_FATAL); } if (!pkg_is_v2(fd)) { return (EPKG_END); } fs = fdopen(fd, "r"); if (fs == NULL) { if ((flags & PKG_OPEN_TRY) == 0) { pkg_emit_error("fdopen(%s): %s", path, strerror(errno)); } return (EPKG_FATAL); } if ((ret = pkg_open_header_v2(fs, &hdr)) != EPKG_OK) { if ((flags & PKG_OPEN_TRY) == 0) { pkg_emit_error("bad v2 header in %s: %s", path, strerror(errno)); } return (ret); } /* If we have signature, we need to check it */ if (hdr.signature_offset > 0) { /* TODO: write signatures check */ } /* Load manifest */ if ((ret = pkg_read_manifest_v2(fs, pkg_p, keys)) != EPKG_OK) { if ((flags & PKG_OPEN_TRY) == 0) { pkg_emit_error("bad v2 manifest in %s: %s", path, strerror(errno)); } return (ret); } if (flags & PKG_OPEN_MANIFEST_COMPACT) { return (EPKG_OK); } /* Read files as well */ if ((ret = pkg_read_files_v2(fs, *pkg_p, keys)) != EPKG_OK) { if (ret != EPKG_END) { /* We have some fatal error */ return (EPKG_FATAL); } } /* If we need files, then go to payload and open archive */ if (flags & PKG_OPEN_MANIFEST_ONLY) { return (EPKG_OK); } if ((ret = pkg_read_archive_v2(fs, *pkg_p, a, ae)) != EPKG_OK) { if (ret != EPKG_END) { /* We have some fatal error */ return (EPKG_FATAL); } } return (ret); }
/* * Modified : 01.20.2002 Author : Dark0n3 * * Description : Parses file entries from sfv file and store them in a file. * * Todo : Add dupefile remover. * * Totally rewritten by js on 08.02.2005 */ int copysfv(const char *source, const char *target, struct VARS *raceI) { int infd, outfd, i, retval = 0; short int music, rars, video, others, type; char *ptr, fbuf[2048]; FILE *insfv; DIR *dir; SFVDATA sd; //#if ( sfv_dupecheck == TRUE ) int skip = 0; SFVDATA tempsd; //#endif #if ( sfv_cleanup == TRUE ) int tmpfd; char crctmp[16]; if ((tmpfd = open(".tmpsfv", O_CREAT | O_TRUNC | O_RDWR, 0644)) == -1) d_log("copysfv: open(.tmpsfv): %s\n", strerror(errno)); #endif if ((infd = open(source, O_RDONLY)) == -1) { d_log("copysfv: open(%s): %s\n", source, strerror(errno)); remove_lock(raceI); exit(EXIT_FAILURE); } if ((outfd = open(target, O_CREAT | O_TRUNC | O_RDWR, 0666)) == -1) { d_log("copysfv: open(%s): %s\n", target, strerror(errno)); remove_lock(raceI); exit(EXIT_FAILURE); } video = music = rars = others = type = 0; dir = opendir("."); if (!update_lock(raceI, 1, 0)) { d_log("copysfv: Lock is suggested removed. Will comply and exit\n"); remove_lock(raceI); exit(EXIT_FAILURE); } if ((insfv = fdopen(infd, "r")) == NULL) { d_log("copysfv: Unable to fdopen %s: %s\n", source, strerror(errno)); remove_lock(raceI); exit(EXIT_FAILURE); } while ((fgets(fbuf, sizeof(fbuf), insfv))) { /* remove comment */ if ((ptr = find_first_of(fbuf, ";"))) *ptr = '\0'; tailstrip_chars(fbuf, WHITESPACE_STR); ptr = prestrip_chars(fbuf, WHITESPACE_STR); if (ptr != fbuf) d_log("copysfv: prestripped whitespaces (%d chars)\n", ptr - fbuf); if (strlen(ptr) == 0) continue; #if (sfv_cleanup_lowercase == TRUE) for (; *ptr; ptr++) *ptr = tolower(*ptr); #endif sd.crc32 = 0; bzero(sd.fname, sizeof(sd.fname)); if ((ptr = find_last_of(fbuf, " \t"))) { /* pass the " \t" */ ptr++; /* what we have now is hopefully a crc */ for (i = 0; isxdigit(*ptr) != 0; i++) ptr++; ptr -= i; if (i > 8 || i < 6) { /* we didn't get an 8 digit crc number */ #if (sfv_cleanup == TRUE) /* do stuff */ d_log("copysfv: We did not get a 8 digit crc number for %s - trying to continue anyway\n", sd.fname); #else retval = 1; goto END; #endif } else { sd.crc32 = hexstrtodec(ptr); /* cut off crc string */ *ptr = '\0'; /* nobody should be stupid enough to have spaces * at the end of the file name */ tailstrip_chars(fbuf, WHITESPACE_STR); } } else { /* we have a filename only. */ #if (sfv_cleanup == TRUE) /* do stuff */ d_log("copysfv: We did not find a crc number for %s - trying to continue anyway\n", sd.fname); #else retval = 1; goto END; #endif } /* we assume what's left is a filename */ ptr = prestrip_chars(fbuf, WHITESPACE_STR); if (ptr != fbuf) d_log("copysfv: prestripped whitespaces (%d chars)\n", ptr - fbuf); #if (allow_slash_in_sfv == TRUE) if (ptr != find_last_of(ptr, "/")) { ptr = find_last_of(ptr, "/") + 1; d_log("copysfv: found '/' in filename - adjusting.\n"); } if (ptr != find_last_of(ptr, "\\")) { ptr = find_last_of(ptr, "\\") + 1; d_log("copysfv: found '\\' in filename - adjusting.\n"); } #endif if (strlen(ptr) > 0 && strlen(ptr) < NAME_MAX-9 ) { strlcpy(sd.fname, ptr, NAME_MAX-9); if (sd.fname != find_last_of(sd.fname, "\t") || sd.fname != find_last_of(sd.fname, "\\") || sd.fname != find_last_of(sd.fname, "/")) { d_log("copysfv: found '/', '\\' or <TAB> as part of filename in sfv - logging file as bad.\n"); retval = 1; break; } if (sd.crc32 == 0) { #if (sfv_calc_single_fname == TRUE || create_missing_sfv == TRUE) sd.crc32 = match_lenient(dir, sd.fname); d_log("copysfv: Got filename (%s) without crc, calculated to %X.\n", sd.fname, sd.crc32); #else d_log("copysfv: Got filename (%s) without crc - ignoring file.\n", sd.fname); continue; #endif } /* get file extension */ ptr = find_last_of(fbuf, "."); if (*ptr == '.') ptr++; if (!strcomp(ignored_types, ptr) && !(strcomp(allowed_types, ptr) && !matchpath(allowed_types_exemption_dirs, raceI->misc.current_path)) && !strcomp("sfv", ptr) && !strcomp("nfo", ptr)) { skip = 0; //#if ( sfv_dupecheck == TRUE ) /* read from sfvdata - no parsing */ lseek(outfd, 0L, SEEK_SET); while (read(outfd, &tempsd, sizeof(SFVDATA))) // if (!strcmp(sd.fname, tempsd.fname) || (sd.crc32 == tempsd.crc32 && sd.crc32)) if (!strcmp(sd.fname, tempsd.fname)) skip = 1; lseek(outfd, 0L, SEEK_END); #if ( sfv_dupecheck == TRUE ) if (skip) continue; #endif d_log("copysfv: File in sfv: '%s' (%x)\n", sd.fname, sd.crc32); #if ( sfv_cleanup == TRUE ) /* write good stuff to .tmpsfv */ if (tmpfd != -1) { sprintf(crctmp, "%.8x", sd.crc32); if (write(tmpfd, sd.fname, strlen(sd.fname)) != (int)strlen(sd.fname)) d_log("copysfv: write failed: %s\n", strerror(errno)); if (write(tmpfd, " ", 1) != 1) d_log("copysfv: write failed: %s\n", strerror(errno)); if (write(tmpfd, crctmp, 8) != 8) d_log("copysfv: write failed: %s\n", strerror(errno)); #if (sfv_cleanup_crlf == TRUE ) if (write(tmpfd, "\r", 1) != 1) d_log("copysfv: write failed: %s\n", strerror(errno)); #endif if (write(tmpfd, "\n", 1) != 1) d_log("copysfv: write failed: %s\n", strerror(errno)); } #endif if (strcomp(audio_types, ptr)) music++; else if (israr(ptr)) rars++; else if (strcomp(video_types, ptr)) video++; else others++; #if ( create_missing_files == TRUE ) if (!findfile(dir, sd.fname) && !(matchpath(allowed_types_exemption_dirs, raceI->misc.current_path) && strcomp(allowed_types, ptr))) create_missing(sd.fname, raceI); #endif if (write(outfd, &sd, sizeof(SFVDATA)) != sizeof(SFVDATA)) d_log("copysfv: write failed: %s\n", strerror(errno)); } } } if (music > rars) { if (video > music) type = (video >= others ? 4 : 2); else type = (music >= others ? 3 : 2); } else { if (video > rars) type = (video >= others ? 4 : 2); else type = (rars >= others ? 1 : 2); } #if ( sfv_cleanup == FALSE ) END: #endif close(infd); #if ( sfv_cleanup == TRUE ) if (tmpfd != -1) { close(tmpfd); unlink(source); rename(".tmpsfv", source); #ifdef USING_EBFTPD if (ebftpd_chown(source, raceI->user.uid, raceI->user.gid) < 0) d_log("copysfv: ebftpd_chown(%s,%i,%i): %s\n", source, raceI->user.uid, raceI->user.gid, strerror(errno)); #endif } #endif closedir(dir); close(outfd); if (!update_lock(raceI, 1, type)) { d_log("copysfv: Lock is suggested removed. Will comply and exit\n"); remove_lock(raceI); exit(EXIT_FAILURE); } raceI->data_type = type; return retval; }
/* vraci system rc error kod */ static int bench(void) { int i,j,k; pid_t pid=0; FILE *f; /* check avaibility of target server */ printf("%s\n",host); i=Socket(proxyhost==NULL?host:proxyhost,proxyport); if(i<0) { fprintf(stderr,"\nConnect to server failed. Aborting benchmark.\n"); return 1; } close(i); /* create pipe */ if(pipe(mypipe)) { perror("pipe failed."); return 3; } /* not needed, since we have alarm() in childrens */ /* wait 4 next system clock tick */ /* cas=time(NULL); while(time(NULL)==cas) sched_yield(); */ /* fork childs */ for(i=0;i<clients;i++) { printf("clients: %d\n",clients); pid=fork(); if(pid <= (pid_t) 0) { /* child process or error*/ sleep(1); /* make childs faster */ break; } } if( pid< (pid_t) 0) { fprintf(stderr,"problems forking worker no. %d\n",i); perror("fork failed."); return 3; } if(pid== (pid_t) 0) { /* I am a child */ if(proxyhost==NULL) benchcore(host,proxyport,request); else benchcore(proxyhost,proxyport,request); /* write results to pipe */ f=fdopen(mypipe[1],"w"); if(f==NULL) { perror("open pipe for writing failed."); return 3; } /* fprintf(stderr,"Child - %d %d\n",speed,failed); */ fprintf(f,"%d %d %d\n",speed,failed,bytes); fclose(f); return 0; } else { f=fdopen(mypipe[0],"r"); if(f==NULL) { perror("open pipe for reading failed."); return 3; } setvbuf(f,NULL,_IONBF,0); speed=0; failed=0; bytes=0; while(1) { pid=fscanf(f,"%d %d %d",&i,&j,&k); if(pid<2) { fprintf(stderr,"Some of our childrens died.\n"); break; } speed+=i; failed+=j; bytes+=k; /* fprintf(stderr,"*Knock* %d %d read=%d\n",speed,failed,pid); */ if(--clients==0) break; } fclose(f); printf("\nSpeed=%d pages/min, %d bytes/sec.\nRequests: %d susceed, %d failed.\n", (int)((speed+failed)/(benchtime/60.0f)), (int)(bytes/(float)benchtime), speed, failed); } return i; }
/* load a single input file */ static int load_file( const char *input_name, const char *output_name ) { int ret; /* Run the preprocessor on the input */ if(!no_preprocess) { FILE *output; int ret, fd; char *name; /* * Preprocess the input to a temp-file, or stdout if * no output was given. */ if (preprocess_only) { if (output_name) { if (!(output = fopen( output_name, "w" ))) fatal_perror( "Could not open %s for writing", output_name ); ret = wpp_parse( input_name, output ); fclose( output ); } else ret = wpp_parse( input_name, stdout ); if (ret) return ret; output_name = NULL; exit(0); } if (output_name && output_name[0]) name = strmake( "%s.XXXXXX", output_name ); else name = xstrdup( "wrc.XXXXXX" ); if ((fd = mkstemps( name, 0 )) == -1) error("Could not generate a temp name from %s\n", name); temp_name = name; if (!(output = fdopen(fd, "wt"))) error("Could not open fd %s for writing\n", name); ret = wpp_parse( input_name, output ); fclose( output ); if (ret) return ret; input_name = name; } /* Reset the language */ currentlanguage = dup_language( defaultlanguage ); check_utf8 = 1; /* Go from .rc to .res */ chat("Starting parse\n"); if(!(parser_in = fopen(input_name, "rb"))) fatal_perror("Could not open %s for input", input_name); ret = parser_parse(); fclose(parser_in); parser_lex_destroy(); if (temp_name) { unlink( temp_name ); temp_name = NULL; } free( currentlanguage ); return ret; }
/* * Set history and editing status. Called whenever the status may * have changed (figures out what to do). */ void histedit(void) { #define editing (Eflag || Vflag) if (iflag) { if (!hist) { /* * turn history on */ INTOFF; hist = history_init(); INTON; if (hist != NULL) sethistsize(histsizeval()); else out2fmt_flush("sh: can't initialize history\n"); } if (editing && !el && isatty(0)) { /* && isatty(2) ??? */ /* * turn editing on */ char *term; INTOFF; if (el_in == NULL) el_in = fdopen(0, "r"); if (el_err == NULL) el_err = fdopen(1, "w"); if (el_out == NULL) el_out = fdopen(2, "w"); if (el_in == NULL || el_err == NULL || el_out == NULL) goto bad; term = lookupvar("TERM"); if (term) setenv("TERM", term, 1); else unsetenv("TERM"); el = el_init(arg0, el_in, el_out, el_err); if (el != NULL) { if (hist) el_set(el, EL_HIST, history, hist); el_set(el, EL_PROMPT, getprompt); el_set(el, EL_ADDFN, "sh-complete", "Filename completion", _el_fn_sh_complete); } else { bad: out2fmt_flush("sh: can't initialize editing\n"); } INTON; } else if (!editing && el) { INTOFF; el_end(el); el = NULL; INTON; } if (el) { if (Vflag) el_set(el, EL_EDITOR, "vi"); else if (Eflag) el_set(el, EL_EDITOR, "emacs"); el_set(el, EL_BIND, "^I", "sh-complete", NULL); el_source(el, NULL); } } else { INTOFF; if (el) { /* no editing if not interactive */ el_end(el); el = NULL; } if (hist) { history_end(hist); hist = NULL; } INTON; } }
/* * Validate file access. Since we * have no uid or gid, for now require * file to exist and be publicly * readable/writable. * If we were invoked with arguments * from inetd then the file must also be * in one of the given directory prefixes. * Note also, full path name must be * given as we have no login directory. */ int validate_access(int peer, char **filep, int mode) { struct stat stbuf; int fd; int error; struct dirlist *dirp; static char pathname[MAXPATHLEN]; char *filename = *filep; /* * Prevent tricksters from getting around the directory restrictions */ if (strstr(filename, "/../")) return (EACCESS); if (*filename == '/') { /* * Allow the request if it's in one of the approved locations. * Special case: check the null prefix ("/") by looking * for length = 1 and relying on the arg. processing that * it's a /. */ for (dirp = dirs; dirp->name != NULL; dirp++) { if (dirp->len == 1 || (!strncmp(filename, dirp->name, dirp->len) && filename[dirp->len] == '/')) break; } /* If directory list is empty, allow access to any file */ if (dirp->name == NULL && dirp != dirs) return (EACCESS); if (stat(filename, &stbuf) < 0) return (errno == ENOENT ? ENOTFOUND : EACCESS); if ((stbuf.st_mode & S_IFMT) != S_IFREG) return (ENOTFOUND); if (mode == RRQ) { if ((stbuf.st_mode & S_IROTH) == 0) return (EACCESS); } else { if ((stbuf.st_mode & S_IWOTH) == 0) return (EACCESS); } } else { int err; /* * Relative file name: search the approved locations for it. * Don't allow write requests that avoid directory * restrictions. */ if (!strncmp(filename, "../", 3)) return (EACCESS); /* * If the file exists in one of the directories and isn't * readable, continue looking. However, change the error code * to give an indication that the file exists. */ err = ENOTFOUND; for (dirp = dirs; dirp->name != NULL; dirp++) { snprintf(pathname, sizeof(pathname), "%s/%s", dirp->name, filename); if (stat(pathname, &stbuf) == 0 && (stbuf.st_mode & S_IFMT) == S_IFREG) { if ((stbuf.st_mode & S_IROTH) != 0) { break; } err = EACCESS; } } if (dirp->name != NULL) *filep = filename = pathname; else if (mode == RRQ) return (err); } /* * This option is handled here because it (might) require(s) the * size of the file. */ option_tsize(peer, NULL, mode, &stbuf); if (mode == RRQ) fd = open(filename, O_RDONLY); else { if (create_new) { if (increase_name) { error = find_next_name(filename, &fd); if (error > 0) return (error + 100); } else fd = open(filename, O_WRONLY | O_TRUNC | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); } else fd = open(filename, O_WRONLY | O_TRUNC); } if (fd < 0) return (errno + 100); file = fdopen(fd, (mode == RRQ)? "r":"w"); if (file == NULL) { close(fd); return (errno + 100); } return (0); }
int runner_start (runner_t *runner) { int pi[3][2] = {{-1, -1}, {-1, -1}, {-1, -1}}; int xpi[2]; int ret = 0; int errno_priv = 0; int i = 0; sigset_t set; if (runner->runerr) { errno = runner->runerr; return -1; } GF_ASSERT (runner->argv[0]); /* set up a channel to child to communicate back * possible execve(2) failures */ ret = pipe(xpi); if (ret != -1) ret = fcntl (xpi[1], F_SETFD, FD_CLOEXEC); for (i = 0; i < 3; i++) { if (runner->chfd[i] != -2) continue; ret = pipe (pi[i]); if (ret != -1) { runner->chio[i] = fdopen (pi[i][i ? 0 : 1], i ? "r" : "w"); if (!runner->chio[i]) ret = -1; } } if (ret != -1) runner->chpid = fork (); switch (runner->chpid) { case -1: errno_priv = errno; close (xpi[0]); close (xpi[1]); for (i = 0; i < 3; i++) { close (pi[i][0]); close (pi[i][1]); } errno = errno_priv; return -1; case 0: for (i = 0; i < 3; i++) close (pi[i][i ? 0 : 1]); close (xpi[0]); ret = 0; for (i = 0; i < 3; i++) { if (ret == -1) break; switch (runner->chfd[i]) { case -1: /* no redir */ break; case -2: /* redir to pipe */ ret = dup2 (pi[i][i ? 1 : 0], i); break; default: /* redir to file */ ret = dup2 (runner->chfd[i], i); } } if (ret != -1 ) { DIR *d = NULL; struct dirent *de = NULL; char *e = NULL; d = opendir ("/proc/self/fd"); if (d) { while ((de = readdir (d))) { i = strtoul (de->d_name, &e, 10); if (*e == '\0' && i > 2 && i != dirfd (d) && i != xpi[1]) close (i); } closedir (d); } else ret = -1; struct rlimit rl; ret = getrlimit (RLIMIT_NOFILE, &rl); GF_ASSERT (ret == 0); for (i = 3; i < rl.rlim_cur; i++) { if (i != xpi[1]) close (i); } } if (ret != -1) { /* save child from inheriting our singal handling */ sigemptyset (&set); sigprocmask (SIG_SETMASK, &set, NULL); execvp (runner->argv[0], runner->argv); } ret = write (xpi[1], &errno, sizeof (errno)); _exit (1); } errno_priv = errno; for (i = 0; i < 3; i++) close (pi[i][i ? 1 : 0]); close (xpi[1]); if (ret == -1) { for (i = 0; i < 3; i++) { if (runner->chio[i]) { fclose (runner->chio[i]); runner->chio[i] = NULL; } } } else { ret = read (xpi[0], (char *)&errno_priv, sizeof (errno_priv)); close (xpi[0]); if (ret <= 0) return 0; GF_ASSERT (ret == sizeof (errno_priv)); } errno = errno_priv; return -1; }
int main(int argc, char* argv[]){ FILE *fp; char hostname[128]; int i, s, port; struct hostent *hp; //この構造体はどっかで決まってるのだろう struct sockaddr_in sin; //この構造体もどっかで決まってるのだろう char buf[128]; //引数の数があってないならはじく(portとhostを指定するはず?なのかな?) if(argc <= 2) { perror("host and port required"); exit(1); } //argv[2]がport番号やから、これが0やったらはじく、と if((port = atoi(argv[2])) == 0) { perror("no port"); exit(1); } //gethostbyname #とは //nameにはホスト名、ドット区切りのIPv4、コロン区切りのIPv6を指定する //んで、hostent構造体を返す //hostを名前から取ってくるんやけど、argv[1]がその名前なのかな //それがNULL、つまり見つからんかったらunknown hostではじくと if ((hp = gethostbyname(argv[1])) == NULL) { fprintf(stderr, "%s: unknown host.\n", hostname); exit(1); } //ここ多分決まった形 //socketはこう書かないといけないのだろう //errorのときに-1が返るのかな? //socket(domain,type,protocol)で成功したらソケット記述子、失敗したら-1 //AF_INETは2ホスト間プロセス通信 //SOCK_STREAMは順次双方向バイトストリーム //0は自動設定 //作ったsocketはcloseで閉じる if((s = socket(AF_INET, SOCK_STREAM, 0)) == -1) { perror("client socket()"); exit(1); } //bzeroとか知らんのじゃい //bzero(void* s,size_t n)で、バイト列sの先頭nバイトを数値0で埋める //memsetと同じ感じ(memsetが推奨) bzero(&sin, sizeof(sin)); sin.sin_family = AF_INET; //アドレスファミリ.AF_INETで固定されることが多い(?) sin.sin_port = htons(port); //sin_portにはポート番号がはいる //big endianにするためにhtons関数を用いる memcpy(&sin.sin_addr, hp->h_addr, hp-> h_length);//hp->h_addrをhp->h_length分sin.sin_addrにコピー //int connect(int socket, const struct sochaddr *address, size_t address_len) //socket::socket()で作成したソケットディスクリプタを指定 //address::sockadderへのポインタを指定 //address_length::アドレス構造体のサイズを指定 //戻り値は成功:0,失敗:-1 if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) { perror("client connect()"); exit(1); } fp = fdopen(s, "r"); // send request to server for(i = 0; i < NUMSTR; i++) { send(s, reqlines[i], strlen(reqlines[i]), 0); } // receive contents from server while (fgets(buf, sizeof(buf), fp) != NULL) { printf("%s", buf); } close(s); return 0; }
static int read_reply(int s, cachemgr_request * req) { char buf[4 * 1024]; FILE *fp = fdopen(s, "r"); /* interpretation states */ enum { isStatusLine, isHeaders, isBodyStart, isBody, isForward, isEof, isForwardEof, isSuccess, isError } istate = isStatusLine; int parse_menu = 0; const char *action = req->action; const char *statusStr = NULL; int status = -1; if (0 == strlen(req->action)) parse_menu = 1; else if (0 == strcasecmp(req->action, "menu")) parse_menu = 1; if (fp == NULL) { perror("fdopen"); return 1; } if (parse_menu) action = "menu"; /* read reply interpreting one line at a time depending on state */ while (istate < isEof) { if (!fgets(buf, sizeof(buf), fp)) istate = istate == isForward ? isForwardEof : isEof; switch (istate) { case isStatusLine: /* get HTTP status */ /* uncomment the following if you want to debug headers */ /* fputs("\r\n\r\n", stdout); */ status = parse_status_line(buf, &statusStr); istate = status == 200 ? isHeaders : isForward; /* if cache asks for authentication, we have to reset our info */ if (status == 401 || status == 407) { reset_auth(req); status = 403; /* Forbiden, see comments in case isForward: */ } /* this is a way to pass HTTP status to the Web server */ if (statusStr) printf("Status: %d %s", status, statusStr); /* statusStr has '\n' */ break; case isHeaders: /* forward header field */ if (!strcmp(buf, "\r\n")) { /* end of headers */ fputs("Content-Type: text/html\r\n", stdout); /* add our type */ istate = isBodyStart; } if (strncasecmp(buf, "Content-Type:", 13)) /* filter out their type */ fputs(buf, stdout); break; case isBodyStart: printf("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"); printf("<HTML><HEAD><TITLE>CacheMgr@%s: %s</TITLE>\n", req->hostname, action); printf("<STYLE type=\"text/css\"><!--BODY{background-color:#ffffff;font-family:verdana,sans-serif}TABLE{background-color:#333333;border:0pt;padding:0pt}TH,TD{background-color:#ffffff}--></STYLE>\n"); printf("</HEAD><BODY>\n"); if (parse_menu) { printf("<H2><a href=\"%s\">Cache Manager</a> menu for %s:</H2>", menu_url(req, "authenticate"), req->hostname); printf("<UL>\n"); } else { printf("<P><A HREF=\"%s\">%s</A>\n<HR noshade size=\"1px\">\n", menu_url(req, "menu"), "Cache Manager menu"); printf("<PRE>\n"); } istate = isBody; /* yes, fall through, we do not want to loose the first line */ case isBody: /* interpret [and reformat] cache response */ if (parse_menu) fputs(munge_menu_line(buf, req), stdout); else fputs(munge_other_line(buf, req), stdout); break; case isForward: /* forward: no modifications allowed */ /* * Note: we currently do not know any way to get browser.reply to * 401 to .cgi because web server filters out all auth info. Thus we * disable authentication headers for now. */ if (!strncasecmp(buf, "WWW-Authenticate:", 17) || !strncasecmp(buf, "Proxy-Authenticate:", 19)); /* skip */ else fputs(buf, stdout); break; case isEof: /* print trailers */ if (parse_menu) printf("</UL>\n"); else printf("</table></PRE>\n"); print_trailer(); istate = isSuccess; break; case isForwardEof: /* indicate that we finished processing an "error" sequence */ istate = isError; break; default: printf("%s: internal bug: invalid state reached: %d", script_name, istate); istate = isError; } } close(s); return 0; }
int main(void){ FILE *par_infile; int pfdout[2], pfdin[2], fd, nread, area_code, mid_code, last_code; int previ_code = 0; int cd_count = 0; int total_count = 0; int count = 0; char buf[512], firstname[25], lastname[25]; if(pipe(pfdout) == -1 || pipe(pfdin) == -1){ perror("pipe"); exit(1); } switch(fork()){ case -1: perror("fork"); exit(2); case 0: if(close(0) == -1){ perror("pipe"); exit(1); } if(dup(pfdout[0]) != 0){ perror("dup"); exit(1); } if(close(1) == -1){ perror("pipe"); exit(1); } if(dup(pfdin[1]) != 1){ perror("dup"); exit(1); } if(close(pfdout[0]) == -1 || close(pfdout[1]) == -1 || close(pfdin[0]) == -1 || close(pfdin[1]) == -1){ perror("close"); exit(1); } execlp("sort", "sort", "-k 3.3n", "-k 1.1", "-k 2.2", NULL); perror("execlp"); exit(1); } if(close(pfdout[0]) == -1 || close(pfdin[1]) == -1){ perror("close"); exit(1); } if((fd = open("cs308a2_sort_data", O_RDONLY, 0)) == -1){ perror("cannot open"); exit(1); } printf("\n"); fflush(stdout); while((nread = read(fd, buf, 80)) != 0){ if(nread == -1){ perror("read"); exit(1); } if(write(pfdout[1], buf, nread) == -1){ perror("write"); exit(1); } if((count += nread) < 4096){ write(1, "*" , 1); } else { /*printf(" "); fflush(stdout);*/ total_count += count; count = 0; sprintf(buf, " %d bytes\n", total_count); write(1, buf, strlen(buf)+1); } } if(close(fd) == -1 || close(pfdout[1]) == -1){ perror("close"); exit(1); } write(1, "\nThrough All Data\n", 18); par_infile = fdopen(pfdin[0], "r"); fscanf(par_infile, "%s %s %d %d %d", lastname, firstname, &area_code, &mid_code, &last_code); sprintf(buf, "\nFirst entry: %s %s %d %d %d\n\n", lastname, firstname, area_code, mid_code, last_code); write(1, buf, strlen(buf)+1); ++cd_count; previ_code = area_code; /* printf("\n%d %d\n", area_code, cd_count); fflush(stdout);*/ while(fscanf(par_infile, "%s %s %d %d %d", lastname, firstname, &area_code, &mid_code, &last_code) != EOF ){ if(area_code != previ_code){ sprintf(buf, "Area code %d appeared %d times.\n", previ_code, cd_count); write(1, buf, strlen(buf)+1); previ_code = area_code; cd_count = 0; } else { /*if(area_code == 103){ printf("here\n"); fflush(stdout); }*/ ++cd_count; } } printf("Area code %d appeared %d times.\n\n", area_code, cd_count); fflush(stdout); fclose(par_infile); return(0); }
/** * readline() 実行 * * @param[in] data テストデータ * @param[in] length バイト数 * @return 結果文字列 */ static uchar * exec_readline(char *data, size_t length) { FILE *fp = NULL; /* ファイルポインタ */ int retval = 0; /* 戻り値 */ pid_t cpid = 0; /* プロセスID */ pid_t w = 0; /* wait戻り値 */ int status = 0; /* ステイタス */ ssize_t len = 0; /* writen 戻り値 */ retval = pipe(pfd); if (retval < 0) { cut_error("pipe=%d", retval); return NULL; } fp = fdopen(pfd[PIPE_R], "r"); if (!fp) { cut_error("fdopen=%p", fp); return NULL; } cpid = fork(); if (cpid < 0) { cut_error("fork(%d)", errno); return NULL; } if (cpid == 0) { /* 子プロセス */ dbglog("child"); close_fd(&pfd[PIPE_R], NULL); /* 送信 */ len = writen(pfd[PIPE_W], data, length); if (len < 0) { outlog("writen"); close_fd(&pfd[PIPE_W], NULL); exit(EXIT_FAILURE); } close_fd(&pfd[PIPE_W], NULL); exit(EXIT_SUCCESS); } else { /* 親プロセス */ dbglog("parent: cpid=%d", (int)cpid); close_fd(&pfd[PIPE_W], NULL); /* テスト関数の実行 */ /* 受信待ち */ result = _readline(fp); dbglog("result=%s", result); close_fd(&pfd[PIPE_R], NULL); w = waitpid(-1, &status, WNOHANG); if (w < 0) cut_notify("wait: status=%d(%d)", status, errno); dbglog("w=%d", (int)w); if (WEXITSTATUS(status)) { cut_notify("child error"); return NULL; } } return result; }
int main (int argc, char* args[]) { /* f = the size of the file n = number of blocks = f / BLK_SIZE + (bool)f%BLK_SIZE fname = the name of the file */ unsigned long b = BLK_SIZE, f = MAX_FILE_SIZE; // std filesize is 100MB int ret; char *fname = tempnam("/tmp", cuserid(NULL)); char *blk; bool random = false; Operation operation = kFWrite; unsigned long i = 0; for (i = 1; i < argc; i++) { if ((args[i][0] == 'b') && (args[i][1] == '=') && (strlen(args[i]) > 2)) { b = atol(&args[i][2]); if (b < 0 || b > MAX_FILE_SIZE) { fprintf(stderr, "Illegal block size %d\n", b); fflush(stderr); b = BLK_SIZE; } } else if ((args[i][0] == 'f') && (args[i][1] == '=') && (strlen(args[i]) > 2)) { f = atol(&args[i][2]); if (f < 0 || f > MAX_FILE_SIZE) { fprintf(stderr, "Illegal block size %d\n", f); fflush(stderr); f = MAX_FILE_SIZE; } } else if (strcmp(args[i], "random") == 0) { random = true; } else if (strcmp(args[i], "read") == 0) { operation = kRead; } else if (strcmp(args[i], "fread") == 0) { operation = kFRead; } else if (strcmp(args[i], "write") == 0) { operation = kWrite; } else if (strcmp(args[i], "fwrite") == 0) { operation = kFWrite; } else { free(fname); fname = args[i]; } } // create the data block and initialize it if necessary blk = (char *) calloc(b, sizeof(char)); if (doingWrites(operation)) composeText(blk, b); // Open the data files FILE *file; int filedes; bool error = 0; switch (operation) { case kRead: filedes = open(fname, O_RDONLY); error = filedes < 0; break; case kWrite: filedes = open(fname, O_CREAT|O_EXCL|O_WRONLY, S_IRWXU); error = filedes < 0; if (error) break; unlink(fname); break; case kFRead: file = fopen(fname, "r"); error = file == NULL; break; case kFWrite: filedes = open(fname, O_CREAT|O_EXCL|O_WRONLY, S_IRWXU); error = filedes < 0; if (error) break ; unlink(fname); file = fdopen(filedes, "w"); error = file == NULL; break; } if (error) { perror("fileIO: Can't open file"); return errno; } if (doingReads(operation)) { struct stat buf; // make stat(2) call stat(fname, &buf); // check filesize f = buf.st_size; } unsigned long n = f/b + ((f%b)?1:0); // n has the number of times to perform the I/O operation, the last // operation may not be a full block unsigned long last_write_size = f % b; unsigned long *randomBlockOrder = NULL; if (random) { randomBlockOrder = (unsigned long *) calloc(n, sizeof(long)); shuffleAry(randomBlockOrder, n); } // testing printf("f: %lu \tb: %lu \tn: %lu\n", f, b, n); printf("%s\t%s\t%s\n", random ? "random" : "", text(operation), fname); // Flush the IO buffers before starting the I/O fflush(stdout); fflush(stderr); // start timing struct timeval t1, t2; gettimeofday(&t1, 0); unsigned long pos = 0; unsigned bytes_left = f; // for (i = 0, pos = 0; pos < f; i++, pos += b) while (bytes_left) { int io_size; io_size = (bytes_left >b)?b:bytes_left; if (random) { if (doingBufferedIO(operation)) ret = fseek(file, pos = randomBlockOrder[i] * b, SEEK_SET); else ret = lseek(filedes, pos = randomBlockOrder[i] * b, SEEK_SET); if (ret < 0) { fprintf(stderr, "Positioning error on operation %ld at position %ld\n", i, pos); perror("Error:"); } } switch(operation) { case kRead: ret = read(filedes, blk, io_size); break; case kWrite: ret = write(filedes, blk, io_size); break; case kFRead: ret = fread(blk, sizeof(char), io_size, file); break; case kFWrite: ret = fwrite(blk, sizeof(char), io_size, file); break; } if (ret < 0) { perror("Error on IO operation:"); break; } bytes_left -= ret; } gettimeofday(&t2, 0); // end timing printf("Time : %ld (secs) + %ld (usecs) \n", (t2.tv_sec - t1.tv_sec - ((bool) (t1.tv_usec > t2.tv_usec))), (t2.tv_usec - t1.tv_usec + ((bool) (t1.tv_usec > t2.tv_usec))*1000000)); return 0; }
/* Joins /proc/[pid]/fd/ and /proc/[pid]/fdinfo/ into the following lines: * 0:/dev/pts/23 * pos: 0 * flags: 0100002 * * 1:/dev/pts/23 * pos: 0 * flags: 0100002 * * 2:/dev/pts/23 * pos: 0 * flags: 0100002 * EOF */ static int compose_open_fds(pid_t pid, char **open_fds) { _cleanup_closedir_ DIR *proc_fd_dir = NULL; _cleanup_close_ int proc_fdinfo_fd = -1; _cleanup_free_ char *buffer = NULL; _cleanup_fclose_ FILE *stream = NULL; const char *fddelim = "", *path; struct dirent *dent = NULL; size_t size = 0; int r; assert(pid >= 0); assert(open_fds != NULL); path = procfs_file_alloca(pid, "fd"); proc_fd_dir = opendir(path); if (!proc_fd_dir) return -errno; proc_fdinfo_fd = openat(dirfd(proc_fd_dir), "../fdinfo", O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC|O_PATH); if (proc_fdinfo_fd < 0) return -errno; stream = open_memstream_unlocked(&buffer, &size); if (!stream) return -ENOMEM; FOREACH_DIRENT(dent, proc_fd_dir, return -errno) { _cleanup_fclose_ FILE *fdinfo = NULL; _cleanup_free_ char *fdname = NULL; int fd; r = readlinkat_malloc(dirfd(proc_fd_dir), dent->d_name, &fdname); if (r < 0) return r; fprintf(stream, "%s%s:%s\n", fddelim, dent->d_name, fdname); fddelim = "\n"; /* Use the directory entry from /proc/[pid]/fd with /proc/[pid]/fdinfo */ fd = openat(proc_fdinfo_fd, dent->d_name, O_NOFOLLOW|O_CLOEXEC|O_RDONLY); if (fd < 0) continue; fdinfo = fdopen(fd, "r"); if (!fdinfo) { safe_close(fd); continue; } for (;;) { _cleanup_free_ char *line = NULL; r = read_line(fdinfo, LONG_LINE_MAX, &line); if (r < 0) return r; if (r == 0) break; fputs(line, stream); fputc('\n', stream); } } errno = 0; stream = safe_fclose(stream); if (errno > 0) return -errno; *open_fds = TAKE_PTR(buffer); return 0; }
/**************************************************************************** * Creator: T. M. Farrington * Purpose: To search a binary file that contains command syntaxes. * * Inputs: One binary file, the name of which is defined in the include file. * Character pointer to the function name to be looked up. * Character pointer to a buffer where the full command syntax will * be placed if it is found. * Maximum string size that the buffer can receive. * * Outputs: Return TRUE if search was successful, FALSE if not. * If TRUE, places full command syntax in the buffer. * ****************************************************************************/ int W_EXPORT KpeGetKALHelp(LPSTR fnameptr, LPSTR buffer, int maxsiz) { FILE *finptr; int iFile; OFSTRUCT of; char pFullPath[FILENAME_MAX]; unsigned short csfname = lstrlen(fnameptr) + 1; unsigned short ssfname, ssrecord; unsigned short found = FALSE; /* First look for the file in KAPPA's system directory. * * If not there, then use the PATH. */ KppGetSystemDirectory(pFullPath, FILENAME_MAX); strncat(pFullPath, binary_file, FILENAME_MAX - strlen(pFullPath) - 1); if ((iFile = OpenFile(pFullPath, &of, OF_READ)) == -1) iFile = OpenFile(binary_file, &of, OF_READ); if ((iFile == -1) || ((finptr = fdopen(iFile, "rb")) == NULL)) { RegisterKappaMessage(IDE_FCANTOPEN, KppAddAtom(binary_file), NULLID, NULLID); KppIncrementPopupCountCB(EDITW); PostKappaMessage(); KppDecrementPopupCountCB(EDITW); return FALSE; } rewind(finptr); /* While not found, get the two string length values (2 bytes each) * at the begining of the record. */ while (!found) { fread(&ssfname, 2, 1, finptr); if (feof(finptr)) break; fread(&ssrecord, 2, 1, finptr); if (feof(finptr)) break; /* If the size of the parameter function name == * size of the scanned function name, */ if (csfname == ssfname) { char data[MAX_RECORD_LENGTH]; /* then read the function name and if the strings match, */ if ((fread(data, ssfname, 1, finptr) != NULL) && (!lstrcmp(fnameptr, data))) { /* get the rest of the record and concatenate both strings into the output file, RBP: Do not concatenate */ /* kstrcpy (buffer, data, maxsiz); */ if (fread(data, ssrecord - ssfname - 4, 1, finptr) != NULL) _fstrncpy(buffer, data, maxsiz); /* Stop the search. */ found = TRUE; } else /* otherwise advance the file pointer to the next record.*/ fseek(finptr, (long) ssrecord - 4 - ssfname, SEEK_CUR); } else /* otherwise advance the file pointer to the next record. */ fseek(finptr, (long) ssrecord - 4, SEEK_CUR); } fclose(finptr); if (!found && (KppGetKalFunctionSyntaxCB(KppCheckAtom(fnameptr), buffer, maxsiz) != -1 || KppGetDLLFunctionSyntax(fnameptr, buffer, maxsiz) != -1)) found = TRUE; return found; }
static int do_ca_cert_bootstrap(struct stream *stream) { struct ssl_stream *sslv = ssl_stream_cast(stream); STACK_OF(X509) *chain; X509 *cert; FILE *file; int error; int fd; chain = SSL_get_peer_cert_chain(sslv->ssl); if (!chain || !sk_X509_num(chain)) { VLOG_ERR("could not bootstrap CA cert: no certificate presented by " "peer"); return EPROTO; } cert = sk_X509_value(chain, sk_X509_num(chain) - 1); /* Check that 'cert' is self-signed. Otherwise it is not a CA * certificate and we should not attempt to use it as one. */ error = X509_check_issued(cert, cert); if (error) { VLOG_ERR("could not bootstrap CA cert: obtained certificate is " "not self-signed (%s)", X509_verify_cert_error_string(error)); if (sk_X509_num(chain) < 2) { VLOG_ERR("only one certificate was received, so probably the peer " "is not configured to send its CA certificate"); } return EPROTO; } fd = open(ca_cert.file_name, O_CREAT | O_EXCL | O_WRONLY, 0444); if (fd < 0) { if (errno == EEXIST) { VLOG_INFO_RL(&rl, "reading CA cert %s created by another process", ca_cert.file_name); stream_ssl_set_ca_cert_file__(ca_cert.file_name, true, true); return EPROTO; } else { VLOG_ERR("could not bootstrap CA cert: creating %s failed: %s", ca_cert.file_name, ovs_strerror(errno)); return errno; } } file = fdopen(fd, "w"); if (!file) { error = errno; VLOG_ERR("could not bootstrap CA cert: fdopen failed: %s", ovs_strerror(error)); unlink(ca_cert.file_name); return error; } if (!PEM_write_X509(file, cert)) { VLOG_ERR("could not bootstrap CA cert: PEM_write_X509 to %s failed: " "%s", ca_cert.file_name, ERR_error_string(ERR_get_error(), NULL)); fclose(file); unlink(ca_cert.file_name); return EIO; } if (fclose(file)) { error = errno; VLOG_ERR("could not bootstrap CA cert: writing %s failed: %s", ca_cert.file_name, ovs_strerror(error)); unlink(ca_cert.file_name); return error; } VLOG_INFO("successfully bootstrapped CA cert to %s", ca_cert.file_name); log_ca_cert(ca_cert.file_name, cert); bootstrap_ca_cert = false; ca_cert.read = true; /* SSL_CTX_add_client_CA makes a copy of cert's relevant data. */ SSL_CTX_add_client_CA(ctx, cert); SSL_CTX_set_cert_store(ctx, X509_STORE_new()); if (SSL_CTX_load_verify_locations(ctx, ca_cert.file_name, NULL) != 1) { VLOG_ERR("SSL_CTX_load_verify_locations: %s", ERR_error_string(ERR_get_error(), NULL)); return EPROTO; } VLOG_INFO("killing successful connection to retry using CA cert"); return EPROTO; }
/* * ex_mkexrc -- :mkexrc[!] [file] * * Create (or overwrite) a .exrc file with the current info. * * PUBLIC: int ex_mkexrc __P((SCR *, EXCMD *)); */ int ex_mkexrc(SCR *sp, EXCMD *cmdp) { struct stat sb; FILE *fp; int fd, sverrno; char *fname; size_t flen; switch (cmdp->argc) { case 0: fname = _PATH_EXRC; break; case 1: INT2CHAR(sp, cmdp->argv[0]->bp, cmdp->argv[0]->len + 1, fname, flen); set_alt_name(sp, fname); break; default: abort(); } if (!FL_ISSET(cmdp->iflags, E_C_FORCE) && !stat(fname, &sb)) { msgq_str(sp, M_ERR, fname, "137|%s exists, not written; use ! to override"); return (1); } /* Create with max permissions of rw-r--r--. */ if ((fd = open(fname, O_CREAT | O_TRUNC | O_WRONLY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) { msgq_str(sp, M_SYSERR, fname, "%s"); return (1); } if ((fp = fdopen(fd, "w")) == NULL) { sverrno = errno; (void)close(fd); goto e2; } if (seq_save(sp, fp, "abbreviate ", SEQ_ABBREV) || ferror(fp)) goto e1; if (seq_save(sp, fp, "map ", SEQ_COMMAND) || ferror(fp)) goto e1; if (seq_save(sp, fp, "map! ", SEQ_INPUT) || ferror(fp)) goto e1; if (opts_save(sp, fp) || ferror(fp)) goto e1; if (fclose(fp)) { sverrno = errno; goto e2; } msgq_str(sp, M_INFO, fname, "138|New exrc file: %s"); return (0); e1: sverrno = errno; (void)fclose(fp); e2: errno = sverrno; msgq_str(sp, M_SYSERR, fname, "%s"); return (1); }
/** Post job result information to Nagios 3.x. * * Nagios 3.x uses a filesystem-based method of posting results. Results are * written to a temporary file. Once the temp file is closed, it's moved into * the Nagios results queue directory, and a marker file of the same name, but * with a ".ok" suffice, is created. This marker file tells Nagios that the * results file is complete and ready to be processed. * * Nagios writes the first half of the results file in a temporary directory, * and allows the child check process to finish it and move it to the results * queue directory. DNX foregoes the temporarly file and writes the results * file directly into the queue directory, and then creates the marker file. * * SECURITY NOTE: Nagios creates the results file in a secure manner by * setting the umask to mask off ALL rights from anyone but the owner of the * file (Nagios). DNX doesn't have the luxury of being able to manipulate the * umask because DNX check results are posted in a secondary thread, which is * not allowed to manipulate the umask because it would cause a race condition * with the main thread in Nagios. * * @param[in] svc - the nagios service to which the results belong. * @param[in] check_type - nagios 3.x check type value. * @param[in] check_options - nagios 3.x bit-wise check options. * @param[in] schedule - boolean; nagios 3.x schedule flag. * @param[in] reschedule - boolean; nagios 3.x reschedule flag. * @param[in] start_time - the check start time in seconds. * @param[in] finish_time - the check finish time in seconds. * @param[in] early_timeout - boolean; true (!0) means the service timed out. * @param[in] exited_ok - boolean; true (!0) if the external check exited ok. * @param[in] res_code - the check result code. * @param[in] res_data - the check result data. * * @return Zero on success, or a non-zero error value. * * @todo This routine should be in nagios code. */ static int nagios3xPostResult(service * svc, int check_type, int check_options, int schedule, int reschedule, time_t start_time, time_t finish_time, int early_timeout, int exited_ok, int res_code, char * res_data) { char * escaped_res_data; char * filename; FILE * fp = 0; int fd; // a nagios 3.x global variable extern char * temp_path; // a nagios 3.x core function if ((escaped_res_data = escape_newlines(res_data)) == 0) return DNX_ERR_MEMORY; // open a file in the check results path for storing check results // path length + 'checkXXXXXX' (11) + '/' (1) + '.ok' (3) + null (1) if ((filename = (char *)xmalloc(strlen(temp_path) + 11 + 1 + 3 + 1)) == 0) { free(escaped_res_data); // allocated by nagios - use free return DNX_ERR_MEMORY; } sprintf(filename, "%s/checkXXXXXX", temp_path); if ((fd = mkstemp(filename)) < 0 || (fp = fdopen(fd, "w")) == 0) { xfree(filename); free(escaped_res_data); // allocated by nagios - use free if (fd >= 0) close(fd); return DNX_ERR_OPEN; } // write check results to the queue file fprintf(fp, "### Active Check Result File ###\n"); fprintf(fp, "file_time=%lu\n\n", (unsigned long)start_time); fprintf(fp, "### Nagios Service Check Result ###\n"); fprintf(fp, "# Time: %s", ctime(&start_time)); fprintf(fp, "host_name=%s\n", svc->host_name); fprintf(fp, "service_description=%s\n", svc->description); fprintf(fp, "check_type=%d\n", check_type); fprintf(fp, "check_options=%d\n", check_options); fprintf(fp, "scheduled_check=%d\n", schedule); fprintf(fp, "reschedule_check=%d\n", reschedule); fprintf(fp, "latency=%f\n", svc->latency); fprintf(fp, "start_time=%lu.0\n", (unsigned long)start_time); fprintf(fp, "finish_time=%lu.%lu\n", (unsigned long)finish_time); fprintf(fp, "early_timeout=%d\n", early_timeout); fprintf(fp, "exited_ok=%d\n", exited_ok); fprintf(fp, "return_code=%d\n", res_code); fprintf(fp, "output=%s\n", escaped_res_data); fclose(fp); free(escaped_res_data); // allocated by nagios - use free nagios3xMoveCheckResultToQueue(filename); xfree(filename); return 0; }
static char *lxc_attach_getpwshell(uid_t uid) { /* local variables */ pid_t pid; int pipes[2]; int ret; int fd; char *result = NULL; /* we need to fork off a process that runs the * getent program, and we need to capture its * output, so we use a pipe for that purpose */ ret = pipe(pipes); if (ret < 0) return NULL; pid = fork(); if (pid < 0) { close(pipes[0]); close(pipes[1]); return NULL; } if (pid) { /* parent process */ FILE *pipe_f; char *line = NULL; size_t line_bufsz = 0; int found = 0; int status; close(pipes[1]); pipe_f = fdopen(pipes[0], "r"); while (getline(&line, &line_bufsz, pipe_f) != -1) { char *token; char *saveptr = NULL; long value; char *endptr = NULL; int i; /* if we already found something, just continue * to read until the pipe doesn't deliver any more * data, but don't modify the existing data * structure */ if (found) continue; /* trim line on the right hand side */ for (i = strlen(line); i > 0 && (line[i - 1] == '\n' || line[i - 1] == '\r'); --i) line[i - 1] = '\0'; /* split into tokens: first user name */ token = strtok_r(line, ":", &saveptr); if (!token) continue; /* next: dummy password field */ token = strtok_r(NULL, ":", &saveptr); if (!token) continue; /* next: user id */ token = strtok_r(NULL, ":", &saveptr); value = token ? strtol(token, &endptr, 10) : 0; if (!token || !endptr || *endptr || value == LONG_MIN || value == LONG_MAX) continue; /* dummy sanity check: user id matches */ if ((uid_t) value != uid) continue; /* skip fields: gid, gecos, dir, go to next field 'shell' */ for (i = 0; i < 4; i++) { token = strtok_r(NULL, ":", &saveptr); if (!token) break; } if (!token) continue; if (result) free(result); result = strdup(token); /* sanity check that there are no fields after that */ token = strtok_r(NULL, ":", &saveptr); if (token) continue; found = 1; } free(line); fclose(pipe_f); again: if (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) goto again; return NULL; } /* some sanity checks: if anything even hinted at going * wrong: we can't be sure we have a valid result, so * we assume we don't */ if (!WIFEXITED(status)) return NULL; if (WEXITSTATUS(status) != 0) return NULL; if (!found) return NULL; return result; } else { /* child process */ char uid_buf[32]; char *arguments[] = { "getent", "passwd", uid_buf, NULL }; close(pipes[0]); /* we want to capture stdout */ dup2(pipes[1], 1); close(pipes[1]); /* get rid of stdin/stderr, so we try to associate it * with /dev/null */ fd = open("/dev/null", O_RDWR); if (fd < 0) { close(0); close(2); } else { dup2(fd, 0); dup2(fd, 2); close(fd); } /* finish argument list */ ret = snprintf(uid_buf, sizeof(uid_buf), "%ld", (long) uid); if (ret <= 0) exit(-1); /* try to run getent program */ (void) execvp("getent", arguments); exit(-1); } }
int main(int argc, char *argv[]) { int c; char *dir = "."; char *outf = NULL; char *volname = NULL; int verbose=0; char buf[256]; struct filenode *root; struct stat sb; int lastoff; int i; char *p; struct aligns *pa, *pa2; struct excludes *pe, *pe2; FILE *f; while ((c = getopt(argc, argv, "V:vd:f:ha:A:x:")) != EOF) { switch(c) { case 'd': dir = optarg; break; case 'f': outf = optarg; break; case 'V': volname = optarg; break; case 'v': verbose = 1; break; case 'h': showhelp(argv[0]); exit(0); case 'a': align = strtoul(optarg, NULL, 0); if (align < 16 || (align & (align - 1))) { fprintf(stderr, "Align has to be at least 16 bytes and a power of two\n"); exit(1); } break; case 'A': i = strtoul(optarg, &p, 0); if (i < 16 || (i & (i - 1))) { fprintf(stderr, "Align has to be at least 16 bytes and a power of two\n"); exit(1); } if (*p != ',' || !p[1]) { fprintf(stderr, "-A takes N,PATTERN format of argument, where N is a number\n"); exit(1); } /* strlen(p+1) + 1 eq strlen(p) */ pa = (struct aligns *)malloc(sizeof(*pa) + strlen(p)); pa->align = i; pa->next = NULL; strcpy(pa->pattern, p + 1); if (!alignlist) alignlist = pa; else { for (pa2 = alignlist; pa2->next; pa2 = pa2->next) ; pa2->next = pa; } break; case 'x': pe = (struct excludes *)malloc(sizeof(*pe) + strlen(optarg) + 1); pe->next = NULL; strcpy(pe->pattern, optarg); if (!excludelist) excludelist = pe; else { for (pe2 = excludelist; pe2->next; pe2 = pe2->next) ; pe2->next = pe; } break; default: exit(1); } } if (!volname) { sprintf(buf, "rom %08lx", time(NULL)); volname = buf; } if (!outf) { fprintf(stderr, "%s: you must specify the destination file\n", argv[0]); fprintf(stderr, "Try `%s -h' for more information\n",argv[0]); exit(1); } if (strcmp(outf, "-") == 0) { f = fdopen(1,"wb"); } else f = fopen(outf, "wb"); if (!f) { perror(outf); exit(1); } realbase = strlen(dir); root = newnode(dir, volname, 0); root->parent = root; lastoff = processdir (1, dir, dir, &sb, root, root, spaceneeded(root)); if (verbose) shownode(0, root, stderr); dumpall(root, lastoff, f); exit(0); }