コード例 #1
0
ファイル: path.cpp プロジェクト: sekrit-twc/imagine
std::string path_canonicalize(const std::string &path)
{
	std::wstring wpath = utf8_to_utf16(path);
	std::wstring out;

	DWORD status = MAX_PATH;
	while (status > out.size()) {
		out.resize(status);
		status = GetFullPathNameW(wpath.c_str(), static_cast<DWORD>(out.size()), &out[0], nullptr);
		if (status == 0)
			trap_error("error canonicalizing path");
	}
	// On success, GetFullPathName returns the number of non-terminating characters.
	out.resize(status);
	return utf16_to_utf8(out);
}
コード例 #2
0
ファイル: ifc_file.c プロジェクト: CESNET/Nemea-Framework
/**
 * \brief Allocate and initiate file output interface.
 * This function is called by TRAP library to initialize one output interface.
 * \param[in,out] ctx   Pointer to the private libtrap context data (trap_ctx_init()).
 * \param[in] params    Configuration string containing colon separated values of these parameters (in this exact order): *file_name*:*open_mode*,
 * where file_name is a path to a file in which data is to be written and
 * open_mode is either a - append or w - write, if no mode is specified, the file will be opened in append mode.
 * \param[in,out] ifc   IFC interface used for calling file module.
 * \param[in] idx       Index of IFC that is created.
 * \return 0 on success (TRAP_E_OK), TRAP_E_MEMORY, TRAP_E_BADPARAMS on error
 */
