008-09-21 Felix Zielcke <fzielcke@z-51.de>
[grub2/phcoder.git] / lib / envblk.c
blob6618d97f60e8b47008f4203a31214f26c7308c51
1 /* envblk.c - Common function for environment block. */
2 /*
3 * GRUB -- GRand Unified Bootloader
4 * Copyright (C) 2008 Free Software Foundation, Inc.
6 * GRUB is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * GRUB is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
20 #include <config.h>
21 #include <grub/types.h>
22 #include <grub/misc.h>
23 #include <grub/lib/envblk.h>
25 grub_envblk_t
26 grub_envblk_find (char *buf)
28 grub_uint32_t *pd;
29 int len;
31 pd = (grub_uint32_t *) buf;
33 for (len = GRUB_ENVBLK_MAXLEN - 6; len > 0; len -= 4, pd++)
34 if (*pd == GRUB_ENVBLK_SIGNATURE)
36 grub_envblk_t p;
38 p = (grub_envblk_t) pd;
39 if (p->length <= len)
40 return p;
43 return 0;
46 int
47 grub_envblk_insert (grub_envblk_t envblk, char *name, char *value)
49 char *p, *pend;
50 char *found = 0;
51 int nl;
53 nl = grub_strlen (name);
54 p = envblk->data;
55 pend = p + envblk->length;
57 while (*p)
59 if ((! found) && (! grub_memcmp (name, p, nl)) && (p[nl] == '='))
60 found = p + nl + 1;
62 p += grub_strlen (p) + 1;
63 if (p >= pend)
64 return 1;
67 if (found)
69 int len1, len2;
71 len1 = grub_strlen (found);
72 len2 = grub_strlen (value);
73 if ((p - envblk->data) + 1 - len1 + len2 > envblk->length)
74 return 1;
76 grub_memcpy (found + len2 + 1, found + len1 + 1, (p - found) - len1);
77 grub_strcpy (found, value);
79 else
81 int len2 = grub_strlen (value);
83 if ((p - envblk->data) + nl + 1 + len2 + 2 > envblk->length)
84 return 1;
86 grub_strcpy (p, name);
87 p[nl] = '=';
88 grub_strcpy (p + nl + 1, value);
89 p[nl + 1 + len2 + 1] = 0;
92 return 0;
95 void
96 grub_envblk_delete (grub_envblk_t envblk, char *name)
98 char *p, *pend;
99 char *found = 0;
100 int nl;
102 nl = grub_strlen (name);
103 p = envblk->data;
104 pend = p + envblk->length;
106 while (*p)
108 if ((! found) && (! grub_memcmp (name, p, nl)) && (p[nl] == '='))
109 found = p;
111 p += grub_strlen (p) + 1;
112 if (p >= pend)
113 return;
116 if (found)
118 int len;
120 len = grub_strlen (found);
121 grub_memcpy (found, found + len + 1, (p - found) - len);
125 void
126 grub_envblk_iterate (grub_envblk_t envblk,
127 int hook (char *name, char *value))
129 char *p, *pend;
131 p = envblk->data;
132 pend = p + envblk->length;
134 while (*p)
136 char *v;
137 int r;
139 v = grub_strchr (p, '=');
140 if (v)
142 *v = 0;
143 r = hook (p, v + 1);
144 *v = '=';
146 else
147 r = hook (p, "");
149 if (r)
150 break;
152 p += grub_strlen (p) + 1;
153 if (p >= pend)
154 break;