コード例 #1
0
/**
 * Verifies that the MAR file matches the current product, channel, and version
 * 
 * @param MARChannelID   The MAR channel name to use, only updates from MARs
 *                       with a matching MAR channel name will succeed.
 *                       If an empty string is passed, no check will be done
 *                       for the channel name in the product information block.
 *                       If a comma separated list of values is passed then
 *                       one value must match.
 * @param appVersion     The application version to use, only MARs with an
 *                       application version >= to appVersion will be applied.
 * @return OK on success
 *         COULD_NOT_READ_PRODUCT_INFO_BLOCK if the product info block 
 *                                           could not be read.
 *         MARCHANNEL_MISMATCH_ERROR         if update-settings.ini's MAR 
 *                                           channel ID doesn't match the MAR
 *                                           file's MAR channel ID. 
 *         VERSION_DOWNGRADE_ERROR           if the application version for
 *                                           this updater is newer than the
 *                                           one in the MAR.
 */
int
ArchiveReader::VerifyProductInformation(const char *MARChannelID, 
                                        const char *appVersion)
{
  if (!mArchive) {
    return ARCHIVE_NOT_OPEN;
  }

  ProductInformationBlock productInfoBlock;
  int rv = mar_read_product_info_block(mArchive, 
                                       &productInfoBlock);
  if (rv != OK) {
    return COULD_NOT_READ_PRODUCT_INFO_BLOCK_ERROR;
  }

  // Only check the MAR channel name if specified, it should be passed in from
  // the update-settings.ini file.
  if (MARChannelID && strlen(MARChannelID)) {
    // Check for at least one match in the comma separated list of values.
    const char *delimiter = " ,\t";
    // Make a copy of the string in case a read only memory buffer 
    // was specified.  strtok modifies the input buffer.
    char channelCopy[512] = { 0 };
    strncpy(channelCopy, MARChannelID, sizeof(channelCopy) - 1);
    char *channel = strtok(channelCopy, delimiter);
    rv = MAR_CHANNEL_MISMATCH_ERROR;
    while(channel) {
      if (!strcmp(channel, productInfoBlock.MARChannelID)) {
        rv = OK;
        break;
      }
      channel = strtok(nullptr, delimiter);
    }
  }

  if (rv == OK) {
    /* Compare both versions to ensure we don't have a downgrade
        -1 if appVersion is older than productInfoBlock.productVersion
        1 if appVersion is newer than productInfoBlock.productVersion
        0 if appVersion is the same as productInfoBlock.productVersion
       This even works with strings like:
        - 12.0a1 being older than 12.0a2
        - 12.0a2 being older than 12.0b1
        - 12.0a1 being older than 12.0
        - 12.0 being older than 12.1a1 */
    int versionCompareResult = 
      mozilla::CompareVersions(appVersion, productInfoBlock.productVersion);
    if (1 == versionCompareResult) {
      rv = VERSION_DOWNGRADE_ERROR;
    }
  }

  free((void *)productInfoBlock.MARChannelID);
  free((void *)productInfoBlock.productVersion);
  return rv;
}
コード例 #2
0
/** 
 * Reads the product info block from the MAR file's additional block section.
 * The caller is responsible for freeing the fields in infoBlock
 * if the return is successful.
 *
 * @param infoBlock Out parameter for where to store the result to
 * @return 0 on success, -1 on failure
*/
int
read_product_info_block(char *path, 
                        struct ProductInformationBlock *infoBlock)
{
  int rv;
  MarFile mar;
  mar.fp = fopen(path, "rb");
  if (!mar.fp) {
    return -1;
  }
  rv = mar_read_product_info_block(&mar, infoBlock);
  fclose(mar.fp);
  return rv;
}
コード例 #3
0
ファイル: mar_read.c プロジェクト: paulmadore/luckyde
/** 
 * Reads the product info block from the MAR file's additional block section.
 * The caller is responsible for freeing the fields in infoBlock
 * if the return is successful.
 *
 * @param infoBlock Out parameter for where to store the result to
 * @return 0 on success, -1 on failure
*/
int
read_product_info_block(char *path, 
                        struct ProductInformationBlock *infoBlock)
{
  int rv;
  MarFile mar;
  mar.fp = fopen(path, "rb");
  if (!mar.fp) {
    fprintf(stderr, "ERROR: could not open file in read_product_info_block()\n");
    perror(path);
    return -1;
  }
  rv = mar_read_product_info_block(&mar, infoBlock);
  fclose(mar.fp);
  return rv;
}