224 lines
5.2 KiB
C
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");
|
|
}
|
|
}
|