Magellan Linux

Diff of /trunk/grubby/grubby.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 2977 by niro, Thu Jun 30 10:24:27 2016 UTC revision 2992 by niro, Thu Jun 30 10:35:14 2016 UTC
# Line 222  struct configFileInfo grubConfigType = { Line 222  struct configFileInfo grubConfigType = {
222      .mbHyperFirst = 1,      .mbHyperFirst = 1,
223      .mbInitRdIsModule = 1,      .mbInitRdIsModule = 1,
224      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
225        .titlePosition = 1,
226  };  };
227    
228  struct keywordTypes grub2Keywords[] = {  struct keywordTypes grub2Keywords[] = {
# Line 428  char *grub2ExtractTitle(struct singleLin Line 429  char *grub2ExtractTitle(struct singleLin
429    
430      /* bail out if line does not start with menuentry */      /* bail out if line does not start with menuentry */
431      if (strcmp(line->elements[0].item, "menuentry"))      if (strcmp(line->elements[0].item, "menuentry"))
432        return NULL;   return NULL;
433    
434      i = 1;      i = 1;
435      current = line->elements[i].item;      current = line->elements[i].item;
# Line 437  char *grub2ExtractTitle(struct singleLin Line 438  char *grub2ExtractTitle(struct singleLin
438      /* if second word is quoted, strip the quotes and return single word */      /* if second word is quoted, strip the quotes and return single word */
439      if (isquote(*current) && isquote(current[current_len - 1])) {      if (isquote(*current) && isquote(current[current_len - 1])) {
440   char *tmp;   char *tmp;
441    
442   tmp = strdup(current);   tmp = strdup(current+1);
443   *(tmp + current_len - 1) = '\0';   if (!tmp)
444   return ++tmp;      return NULL;
445     tmp[strlen(tmp)-1] = '\0';
446     return tmp;
447      }      }
448    
449      /* if no quotes, return second word verbatim */      /* if no quotes, return second word verbatim */
# Line 451  char *grub2ExtractTitle(struct singleLin Line 454  char *grub2ExtractTitle(struct singleLin
454       * whose last character is also quote (assuming it's the closing one) */       * whose last character is also quote (assuming it's the closing one) */
455      int resultMaxSize;      int resultMaxSize;
456      char * result;      char * result;
457            /* need to ensure that ' does not match " as we search */
458        char quote_char = *current;
459    
460      resultMaxSize = sizeOfSingleLine(line);      resultMaxSize = sizeOfSingleLine(line);
461      result = malloc(resultMaxSize);      result = malloc(resultMaxSize);
462      snprintf(result, resultMaxSize, "%s", ++current);      snprintf(result, resultMaxSize, "%s", ++current);
463        
464      i++;      i++;
465      for (; i < line->numElements; ++i) {      for (; i < line->numElements; ++i) {
466   current = line->elements[i].item;   current = line->elements[i].item;
# Line 464  char *grub2ExtractTitle(struct singleLin Line 469  char *grub2ExtractTitle(struct singleLin
469   current_indent_len = strlen(current_indent);   current_indent_len = strlen(current_indent);
470    
471   strncat(result, current_indent, current_indent_len);   strncat(result, current_indent, current_indent_len);
472   if (!isquote(current[current_len-1])) {   if (current[current_len-1] != quote_char) {
473      strncat(result, current, current_len);      strncat(result, current, current_len);
474   } else {   } else {
475      strncat(result, current, current_len - 1);      strncat(result, current, current_len - 1);
# Line 594  struct configFileInfo eliloConfigType = Line 599  struct configFileInfo eliloConfigType =
599      .needsBootPrefix = 1,      .needsBootPrefix = 1,
600      .argsInQuotes = 1,      .argsInQuotes = 1,
601      .mbConcatArgs = 1,      .mbConcatArgs = 1,
602        .titlePosition = 1,
603  };  };
604    
605  struct configFileInfo liloConfigType = {  struct configFileInfo liloConfigType = {
# Line 602  struct configFileInfo liloConfigType = { Line 608  struct configFileInfo liloConfigType = {
608      .entryStart = LT_KERNEL,      .entryStart = LT_KERNEL,
609      .argsInQuotes = 1,      .argsInQuotes = 1,
610      .maxTitleLength = 15,      .maxTitleLength = 15,
611        .titlePosition = 1,
612  };  };
613    
614  struct configFileInfo yabootConfigType = {  struct configFileInfo yabootConfigType = {
# Line 612  struct configFileInfo yabootConfigType = Line 619  struct configFileInfo yabootConfigType =
619      .argsInQuotes = 1,      .argsInQuotes = 1,
620      .maxTitleLength = 15,      .maxTitleLength = 15,
621      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
622        .titlePosition = 1,
623  };  };
624    
625  struct configFileInfo siloConfigType = {  struct configFileInfo siloConfigType = {
# Line 621  struct configFileInfo siloConfigType = { Line 629  struct configFileInfo siloConfigType = {
629      .needsBootPrefix = 1,      .needsBootPrefix = 1,
630      .argsInQuotes = 1,      .argsInQuotes = 1,
631      .maxTitleLength = 15,      .maxTitleLength = 15,
632        .titlePosition = 1,
633  };  };
634    
635  struct configFileInfo ziplConfigType = {  struct configFileInfo ziplConfigType = {
# Line 640  struct configFileInfo extlinuxConfigType Line 649  struct configFileInfo extlinuxConfigType
649      .maxTitleLength = 255,      .maxTitleLength = 255,
650      .mbAllowExtraInitRds = 1,      .mbAllowExtraInitRds = 1,
651      .defaultIsUnquoted = 1,      .defaultIsUnquoted = 1,
652        .titlePosition = 1,
653  };  };
654    
655  struct grubConfig {  struct grubConfig {
# Line 828  static int isEntryStart(struct singleLin Line 838  static int isEntryStart(struct singleLin
838  }  }
839    
840  /* extract the title from within brackets (for zipl) */  /* extract the title from within brackets (for zipl) */
841  static char * extractTitle(struct singleLine * line) {  static char * extractTitle(struct grubConfig *cfg, struct singleLine * line) {
842      /* bracketed title... let's extract it */      /* bracketed title... let's extract it */
843      char * title = NULL;      char * title = NULL;
844      if (line->type == LT_TITLE) {      if (line->type == LT_TITLE) {
845   title = strdup(line->elements[0].item + 1);   char *tmp = line->elements[cfg->cfi->titlePosition].item;
846   *(title + strlen(title) - 1) = '\0';   if (cfg->cfi->titleBracketed) {
847        tmp++;
848        title = strdup(tmp);
849        *(title + strlen(title) - 1) = '\0';
850     } else {
851        title = strdup(tmp);
852     }
853      } else if (line->type == LT_MENUENTRY)      } else if (line->type == LT_MENUENTRY)
854   title = strdup(line->elements[1].item);   title = strdup(line->elements[1].item);
855      else      else
# Line 917  static int lineWrite(FILE * out, struct Line 933  static int lineWrite(FILE * out, struct
933   /* Need to handle this, because we strip the quotes from   /* Need to handle this, because we strip the quotes from
934   * menuentry when read it. */   * menuentry when read it. */
935   if (line->type == LT_MENUENTRY && i == 1) {   if (line->type == LT_MENUENTRY && i == 1) {
936      if(!isquote(*line->elements[i].item))      if(!isquote(*line->elements[i].item)) {
937   fprintf(out, "\'%s\'", line->elements[i].item);   int substring = 0;
938      else   /* If the line contains nested quotes, we did not strip
939     * the "interna" quotes and we must use the right quotes
940     * again when writing the updated file. */
941     for (int j = i; j < line->numElements; j++) {
942        if (strchr(line->elements[i].item, '\'') != NULL) {
943           substring = 1;
944           fprintf(out, "\"%s\"", line->elements[i].item);
945           break;
946        }
947     }
948     if (!substring)
949        fprintf(out, "\'%s\'", line->elements[i].item);
950        } else {
951   fprintf(out, "%s", line->elements[i].item);   fprintf(out, "%s", line->elements[i].item);
952        }
953      fprintf(out, "%s", line->elements[i].indent);      fprintf(out, "%s", line->elements[i].indent);
954    
955      continue;      continue;
# Line 1256  static struct grubConfig * readConfig(co Line 1285  static struct grubConfig * readConfig(co
1285      len = 0;      len = 0;
1286      char *extras;      char *extras;
1287      char *title;      char *title;
1288        /* initially unseen value */
1289        char quote_char = '\0';
1290    
1291      for (int i = 1; i < line->numElements; i++) {      for (int i = 1; i < line->numElements; i++) {
1292   len += strlen(line->elements[i].item);   len += strlen(line->elements[i].item);
# Line 1272  static struct grubConfig * readConfig(co Line 1303  static struct grubConfig * readConfig(co
1303      for (int i = 0; i < line->numElements; i++) {      for (int i = 0; i < line->numElements; i++) {
1304   if (!strcmp(line->elements[i].item, "menuentry"))   if (!strcmp(line->elements[i].item, "menuentry"))
1305      continue;      continue;
1306   if (isquote(*line->elements[i].item))   if (isquote(*line->elements[i].item) && quote_char == '\0') {
1307        /* ensure we properly pair off quotes */
1308        quote_char = *line->elements[i].item;
1309      title = line->elements[i].item + 1;      title = line->elements[i].item + 1;
1310   else   } else {
1311      title = line->elements[i].item;      title = line->elements[i].item;
1312     }
1313    
1314   len = strlen(title);   len = strlen(title);
1315          if (isquote(title[len-1])) {          if (title[len-1] == quote_char) {
1316      strncat(buf, title,len-1);      strncat(buf, title,len-1);
1317      break;      break;
1318   } else {   } else {
# Line 1289  static struct grubConfig * readConfig(co Line 1323  static struct grubConfig * readConfig(co
1323    
1324      /* get extras */      /* get extras */
1325      int count = 0;      int count = 0;
1326        quote_char = '\0';
1327      for (int i = 0; i < line->numElements; i++) {      for (int i = 0; i < line->numElements; i++) {
1328   if (count >= 2) {   if (count >= 2) {
1329      strcat(extras, line->elements[i].item);      strcat(extras, line->elements[i].item);
# Line 1299  static struct grubConfig * readConfig(co Line 1334  static struct grubConfig * readConfig(co
1334      continue;      continue;
1335    
1336   /* count ' or ", there should be two in menuentry line. */   /* count ' or ", there should be two in menuentry line. */
1337   if (isquote(*line->elements[i].item))   if (isquote(*line->elements[i].item) && quote_char == '\0') {
1338        /* ensure we properly pair off quotes */
1339                quote_char = *line->elements[i].item;
1340      count++;      count++;
1341     }
1342    
1343   len = strlen(line->elements[i].item);   len = strlen(line->elements[i].item);
1344    
1345   if (isquote(line->elements[i].item[len -1]))   if (line->elements[i].item[len -1] == quote_char)
1346      count++;      count++;
1347    
1348   /* ok, we get the final ' or ", others are extras. */   /* ok, we get the final ' or ", others are extras. */
# Line 1441  static struct grubConfig * readConfig(co Line 1479  static struct grubConfig * readConfig(co
1479                                  line->elements[1].item)) break;                                  line->elements[1].item)) break;
1480                  } else if (line) {                  } else if (line) {
1481                      if (!strcmp(defaultLine->elements[1].item,                      if (!strcmp(defaultLine->elements[1].item,
1482                                  extractTitle(line))) break;                                  extractTitle(cfg, line))) break;
1483                  }                  }
1484   i++;   i++;
1485   entry = NULL;   entry = NULL;
# Line 1492  static void writeDefault(FILE * out, cha Line 1530  static void writeDefault(FILE * out, cha
1530      if (!line)      if (!line)
1531   line = getLineByType(LT_TITLE, entry->lines);   line = getLineByType(LT_TITLE, entry->lines);
1532      if (line) {      if (line) {
1533   title = extractTitle(line);   title = extractTitle(cfg, line);
1534   if (title)   if (title)
1535      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);      cfg->cfi->setEnv(cfg->cfi, "saved_entry", title);
1536      }      }
# Line 1530  static void writeDefault(FILE * out, cha Line 1568  static void writeDefault(FILE * out, cha
1568              else if (line && (line->numElements == 1) &&              else if (line && (line->numElements == 1) &&
1569                       cfg->cfi->titleBracketed) {                       cfg->cfi->titleBracketed) {
1570   fprintf(out, "%sdefault%s%s\n", indent, separator,   fprintf(out, "%sdefault%s%s\n", indent, separator,
1571                          extractTitle(line));                          extractTitle(cfg, line));
1572              }              }
1573   }   }
1574      }      }
# Line 3332  int addMBInitrd(struct grubConfig * cfg, Line 3370  int addMBInitrd(struct grubConfig * cfg,
3370      if (!line)      if (!line)
3371   continue;   continue;
3372    
3373      linetitle = extractTitle(line);      linetitle = extractTitle(cfg, line);
3374      if (!linetitle)      if (!linetitle)
3375   continue;   continue;
3376      if (strcmp(title, linetitle)) {      if (strcmp(title, linetitle)) {
# Line 3386  int updateInitrd(struct grubConfig * cfg Line 3424  int updateInitrd(struct grubConfig * cfg
3424      if (!line)      if (!line)
3425   continue;   continue;
3426    
3427      linetitle = extractTitle(line);      linetitle = extractTitle(cfg, line);
3428      if (!linetitle)      if (!linetitle)
3429   continue;   continue;
3430      if (strcmp(title, linetitle)) {      if (strcmp(title, linetitle)) {
# Line 4176  int addNewKernel(struct grubConfig * con Line 4214  int addNewKernel(struct grubConfig * con
4214      return 0;      return 0;
4215  }  }
4216    
 static void traceback(int signum)  
 {  
     void *array[40];  
     size_t size;  
   
     signal(SIGSEGV, SIG_DFL);  
     memset(array, '\0', sizeof (array));  
     size = backtrace(array, 40);  
   
     fprintf(stderr, "grubby received SIGSEGV!  Backtrace (%ld):\n",  
             (unsigned long)size);  
     backtrace_symbols_fd(array, size, STDERR_FILENO);  
     exit(1);  
 }  
   
4217  int main(int argc, const char ** argv) {  int main(int argc, const char ** argv) {
4218      poptContext optCon;      poptContext optCon;
4219      const char * grubConfig = NULL;      const char * grubConfig = NULL;
# Line 4333  int main(int argc, const char ** argv) { Line 4356  int main(int argc, const char ** argv) {
4356    
4357      useextlinuxmenu=0;      useextlinuxmenu=0;
4358    
     signal(SIGSEGV, traceback);  
   
4359      int i = 0;      int i = 0;
4360      for (int j = 1; j < argc; j++)      for (int j = 1; j < argc; j++)
4361   i += strlen(argv[j]) + 1;   i += strlen(argv[j]) + 1;
# Line 4412  int main(int argc, const char ** argv) { Line 4433  int main(int argc, const char ** argv) {
4433      }      }
4434    
4435      if (!cfi) {      if (!cfi) {
4436          if (grub2FindConfig(&grub2ConfigType))          if (grub2FindConfig(&grub2ConfigType)) {
4437      cfi = &grub2ConfigType;      cfi = &grub2ConfigType;
4438   else      if (envPath)
4439     cfi->envFile = envPath;
4440            } else
4441        #ifdef __ia64__        #ifdef __ia64__
4442      cfi = &eliloConfigType;      cfi = &eliloConfigType;
4443        #elif __powerpc__        #elif __powerpc__
# Line 4628  int main(int argc, const char ** argv) { Line 4651  int main(int argc, const char ** argv) {
4651   struct singleLine * line;   struct singleLine * line;
4652   struct singleEntry * entry;   struct singleEntry * entry;
4653    
4654   if (config->defaultImage == -1) return 0;   if (config->defaultImage == -1)
4655        return 0;
4656   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&   if (config->defaultImage == DEFAULT_SAVED_GRUB2 &&
4657   cfi->defaultIsSaved)   cfi->defaultIsSaved)
4658      config->defaultImage = 0;      config->defaultImage = 0;
4659   entry = findEntryByIndex(config, config->defaultImage);   entry = findEntryByIndex(config, config->defaultImage);
4660   if (!entry) return 0;   if (!entry)
4661     return 0;
4662    
4663   if (!configureGrub2) {   if (!configureGrub2) {
4664    line = getLineByType(LT_TITLE, entry->lines);      char *title;
4665    if (!line) return 0;      line = getLineByType(LT_TITLE, entry->lines);
4666    printf("%s\n", line->elements[1].item);      if (!line)
4667     return 0;
4668        title = extractTitle(config, line);
4669        if (!title)
4670     return 0;
4671        printf("%s\n", title);
4672        free(title);
4673   } else {   } else {
4674    char * title;      char * title;
4675    
4676    dbgPrintf("This is GRUB2, default title is embeded in menuentry\n");      dbgPrintf("This is GRUB2, default title is embeded in menuentry\n");
4677    line = getLineByType(LT_MENUENTRY, entry->lines);      line = getLineByType(LT_MENUENTRY, entry->lines);
4678    if (!line) return 0;      if (!line)
4679    title = grub2ExtractTitle(line);   return 0;
4680    if (title)      title = grub2ExtractTitle(line);
4681      printf("%s\n", title);      if (title)
4682     printf("%s\n", title);
4683   }   }
4684   return 0;   return 0;
4685    

Legend:
Removed from v.2977  
changed lines
  Added in v.2992