1 ; **************************************************************************** 2 ; pwd8086.s (pwd0.s) - by Erdogan Tan - 05/05/2022 3 ; ---------------------------------------------------------------------------- 4 ; Retro UNIX 8086 v1 - pwd - print working directory pathname 5 ; 6 ; [ Last Modification: 14/05/2022 ] 7 ; 8 ; Derived from (original) UNIX v5 'pwd.c' source Code 9 ; Ref: 10 ; www.tuhs.org (https://minnie.tuhs.org) 11 ; v5root.tar.gz 12 ; **************************************************************************** 13 ; [ usr/source/s2/pwd.c (archive date: 27-11-1974) ] 14 15 ; pwd0.s - Retro UNIX 8086 v1 (16 bit version of 'pwd1.s') 16 ; pwd1.s - Retro UNIX 386 v1 (unix v1 inode structure) 17 ; pwd2.s - Retro UNIX 386 v1.1 (16 byte directory entries) 18 ; pwd3.s - Retro UNIX 386 v1.2 (& v2) (modified unix v7 inode) 19 20 ; UNIX v1 system calls 21 _rele equ 0 22 _exit equ 1 23 _fork equ 2 24 _read equ 3 25 _write equ 4 26 _open equ 5 27 _close equ 6 28 _wait equ 7 29 _creat equ 8 30 _link equ 9 31 _unlink equ 10 32 _exec equ 11 33 _chdir equ 12 34 _time equ 13 35 _mkdir equ 14 36 _chmod equ 15 37 _chown equ 16 38 _break equ 17 39 _stat equ 18 40 _seek equ 19 41 _tell equ 20 42 _mount equ 21 43 _umount equ 22 44 _setuid equ 23 45 _getuid equ 24 46 _stime equ 25 47 _quit equ 26 48 _intr equ 27 49 _fstat equ 28 50 _emt equ 29 51 _mdate equ 30 52 _stty equ 31 53 _gtty equ 32 54 _ilgins equ 33 55 _sleep equ 34 ; Retro UNIX 8086 v1 feature only ! 56 _msg equ 35 ; Retro UNIX 386 v1 feature only ! 57 58 ;;; 59 ESCKey equ 1Bh 60 EnterKey equ 0Dh 61 62 63 ;%macro sys 1-4 64 ; ; 03/09/2015 65 ; ; 13/04/2015 66 ; ; Retro UNIX 386 v1 system call. 67 ; %if %0 >= 2 68 ; mov ebx, %2 69 ; %if %0 >= 3 70 ; mov ecx, %3 71 ; ;%if %0 = 4 72 ; %if %0 >= 4 ; 11/03/2022 73 ; mov edx, %4 74 ; %endif 75 ; %endif 76 ; %endif 77 ; mov eax, %1 78 ; int 30h 79 ;%endmacro 80 81 %macro sys 1-4 82 ; Retro UNIX 8086 v1 system call. 83 %if %0 >= 2 84 mov bx, %2 85 %if %0 >= 3 86 mov cx, %3 87 %if %0 >= 4 88 mov dx, %4 89 %endif 90 %endif 91 %endif 92 mov ax, %1 93 int 20h 94 %endmacro 95 96 ;; Retro UNIX 386 v1 system call format: 97 ;; sys systemcall (eax) , , 98 99 ;; 11/03/2022 100 ;; Note: Above 'sys' macro has limitation about register positions; 101 ;; ebx, ecx, edx registers must not be used after their 102 ;; positions in sys macro. 103 ;; for example: 104 ;; 'sys _write, 1, msg, ecx' is defective, because 105 ;; ecx will be used/assigned before edx in 'sys' macro. 106 ;; correct order may be: 107 ;; 'sys _write, 1, msg, eax ; (eax = byte count) 108 109 ; Retro UNIX 8086 v1 system call format: 110 ; sys systemcall (ax) , , 111 112 ; ---------------------------------------------------------------------------- 113 114 [BITS 16] ; 16-bit intructions (for 8086/x86 real mode) 115 116 [ORG 0] 117 118 START_CODE: 119 ; 14/05/2022 120 ; 11/05/2022 121 ; 10/05/2022 122 ; 09/05/2022 123 ; 06/05/2022 (16 bit version) -ax,bx,cx,dx- 124 ; 06/05/2022 (32 bit version) -eax,ebx,ecx,edx- 125 ; 05/05/2022 126 127 ;main() { 128 ; int n; 129 130 ; clear (reset) stack (not necessary) 131 00000000 59 pop cx ; cx = number of arguments 132 pwd_0: 133 00000001 58 pop ax ; ax = argument 0 = executable file name 134 00000002 E2FD loop pwd_0 135 136 ;mov byte [y.zero], 0 ; (not necessary) 137 ; (because Retro UNIX kernel 138 ; clears bss -memory page- while 139 ; assigning it to program) 140 ;mov word [off], 0 141 142 ; 06/05/2022 143 00000004 FF0E[AA03] dec word [off] ; -1 144 145 ;loop0: 146 ; stat(dot, &x); 147 ; if((file = open(dotdot,0)) < 0) prname(); 148 149 loop0: 150 ;sys _stat, dot, _x 151 152 ; 11/05/2022 153 ;stat(dot, &d); 154 ;if (d.st_ino==rino && d.st_dev==rdev) 155 ; prname(); 156 157 sys _stat, dot, _d 82 <1> 83 <1> %if %0 >= 2 84 00000008 BB[6601] <1> mov bx, %2 85 <1> %if %0 >= 3 86 0000000B B9[AE03] <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 0000000E B81200 <1> mov ax, %1 93 00000011 CD20 <1> int 20h 158 00000013 7229 jc short error 159 160 00000015 833E[AE03]29 cmp word [d.ino], 41 ; d.st_ino == rino 161 0000001A 7504 jne short pwd_1 162 0000001C 09C0 or ax, ax ; [d.dev] ; && d.st_dev==rdev 163 ;jz short prname ; root device, root dir 164 0000001E 741B jz short pwd_p ; 11/05/2022 165 pwd_1: 166 00000020 A3[AC03] mov [d.dev], ax 167 168 sys _open, dotdot, 0 ; open for read 82 <1> 83 <1> %if %0 >= 2 84 00000023 BB[6501] <1> mov bx, %2 85 <1> %if %0 >= 3 86 00000026 B90000 <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 00000029 B80500 <1> mov ax, %1 93 0000002C CD20 <1> int 20h 169 ;jc short prname 170 ; 11/05/2022 171 0000002E 7313 jnc short pwd_2 172 173 ; 11/05/2022 174 pwd_err: 175 00000030 B8[7701] mov ax, err_1 176 pmsg_exit: 177 00000033 E81701 call print_msg 178 exit: 179 sys _exit ; exit(1); 82 <1> 83 <1> %if %0 >= 2 84 <1> mov bx, %2 85 <1> %if %0 >= 3 86 <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 00000036 B80100 <1> mov ax, %1 93 00000039 CD20 <1> int 20h 180 ;hang: 181 ; nop 182 ; jmp short hang 183 184 185 pwd_p: ; 11/05/2022 186 0000003B E99900 jmp prname 187 188 error: ; 11/05/2022 189 0000003E B8[6C01] mov ax, err_0 190 00000041 EBED jmp short pwd_err 191 192 pwd_2: 193 194 ;loop1: 195 ; if((n = read(file,&y,16)) < 16) prname(); 196 ; if(y.jnum != x.inum)goto loop1; 197 ; close(file); 198 ; if(y.jnum == 1) ckroot(); 199 ; cat(); 200 ; chdir(dotdot); 201 ; goto loop0; 202 ;} 203 204 00000043 A3[A803] mov [file], ax 205 206 ; 11/05/2022 207 ;fstat(file, &dd); 208 ;chdir(dotdot); 209 210 sys _fstat, ax, _dd 82 <1> 83 <1> %if %0 >= 2 84 00000046 89C3 <1> mov bx, %2 85 <1> %if %0 >= 3 86 00000048 B9[D003] <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 0000004B B81C00 <1> mov ax, %1 93 0000004E CD20 <1> int 20h 211 00000050 72EC jc short error 212 213 ;mov [dd.dev], ax ; 14/05/2022 214 00000052 89C1 mov cx, ax 215 216 sys _chdir, dotdot 82 <1> 83 <1> %if %0 >= 2 84 00000054 BB[6501] <1> mov bx, %2 85 <1> %if %0 >= 3 86 <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 00000057 B80C00 <1> mov ax, %1 93 0000005A CD20 <1> int 20h 217 0000005C 72E0 jc short error 218 219 0000005E 3B0E[AC03] cmp cx, [d.dev] 220 00000062 7536 jne short pwd_4 221 222 00000064 A1[AE03] mov ax, [d.ino] 223 00000067 3B06[D003] cmp ax, [dd.ino] 224 0000006B 746A je short prname 225 226 ; do .. while 227 loop1: 228 sys _read, [file], _y, 10 ; Retro UNIX 386 v1 82 <1> 83 <1> %if %0 >= 2 84 0000006D 8B1E[A803] <1> mov bx, %2 85 <1> %if %0 >= 3 86 00000071 B9[F203] <1> mov cx, %3 87 <1> %if %0 >= 4 88 00000074 BA0A00 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 00000077 B80300 <1> mov ax, %1 93 0000007A CD20 <1> int 20h 229 ;;sys _read, [file], _y, 16 ; Retro UNIX 386 v1.1 & v1.2 230 ;jc short prname 231 ; 11/05/2022 232 0000007C 7231 jc short pwd_5 233 ;cmp ax, 10 ; cmp eax, 16 234 ;;jb short prname 235 ;jb short pwd_5 ; 11/05/2022 236 0000007E 09C0 or ax, ax 237 ;jz short prname 238 00000080 742D jz short pwd_5 ; 11/05/2022 239 240 ; 11/05/2022 241 ; while (dir.d_ino != d.st_ino); 242 00000082 A1[F203] mov ax, [jnum] 243 ;cmp ax, [inum] 244 00000085 3B06[AE03] cmp ax, [d.ino] 245 00000089 75E2 jne short loop1 246 247 pwd_3: 248 sys _close, [file] 82 <1> 83 <1> %if %0 >= 2 84 0000008B 8B1E[A803] <1> mov bx, %2 85 <1> %if %0 >= 3 86 <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 0000008F B80600 <1> mov ax, %1 93 00000092 CD20 <1> int 20h 249 250 ;;cmp word [jnum], 1 ; Retro UNIX 386 v1.2 251 ;cmp word [jnum], 41 ; root dir inode number 252 ;je short ckroot 253 ;call cat 254 ;sys _chdir, dotdot 255 ;jmp short loop0 256 257 ; 11/05/2022 258 00000094 E87000 call cat 259 00000097 E96EFF jmp loop0 ; for (;;) 260 261 pwd_4: 262 loop_2: 263 ; 11/05/2022 264 ; else do .. while 265 sys _read, [file], _y, 10 ; Retro UNIX 386 v1 82 <1> 83 <1> %if %0 >= 2 84 0000009A 8B1E[A803] <1> mov bx, %2 85 <1> %if %0 >= 3 86 0000009E B9[F203] <1> mov cx, %3 87 <1> %if %0 >= 4 88 000000A1 BA0A00 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 000000A4 B80300 <1> mov ax, %1 93 000000A7 CD20 <1> int 20h 266 ;sys _read, [file], _y, 16 ; Retro UNIX 386 v1.1 & v1.2 267 000000A9 7204 jc short pwd_5 268 000000AB 21C0 and ax, ax 269 000000AD 7506 jnz short pwd_6 270 pwd_5: 271 000000AF B8[9001] mov ax, err_2 272 000000B2 E97EFF jmp pmsg_exit 273 pwd_6: 274 ; stat(dir.d_name, &dd); 275 sys _stat, yname, _dd 82 <1> 83 <1> %if %0 >= 2 84 000000B5 BB[F403] <1> mov bx, %2 85 <1> %if %0 >= 3 86 000000B8 B9[D003] <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 000000BB B81200 <1> mov ax, %1 93 000000BE CD20 <1> int 20h 276 000000C0 7303 jnc short pwd_7 277 000000C2 E979FF jmp error 278 pwd_7: 279 ; while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); 280 000000C5 8B0E[AE03] mov cx, [d.ino] 281 000000C9 3B0E[D003] cmp cx, [dd.ino] 282 000000CD 75CB jne short loop_2 283 000000CF 3B06[AC03] cmp ax, [d.dev] 284 000000D3 75C5 jne short loop_2 285 000000D5 EBB4 jmp short pwd_3 286 287 ;prname() { 288 ; name[off] = '\n'; 289 ; write(1,name,off+1); 290 ; exit(); 291 292 prname: 293 sys _write, 1, nextline, 3 ; 06/05/2022 82 <1> 83 <1> %if %0 >= 2 84 000000D7 BB0100 <1> mov bx, %2 85 <1> %if %0 >= 3 86 000000DA B9[6801] <1> mov cx, %3 87 <1> %if %0 >= 4 88 000000DD BA0300 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 000000E0 B80400 <1> mov ax, %1 93 000000E3 CD20 <1> int 20h 294 295 000000E5 8B36[AA03] mov si, [off] 296 297 ;if (off<0) off = 0; 298 000000E9 46 inc si ; -1 -> 0 299 000000EA 7401 jz short prname_crlf 300 000000EC 4E dec si 301 prname_crlf: 302 ;mov byte [si+name], 0Dh ; CR 303 000000ED C784[A801]0D0A mov word [si+name], 0A0Dh ; CRLF 304 ;inc dword [off] 305 000000F3 46 inc si 306 000000F4 46 inc si 307 ;mov [off], si 308 ;sys _write, 1, name, [off] 309 sys _write, 1, name, si 82 <1> 83 <1> %if %0 >= 2 84 000000F5 BB0100 <1> mov bx, %2 85 <1> %if %0 >= 3 86 000000F8 B9[A801] <1> mov cx, %3 87 <1> %if %0 >= 4 88 000000FB 89F2 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 000000FD B80400 <1> mov ax, %1 93 00000100 CD20 <1> int 20h 310 _exit_: 311 sys _exit ; exit(0); 82 <1> 83 <1> %if %0 >= 2 84 <1> mov bx, %2 85 <1> %if %0 >= 3 86 <1> mov cx, %3 87 <1> %if %0 >= 4 88 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 00000102 B80100 <1> mov ax, %1 93 00000105 CD20 <1> int 20h 312 ;hang: 313 ; nop 314 ; jmp short hang 315 316 ;ckroot() { 317 ; int i, n; 318 ; 319 ; if((n = stat(y.name,&x)) < 0) prname(); 320 ; i = x.devn; 321 ; if((n = chdir(root)) < 0) prname(); 322 ; if((file = open(root,0)) < 0) prname(); 323 ;loop: 324 ; if((n = read(file,&y,16)) < 16) prname(); 325 ; if(y.jnum == 0) goto loop; 326 ; if((n = stat(y.name,&x)) < 0) prname(); 327 ; if(x.devn != i) goto loop; 328 ; x.i[0] =& 060000; 329 ; if(x.i[0] != 040000) goto loop; 330 ; cat(); 331 ; prname(); 332 333 ; ; 10/05/2022 334 ; ; 09/05/2022 (new -retro unix 8286 v1- kernel) 335 ; ; (sysstat returns with device number in ax) 336 ;ckroot: 337 ; ; 09/05/2022 338 ; sys _stat, yname, _x 339 ; jc short ckroot_err 340 ; mov [idev], ax ; device number 341 ; sys _chdir, root 342 ; jc short ckroot_err 343 ; sys _open, root, 0 ; open root dir for read 344 ; jc short ckroot_err 345 ; ; 10/05/2022 346 ; mov [file], ax 347 ;ckroot_loop: 348 ; sys _read, [file], _y, 10 349 ; ; read one dir entry 350 ; jc short ckroot_err 351 ; ; 10/05/2022 352 ; or ax, ax 353 ; jz short ckroot_err 354 ; cmp word [jnum], 0 355 ; jna short ckroot_loop 356 ; sys _stat, yname, _x 357 ; jc short ckroot_err 358 ; cmp ax, [idev] ; same device number ? 359 ; jne short ckroot_loop ; no 360 ; ; 10/05/2022 361 ; test byte [ximode+1], 40h ; directory ? 362 ; jz short ckroot_loop 363 ; ; 364 ; call cat 365 ; ; 366 ;ckroot_err: 367 ; jmp prname 368 369 ; ; 06/05/2022 370 ; ; Note: For Retro UNIX 386 v1 & v1.1 & v1.2, 371 ; ; mounted device is handled via 'mnti' 372 ; ; field which keeps (device 0) mounting 373 ; ; directory inode number for mounted 374 ; ; device (1). Device number (0 or 1) check 375 ; ; (via 'sysstat') is not possible 376 ; ; for current Retro UNIX kernel versions 377 ; ; because 'sysstat' output does not contain 378 ; ; device number. 379 ; ; *** 380 ; ; As a temporary solution (before a next 381 ; ; kernel version with new 'sysstat'), 382 ; ; root dir entries are checked for a subdir 383 ; ; ('usr' & 'mnt' dirs for now) with root dir 384 ; ; inode number (41 or 1), if there is.. 385 ; ; root directory is a real (device 0) root 386 ; ; directory; if not, device 1 root directory 387 ; ; is mounted to a sub directory of device 0. 388 ; ; (Also it must be verified after 'chdir /') 389 ; ; 390 ; ; assumptions... 391 ; ; a sub dir with root inode number 392 ; ; dotdot / - chdir / 393 ; ; no - no ----> root 394 ; ; yes - (yes) --> root, not checked 395 ; ; no - yes ----> mounted 396 ; ; yes - (no) ---> root, not checked 397 ; 398 ;ckroot: 399 ; ; 06/05/2022 400 ; ; check 'usr' directory 401 ; mov dx, usr 402 ; call statm 403 ; jz short ckroot_2 ; root dir 404 ; ; check 'mnt' directory 405 ; mov dx, mnt 406 ; call statm 407 ; jz short ckroot_2 ; root dir 408 ; 409 ; sys _chdir, root 410 ; jc short ckroot_2 ; jmp short prname 411 ; 412 ; ; check 'usr' directory 413 ; mov dx, usr 414 ; call statm 415 ; jz short ckroot_1 ; mounted 416 ; ; check 'mnt' directory 417 ; mov dx, mnt 418 ; call statm 419 ; jnz short ckroot_2 ; not mounted 420 ; 421 ; ; mounted 422 ;ckroot_1: 423 ; ; move mounting directory name 424 ; mov si, dx 425 ; mov di, yname 426 ; movsw 427 ; movsw 428 ; ; concatenate (add to head of the path) 429 ; call cat 430 ;ckroot_2: 431 ; jmp prname 432 ; 433 ;statm: 434 ; ; 06/05/2022 435 ; sys _stat, dx, _x 436 ; jc short statm_1 437 ; ;cmp word [inum], 1 ; Retro UNIX 386 v1.2 438 ; cmp word [inum], 41 ; root dir inode number 439 ;statm_1: 440 ; retn 441 442 ;cat() { 443 ; int i, j; 444 ; 445 ; i = -1; 446 ; while(y.name[++i] != 0); 447 ; if((off+i+2) > 511) prname(); 448 ; for(j=off+1; j>=0; --j) name[j+i+1] = name[j]; 449 ; off=i+off+1; 450 ; name[i] = root[0]; 451 ; for(--i; i>=0; --i) name[i] = y.name[i]; 452 ;} 453 454 cat: 455 00000107 31DB xor bx, bx 456 00000109 4B dec bx ; i = -1 457 cat_0: 458 0000010A 43 inc bx ; ++i 459 0000010B 80BF[F403]00 cmp byte [yname+bx], 0 460 00000110 77F8 ja short cat_0 461 00000112 89DA mov dx, bx ; i 462 00000114 8B0E[AA03] mov cx, [off] 463 00000118 41 inc cx ; j = [off]+1 464 00000119 01CA add dx, cx ; dx = [off]+i+1 465 0000011B 81FAFD01 cmp dx, 511-2 ; (+ CRLF + 0) 466 0000011F 77B6 ja short prname 467 ;;ja short ckroot_2 ; jmp prname 468 ;ja short ckroot_err ; 09/05/2022 469 00000121 BE[A801] mov si, name 470 00000124 01CE add si, cx ; name[j] 471 00000126 89F7 mov di, si 472 00000128 01DF add di, bx ; name[j+i] 473 0000012A 47 inc di ; name[j+i+1] 474 cat_1: 475 ;std 476 ;rep stosb 477 ;cld 478 0000012B 49 dec cx 479 0000012C 7808 js short cat_2 480 0000012E 4E dec si 481 0000012F 8A04 mov al, [si] 482 00000131 4F dec di 483 00000132 8805 mov [di], al 484 00000134 EBF5 jmp short cat_1 485 cat_2: 486 00000136 8916[AA03] mov [off], dx ; [off] = i+[off]+1 487 0000013A C687[A801]2F mov byte [name+bx], '/' ; name[i] = '/'; 488 cat_3: 489 0000013F 4B dec bx ; --i 490 00000140 780A js short cat_4 ; 0 -> -1 491 ; name[i] = yname[i] 492 00000142 8A87[F403] mov al, [yname+bx] 493 00000146 8887[A801] mov [name+bx], al 494 0000014A EBF3 jmp short cat_3 ; i >= 0 495 cat_4: 496 0000014C C3 retn 497 498 ;----------------------------------------------------------------- 499 500 print_msg: 501 ; ax = asciiz string address 502 0000014D 89C6 mov si, ax 503 0000014F 4E dec si 504 nextchr: 505 00000150 46 inc si 506 00000151 803C00 cmp byte [si], 0 507 00000154 77FA ja short nextchr 508 ;cmp [si], 0Dh 509 ;ja short nextchr 510 00000156 29C6 sub si, ax 511 ; si = asciiz string length 512 ; 513 sys _write, 1, ax, si 82 <1> 83 <1> %if %0 >= 2 84 00000158 BB0100 <1> mov bx, %2 85 <1> %if %0 >= 3 86 0000015B 89C1 <1> mov cx, %3 87 <1> %if %0 >= 4 88 0000015D 89F2 <1> mov dx, %4 89 <1> %endif 90 <1> %endif 91 <1> %endif 92 0000015F B80400 <1> mov ax, %1 93 00000162 CD20 <1> int 20h 514 ; 515 00000164 C3 retn 516 517 ;----------------------------------------------------------------- 518 ; data - initialized data 519 ;----------------------------------------------------------------- 520 521 ; 05/05/2022 522 523 00000165 2E dotdot: db '.' 524 00000166 2E dot: db '.' 525 00000167 00 db 0 526 527 ; 06/05/2022 528 nextline: 529 00000168 0D0A db 0Dh, 0Ah 530 0000016A 2F00 root: db '/', 0 531 532 ; 14/05/2022 533 ; default mounting directories (for current retro unix version) 534 ;usr: db 'usr', 0 535 ;mnt: db 'mnt', 0 536 537 ; 11/05/2022 538 0000016C 0D0A err_0: db 0Dh, 0Ah 539 0000016E 4572726F7221 db "Error!" 540 00000174 0D0A00 db 0dh, 0Ah, 0 541 542 00000177 0D0A err_1: db 0Dh, 0Ah 543 00000179 7077643A2063616E20- db "pwd: can not open .." 543 00000182 6E6F74206F70656E20- 543 0000018B 2E2E 544 0000018D 0D0A00 db 0Dh, 0Ah, 0 545 00000190 0D0A err_2: db 0Dh, 0Ah 546 00000192 72656164206572726F- db "read error in .." 546 0000019B 7220696E202E2E 547 000001A2 0D0A00 db 0Dh, 0Ah, 0 548 549 ;----------------------------------------------------------------- 550 ; bss - uninitialized data 551 ;----------------------------------------------------------------- 552 553 000001A5 90 align 4 554 555 bss_start: 556 557 ABSOLUTE bss_start 558 559 ; 06/05/2022 560 561 000001A8 name: resb 512 562 563 000003A8 ???? file: resw 1 564 000003AA ???? off: resw 1 565 566 ; 09/05/2022 567 idev: 568 ; 11/05/2022 569 000003AC ???? d.dev: resw 1 ; device number (0 = root, 1 = mounted) 570 ;dd.dev: resw 1 ; 14/05/2022 571 572 ; 06/05/2022 573 _x: ; stat(us) buffer 574 _d: ; 11/05/2022 575 inum: 576 d.ino: ; 11/05/2022 577 000003AE ???? resw 1 578 ximode: 579 d.mode: ; 11/05/22022 580 ;resb 64 ; Retro UNIX 386 v1.2 581 000003B0 resb 32 ; Retro UNIX 386 v1 & v1.1 582 583 ; 11/05/2022 584 _dd: ; stat(us) buffer 585 000003D0 ???? dd.ino: resw 1 586 dd.mode: 587 000003D2 resb 32 588 589 ; 06/05/2022 590 _y: ; directory entry buffer 591 000003F2 ???? jnum: resw 1 592 yname: ;resb 14 ; Retro UNIX 386 v1.1 & v1.2 593 000003F4 ???????????????? resb 8 ; Retro UNIX 386 v1 (unix v1) 594 595 000003FC ???? yzero: resw 1 596 597 ; 05/05/2022 598 599 ;----------------------------------------------------------------- 600 ; Original UNIX v7 - /bin/pwd file - c source code (pwd.c) 601 ;----------------------------------------------------------------- 602 ; 603 ;/* 604 ; * Print working (current) directory 605 ; */ 606 ;#include 607 ;#include 608 ;#include 609 ;#include 610 ; 611 ;char dot[] = "."; 612 ;char dotdot[] = ".."; 613 ;char name[512]; 614 ;int file; 615 ;int off = -1; 616 ;struct stat d, dd; 617 ;struct direct dir; 618 ; 619 ;main() 620 ;{ 621 ; int rdev, rino; 622 ; 623 ; stat("/", &d); 624 ; rdev = d.st_dev; 625 ; rino = d.st_ino; 626 ; for (;;) { 627 ; stat(dot, &d); 628 ; if (d.st_ino==rino && d.st_dev==rdev) 629 ; prname(); 630 ; if ((file = open(dotdot,0)) < 0) { 631 ; fprintf(stderr,"pwd: cannot open ..\n"); 632 ; exit(1); 633 ; } 634 ; fstat(file, &dd); 635 ; chdir(dotdot); 636 ; if(d.st_dev == dd.st_dev) { 637 ; if(d.st_ino == dd.st_ino) 638 ; prname(); 639 ; do 640 ; if (read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) { 641 ; fprintf(stderr,"read error in ..\n"); 642 ; exit(1); 643 ; } 644 ; while (dir.d_ino != d.st_ino); 645 ; } 646 ; else do { 647 ; if(read(file, (char *)&dir, sizeof(dir)) < sizeof(dir)) { 648 ; fprintf(stderr,"read error in ..\n"); 649 ; exit(1); 650 ; } 651 ; stat(dir.d_name, &dd); 652 ; } while(dd.st_ino != d.st_ino || dd.st_dev != d.st_dev); 653 ; close(file); 654 ; cat(); 655 ; } 656 ;} 657 ; 658 ;prname() 659 ;{ 660 ; write(1, "/", 1); 661 ; if (off<0) 662 ; off = 0; 663 ; name[off] = '\n'; 664 ; write(1, name, off+1); 665 ; exit(0); 666 ;} 667 ; 668 ;cat() 669 ;{ 670 ; register i, j; 671 ; 672 ; i = -1; 673 ; while (dir.d_name[++i] != 0); 674 ; if ((off+i+2) > 511) 675 ; prname(); 676 ; for(j=off+1; j>=0; --j) 677 ; name[j+i+1] = name[j]; 678 ; off=i+off+1; 679 ; name[i] = '/'; 680 ; for(--i; i>=0; --i) 681 ; name[i] = dir.d_name[i]; 682 ;} 683 684 ; 05/05/2022 685 686 ;----------------------------------------------------------------- 687 ; Original UNIX v5 - /usr/bin/pwd file - c source code (pwd.c) 688 ;----------------------------------------------------------------- 689 ; 690 ;char dot[] "."; 691 ;char dotdot[] ".."; 692 ;char root[] "/"; 693 ;char name[512]; 694 ;int file, off -1; 695 ;struct statb {int devn, inum, i[18];}x; 696 ;struct entry { int jnum; char name[16];}y; 697 ; 698 ;main() { 699 ; int n; 700 ; 701 ;loop0: 702 ; stat(dot, &x); 703 ; if((file = open(dotdot,0)) < 0) prname(); 704 ;loop1: 705 ; if((n = read(file,&y,16)) < 16) prname(); 706 ; if(y.jnum != x.inum)goto loop1; 707 ; close(file); 708 ; if(y.jnum == 1) ckroot(); 709 ; cat(); 710 ; chdir(dotdot); 711 ; goto loop0; 712 ;} 713 ;ckroot() { 714 ; int i, n; 715 ; 716 ; if((n = stat(y.name,&x)) < 0) prname(); 717 ; i = x.devn; 718 ; if((n = chdir(root)) < 0) prname(); 719 ; if((file = open(root,0)) < 0) prname(); 720 ;loop: 721 ; if((n = read(file,&y,16)) < 16) prname(); 722 ; if(y.jnum == 0) goto loop; 723 ; if((n = stat(y.name,&x)) < 0) prname(); 724 ; if(x.devn != i) goto loop; 725 ; x.i[0] =& 060000; 726 ; if(x.i[0] != 040000) goto loop; 727 ; cat(); 728 ; prname(); 729 ;} 730 ;prname() { 731 ; name[off] = '\n'; 732 ; write(1,name,off+1); 733 ; exit(); 734 ;} 735 ;cat() { 736 ; int i, j; 737 ; 738 ; i = -1; 739 ; while(y.name[++i] != 0); 740 ; if((off+i+2) > 511) prname(); 741 ; for(j=off+1; j>=0; --j) name[j+i+1] = name[j]; 742 ; off=i+off+1; 743 ; name[i] = root[0]; 744 ; for(--i; i>=0; --i) name[i] = y.name[i]; 745 ;}