mirror of
https://github.com/Soccera1/init.git
synced 2026-02-04 04:23:40 +01:00
Initial commit
This commit is contained in:
commit
12f9c4274b
16 changed files with 255 additions and 0 deletions
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
|
|
@ -0,0 +1 @@
|
|||
bin/
|
||||
2
examples/1
Normal file
2
examples/1
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
logging.sh
|
||||
network.sh
|
||||
1
examples/1.logging.sh
Symbolic link
1
examples/1.logging.sh
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
logging.sh
|
||||
1
examples/1.network.sh
Symbolic link
1
examples/1.network.sh
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
network.sh
|
||||
4
examples/3
Normal file
4
examples/3
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
logging.sh
|
||||
network.sh
|
||||
db.sh
|
||||
app.sh
|
||||
1
examples/3.app.sh
Symbolic link
1
examples/3.app.sh
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
app.sh
|
||||
1
examples/3.db.sh
Symbolic link
1
examples/3.db.sh
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
db.sh
|
||||
1
examples/3.logging.sh
Symbolic link
1
examples/3.logging.sh
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
logging.sh
|
||||
1
examples/3.network.sh
Symbolic link
1
examples/3.network.sh
Symbolic link
|
|
@ -0,0 +1 @@
|
|||
network.sh
|
||||
2
examples/app.sh
Normal file
2
examples/app.sh
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
db.sh network.sh
|
||||
echo "Application service started"
|
||||
2
examples/db.sh
Normal file
2
examples/db.sh
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
network.sh
|
||||
echo "Database service started"
|
||||
2
examples/logging.sh
Normal file
2
examples/logging.sh
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# This script has no dependencies
|
||||
echo "Logging service started"
|
||||
2
examples/network.sh
Normal file
2
examples/network.sh
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
logging.sh
|
||||
echo "Network service started"
|
||||
1
src/config.h
Normal file
1
src/config.h
Normal file
|
|
@ -0,0 +1 @@
|
|||
#define INIT_DIRECTORY "/home/lily/init/examples"
|
||||
66
src/main.c
Normal file
66
src/main.c
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
#include <stdio.h>
|
||||
#include <sys/stat.h>
|
||||
#include <stdlib.h>
|
||||
#include <dirent.h>
|
||||
#include "config.h"
|
||||
|
||||
void check_init() {
|
||||
|
||||
const char* init_directory;
|
||||
init_directory=INIT_DIRECTORY;
|
||||
struct stat sb;
|
||||
|
||||
if (stat(init_directory, &sb) == 0 && S_ISDIR(sb.st_mode)) {
|
||||
printf("Init directory found! Continuing.\n");
|
||||
} else {
|
||||
printf ("Init directory not found!\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int has_char_before_dot(const char *filename, char c) {
|
||||
int found_c = 0;
|
||||
for (int i = 0; filename[i] != '\0'; i++) {
|
||||
if (filename[i] == '.') return found_c;
|
||||
if (filename[i] == c) {
|
||||
found_c = 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void parse_names(char runlevel) {
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
d = opendir(INIT_DIRECTORY);
|
||||
if (d) {
|
||||
while ((dir = readdir(d)) != NULL) {
|
||||
// Use 8 if DT_REG is not defined (standard on most Linux systems)
|
||||
#ifndef DT_REG
|
||||
#define DT_REG 8
|
||||
#endif
|
||||
#ifndef DT_LNK
|
||||
#define DT_LNK 10
|
||||
#endif
|
||||
if (dir->d_type == DT_REG || dir->d_type == DT_LNK) {
|
||||
if (has_char_before_dot(dir->d_name, runlevel)) {
|
||||
printf("File: %s, Number: %c\n", dir->d_name, runlevel);
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <runlevel>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
char runlevel = argv[1][0];
|
||||
|
||||
check_init();
|
||||
parse_names(runlevel);
|
||||
return 0;
|
||||
}
|
||||
167
src/solver.c
Normal file
167
src/solver.c
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#include "config.h"
|
||||
|
||||
#define MAX_SCRIPTS 1000
|
||||
#define MAX_NAME 256
|
||||
#define MAX_DEPS 200
|
||||
|
||||
typedef struct {
|
||||
char generic_name[MAX_NAME];
|
||||
char full_name[MAX_NAME];
|
||||
char dependencies[MAX_DEPS][MAX_NAME];
|
||||
int num_dependencies;
|
||||
int in_degree;
|
||||
int processed;
|
||||
} Script;
|
||||
|
||||
static Script scripts[MAX_SCRIPTS];
|
||||
static int num_scripts = 0;
|
||||
|
||||
void check_init() {
|
||||
const char* init_directory = INIT_DIRECTORY;
|
||||
struct stat sb;
|
||||
|
||||
if (stat(init_directory, &sb) == 0 && S_ISDIR(sb.st_mode)) {
|
||||
printf("Init directory found! Continuing.\n");
|
||||
} else {
|
||||
printf("Init directory not found!\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
static int has_char_before_dot(const char *filename, char c) {
|
||||
int found_c = 0;
|
||||
for (int i = 0; filename[i] != '\0'; i++) {
|
||||
if (filename[i] == '.') return found_c;
|
||||
if (filename[i] == c) found_c = 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void get_generic_name(const char *filename, char *dest) {
|
||||
const char *dot = strchr(filename, '.');
|
||||
if (dot) {
|
||||
strcpy(dest, dot + 1);
|
||||
} else {
|
||||
strcpy(dest, filename);
|
||||
}
|
||||
}
|
||||
|
||||
static int find_script_idx(const char *generic_name) {
|
||||
for (int i = 0; i < num_scripts; i++) {
|
||||
if (strcmp(scripts[i].generic_name, generic_name) == 0) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void solve_dependencies(char runlevel) {
|
||||
DIR *d;
|
||||
struct dirent *dir;
|
||||
num_scripts = 0;
|
||||
|
||||
d = opendir(INIT_DIRECTORY);
|
||||
if (!d) {
|
||||
perror("opendir");
|
||||
return;
|
||||
}
|
||||
|
||||
while ((dir = readdir(d)) != NULL) {
|
||||
#ifndef DT_REG
|
||||
#define DT_REG 8
|
||||
#endif
|
||||
#ifndef DT_LNK
|
||||
#define DT_LNK 10
|
||||
#endif
|
||||
if ((dir->d_type == DT_REG || dir->d_type == DT_LNK) && has_char_before_dot(dir->d_name, runlevel)) {
|
||||
if (num_scripts >= MAX_SCRIPTS) break;
|
||||
|
||||
Script *s = &scripts[num_scripts];
|
||||
strncpy(s->full_name, dir->d_name, MAX_NAME);
|
||||
get_generic_name(dir->d_name, s->generic_name);
|
||||
s->num_dependencies = 0;
|
||||
s->in_degree = 0;
|
||||
s->processed = 0;
|
||||
|
||||
char path[512];
|
||||
snprintf(path, sizeof(path), "%s/%s", INIT_DIRECTORY, dir->d_name);
|
||||
FILE *f = fopen(path, "r");
|
||||
if (f) {
|
||||
char line[1024];
|
||||
if (fgets(line, sizeof(line), f)) {
|
||||
char *token = strtok(line, " \t\n\r");
|
||||
while (token && s->num_dependencies < MAX_DEPS) {
|
||||
strncpy(s->dependencies[s->num_dependencies++], token, MAX_NAME);
|
||||
token = strtok(NULL, " \t\n\r");
|
||||
}
|
||||
}
|
||||
fclose(f);
|
||||
}
|
||||
num_scripts++;
|
||||
}
|
||||
}
|
||||
closedir(d);
|
||||
|
||||
for (int i = 0; i < num_scripts; i++) {
|
||||
for (int j = 0; j < scripts[i].num_dependencies; j++) {
|
||||
int dep_idx = find_script_idx(scripts[i].dependencies[j]);
|
||||
if (dep_idx != -1) {
|
||||
scripts[i].in_degree++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
char out_path[512];
|
||||
snprintf(out_path, sizeof(out_path), "%s/%c", INIT_DIRECTORY, runlevel);
|
||||
FILE *out = fopen(out_path, "w");
|
||||
if (!out) {
|
||||
perror("fopen output");
|
||||
return;
|
||||
}
|
||||
|
||||
int resolved = 0;
|
||||
while (resolved < num_scripts) {
|
||||
int found = 0;
|
||||
for (int i = 0; i < num_scripts; i++) {
|
||||
if (!scripts[i].processed && scripts[i].in_degree == 0) {
|
||||
fprintf(out, "%s\n", scripts[i].generic_name);
|
||||
scripts[i].processed = 1;
|
||||
found = 1;
|
||||
resolved++;
|
||||
|
||||
for (int j = 0; j < num_scripts; j++) {
|
||||
if (!scripts[j].processed) {
|
||||
for (int k = 0; k < scripts[j].num_dependencies; k++) {
|
||||
if (strcmp(scripts[j].dependencies[k], scripts[i].generic_name) == 0) {
|
||||
scripts[j].in_degree--;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
fprintf(stderr, "Cycle detected or missing dependency in runlevel %c\n", runlevel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
fclose(out);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
if (argc < 2) {
|
||||
printf("Usage: %s <runlevel>\n", argv[0]);
|
||||
return 1;
|
||||
}
|
||||
char runlevel = argv[1][0];
|
||||
|
||||
check_init();
|
||||
solve_dependencies(runlevel);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue