#include <libintl.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "librsc.h"
#include "adm.h"
int
ADM_Send_file(FILE *FilePtr)
{
static char ADM_Line[ADM_LINE_SIZE];
static bp_msg_t Message;
static struct timespec Timeout;
int LinesWritten;
int Status;
int BootRetry;
int LastRecord;
long FileLength = 0L;
long FilePos;
if (fseek(FilePtr, 0L, SEEK_END) == 0) {
FileLength = ftell(FilePtr);
rewind(FilePtr);
}
LinesWritten = 0;
LastRecord = 0;
while ((fgets(ADM_Line, ADM_LINE_SIZE, FilePtr) != NULL) &&
(LastRecord == 0)) {
if ((ADM_Line[0] == 'S') &&
((ADM_Line[1] == '7') || (ADM_Line[1] == '8') ||
(ADM_Line[1] == '9'))) {
LastRecord = 1;
}
BootRetry = ADM_BOOT_RETRY;
while (BootRetry > 0) {
if ((Status =
rsc_raw_write(ADM_Line, strlen(ADM_Line))) != 0) {
return (Status);
}
Timeout.tv_nsec = 0;
Timeout.tv_sec = ADM_BOOT_LOAD_TIMEOUT;
if ((Status = ADM_Boot_recv(&Message, &Timeout)) != 0) {
BootRetry = BootRetry - 1;
continue;
} else {
if ((Message.cmd == BP_RSC_BOOTOK) &&
(Message.dat1 == 0) &&
(Message.dat2 == 0)) {
LastRecord = 1;
break;
}
if ((Message.cmd != BP_RSC_BOOTACK) ||
(Message.dat1 != BP_DAT1_SRECORD_ACK)) {
if (Message.dat1 ==
BP_DAT1_SRECORD_NAK) {
continue;
}
ADM_Display_download_error(
(int)Message.cmd,
(int)Message.dat1);
exit(-1);
}
break;
}
}
if (BootRetry <= 0) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: SC failed to respond during "
"download"));
exit(-1);
}
LinesWritten++;
if ((LinesWritten % 100) == 0) {
(void) printf(".");
(void) fflush(stdout);
}
if ((LinesWritten % 4000) == 0) {
if (FileLength) {
FilePos = ftell(FilePtr);
(void) printf(" (%ld%%)",
(FilePos * 100) / FileLength);
}
(void) printf("\n");
(void) fflush(stdout);
}
}
if ((FileLength) && ((LinesWritten % 4000) != 0)) {
FilePos = ftell(FilePtr);
(void) printf(" (%ld%%)",
(FilePos * 100) / FileLength);
}
(void) printf("\n");
return (0);
}
void
ADM_Display_download_error(int cmd, int dat1)
{
if (cmd == BP_RSC_BOOTFAIL) {
if (dat1 == BP_DAT1_REJECTED) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download rejected"));
} else if (dat1 == BP_DAT1_RANGE_ERR) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download failed, "
"SC reported range error"));
} else if (dat1 == BP_DAT1_VERIFY_ERR) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download failed, "
"SC reported verify error"));
} else if (dat1 == BP_DAT1_ERASE_ERR) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download failed, "
"SC reported erase error"));
} else if (dat1 == BP_DAT1_INT_WP_ERR) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download failed, "
"SC reported int_wp error"));
} else if (dat1 == BP_DAT1_WP_ERR) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download failed, "
"SC reported wp error"));
} else if (dat1 == BP_DAT1_VPP_ERR) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download failed, "
"SC reported vpp error"));
} else {
(void) fprintf(stderr, "%s 0x%08x\n",
gettext("scadm: SC returned fatal error"), dat1);
}
} else if (cmd == BP_RSC_BOOTACK) {
if (dat1 == BP_DAT1_SRECORD_ACK) {
(void) fprintf(stderr, "\n%s\n\n",
gettext("scadm: download failed"));
} else {
(void) fprintf(stderr, "%s 0x%08x\n",
gettext("scadm: SC returned fatal error"), dat1);
}
} else {
(void) fprintf(stderr, "%s 0x%08x:0x%08x\n",
gettext("scadm: SC returned unknown error"), cmd, dat1);
}
}