Beispiel #1
0
static struct write_list *
mk_empty_ptable(void)
{
    struct write_list *wr;
    static const short int magic = 0xAA55;

    wr = alloc_wl(72);
    if (!wr)
        return NULL;
    memset(wr->data, 0, 70);
    memcpy(wr->data + 70, &magic, sizeof(magic));
    wr->offset = 440;
    return wr;
}
static struct write_list *
mk_empty_ptable(void)
{
    struct write_list *wr;
    static const unsigned char magic[2] = {0x55, 0xAA};

    wr = alloc_wl(66);
    if (!wr)
        return NULL;
    memset(wr->data, 0, 64);
    memcpy(wr->data + 64, magic, sizeof(magic));
    wr->offset = 446;
    return wr;
}
static struct write_list *
mk_pri_pentry(struct disk_info *dinfo, struct part_info *pinfo, int pnum,
              uint32_t *lba)
{
    struct write_list *item;
    struct pc_partition *pentry;

    if (pnum >= PC_NUM_BOOT_RECORD_PARTS) {
        LOGE("Maximum number of primary partition exceeded.");
        return NULL;
    }

    if (!(item = alloc_wl(sizeof(struct pc_partition)))) {
        LOGE("Unable to allocate memory for partition entry.");
        return NULL;
    }

    {
        /* DO NOT DEREFERENCE */
        struct pc_boot_record *mbr = (void *)PC_MBR_DISK_OFFSET; 
        /* grab the offset in mbr where to write this partition entry. */
        item->offset = (loff_t)((uint32_t)((uint8_t *)(&mbr->ptable[pnum])));
    }

    pentry = (struct pc_partition *) &item->data;

    /* need a standard primary partition entry */
    if (pinfo) {
        /* need this to be 64 bit in case len_kb is large */
        uint64_t len_lba; 

        if (pinfo->len_kb != (uint32_t)-1) {
            /* bump it up to the next LBA boundary just in case */
            len_lba = ((uint64_t)pinfo->len_kb * 1024);
            len_lba += ((uint64_t)dinfo->sect_size - 1);
            len_lba &= ~((uint64_t)dinfo->sect_size - 1);
            len_lba /= (uint64_t)dinfo->sect_size;
        } else {
            /* make it fill the rest of disk */
            len_lba = dinfo->num_lba - *lba;
        }

        cfg_pentry(pentry, ((pinfo->flags & PART_ACTIVE_FLAG) ?
                            PC_PART_ACTIVE : PC_PART_NORMAL),
                   pinfo->type, *lba, (uint32_t)len_lba);

        pinfo->start_lba = *lba;
        *lba += (uint32_t)len_lba;
    } else {
        /* this should be made an extended partition, and should take
         * up the rest of the disk as a primary partition */
        cfg_pentry(pentry, PC_PART_NORMAL, PC_PART_TYPE_EXTENDED,
                   *lba, dinfo->num_lba - *lba);

        /* note that we do not update the *lba because we now have to
         * create a chain of extended partition tables, and first one is at
         * *lba */
    }

    return item;
}
/* This function configures an extended boot record at the beginning of an
 * extended partition. This creates a logical partition and a pointer to
 * the next EBR.
 *
 * ext_lba == The start of the toplevel extended partition (pointed to by the
 * entry in the MBR).
 */
