Kaydet (Commit) e7c5911d authored tarafından Ozan Çağlayan's avatar Ozan Çağlayan

Move coolplug to its own directory

üst 39b4b0de
CC= klcc
EXE= coolplug
OBJS= main.c utility.c module.c scsi.c devnode.c
INCLUDES= common.h
CFLAGS= -Os -Wall
LDFLAGS=
$(EXE): $(OBJS) $(INCLUDES)
$(CC) $(CFLAGS) $(LDFLAGS) -o $(EXE) $(OBJS)
strip -s --remove-section=.note --remove-section=.comment $(EXE)
clean:
rm -f $(EXE)
/*
** Copyright (c) 2006, TUBITAK/UEKAE
**
** 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. Please read the COPYING file.
*/
#include <stddef.h>
#include <string.h>
extern int cfg_debug;
struct list {
struct list *next;
char *data;
};
int list_has(struct list *listptr, const char *data);
struct list *list_add(struct list *listptr, const char *data);
void *zalloc(size_t size);
char *concat(const char *str, const char *append);
int fnmatch(const char *p, const char *s);
char *my_readlink(const char *path);
char *sys_value(const char *path, const char *value);
struct list *module_get_list(const char *syspath);
int module_probe(const char *name);
struct list *scsi_get_list(void);
int devnode_mknod(const char *name, const char *major, const char *minor);
int devnode_populate(void);
/*
** Copyright (c) 2006-2007, TUBITAK/UEKAE
**
** 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. Please read the COPYING file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include "common.h"
static void
ensure_path(char *path)
{
struct stat fs;
char *t, *cur;
path = strdup(path);
cur = path;
if (path[0] == '/') ++cur;
while (1) {
t = strchr(cur, '/');
if (!t) break;
*t = '\0';
if (stat(path, &fs) != 0) {
mkdir(path, 0755);
}
*t = '/';
cur = t + 1;
}
}
int
devnode_mknod(const char *name, const char *major, const char *minor)
{
struct stat fs;
char buf[512];
char *path;
char *t;
path = concat("/dev/", name);
for (t=path; *t != '\0'; t++) {
if (*t == '!') *t = '/';
}
if (stat(path, &fs) == 0) {
if (cfg_debug) printf("exists: mknod %s b %s %s\n", path, major, minor);
} else {
sprintf(buf, "mknod %s b %s %s", path, major, minor);
if (cfg_debug)
puts(buf);
else {
ensure_path(path);
system(buf);
}
}
return 0;
}
static int
mknod_parts(char *dev)
{
char *path;
DIR *dir;
struct dirent *dirent;
char *tmp;
char *major;
char *minor;
path = concat("/sys/block/", dev);
dir = opendir(path);
if (!dir) return -1;
while((dirent = readdir(dir))) {
char *name = dirent->d_name;
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
continue;
if (strncmp(name, dev, strlen(dev)) != 0)
continue;
tmp = concat(concat(path, "/"), name);
tmp = sys_value(tmp, "dev");
major = strtok(tmp, ":");
minor = strtok(NULL, "");
if (minor) devnode_mknod(name, major, minor);
}
closedir(dir);
return 0;
}
int
devnode_populate(void)
{
DIR *dir;
struct dirent *dirent;
dir = opendir("/sys/block");
if (!dir) return -1;
while((dirent = readdir(dir))) {
char *path;
char *dev;
char *major;
char *minor;
char *name = dirent->d_name;
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
continue;
path = concat("/sys/block/", name);
dev = sys_value(path, "dev");
major = strtok(dev, ":");
minor = strtok(NULL, "");
if (minor) {
devnode_mknod(name, major, minor);
mknod_parts(name);
}
}
closedir(dir);
return 0;
}
/*
** Copyright (c) 2006, TUBITAK/UEKAE
**
** Coldplug program for initrd
** Unfortunately we cant use muavin.py there
**
** 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. Please read the COPYING file.
*/
#include <unistd.h>
#include "common.h"
int cfg_debug = 0;
int
main(int argc, char *argv[])
{
struct list *modules;
struct list *item;
int has_scsi_storage = 0;
if (argc == 2 && strcmp(argv[1], "--debug") == 0)
cfg_debug = 1;
// First, load PCI modules
modules = module_get_list("/sys/bus/pci/devices/");
for (item = modules; item; item = item->next)
module_probe(item->data);
// Second, load USB modules
modules = module_get_list("/sys/bus/usb/devices/");
if (list_has(modules, "usb_storage"))
has_scsi_storage = 1;
for (item = modules; item; item = item->next)
module_probe(item->data);
// Then, check if there is a need for scsi disk/cdrom drivers
// If these are on usb bus, they need some time to properly
// setup, so we wait a little bit.
if (has_scsi_storage) {
sleep(2);
}
modules = scsi_get_list();
for (item = modules; item; item = item->next)
module_probe(item->data);
// Populate /dev directory for probed disk/cdrom devices
// Again, wait a bit for devices to settle
if (has_scsi_storage) {
sleep(1);
}
devnode_populate();
return 0;
}
/*
** Copyright (c) 2006, TUBITAK/UEKAE
**
** 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. Please read the COPYING file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/utsname.h>
#include "common.h"
static struct list *
find_aliases(const char *syspath)
{
DIR *dir;
struct dirent *dirent;
struct list *aliases = NULL;
char *modalias;
char *path;
dir = opendir(syspath);
if (!dir) return NULL;
while((dirent = readdir(dir))) {
char *name = dirent->d_name;
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
continue;
path = concat(syspath, name);
modalias = sys_value(path, "modalias");
if (modalias) {
aliases = list_add(aliases, modalias);
}
}
closedir(dir);
return aliases;
}
static struct list *
find_modules(const char *mapfile, struct list *aliases)
{
FILE *f;
struct list *modules = NULL;
struct list *alias;
char line[256];
char *modalias, *modname;
if (!aliases) return NULL;
f = fopen(mapfile, "rb");
while (fgets(line, 255, f)) {
if (line[0] == '#' || line[0] == '\n' || line[0] == '\0')
continue;
strtok(line, " \t");
if (strncmp(line, "alias", 5) != 0)
continue;
modalias = strtok(NULL, " \t");
modname = strtok(NULL, " \t\r\n");
for (alias = aliases; alias; alias = alias->next) {
if (0 == fnmatch(modalias, alias->data)) {
modules = list_add(modules, modname);
}
}
}
return modules;
}
struct list *
module_get_list(const char *syspath)
{
struct list *aliases;
struct utsname name;
char *mapfile;
uname(&name);
mapfile = concat("/lib/modules/", name.release);
mapfile = concat(mapfile, "/modules.alias");
aliases = find_aliases(syspath);
return find_modules(mapfile, aliases);
}
int
module_probe(const char *name)
{
char *cmd;
cmd = concat("modprobe ", name);
if (cfg_debug)
puts(cmd);
else
system(cmd);
return 0;
}
/*
** Copyright (c) 2006, TUBITAK/UEKAE
**
** 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. Please read the COPYING file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
#include "common.h"
struct list *
scsi_get_list(void)
{
DIR *dir;
struct dirent *dirent;
struct list *modules = NULL;
dir = opendir("/sys/bus/scsi/devices");
if (!dir) return NULL;
while((dirent = readdir(dir))) {
char *path;
char *tmp;
char *name = dirent->d_name;
if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0)
continue;
if (name[0] < '0' || name[0] > '9')
continue;
path = concat("/sys/bus/scsi/devices/", name);
path = my_readlink(path);
tmp = sys_value(path, "type");
if (tmp) {
if (strcmp(tmp, "0") == 0 || strcmp(tmp, "7") == 0)
modules = list_add(modules, "sd_mod");
if (strcmp(tmp, "1") == 0)
modules = list_add(modules, "st");
if (strcmp(tmp, "4") == 0 || strcmp(tmp, "5") == 0)
modules = list_add(modules, "sr_mod");
}
}
closedir(dir);
return modules;
}
/*
** Copyright (c) 2006, TUBITAK/UEKAE
**
** 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. Please read the COPYING file.
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "common.h"
int
list_has(struct list *listptr, const char *data)
{
struct list *tmp;
// Our lists arent big, so simple iteration isnt slow
for (tmp = listptr; tmp; tmp = tmp->next) {
if (0 == strcmp(tmp->data, data))
return 1;
}
return 0;
}
struct list *
list_add(struct list *listptr, const char *data)
{
struct list *tmp;
// We dont want duplicate module names in our lists
if (list_has(listptr, data))
return listptr;
tmp = zalloc(sizeof(struct list));
tmp->next = listptr;
tmp->data = strdup(data);
return tmp;
}
void *
zalloc(size_t size)
{
void *ptr = 0;
// For small allocations we shouldn't really fail
while (ptr == 0) {
// we usually need zeroed buffers
ptr = calloc(1, size);
}
return ptr;
}
char *
concat(const char *str, const char *append)
{
char *buf;
size_t str_len = strlen(str);
size_t append_len = strlen(append);
buf = zalloc(str_len + 1 + append_len);
memcpy(buf, str, str_len);
memcpy(buf + str_len, append, append_len);
buf[str_len + append_len] = '\0';
return buf;
}
char *
my_readlink(const char *path)
{
char *pathdir;
char *tmp;
char buf[512];
size_t size;
size = readlink(path, buf, 510);
if (size == -1) {
buf[0] = '\0';
return strdup(buf);
}
buf[size] = '\0';
pathdir = strdup(path);
tmp = pathdir + strlen(path) - 1;
while (*tmp != '/') --tmp;
++tmp;
*tmp = '\0';
return concat(pathdir, buf);
}
char *
sys_value(const char *path, const char *value)
{
static char valbuf[128];
static char *buf = NULL;
static size_t buf_size = 0;
FILE *f;
size_t size;
size_t path_len = strlen(path);
size_t value_len = strlen(value);
size = path_len + value_len + 2;
if (buf_size < size) {
free(buf);
buf = zalloc(size * 2);
buf_size = size * 2;
}
memcpy(buf, path, path_len);
buf[path_len] = '/';
memcpy(buf + path_len + 1, value, value_len);
buf[path_len + 1 + value_len] = '\0';
f = fopen(buf, "rb");
if (!f) return NULL;
size = fread(valbuf, 1, 126, f);
if (size < 1) {
fclose(f);
return NULL;
}
fclose(f);
valbuf[size] = '\0';
if (valbuf[size-1] == '\n')
valbuf[size-1] = '\0';
return valbuf;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment