Exemplo n.º 1
0
// basically oauth_sign_url() from liboauth in steps..
char *oauthsign_ext (int mode, char *method, oauthparam *op, int optargc, char **optargv, int *saveargcp, char ***saveargvp) {
    int argc=0;
    char **argv = NULL;
    char *sign=NULL;

    url_to_array(&argc, &argv, mode, op->url);
    append_parameters(&argc, &argv, optargc, optargv);
    add_oauth_params_to_array(&argc, &argv, op);
    if (saveargvp && saveargcp) {
        clear_parameters(saveargcp, saveargvp);
        append_parameters(saveargcp, saveargvp, argc, argv);
    }

    sign=process_array(argc, argv, method, mode, op);
    free_array(argc,argv);
    return (sign); // needs to be free()d.

#if 0 // cruft
    if (sign) {
        add_kv_to_array(&argc, &argv, "oauth_signature", sign);
        free(sign);
    }
    char *result;
    result = oauth_serialize_url(argc, (mode&2?1:0), argv);
    return (result);
#endif
}
Exemplo n.º 2
0
int main (int argc, char *argv[])
{
  /* check that we were given at least one argument
   * (the transfer file name) */
  if (argc != 2) {
    printf("Usage: scr_transfer <transferfile>\n");
    return 1;
  }

  /* record the name of the transfer file */
  scr_transfer_file = strdup(argv[1]);
  if (scr_transfer_file == NULL) {
    scr_err("scr_transfer: Copying transfer file name @ %s:%d",
            __FILE__, __LINE__
    );
    return 1;
  }

  /* initialize our tracking variables */
  read_params();

  /* get file io mode */
  mode_t mode_file = scr_getmode(1, 1, 0);

  /* we cache the opened file descriptors to avoid extra opens,
   * seeks, and closes */
  int fd_src = -1;
  int fd_dst = -1;

  char* new_file_src = NULL;
  char* old_file_src = NULL;
  char* new_file_dst = NULL;
  char* old_file_dst = NULL;

  off_t new_position = 0;
  off_t old_position = 0;

  /* start in the stopped state */
  state = STOPPED;
  set_transfer_file_state(SCR_TRANSFER_KEY_STATE_STOP, 0);

  /* TODO: enable this value to be set from config file */
  /* TODO: page-align this buffer for faster performance */
  /* allocate our file copy buffer */
  size_t bufsize = scr_file_buf_size;
  char* buf = malloc(bufsize);
  if (buf == NULL) {
    scr_err("scr_transfer: Failed to allocate %llu bytes for file copy buffer @ %s:%d",
            (unsigned long long) bufsize, __FILE__, __LINE__
    );
    return 1;
  }

  int nread = 0;
  double secs_run   = 0.0;
  double secs_slept = 0.0;
  double secs_run_start  = scr_seconds();
  double secs_run_end    = secs_run_start;
  double secs_last_write = secs_run_start;
  scr_hash* hash = scr_hash_new();
  while (keep_running) {
    /* loop here sleeping and checking transfer file periodically
     * until state changes and / or some time elapses */
    /* reset our timer for our last write */
    double secs_remain = scr_transfer_secs;
    while (keep_running && (state == STOPPED || secs_remain > 0.0)) {
      /* remember our current state before reading transfer file */
      int old_state = state;

      /* read the transfer file, which fills in our hash and
       * also updates state and bytes_per_second */
      scr_hash_delete(&hash);
      hash = read_transfer_file();

      /* compute time we should sleep before writing more data based
       * on bandwidth and percent of runtime limits */
      if (state == RUNNING) {
        /* get the current time */
        double secs_now = scr_seconds();

        /* based on the amount we last wrote and our allocated bandwidth,
         * compute time we need to sleep before attempting our next write */
        double secs_remain_bw = 0.0;
        if (nread > 0 && bytes_per_second > 0.0) {
          double secs_to_wait_bw = (double) nread / bytes_per_second;
          double secs_waited_bw = secs_now - secs_last_write;
          secs_remain_bw = secs_to_wait_bw - secs_waited_bw;
        }

        /* based on the percentage of time we are allowed to be running,
         * compute time we need to sleep before attempting our next write */
        double secs_remain_runtime = 0.0;
        if (percent_runtime > 0.0) {
          /* stop the run clock, add to the run time,
           * and restart the run clock */
          secs_run_end = secs_now;
          secs_run += secs_run_end - secs_run_start;
          secs_run_start = secs_run_end;

          /* compute our total time, and the time we need to sleep */
          double secs_total = secs_run + secs_slept;
          secs_remain_runtime = secs_run / percent_runtime - secs_total;
        }

        /* take the maximum of these two values */
        secs_remain = secs_remain_bw;
        if (secs_remain_runtime > secs_remain) {
          secs_remain = secs_remain_runtime;
        }
      }

      /* check for a state transition */
      if (state != old_state) {
        if (state == RUNNING) {
          /* if we switched to RUNNING, kick out without sleeping and
           * reset the total run and sleep times */
          secs_remain = 0.0;
          secs_run    = 0.0;
          secs_slept  = 0.0;
        } else if (state == STOPPED) {
          /* if we switched to STOPPED, close our files if open */
          close_files(new_file_src, &fd_src, new_file_dst, &fd_dst);
          clear_parameters(&new_file_src, &new_file_dst, &new_position);
          clear_parameters(&old_file_src, &old_file_dst, &old_position);

          /* after closing our files, update our state in the transfer file */
          set_transfer_file_state(SCR_TRANSFER_KEY_STATE_STOP, 0);
        }
      }

      /* assume we can sleep for the full remainder of the time */
      double secs = secs_remain;

      /* if we're not running, always sleep for the full time */
      if (state != RUNNING) {
        secs = scr_transfer_secs;
      }

      /* set a maximum time to sleep before we read the hash file again
       * (ensures some responsiveness) */
      if (secs > scr_transfer_secs) {
        secs = scr_transfer_secs;
      }

      /* sleep if we need to */
      if (secs > 0.0) {
        /* stop the run clock and add to the total run time */
        secs_run_end = scr_seconds();
        secs_run += secs_run_end - secs_run_start;

        /* sleep */
        usleep((unsigned long) (secs * 1000000.0));
        secs_slept += secs;
        secs_remain -= secs;

        /* restart the run clock */
        secs_run_start = scr_seconds();
      }
    }

    /* write data out */
    if (state == RUNNING) {
      /* look for a new file to transfer */
      off_t filesize = 0;
      find_file(hash, &new_file_src, &new_file_dst, &new_position, &filesize);

      /* if we got a new file, close the old one (if open),
       * open the new file */
      if (bool_diff_files(new_file_src, old_file_src)) {
        /* close the old descriptor if it's open */
        if (fd_src >= 0) {
          scr_close(old_file_src, fd_src);
          fd_src = -1;
        }

        /* delete the old file name if we have one */
        if (old_file_src != NULL) {
          free(old_file_src);
          old_file_src = NULL;
        }

        /* reset our position counter */
        old_position = 0;

        /* open the file and remember the filename if we have one */
        if (new_file_src != NULL) {
          fd_src = scr_open(new_file_src, O_RDONLY);
          /* TODO: check for errors here */
          old_file_src = strdup(new_file_src);
          /* TODO: check for errors here */
        }
      }

      /* if we got a new file, close the old one (if open),
       * open the new file */
      if (bool_diff_files(new_file_dst, old_file_dst)) {
        /* close the old descriptor if it's open */
        if (fd_dst >= 0) {
          scr_close(old_file_dst, fd_dst);
          fd_dst = -1;
        }

        /* delete the old file name if we have one */
        if (old_file_dst != NULL) {
          free(old_file_dst);
          old_file_dst = NULL;
        }

        /* reset our position counter */
        old_position = 0;

        /* open the file and remember the filename if we have one */
        if (new_file_dst != NULL) {
          fd_dst = scr_open(new_file_dst, O_RDWR | O_CREAT, mode_file);
          /* TODO: check for errors here */
          old_file_dst = strdup(new_file_dst);
          /* TODO: check for errors here */
        }
      }

      /* we may have the same file, but perhaps the position changed
       * (may need to seek) */
      if (new_position != old_position) {
        if (fd_src >= 0) {
          lseek(fd_src, new_position, SEEK_SET);
          /* TODO: check for errors here */
        }

        if (fd_dst >= 0) {
          lseek(fd_dst, new_position, SEEK_SET);
          /* TODO: check for errors here */
        }

        /* remember the new position */
        old_position = new_position;
      }

      /* if we have two open files,
       * copy a chunk from source file to destination file */
      nread = 0;
      if (fd_src >= 0 && fd_dst >= 0) {
        /* compute number of bytes to read from file */
        size_t count = (size_t) (filesize - new_position);
        if (count > bufsize) {
          count = bufsize;
        }

        /* read a chunk */
        nread = scr_read(new_file_src, fd_src, buf, count);

        /* if we read data, write it out */
        if (nread > 0) {
          /* record the time of our write */
          secs_last_write = scr_seconds();

          /* write the chunk and force it out with an fsync */
          scr_write(new_file_dst, fd_dst, buf, nread);
          fsync(fd_dst);

          /* update our position */
          new_position += (off_t) nread;
          old_position = new_position;

          /* record the updated position in the transfer file */
          update_transfer_file(new_file_src, new_file_dst, new_position);
        }

        /* if we've written all of the bytes, close the files */
        if (new_position == filesize) {
          close_files(new_file_src, &fd_src, new_file_dst, &fd_dst);
          clear_parameters(&new_file_src, &new_file_dst, &new_position);
          clear_parameters(&old_file_src, &old_file_dst, &old_position);
        }
      } else {
        /* TODO: we may have an error
         * (failed to open the source or dest file) */
        /* if we found no file to transfer, move to a STOPPED state */
        if (new_file_src == NULL) {
          state = STOPPED;
          set_transfer_file_state(SCR_TRANSFER_KEY_STATE_STOP, 1);
        }
      }
    }
  }

  /* free our file copy buffer */
  if (buf != NULL) {
    free(buf);
    buf = NULL;
  }

  /* free the strdup'd tranfer file name */
  if (scr_transfer_file != NULL) {
    free(scr_transfer_file);
    scr_transfer_file = NULL;
  }

  return 0;
}
Exemplo n.º 3
0
/* given a hash of transfer file data, look for a file which needs to
 * be transfered. If src file is set, try to continue with that file,
 * otherwise, pick the first available file */