static struct write_list *
mk_ext_pentry(struct disk_info *dinfo, struct part_info *pinfo, uint32_t *lba,
              uint32_t ext_lba, struct part_info *pnext)
{
    struct write_list *item;
    struct pc_boot_record *ebr;
    uint32_t len; /* in lba units */

    if (!(item = alloc_wl(sizeof(struct pc_boot_record)))) {
        LOGE("Unable to allocate memory for EBR.");
        return NULL;
    }

    /* we are going to write the ebr at the current LBA, and then bump the
     * lba counter since that is where the logical data partition will start */
    item->offset = (*lba) * dinfo->sect_size;
    (*lba)++;

    ebr = (struct pc_boot_record *) &item->data;
    memset(ebr, 0, sizeof(struct pc_boot_record));
    ebr->mbr_sig = PC_BIOS_BOOT_SIG;

    if (pinfo->len_kb != (uint32_t)-1)
        len = kb_to_lba(pinfo->len_kb, dinfo->sect_size);
    else {
        if (pnext) {
            LOGE("Only the last partition can be specified to fill the disk "
                 "(name = '%s')", pinfo->name);
            goto fail;
        }
        len = dinfo->num_lba - *lba;
        /* update the pinfo structure to reflect the new size, for
         * bookkeeping */
        pinfo->len_kb =
            (uint32_t)(((uint64_t)len * (uint64_t)dinfo->sect_size) /
                       ((uint64_t)1024));
    }

    cfg_pentry(&ebr->ptable[PC_EBR_LOGICAL_PART], PC_PART_NORMAL,
               pinfo->type, 1, len);

    pinfo->start_lba = *lba;
    *lba += len;

    /* If this is not the last partition, we have to create a link to the
     * next extended partition.
     *
     * Otherwise, there's nothing to do since the "pointer entry" is
     * already zero-filled.
     */
    if (pnext) {
        /* The start lba for next partition is an offset from the beginning
         * of the top-level extended partition */
        uint32_t next_start_lba = *lba - ext_lba;
        uint32_t next_len_lba;
        if (pnext->len_kb != (uint32_t)-1)
            next_len_lba = 1 + kb_to_lba(pnext->len_kb, dinfo->sect_size);
        else
            next_len_lba = dinfo->num_lba - *lba;
        cfg_pentry(&ebr->ptable[PC_EBR_NEXT_PTR_PART], PC_PART_NORMAL,
                   PC_PART_TYPE_EXTENDED, next_start_lba, next_len_lba);
    }

    return item;

fail:
    free_wl(item);
    return NULL;
}
Beispiel #5
0
int process_defexternal()
{
   int                    token;
   struct word_list       *relation;
   DEF_EXT                *cur_def_ex_funcs;

   /*============================*/
   /* Check for defexternal name */
   /*============================*/

   token = gettoken(cur_file);

   IF(token NEQ WORD) THEN
      error_message(ERROR, "Expected a name following defexternal keyword!");
      find_rht_paren();
      return(ERROR);
   END_IF

   cur_obj_name  = TKNWORD;

   IF(VERBOSE IS_ON) THEN
      sprintf(msg_buf,"\n\nProcessing defexternal: %.40s",cur_obj_name);
      send_message(msg_buf,NO);
   END_IF

   /*============================================*/
   /* Check if function has been previously used */
   /*============================================*/

   IF(find_ex_func(ex_funcs_head, cur_obj_name) NEQ NULL) THEN
      sprintf(msg_buf, "External function %.40s defined after being used.\n",
                    cur_obj_name);
      error_message(WARNING, msg_buf);
   END_IF

   /*======================================*/
   /* Get pointer to defexternal structure */
   /*======================================*/
   def_ext_head     = find_create_def_ex_func(def_ext_head, cur_obj_name);
   cur_def_ex_funcs = current_de;

   /*===================================*/
   /* Begin processing defexternal info */
   /*===================================*/

   token = gettoken(cur_file);

   IF(token NEQ LPAREN) THEN
      error_message(ERROR, "Expecting a left paren inside a defexternal");
      return(RESTART);
   END_IF


   /*=================================*/
   /* Check for ART style defexternal */
   /*=================================*/

   IF((token EQ BWORD) OR (token EQ BWORDS)) THEN
      find_rht_paren();                   /* Ignore ART style code */
      find_rht_paren();                   /* Provided for compatibility */
      return(ERROR);                      /* Return error, not restart */
   END_IF

   /*===================================*/
   /* Read and process defexternal info */
   /*===================================*/

   while(token NEQ RPAREN) DO

      /*======================================*/
      /* Find opening paren, and get key word */
      /*======================================*/

      IF(token NEQ LPAREN) THEN
         error_message(ERROR, "Expecting a left paren inside a defexternal");
         return(RESTART);
      END_IF

      token = gettoken(cur_file);
      IF((token EQ WORD) AND
         (strcmp("true-function-name",TKNWORD) EQ 0)) THEN

           /*============================================*
            *  Process true function name                *
            *============================================*/

           token = gettoken(cur_file);
           IF((token NEQ WORD) AND (token NEQ STRING)) THEN
             error_message(ERROR, "Expecting a word or a string for ");
             send_message("true-function-name in defexternal",NO);
           ELSE
             cur_def_ex_funcs->true_name = TKNWORD;
           END_IF
           find_rht_paren();

      ELSE_IF((token EQ WORD) AND (strcmp("asserts",TKNWORD) EQ 0))

          /*===========================================================*
           *  Process the relations asserted by the external function  *
           *===========================================================*/

           token = gettoken(cur_file);
           IF(token == RPAREN) THEN
               error_message(ERROR, "Expecting a word, string, ?NONE ");
               send_message("or ?VARIABLE after asserts in defexternal",NO);
           END_IF

           while (token NEQ RPAREN) DO
              IF(token EQ BWORD) THEN
                 IF((strcmp(TKNWORD,"VARIABLE") NEQ 0) AND
                    (strcmp(TKNWORD,"NONE") NEQ 0)) THEN
           		     error_message(ERROR,
           		        "Unidentified word, expected VARIABLE or NONE after ?");
           		 END_IF

              ELSE_IF((token NEQ WORD) AND (token NEQ STRING))
                 error_message(ERROR, "Expecting a word, string, ?NONE, or ");
                 send_message("?VARIABLE after asserts in defexternal",NO);
                 find_rht_paren();

              ELSE
                 relation = alloc_wl();
                 relation->word = TKNWORD;
                 relation->next_word = cur_def_ex_funcs->assert_list;
                 cur_def_ex_funcs->assert_list = relation;
              END_IF
              token = gettoken(cur_file);
           END_WHILE

     ELSE_IF((token EQ WORD) AND (strcmp("retracts",TKNWORD) EQ 0))

          /*============================================================*
           *  Process the relations retracted by the external function  *
           *============================================================*/

           token = gettoken(cur_file);
           IF(token == RPAREN) THEN
               error_message(ERROR, "Expecting a word, string, ?NONE ");
               send_message("or ?VARIABLE after retracts in defexternal",NO);
           END_IF

           while (token NEQ RPAREN) DO
              IF(token EQ BWORD) THEN
                 IF((strcmp(TKNWORD,"VARIABLE") NEQ 0) AND
                    (strcmp(TKNWORD,"NONE") NEQ 0)) THEN
           		     error_message(ERROR,
           		        "Unidentified word, expected VARIABLE or NONE after ?");
           		 END_IF

              ELSE_IF((token NEQ WORD) AND (token NEQ STRING))
                 error_message(ERROR, "Expecting a word, string, ?NONE, or ");
                 send_message("?VARIABLE after retracts in defexternal",NO);
                 find_rht_paren();

              ELSE
                 relation = alloc_wl();
                 relation->word = TKNWORD;
                 relation->next_word = cur_def_ex_funcs->retract_list;
                 cur_def_ex_funcs->retract_list = relation;
              END_IF
                 token = gettoken(cur_file);
           END_WHILE

      ELSE_IF((token EQ WORD) AND (strcmp("min-number-of-args", TKNWORD) EQ 0))

         /*=================================*/
         /* Process min-number-of-arguments */
         /*=================================*/

         token = gettoken(cur_file);
         IF((token EQ BWORD) AND (strcmp("VARIABLE", TKNWORD) EQ 0)) THEN
            cur_def_ex_funcs->min_arguments = 0;
         ELSE_IF(token NEQ NUMBER)
            error_message(ERROR, 
               "Expecting a number for argument min-number-of-argument in defexternal");
         ELSE
            cur_def_ex_funcs->min_arguments = TKNNUMBER;
         END_IF
         find_rht_paren();

      ELSE_IF((token EQ WORD) AND (strcmp("max-number-of-args", TKNWORD) EQ 0))

         /*=================================*/
         /* Process max-number-of-arguments */
         /*=================================*/

         token = gettoken(cur_file);
         IF((token EQ BWORD) AND (strcmp("VARIABLE", TKNWORD) EQ 0)) THEN
            cur_def_ex_funcs->max_arguments = 10000;
         ELSE_IF(token NEQ NUMBER)
            error_message(ERROR, 
               "Expecting a number for argument max-number-of-arguments definition");
         ELSE
            cur_def_ex_funcs->max_arguments = TKNNUMBER;
         END_IF
         find_rht_paren();

      ELSE_IF((token EQ WORD) AND  (strcmp("return-type",TKNWORD) == 0))

         /*================================*
          * Process return-type            *
          *================================*/

          token = gettoken(cur_file);
          IF(token NEQ WORD) THEN
             error_message(ERROR, "Expecting NUMBER, STRING, WORD, ");
             send_message("MULTI, or NONE for return type",NO);
          ELSE
	         IF(strcmp(TKNWORD,"MULTI") EQ 0) THEN
	            cur_def_ex_funcs->return_word   = YES;
	            cur_def_ex_funcs->return_string = YES;
	            cur_def_ex_funcs->return_number = YES;

	         ELSE_IF((strcmp(TKNWORD,"FLOAT") EQ 0) OR
	                 (strcmp(TKNWORD,"NUMBER") EQ 0) OR
	                 (strcmp(TKNWORD,"INTEGER") EQ 0))
	         		cur_def_ex_funcs->return_number = YES;

	         ELSE_IF((strcmp(TKNWORD,"NONE")) EQ 0)
	            cur_def_ex_funcs->return_word   = NO;
	            cur_def_ex_funcs->return_string = NO;
	            cur_def_ex_funcs->return_number = NO;

	         ELSE_IF(strcmp(TKNWORD,"STRING") EQ 0)
	         		cur_def_ex_funcs->return_string = YES;

	         ELSE_IF((strcmp(TKNWORD,"CHARACTER") EQ 0) OR
	                 (strcmp(TKNWORD,"WORD") EQ 0))
	         		cur_def_ex_funcs->return_word = YES;
	         ELSE
                error_message(ERROR, "Expecting NUMBER, STRING, WORD, ");
                send_message("MULTI, or NONE for return type",NO);
	         END_IF
	      END_IF

          if(token != RPAREN)
             find_rht_paren();

      ELSE_IF((token EQ WORD) AND (strcmp("argument", TKNWORD) EQ 0))

         /*=============================== */
         /* Process an argument definition */
         /*=============================== */
         (void)process_argument_def(cur_def_ex_funcs);

      ELSE

         /*========================*/
         /* Unrecognized key word! */
         /*========================*/

         sprintf(msg_buf,
            "Unrecognized definition: %.40s inside a defexternal", TKNWORD);
         error_message(ERROR, msg_buf);
         find_rht_paren();
      END_IF

      token = gettoken(cur_file);
   END_WHILE
  return(OK);
}