예제 #1
0
/**
 * @name main:
 */
int main(int argc, char *argv[]) {

  int rv = 0;
  char **argp = argv;

  gammu_state_t *s = NULL;
  initialize_application_options(&app);

  argc -= 1;
  app.application_name = *argp++;

  int n = parse_global_arguments(argc, argp, &app);

  if (app.invalid) {
    print_usage_error(U_ERR_ARGS_INVAL);
    goto cleanup;
  }
  
  if (app.help) {
    usage();
    goto cleanup;
  }

  argc -= n;
  argp += n;

  /* Execute command:
   *   This runs the operation provided via command-line arguments. */

  if (argc > 0) {
    if (!process_command(&s, argc, argp, &rv)) {
      print_usage_error(U_ERR_CMD_INVAL);
    }
  } else if (!app.repl) {
    print_usage_error(U_ERR_CMD_MISSING);
    goto cleanup;
  }

  /* Read, execute, print loop:
   *  Repeatedly read lines of JSON from standard input, parse
   *  them in to command/arguments tuples, dispatch these tuples
   *  to `process_command`, and repeat until reaching end-of-file. */

  if (app.repl) {
    process_repl_commands(&s, stdin);
  }

  cleanup:

    if (s) {
      gammu_destroy(s);
    }

    return rv;
}
예제 #2
0
/**
 * @name process_repl_commands:
 */
void process_repl_commands(gammu_state_t **s, FILE *stream) {

  for (;;) {

    boolean_t is_eof = FALSE;
    char *line = read_line(stream, &is_eof);

    if (!line) {
      break;
    }

    if (is_eof && line[0] == '\0') {
      goto cleanup;
    }

    parsed_json_t *p = parse_json(line);

    if (p) {

      char **argv = NULL;
      int argc = 0, err = 0;

      boolean_t rv = parsed_json_to_arguments(p, &argc, &argv, &err);

      if (!rv) {
        print_json_validation_error(err);
        goto cleanup_json;
      }

      int result = 0;

      if (!process_command(s, argc, argv, &result)) {

        if (!result) {
          print_usage_error(U_ERR_CMD_INVAL);
        }
        goto cleanup_json;
      }

    } else {
      print_json_validation_error(V_ERR_PARSE);
    }

    cleanup_json:

      if (p) {
        release_parsed_json(p);
      }

    cleanup:

      free(line);

      if (is_eof) {
        break;
      }
  }
}
예제 #3
0
/**
 * @name parse_global_arguments:
 */
int parse_global_arguments(int argc, char *argv[], app_options_t *o) {

  int rv = 0;
  char **argp = argv;

  while (*argp != NULL) {

    if (strcmp(*argp, "-h") == 0 || strcmp(*argp, "--help") == 0) {
      o->help = TRUE;
      break;
    }

    if (strcmp(*argp, "-c") == 0 || strcmp(*argp, "--config") == 0) {

      if (*++argp == NULL) {
        print_usage_error(U_ERR_CONFIG_MISSING);
        o->invalid = TRUE;
        break;
      }

      o->gammu_configuration_path = *argp++;
      rv += 2;

      continue;
    }

    if (strcmp(*argp, "-v") == 0 || strcmp(*argp, "--verbose") == 0) {
      o->verbose = TRUE;
      ++argp; ++rv;
      continue;
    }

    if (strcmp(*argp, "-r") == 0 || strcmp(*argp, "--repl") == 0) {

      o->repl = TRUE;
      ++argp; ++rv;

      /* FIXME: Remove this when REPL mode is stable */
      warn("-r/--repl is experimental code");

      continue;
    }

    break;
  }

  return rv;
}
예제 #4
0
/**
 * @name action_delete_messages:
 */
