Beispiel #1
0
///////////////////////////////////////////////////////////////////////////////
/// @fn validateDate( string date )
/// @brief Checks the passed date for validity in format and numbering
/// @param string date is the date to be checked
/// @return true if the date is valid (in "MM/DD" format with possible real days)
/// @return false if the date is invalid
///////////////////////////////////////////////////////////////////////////////
bool validate::validateDate( string date ) {
  
  int month = 0;           //Number of the month we were sent to check
  int day = 0;             //Number of the day we were sent to check
  int monthsInAYear = 12;  //Number of months in a year

  //This is an array of the number of days in each month, that is:
  //31 days in January, 28 (or 29) in February, 31 in March, etc.
  int daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

  //Makes sure the date is only 5 characters long, that is, "MM/DD"
  if ( date.length() != 5 ) { return false; }

  //Grabs the 2 left characters of the date and converts to an integer
  month = str_to_int( str_left( date, 2 ) );

  //Grabs the 2 right characters of the date and converts to an integer
  day = str_to_int( str_right( date, 2 ) );
  
  //Checks to make sure the month number is a valid number
  if ( month > monthsInAYear || month <= 0 ) {

    return false;
  
  //checks to make sure the day number is valid
  } else if ( day > daysInMonth[month - 1] || day <= 0 ) {

    return false;
  		
  }

  return true;

}
//////////////////////////////////////////////////////////////////////
/// @fn vector<string> str_split(string str, string delimiters, bool keep_delim)
/// @brief -- Returns a vector of strings from str by breaking
///           lines at any of delimiters, 
/// @param string str -- The string to search
/// @param string delimiters -- A string of delimiting characters.
/// @param bool keep_delim -- Maintains the delimiters in the lines
///                           if true, or discards if false.
//////////////////////////////////////////////////////////////////////
vector<string> str_split(string str, string delimiters, bool keep_delim) {

  vector<string> lines;

  while (str != "") {

    unsigned int delimiter_pos = str.find_first_of(delimiters);

    // If we DID find a delimiter...
    if (delimiter_pos != string::npos) {

      // Shift the position forward by either one or zero,
      // depending on keep_delim.
      // This prevents delimiter_pos from becoming zero if
      // we don't find a delimiter (npos = -1) and keep_delim
      // is true, thus calling str_left with a length of zero.
      delimiter_pos += keep_delim;

      // By keeping the length to delimiter_pos, we can exclude the
      // delimiters unless keep_delim is true, in which case it
      // will include the delimiters
      lines.push_back(str_left(str, delimiter_pos));

      // Remove the part of the string we just captured.
      // Adjust by keep_delim here instead of in str_left
      // so we avoid the situation described above.
      str = str_right(str, str.length() - delimiter_pos + keep_delim - 1);

    } else {

      // If we didn't find a delimiter...
      // Push EVERYTHING onto the vector.
      lines.push_back(str);

      // And empty the string.
      str = "";

    }

  };

  return lines;

}
Beispiel #3
0
static void
handle_sigurg(void* p_private)
{
  struct mystr async_cmd_str = INIT_MYSTR;
  struct mystr async_arg_str = INIT_MYSTR;
  struct mystr real_cmd_str = INIT_MYSTR;
  unsigned int len;
  struct vsf_session* p_sess = (struct vsf_session*) p_private;
  /* Did stupid client sent something OOB without a data connection? */
  if (p_sess->data_fd == -1)
  {
    return;
  }
  /* Get the async command - blocks (use data timeout alarm) */
  vsf_cmdio_get_cmd_and_arg(p_sess, &async_cmd_str, &async_arg_str, 0);
  /* Chop off first four characters; they are telnet characters. The client
   * should have sent the first two normally and the second two as urgent
   * data.
   */
  len = str_getlen(&async_cmd_str);
  if (len >= 4)
  {
    str_right(&async_cmd_str, &real_cmd_str, len - 4);
  }
  if (str_equal_text(&real_cmd_str, "ABOR"))
  {
    p_sess->abor_received = 1;
    vsf_sysutil_shutdown_failok(p_sess->data_fd);
  }
  else
  {
    /* Sorry! */
    vsf_cmdio_write(p_sess, FTP_BADCMD, "Unknown command.");
  }
  str_free(&async_cmd_str);
  str_free(&async_arg_str);
  str_free(&real_cmd_str);
}
Beispiel #4
0
///////////////////////////////////////////////////////////////////////////////
/// @fn vector<string> getDates( string startDate, string endDate )
/// @brief Returns a vector of strings that contain all the dates between 
///   startDate and endDate, inclusively
/// @param string startDate is the start date for the requested vacation 
/// @param string endDate is the end date for the requested vacation
/// @pre the dates being passed in have already been validated
///   using the validateDate function
/// @ret vector of strings that contain all dates between startDate and endDate
///   inclusive
/// @note the parameters startDate and endDate must be in "MM/DD" where MM is 
///   the month number and DD is the day number
/// @note all of the strings (dates) in the vector returned will be in the 
///   format of "MM/DD"
///////////////////////////////////////////////////////////////////////////////
vector<string> validate::getDates( string startDate, string endDate ) {

  //if ( validateDate( startDate ) == false || validateDate( endDate ) == false ) {

    //OUTPUT.insert_line(OUTPUT.num_lines(), "The dates sent into getDates fail. This is why we're infinite looping probably k.\n";

  //}

  //Grabs the 2 left characters of the dates and converts to integers
  int startMonth = str_to_int( str_left( startDate, 2 ) );
  int   endMonth = str_to_int( str_left( endDate, 2 ) );

  //Grabs the 2 right characters of the dates and converts to integers
  int startDay = str_to_int( str_right( startDate, 2 ) );
  int   endDay = str_to_int( str_right( endDate, 2 ) );

  //This will be our day to begin each iteration's pushing of dates into the
  //dates vector
  int startIterationDay = 0;

  //An array of 12 items (0 to 11) telling us how many days are in each month
  int daysInMonth[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };

  //This will be used so we can deal with request rollovers from month to month
  //And from december into january
  int currentIterationMonth = startMonth; 
  
  //This will be our flag for telling us we're done loading all of the dates 
  //between start and end into the vector. 1=done, 0=not done yet
  bool Done = false;
  
  //This will be our flag for telling us when we're rolling over from one month
  //to another, default to false so we can start from the middle of a random
  //month 
  bool fromAnotherMonth = false;

  //This will be used for pushing onto the dates vector
  string currentIterationDate = "";

  //This will store all of the dates between startDate and endDate, inclusively
  vector<string> dates;

  //While we're not done
  while ( !Done ) {

    //This should start us on the correct day, be it at the beginning of the
    //month due to rollover or in the middle of some random month because that
    //is the day that was requested
    if ( fromAnotherMonth ) {
      
      startIterationDay = 1;
    
    } else {
      
      startIterationDay = startDay;
    
    }
      
    //This should run from either the start day or the beginning of a 
    //the month to the number of days in the month or the endDate
    //Whichever happens to come first
    for ( int x = startIterationDay; x <= daysInMonth[currentIterationMonth - 1]; x++ ) {
      
      //We want to generate dates like: "0M/0D" or "0M/DD"
      if ( currentIterationMonth < 10 ) {

        //We want to generate dates like: "0M/0D"
        if ( x < 10 ) {

          currentIterationDate = "0" + int_to_str( currentIterationMonth ) + "/0" + int_to_str( x );
        
        //We want to generate dates like "0M/DD"
        } else {

          currentIterationDate =  "0" + int_to_str( currentIterationMonth ) + "/" + int_to_str( x );

        }
      
      //We want to generate dates like: "MM/0D" or "MM/DD"
      } else {

        //We want to generate dates like: "MM/0D"
        if ( x < 10 ) {

          currentIterationDate = int_to_str( currentIterationMonth ) + "/0" + int_to_str( x );

        }

        //We want to generate dates like "MM/DD"
        else {

          currentIterationDate = int_to_str( currentIterationMonth ) + "/" + int_to_str( x );

        }

      } //End date generation //end else
            
      //Push proper date in form of MM/DD into the dates vector! Yaaay!
      dates.push_back( currentIterationDate );

      //If we've arrived at the endDate, we need to stop pushing more 
      //dates into the vector, we we change our Done flag to 1 to
      //stop us once we go back to the top of the while loop

      /*
      //The stuff in this comment block is the original stuff, the rest below the loop
      OUTPUT.insert_line(OUTPUT.num_lines(), "currentiterationdate: " << currentIterationDate << "endDate: " << endDate << "\n";
      if ( currentIterationDate == endDate ) { Done = true; break; }
      
      //However, if we still haven't hit the endDate and we're at the
      //end of the month, we need to set up to rollover to the next month
      else if ( x == daysInMonth[currentIterationMonth - 1] ) {

        fromAnotherMonth = true;       //We are coming from another month
        currentIterationMonth+=1;   //We need to start in the next month

      }
      
      //And for added rollover ability, if we get to the end of December
      //and we need to roll into January, we set the month iteration back
      //to 1, for the first month
      if ( currentIterationMonth == 13 ) { currentIterationMonth = 1; break; }*/
      
    } //End for loop

      //However, if we still haven't hit the endDate and we're at the
      //end of the month, we need to set up to rollover to the next month
      //else if ( x == daysInMonth[currentIterationMonth - 1] ) {

        fromAnotherMonth = true;       //We are coming from another month
        currentIterationMonth+=1;   //We need to start in the next month

      //}
      if ( currentIterationDate == endDate ) { Done = true; break; }
      //And for added rollover ability, if we get to the end of December
      //and we need to roll into January, we set the month iteration back
      //to 1, for the first month
      if ( currentIterationMonth == 13 ) { currentIterationMonth = 1; }

  } //end while loop

  return dates; //Sends back the vector of dates we workd so hard to get

} //end getDates()
Beispiel #5
0
int
vsf_filename_passes_filter(const struct mystr* p_filename_str,
                           const struct mystr* p_filter_str,
                           unsigned int* iters)
{
    /* A simple routine to match a filename against a pattern.
     * This routine is used instead of e.g. fnmatch(3), because we should be
     * reluctant to trust the latter. fnmatch(3) involves _lots_ of string
     * parsing and handling. There is broad potential for any given fnmatch(3)
     * implementation to be buggy.
     *
     * Currently supported pattern(s):
     * - any number of wildcards, "*" or "?"
     * - {,} syntax (not nested)
     *
     * Note that pattern matching is only supported within the last path
     * component. For example, searching for /a/b/? will work, but searching
     * for /a/?/c will not.
     */
    struct mystr filter_remain_str = INIT_MYSTR;
    struct mystr name_remain_str = INIT_MYSTR;
    struct mystr temp_str = INIT_MYSTR;
    struct mystr brace_list_str = INIT_MYSTR;
    struct mystr new_filter_str = INIT_MYSTR;
    int ret = 0;
    char last_token = 0;
    int must_match_at_current_pos = 1;
    str_copy(&filter_remain_str, p_filter_str);
    str_copy(&name_remain_str, p_filename_str);

    while (!str_isempty(&filter_remain_str) && *iters < VSFTP_MATCHITERS_MAX)
    {
        static struct mystr s_match_needed_str;
        /* Locate next special token */
        struct str_locate_result locate_result =
            str_locate_chars(&filter_remain_str, "*?{");
        (*iters)++;
        /* Isolate text leading up to token (if any) - needs to be matched */
        if (locate_result.found)
        {
            unsigned int indexx = locate_result.index;
            str_left(&filter_remain_str, &s_match_needed_str, indexx);
            str_mid_to_end(&filter_remain_str, &temp_str, indexx + 1);
            str_copy(&filter_remain_str, &temp_str);
            last_token = locate_result.char_found;
        }
        else
        {
            /* No more tokens. Must match remaining filter string exactly. */
            str_copy(&s_match_needed_str, &filter_remain_str);
            str_empty(&filter_remain_str);
            last_token = 0;
        }
        if (!str_isempty(&s_match_needed_str))
        {
            /* Need to match something.. could be a match which has to start at
             * current position, or we could allow it to start anywhere
             */
            unsigned int indexx;
            locate_result = str_locate_str(&name_remain_str, &s_match_needed_str);
            if (!locate_result.found)
            {
                /* Fail */
                goto out;
            }
            indexx = locate_result.index;
            if (must_match_at_current_pos && indexx > 0)
            {
                goto out;
            }
            /* Chop matched string out of remainder */
            str_mid_to_end(&name_remain_str, &temp_str,
                           indexx + str_getlen(&s_match_needed_str));
            str_copy(&name_remain_str, &temp_str);
        }
        if (last_token == '?')
        {
            if (str_isempty(&name_remain_str))
            {
                goto out;
            }
            str_right(&name_remain_str, &temp_str, str_getlen(&name_remain_str) - 1);
            str_copy(&name_remain_str, &temp_str);
            must_match_at_current_pos = 1;
        }
        else if (last_token == '{')
        {
            struct str_locate_result end_brace =
                str_locate_char(&filter_remain_str, '}');
            must_match_at_current_pos = 1;
            if (end_brace.found)
            {
                str_split_char(&filter_remain_str, &temp_str, '}');
                str_copy(&brace_list_str, &filter_remain_str);
                str_copy(&filter_remain_str, &temp_str);
                str_split_char(&brace_list_str, &temp_str, ',');
                while (!str_isempty(&brace_list_str))
                {
                    str_copy(&new_filter_str, &brace_list_str);
                    str_append_str(&new_filter_str, &filter_remain_str);
                    if (vsf_filename_passes_filter(&name_remain_str, &new_filter_str,
                                                   iters))
                    {
                        ret = 1;
                        goto out;
                    }
                    str_copy(&brace_list_str, &temp_str);
                    str_split_char(&brace_list_str, &temp_str, ',');
                }
                goto out;
            }
            else if (str_isempty(&name_remain_str) ||
                     str_get_char_at(&name_remain_str, 0) != '{')
            {
                goto out;
            }
            else
            {
                str_right(&name_remain_str, &temp_str,
                          str_getlen(&name_remain_str) - 1);
                str_copy(&name_remain_str, &temp_str);
            }
        }
        else
        {
            must_match_at_current_pos = 0;
        }
    }
    /* Any incoming string left means no match unless we ended on the correct
     * type of wildcard.
     */
    if (str_getlen(&name_remain_str) > 0 && last_token != '*')
    {
        goto out;
    }
    /* OK, a match */
    ret = 1;
    if (*iters == VSFTP_MATCHITERS_MAX) {
        ret = 0;
    }
out:
    str_free(&filter_remain_str);
    str_free(&name_remain_str);
    str_free(&temp_str);
    str_free(&brace_list_str);
    str_free(&new_filter_str);
    return ret;
}
//////////////////////////////////////////////////////////////////////
/// @fn string str_strip(string str, string to_strip, bool leading, bool inner, bool trailing)
/// @brief -- Returns the string with all instances of to_strip
///           removed, according to the parameters.
/// @param string str -- The string to examine
/// @param string to_strip -- The string to find and remove
/// @param bool leading -- Whether to remove instances of to_strip found
///                        at the beginning of the string, before other
///                        characters.
/// @param bool inner -- Whether to remove instances of to_strip found
///                      between other characters.
/// @param bool trailing -- Whether to remove instances of to_strip found
///                         at the end of the string.
//////////////////////////////////////////////////////////////////////
string str_strip(string str, string to_strip, bool leading, bool inner, bool trailing) {

  // For sanity's sake...
  if (str.find(to_strip) == string::npos ||
      (!leading && !inner && !trailing)) {

    // Don't bother if it's not there. :)
    return str;

  }

  // Now... Check leading/trailing
  if (leading) {

    // While the first characters in the string match
    // what we're stripping...
    while (str_left(str, to_strip.length()) == to_strip) {

      // Throw them away.
      str = str_right(str, str.length() - to_strip.length());

    };

  } /* if (leading) */

  if (trailing) {

    // While the last characters in the string match
    // what we're stripping...
    while (str_right(str, to_strip.length()) == to_strip) {

      // Throw them away.
      str = str_left(str, str.length() - to_strip.length());

    };

  } /* if (trailing) */

  // Work from the inside.
  if (inner) {

    // Get the edges.
    unsigned int left = 0;
    unsigned int right = str.length();

    // Loop through the string and find the first bit that
    // doesn't match what we're stripping.
    while (str_mid(str, left, to_strip.length()) == to_strip) {

      left += to_strip.length();

    };

    // Loop through and find the last that doesn't match.
    while (str_mid(str, right - to_strip.length(), to_strip.length()) == to_strip) {

      right -= to_strip.length();

    };

    bool done = false;

    while (!done) {

      unsigned int pos = str.find(to_strip, left);

      if (pos == string::npos || pos > right) {

        done = true;

      } else {

        str.erase(pos, to_strip.length());

        // Since we just removed a chunk of the string,
        // we have to adjust the right bound.
        right -= to_strip.length();

      } /* if (pos == string::npos) */

    }; /* while (!done) */

  } /* if (inner) */

  return str;

}