Mercurial > hg > Members > kono > os9 > sbc09
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 # |