int create_file_send_ifc(trap_ctx_priv_t *ctx, const char *params, trap_output_ifc_t *ifc, uint32_t idx)
{
   file_private_t *priv;
   char *dest;
   const char *params_next = NULL;
   wordexp_t exp_result;
   size_t length;

   if (params == NULL) {
      return trap_errorf(ctx, TRAP_E_BADPARAMS, "parameter is null pointer");
   }

   /* Create structure to store private data */
   priv = calloc(1, sizeof(file_private_t));
   if (!priv) {
      return trap_error(ctx, TRAP_E_MEMORY);
   }

   priv->ctx = ctx;
   priv->ifc_idx = idx;
   priv->file_change_size = 0;
   priv->file_change_time = 0;
   priv->file_index = 0;
   priv->file_cnt = 0;
   priv->filename = dest = NULL;
   /* Set default mode */
   strcpy(priv->mode, "ab");

   /* Parse file name */
   length = strcspn(params, ":");
   if (params[length] == ':') {
      params_next = params + length + 1;
   }

   if (length) {
      dest = (char*) calloc(length + 1, sizeof(char));
      if (!dest) {
         free(priv);
         return trap_error(ctx, TRAP_E_MEMORY);
      }

      strncpy(dest, params, length);
   } else {
      free(priv);
      return trap_errorf(ctx, TRAP_E_BADPARAMS, "OUTPUT FILE IFC: file name not specified");
   }

   /* Perform shell-like expansion of ~ */
   if (wordexp(dest, &exp_result, 0) != 0) {
      VERBOSE(CL_ERROR, "CREATE OUTPUT FILE IFC: unable to perform shell-like expand of: %s", dest);
      free(priv);
      free(dest);
      wordfree(&exp_result);
      return trap_errorf(ctx, TRAP_E_BADPARAMS, "CREATE OUTPUT FILE IFC: unable to perform shell-like expand");
   }

   free(dest);
   priv->filename_base_length = strlen(exp_result.we_wordv[0]);

   priv->filename = (char *) calloc(priv->filename_base_length + 1, sizeof(char));
   if (!priv->filename) {
      free(priv);
      wordfree(&exp_result);
      return trap_error(ctx, TRAP_E_MEMORY);
   }

   strncpy(priv->filename, exp_result.we_wordv[0], priv->filename_base_length + 1);
   wordfree(&exp_result);

   /* Parse mode */
   if (params_next) {
      length = strcspn(params_next, ":");
      if (length == 1) {
         if (params_next[0] == 'w') {
            priv->mode[0] = 'w';
         }

         if (params_next[1] == ':') {
            params_next = params_next + 2;
         } else {
            params_next = NULL;
         }
      }
   }

   /* Set special behavior for /dev/stdout */
   if (priv->filename_base_length == 11 && strncmp(priv->filename, "/dev/stdout", 11) == 0) {
      priv->mode[0] = 'w';
      priv->file_change_size = 0;
      priv->file_change_time = 0;
   } else {
      /* Parse remaining parameters */
      while (params_next) {
         length = strcspn(params_next, ":");
         if (length > 5 && strncmp(params_next, "time=", 5) == 0) {
            priv->file_change_time = atoi(params_next + 5);
            /* Generate new name of file from current time */
            char *tmp = create_filename_from_time(priv);
            free(priv->filename);
            if (!tmp) {
               VERBOSE(CL_ERROR, "CREATE OUTPUT FILE IFC[%d]: memory allocation failed.", priv->ifc_idx);
               free(priv);
               return trap_error(ctx, TRAP_E_MEMORY);
            } else {
               priv->filename = tmp;
            }
         } else if (length > 5 && strncmp(params_next, "size=", 5) == 0) {
            priv->file_change_size = atoi(params_next + 5);
         }

         if (params_next[length] == '\0') {
            break;
         }

         params_next = params_next + length + 1;
      }
   }

   if (priv->mode[0] == 'a' && access(priv->filename, F_OK) != -1) {
      char *buffer = NULL;
      do {
         if (buffer != NULL) {
            free(buffer);
            buffer = NULL;
         }

         if (asprintf(&buffer, "%s.%zu", priv->filename, priv->file_index) < 0) {
            VERBOSE(CL_ERROR, "CREATE OUTPUT FILE IFC: asprintf failed.");
            free(priv->filename);
            free(priv);
            return trap_error(ctx, TRAP_E_MEMORY);
         }

         priv->file_index++;
      } while (access(buffer, F_OK) != -1);

      priv->fd = fopen(buffer, priv->mode);
      free(buffer);
   } else {
      priv->fd = fopen(priv->filename, priv->mode);
   }

   if (priv->fd == NULL) {
      VERBOSE(CL_ERROR, "CREATE OUTPUT FILE IFC : unable to open file \"%s\" in mode \"%c\". Possible reasons: non-existing file, bad permission, file can not be opened in this mode.", priv->filename, priv->mode[0]);
      free(priv->filename);
      free(priv);
      return trap_errorf(ctx, TRAP_E_BADPARAMS, "unable to open file");
   }

   priv->is_terminated = 0;

   /* Fills interface structure */
   ifc->send = file_send;
   ifc->disconn_clients = open_next_file_wrapper;
   ifc->terminate = file_terminate;
   ifc->destroy = file_destroy;
   ifc->get_client_count = file_get_client_count;
   ifc->create_dump = file_create_dump;
   ifc->priv = priv;
   ifc->get_id = file_send_ifc_get_id;

   return TRAP_E_OK;
}
コード例 #3
0
ファイル: ifc_file.c プロジェクト: CESNET/Nemea-Framework
/**
 * \brief Allocate and initiate file input interface.
 * This function is called by TRAP library to initialize one input interface.
 *
 * \param[in,out] ctx   Pointer to the private libtrap context data (trap_ctx_init()).
 * \param[in] params    Configuration string containing *file_name*,
 * where file_name is a path to a file from which data is to be read
 * \param[in,out] ifc   IFC interface used for calling file module.
 * \param[in] idx       Index of IFC that is created.
 * \return 0 on success (TRAP_E_OK), TRAP_E_MEMORY, TRAP_E_BADPARAMS on error
 */
