12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556 |
- /*
- * GRUB -- GRand Unified Bootloader
- * Copyright (C) 2013 Free Software Foundation, Inc.
- *
- * GRUB is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * GRUB is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
- */
- #include <grub/mm.h>
- #include <grub/file.h>
- #include <grub/normal.h>
- #include <grub/syslinux_parse.h>
- struct syslinux_say
- {
- struct syslinux_say *next;
- struct syslinux_say *prev;
- char msg[0];
- };
- struct initrd_list
- {
- struct initrd_list *next;
- char *file;
- };
- struct syslinux_menuentry
- {
- struct syslinux_menuentry *next;
- struct syslinux_menuentry *prev;
- char *label;
- char *extlabel;
- char *kernel_file;
- struct initrd_list *initrds;
- struct initrd_list *initrds_last;
- char *append;
- char *argument;
- char *help;
- char *comments;
- grub_size_t commentslen;
- char hotkey;
- int make_default;
- struct syslinux_say *say;
- enum { KERNEL_NO_KERNEL, KERNEL_LINUX, KERNEL_CHAINLOADER,
- KERNEL_BIN, KERNEL_PXE, KERNEL_CHAINLOADER_BPB,
- KERNEL_COM32, KERNEL_COM, KERNEL_IMG, KERNEL_CONFIG, LOCALBOOT }
- entry_type;
- };
- struct syslinux_menu
- {
- struct syslinux_menu *parent;
- struct syslinux_menuentry *entries;
- char *def;
- char *comments;
- char *background;
- const char *root_read_directory;
- const char *root_target_directory;
- const char *current_read_directory;
- const char *current_target_directory;
- const char *filename;
- grub_size_t commentslen;
- unsigned long timeout;
- struct syslinux_say *say;
- grub_syslinux_flavour_t flavour;
- };
- struct output_buffer
- {
- grub_size_t alloc;
- grub_size_t ptr;
- char *buf;
- };
- static grub_err_t
- syslinux_parse_real (struct syslinux_menu *menu);
- static grub_err_t
- config_file (struct output_buffer *outbuf,
- const char *root, const char *target_root,
- const char *cwd, const char *target_cwd,
- const char *fname, struct syslinux_menu *parent,
- grub_syslinux_flavour_t flav);
- static grub_err_t
- print_entry (struct output_buffer *outbuf,
- struct syslinux_menu *menu,
- const char *str);
- static grub_err_t
- ensure_space (struct output_buffer *outbuf, grub_size_t len)
- {
- grub_size_t newlen;
- char *newbuf;
- if (len < outbuf->alloc - outbuf->ptr)
- return GRUB_ERR_NONE;
- newlen = (outbuf->ptr + len + 10) * 2;
- newbuf = grub_realloc (outbuf->buf, newlen);
- if (!newbuf)
- return grub_errno;
- outbuf->alloc = newlen;
- outbuf->buf = newbuf;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- print (struct output_buffer *outbuf, const char *str, grub_size_t len)
- {
- grub_err_t err;
- err = ensure_space (outbuf, len);
- if (err)
- return err;
- grub_memcpy (&outbuf->buf[outbuf->ptr], str, len);
- outbuf->ptr += len;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- add_comment (struct syslinux_menu *menu, const char *comment, int nl)
- {
- if (menu->entries)
- {
- if (menu->entries->commentslen == 0 && *comment == 0)
- return GRUB_ERR_NONE;
- menu->entries->comments = grub_realloc (menu->entries->comments,
- menu->entries->commentslen
- + 2 + grub_strlen (comment));
- if (!menu->entries->comments)
- return grub_errno;
- menu->entries->commentslen
- += grub_stpcpy (menu->entries->comments + menu->entries->commentslen,
- comment)
- - (menu->entries->comments + menu->entries->commentslen);
- if (nl)
- menu->entries->comments[menu->entries->commentslen++] = '\n';
- menu->entries->comments[menu->entries->commentslen] = '\0';
- }
- else
- {
- if (menu->commentslen == 0 && *comment == 0)
- return GRUB_ERR_NONE;
- menu->comments = grub_realloc (menu->comments, menu->commentslen
- + 2 + grub_strlen (comment));
- if (!menu->comments)
- return grub_errno;
- menu->commentslen += grub_stpcpy (menu->comments + menu->commentslen,
- comment)
- - (menu->comments + menu->commentslen);
- if (nl)
- menu->comments[menu->commentslen++] = '\n';
- menu->comments[menu->commentslen] = '\0';
- }
- return GRUB_ERR_NONE;
- }
- #define print_string(x) do { err = print (outbuf, x, sizeof (x) - 1); if (err) return err; } while (0)
- static grub_err_t
- print_num (struct output_buffer *outbuf, int n)
- {
- char buf[20];
- grub_snprintf (buf, sizeof (buf), "%d", n);
- return print (outbuf, buf, grub_strlen (buf));
- }
- static grub_err_t
- label (const char *line, struct syslinux_menu *menu)
- {
- struct syslinux_menuentry *entry;
- entry = grub_malloc (sizeof (*entry));
- if (!entry)
- return grub_errno;
- grub_memset (entry, 0, sizeof (*entry));
- entry->label = grub_strdup (line);
- if (!entry->label)
- {
- grub_free (entry);
- return grub_errno;
- }
- entry->next = menu->entries;
- entry->prev = NULL;
- if (menu->entries)
- menu->entries->prev = entry;
- menu->entries = entry;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- kernel (const char *line, struct syslinux_menu *menu)
- {
- const char *end = line + grub_strlen (line);
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_LINUX;
- if (end - line >= 2 && grub_strcmp (end - 2, ".0") == 0)
- menu->entries->entry_type = KERNEL_PXE;
- if (end - line >= 4 && grub_strcasecmp (end - 4, ".bin") == 0)
- menu->entries->entry_type = KERNEL_BIN;
- if (end - line >= 3 && grub_strcasecmp (end - 3, ".bs") == 0)
- menu->entries->entry_type = KERNEL_CHAINLOADER;
- if (end - line >= 4 && grub_strcasecmp (end - 4, ".bss") == 0)
- menu->entries->entry_type = KERNEL_CHAINLOADER_BPB;
- if (end - line >= 4 && grub_strcasecmp (end - 4, ".c32") == 0)
- menu->entries->entry_type = KERNEL_COM32;
- if (end - line >= 4 && grub_strcasecmp (end - 4, ".cbt") == 0)
- menu->entries->entry_type = KERNEL_COM;
- if (end - line >= 4 && grub_strcasecmp (end - 4, ".com") == 0)
- menu->entries->entry_type = KERNEL_COM;
- if (end - line >= 4 && grub_strcasecmp (end - 4, ".img") == 0)
- menu->entries->entry_type = KERNEL_IMG;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_linux (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_LINUX;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_boot (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_CHAINLOADER;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_bss (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_CHAINLOADER_BPB;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_pxe (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_PXE;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_fdimage (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_IMG;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_comboot (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_COM;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_com32 (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = KERNEL_COM32;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_config (const char *line, struct syslinux_menu *menu)
- {
- const char *space;
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- for (space = line; *space && !grub_isspace (*space); space++);
- menu->entries->kernel_file = grub_strndup (line, space - line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- for (; *space && grub_isspace (*space); space++);
- if (*space)
- {
- menu->entries->argument = grub_strdup (space);
- if (!menu->entries->argument)
- return grub_errno;
- }
- menu->entries->entry_type = KERNEL_CONFIG;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_append (const char *line, struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->append = grub_strdup (line);
- if (!menu->entries->append)
- return grub_errno;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_initrd (const char *line, struct syslinux_menu *menu)
- {
- struct initrd_list *ninitrd;
- const char *comma;
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- while (*line)
- {
- for (comma = line; *comma && *comma != ','; comma++);
- ninitrd = grub_malloc (sizeof (*ninitrd));
- if (!ninitrd)
- return grub_errno;
- ninitrd->file = grub_strndup (line, comma - line);
- if (!ninitrd->file)
- {
- grub_free (ninitrd);
- return grub_errno;
- }
- ninitrd->next = NULL;
- if (menu->entries->initrds_last)
- menu->entries->initrds_last->next = ninitrd;
- else
- {
- menu->entries->initrds_last = ninitrd;
- menu->entries->initrds = ninitrd;
- }
- line = comma;
- while (*line == ',')
- line++;
- }
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_default (const char *line, struct syslinux_menu *menu)
- {
- menu->def = grub_strdup (line);
- if (!menu->def)
- return grub_errno;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_timeout (const char *line, struct syslinux_menu *menu)
- {
- menu->timeout = grub_strtoul (line, NULL, 0);
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_menudefault (const char *line __attribute__ ((unused)),
- struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->make_default = 1;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_menubackground (const char *line,
- struct syslinux_menu *menu)
- {
- menu->background = grub_strdup (line);
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_localboot (const char *line,
- struct syslinux_menu *menu)
- {
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->kernel_file = grub_strdup (line);
- if (!menu->entries->kernel_file)
- return grub_errno;
- menu->entries->entry_type = LOCALBOOT;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_extlabel (const char *line, struct syslinux_menu *menu)
- {
- const char *in;
- char *out;
- if (!menu->entries)
- return grub_error (GRUB_ERR_BAD_ARGUMENT, "kernel without label");
- menu->entries->extlabel = grub_malloc (grub_strlen (line) + 1);
- if (!menu->entries->extlabel)
- return grub_errno;
- in = line;
- out = menu->entries->extlabel;
- while (*in)
- {
- if (in[0] == '^' && in[1])
- {
- menu->entries->hotkey = grub_tolower (in[1]);
- in++;
- }
- *out++ = *in++;
- }
- *out = 0;
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- cmd_say (const char *line, struct syslinux_menu *menu)
- {
- struct syslinux_say *nsay;
- nsay = grub_malloc (sizeof (*nsay) + grub_strlen (line) + 1);
- if (!nsay)
- return grub_errno;
- nsay->prev = NULL;
- if (menu->entries)
- {
- nsay->next = menu->entries->say;
- menu->entries->say = nsay;
- }
- else
- {
- nsay->next = menu->say;
- menu->say = nsay;
- }
- if (nsay->next)
- nsay->next->prev = nsay;
- grub_memcpy (nsay->msg, line, grub_strlen (line) + 1);
- return GRUB_ERR_NONE;
- }
- static char *
- get_read_filename (struct syslinux_menu *menu,
- const char *filename)
- {
- return grub_xasprintf ("%s/%s",
- filename[0] == '/' ? menu->root_read_directory
- : menu->current_read_directory, filename);
- }
- static char *
- get_target_filename (struct syslinux_menu *menu,
- const char *filename)
- {
- return grub_xasprintf ("%s/%s",
- filename[0] == '/' ? menu->root_target_directory
- : menu->current_target_directory, filename);
- }
- static grub_err_t
- syslinux_parse (const char *filename,
- struct syslinux_menu *menu)
- {
- const char *old_filename = menu->filename;
- grub_err_t ret;
- char *nf;
- nf = get_read_filename (menu, filename);
- if (!nf)
- return grub_errno;
- menu->filename = nf;
- ret = syslinux_parse_real (menu);
- if (ret == GRUB_ERR_FILE_NOT_FOUND
- || ret == GRUB_ERR_BAD_FILENAME)
- {
- grub_errno = ret = GRUB_ERR_NONE;
- add_comment (menu, "# File ", 0);
- add_comment (menu, nf, 0);
- add_comment (menu, " not found", 1);
- }
- grub_free (nf);
- menu->filename = old_filename;
- return ret;
- }
- struct
- {
- const char *name1;
- const char *name2;
- grub_err_t (*parse) (const char *line, struct syslinux_menu *menu);
- } commands[] = {
- /* FIXME: support tagname. */
- {"include", NULL, syslinux_parse},
- {"menu", "include", syslinux_parse},
- {"label", NULL, label},
- {"kernel", NULL, kernel},
- {"linux", NULL, cmd_linux},
- {"boot", NULL, cmd_boot},
- {"bss", NULL, cmd_bss},
- {"pxe", NULL, cmd_pxe},
- {"fdimage", NULL, cmd_fdimage},
- {"comboot", NULL, cmd_comboot},
- {"com32", NULL, cmd_com32},
- {"config", NULL, cmd_config},
- {"append", NULL, cmd_append},
- /* FIXME: ipappend not supported. */
- {"localboot", NULL, cmd_localboot},
- {"initrd", NULL, cmd_initrd},
- {"default", NULL, cmd_default},
- {"menu", "label", cmd_extlabel},
- /* FIXME: MENU LABEL not supported. */
- /* FIXME: MENU HIDDEN not supported. */
- /* FIXME: MENU SEPARATOR not supported. */
- /* FIXME: MENU INDENT not supported. */
- /* FIXME: MENU DISABLE not supported. */
- /* FIXME: MENU HIDE not supported. */
- {"menu", "default", cmd_menudefault},
- /* FIXME: MENU PASSWD not supported. */
- /* FIXME: MENU MASTER PASSWD not supported. */
- {"menu", "background", cmd_menubackground},
- /* FIXME: MENU BEGIN not supported. */
- /* FIXME: MENU GOTO not supported. */
- /* FIXME: MENU EXIT not supported. */
- /* FIXME: MENU QUIT not supported. */
- /* FIXME: MENU START not supported. */
- /* FIXME: MENU AUTOBOOT not supported. */
- /* FIXME: MENU TABMSG not supported. */
- /* FIXME: MENU NOTABMSG not supported. */
- /* FIXME: MENU PASSPROMPT not supported. */
- /* FIXME: MENU COLOR not supported. */
- /* FIXME: MENU MSGCOLOR not supported. */
- /* FIXME: MENU WIDTH not supported. */
- /* FIXME: MENU MARGIN not supported. */
- /* FIXME: MENU PASSWORDMARGIN not supported. */
- /* FIXME: MENU ROWS not supported. */
- /* FIXME: MENU TABMSGROW not supported. */
- /* FIXME: MENU CMDLINEROW not supported. */
- /* FIXME: MENU ENDROW not supported. */
- /* FIXME: MENU PASSWORDROW not supported. */
- /* FIXME: MENU TIMEOUTROW not supported. */
- /* FIXME: MENU HELPMSGROW not supported. */
- /* FIXME: MENU HELPMSGENDROW not supported. */
- /* FIXME: MENU HIDDENROW not supported. */
- /* FIXME: MENU HSHIFT not supported. */
- /* FIXME: MENU VSHIFT not supported. */
- {"timeout", NULL, cmd_timeout},
- /* FIXME: TOTALTIMEOUT not supported. */
- /* FIXME: ONTIMEOUT not supported. */
- /* FIXME: ONERROR not supported. */
- /* FIXME: SERIAL not supported. */
- /* FIXME: CONSOLE not supported. */
- /* FIXME: FONT not supported. */
- /* FIXME: KBDMAP not supported. */
- {"say", NULL, cmd_say},
- /* FIXME: DISPLAY not supported. */
- /* FIXME: F* not supported. */
- /* Commands to control interface behaviour which aren't needed with GRUB.
- If they are important in your environment please contact GRUB team.
- */
- {"prompt", NULL, NULL},
- {"nocomplete", NULL, NULL},
- {"noescape", NULL, NULL},
- {"implicit", NULL, NULL},
- {"allowoptions", NULL, NULL}
- };
- static grub_err_t
- helptext (const char *line, grub_file_t file, struct syslinux_menu *menu)
- {
- char *help;
- char *buf = NULL;
- grub_size_t helplen, alloclen = 0;
- help = grub_strdup (line);
- if (!help)
- return grub_errno;
- helplen = grub_strlen (line);
- while ((grub_free (buf), buf = grub_file_getline (file)))
- {
- char *ptr;
- grub_size_t needlen;
- for (ptr = buf; *ptr && grub_isspace (*ptr); ptr++);
- if (grub_strncasecmp (ptr, "endtext", sizeof ("endtext") - 1) == 0)
- {
- ptr += sizeof ("endtext") - 1;
- for (; *ptr && (grub_isspace (*ptr) || *ptr == '\n' || *ptr == '\r');
- ptr++);
- if (!*ptr)
- {
- menu->entries->help = help;
- grub_free (buf);
- return GRUB_ERR_NONE;
- }
- }
- needlen = helplen + 1 + grub_strlen (buf);
- if (alloclen < needlen)
- {
- alloclen = 2 * needlen;
- help = grub_realloc (help, alloclen);
- if (!help)
- {
- grub_free (buf);
- return grub_errno;
- }
- }
- helplen += grub_stpcpy (help + helplen, buf) - (help + helplen);
- }
- grub_free (buf);
- grub_free (help);
- return grub_errno;
- }
- static grub_err_t
- syslinux_parse_real (struct syslinux_menu *menu)
- {
- grub_file_t file;
- char *buf = NULL;
- grub_err_t err = GRUB_ERR_NONE;
- file = grub_file_open (menu->filename, GRUB_FILE_TYPE_CONFIG);
- if (!file)
- return grub_errno;
- while ((grub_free (buf), buf = grub_file_getline (file)))
- {
- const char *ptr1, *ptr2, *ptr3, *ptr4, *ptr5;
- char *end;
- unsigned i;
- end = buf + grub_strlen (buf);
- while (end > buf && (end[-1] == '\n' || end[-1] == '\r'))
- end--;
- *end = 0;
- for (ptr1 = buf; *ptr1 && grub_isspace (*ptr1); ptr1++);
- if (*ptr1 == '#' || *ptr1 == 0)
- {
- err = add_comment (menu, ptr1, 1);
- if (err)
- goto fail;
- continue;
- }
- for (ptr2 = ptr1; !grub_isspace (*ptr2) && *ptr2; ptr2++);
- for (ptr3 = ptr2; grub_isspace (*ptr3) && *ptr3; ptr3++);
- for (ptr4 = ptr3; !grub_isspace (*ptr4) && *ptr4; ptr4++);
- for (ptr5 = ptr4; grub_isspace (*ptr5) && *ptr5; ptr5++);
- for (i = 0; i < ARRAY_SIZE(commands); i++)
- if (grub_strlen (commands[i].name1) == (grub_size_t) (ptr2 - ptr1)
- && grub_strncasecmp (commands[i].name1, ptr1, ptr2 - ptr1) == 0
- && (commands[i].name2 == NULL
- || (grub_strlen (commands[i].name2)
- == (grub_size_t) (ptr4 - ptr3)
- && grub_strncasecmp (commands[i].name2, ptr3, ptr4 - ptr3)
- == 0)))
- break;
- if (i == ARRAY_SIZE(commands))
- {
- if (sizeof ("text") - 1 == ptr2 - ptr1
- && grub_strncasecmp ("text", ptr1, ptr2 - ptr1) == 0
- && (sizeof ("help") - 1 == ptr4 - ptr3
- && grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0))
- {
- if (helptext (ptr5, file, menu))
- {
- grub_free (buf);
- return 1;
- }
- continue;
- }
- add_comment (menu, " # UNSUPPORTED command '", 0);
- add_comment (menu, ptr1, 0);
- add_comment (menu, "'", 1);
- continue;
- }
- if (commands[i].parse)
- {
- err = commands[i].parse (commands[i].name2
- ? ptr5 : ptr3, menu);
- if (err)
- goto fail;
- }
- }
- fail:
- grub_file_close (file);
- grub_free (buf);
- return err;
- }
- static grub_err_t
- print_escaped (struct output_buffer *outbuf,
- const char *from, const char *to)
- {
- const char *ptr;
- grub_err_t err;
- if (!to)
- to = from + grub_strlen (from);
- err = ensure_space (outbuf, (to - from) * 4 + 2);
- if (err)
- return err;
- outbuf->buf[outbuf->ptr++] = '\'';
- for (ptr = from; *ptr && ptr < to; ptr++)
- {
- if (*ptr == '\'')
- {
- outbuf->buf[outbuf->ptr++] = '\'';
- outbuf->buf[outbuf->ptr++] = '\\';
- outbuf->buf[outbuf->ptr++] = '\'';
- outbuf->buf[outbuf->ptr++] = '\'';
- }
- else
- outbuf->buf[outbuf->ptr++] = *ptr;
- }
- outbuf->buf[outbuf->ptr++] = '\'';
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- print_file (struct output_buffer *outbuf,
- struct syslinux_menu *menu, const char *from, const char *to)
- {
- grub_err_t err;
- if (!to)
- to = from + grub_strlen (from);
- err = print_escaped (outbuf, from[0] == '/'
- ? menu->root_target_directory
- : menu->current_target_directory, NULL);
- if (err)
- return err;
- err = print (outbuf, "/", 1);
- if (err)
- return err;
- return print_escaped (outbuf, from, to);
- }
- /*
- * Makefile.am mimics this when generating tests/syslinux/ubuntu10.04_grub.cfg,
- * so changes here may need to be reflected there too.
- */
- static void
- simplify_filename (char *str)
- {
- char *iptr, *optr = str;
- for (iptr = str; *iptr; iptr++)
- {
- if (*iptr == '/' && optr != str && optr[-1] == '/')
- continue;
- if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '/')
- {
- iptr += 2;
- continue;
- }
- if (iptr[0] == '/' && iptr[1] == '.' && iptr[2] == '.'
- && iptr[3] == '/')
- {
- iptr += 3;
- while (optr >= str && *optr != '/')
- optr--;
- if (optr < str)
- {
- str[0] = '/';
- optr = str;
- }
- optr++;
- continue;
- }
- *optr++ = *iptr;
- }
- *optr = '\0';
- }
- static grub_err_t
- print_config (struct output_buffer *outbuf,
- struct syslinux_menu *menu,
- const char *filename, const char *basedir)
- {
- struct syslinux_menu *menuptr;
- grub_err_t err = GRUB_ERR_NONE;
- char *new_cwd = NULL;
- char *new_target_cwd = NULL;
- char *newname = NULL;
- int depth = 0;
- new_cwd = get_read_filename (menu, basedir);
- if (!new_cwd)
- {
- err = grub_errno;
- goto out;
- }
- new_target_cwd = get_target_filename (menu, basedir);
- if (!new_target_cwd)
- {
- err = grub_errno;
- goto out;
- }
- newname = get_read_filename (menu, filename);
- if (!newname)
- {
- err = grub_errno;
- goto out;
- }
- simplify_filename (newname);
- print_string ("#");
- print_file (outbuf, menu, filename, NULL);
- print_string (" ");
- err = print (outbuf, newname, grub_strlen (newname));
- if (err)
- return err;
- print_string (":\n");
- for (menuptr = menu; menuptr; menuptr = menuptr->parent, depth++)
- if (grub_strcmp (menuptr->filename, newname) == 0
- || depth > 20)
- break;
- if (menuptr)
- {
- print_string (" syslinux_configfile -r ");
- print_file (outbuf, menu, "/", NULL);
- print_string (" -c ");
- print_file (outbuf, menu, basedir, NULL);
- print_string (" ");
- print_file (outbuf, menu, filename, NULL);
- print_string ("\n");
- }
- else
- {
- err = config_file (outbuf, menu->root_read_directory,
- menu->root_target_directory, new_cwd, new_target_cwd,
- newname, menu, menu->flavour);
- if (err == GRUB_ERR_FILE_NOT_FOUND
- || err == GRUB_ERR_BAD_FILENAME)
- {
- grub_errno = err = GRUB_ERR_NONE;
- print_string ("# File ");
- err = print (outbuf, newname, grub_strlen (newname));
- if (err)
- goto out;
- print_string (" not found\n");
- }
- }
- out:
- grub_free (newname);
- grub_free (new_cwd);
- grub_free (new_target_cwd);
- return err;
- }
- static grub_err_t
- write_entry (struct output_buffer *outbuf,
- struct syslinux_menu *menu,
- struct syslinux_menuentry *curentry)
- {
- grub_err_t err;
- if (curentry->comments)
- {
- err = print (outbuf, curentry->comments,
- grub_strlen (curentry->comments));
- if (err)
- return err;
- }
- {
- struct syslinux_say *say;
- for (say = curentry->say; say && say->next; say = say->next);
- for (; say && say->prev; say = say->prev)
- {
- print_string ("echo ");
- if (print_escaped (outbuf, say->msg, NULL)) return grub_errno;
- print_string ("\n");
- }
- }
- /* FIXME: support help text. */
- switch (curentry->entry_type)
- {
- case KERNEL_LINUX:
- {
- const char *ptr;
- const char *initrd = NULL, *initrde= NULL;
- for (ptr = curentry->append; ptr && *ptr; ptr++)
- if ((ptr == curentry->append || grub_isspace (ptr[-1]))
- && grub_strncasecmp (ptr, "initrd=", sizeof ("initrd=") - 1)
- == 0)
- break;
- if (ptr && *ptr)
- {
- initrd = ptr + sizeof ("initrd=") - 1;
- for (initrde = initrd; *initrde && !grub_isspace (*initrde); initrde++);
- }
- print_string (" if test x$grub_platform = xpc; then "
- "linux_suffix=16; else linux_suffix= ; fi\n");
- print_string (" linux$linux_suffix ");
- print_file (outbuf, menu, curentry->kernel_file, NULL);
- print_string (" ");
- if (curentry->append)
- {
- err = print (outbuf, curentry->append, grub_strlen (curentry->append));
- if (err)
- return err;
- }
- print_string ("\n");
- if (initrd || curentry->initrds)
- {
- struct initrd_list *lst;
- print_string (" initrd$linux_suffix ");
- if (initrd)
- {
- print_file (outbuf, menu, initrd, initrde);
- print_string (" ");
- }
- for (lst = curentry->initrds; lst; lst = lst->next)
- {
- print_file (outbuf, menu, lst->file, NULL);
- print_string (" ");
- }
- print_string ("\n");
- }
- }
- break;
- case KERNEL_CHAINLOADER:
- print_string (" chainloader ");
- print_file (outbuf, menu, curentry->kernel_file, NULL);
- print_string ("\n");
- break;
- case KERNEL_CHAINLOADER_BPB:
- print_string (" chainloader --bpb ");
- print_file (outbuf, menu, curentry->kernel_file, NULL);
- print_string ("\n");
- break;
- case LOCALBOOT:
- /* FIXME: support -1. */
- /* FIXME: PXELINUX. */
- {
- int n = grub_strtol (curentry->kernel_file, NULL, 0);
- if (n >= 0 && n <= 0x02)
- {
- print_string (" root=fd");
- if (print_num (outbuf, n))
- return grub_errno;
- print_string (";\n chainloader +1;\n");
- break;
- }
- if (n >= 0x80 && n < 0x8a)
- {
- print_string (" root=hd");
- if (print_num (outbuf, n - 0x80))
- return grub_errno;
- print_string (";\n chainloader +1;\n");
- break;
- }
- print_string (" # UNSUPPORTED localboot type ");
- print_string ("\ntrue;\n");
- if (print_num (outbuf, n))
- return grub_errno;
- print_string ("\n");
- break;
- }
- case KERNEL_COM32:
- case KERNEL_COM:
- {
- char *basename = NULL;
- {
- char *ptr;
- for (ptr = curentry->kernel_file; *ptr; ptr++)
- if (*ptr == '/' || *ptr == '\\')
- basename = ptr;
- }
- if (!basename)
- basename = curentry->kernel_file;
- else
- basename++;
- if (grub_strcasecmp (basename, "chain.c32") == 0)
- {
- char *file = NULL;
- int is_fd = -1, devn = 0;
- int part = -1;
- int swap = 0;
- char *ptr;
- for (ptr = curentry->append; *ptr; )
- {
- while (grub_isspace (*ptr))
- ptr++;
- /* FIXME: support mbr: and boot. */
- if (ptr[0] == 'h' && ptr[1] == 'd')
- {
- is_fd = 0;
- devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0);
- continue;
- }
- if (grub_strncasecmp (ptr, "file=", 5) == 0)
- {
- file = ptr + 5;
- for (ptr = file; *ptr && !grub_isspace (*ptr); ptr++);
- if (*ptr)
- {
- *ptr = 0;
- ptr++;
- }
- continue;
- }
- if (grub_strncasecmp (ptr, "swap", sizeof ("swap") - 1) == 0)
- {
- swap = 1;
- ptr += sizeof ("swap") - 1;
- continue;
- }
- if (ptr[0] == 'f' && ptr[1] == 'd')
- {
- is_fd = 1;
- devn = grub_strtoul (ptr + 2, (const char **)&ptr, 0);
- continue;
- }
- if (grub_isdigit (ptr[0]))
- {
- part = grub_strtoul (ptr, (const char **)&ptr, 0);
- continue;
- }
- /* FIXME: isolinux, ntldr, cmldr, *dos, seg, hide
- FIXME: sethidden. */
- print_string (" # UNSUPPORTED option ");
- if (print (outbuf, ptr, grub_strlen (ptr)))
- return 0;
- print_string ("\n");
- break;
- }
- if (is_fd == -1)
- {
- print_string (" # no drive specified\n");
- break;
- }
- if (!*ptr)
- {
- print_string (is_fd ? " root=fd": " root=hd");
- if (print_num (outbuf, devn))
- return grub_errno;
- if (part != -1)
- {
- print_string (",");
- if (print_num (outbuf, part + 1))
- return grub_errno;
- }
- print_string (";\n");
- if (file)
- {
- print_string (" chainloader ");
- print_file (outbuf, menu, file, NULL);
- print_string (";\n");
- }
- else
- print_string (" chainloader +1;\n");
- if (swap)
- print_string (" drivemap -s hd0 \"root\";\n");
- }
- break;
- }
- if (grub_strcasecmp (basename, "mboot.c32") == 0)
- {
- char *ptr;
- int first = 1;
- int is_kernel = 1;
- for (ptr = curentry->append; *ptr; )
- {
- char *ptrr = ptr;
- while (*ptr && !grub_isspace (*ptr))
- ptr++;
- if (ptrr + 2 == ptr && ptrr[0] == '-' && ptrr[1] == '-')
- {
- print_string ("\n");
- first = 1;
- continue;
- }
- if (first)
- {
- if (is_kernel)
- print_string (" multiboot ");
- else
- print_string (" module ");
- first = 0;
- is_kernel = 0;
- if (print_file (outbuf, menu, ptrr, ptr))
- return grub_errno;
- continue;
- }
- if (print_escaped (outbuf, ptrr, ptr))
- return grub_errno;
- }
- break;
- }
- if (grub_strcasecmp (basename, "ifcpu64.c32") == 0)
- {
- char *lm, *lme, *pae = 0, *paee = 0, *i386s = 0, *i386e = 0;
- char *ptr;
- ptr = curentry->append;
- while (grub_isspace (*ptr))
- ptr++;
- lm = ptr;
- while (*ptr && !grub_isspace (*ptr))
- ptr++;
- lme = ptr;
- while (grub_isspace (*ptr))
- ptr++;
- if (ptr[0] == '-' && ptr[1] == '-')
- {
- ptr += 2;
- while (grub_isspace (*ptr))
- ptr++;
- pae = ptr;
- while (*ptr && !grub_isspace (*ptr))
- ptr++;
- paee = ptr;
- }
- while (grub_isspace (*ptr))
- ptr++;
- if (ptr[0] == '-' && ptr[1] == '-')
- {
- ptr += 2;
- while (grub_isspace (*ptr))
- ptr++;
- i386s = ptr;
- while (*ptr && !grub_isspace (*ptr))
- ptr++;
- i386e = ptr;
- }
- *lme = '\0';
- if (paee)
- *paee = '\0';
- if (i386e)
- *i386e = '\0';
- if (!i386s)
- {
- i386s = pae;
- pae = 0;
- }
- print_string ("if cpuid --long-mode; then true;\n");
- if (print_entry (outbuf, menu, lm))
- return grub_errno;
- if (pae)
- {
- print_string ("elif cpuid --pae; then true;\n");
- if (print_entry (outbuf, menu, pae))
- return grub_errno;
- }
- print_string ("else\n");
- if (print_entry (outbuf, menu, i386s))
- return grub_errno;
- print_string ("fi\n");
- break;
- }
- if (grub_strcasecmp (basename, "reboot.c32") == 0)
- {
- print_string (" reboot\n");
- break;
- }
- if (grub_strcasecmp (basename, "poweroff.com") == 0)
- {
- print_string (" halt\n");
- break;
- }
- if (grub_strcasecmp (basename, "whichsys.c32") == 0)
- {
- grub_syslinux_flavour_t flavour = GRUB_SYSLINUX_ISOLINUX;
- const char *flav[] =
- {
- [GRUB_SYSLINUX_ISOLINUX] = "iso",
- [GRUB_SYSLINUX_PXELINUX] = "pxe",
- [GRUB_SYSLINUX_SYSLINUX] = "sys"
- };
- char *ptr;
- for (ptr = curentry->append; *ptr; )
- {
- char *bptr, c;
- while (grub_isspace (*ptr))
- ptr++;
- if (grub_strncasecmp (ptr, "-iso-", 5) == 0)
- {
- ptr += sizeof ("-iso-") - 1;
- flavour = GRUB_SYSLINUX_ISOLINUX;
- continue;
- }
- if (grub_strncasecmp (ptr, "-pxe-", 5) == 0)
- {
- ptr += sizeof ("-pxe-") - 1;
- flavour = GRUB_SYSLINUX_PXELINUX;
- continue;
- }
- if (grub_strncasecmp (ptr, "-sys-", 5) == 0)
- {
- ptr += sizeof ("-sys-") - 1;
- flavour = GRUB_SYSLINUX_SYSLINUX;
- continue;
- }
- bptr = ptr;
- while (*ptr && !grub_isspace (*ptr))
- ptr++;
- c = *ptr;
- *ptr = '\0';
- if (menu->flavour == GRUB_SYSLINUX_UNKNOWN
- && flavour == GRUB_SYSLINUX_ISOLINUX)
- {
- print_string ("if [ x$syslinux_flavour = xiso -o x$syslinux_flavour = x ]; then true;\n");
- menu->flavour = GRUB_SYSLINUX_ISOLINUX;
- print_entry (outbuf, menu, bptr);
- menu->flavour = GRUB_SYSLINUX_UNKNOWN;
- print_string ("fi\n");
- }
- else if (menu->flavour == GRUB_SYSLINUX_UNKNOWN)
- {
- print_string ("if [ x$syslinux_flavour = x");
- err = print (outbuf, flav[flavour], grub_strlen (flav[flavour]));
- if (err)
- return err;
- print_string (" ]; then true;\n");
- menu->flavour = flavour;
- print_entry (outbuf, menu, bptr);
- menu->flavour = GRUB_SYSLINUX_UNKNOWN;
- print_string ("fi\n");
- }
- if (menu->flavour != GRUB_SYSLINUX_UNKNOWN
- && menu->flavour == flavour)
- print_entry (outbuf, menu, bptr);
- *ptr = c;
- }
- break;
- }
- if (grub_strcasecmp (basename, "menu.c32") == 0 ||
- grub_strcasecmp (basename, "vesamenu.c32") == 0)
- {
- char *ptr;
- char *end;
- ptr = curentry->append;
- if (!ptr)
- return grub_errno;
- while (*ptr)
- {
- end = ptr;
- for (end = ptr; *end && !grub_isspace (*end); end++);
- if (*end)
- *end++ = '\0';
- /* "~" is supposed to be current file, so let's skip it */
- if (grub_strcmp (ptr, "~") != 0)
- {
- err = print_config (outbuf, menu, ptr, "");
- if (err != GRUB_ERR_NONE)
- break;
- }
- for (ptr = end; *ptr && grub_isspace (*ptr); ptr++);
- }
- err = GRUB_ERR_NONE;
- break;
- }
- /* FIXME: gdb, GFXBoot, Hdt, Ifcpu, Ifplop, Kbdmap,
- FIXME: Linux, Lua, Meminfo, rosh, Sanbboot */
- print_string (" # UNSUPPORTED com(32) ");
- err = print (outbuf, basename, grub_strlen (basename));
- if (err)
- return err;
- print_string ("\ntrue;\n");
- break;
- }
- case KERNEL_CONFIG:
- {
- const char *ap;
- ap = curentry->append;
- if (!ap)
- ap = curentry->argument;
- if (!ap)
- ap = "";
- print_config (outbuf, menu, curentry->kernel_file, ap);
- }
- break;
- case KERNEL_NO_KERNEL:
- /* FIXME: support this. */
- case KERNEL_BIN:
- case KERNEL_PXE:
- case KERNEL_IMG:
- print_string (" # UNSUPPORTED entry type ");
- if (print_num (outbuf, curentry->entry_type))
- return grub_errno;
- print_string ("\ntrue;\n");
- break;
- }
- return GRUB_ERR_NONE;
- }
- static grub_err_t
- print_entry (struct output_buffer *outbuf,
- struct syslinux_menu *menu,
- const char *str)
- {
- struct syslinux_menuentry *curentry;
- for (curentry = menu->entries; curentry; curentry = curentry->next)
- if (grub_strcasecmp (curentry->label, str) == 0)
- {
- grub_err_t err;
- err = write_entry (outbuf, menu, curentry);
- if (err)
- return err;
- }
- return GRUB_ERR_NONE;
- }
- static void
- free_menu (struct syslinux_menu *menu)
- {
- struct syslinux_say *say, *nsay;
- struct syslinux_menuentry *entry, *nentry;
- grub_free (menu->def);
- grub_free (menu->comments);
- grub_free (menu->background);
- for (say = menu->say; say ; say = nsay)
- {
- nsay = say->next;
- grub_free (say);
- }
- for (entry = menu->entries; entry ; entry = nentry)
- {
- nentry = entry->next;
- struct initrd_list *initrd, *ninitrd;
- for (initrd = entry->initrds; initrd ; initrd = ninitrd)
- {
- ninitrd = initrd->next;
- grub_free (initrd->file);
- grub_free (initrd);
- }
- grub_free (entry->comments);
- grub_free (entry->kernel_file);
- grub_free (entry->label);
- grub_free (entry->extlabel);
- grub_free (entry->append);
- grub_free (entry->help);
- grub_free (entry);
- }
- }
- static grub_err_t
- config_file (struct output_buffer *outbuf,
- const char *root, const char *target_root,
- const char *cwd, const char *target_cwd,
- const char *fname, struct syslinux_menu *parent,
- grub_syslinux_flavour_t flav)
- {
- grub_err_t err;
- struct syslinux_menu menu;
- struct syslinux_menuentry *curentry, *lentry;
- struct syslinux_say *say;
- grub_memset (&menu, 0, sizeof (menu));
- menu.flavour = flav;
- menu.root_read_directory = root;
- menu.root_target_directory = target_root;
- menu.current_read_directory = cwd;
- menu.current_target_directory = target_cwd;
- menu.filename = fname;
- menu.parent = parent;
- err = syslinux_parse_real (&menu);
- if (err)
- return err;
- for (say = menu.say; say && say->next; say = say->next);
- for (; say && say->prev; say = say->prev)
- {
- print_string ("echo ");
- err = print_escaped (outbuf, say->msg, NULL);
- if (err)
- return err;
- print_string ("\n");
- }
- if (menu.background)
- {
- print_string (" background_image ");
- err = print_file (outbuf, &menu, menu.background, NULL);
- if (err)
- return err;
- print_string ("\n");
- }
- if (menu.comments)
- {
- err = print (outbuf, menu.comments, grub_strlen (menu.comments));
- if (err)
- return err;
- }
- if (menu.timeout == 0 && menu.entries && menu.def)
- {
- err = print_entry (outbuf, &menu, menu.def);
- if (err)
- return err;
- }
- else if (menu.entries)
- {
- for (curentry = menu.entries; curentry->next; curentry = curentry->next);
- lentry = curentry;
- print_string ("set timeout=");
- err = print_num (outbuf, (menu.timeout + 9) / 10);
- if (err)
- return err;
- print_string ("\n");
- if (menu.def)
- {
- print_string (" default=");
- err = print_escaped (outbuf, menu.def, NULL);
- if (err)
- return err;
- print_string ("\n");
- }
- for (curentry = lentry; curentry; curentry = curentry->prev)
- {
- print_string ("menuentry ");
- err = print_escaped (outbuf,
- curentry->extlabel ? : curentry->label, NULL);
- if (err)
- return err;
- if (curentry->hotkey)
- {
- char hk[] = { curentry->hotkey, '\0' };
- print_string (" --hotkey '");
- print_string (hk);
- print_string ("'");
- }
- print_string (" --id ");
- err = print_escaped (outbuf, curentry->label, NULL);
- if (err)
- return err;
- print_string (" {\n");
- err = write_entry (outbuf, &menu, curentry);
- if (err)
- return err;
- print_string ("}\n");
- }
- }
- free_menu (&menu);
- return GRUB_ERR_NONE;
- }
- char *
- grub_syslinux_config_file (const char *base, const char *target_base,
- const char *cwd, const char *target_cwd,
- const char *fname, grub_syslinux_flavour_t flav)
- {
- struct output_buffer outbuf = { 0, 0, 0 };
- grub_err_t err;
- err = config_file (&outbuf, base, target_base, cwd, target_cwd,
- fname, NULL, flav);
- if (err)
- return NULL;
- err = print (&outbuf, "\0", 1);
- if (err)
- return NULL;
- return outbuf.buf;
- }
|