dvnixload/src/cmd.c

223 lines
4.8 KiB
C

/*
* cmd.h -- external commands definitions.
*
* Copyright (C) 2008 Hugo Villeneuve <hugo@hugovil.com>
*
* This program 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 2 of the License, or
* (at your option) any later version.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h> /* Standard input/output definitions */
#include <string.h> /* String function definitions */
#include <unistd.h> /* UNIX standard function definitions */
#include <fcntl.h> /* File control definitions */
#include <assert.h>
#include <sys/time.h>
#include <sys/wait.h>
#include "common.h"
#include "options.h"
#include "serial.h"
#define MAX_LINES 1000
#define MAX_CHARS 1024
#define MAX_TXT 25600
/*
* This function executes a piped command and capture its output (stdout).
*
* exe_str: string of the command to execute
* buffer: array where each line is stored
* lineptr: array-of-pointers where each element of the array points to the
* beginning of each line stored in buffer.
*
* returns the number of lines read into buffer, cnt.
*/
int run_popen(char *lineptr[], char *buffer, char *exe_str)
{
int i;
int cnt = 0;
FILE *ptr;
char *bufstart;
char *bufend;
char line[MAX_TXT];
bufstart = buffer; /* Mark start of available space */
bufend = buffer + MAX_CHARS; /* Mark end of available space */
ptr = popen(exe_str, "r");
if (ptr == NULL) {
log_fail("Couldn't open pipe");
exit(1);
}
for (i = 0; i < MAX_LINES; i++) {
if (fgets(line, MAX_TXT, ptr) == NULL)
break;
line[strlen(line) - 1] = '\0'; /* No new-lines */
if ((bufstart + strlen(line) + 1) >= bufend) {
log_fail("Line too long");
exit(1);
}
lineptr[i] = bufstart; /* Save the address of the line */
strcpy(bufstart, line); /* Save the line into buffer */
bufstart += strlen(line) + 1; /* Update starting pointer */
cnt++;
}
fclose(ptr);
return cnt;
}
/* Return values:
* 0: no error
* > 0: error(s)
*/
int run_cmd_get_string(char *cmd, char *output, ssize_t size)
{
int count;
char *slines[MAX_LINES];
char sbuf[MAX_CHARS];
log_debug2("run_cmd_get_string()\n");
log_debug2(" CMD = \"%s\"\n", cmd);
count = run_popen(slines, sbuf, cmd);
log_debug2(" OUTPUT count is %d\n", count);
if (count != 1) {
log_fail("Entry point not found");
return 1;
}
strncpy(output, slines[0], size);
/* Add the null-terminating character just in case 'src' is larger
* than 'dest'. */
output[size - 1] = '\0';
return 0;
}
int copy_file(const char *src, const char *dst)
{
int count;
char cmd[MAX_CMD_LENGTH];
char *slines[MAX_LINES];
char sbuf[MAX_CHARS];
int k;
sprintf(cmd, "cp %s %s 2>&1", src, dst);
count = run_popen(slines, sbuf, cmd);
log_debug2("count is %d\n", count);
for (k = 0; k < count; k++)
log_debug2("[%s]\n", slines[k]);
if (count != 0) {
log_fail("Error copying file");
return 1;
}
return 0;
}
int remove_file(const char *filename)
{
int count;
char cmd[MAX_CMD_LENGTH];
char *slines[MAX_LINES];
char sbuf[MAX_CHARS];
int k;
sprintf(cmd, "rm %s 2>&1", filename);
count = run_popen(slines, sbuf, cmd);
log_debug2("count is %d\n", count);
for (k = 0; k < count; k++)
log_debug2("[%s]\n", slines[k]);
if (count != 0) {
log_fail("Error removing file %s", filename);
return 1;
}
return 0;
}
static int
test_file_presence(const char *filename)
{
char cmd[MAX_CMD_LENGTH];
sprintf(cmd, "test -f %s", filename);
log_debug1("Running command: %s", cmd);
return system(cmd);
}
static int
test_file_elf(const char *filename)
{
char cmd[MAX_CMD_LENGTH];
sprintf(cmd, "file %s | grep ELF 1> /dev/null 2>&1", filename);
log_debug1("Running command: %s", cmd);
return system(cmd);
}
int
check_source_files(int app_elf_format, const char *ubl, const char *app)
{
int ret;
ret = test_file_presence(ubl);
if (ret) {
log_fail("UBL file \"%s\" not found", ubl);
return ret;
}
ret = test_file_elf(ubl);
if (ret) {
log_fail("UBL file \"%s\" not in ELF format", ubl);
return ret;
}
ret = test_file_presence(app);
if (ret) {
log_fail("Application file \"%s\" not found", app);
return ret;
}
if (app_elf_format) {
ret = test_file_elf(app);
if (ret) {
log_fail("Application file \"%s\" not in ELF format",
app);
return ret;
}
}
return 0;
}