#include #include #include #include #include #include #include #include #include #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"); } }