int create_file_recv_ifc(trap_ctx_priv_t *ctx, const char *params, trap_input_ifc_t *ifc, uint32_t idx)
{
   file_private_t *priv;
   size_t name_length;
   wordexp_t files_exp;
   int i, j;

   if (params == NULL) {
      return trap_errorf(ctx, TRAP_E_BADPARAMS, "parameter is null pointer");
   }

   /* Create structure to store private data */
   priv = calloc(1, sizeof(file_private_t));
   if (!priv) {
      return trap_error(ctx, TRAP_E_MEMORY);
   }

   priv->ctx = ctx;
   priv->ifc_idx = idx;
   /* Perform shell-like expansion of ~ */
   if (wordexp(params, &files_exp, 0) != 0) {
      VERBOSE(CL_ERROR, "CREATE INPUT FILE IFC: unable to perform shell-like expand of: %s", params);
      free(priv);
      return trap_errorf(ctx, TRAP_E_BADPARAMS, "CREATE INPUT FILE IFC: unable to perform shell-like expand");
   }

   priv->file_cnt = files_exp.we_wordc;
   priv->files = (char**) calloc(priv->file_cnt, sizeof(char*));
   if (!priv->files) {
      free(priv);
      wordfree(&files_exp);
      return trap_error(ctx, TRAP_E_MEMORY);
   }

   for (i = 0; i < priv->file_cnt; i++) {
      name_length = strlen(files_exp.we_wordv[i]);
      priv->files[i] = (char*) calloc(name_length + 1, sizeof(char));
      if (!priv->files[i]) {
         for (j = i - 1; j >= 0; j --) {
            free(priv->files[j]);
         }

         free(priv->files);
         free(priv);
         wordfree(&files_exp);
         return trap_error(ctx, TRAP_E_MEMORY);
      }

      strncpy(priv->files[i], files_exp.we_wordv[i], name_length);
   }

   wordfree(&files_exp);
   priv->filename = priv->files[0];

   /* Sets mode and filename */
   strcpy(priv->mode, "rb");

   /* Attempts to open the file */
   priv->fd = fopen(priv->filename, priv->mode);
   if (priv->fd == NULL) {
      VERBOSE(CL_ERROR, "CREATE INPUT FILE IFC: unable to open file \"%s\". Possible reasons: non-existing file, bad permission.", priv->filename);
      for (i = 0; i < priv->file_cnt; i++) {
         free(priv->files[i]);
      }

      free(priv->files);
      free(priv);
      return trap_errorf(ctx, TRAP_E_BADPARAMS, "unable to open file");
   }

   priv->file_index = 0;
   priv->is_terminated = 0;

   /* Fills interface structure */
   ifc->recv = file_recv;
   ifc->terminate = file_terminate;
   ifc->destroy = file_destroy;
   ifc->create_dump = file_create_dump;
   ifc->priv = priv;
   ifc->get_id = file_recv_ifc_get_id;
   ifc->is_conn = file_recv_ifc_is_conn;

   return TRAP_E_OK;
}
コード例 #4
0
ファイル: ifc_file.c プロジェクト: CESNET/Nemea-Framework
/**
 * \brief Write data to a file.
 * Data to write are expected as a trap_buffer_header_t structure, thus actual length of data to be written is determined from trap_buffer_header_t->data_length
 * trap_buffer_header_t->data_length is expected to be in network byte order (little endian)
 *
 * \param[in] priv   pointer to module private data
 * \param[in] data   pointer to data to write
 * \param[in] size   size of data to write - NOT USED IN THIS INTERFACE
 * \param[in] timeout   NOT USED IN THIS INTERFACE
 * \return 0 on success (TRAP_E_OK), TTRAP_E_IO_ERROR if error occurs during writing, TRAP_E_TERMINATED if interface was terminated.
 */
