Пример #1
0
bool qbd_compute_pi0(const MatrixXd & R,
		     const MatrixXd & B0,
		     const MatrixXd & A0,
		     RowVectorXd & pi0,
		     const qbd_parms & parms) throw (Exc) {
  if(R.rows()!=R.cols())
    EXC_PRINT("R had to be square");

  if (!check_sizes(A0,R) || !check_sizes(A0,B0)) 
    EXC_PRINT("A0, A1, A2 matrixes have to be square and equal size");

  if ((R.minCoeff()<0)&&parms.verbose)
    cerr<<"QBD_COMPUTE_PI0: Warning: R has negative coeeficients"<<endl;
  SelfAdjointEigenSolver<MatrixXd> eigensolver(R);
  if (eigensolver.info() != Success) {
    if (parms.verbose)
      cerr<<"QBD_COMPUTE_PI0: cannot compute eigenvalues of R"<<endl;
    return false;
  }
  if ((ArrayXd(eigensolver.eigenvalues()).abs().maxCoeff()>1)&&parms.verbose)
    cerr<<"QBD_COMPUTE_PI0: Warning: R has spectral radius greater than 1"<<endl;
  int n = R.rows();
  MatrixXd Id = MatrixXd::Identity(n,n);
  VectorXd u(n);
  u.setOnes();
  MatrixXd M(n,n+1);
  M.block(0,0,n,n)= B0+R*A0-Id;
  M.block(0,n,n,1)= (Id-R).inverse()*u;

  FullPivLU<MatrixXd> lu_decomp(M);
  if(lu_decomp.rank()<n) {
    if (parms.verbose)
      cerr<<"QBD_COMPUTE_PI0: No unique solution"<<endl;
    return false;
  }

  RowVectorXd work(n+1);
  work.setZero();
  work(n)=1;
  MatrixXd W1;
  pseudoInverse<MatrixXd>(M,W1);
  pi0 = work*W1;
  if ((pi0.minCoeff()<0)&&parms.verbose)
    cerr<<"QBD_COMPUTE_PI0: Warning: x0 has negative elements"<<endl;
  return true;
}
Пример #2
0
/*
 * All checks
 */
