2 * GRUB -- GRand Unified Bootloader
3 * Copyright (C) 2000,2001,2002 Free Software Foundation, Inc.
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 /* Based on "src/misc.c" in etherboot-5.0.5. */
27 /**************************************************************************
28 RANDOM - compute a random number between 0 and 2147483647L or 2147483562?
29 **************************************************************************/
32 static int32_t seed
= 0;
34 if (!seed
) /* Initialize linear congruential generator */
35 seed
= currticks() + *(int32_t *)&arptable
[ARP_CLIENT
].node
36 + ((int16_t *)arptable
[ARP_CLIENT
].node
)[2];
37 /* simplified version of the LCG given in Bruce Schneier's
38 "Applied Cryptography" */
40 if ((seed
= 40014*(seed
-53668*q
) - 12211*q
) < 0) seed
+= 2147483563L;
44 /**************************************************************************
46 **************************************************************************/
47 void poll_interruptions(void)
49 if (checkkey() != -1 && ASCII_CHAR(getkey()) == K_INTR
) {
54 /**************************************************************************
56 **************************************************************************/
61 for (tmo
= currticks()+secs
*TICKS_PER_SEC
; currticks() < tmo
; ) {
66 /**************************************************************************
68 **************************************************************************/
69 void interruptible_sleep(int secs
)
75 /**************************************************************************
77 **************************************************************************/
82 static const char tiddles
[]="-\\|/";
83 static unsigned long lastticks
= 0;
87 extern char pxeemu_nbp_active
;
88 if(pxeemu_nbp_active
!= 0)
92 /* Limit the maximum rate at which characters are printed */
94 if ((lastticks
+ (TICKS_PER_SEC
/18)) > ticks
)
98 putchar(tiddles
[(count
++)&3]);
102 #endif /* BAR_PROGRESS */
106 /* Because Etherboot uses its own formats for the printf family,
107 define separate definitions from GRUB. */
108 /**************************************************************************
112 %[#]x - 4 bytes long (8 hex digits, lower case)
113 %[#]X - 4 bytes long (8 hex digits, upper case)
114 %[#]hx - 2 bytes int (4 hex digits, lower case)
115 %[#]hX - 2 bytes int (4 hex digits, upper case)
116 %[#]hhx - 1 byte int (2 hex digits, lower case)
117 %[#]hhX - 1 byte int (2 hex digits, upper case)
118 - optional # prefixes 0x or 0X
122 %@ - Internet address in ddd.ddd.ddd.ddd notation
123 %! - Ethernet address in xx:xx:xx:xx:xx:xx notation
124 Note: width specification not supported
125 **************************************************************************/
127 etherboot_vsprintf (char *buf
, const char *fmt
, const int *dp
)
132 for ( ; *fmt
!= '\0'; ++fmt
)
136 buf
? *s
++ = *fmt
: grub_putchar (*fmt
);
142 for (p
= (char *) *dp
++; *p
!= '\0'; p
++)
143 buf
? *s
++ = *p
: grub_putchar (*p
);
147 /* Length of item is bounded */
148 char tmp
[20], *q
= tmp
;
171 * Before each format q points to tmp buffer
172 * After each format q points past end of item
174 if ((*fmt
| 0x20) == 'x')
176 /* With x86 gcc, sizeof(long) == sizeof(int) */
177 const long *lp
= (const long *) dp
;
179 int ncase
= (*fmt
& 0x20);
181 dp
= (const int *) lp
;
187 for (; shift
>= 0; shift
-= 4)
188 *q
++ = "0123456789ABCDEF"[(h
>> shift
) & 0xF] | ncase
;
190 else if (*fmt
== 'd')
201 p
= q
; /* save beginning of digits */
204 *q
++ = '0' + (i
% 10);
209 /* reverse digits, stop in middle */
210 r
= q
; /* don't alter q */
218 else if (*fmt
== '@')
227 const long *lp
= (const long *) dp
;
230 dp
= (const int *) lp
;
232 for (r
= &u
.c
[0]; r
< &u
.c
[4]; ++r
)
233 q
+= etherboot_sprintf (q
, "%d.", *r
);
237 else if (*fmt
== '!')
242 for (r
= p
+ ETH_ALEN
; p
< r
; ++p
)
243 q
+= etherboot_sprintf (q
, "%hhX:", *p
);
247 else if (*fmt
== 'c')
252 /* now output the saved string */
253 for (p
= tmp
; p
< q
; ++p
)
254 buf
? *s
++ = *p
: grub_putchar (*p
);
265 etherboot_sprintf (char *buf
, const char *fmt
, ...)
267 return etherboot_vsprintf (buf
, fmt
, ((const int *) &fmt
) + 1);
271 etherboot_printf (const char *fmt
, ...)
273 (void) etherboot_vsprintf (0, fmt
, ((const int *) &fmt
) + 1);
277 inet_aton (char *p
, in_addr
*addr
)
279 unsigned long ip
= 0;
283 for (i
= 0; i
< 4; i
++)
287 if (val
< 0 || val
> 255)
290 if (i
!= 3 && *p
++ != '.')
293 ip
= (ip
<< 8) | val
;
296 addr
->s_addr
= htonl (ip
);
307 if (*p
< '0' || *p
> '9')
310 while (*p
>= '0' && *p
<= '9')
312 ret
= ret
* 10 + (*p
- '0');