diff vdisk.c @ 52:51b437557f42

boot without disk image dir -e on other directory
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 22 Jul 2018 15:52:39 +0900
parents 498b6fcaf270
children 4fa2bdb0c457
line wrap: on
line diff
--- a/vdisk.c	Sun Jul 22 05:48:04 2018 +0900
+++ b/vdisk.c	Sun Jul 22 15:52:39 2018 +0900
@@ -116,12 +116,12 @@
 #define MAXPAHTLEN 256
 
 static void
-putOs9str(char *s) {
+putOs9str(char *s,int max) {
     if (s==0) {
         printf("(null)");
         return;
     }
-    while(*s && *s>=' ' && ((*s&0x80)==0)) {
+    while(*s && (*s&0x7f)>=' ' && ((*s&0x80)==0) && --max !=0) {
         putchar(*s); s++;
     }
     if (*s&0x80) putchar(*s&0x7f);
@@ -136,7 +136,7 @@
 addCurdir(char *name, PathDesc *pd, int curdir) {
     int ns =0 ;
     char *n = name;
-if(vdiskdebug&0x2) { printf("addcur \""); putOs9str(name); printf("\" cur \""); putOs9str( cdt[curdir]); printf("\"\n"); }
+if(vdiskdebug&0x2) { printf("addcur \""); putOs9str(name,0); printf("\" cur \""); putOs9str( cdt[curdir],0); printf("\"\n"); }
     if (name[0]=='/') {
         name++; while(*name !='/' && *name!=0) name ++ ; // skip /d0
         while(name[ns]!=0) ns++;
@@ -172,15 +172,15 @@
     char *p = path;
     char *name = path;
     int maxlen = MAXPAHTLEN;
-if(vdiskdebug&2) { printf("checkf \""); putOs9str(name); printf("\"\n"); }
+if(vdiskdebug&2) { printf("checkf \""); putOs9str(name,0); printf("\"\n"); }
     while(*p!=0 && (*p&0x80)==0 && (*p&0x7f)>' ' && maxlen-->0) p++;
     if (maxlen==MAXPAHTLEN) return 0;
-    if (*p!=0) {
-        name = (char *)malloc(p-path+1); 
+    if (*p) {  // 8th bit termination or non ascii termination
+        int eighth = ((*p&0x80)!=0);
+        name = (char *)malloc(p-path+1+eighth); 
         int i;
-        for(i=0;i<p-path;i++) {
-            name[i] = path[i]&0x7f;
-        }
+        for(i=0;i<p-path;i++) name[i] = path[i];
+        if (eighth) { name[i] = path[i]&0x7f; p++ ; i++; }
         name[i] = 0;
     }
     char *name1 = addCurdir(name,pd,curdir);
@@ -189,16 +189,16 @@
     pd->name = name1;
 if(vdiskdebug&2) {
     printf(" remain = \"");
-    char *p1 = p;
-    while(*p1 && (*p1&0x80)==0 ) { if (*p1<0x20)  printf("(0x%02x)",*p1); else  putchar(*p1); p1++; }
+    char *p1 = p; int max=31;
+    while(*p1 && (*p1&0x80)==0 && max-->0) { if (*p1<0x20)  printf("(0x%02x)",*p1); else  putchar(*p1); p1++; }
     if (*p1)  { if ((*p1&0x7f)<0x20)  printf("(0x%02x)",*p1); else  putchar(*p1&0x7f); }
-    printf("\" checkname result \""); putOs9str(pd->name); printf("\"\n");
+    printf("\" checkname result \""); putOs9str(pd->name,0); printf("\"\n");
 }
     return p;
 }
 
 static void 
-os9setmode(char *os9mode,int mode) {
+os9setmode(Byte *os9mode,int mode) {
     char m = 0;
     if (mode&S_IFDIR) m|=0x80;
     if (mode&S_IRUSR) m|=0x01;
@@ -303,12 +303,12 @@
 }
 
 static void 
-os9setdate(char *d,struct timespec * unixtime) {
+os9setdate(Byte *d,struct timespec * unixtime) {
     //   yymmddhhss
     struct tm r;
     localtime_r(&unixtime->tv_sec,&r);
-    d[0] = r.tm_year-2000;
-    d[1] = r.tm_mon;
+    d[0] = r.tm_year-2048;
+    d[1] = r.tm_mon + 1;
     d[2] = r.tm_mday;
     d[3] = r.tm_hour;
     d[4] = r.tm_min;
@@ -320,24 +320,27 @@
  *    if buf!=0, copy it 
  */
 static int 
-filedescriptor(Byte *buf, int len, PathDesc *pd) {
+filedescriptor(Byte *buf, int len, Byte *name,int curdir) {
+    int err = 0x255;
+    PathDesc pd;  
+    if (len<13) return -1;
+    checkFileName((char*)name,&pd,curdir);
     struct stat st;
-    if (pd->fd) return 1;
-    pd->fd = (char *)malloc(256);
-    stat(pd->name,&st);
-    os9setmode(pd->fd+FD_ATT,st.st_mode);
-    pd->fd[FD_OWN]=(st.st_uid&0xff00)>>8;
-    pd->fd[FD_OWN+1]=st.st_uid&0xff;
-    os9setdate(pd->fd + FD_DAT,&st.st_mtimespec);
-    pd->fd[FD_LNK]=st.st_nlink&0xff;
-    pd->fd[FD_SIZ+0]=(st.st_size&0xff000000)>>24;
-    pd->fd[FD_SIZ+1]=(st.st_size&0xff0000)>>16;
-    pd->fd[FD_SIZ+2]=(st.st_size&0xff00)>>8;
-    pd->fd[FD_SIZ+3]=st.st_size&0xff;
-    os9setdate(pd->fd+FD_Creat,&st.st_ctimespec);
-    // dummy segment list
-    for(int i=FD_SEG ; i < 256; i++) pd->fd[i] = 0;
-    return 0;
+    if (stat(pd.name,&st)!=0) goto err1;
+    os9setmode(buf+FD_ATT,st.st_mode);
+    buf[FD_OWN]=(st.st_uid&0xff00)>>8;
+    buf[FD_OWN+1]=st.st_uid&0xff;
+    os9setdate(buf+ FD_DAT,&st.st_mtimespec);
+    buf[FD_LNK]=st.st_nlink&0xff;
+    buf[FD_SIZ+0]=(st.st_size&0xff000000)>>24;
+    buf[FD_SIZ+1]=(st.st_size&0xff0000)>>16;
+    buf[FD_SIZ+2]=(st.st_size&0xff00)>>8;
+    buf[FD_SIZ+3]=st.st_size&0xff;
+    os9setdate(buf+FD_Creat,&st.st_ctimespec);
+    err = 0;
+err1:
+    free(pd.name);
+    return err;
 }
 
 /* read direcotry entry for any file in the directory 
@@ -347,25 +350,24 @@
  *     inode==bitmap should return disk sector map for os9 free command
  */
 static int 
-fdinfo(Byte *buf,int len, int inode, PathDesc *pd) {
+fdinfo(Byte *buf,int len, int inode, PathDesc *pd,int curdir) {
     int i;
     for(i=0;i<MAXPDV;i++) {
         PathDesc *pd = pdv+i;
         if (!pd->use || !pd->dir) continue;
         //  find inode in directory
-        char *dir = (char *)pd->dirfp;
-        char *end = (char *)pd->dirfp + pd->sz;
+        Byte *dir = (Byte*)pd->dirfp;
+        Byte *end = (Byte*)pd->dirfp + pd->sz;
         while( dir < end ) {
-            Byte *p = (Byte *)(dir + DIR_NM);
+            Byte *p = (dir + DIR_NM);
             int dinode = (p[0]<<16)+(p[1]<<8)+p[2];
             if (inode == dinode) {
-                filedescriptor(buf,len,pd);
-                return 1;
+                return filedescriptor(buf,len,dir,curdir);
             }
             dir += 0x20;
         }
     }
-    return 0;
+    return 255;
 }
 
 void
@@ -763,11 +765,10 @@
                  *                                 R$B=SS.FD ($0F)
                  *                                 R$X=Pointer to a 256 byte buffer
                  *                                 R$Y=# bytes of FD required
-                 *   this should be handled in vrbf
                  */
                     *breg = 0xff;
                     if (pd==0) break;
-                    *breg = filedescriptor(pmem(xreg), yreg,pd) ;
+                    *breg = filedescriptor(pmem(xreg), yreg,(Byte*)pd->name,curdir) ;
                     break;
                 case 0x20: // Pos.FDInf    mandatry for dir command
                 /*         SS.FDInf ($20) - Directly reads a file descriptor from anywhere
@@ -782,7 +783,7 @@
                     *breg = 0xff;
                     if (pd==0) break;
                     ureg = getword(smem(u+8));
-                    *breg  = fdinfo(pmem(xreg),yreg,xreg*0x10000+ureg,pd);
+                    *breg  = fdinfo(pmem(xreg),(yreg&0xff),((yreg&0xff00)>>8)*0x10000+ureg,pd,curdir);
                     break;
                 default:
                 *breg = 0xff;
@@ -815,6 +816,7 @@
             }
             break;
     }
+    if (vdiskdebug && *breg) printf("  vdisk call error %x\n",*breg);
     // return value
     mem[0xffc0] = *breg;
     *smem(u+2) = *breg ;