mirror of
https://github.com/Fohdeesha/lab-docu.git
synced 2024-11-29 11:15:23 +01:00
1242 lines
24 KiB
C
1242 lines
24 KiB
C
/***************************************************************************
|
|
* *
|
|
* Copyright 2012 LSI Corporation. All rights reserved. *
|
|
* *
|
|
* This file is confidential and a trade secret of LSI Corporation. The *
|
|
* receipt of or possession of this file does not convey any rights to *
|
|
* reproduce or disclose its contents or to manufacture, use, or sell *
|
|
* anything it may describe, in whole, or in part, without the specific *
|
|
* written consent of LSI Corporation. *
|
|
* *
|
|
***************************************************************************
|
|
*/
|
|
/*
|
|
* helper -- EFI helper routines commonly found in a CRTL
|
|
*
|
|
* Written by Stephen F. Shirron, September 15, 2006
|
|
*/
|
|
|
|
EFI_STATUS last_efi_status;
|
|
int errno;
|
|
int optind;
|
|
char *optarg;
|
|
|
|
EFI_HANDLE gImageHandle;
|
|
|
|
EFI_LOADED_IMAGE *gLoadedImage;
|
|
|
|
EFI_EVENT gSleepEvent;
|
|
|
|
size_t strlen(const char *s)
|
|
{
|
|
const char *c = s;
|
|
|
|
while (*c++);
|
|
|
|
return c - s - 1;
|
|
}
|
|
|
|
char *strcpy(char *s1, const char *s2)
|
|
{
|
|
char *c1 = s1;
|
|
const char *c2 = s2;
|
|
|
|
while (*c1++ = *c2++);
|
|
|
|
return s1;
|
|
}
|
|
|
|
char *strncpy(char *s1, const char *s2, size_t n)
|
|
{
|
|
unsigned char *c1 = s1;
|
|
const char *c2 = s2;
|
|
size_t t = 0;
|
|
|
|
while (t++ < n && (*c1++ = *c2++));
|
|
while (t++ < n) *c1++ = 0;
|
|
|
|
return s1;
|
|
}
|
|
|
|
char *strcat(char *s1, const char *s2)
|
|
{
|
|
char *c1 = s1;
|
|
const char *c2 = s2;
|
|
|
|
while (*c1) c1++;
|
|
while (*c1++ = *c2++);
|
|
|
|
return s1;
|
|
}
|
|
|
|
char *strncat(char *s1, const char *s2, size_t n)
|
|
{
|
|
char *c1 = s1;
|
|
const char *c2 = s2;
|
|
size_t t;
|
|
|
|
while (*c1) c1++;
|
|
t = 0;
|
|
while (t++ < n && (*c1++ = *c2++));
|
|
if (t >= n && *(c1-1)) *c1 = 0;
|
|
|
|
return s1;
|
|
}
|
|
|
|
char *strchr(const char *s1, int t)
|
|
{
|
|
while (*s1) if (*s1++ == t) return (char *)--s1;
|
|
return NULL;
|
|
}
|
|
|
|
int strcmp(const char *s1, const char *s2)
|
|
{
|
|
while (*s1 && *s1 == *s2) s1++, s2++;
|
|
if (*s1 < *s2) return -1;
|
|
if (*s1 > *s2) return 1;
|
|
return 0;
|
|
}
|
|
|
|
int strncmp(const char *s1, const char *s2, size_t n)
|
|
{
|
|
while (n && *s1 && *s1 == *s2) n--, s1++, s2++;
|
|
if (n == 0) return 0;
|
|
if (*s1 < *s2) return -1;
|
|
if (*s1 > *s2) return 1;
|
|
return 0;
|
|
}
|
|
|
|
int toupper(int c)
|
|
{
|
|
if (c >= 'a' && c <= 'z') return c - 'a' + 'A';
|
|
return c;
|
|
}
|
|
|
|
int tolower(int c)
|
|
{
|
|
if (c >= 'A' && c <= 'Z') return c - 'A' + 'a';
|
|
return c;
|
|
}
|
|
|
|
int strcasecmp(const char *s1, const char *s2)
|
|
{
|
|
while (*s1 && tolower(*s1) == tolower(*s2)) s1++, s2++;
|
|
if (tolower(*s1) < tolower(*s2)) return -1;
|
|
if (tolower(*s1) > tolower(*s2)) return 1;
|
|
return 0;
|
|
}
|
|
|
|
int strncasecmp(const char *s1, const char *s2, size_t n)
|
|
{
|
|
while (n && *s1 && tolower(*s1) == tolower(*s2)) n--, s1++, s2++;
|
|
if (n == 0) return 0;
|
|
if (tolower(*s1) < tolower(*s2)) return -1;
|
|
if (tolower(*s1) > tolower(*s2)) return 1;
|
|
return 0;
|
|
}
|
|
|
|
void *memset(void *s, int t, size_t n)
|
|
{
|
|
char *c = s;
|
|
|
|
while (n) n--, *c++ = t;
|
|
return s;
|
|
}
|
|
|
|
void *memcpy(void *s2, const void *s1, size_t n)
|
|
{
|
|
const char *c1 = s1;
|
|
char *c2 = s2;
|
|
|
|
while (n) n--, *c2++ = *c1++;
|
|
return s2;
|
|
}
|
|
|
|
int memcmp(const void *s1, const void *s2, size_t n)
|
|
{
|
|
const char *c1 = s1;
|
|
const char *c2 = s2;
|
|
|
|
while (n && *c1 == *c2) n--, c1++, c2++;
|
|
if (n == 0) return 0;
|
|
if (*c1 < *c2) return -1;
|
|
if (*c1 > *c2) return 1;
|
|
return 0;
|
|
}
|
|
|
|
void bzero(void *s, size_t n)
|
|
{
|
|
char *c = s;
|
|
|
|
while (n)
|
|
{
|
|
*c++ = 0;
|
|
n--;
|
|
}
|
|
}
|
|
|
|
void bcopy(const void *s1, void *s2, size_t n)
|
|
{
|
|
const char *c1 = s1;
|
|
char *c2 = s2;
|
|
|
|
while (n)
|
|
{
|
|
*c2++ = *c1++;
|
|
n--;
|
|
}
|
|
}
|
|
|
|
int isdigit(int c)
|
|
{
|
|
if (c >= '0' && c <= '9') return 1;
|
|
return 0;
|
|
}
|
|
|
|
int isxdigit(int c)
|
|
{
|
|
if (c >= '0' && c <= '9') return 1;
|
|
if (c >= 'a' && c <= 'f') return 1;
|
|
if (c >= 'A' && c <= 'F') return 1;
|
|
return 0;
|
|
}
|
|
|
|
int isalpha(int c)
|
|
{
|
|
if (c >= 'a' && c <= 'z') return 1;
|
|
if (c >= 'A' && c <= 'Z') return 1;
|
|
return 0;
|
|
}
|
|
|
|
int isalnum(int c)
|
|
{
|
|
if (c >= '0' && c <= '9') return 1;
|
|
if (c >= 'a' && c <= 'z') return 1;
|
|
if (c >= 'A' && c <= 'Z') return 1;
|
|
return 0;
|
|
}
|
|
|
|
int isprint(int c)
|
|
{
|
|
if (c >= ' ' && c <= '~') return 1;
|
|
return 0;
|
|
}
|
|
|
|
void *malloc(size_t size)
|
|
{
|
|
return AllocatePool(size);
|
|
}
|
|
|
|
void *realloc(void *oldp, size_t size)
|
|
{
|
|
void *newp = malloc(size);
|
|
|
|
memcpy(newp, oldp, size);
|
|
|
|
free(oldp);
|
|
|
|
return newp;
|
|
}
|
|
|
|
void free(void *p)
|
|
{
|
|
FreePool(p);
|
|
}
|
|
|
|
static void convert_unicode_ascii(const CHAR16 *s1, char *s2, int n)
|
|
{
|
|
int i;
|
|
char c;
|
|
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
c = (char)*s1++;
|
|
*s2++ = c;
|
|
|
|
if (c == 0)
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int convert_dtoi(const char *s, int *r, int w)
|
|
{
|
|
int n = 0;
|
|
char c;
|
|
|
|
*r = 0;
|
|
while (isdigit(c = *s++))
|
|
{
|
|
*r *= 10;
|
|
*r += c - '0';
|
|
n++;
|
|
if (n == w)
|
|
return n;
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
static int convert_xtoi(const char *s, int *r, int w)
|
|
{
|
|
int n = 0;
|
|
char c;
|
|
|
|
*r = 0;
|
|
while (isxdigit(c = *s++))
|
|
{
|
|
*r *= 16;
|
|
if (isdigit(c))
|
|
*r += c - '0';
|
|
else
|
|
*r += tolower(c) - 'a' + 10;
|
|
n++;
|
|
if (n == w)
|
|
return n;
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
static int convert_itod(char *s, int64_t r)
|
|
{
|
|
char c;
|
|
char buffer[32];
|
|
int i;
|
|
int n = 0;
|
|
int negative = 0;
|
|
|
|
if (r < 0)
|
|
{
|
|
r = -r;
|
|
*s++ = '-';
|
|
negative = 1;
|
|
}
|
|
|
|
do
|
|
{
|
|
c = (char)(r % 10);
|
|
r /= 10;
|
|
buffer[n] = c + '0';
|
|
n++;
|
|
}
|
|
while (r);
|
|
|
|
for (i = 0; i < n; i++)
|
|
s[i] = buffer[n - i - 1];
|
|
|
|
s[n] = 0;
|
|
|
|
return n + negative;
|
|
}
|
|
|
|
static int convert_itox(char *s, uint64_t r)
|
|
{
|
|
char c;
|
|
char buffer[32];
|
|
int i;
|
|
int n = 0;
|
|
uint64_t r0 = r;
|
|
|
|
do
|
|
{
|
|
c = (char)(r % 16);
|
|
r /= 16;
|
|
if (c < 10)
|
|
buffer[n] = c + '0';
|
|
else
|
|
buffer[n] = c + 'a' - 10;
|
|
n++;
|
|
}
|
|
while (r);
|
|
|
|
for (i = 0; i < n; i++)
|
|
s[i] = buffer[n - i - 1];
|
|
|
|
s[n] = 0;
|
|
|
|
return n;
|
|
}
|
|
|
|
char *fgets(char *s, int size, FILE *stream)
|
|
{
|
|
CHAR16 buffer[256];
|
|
|
|
if (stream == stdin)
|
|
{
|
|
Input(NULL, buffer, sizeof buffer / 2);
|
|
convert_unicode_ascii(buffer, s, size);
|
|
APrint("\n");
|
|
|
|
return s;
|
|
}
|
|
|
|
printf("fgets from a file not implemented yet!\n");
|
|
|
|
return NULL;
|
|
}
|
|
|
|
int sscanf(const char *s, const char *format, ...)
|
|
{
|
|
va_list args;
|
|
char c;
|
|
int n = 0;
|
|
int w;
|
|
char *as;
|
|
int *ad;
|
|
int *ax;
|
|
int t;
|
|
const char *b;
|
|
|
|
va_start(args, format);
|
|
|
|
b = s;
|
|
while ((c = *format++))
|
|
{
|
|
while (*s == ' ')
|
|
*s++;
|
|
if (c == '%')
|
|
{
|
|
c = *format++;
|
|
w = 0;
|
|
if (isdigit(c))
|
|
{
|
|
format += convert_dtoi(--format, &w, 0);
|
|
c = *format++;
|
|
}
|
|
if (!c)
|
|
break;
|
|
switch (c)
|
|
{
|
|
case 's':
|
|
if (!*s)
|
|
break;
|
|
as = va_arg(args, char *);
|
|
while ((c = *s))
|
|
{
|
|
s++;
|
|
if (c == ' ' || c == '\t' || c == '\r' || c == '\n')
|
|
break;
|
|
*as++ = c;
|
|
}
|
|
*as = 0;
|
|
n++;
|
|
break;
|
|
case 'c':
|
|
if (!*s)
|
|
break;
|
|
as = va_arg(args, char *);
|
|
*as = *s++;
|
|
n++;
|
|
break;
|
|
case 'd':
|
|
if (!*s)
|
|
break;
|
|
ad = va_arg(args, int *);
|
|
t = convert_dtoi(s, ad, w);
|
|
if (t)
|
|
{
|
|
s += t;
|
|
n++;
|
|
}
|
|
break;
|
|
case 'x':
|
|
if (!*s)
|
|
break;
|
|
ax = va_arg(args, int *);
|
|
t = convert_xtoi(s, ax, w);
|
|
if (t)
|
|
{
|
|
s += t;
|
|
n++;
|
|
}
|
|
break;
|
|
case 'n':
|
|
ad = va_arg(args, int *);
|
|
*ad = (int)(s - b);
|
|
break;
|
|
}
|
|
}
|
|
else if (c != ' ')
|
|
{
|
|
if (*s++ != c)
|
|
break;
|
|
}
|
|
}
|
|
|
|
va_end(args);
|
|
|
|
return n;
|
|
}
|
|
|
|
int vsprintf(char *s1, const char *format, va_list args)
|
|
{
|
|
char c;
|
|
char *s;
|
|
char s2[256];
|
|
char b[32];
|
|
int len;
|
|
int n = 0;
|
|
int t = 0;
|
|
int i;
|
|
int w;
|
|
char ac;
|
|
char *as;
|
|
int64_t ad;
|
|
int64_t ax;
|
|
#if !EFIEBC
|
|
double af;
|
|
#endif
|
|
int left;
|
|
char pad;
|
|
int minw;
|
|
int maxw;
|
|
int longint;
|
|
|
|
if (!s1)
|
|
s = s2;
|
|
else
|
|
s = s1;
|
|
|
|
while ((c = *format++))
|
|
{
|
|
if (c == '%')
|
|
{
|
|
c = *format++;
|
|
left = 0;
|
|
pad = ' ';
|
|
minw = 1;
|
|
maxw = 100;
|
|
longint = 0;
|
|
if (c == '-')
|
|
{
|
|
left = 1;
|
|
c = *format++;
|
|
}
|
|
if (c == '0')
|
|
{
|
|
pad = '0';
|
|
c = *format++;
|
|
}
|
|
if (isdigit(c))
|
|
{
|
|
format += convert_dtoi(--format, &minw, 0);
|
|
c = *format++;
|
|
}
|
|
if (c == '.')
|
|
{
|
|
c = *format++;
|
|
if (isdigit(c))
|
|
{
|
|
format += convert_dtoi(--format, &maxw, 0);
|
|
c = *format++;
|
|
}
|
|
}
|
|
if (c == 'l')
|
|
{
|
|
c = *format++;
|
|
if (c == 'l')
|
|
c = *format++;
|
|
longint = 1;
|
|
}
|
|
if (!c)
|
|
break;
|
|
switch (c)
|
|
{
|
|
case 'c':
|
|
ac = (char)va_arg(args, int);
|
|
b[0] = ac;
|
|
b[1] = 0;
|
|
as = b;
|
|
break;
|
|
case 's':
|
|
as = va_arg(args, char *);
|
|
break;
|
|
case 'd':
|
|
if (longint)
|
|
ad = (int64_t)va_arg(args, int64_t);
|
|
else
|
|
ad = (int)va_arg(args, int);
|
|
convert_itod(b, ad);
|
|
as = b;
|
|
break;
|
|
case 'x':
|
|
if (longint)
|
|
ax = (uint64_t)va_arg(args, uint64_t);
|
|
else
|
|
ax = (unsigned int)va_arg(args, unsigned int);
|
|
convert_itox(b, ax);
|
|
as = b;
|
|
break;
|
|
case 'X':
|
|
if (longint)
|
|
ax = (uint64_t)va_arg(args, uint64_t);
|
|
else
|
|
ax = (unsigned int)va_arg(args, unsigned int);
|
|
convert_itox(b, ax);
|
|
for (i = 0; i < (int)strlen(b); i++)
|
|
b[i] = toupper(b[i]);
|
|
as = b;
|
|
break;
|
|
case 'p':
|
|
ax = (uint64_t)va_arg(args, void *);
|
|
convert_itox(b, ax);
|
|
as = b;
|
|
break;
|
|
#if !EFIEBC
|
|
case 'f':
|
|
af = (double)va_arg(args, double);
|
|
for (i = 0, ax = 1; i < maxw; i++, ax *= 10);
|
|
ad = (int64_t)(af * ax + 0.5);
|
|
convert_itod(b, ad);
|
|
if (maxw)
|
|
{
|
|
len = (int)strlen(b);
|
|
if (len < maxw + 1)
|
|
{
|
|
for (i = maxw + 1; i > maxw - len; i--)
|
|
b[i] = b[i-maxw-1+len];
|
|
for (i = 0; i < maxw + 1 - len; i++)
|
|
b[i] = '0';
|
|
len = maxw + 1;
|
|
}
|
|
for (i = len + 1; i > len - maxw; i--)
|
|
b[i] = b[i-1];
|
|
b[i] = '.';
|
|
}
|
|
as = b;
|
|
maxw = 100;
|
|
break;
|
|
#endif
|
|
default:
|
|
s[n++] = c;
|
|
as = NULL;
|
|
minw = 0;
|
|
break;
|
|
}
|
|
if (minw)
|
|
{
|
|
len = (int)strlen(as);
|
|
if (as != b)
|
|
{
|
|
if (len > maxw)
|
|
len = maxw;
|
|
}
|
|
w = minw - len;
|
|
if (!left && w > 0)
|
|
{
|
|
memset(s + n, pad, w);
|
|
n += w;
|
|
}
|
|
memcpy(s + n, as, len);
|
|
n += len;
|
|
if (left && w > 0)
|
|
{
|
|
memset(s + n, pad, w);
|
|
n += w;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
s[n++] = c;
|
|
}
|
|
if (c == '\n' && !s1)
|
|
{
|
|
s[n] = 0;
|
|
t += n;
|
|
|
|
if (n)
|
|
APrint("%a", s);
|
|
|
|
n = 0;
|
|
}
|
|
}
|
|
|
|
s[n] = 0;
|
|
t += n;
|
|
|
|
if (n && !s1)
|
|
APrint("%a", s);
|
|
|
|
return n;
|
|
}
|
|
|
|
#if sfs
|
|
int printf(const char *format, ...)
|
|
{
|
|
va_list args;
|
|
int n;
|
|
|
|
va_start(args, format);
|
|
|
|
n = vsprintf(NULL, format, args);
|
|
|
|
va_end(args);
|
|
|
|
return n;
|
|
}
|
|
#endif
|
|
|
|
int sprintf(char *s, const char *format, ...)
|
|
{
|
|
va_list args;
|
|
int n;
|
|
|
|
va_start(args, format);
|
|
|
|
n = vsprintf(s, format, args);
|
|
|
|
va_end(args);
|
|
|
|
return n;
|
|
}
|
|
|
|
#define MAX_HANDLES 32
|
|
|
|
EFI_FILE_HANDLE gFileHandles[MAX_HANDLES];
|
|
|
|
FILE *fopen(const char *name, const char *mode)
|
|
{
|
|
int flags;
|
|
int fd;
|
|
|
|
if (strchr(mode, 'r'))
|
|
flags = O_RDONLY;
|
|
else if (strchr(mode, 'w'))
|
|
flags = O_RDWR | O_CREAT | O_TRUNC;
|
|
else if (strchr(mode, 'a'))
|
|
flags = O_RDWR | O_CREAT;
|
|
|
|
fd = open(name, flags);
|
|
if (fd < 0)
|
|
return NULL;
|
|
|
|
return (FILE *)fd;
|
|
}
|
|
|
|
int fclose(FILE *stream)
|
|
{
|
|
return close((int)stream);
|
|
}
|
|
|
|
#if sfs
|
|
int fprintf(FILE *stream, const char *format, ...)
|
|
{
|
|
va_list args;
|
|
char *s;
|
|
char s2[256];
|
|
int n;
|
|
|
|
if (stream == stdout || stream == stderr)
|
|
s = NULL;
|
|
else
|
|
s = s2;
|
|
|
|
va_start(args, format);
|
|
|
|
n = vsprintf(s, format, args);
|
|
|
|
va_end(args);
|
|
|
|
if (s)
|
|
n = write((int)stream, s, n);
|
|
|
|
return n;
|
|
}
|
|
#endif
|
|
|
|
int fflush(FILE *stream)
|
|
{
|
|
EFI_FILE_HANDLE file;
|
|
EFI_STATUS status;
|
|
int fd = (int)stream;
|
|
|
|
if (fd < 4)
|
|
return -1;
|
|
fd -= 4;
|
|
if (fd > MAX_HANDLES)
|
|
return -1;
|
|
|
|
file = gFileHandles[fd];
|
|
if (!file)
|
|
return -1;
|
|
|
|
status = file->Flush(file);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
printf("Flush failed!\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int fputs(const char *s, FILE *stream)
|
|
{
|
|
int n;
|
|
|
|
n = (int)strlen(s);
|
|
if (stream == stdout || stream == stderr)
|
|
APrint("%a", s);
|
|
else
|
|
write((int)stream, s, n);
|
|
|
|
return n;
|
|
}
|
|
|
|
int fputc(int c, FILE *stream)
|
|
{
|
|
if (stream == stdout || stream == stderr)
|
|
APrint("%c", (UINTN)c);
|
|
else
|
|
write((int)stream, (void *)&c, 1);
|
|
|
|
return 1;
|
|
}
|
|
|
|
int open(const char *name, int flags, ...)
|
|
{
|
|
EFI_FILE_IO_INTERFACE *fileIo;
|
|
EFI_FILE_HANDLE root;
|
|
EFI_FILE_HANDLE file;
|
|
EFI_FILE_INFO *info;
|
|
EFI_GUID SimpleFileSystemProtocol = SIMPLE_FILE_SYSTEM_PROTOCOL;
|
|
EFI_STATUS status;
|
|
CHAR16 *path;
|
|
CHAR16 filename[128];
|
|
UINTN i;
|
|
UINT64 mode;
|
|
int fd;
|
|
|
|
for (fd = 0; fd < MAX_HANDLES; fd++)
|
|
if (!gFileHandles[fd])
|
|
break;
|
|
if (fd == MAX_HANDLES)
|
|
return -1;
|
|
|
|
if (*name == '.' || (isalnum(*name) && !strchr(name, ':')))
|
|
{
|
|
path = DevicePathToStr(gLoadedImage->FilePath);
|
|
|
|
// APrint("loaded image = <%s>\n", path);
|
|
|
|
for (i = StrLen(path) - 1; i > 0; i--)
|
|
if (path[i] == L'/')
|
|
break;
|
|
// if the path contains "/." at the end, remove it
|
|
if (i >= 2 && path[i-2] == '/' && path[i-1] == '.')
|
|
i -= 2;
|
|
// if the path doesn't end with "\", add one
|
|
if (!(i >= 1 && path[i-1] == '\\'))
|
|
path[i++] = '\\';
|
|
// throw away the rest of the string
|
|
path[i] = 0;
|
|
StrCpy(filename, path);
|
|
|
|
FreePool(path);
|
|
} else
|
|
filename[0] = 0;
|
|
|
|
for (i = StrLen(filename); *name; i++)
|
|
filename[i] = (CHAR16)*name++;
|
|
filename[i] = 0;
|
|
|
|
// APrint("filename = <%s>\n", filename);
|
|
|
|
status = BS->HandleProtocol(gLoadedImage->DeviceHandle,
|
|
&SimpleFileSystemProtocol, &fileIo);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
printf("HandleProtocol(SimpleFileSystem) failed!\n");
|
|
return -1;
|
|
}
|
|
|
|
status = fileIo->OpenVolume(fileIo, &root);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
printf("OpenVolume failed!\n");
|
|
return -1;
|
|
}
|
|
|
|
mode = EFI_FILE_MODE_READ;
|
|
if (flags & O_RDWR)
|
|
mode |= EFI_FILE_MODE_WRITE;
|
|
if (flags & O_CREAT)
|
|
mode |= EFI_FILE_MODE_CREATE;
|
|
|
|
status = root->Open(root, &file, filename, mode, 0);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
APrint("Open of <%s> failed!\n", filename);
|
|
return -1;
|
|
}
|
|
|
|
if (flags & O_CREAT)
|
|
{
|
|
info = LibFileInfo(file);
|
|
if (info)
|
|
{
|
|
if (flags & O_TRUNC)
|
|
{
|
|
info->FileSize = 0;
|
|
info->PhysicalSize = 0;
|
|
status = file->SetInfo(file, &GenericFileInfo, (UINTN)info->Size, info);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
APrint("SetInfo of <%s> failed!\n", filename);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
status = file->SetPosition(file, info->FileSize);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
APrint("SetPosition of <%s> failed!\n", filename);
|
|
}
|
|
}
|
|
|
|
FreePool(info);
|
|
}
|
|
}
|
|
|
|
gFileHandles[fd] = file;
|
|
|
|
fd += 4;
|
|
|
|
return fd;
|
|
}
|
|
|
|
int close(int fd)
|
|
{
|
|
EFI_FILE_HANDLE file;
|
|
EFI_STATUS status;
|
|
|
|
if (fd < 4)
|
|
return -1;
|
|
fd -= 4;
|
|
if (fd > MAX_HANDLES)
|
|
return -1;
|
|
|
|
file = gFileHandles[fd];
|
|
if (!file)
|
|
return -1;
|
|
|
|
status = file->Close(file);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
printf("Close failed!\n");
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
ssize_t read(int fd, void *buf, size_t count)
|
|
{
|
|
EFI_FILE_HANDLE file;
|
|
EFI_STATUS status;
|
|
UINTN size = count;
|
|
|
|
if (fd < 4)
|
|
return -1;
|
|
fd -= 4;
|
|
if (fd > MAX_HANDLES)
|
|
return -1;
|
|
|
|
file = gFileHandles[fd];
|
|
if (!file)
|
|
return -1;
|
|
|
|
status = file->Read(file, &size, buf);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
printf("Read failed!\n");
|
|
return -1;
|
|
}
|
|
|
|
return (ssize_t)size;
|
|
}
|
|
|
|
ssize_t write(int fd, const void *buf, size_t count)
|
|
{
|
|
EFI_FILE_HANDLE file;
|
|
EFI_STATUS status;
|
|
UINTN size = count;
|
|
|
|
if (fd < 4)
|
|
return -1;
|
|
fd -= 4;
|
|
if (fd > MAX_HANDLES)
|
|
return -1;
|
|
|
|
file = gFileHandles[fd];
|
|
if (!file)
|
|
return -1;
|
|
|
|
status = file->Write(file, &size, (void *)buf);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
printf("Write failed!\n");
|
|
return -1;
|
|
}
|
|
|
|
return (ssize_t)size;
|
|
}
|
|
|
|
int fstat(int fd, struct stat *buf)
|
|
{
|
|
EFI_FILE_HANDLE file;
|
|
EFI_FILE_INFO *info;
|
|
|
|
if (fd < 4)
|
|
return -1;
|
|
fd -= 4;
|
|
if (fd > MAX_HANDLES)
|
|
return -1;
|
|
|
|
file = gFileHandles[fd];
|
|
if (!file)
|
|
return -1;
|
|
|
|
info = LibFileInfo(file);
|
|
if (!info)
|
|
{
|
|
printf("GetInfo failed!\n");
|
|
return -1;
|
|
}
|
|
|
|
buf->st_size = (size_t)info->FileSize;
|
|
|
|
FreePool(info);
|
|
|
|
return 0;
|
|
}
|
|
|
|
static int rand_seed = 152L;
|
|
|
|
int rand(void)
|
|
{
|
|
rand_seed = rand_seed * 69069L + 1;
|
|
|
|
return ((rand_seed >> 16) + (rand_seed << 16));
|
|
}
|
|
|
|
void perror(const char *s)
|
|
{
|
|
if (s && *s)
|
|
APrint("%a: ", s);
|
|
APrint("%r\n", last_efi_status);
|
|
}
|
|
|
|
static int dpm[] = {
|
|
0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
|
|
};
|
|
|
|
#ifndef DISABLE_TIMEOUTS
|
|
time_t time(time_t *t)
|
|
{
|
|
EFI_TIME et;
|
|
time_t local_t;
|
|
int days;
|
|
|
|
RT->GetTime(&et, NULL);
|
|
|
|
days = dpm[et.Month - 1] + et.Day - 1;
|
|
|
|
if (et.Year >= 1970)
|
|
{
|
|
days += (et.Year - 1970) * 365;
|
|
|
|
// all modulo-4 years since 1970 are leap years, up until 2100
|
|
days += (et.Year - 1969) / 4;
|
|
}
|
|
|
|
local_t = ((days * 24 + et.Hour) * 60 + et.Minute) * 60 + et.Second;
|
|
if (t)
|
|
*t = local_t;
|
|
|
|
return local_t;
|
|
}
|
|
#endif
|
|
|
|
static const char *day_name[] = {
|
|
"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
|
|
};
|
|
|
|
static const char *mon_name[] = {
|
|
"Mar", "Apr", "May", "Jun", "Jul", "Aug",
|
|
"Sep", "Oct", "Nov", "Dec", "Jan", "Feb"
|
|
};
|
|
|
|
static const int days_per[12] = {
|
|
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
|
|
};
|
|
|
|
static char ctime_result[26];
|
|
|
|
char *ctime(const time_t *seconds)
|
|
{
|
|
int f, k, m, D, C, d; // going to use Zeller's Rule to derive the weekday
|
|
int days, leap, year, month, day, hours, mins, secs, t;
|
|
|
|
days = *seconds / 86400;
|
|
t = days;
|
|
year = 1970;
|
|
// if it's already past 2004, get that out of the way quick
|
|
if (t >= 12418)
|
|
{
|
|
t -= 12418;
|
|
year += 34;
|
|
}
|
|
for (; ; year++)
|
|
{
|
|
// this simple rule is good until 2100
|
|
leap = (year % 4) == 0;
|
|
if (t < 365 + leap)
|
|
break;
|
|
t -= 365 + leap;
|
|
}
|
|
month = 0;
|
|
// if it's already past June, get that out of the way quick
|
|
if (t >= 181 + leap)
|
|
{
|
|
t -= 181 + leap;
|
|
month += 6;
|
|
}
|
|
for (; ; month++)
|
|
{
|
|
if (t < days_per[month])
|
|
break;
|
|
t -= days_per[month];
|
|
if (month == 1)
|
|
{
|
|
if (t < leap)
|
|
break;
|
|
t -= leap;
|
|
}
|
|
}
|
|
day = t + 1;
|
|
t = *seconds - days * 86400;
|
|
hours = t / 3600;
|
|
t -= hours * 3600;
|
|
mins = t / 60;
|
|
t -= mins * 60;
|
|
secs = t;
|
|
|
|
k = day;
|
|
m = month - 1;
|
|
D = year % 100;
|
|
C = year / 100;
|
|
|
|
if (m < 1)
|
|
{
|
|
m += 12;
|
|
D -= 1;
|
|
}
|
|
|
|
f = k + (13*m-1)/5 + D + D/4 + C/4 - 2*C;
|
|
|
|
d = f % 7;
|
|
if (d < 0)
|
|
d += 7;
|
|
|
|
sprintf(ctime_result, "%.3s %.3s%3d %02d:%02d:%02d %d\n",
|
|
day_name[d], mon_name[m-1],
|
|
day, hours, mins, secs, year);
|
|
|
|
return ctime_result;
|
|
}
|
|
|
|
VOID EfiMain(EFI_HANDLE ImageHandle, EFI_SYSTEM_TABLE *SystemTable)
|
|
{
|
|
EFI_TIME et;
|
|
EFI_STATUS status;
|
|
int i;
|
|
int argc;
|
|
char **argv;
|
|
int n;
|
|
|
|
InitializeShellApplication(ImageHandle, SystemTable);
|
|
|
|
gImageHandle = ImageHandle;
|
|
|
|
status = BS->HandleProtocol(gImageHandle, &LoadedImageProtocol, &gLoadedImage);
|
|
if (EFI_ERROR(status))
|
|
{
|
|
last_efi_status = status;
|
|
printf("HandleProtocol(LoadedImage) failed!\n");
|
|
gLoadedImage = NULL;
|
|
}
|
|
|
|
status = BS->CreateEvent(EVT_TIMER, 0, NULL, NULL, &gSleepEvent);
|
|
if (EFI_ERROR(status))
|
|
gSleepEvent = NULL;
|
|
|
|
RT->GetTime(&et, NULL);
|
|
if (et.Year % 4 == 0 && et.Year % 100 != 0 && et.Year % 400 == 0)
|
|
dpm[3]++;
|
|
|
|
argc = (int)SI->Argc;
|
|
argv = malloc(sizeof argv * argc);
|
|
|
|
for (i = 0; i < argc; i++)
|
|
{
|
|
n = (int)StrLen(SI->Argv[i]) + 1;
|
|
argv[i] = malloc(n);
|
|
convert_unicode_ascii(SI->Argv[i], argv[i], n);
|
|
}
|
|
|
|
main(argc, argv);
|
|
}
|
|
|
|
void exit(int status)
|
|
{
|
|
if (gSleepEvent)
|
|
BS->CloseEvent(gSleepEvent);
|
|
|
|
if (status == 0)
|
|
BS->Exit(gImageHandle, EFI_SUCCESS, 0, NULL);
|
|
else
|
|
BS->Exit(gImageHandle, EFIERR_OEM(status), 0, NULL);
|
|
}
|
|
|
|
unsigned int sleep(unsigned int seconds)
|
|
{
|
|
UINTN unused;
|
|
|
|
if (gSleepEvent)
|
|
{
|
|
BS->SetTimer(gSleepEvent, TimerRelative, seconds * 10000000);
|
|
BS->WaitForEvent(1, &gSleepEvent, &unused);
|
|
}
|
|
else
|
|
{
|
|
BS->Stall(seconds * 1000000);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void mdelay(int milliseconds)
|
|
{
|
|
BS->Stall(milliseconds * 1000);
|
|
}
|
|
|
|
void udelay(int microseconds)
|
|
{
|
|
BS->Stall(microseconds);
|
|
}
|
|
|
|
int _fltused;
|
|
|
|
#include "getopt.c"
|
|
|
|
/* vi: set sw=4 ts=4 sts=4 et :iv */
|