Initial commit
This commit is contained in:
223
gen/dat_tascom_dir.c
Normal file
223
gen/dat_tascom_dir.c
Normal file
@ -0,0 +1,223 @@
|
||||
#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");
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user