static void check_tree(rba_buffer_t *b) {
  if (!tree_is_ordered(b) || !tree_is_well_colored(b) ||
      !tree_is_balanced(b) || !check_sizes(b)) {
    exit(1);
  }
}
Пример #3
0
/* Try to insert OBJ in CUR, recurse if needed */
static void
add_object(struct topo_topology *topology, topo_obj_t cur, topo_obj_t obj)
{
  topo_obj_t child, container, *cur_children, *obj_children, next_child;
  int put;

  /* Make sure we haven't gone too deep.  */
  assert(topo_cpuset_isincluded(&obj->cpuset, &cur->cpuset));

  /* Check whether OBJ is included in some child.  */
  container = NULL;
  for (child = cur->first_child; child; child = child->next_sibling) {
    switch (topo_obj_cmp(obj, child)) {
      case TOPO_OBJ_EQUAL:
	assert(topo_cpuset_isequal(&obj->cpuset, &child->cpuset));
	assert(obj->os_index == child->os_index);
	switch(obj->type) {
	  case TOPO_OBJ_NODE:
	    // Do not check these, it may change between calls
	    //check_sizes(obj, child, attr->node.memory_kB);
	    //check_sizes(obj, child, attr->node.huge_page_free);
	    break;
	  case TOPO_OBJ_CACHE:
	    check_sizes(obj, child, attr->cache.memory_kB);
	    break;
	  default:
	    break;
	}
	/* Already present, no need to insert.  */
	return;
      case TOPO_OBJ_INCLUDED:
	if (container) {
	  /* TODO: how to report?  */
	  fprintf(stderr, "object included in several different objects!\n");
	  /* We can't handle that.  */
	  return;
	}
	/* This child contains OBJ.  */
	container = child;
	break;
      case TOPO_OBJ_INTERSECTS:
	/* TODO: how to report?  */
	fprintf(stderr, "object intersection without inclusion!\n");
	/* We can't handle that.  */
	return;
      case TOPO_OBJ_CONTAINS:
	/* OBJ will be above CHILD.  */
	break;
      case TOPO_OBJ_DIFFERENT:
	/* OBJ will be alongside CHILD.  */
	break;
    }
  }

  if (container) {
    /* OBJ is strictly contained is some child of CUR, go deeper.  */
    add_object(topology, container, obj);
    return;
  }

  /*
   * Children of CUR are either completely different from or contained into
   * OBJ. Take those that are contained (keeping sorting order), and sort OBJ
   * along those that are different.
   */

  /* OBJ is not put yet.  */
  put = 0;

  /* These will always point to the pointer to their next last child. */
  cur_children = &cur->first_child;
  obj_children = &obj->first_child;

  /* Construct CUR's and OBJ's children list.  */

  /* Iteration with prefetching to be completely safe against CHILD removal.  */
  for (child = cur->first_child, child ? next_child = child->next_sibling : 0;
       child;
       child = next_child, child ? next_child = child->next_sibling : 0) {

    switch (topo_obj_cmp(obj, child)) {

      case TOPO_OBJ_DIFFERENT:
	/* Leave CHILD in CUR.  */
	if (!put && topo_cpuset_compar_first(&obj->cpuset, &child->cpuset) < 0) {
	  /* Sort children by cpuset: put OBJ before CHILD in CUR's children.  */
	  *cur_children = obj;
	  cur_children = &obj->next_sibling;
	  put = 1;
	}
	/* Now put CHILD in CUR's children.  */
	*cur_children = child;
	cur_children = &child->next_sibling;
	break;

      case TOPO_OBJ_CONTAINS:
	/* OBJ contains CHILD, put the latter in the former.  */
	*obj_children = child;
	obj_children = &child->next_sibling;
	break;

      case TOPO_OBJ_EQUAL:
      case TOPO_OBJ_INCLUDED:
      case TOPO_OBJ_INTERSECTS:
	/* Shouldn't ever happen as we have handled them above.  */
	abort();
    }
  }

  /* Put OBJ last in CUR's children if not already done so.  */
  if (!put) {
    *cur_children = obj;
    cur_children = &obj->next_sibling;
  }

  /* Close children lists.  */
  *obj_children = NULL;
  *cur_children = NULL;
}
Пример #4
0
void BootloaderInstallAms::installStage2(void)
{    
    qDebug() << "[BootloaderInstallAms] installStage2";
    
    unsigned char* buf;
    unsigned char* of_packed;
    int of_packedsize;
    unsigned char* rb_packed;
    int rb_packedsize;
    off_t len;
    struct md5sums sum;
    char md5sum[33]; /* 32 hex digits, plus terminating zero */
    int n;
    int firmware_size;
    int bootloader_size;
    int patchable;
    int totalsize;
    char errstr[200];
      
    sum.md5 = md5sum;  
      
    m_tempfile.open();
    QString bootfile = m_tempfile.fileName();
    m_tempfile.close();

    /* Load original firmware file */                
    buf = load_of_file(m_offile.toLocal8Bit().data(), &len,&sum,&firmware_size,
                        &of_packed,&of_packedsize,errstr,sizeof(errstr));
    if (buf == NULL) 
    {
        qDebug() << "[BootloaderInstallAms] could not load OF: " << m_offile;
        emit logItem(errstr, LOGERROR);
        emit logItem(tr("Could not load %1").arg(m_offile), LOGERROR);
        emit done(true);
        return;
    }

    /* Load bootloader file */
    rb_packed = load_rockbox_file(bootfile.toLocal8Bit().data(), sum.model,
                                  &bootloader_size,&rb_packedsize,
                                    errstr,sizeof(errstr));
    if (rb_packed == NULL) 
    {   
        qDebug() << "[BootloaderInstallAms] could not load bootloader: " << bootfile;
        emit logItem(errstr, LOGERROR);
        emit logItem(tr("Could not load %1").arg(bootfile), LOGERROR);
        free(buf);
        free(of_packed);
        emit done(true);
        return;
    }
    
    /* check total size */
    patchable = check_sizes(sum.model, rb_packedsize, bootloader_size,
            of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr));

    if (!patchable)
    {
        qDebug() << "[BootloaderInstallAms] No room to insert bootloader";
        emit logItem(errstr, LOGERROR);
        emit logItem(tr("No room to insert bootloader, try another firmware version"),
                     LOGERROR);
        free(buf);
        free(of_packed);
        free(rb_packed);
        emit done(true);
        return;
    }
    
    /* patch the firmware */
    emit logItem(tr("Patching Firmware..."), LOGINFO);
    
    patch_firmware(sum.model,firmware_revision(sum.model),firmware_size,buf,
                   len,of_packed,of_packedsize,rb_packed,rb_packedsize);

    /* write out file */
    QFile out(m_blfile);
    
    if(!out.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        qDebug() << "[BootloaderInstallAms] Could not open" <<  m_blfile << "for writing";
        emit logItem(tr("Could not open %1 for writing").arg(m_blfile),LOGERROR);
        free(buf);
        free(of_packed);
        free(rb_packed);
        emit done(true);
        return;
    }
    
    n = out.write((char*)buf, len);

    if (n != len)
    {
        qDebug() << "[BootloaderInstallAms] Could not write firmware file";
        emit logItem(tr("Could not write firmware file"),LOGERROR);
        free(buf);
        free(of_packed);
        free(rb_packed);
        emit done(true);
        return;
    }

    out.close();
    
    free(buf);
    free(of_packed);
    free(rb_packed);
    
    //end of install
    qDebug() << "[BootloaderInstallAms] install successfull";
    emit logItem(tr("Success: modified firmware file created"), LOGINFO);
    logInstall(LogAdd);
    emit done(false);
    return;
}
int
Ndb_move_data::check_tables()
{
  int ret = 0;
  const Opts& opts = m_opts;
  do
  {
    int attrcount1 = m_source->getNoOfColumns();
    int attrcount2 = m_target->getNoOfColumns();
    m_sourceattr = new Attr [attrcount1];
    m_targetattr = new Attr [attrcount2];

    // set type info, remap columns, check missing

    for (int i1 = 0; i1 < attrcount1; i1++)
    {
      Attr& attr1 = m_sourceattr[i1];
      attr1.id = i1;
      const NdbDictionary::Column* c1 = m_source->getColumn(i1);
      require(c1 != 0);
      set_type(attr1, c1);
      const NdbDictionary::Column* c2 = m_target->getColumn(attr1.name);
      if (c2 == 0)
      {
        CHK2(opts.flags & Opts::MD_EXCLUDE_MISSING_COLUMNS,
             (Error::NoExcludeMissingFlag,
              "cannot convert source to target"
              ": source column #%d '%s' not found in target"
              " and exclude-missing-columns has not been specified",
              1+i1, attr1.name));
      }
      else
      {
        int i2 = c2->getColumnNo();
        require(i2 >= 0 && i2 < attrcount2);
        Attr& attr2 = m_targetattr[i2];
        attr1.map_id = i2;
        require(attr2.map_id == -1);
        attr2.map_id = i1;
      }
    }
    CHK1(ret == 0);

    for (int i2 = 0; i2 < attrcount2; i2++)
    {
      Attr& attr2 = m_targetattr[i2];
      attr2.id = i2;
      const NdbDictionary::Column* c2 = m_target->getColumn(i2);
      require(c2 != 0);
      set_type(attr2, c2);
      const NdbDictionary::Column* c1 = m_source->getColumn(attr2.name);
      if (c1 == 0)
      {
        CHK2(opts.flags & Opts::MD_EXCLUDE_MISSING_COLUMNS,
             (Error::NoExcludeMissingFlag,
              "cannot convert source to target"
              ": target column #%d '%s' not found in source"
              " and exclude-missing-columns has not been specified",
              1+i2, attr2.name));
      }
      else
      {
        int i1 = c1->getColumnNo();
        require(i2 >= 0 && i2 < attrcount2);
        Attr& attr1 = m_sourceattr[i1];
        require(attr1.map_id == i2);
        require(attr2.map_id == i1);
      }
    }
    CHK1(ret == 0);

    // check conversion of non-excluded columns

    for (int i1 = 0; i1 < attrcount1; i1++)
    {
      Attr& attr1 = m_sourceattr[i1];
      int i2 = attr1.map_id;
      if (i2 == -1) // excluded
        continue;
      Attr& attr2 = m_targetattr[i2];

      {
        /* Exclude internal implementation details when comparing */
        NdbDictionary::Column a1ColCopy(*attr1.column);
        NdbDictionary::Column a2ColCopy(*attr2.column);
        
        /* [Non] Dynamic internal storage is irrelevant */ 
        a1ColCopy.setDynamic(false);
        a2ColCopy.setDynamic(false);
        
        if ((attr1.equal = attr2.equal = a1ColCopy.equal(a2ColCopy)))
        {
          continue;
        }
      }

      if (attr1.type == Attr::TypeArray &&
          attr2.type == Attr::TypeBlob)
      {
        CHK1(check_nopk(attr1, attr2) == 0);
        CHK1(check_promotion(attr1, attr2) == 0);
        continue;
      }

      if (attr1.type == Attr::TypeBlob &&
          attr2.type == Attr::TypeArray)
      {
        CHK1(check_nopk(attr1, attr2) == 0);
        CHK1(check_demotion(attr1, attr2) == 0);
        continue;
      }

      if (attr1.type == Attr::TypeArray &&
          attr2.type == Attr::TypeArray)
      {
        CHK1(check_sizes(attr1, attr2) == 0);
        continue;
      }

      CHK1(check_unsupported(attr1, attr2) == 0);
    }
    CHK1(ret == 0);
  }
  while (0);
  return ret;
}
Пример #6
0
static void test_layout(void)
{
    HWND hRebar;
    REBARBANDINFOA rbi;
    HIMAGELIST himl;
    REBARINFO ri;

    rbsize_results_init();

    hRebar = create_rebar_control();
    check_sizes();
    rbi.cbSize = REBARBANDINFOA_V6_SIZE;
    rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
    rbi.cx = 200;
    rbi.cxMinChild = 100;
    rbi.cyMinChild = 30;
    rbi.hwndChild = NULL;
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    rbi.fMask |= RBBIM_STYLE;
    rbi.fStyle = RBBS_CHILDEDGE;
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    rbi.fStyle = 0;
    rbi.cx = 200;
    rbi.cxMinChild = 30;
    rbi.cyMinChild = 30;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    rbi.fStyle = RBBS_CHILDEDGE;
    rbi.cx = 68;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    SetWindowLongA(hRebar, GWL_STYLE, GetWindowLongA(hRebar, GWL_STYLE) | RBS_BANDBORDERS);
    check_sizes();      /* a style change won't start a relayout */
    rbi.fMask = RBBIM_SIZE;
    rbi.cx = 66;
    SendMessageA(hRebar, RB_SETBANDINFOA, 3, (LPARAM)&rbi);
    check_sizes();      /* here it will be relayouted */

    /* this will force a new row */
    rbi.fMask = RBBIM_SIZE | RBBIM_CHILDSIZE | RBBIM_CHILD;
    rbi.cx = 200;
    rbi.cxMinChild = 400;
    rbi.cyMinChild = 30;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, 1, (LPARAM)&rbi);
    check_sizes();

    rbi.fMask = RBBIM_STYLE;
    rbi.fStyle = RBBS_HIDDEN;
    SendMessageA(hRebar, RB_SETBANDINFOA, 2, (LPARAM)&rbi);
    check_sizes();

    SendMessageA(hRebar, RB_DELETEBAND, 2, 0);
    check_sizes();
    SendMessageA(hRebar, RB_DELETEBAND, 0, 0);
    check_sizes();
    SendMessageA(hRebar, RB_DELETEBAND, 1, 0);
    check_sizes();

    DestroyWindow(hRebar);

    hRebar = create_rebar_control();
    add_band_w(hRebar, "ABC",     70,  40, 100);
    add_band_w(hRebar, NULL,      40,  70, 100);
    add_band_w(hRebar, NULL,     170, 240, 100);
    add_band_w(hRebar, "MMMMMMM", 60,  60, 100);
    add_band_w(hRebar, NULL,     200, 200, 100);
    check_sizes();
    SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
    check_sizes();
    SendMessageA(hRebar, RB_MAXIMIZEBAND, 1, TRUE);
    check_sizes();
    SendMessageA(hRebar, RB_MAXIMIZEBAND, 2, FALSE);
    check_sizes();
    SendMessageA(hRebar, RB_MINIMIZEBAND, 2, 0);
    check_sizes();
    SendMessageA(hRebar, RB_MINIMIZEBAND, 0, 0);
    check_sizes();

    /* an image will increase the band height */
    himl = ImageList_LoadImageA(GetModuleHandleA("comctl32"), MAKEINTRESOURCEA(121), 24, 2,
            CLR_NONE, IMAGE_BITMAP, LR_DEFAULTCOLOR);
    ri.cbSize = sizeof(ri);
    ri.fMask = RBIM_IMAGELIST;
    ri.himl = himl;
    ok(SendMessageA(hRebar, RB_SETBARINFO, 0, (LPARAM)&ri), "RB_SETBARINFO failed\n");
    rbi.fMask = RBBIM_IMAGE;
    rbi.iImage = 1;
    SendMessageA(hRebar, RB_SETBANDINFOA, 1, (LPARAM)&rbi);
    check_sizes();

    /* after removing it everything is back to normal*/
    rbi.iImage = -1;
    SendMessageA(hRebar, RB_SETBANDINFOA, 1, (LPARAM)&rbi);
    check_sizes();

    /* Only -1 means that the image is not present. Other invalid values increase the height */
    rbi.iImage = -2;
    SendMessageA(hRebar, RB_SETBANDINFOA, 1, (LPARAM)&rbi);
    check_sizes();

    DestroyWindow(hRebar);

    /* VARHEIGHT resizing test on a horizontal rebar */
    hRebar = create_rebar_control();
    SetWindowLongA(hRebar, GWL_STYLE, GetWindowLongA(hRebar, GWL_STYLE) | RBS_AUTOSIZE);
    check_sizes();
    rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
    rbi.fStyle = RBBS_VARIABLEHEIGHT;
    rbi.cxMinChild = 50;
    rbi.cyMinChild = 10;
    rbi.cyIntegral = 11;
    rbi.cyChild = 70;
    rbi.cyMaxChild = 200;
    rbi.cx = 90;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);

    rbi.cyChild = 50;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);

    rbi.cyMinChild = 40;
    rbi.cyChild = 50;
    rbi.cyIntegral = 5;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    DestroyWindow(hRebar);

    /* VARHEIGHT resizing on a vertical rebar */
    hRebar = create_rebar_control();
    SetWindowLongA(hRebar, GWL_STYLE, GetWindowLongA(hRebar, GWL_STYLE) | CCS_VERT | RBS_AUTOSIZE);
    check_sizes();
    rbi.fMask = RBBIM_CHILD | RBBIM_CHILDSIZE | RBBIM_SIZE | RBBIM_STYLE;
    rbi.fStyle = RBBS_VARIABLEHEIGHT;
    rbi.cxMinChild = 50;
    rbi.cyMinChild = 10;
    rbi.cyIntegral = 11;
    rbi.cyChild = 70;
    rbi.cyMaxChild = 90;
    rbi.cx = 90;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    rbi.cyChild = 50;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    rbi.cyMinChild = 40;
    rbi.cyChild = 50;
    rbi.cyIntegral = 5;
    rbi.hwndChild = build_toolbar(0, hRebar);
    SendMessageA(hRebar, RB_INSERTBANDA, -1, (LPARAM)&rbi);
    check_sizes();

    rbsize_results_free();
    DestroyWindow(hRebar);
    ImageList_Destroy(himl);
}
Пример #7
0
/* standalone executable */
int main(int argc, char* argv[])
{
    char *infile, *bootfile, *outfile;
    int fdout;
    off_t len;
    uint32_t n;
    unsigned char* buf;
    int firmware_size;
    int bootloader_size;
    unsigned char* of_packed;
    int of_packedsize;
    unsigned char* rb_packed;
    int rb_packedsize;
    int patchable;
    int totalsize;
    int model;
    char errstr[200];
    struct md5sums sum;
    char md5sum[33]; /* 32 digits + \0 */

    sum.md5 = md5sum;

/* VERSION comes frome the Makefile */
    fprintf(stderr,
"mkamsboot Version " VERSION "\n"
"This is free software; see the source for copying conditions.  There is NO\n"
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n"
"\n");

    if(argc != 4) {
        printf("Usage: mkamsboot <firmware file> <boot file> <output file>\n");
        return 1;
    }

    infile = argv[1];
    bootfile = argv[2];
    outfile = argv[3];

    /* Load bootloader file */
    rb_packed = load_rockbox_file(bootfile, &model, &bootloader_size,
            &rb_packedsize, errstr, sizeof(errstr));
    if (rb_packed == NULL) {
        fprintf(stderr, "%s", errstr);
        fprintf(stderr, "[ERR]  Could not load %s\n", bootfile);
        return 1;
    }

    /* Load original firmware file */
    buf = load_of_file(infile, model, &len, &sum,
            &firmware_size, &of_packed, &of_packedsize, errstr, sizeof(errstr));

    if (buf == NULL) {
        free(rb_packed);
        fprintf(stderr, "%s", errstr);
        fprintf(stderr, "[ERR]  Could not load %s\n", infile);
        return 1;
    }

    fprintf(stderr, "[INFO] Original firmware MD5 checksum match\n");
    fprintf(stderr, "[INFO] Model: Sansa %s v%d - Firmware version: %s\n",
            model_names[sum.model], hw_revisions[sum.model], sum.version);


    printf("[INFO] Firmware patching has begun !\n\n");

    fprintf(stderr, "[INFO] Original firmware size:   %d bytes\n",
            firmware_size);
    fprintf(stderr, "[INFO] Packed OF size:           %d bytes\n",
            of_packedsize);
    fprintf(stderr, "[INFO] Bootloader size:          %d bytes\n",
            (int)bootloader_size);
    fprintf(stderr, "[INFO] Packed bootloader size:   %d bytes\n",
            rb_packedsize);
    fprintf(stderr, "[INFO] Dual-boot function size:  %d bytes\n",
            bootloader_sizes[sum.model]);
    fprintf(stderr, "[INFO] UCL unpack function size: %u bytes\n",
            (unsigned int)sizeof(nrv2e_d8));

    patchable = check_sizes(sum.model, rb_packedsize, bootloader_size,
        of_packedsize, firmware_size, &totalsize, errstr, sizeof(errstr));

    fprintf(stderr, "[INFO] Total size of new image:  %d bytes\n", totalsize);

    if (!patchable) {
        fprintf(stderr, "%s", errstr);
        free(buf);
        free(of_packed);
        free(rb_packed);
        return 1;
    }

    patch_firmware(sum.model, fw_revisions[sum.model], firmware_size, buf, len,
            of_packed, of_packedsize, rb_packed, rb_packedsize);

    /* Write the new firmware */
    fdout = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0666);

    if (fdout < 0) {
        fprintf(stderr, "[ERR]  Could not open %s for writing\n", outfile);
        free(buf);
        free(of_packed);
        free(rb_packed);
        return 1;
    }

    n = write(fdout, buf, len);

    if (n != (unsigned)len) {
        fprintf(stderr, "[ERR]  Could not write firmware file\n");
        free(buf);
        free(of_packed);
        free(rb_packed);
        return 1;
    }

    close(fdout);
    free(buf);
    free(of_packed);
    free(rb_packed);
    fprintf(stderr, "\n[INFO] Patching succeeded!\n");

    return 0;
}