int file_send(void *priv, const void *data, uint32_t size, int timeout)
{
   int ret_val = 0;
   file_private_t *config = (file_private_t*) priv;
   size_t written;

   if (config->is_terminated) {
      return trap_error(config->ctx, TRAP_E_TERMINATED);
   }

   /* Check whether the file stream is opened */
   if (config->fd == NULL) {
      return trap_error(config->ctx, TRAP_E_NOT_INITIALIZED);
   }

#ifdef ENABLE_NEGOTIATION
   if (config->neg_initialized == 0) {
      ret_val = output_ifc_negotiation((void *) config, TRAP_IFC_TYPE_FILE, 0);
      if (ret_val == NEG_RES_OK) {
         VERBOSE(CL_VERBOSE_LIBRARY, "File output_ifc_negotiation result: success.");
         config->neg_initialized = 1;
         fflush(config->fd);
      } else if (ret_val == NEG_RES_FMT_UNKNOWN) {
         VERBOSE(CL_VERBOSE_LIBRARY, "File output_ifc_negotiation result: failed (unknown data format of this output interface -> refuse client).");
         return trap_error(config->ctx, TRAP_E_NOT_INITIALIZED);
      } else { /* ret_val == NEG_RES_FAILED */
         VERBOSE(CL_VERBOSE_LIBRARY, "File output_ifc_negotiation result: failed (error while sending hello message to input interface).");
         return trap_error(config->ctx, TRAP_E_NOT_INITIALIZED);
      }
   }
#endif

   /* Writes data_length bytes to the file */
   written = fwrite(data, 1, size, config->fd);
   if (written != size) {
      VERBOSE(CL_ERROR, "OUTPUT FILE IFC: unable to write to file: %s", config->filename);
      return trap_errorf(config->ctx, TRAP_E_IO_ERROR, "OUTPUT FILE IFC: unable to write");
   }

   if (config->file_change_time != 0) {
      time_t current_time = time(NULL);
      if (difftime(current_time, config->starting_time) / 60 >= config->file_change_time) {
         char *new_filename = create_filename_from_time(priv);
         if (!new_filename) {
            VERBOSE(CL_ERROR, "OUTPUT FILE IFC[%d]: memory allocation failed.", config->ifc_idx);
            return trap_error(config->ctx, TRAP_E_MEMORY);
         }

         if (open_next_file(priv, new_filename) < 0) {
            VERBOSE(CL_ERROR, "OUTPUT FILE IFC[%d]: opening new file failed.", config->ifc_idx);
            return trap_errorf(config->ctx, TRAP_E_BADPARAMS, "unable to open file");
         }
      }
   }

   if (config->file_change_size != 0 && (uint64_t)ftell(config->fd) >= (uint64_t)(1024 * 1024 * (uint64_t)config->file_change_size)) {
      char *new_filename = create_next_filename(priv);
      if (!new_filename) {
         VERBOSE(CL_ERROR, "OUTPUT FILE IFC[%d]: memory allocation failed.", config->ifc_idx);
         return trap_error(config->ctx, TRAP_E_MEMORY);
      }

         if (open_next_file(priv, new_filename) < 0) {
            VERBOSE(CL_ERROR, "OUTPUT FILE IFC[%d]: opening new file failed.", config->ifc_idx);
            return trap_errorf(config->ctx, TRAP_E_BADPARAMS, "unable to open file");
         }
   }

   return TRAP_E_OK;
}
コード例 #5
0
ファイル: ifc_file.c プロジェクト: CESNET/Nemea-Framework
/**
 * \brief Read data from a file.
 * \param[in] priv   pointer to module private data
 * \param[out] data  pointer to a memory block in which data is to be stored
 * \param[out] size  pointer to a memory block in which size of read data is to be stored
 * \param[in] timeout   NOT USED IN THIS INTERFACE
 * \return 0 on success (TRAP_E_OK), TRAP_E_IO_ERROR if error occurs during reading, TRAP_E_TERMINATED if interface was terminated.
 */