int action_delete_messages(gammu_state_t **sp,
                           int argc, char *argv[]) {

  int rv = 0;
  bitfield_t *bf = NULL;

  if (argc < 2) {
    print_usage_error(U_ERR_LOC_MISSING);
    return 1;
  }

  int delete_all = (strcmp(argv[1], "all") == 0);

  if (!delete_all) {

    unsigned long n;
    boolean_t found = find_maximum_integer_argument(&n, &argv[1]);

    if (!found) {
      print_usage_error(U_ERR_LOC_INVAL);
      rv = 2; goto cleanup;
    }

    if (n == ULONG_MAX && errno == ERANGE) {
      print_usage_error(U_ERR_OVERFLOW);
      rv = 3; goto cleanup;
    }

    bf = bitfield_create(n);

    if (!bf) {
      print_operation_error(OP_ERR_INDEX);
      rv = 4; goto cleanup_delete;
    }

    if (!bitfield_set_integer_arguments(bf, &argv[1])) {
      print_operation_error(OP_ERR_LOCATION);
      rv = 5; goto cleanup_delete;
    }
  }

  /* Lazy initialization of libgammu */
  gammu_state_t *s = gammu_create_if_necessary(sp);

  if (!s) {
    print_operation_error(OP_ERR_INIT);
    rv = 6; goto cleanup_delete;
  }

  printf("{ ");

  if (!delete_selected_messages(s, bf)) {
    print_operation_error(OP_ERR_DELETE);
    rv = 7; goto cleanup_json;
  }

  cleanup_json:
    printf(" }\n");

  cleanup_delete:
    if (bf) {
      bitfield_destroy(bf);
    }

  cleanup:
    return rv;
}
예제 #5
0
/**
 * @name action_send_messages:
 */
