Skip to content
Snippets Groups Projects
auxiliary.c 4.68 KiB
Newer Older
/**
 * Use a fifo to signal that we want to stop the api server.
 */
void stop_server()
{
    printf("Stopping cryptops-api server...\n");
    int fifo;
    char fifo_path[] = FIFO_PATH;
    fifo = open(fifo_path, O_WRONLY);
    char * msg = "stop";
    write(fifo, msg, strlen(msg) + 1);
}

Maarten de Waard's avatar
Maarten de Waard committed
/**
 * Read the contents of an already opened file into a string
 * @param   file    The file as opened by fopen with "rb"
 * @return          Contents of the file
 */
char * read_from_file(FILE * file)
{
    char buf[100];
    char *str = NULL;
    char *temp = NULL;
    unsigned int size = 1;  // start with size of 1 to make room for null terminator
    unsigned int strlength;
    if (file)
    {
        while (fgets(buf, sizeof(buf), file) != NULL) {
            strlength = strlen(buf);
            temp = realloc(str, size + strlength);  // allocate room for the buf that gets appended
            if (temp == NULL) {
                // allocation error
            } else {
                str = temp;
            }
            strcpy(str + size - 1, buf);     // append buffer to str
            size += strlength; 
        }
        pclose(file);
    }
    return str;
}

/**
 * Read a file completely into a string.
 * @param  filename Path to the file to read.
 * @return          Contents of the file.
 */
char * read_file(const char * filename)
{
    if (filename != NULL)
    {
        FILE * file = fopen(filename, "rb");
        return read_from_file(file);
/**
 * Respond to the request with a simple json structure '{$field: $value}'.
 * @param  response    response struct to use
 * @param  http_status HTTP status code to return
 * @param  field       name of the json field to return
 * @param  value       json value to return
int send_simple_response(struct _u_response * response, int http_status,
    const char * field, const char * value)
{
    json_t * json_body = NULL;
    json_body = json_object();
    json_object_set_new(json_body, field, json_string(value));
    ulfius_set_json_body_response(response, http_status, json_body);
    json_decref(json_body);
    return U_CALLBACK_CONTINUE;
}

/**
 * Determine the size of a block device.
 * @param  device_path Path to the block device.
 * @return             Size of the device in bytes.
 */
unsigned long device_size(char * device_path)
{
    int fd;
    unsigned long numblocks = 0;

    fd = open(device_path, O_RDONLY);
    ioctl(fd, BLKGETSIZE, &numblocks);
    close(fd);
    printf("Number of blocks: %lu, this makes %.3f GB\n",
        numblocks, (double)numblocks * 512.0 / (1024 * 1024 * 1024));
    return (numblocks * 512);
}

/**
 * Determine available memory.
 * @return Available memory in bytes.
 */
unsigned long available_memory()
{
  struct sysinfo myinfo;
  unsigned long free_bytes;
  sysinfo(&myinfo);
  free_bytes = myinfo.mem_unit * myinfo.freeram;
  printf("Free memory: %lu B, %lu MB\n",
      free_bytes, free_bytes / 1024 / 1024);
  return free_bytes;
}

/**
 * Determine the usage of the given filesystem.
 * @param  path Path of the mounted filesystem.
 * @return      Number of bytes used, or -1 in case of failure.
 */
unsigned long filesystem_usage(const char * path)
{
    struct statvfs s;
    int r = statvfs(path, &s);
    if (r != 0)
    {
        return -1;
    }
    return (s.f_blocks - s.f_bfree) * s.f_bsize;
}

/**
 * Mount a filesystem; create the mount target if it doesn't exist.
 * @param  device_path Path to the device to mount.
 * @param  mount_path  Path to the mount target.
 * @return             Status code.
 */
int temporary_mount(char * device_path, char * mount_path,
    char * filesystem_type)
{
    struct stat st = {0};
    if (stat(mount_path, &st) == -1)
    {
        mkdir(mount_path, 0700);
    }
    // Mount the device.
    unsigned long mount_flags = MS_NOATIME | MS_NODEV | MS_NOEXEC;
    int r = mount(device_path, mount_path, filesystem_type,
        mount_flags, "");
    return r;
}
Arie Peterson's avatar
Arie Peterson committed
/**
 * Reboot the system. We cannot simply use the `reboot` command because
 * we're running as init (pid 0).
 */
void reboot_initrd()
{
    pid_t pid;
    pid = vfork();
    if (pid == 0)
    {
        // Child.
Arie Peterson's avatar
Arie Peterson committed
        reboot(RB_AUTOBOOT);
        _exit(EXIT_SUCCESS);
    }
    // Parent (init) waits.
    while (1);
}

/**
 * Parse an integer written in decimal.
 * @param[in]  input  String to parse.
 * @param[out] result Resulting integer, or NULL on failure.
 * @return            Return code: 0 on success, nonzero on failure.
 */
int parse_int(const char * input, int * result)
{
    if (input[0] == '\0' || isspace((unsigned char) input[0]))
    {
        return -1;
    }
    char * end;
    long l = strtol(input, &end, 10);
    if (*end != '\0')
    {
        return -1;
    }
    *result = l;
    return 0;
}