int file_recv(void *priv, void *data, uint32_t *size, int timeout)
{
   size_t loaded;
   char *next_file = NULL;
   /* header of message inside the buffer */
   uint16_t *m_head = data;
   uint32_t data_size = 0;

   file_private_t *config = (file_private_t*) priv;

   if (config->is_terminated) {
      return trap_error(config->ctx, TRAP_E_TERMINATED);
   }

   /* Check whether the file stream is opened */
   if (config->fd == NULL) {
      return trap_error(config->ctx, TRAP_E_NOT_INITIALIZED);
   }

#ifdef ENABLE_NEGOTIATION
neg_start:
   if (config->neg_initialized == 0) {
      switch(input_ifc_negotiation((void *) config, TRAP_IFC_TYPE_FILE)) {
      case NEG_RES_FMT_UNKNOWN:
         VERBOSE(CL_VERBOSE_LIBRARY, "Input_ifc_negotiation result: failed (unknown data format of the output interface).");
         return TRAP_E_FORMAT_MISMATCH;

      case NEG_RES_CONT:
         VERBOSE(CL_VERBOSE_LIBRARY, "Input_ifc_negotiation result: success.");
         config->neg_initialized = 1;
         break;

      case NEG_RES_RECEIVER_FMT_SUBSET:
         VERBOSE(CL_VERBOSE_LIBRARY, "Input_ifc_negotiation result: success (data specifier of the input interface is subset of the output interface data specifier).");
         config->neg_initialized = 1;
         break;

      case NEG_RES_SENDER_FMT_SUBSET:
         VERBOSE(CL_VERBOSE_LIBRARY, "Input_ifc_negotiation result: success (new data specifier of the output interface is subset of the old one; it was not first negotiation).");
         config->neg_initialized = 1;
         break;

      case NEG_RES_FAILED:
         VERBOSE(CL_VERBOSE_LIBRARY, "Input_ifc_negotiation result: failed (error while receiving hello message from output interface).");
         return TRAP_E_FORMAT_MISMATCH;

      case NEG_RES_FMT_MISMATCH:
         VERBOSE(CL_VERBOSE_LIBRARY, "Input_ifc_negotiation result: failed (data format or data specifier mismatch).");
         return TRAP_E_FORMAT_MISMATCH;

      default:
         VERBOSE(CL_VERBOSE_LIBRARY, "Input_ifc_negotiation result: default case");
         break;
      }
   }
#endif

   /* Reads 4 bytes from the file, determining the length of bytes to be read to @param[out] data */
   loaded = fread(&data_size, sizeof(uint32_t), 1, config->fd);
   if (loaded != 1) {
      if (feof(config->fd)) {
         next_file = get_next_file(priv);
         if (!next_file) {
            /* set size of buffer to the size of 1 message (including its header) */
            (*size) = 2;
            /* set the header of message to 0B */
            *m_head = 0;

            return TRAP_E_OK;
         } else {
            if (open_next_file(config, next_file) == 0) {
#ifdef ENABLE_NEGOTIATION
               goto neg_start;
#endif
            } else {
               return trap_errorf(config->ctx, TRAP_E_IO_ERROR, "INPUT FILE IFC[%d]: unable to open next file.", config->ifc_idx);
            }
         }
      } else {
         VERBOSE(CL_ERROR, "INPUT FILE IFC: read error occurred in file: %s", config->filename);
         return trap_errorf(config->ctx, TRAP_E_IO_ERROR, "INPUT FILE IFC: unable to read");
      }
   }

   *size = ntohl(data_size);
   /* Reads (*size) bytes from the file */
   loaded = fread(data, 1, (*size), config->fd);
   if (loaded != (*size)) {
         VERBOSE(CL_ERROR, "INPUT FILE IFC: read incorrect number of bytes from file: %s. Attempted to read %d bytes, but the actual count of bytes read was %zu.", config->filename, (*size), loaded);
   }

   return TRAP_E_OK;
}