Example #1
0
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;
}
Example #2
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);
}
Example #3
0
/* 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;
}
Example #4
0
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;
}
Example #5
0
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));
}
Example #6
0
/*
 * 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;
	}
}
Example #7
0
 FileToString() {
   pipe(FD);
   input = fdopen(FD[1], "w");
 }
Example #8
0
/*
 * 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");
}
Example #9
0
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);
}
Example #10
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;
}
Example #11
0
//********************************************************************
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;
}
Example #12
0
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);
}
Example #13
0
/*
 * 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;
}
Example #14
0
/* 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;
}
Example #15
0
File: wrc.c Project: DeltaYang/wine
/* 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;
}
Example #16
0
/*
 * 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;
	}
}
Example #17
0
/*
 * 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);
}
Example #18
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;
}
Example #19
0
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;
}
Example #20
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;
}
Example #21
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);
}
Example #22
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;
}
Example #23
0
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;
}
Example #24
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;
}
Example #25
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;
}
Example #26
0
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;
}
Example #27
0
/*
 * 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);
}
Example #28
0
/** 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;
}
Example #29
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);
    }
}
Example #30
0
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);
}