int action_send_messages(gammu_state_t **sp,
                         int argc, char *argv[]) {

  int rv = 0;
  char **argp = &argv[1];

  if (argc <= 2) {
    print_usage_error(U_ERR_ARGS_MISSING);
    return 1;
  }

  if (argc % 2 != 1) {
    print_usage_error(U_ERR_ARGS_ODD);
    return 2;
  }

  /* Lazy initialization of libgammu */
  gammu_state_t *s = gammu_create_if_necessary(sp);

  if (!s) {
    print_operation_error(OP_ERR_INIT);
    rv = 3; goto cleanup;
  }

  /* Allocate */
  smsc_t *smsc = allocate(sizeof(*smsc));
  multimessage_t *sms = allocate(sizeof(*sms));
  multimessage_info_t *info = allocate(sizeof(*info));

  /* Find SMSC number */
  smsc->Location = 1;

  if ((s->err = GSM_GetSMSC(s->sm, smsc)) != ERR_NONE) {
    print_operation_error(OP_ERR_SMSC);
    rv = 4; goto cleanup_sms;
  }

  transmit_status_t status;
  initialize_transmit_status(&status);

  GSM_SetSendSMSStatusCallback(
    s->sm, _message_transmit_callback, &status
  );

  boolean_t is_start = TRUE;
  unsigned int message_index = 0;

  printf("[");

  /* For each message... */
  while (*argp != NULL) {

    GSM_ClearMultiPartSMSInfo(info);
    GSM_Debug_Info *debug = GSM_GetGlobalDebug();

    /* Copy/convert destination phone number */
    char *sms_destination_number = convert_utf8_utf16be(*argp++, FALSE);

    if (!sms_destination_number) {
      status.err = "Invalid UTF-8 sequence in destination number";
      goto cleanup_end;
    }

    string_info_t nsi;
    utf16be_string_info(sms_destination_number, &nsi);

    /* Check size of phone number:
        We'll be decoding this in to a fixed-sized buffer. */

    if (nsi.units >= GSM_MAX_NUMBER_LENGTH) {
      status.err = "Phone number is too long";
      goto cleanup_transmit_status;
    }

    /* Missing message text:
        This shouldn't happen since we check `argc` above,
        but I'm leaving this here in case we refactor later. */

    if (*argp == NULL) {
      status.err = "No message body provided";
      goto cleanup_transmit_status;
    }

    /* UTF-8 message content */
    char *sms_message = *argp++;

    /* Convert message from UTF-8 to UTF-16-BE:
        Every symbol is two bytes long; the string is then
        terminated by a single 2-byte UTF-16 null character. */

    char *sms_message_utf16be = convert_utf8_utf16be(sms_message, FALSE);

    if (!sms_message_utf16be) {
      status.err = "Invalid UTF-8 sequence";
      goto cleanup_transmit_status;
    }

    /* Prepare message info structure:
        This information is used to encode the possibly-multipart SMS. */

    info->Class = 1;
    info->EntriesNum = 1;
    info->Entries[0].ID = SMS_ConcatenatedTextLong;
    info->Entries[0].Buffer = (uint8_t *) sms_message_utf16be;
    info->UnicodeCoding = !utf16be_is_gsm_string(sms_message_utf16be);

    if ((s->err = GSM_EncodeMultiPartSMS(debug, info, sms)) != ERR_NONE) {
      status.err = "Failed to encode message";
      goto cleanup_sms_text;
    }

    status.parts_sent = 0;
    status.parts_total = sms->Number;

    /* For each SMS part... */
    for (unsigned int i = 0; i < sms->Number; i++) {

      status.finished = FALSE;
      status.message_part_index = i;

      sms->SMS[i].PDU = SMS_Submit;

      /* Copy destination phone number:
           This is a fixed-size buffer; size was already checked above. */

      CopyUnicodeString(sms->SMS[i].SMSC.Number, smsc->Number);

      CopyUnicodeString(
        sms->SMS[i].Number, (unsigned char *) sms_destination_number
      );

      /* Transmit a single message part */
      if ((s->err = GSM_SendSMS(s->sm, &sms->SMS[i])) != ERR_NONE) {
        status.parts[i].err = "Message transmission failed";
        continue;
      }

      for (;;) {
        /* Wait for reply */
        GSM_ReadDevice(s->sm, TRUE);

        if (status.finished) {
          break;
        }
      }

      if (!status.parts[i].transmitted) {
        status.parts[i].err = "Message delivery failed";
        continue;
      }

      status.parts_sent++;
    }

    cleanup_sms_text:
      status.message_index = ++message_index;
      free(sms_message_utf16be);

    cleanup_transmit_status:
      print_json_transmit_status(s, sms, &status, is_start);
      free(sms_destination_number);

    cleanup_end:
      is_start = FALSE;
  }

  cleanup_sms:

    free(sms);
    free(smsc);
    free(info);
    printf("]\n");
  
  cleanup:

    return rv;
}
예제 #6
0
int main(int argc, char **argv)
{
    EncodeInfo encInfo;
    
    // To store size of image and secret file
    uint src_img_size;
    
    // Fill with sample filenames
    encInfo.src_image_fname = "beautiful.bmp";
    encInfo.secret_fname = "secret.txt";
    encInfo.stego_image_fname = "stego_img.bmp";
    
    // Test argument
    if ((argc < 3))
    {
        print_usage_error("Invalid Arguments");
        return 1;
    }
    
    //Test check_operation_type and read_and_validate_encode_args
    if (read_and_validate_encode_args(argv, &encInfo) == e_failure)
    {
        print_usage_error("Invalid Entry. Not Supported");
        return 1;
    }
    
    
    if (check_operation_type(argv) == e_encode)
    {
        // Test open_files
        if (open_files_encode(&encInfo) == e_failure)
        {
            printf("ERROR: %s function failed\n", "open_files" );
            return 1;
        }
        
        // Test get_image_size_for_bmp
        encInfo.image_capacity = get_image_size_for_bmp(encInfo.fptr_src_image);
        //printf("INFO: Image size = %u\n", encInfo.image_capacity);
    
        // Test get_file_size
        encInfo.size_secret_file = get_file_size(encInfo.fptr_secret);
        //printf("INFO: secret  size = %ld\n", encInfo.size_secret_file);
    
        //Test check_capacity
        if (check_capacity(&encInfo) == e_failure)
        {
            printf("%s has less capacity: %u.\n", encInfo.src_image_fname, encInfo.image_capacity );
            close_files_encode(&encInfo);
            return 1;
        }
    
        //Test copy_bmp_header
        if (copy_bmp_header(encInfo.fptr_src_image, encInfo.fptr_stego_image) == e_failure)
        {
            printf("Did not copy\n");
            close_files_encode(&encInfo);
            return 1;
        }
    
        //Test encode_secret_file_size
        if ( encode_secret_file_size(encInfo.size_secret_file, &encInfo) == e_failure)
        {
            printf("Did not encode secret file size.\n");
            close_files_encode(&encInfo);
            return 1;
        }
    
        //Test encode_secret_file_data [includes null too]
        if ( encode_secret_file_data(&encInfo) == e_failure)
        {
            printf("Did not encode secret file data.\n");
            close_files_encode(&encInfo);
            return 1;
        }
    
        //Test copy_remaining_img_data [includes null too]
        if ( copy_remaining_img_data(encInfo.fptr_src_image, encInfo.fptr_stego_image)  == e_failure)
        {
            printf("Did not copy rest of the image data.\n");
            close_files_encode(&encInfo);
            return 1;
        }

        close_files_encode(&encInfo);
    }
    else if (check_operation_type(argv) == e_decode)
    {
        long size_secret_file;
        
        // Test open_files_decode
        if (open_files_decode(&encInfo) == e_failure)
        {
            printf("ERROR: %s function failed\n", "open_files" );
            return 1;
        }
        
        
        //Test decode_secret_file_size
        //printf("stegno is: %s \n", encInfo.stego_image_fname);
        if (decode_secret_file_size(encInfo.fptr_stego_image, &size_secret_file) == e_failure)
        {
            printf("Did not decode file size.\n");
            close_files_decode(&encInfo);
            
            return 1;
        }
        
        
        //Test decode_secret_file_data
        //size_secret_file = 24;
        if (decode_secret_file_data(encInfo.fptr_secret, encInfo.fptr_stego_image, size_secret_file) == e_failure)
        {
            printf("Did not decode file data.\n");
            close_files_decode(&encInfo);
            return 1;
        }
        close_files_decode(&encInfo);
    }
    return 0;
}
예제 #7
0
/**
 * This is the will be the entry point to your text editor.
*/
int main(int argc, char *argv[]) {
  // Checking to see if the editor is being used correctly.
  if (argc != 2) {
    print_usage_error();
    return 1;
  }
  // Setting up a docment based on the file named 'filename'.
  char *filename = get_filename(argc, argv);
  Document *document = Document_create_from_file(filename);

  // Buffer for the command and length of said buffer
  char *command = NULL;
  size_t len = 0;

  // This while loop will keep reading from stdin one line at a time
  // until the user enters 'q' (the quit command).
  int done = 0;
  while (!done) {
    getline(&command, &len, stdin);

    int command_type;

    // remove newline from the command
    char *nl = strchr(command, '\n');
    if (nl)
      *nl = 0;

    int stringlen = strlen(command);

    // if 'q' or 's' is first character only 'q' or 's' is allowed as valid
    // command
    if ((command[0] == 'q' || command[0] == 's') && stringlen != 1) {
      command_type = -1;
    } else {
      command_type = command[0];
    }

    switch (command_type) {
    case 'p':
      handle_display_command(document, command);
      break;
    case 'w':
      handle_write_command(document, command);
      break;
    case 'a':
      handle_append_command(document, command);
      break;
    case 'd':
      handle_delete_command(document, command);
      break;
    case '/':
      handle_search_command(document, command);
      break;
    case 's':
      if (strlen(command) == 1) {
        handle_save_command(document, filename);
      } else {
        invalid_command(command);
      }
      break;
    case 'q':
      done = 1;
      Document_destroy(document);
      break;
    default:
      invalid_command(command);
      break;
    }
  }

  // Need to free the buffer that we created.
  if (command) {
    free(command);
  }
}