chrome-ec/util/misc_util.c

176 lines
3.2 KiB
C

/* Copyright 2013 The Chromium OS Authors. All rights reserved.
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <ctype.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/utsname.h>
#include "comm-host.h"
#include "misc_util.h"
int write_file(const char *filename, const char *buf, int size)
{
FILE *f;
int i;
/* Write to file */
f = fopen(filename, "wb");
if (!f) {
perror("Error opening output file");
return -1;
}
i = fwrite(buf, 1, size, f);
fclose(f);
if (i != size) {
perror("Error writing to file");
return -1;
}
return 0;
}
char *read_file(const char *filename, int *size)
{
FILE *f = fopen(filename, "rb");
char *buf;
int i;
if (!f) {
perror("Error opening input file");
return NULL;
}
fseek(f, 0, SEEK_END);
*size = ftell(f);
rewind(f);
if ((*size > 0x100000) || (*size < 0)) {
if (*size < 0)
perror("ftell failed");
else
fprintf(stderr, "File seems unreasonably large\n");
fclose(f);
return NULL;
}
buf = (char *)malloc(*size);
if (!buf) {
fprintf(stderr, "Unable to allocate buffer.\n");
fclose(f);
return NULL;
}
printf("Reading %d bytes from %s...\n", *size, filename);
i = fread(buf, 1, *size, f);
fclose(f);
if (i != *size) {
perror("Error reading file");
free(buf);
return NULL;
}
return buf;
}
int is_string_printable(const char *buf)
{
while (*buf) {
if (!isprint(*buf))
return 0;
buf++;
}
return 1;
}
/**
* Get the versions of the command supported by the EC.
*
* @param cmd Command
* @param pmask Destination for version mask; will be set to 0 on
* error.
* @return 0 if success, <0 if error
*/
int ec_get_cmd_versions(int cmd, uint32_t *pmask)
{
struct ec_params_get_cmd_versions_v1 pver_v1;
struct ec_params_get_cmd_versions pver;
struct ec_response_get_cmd_versions rver;
int rv;
*pmask = 0;
pver_v1.cmd = cmd;
rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 1, &pver_v1, sizeof(pver_v1),
&rver, sizeof(rver));
if (rv < 0) {
pver.cmd = cmd;
rv = ec_command(EC_CMD_GET_CMD_VERSIONS, 0, &pver, sizeof(pver),
&rver, sizeof(rver));
}
if (rv < 0)
return rv;
*pmask = rver.version_mask;
return 0;
}
/**
* Return non-zero if the EC supports the command and version
*
* @param cmd Command to check
* @param ver Version to check
* @return non-zero if command version supported; 0 if not.
*/
int ec_cmd_version_supported(int cmd, int ver)
{
uint32_t mask = 0;
if (ec_get_cmd_versions(cmd, &mask))
return 0;
return (mask & EC_VER_MASK(ver)) ? 1 : 0;
}
/**
* Return 1 is the current kernel version is greater or equal to
* <major>.<minor>.<sublevel>
*/
int kernel_version_ge(int major, int minor, int sublevel)
{
struct utsname uts;
int atoms, kmajor, kminor, ksublevel;
if (uname(&uts) < 0)
return -1;
atoms = sscanf(uts.release, "%d.%d.%d", &kmajor, &kminor, &ksublevel);
if (atoms < 1)
return -1;
if (kmajor > major)
return 1;
if (kmajor < major)
return 0;
/* kmajor == major */
if (atoms < 2)
return 0 == minor && 0 == sublevel;
if (kminor > minor)
return 1;
if (kminor < minor)
return 0;
/* kminor == minor */
if (atoms < 3)
return 0 == sublevel;
return ksublevel >= sublevel;
}