blob: ea90bbb05621bcfe05a8d0a34cb00dfe8322d3fb [file] [log] [blame]
/*
* libkmod - interface to kernel module operations
*
* Copyright (C) 2011-2013 ProFUSION embedded systems
* Copyright (C) 2012 Lucas De Marchi <lucas.de.marchi@gmail.com>
* Copyright (C) 2013 Intel Corporation. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
#include <stdarg.h>
#include <unistd.h>
#include <string.h>
#include <ctype.h>
#include <shared/util.h>
#include "libkmod.h"
#include "libkmod-internal.h"
const struct kmod_ext kmod_exts[] = {
{".ko", sizeof(".ko") - 1},
#ifdef ENABLE_ZLIB
{".ko.gz", sizeof(".ko.gz") - 1},
#endif
#ifdef ENABLE_XZ
{".ko.xz", sizeof(".ko.xz") - 1},
#endif
{ }
};
inline int alias_normalize(const char *alias, char buf[PATH_MAX], size_t *len)
{
size_t s;
for (s = 0; s < PATH_MAX - 1; s++) {
const char c = alias[s];
switch (c) {
case '-':
buf[s] = '_';
break;
case ']':
return -EINVAL;
case '[':
while (alias[s] != ']' && alias[s] != '\0') {
buf[s] = alias[s];
s++;
}
if (alias[s] != ']')
return -EINVAL;
buf[s] = alias[s];
break;
case '\0':
goto finish;
default:
buf[s] = c;
}
}
finish:
buf[s] = '\0';
if (len)
*len = s;
return 0;
}
inline char *modname_normalize(const char *modname, char buf[PATH_MAX],
size_t *len)
{
size_t s;
for (s = 0; s < PATH_MAX - 1; s++) {
const char c = modname[s];
if (c == '-')
buf[s] = '_';
else if (c == '\0' || c == '.')
break;
else
buf[s] = c;
}
buf[s] = '\0';
if (len)
*len = s;
return buf;
}
char *path_to_modname(const char *path, char buf[PATH_MAX], size_t *len)
{
char *modname;
modname = basename(path);
if (modname == NULL || modname[0] == '\0')
return NULL;
return modname_normalize(modname, buf, len);
}
bool path_ends_with_kmod_ext(const char *path, size_t len)
{
const struct kmod_ext *eitr;
for (eitr = kmod_exts; eitr->ext != NULL; eitr++) {
if (len <= eitr->len)
continue;
if (streq(path + len - eitr->len, eitr->ext))
return true;
}
return false;
}