Files
fit/gen/dat_tascom_dir.c
2022-08-19 15:22:33 +02:00

224 lines
5.2 KiB
C

#include <time.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <dirent.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
#include "myc_str.h"
#include "myc_fortran.h"
typedef struct NameList {
struct NameList *next;
int l;
char name[16];
} NameList;
typedef struct {
char path[PATH_MAX];
int start;
time_t newestTime;
char newestPath[PATH_MAX];
char newestItem[PATH_MAX];
int numor;
int cnt;
int mode;
int level;
int maxlevel;
} TascomDirScan;
void TascomScanDir(TascomDirScan *scan, int length, char *name) {
DIR *dir;
struct dirent *ent;
struct stat st;
int l, n;
char rp[PATH_MAX];
int cnt;
char *ename;
NameList *list, *p, *q;
l = strlen(name);
if (length+l > PATH_MAX-2) {
printf(" filename too long\n");
exit(1);
}
if (strcmp(name, ".") != 0) {
scan->path[length]='/';
length++;
strcpy(scan->path+length, name);
length += l;
}
realpath(scan->path, rp);
if (strcmp(scan->path, rp) != 0) return; /* check for symbolic link */
if (0>stat(scan->path, &st)) return;
if (! S_ISDIR(st.st_mode)) return;
dir=opendir(scan->path);
if (dir == NULL) return;
ent = readdir(dir);
cnt = scan->cnt;
list = NULL;
while (ent != NULL) {
ename = ent->d_name;
if (strchr(ename,'.') == NULL) {
scan->level++;
TascomScanDir(scan, length, ename);
scan->level--;
scan->path[length+1]='\0';
} else {
l = strlen(ename);
if (l == 12 && strcmp(ename+8,".dat") == 0) {
l = 7;
while (l>0 && ename[l] >= '0' && ename[l] <= '9') {
l--;
}
l++;
if (l != 8) {
p = list;
while (p != NULL && (p->l != l || strncmp(p->name, ename, l) != 0)) {
p = p->next;
}
if (!p) {
p = calloc(1, sizeof *p);
p->next = list;
list = p;
p->l = l;
if (scan->level > scan->maxlevel) scan->maxlevel = scan->level;
}
if (strcmp(ename, p->name) > 0) {
strncpy(p->name, ename, 12);
p->name[12]='\0';
}
}
}
}
ent = readdir(dir);
}
p = list;
while (p != NULL) {
scan->path[length]='/';
scan->path[length+1]='\0';
str_copy(rp, scan->path);
str_append(rp, p->name);
n=0;
sscanf(p->name + p->l, "%d", &n);
if (stat(rp, &st) >= 0) {
if (st.st_mtime > scan->newestTime) {
scan->newestTime = st.st_mtime;
str_copy(scan->newestPath, rp);
snprintf(scan->newestItem, sizeof scan->newestItem,
"%.*s%.*s", length-scan->start+1, scan->path+scan->start, p->l, p->name);
scan->numor = n;
}
}
if (scan->mode == 0) {
printf(" %.*s%.*s (%d)\n", length-scan->start+1, scan->path+scan->start, p->l, p->name, n);
}
scan->cnt++;
q = p;
p = p->next;
free(q);
}
if (scan->mode == 1 && scan->level == 1 && scan->cnt > cnt) {
scan->path[length]='\0';
printf(" %s\n", scan->path + scan->start);
}
}
char *TascomGetDir(char *path) {
char answer[128];
char *nl, *slash;
DIR *dir;
static TascomDirScan scan;
static char subdir[PATH_MAX];
int start;
realpath(path, scan.path);
dir=opendir(scan.path);
if (dir == NULL) return NULL;
closedir(dir);
start = strlen(scan.path) + 1;
scan.start = start;
scan.newestTime = 0;
scan.newestPath[0] = '\0';
scan.mode = 1;
scan.level = 0;
scan.maxlevel = 0;
scan.cnt = 0;
printf("\n User directories on %s:\n", path);
printf("\n");
TascomScanDir(&scan, start-1, ".");
slash = strchr(scan.newestPath+scan.start+1, '/');
if (slash) *slash = '\0';
printf("\n user directory [%s]: ", scan.newestPath+scan.start);
answer[0]='\0';
fgets(answer, sizeof answer, stdin);
nl = strchr(answer, '\n');
if (nl) *nl='\0';
if (answer[0] == '\0') {
str_copy(subdir, scan.newestPath+start);
} else {
scan.path[start]='/';
scan.path[start+1]='\0';
str_append(scan.path, answer);
dir = opendir(scan.path);
if (!dir) {
perror(answer);
return "";
}
closedir(dir);
str_copy(subdir, answer);
}
printf("\n");
scan.start = start + strlen(subdir) + 1;
scan.newestTime = 0;
scan.newestPath[0] = '\0';
scan.mode = 0;
scan.level = 0;
scan.maxlevel = 0;
scan.cnt = 0;
TascomScanDir(&scan, start-1, subdir);
scan.newestPath[scan.start+strlen(scan.newestItem)]='\0';
printf("\n");
if (scan.cnt == 0) {
return "";
}
if (scan.cnt == 1) {
return scan.newestPath + start;
}
printf(" ");
if (scan.maxlevel > 0) {
printf("(subdirectory/)");
}
printf("filename [%s]: ", scan.newestItem);
answer[0]='\0';
fgets(answer, sizeof answer, stdin);
printf("\n");
nl = strchr(answer, '\n');
if (nl) *nl='\0';
if (answer[0] == '\0') {
return scan.newestPath + start;
} else {
scan.path[scan.start+1]='\0';
str_append(scan.path, answer);
return scan.path + start;
}
}
void F_FUN(dat_tascom_datadir)(F_CHAR(root), F_CHAR(path) F_CLEN(root) F_CLEN(path)) {
char rootc[PATH_MAX];
char *out;
STR_TO_C(rootc, root);
out=TascomGetDir(rootc);
if (out) {
STR_TO_F(path, out);
} else {
STR_TO_F(path, "0");
}
}