int find_file(scr_hash* hash, char** src, char** dst, off_t* position, off_t* filesize)
{
  int found_a_file = 0;

  scr_hash* files = scr_hash_get(hash, SCR_TRANSFER_KEY_FILES);
  if (files != NULL) {
    /* if we're given a file name, try to continue with that file */
    if (!found_a_file && src != NULL && *src != NULL) {
      /* src was set, so assume dst is also set, create a dummy dst
       * variable to hold the string which may be strdup'd in
       * need_transfer call */
      char* tmp_dst = NULL;
      if (need_transfer(files, *src, &tmp_dst, position, filesize) == SCR_SUCCESS) {
        /* can continue with the same file (position may have been
         * updated though) */
        found_a_file = 1;

        /* free the dummy */
        /* TODO: note that if destination has been updated, we're
         * ignoring that change */
        free(tmp_dst);
      } else {
        /* otherwise, this file no longer needs transfered,
         * so free the strings */
        clear_parameters(src, dst, position);
      }
    }

    /* if we still don't have a file, scan the hash and use the first
     * file we find */
    if (!found_a_file) {
      scr_hash_elem* elem;
      for (elem = scr_hash_elem_first(files);
           elem != NULL;
           elem = scr_hash_elem_next(elem))
      {
        /* get the filename */
        char* name = scr_hash_elem_key(elem);

        /* check whether this file needs transfered */
        if (name != NULL &&
            need_transfer(files, name, dst, position, filesize) == SCR_SUCCESS)
        {
          /* found a file, copy its name (the destination and postion
           * are set in need_transfer) */
          *src = strdup(name);
          found_a_file = 1;
          break;
        }
      }
    }
  }

  /* if we didn't find a file, set src and dst to NULL and set
   * position to 0 */
  if (!found_a_file) {
    clear_parameters(src, dst, position);
    return SCR_FAILURE;
  }

  return SCR_SUCCESS;
}