comparison vdisk.c @ 47:15f1e1b49928

open dir worked ?
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Fri, 20 Jul 2018 17:04:49 +0900
parents ec9f494497e1
children ea1b17311bf3
comparison
equal deleted inserted replaced
46:ec9f494497e1 47:15f1e1b49928
12 #include <unistd.h> 12 #include <unistd.h>
13 #include <sys/stat.h> 13 #include <sys/stat.h>
14 #include <sys/select.h> 14 #include <sys/select.h>
15 #include <dirent.h> 15 #include <dirent.h>
16 #include <string.h> 16 #include <string.h>
17 #include <time.h>
18
17 19
18 20
19 #ifdef USE_MMU 21 #ifdef USE_MMU
20 extern char *prog ; // for disass 22 extern char *prog ; // for disass
21 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ; 23 extern Byte * mem0(Byte *iphymem, Word adr, Byte *immu) ;
24 // pmem physical address using current mmu
25 // smem physical address using system mmu
26 // umem physical address using caller's mmu
22 #define pmem(a) mem0(phymem,a,mmu) 27 #define pmem(a) mem0(phymem,a,mmu)
23 #define smem(a) mem0(phymem,a,&mem[0x20+IOPAGE]) 28 #define smem(a) mem0(phymem,a,&mem[0x20+IOPAGE])
24 #define umem(a) (mem[0x42+IOPAGE]?mem0(phymem,a,&mem[0x21+IOPAGE]):mem0(phymem,a,&mem[0x20+IOPAGE])) 29 #define umem(a) (mem[0x42+IOPAGE]?mem0(phymem,a,&mem[0x28+IOPAGE]):mem0(phymem,a,&mem[0x20+IOPAGE]))
25 #else 30 #else
26 #define pmem(a) (&mem[a]) 31 #define pmem(a) (&mem[a])
27 #define umem(a) (&mem[a]) 32 #define umem(a) (&mem[a])
28 #define smem(a) (&mem[a]) 33 #define smem(a) (&mem[a])
29 #endif 34 #endif
54 if (drv<0 || drv>=MAXVDRV) return -1; 59 if (drv<0 || drv>=MAXVDRV) return -1;
55 drvRoot[drv] = name; 60 drvRoot[drv] = name;
56 return 0; 61 return 0;
57 } 62 }
58 63
59 PathDesc *findPD() {
60 for(int i=0;i<MAXPDV;i++) {
61 if (!pdv[i].use) {
62 pdv[i].use = 1;
63 pdv[i].num = i;
64 pdv[i].mode = 0;
65 pdv[i].fp = 0;
66 pdv[i].dirfp = 0;
67 pdv[i].name = 0;
68 pdv[i].fd = 0;
69 return &pdv[i];
70 }
71 }
72 return 0;
73 }
74
75 void closepd(PathDesc *pd) { 64 void closepd(PathDesc *pd) {
76 int err = fclose(pd->fp) ; 65 int err = fclose(pd->fp) ;
77 pd->use = 0; 66 pd->use = 0;
78 pd->fp = 0; 67 pd->fp = 0;
79 pd->mode = 0; 68 pd->mode = 0;
84 73
85 #define MAXPAHTLEN 256 74 #define MAXPAHTLEN 256
86 75
87 char *addCurdir(char *name, PathDesc *pd, PathDesc *curdir) { 76 char *addCurdir(char *name, PathDesc *pd, PathDesc *curdir) {
88 int ns =0 ; 77 int ns =0 ;
78 char *n = name;
89 if (name[0]=='/') { 79 if (name[0]=='/') {
90 while(*name++ =='/') ; // skip /d0 80 while(*name !='/' && *name!=0) name ++ ; // skip /d0
91 while(name[ns]!=0) ns++; 81 while(name[ns]!=0) ns++;
92 } else if (curdir==0 ) return 0; // no current directory 82 } else if (curdir==0 || !curdir->name ) return 0; // no current directory
93 int ps = ns; 83 int ps = ns;
94 char *base ; 84 char *base ;
95 if (name[0]!='/') { name++; base = curdir->name; ps += strlen(curdir->name)+1; } 85 if (name[0]-='/') {
96 else { base = drvRoot[pd->drv]; ps += strlen(drvRoot[pd->drv])+1; } 86 base = drvRoot[pd->drv]; ps += strlen(drvRoot[pd->drv])+1;
87 } else if (name[0]==0) {
88 return drvRoot[pd->drv];
89 } else {
90 name++; base = curdir->name; ps += strlen(curdir->name)+1;
91 }
97 char *path = (char*)malloc(ps+1); 92 char *path = (char*)malloc(ps+1);
98 int i = 0; 93 int i = 0;
99 for(;base[i];i++) path[i] = base[i]; 94 for(;base[i];i++) path[i] = base[i];
100 path[i++] = '/'; 95 path[i++] = '/';
101 for(int j=0;j<ns;j++,i++) path[i] = name[j]; 96 for(int j=0;j<ns;j++,i++) path[i] = name[j];
105 100
106 char * checkFileName(char *path, PathDesc *pd, PathDesc *curdir) { 101 char * checkFileName(char *path, PathDesc *pd, PathDesc *curdir) {
107 char *p = path; 102 char *p = path;
108 char *name = path; 103 char *name = path;
109 int maxlen = MAXPAHTLEN; 104 int maxlen = MAXPAHTLEN;
110 while(*p!=0 && (*p&80)==0 && maxlen-->0) p++; 105 while(*p!=0 && (*p&0x80)==0 && (*p>0x1f) && maxlen-->0) p++;
111 if (maxlen==MAXPAHTLEN) return 0; 106 if (maxlen==MAXPAHTLEN) return 0;
112 if (*p!=0) { 107 if (*p!=0) {
113 name = (char *)malloc(p-path+1); 108 name = (char *)malloc(p-path+1);
114 strncpy(path,p, MAXPAHTLEN-maxlen); 109 strncpy(name,path, MAXPAHTLEN-maxlen);
110 name[MAXPAHTLEN-maxlen] = 0;
115 } 111 }
116 char *name1 = addCurdir(name,pd,curdir); 112 char *name1 = addCurdir(name,pd,curdir);
117 if (name1!=name && name1!=path) free(name); 113 if (name1!=name && name1!=path) free(name);
114 if (name1==0) return 0;
118 pd->name = name1; 115 pd->name = name1;
119 return p; 116 return p;
120 } 117 }
121 118
122 void os9setmode(char *os9mode,int mode) { 119 void os9setmode(char *os9mode,int mode) {
189 /* read direcotry entry */ 186 /* read direcotry entry */
190 int os9opendir(PathDesc *pd) { 187 int os9opendir(PathDesc *pd) {
191 DIR *dir; 188 DIR *dir;
192 struct dirent *dp; 189 struct dirent *dp;
193 dir = opendir(pd->name); 190 dir = opendir(pd->name);
191 if (dir==0) return -1;
194 int dircount = 0; 192 int dircount = 0;
195 while ((dp = readdir(dir)) != NULL) dircount++; // pass 1 to determine the size 193 while ((dp = readdir(dir)) != NULL) dircount++; // pass 1 to determine the size
196 if (dircount==0) return 0; // should contains . and .. at least 194 if (dircount==0) return 0; // should contains . and .. at least
197 pd->sz = dircount*DIR_SZ; 195 pd->sz = dircount*DIR_SZ;
198 pd->dirfp = (char *)malloc(dircount*DIR_SZ); 196 pd->dirfp = (char *)malloc(dircount*DIR_SZ);
199 rewinddir(dir); 197 rewinddir(dir);
200 int i = 0; 198 int i = 0;
201 while ((dp = readdir(dir)) != NULL) { 199 while ((dp = readdir(dir)) != NULL) {
202 i += DIR_SZ;
203 if (i>pd->sz) return 0;
204 int j = 0; 200 int j = 0;
205 for(j = 0; j < DIR_NM ; j++) { 201 for(j = 0; j < DIR_NM ; j++) {
206 if (j< dp->d_namlen) 202 if (j< dp->d_namlen)
207 pd->dirfp[j] = dp->d_name[j]; 203 pd->dirfp[i+j] = dp->d_name[j];
208 else 204 else
209 pd->dirfp[j] = 0; 205 pd->dirfp[i+j] = 0;
210 } 206 }
211 pd->dirfp[j] = (dp->d_ino&0xff0000)>>16; 207 pd->dirfp[i+j] = (dp->d_ino&0xff0000)>>16;
212 pd->dirfp[j+1] = (dp->d_ino&0xff00)>>8; 208 pd->dirfp[i+j+1] = (dp->d_ino&0xff00)>>8;
213 pd->dirfp[j+2] = dp->d_ino&0xff; 209 pd->dirfp[i+j+2] = dp->d_ino&0xff;
210 i += DIR_SZ;
211 if (i>pd->sz) return 0;
214 } 212 }
215 pd->fp = fmemopen(pd->dirfp,pd->sz,"r"); 213 pd->fp = fmemopen(pd->dirfp,pd->sz,"r");
216 return 0; 214 return 0;
217 } 215 }
218 216
219 void os9setdate(char *d,struct timespec * unixtime) { 217 void os9setdate(char *d,struct timespec * unixtime) {
220 // yymmddhhss 218 // yymmddhhss
219 struct tm r;
220 localtime_r(&unixtime->tv_sec,&r);
221 d[0] = r.tm_year-2000;
222 d[1] = r.tm_mon;
223 d[2] = r.tm_mday;
224 d[3] = r.tm_hour;
225 d[4] = r.tm_min;
226 d[5] = r.tm_sec;
221 } 227 }
222 228
223 /* read file descriptor of Path Desc 229 /* read file descriptor of Path Desc
224 * create file descriptor sector if necessary 230 * create file descriptor sector if necessary
225 * if buf!=0, copy it 231 * if buf!=0, copy it
275 * current directory path number mem[0x42+IOPAGE] 281 * current directory path number mem[0x42+IOPAGE]
276 * yreg has pd number 282 * yreg has pd number
277 */ 283 */
278 void do_vdisk(Byte cmd) { 284 void do_vdisk(Byte cmd) {
279 int err; 285 int err;
280 Byte mode = yreg&0xff;
281 PathDesc *pd = pdv + ((yreg>>8)&0xff);
282 PathDesc *curdir = pdv+mem[0x44+IOPAGE]; // garbage until set 286 PathDesc *curdir = pdv+mem[0x44+IOPAGE]; // garbage until set
283 pd->drv = mem[0x41+IOPAGE];
284 Byte attr ; 287 Byte attr ;
285 Word u = mem[0x45+IOPAGE]; // caller's stack in system segment 288 Word u = (mem[0x45+IOPAGE]<<8)+mem[0x46+IOPAGE]; // caller's stack in system segment
286 xreg = (*smem(u+4)<<8)+*smem(u+5); 289 xreg = (*smem(u+4)<<8)+*smem(u+5);
287 *areg = *smem(u+1); 290 *areg = *smem(u+1);
288 *breg = *smem(u+2); 291 *breg = *smem(u+2);
292 Byte mode = yreg&0xff;
293 Byte *os9pd = smem((mem[0x47+IOPAGE]<<8)+mem[0x48+IOPAGE]);
294 PathDesc *pd = pdv+*os9pd;
295 pd->num = *os9pd;
296 pd->drv = mem[0x41+IOPAGE];
289 char *path,*next,*buf; 297 char *path,*next,*buf;
290 298
291 switch(cmd) { 299 switch(cmd) {
292 /* 300 /*
293 * I$Create Entry Point 301 * I$Create Entry Point
301 * 309 *
302 * Error: CC Carry set 310 * Error: CC Carry set
303 * B = errcode 311 * B = errcode
304 */ 312 */
305 case 0xd1: 313 case 0xd1:
306 pd = findPD();
307 if (pd==0) { *breg = 0xff; break; }
308 mode = *areg; 314 mode = *areg;
309 attr = *breg; 315 attr = *breg;
310 path = (char *)pmem(xreg); 316 path = (char *)umem(xreg);
311 next = pd->name = checkFileName(path,pd,curdir); 317 next = pd->name = checkFileName(path,pd,curdir);
312 pd->dir = 0; 318 pd->dir = 0;
313 pd->fp = fopen(pd->name, os9toUnixAttr(attr)); 319 pd->fp = fopen(pd->name, os9toUnixAttr(attr));
314 if (next!=0 && pd->fp ) { 320 if (next!=0 && pd->fp ) {
315 xreg += ( next - path ); 321 xreg += ( next - path );
316 pd->use = 1; 322 pd->use = 1;
317 } else { 323 } else {
318 *breg = 0xff; 324 *breg = 0xff;
319 free(pd->name); 325 free(pd->name);
326 pd->use = 0;
320 } 327 }
321 break; 328 break;
322 329
323 /* 330 /*
324 * I$Open Entry Point 331 * I$Open Entry Point
331 * 338 *
332 * Error: CC Carry set 339 * Error: CC Carry set
333 * B = errcode 340 * B = errcode
334 */ 341 */
335 case 0xd2: 342 case 0xd2:
336 pd = findPD(); 343 *breg = 0xff;
337 *breg = 0xff;
338 if (pd==0) break;
339 mode = *areg; 344 mode = *areg;
340 attr = *breg; 345 attr = *breg;
341 pd->fp = 0; 346 pd->fp = 0;
342 path = (char*)pmem(xreg); 347 path = (char*)umem(xreg);
343 next = checkFileName(path,pd,curdir); 348 next = checkFileName(path,pd,curdir);
349 *breg = 0xff;
344 if (next!=0) { 350 if (next!=0) {
345 struct stat buf; 351 struct stat buf;
346 if (stat(pd->name,&buf)!=0) break; 352 if (stat(pd->name,&buf)!=0) break;
347 if ((buf.st_mode & S_IFMT) == S_IFDIR) { 353 if ((buf.st_mode & S_IFMT) == S_IFDIR) {
348 pd->dir = 1; 354 pd->dir = 1;
349 os9opendir(pd); 355 os9opendir(pd);
350 } else { 356 } else {
351 pd->dir = 0; 357 pd->dir = 0;
352 pd->fp = fopen( pd->name,os9toUnixAttr(mode)); 358 pd->fp = fopen( pd->name,os9toUnixAttr(mode));
353 } 359 }
360 pd->use = 1;
354 } 361 }
355 if (next!=0 && pd->fp !=0) { 362 if (next!=0 && pd->fp !=0) {
363 *breg = 0;
356 *areg = pd->num; 364 *areg = pd->num;
357 xreg += ( next - path ); 365 xreg += ( next - path );
358 } 366 pd->use = 1;
367 } else {
368 pd->use = 0;
369 }
359 break; 370 break;
360 371
361 /* 372 /*
362 * I$MakDir Entry Point 373 * I$MakDir Entry Point
363 * 374 *
369 * Error: CC Carry set 380 * Error: CC Carry set
370 * B = errcode 381 * B = errcode
371 */ 382 */
372 383
373 case 0xd3: 384 case 0xd3:
374 pd = findPD(); 385 *breg = 0xff;
375 *breg = 0xff; 386 path = (char*)umem(xreg);
376 if (pd==0) break;
377 path = (char*)pmem(xreg);
378 next = checkFileName(path,pd,curdir); 387 next = checkFileName(path,pd,curdir);
379 if (next!=0 && mkdir(pd->name,0)!= 0 ) { 388 if (next!=0 && mkdir(pd->name,0)!= 0 ) {
380 xreg += ( next - path ); 389 xreg += ( next - path );
381 *breg = 0; 390 *breg = 0;
382 } 391 }
403 * 412 *
404 * Error: CC Carry set 413 * Error: CC Carry set
405 * B = errcode 414 * B = errcode
406 */ 415 */
407 case 0xd4: 416 case 0xd4:
408 pd = findPD(); 417 path = (char*)umem(xreg);
409 if (pd==0) { *breg = 0xff; break; }
410 path = (char*)pmem(xreg);
411 next = checkFileName(path,pd,curdir); 418 next = checkFileName(path,pd,curdir);
412 if (next!=0 && os9opendir(pd)) { 419 if (next!=0 && os9opendir(pd)) {
413 if (curdir!=pd) closepd(curdir); 420 if (curdir!=pd) closepd(curdir);
414 if (pd->name != path) { 421 if (pd->name != path) {
415 free(path); 422 free(path);
416 } 423 }
417 xreg += ( next - path ); 424 xreg += ( next - path );
418 *areg = pd->num; 425 *areg = pd->num;
426 pd->use = 1;
419 *breg = 0; 427 *breg = 0;
420 break; 428 break;
421 } 429 }
422 *breg = 0xff; 430 *breg = 0xff;
423 break; 431 break;
434 */ 442 */
435 case 0xd5: { 443 case 0xd5: {
436 *breg = 0xff; 444 *breg = 0xff;
437 if (pd==0) break; 445 if (pd==0) break;
438 struct stat st; 446 struct stat st;
439 path = (char*)pmem(xreg); 447 path = (char*)umem(xreg);
440 next = checkFileName(path,pd,curdir); 448 next = checkFileName(path,pd,curdir);
449 pd->use = 0;
441 if (next!=0 && stat(pd->name,&st)!=0) break; 450 if (next!=0 && stat(pd->name,&st)!=0) break;
442 if (next!=0 && ((st.st_mode&S_IFDIR)?rmdir(pd->name):unlink(pd->name)) == 0) { 451 if (next!=0 && ((st.st_mode&S_IFDIR)?rmdir(pd->name):unlink(pd->name)) == 0) {
443 xreg += ( next - path ); 452 xreg += ( next - path );
444 *breg = 0; 453 *breg = 0;
445 } 454 }
486 */ 495 */
487 case 0xd7: 496 case 0xd7:
488 *breg = 0xff; 497 *breg = 0xff;
489 if (pd==0) break; 498 if (pd==0) break;
490 if (pd->dir) break; 499 if (pd->dir) break;
491 buf = (char*)pmem(xreg); 500 buf = (char*)umem(xreg);
492 if (fgets(buf,yreg,pd->fp)) { 501 if (fgets(buf,yreg,pd->fp)) {
493 int len = yreg; 502 int len = yreg;
494 int i; 503 int i;
495 for(i=0;i<len && buf[i];i++); 504 for(i=0;i<len && buf[i];i++);
496 if (i>0 && buf[i-1]=='\n') { 505 if (i>0 && buf[i-1]=='\n') {
512 * B = errcode 521 * B = errcode
513 */ 522 */
514 case 0xd8: 523 case 0xd8:
515 *breg = 0xff; 524 *breg = 0xff;
516 if (pd==0) break; 525 if (pd==0) break;
517 buf = (char*)pmem(xreg); 526 buf = (char*)umem(xreg);
518 err = fread(buf,yreg,1,pd->fp); 527 err = fread(buf,yreg,1,pd->fp);
519 *breg = err==0?0xff:0 ; 528 *breg = err==0?0xff:0 ;
520 yreg = err ; 529 yreg = err ;
521 break; 530 break;
522 531
539 *breg = 0xff; 548 *breg = 0xff;
540 if (pd==0) break; 549 if (pd==0) break;
541 if (pd->dir) break; 550 if (pd->dir) break;
542 int len = yreg; 551 int len = yreg;
543 int i = 0; 552 int i = 0;
544 Byte *buf = pmem(xreg); 553 Byte *buf = umem(xreg);
545 while(len>0 && *buf !='\r') { 554 while(len>0 && *buf !='\r') {
546 fputc(buf[i++],pd->fp); 555 fputc(buf[i++],pd->fp);
547 len--; 556 len--;
548 } 557 }
549 if (buf[i]=='\r') { 558 if (buf[i]=='\r') {
565 * B = errcode 574 * B = errcode
566 */ 575 */
567 case 0xda : 576 case 0xda :
568 *breg = 0xff; 577 *breg = 0xff;
569 if (!pd->dir) { 578 if (!pd->dir) {
570 Byte *buf = pmem(xreg); 579 Byte *buf = umem(xreg);
571 int len = yreg; 580 int len = yreg;
572 int err = fwrite(buf,len,1,pd->fp); 581 int err = fwrite(buf,len,1,pd->fp);
573 *breg = err?0xff:0; 582 *breg = err?0xff:0;
574 yreg = err; 583 yreg = err;
575 } 584 }
635 * R$X=Pointer to a 256 byte buffer 644 * R$X=Pointer to a 256 byte buffer
636 * R$Y=# bytes of FD required 645 * R$Y=# bytes of FD required
637 * this should be handled in vrbf 646 * this should be handled in vrbf
638 */ 647 */
639 *breg = 0xff; 648 *breg = 0xff;
649 yreg = (*smem(u+6)<<8)+*smem(u+7);
640 if (pd==0) break; 650 if (pd==0) break;
641 *breg = filedescriptor(pmem(xreg), yreg,pd) ; 651 *breg = filedescriptor(umem(xreg), yreg,pd) ;
642 break; 652 break;
643 case 0x20: // Pos.FDInf mandatry for dir command 653 case 0x20: // Pos.FDInf mandatry for dir command
644 /* SS.FDInf ($20) - Directly reads a file descriptor from anywhere 654 /* SS.FDInf ($20) - Directly reads a file descriptor from anywhere
645 * on drive. 655 * on drive.
646 * Entry: R$A=Path # 656 * Entry: R$A=Path #