17c478bd9Sstevel@tonic-gate /* 2*67a4bb8fSGary Mills * Copyright 2015 Gary Mills 385651ed9SJohn.Zolnowsky@Sun.COM * Copyright (c) 1988, 2010, Oracle and/or its affiliates. All rights reserved. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * Copyright (c) 1988 Regents of the University of California. 87c478bd9Sstevel@tonic-gate * All rights reserved. 97c478bd9Sstevel@tonic-gate * 107c478bd9Sstevel@tonic-gate * This code is derived from software contributed to Berkeley by 117c478bd9Sstevel@tonic-gate * Computer Consoles Inc. 127c478bd9Sstevel@tonic-gate * 137c478bd9Sstevel@tonic-gate * Redistribution and use in source and binary forms are permitted 147c478bd9Sstevel@tonic-gate * provided that: (1) source distributions retain this entire copyright 157c478bd9Sstevel@tonic-gate * notice and comment, and (2) distributions including binaries display 167c478bd9Sstevel@tonic-gate * the following acknowledgement: ``This product includes software 177c478bd9Sstevel@tonic-gate * developed by the University of California, Berkeley and its contributors'' 187c478bd9Sstevel@tonic-gate * in the documentation or other materials provided with the distribution 197c478bd9Sstevel@tonic-gate * and in all advertising materials mentioning features or use of this 207c478bd9Sstevel@tonic-gate * software. Neither the name of the University nor the names of its 217c478bd9Sstevel@tonic-gate * contributors may be used to endorse or promote products derived 227c478bd9Sstevel@tonic-gate * from this software without specific prior written permission. 237c478bd9Sstevel@tonic-gate * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 247c478bd9Sstevel@tonic-gate * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 257c478bd9Sstevel@tonic-gate * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate #ifndef lint 297c478bd9Sstevel@tonic-gate char copyright[] = 307c478bd9Sstevel@tonic-gate "@(#) Copyright(c) 1988 Regents of the University of California.\n\ 317c478bd9Sstevel@tonic-gate All rights reserved.\n"; 327c478bd9Sstevel@tonic-gate #endif /* not lint */ 337c478bd9Sstevel@tonic-gate 347c478bd9Sstevel@tonic-gate #ifndef lint 357c478bd9Sstevel@tonic-gate static char sccsid[] = "@(#)fsdb.c 5.8 (Berkeley) 6/1/90"; 367c478bd9Sstevel@tonic-gate #endif /* not lint */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate /* 397c478bd9Sstevel@tonic-gate * fsdb - file system debugger 407c478bd9Sstevel@tonic-gate * 417c478bd9Sstevel@tonic-gate * usage: fsdb [-o suboptions] special 427c478bd9Sstevel@tonic-gate * options/suboptions: 437c478bd9Sstevel@tonic-gate * -o 447c478bd9Sstevel@tonic-gate * ? display usage 457c478bd9Sstevel@tonic-gate * o override some error conditions 467c478bd9Sstevel@tonic-gate * p="string" set prompt to string 477c478bd9Sstevel@tonic-gate * w open for write 487c478bd9Sstevel@tonic-gate */ 497c478bd9Sstevel@tonic-gate 507c478bd9Sstevel@tonic-gate #include <sys/param.h> 517c478bd9Sstevel@tonic-gate #include <sys/signal.h> 527c478bd9Sstevel@tonic-gate #include <sys/file.h> 537c478bd9Sstevel@tonic-gate #include <inttypes.h> 547c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h> 557c478bd9Sstevel@tonic-gate 567c478bd9Sstevel@tonic-gate #ifdef sun 577c478bd9Sstevel@tonic-gate #include <unistd.h> 587c478bd9Sstevel@tonic-gate #include <stdlib.h> 597c478bd9Sstevel@tonic-gate #include <string.h> 607c478bd9Sstevel@tonic-gate #include <fcntl.h> 617c478bd9Sstevel@tonic-gate #include <signal.h> 627c478bd9Sstevel@tonic-gate #include <sys/types.h> 637c478bd9Sstevel@tonic-gate #include <sys/vnode.h> 647c478bd9Sstevel@tonic-gate #include <sys/mntent.h> 657c478bd9Sstevel@tonic-gate #include <sys/wait.h> 667c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fsdir.h> 677c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_fs.h> 687c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_inode.h> 697c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_acl.h> 707c478bd9Sstevel@tonic-gate #include <sys/fs/ufs_log.h> 717c478bd9Sstevel@tonic-gate #else 727c478bd9Sstevel@tonic-gate #include <sys/dir.h> 737c478bd9Sstevel@tonic-gate #include <ufs/fs.h> 747c478bd9Sstevel@tonic-gate #include <ufs/dinode.h> 757c478bd9Sstevel@tonic-gate #include <paths.h> 767c478bd9Sstevel@tonic-gate #endif /* sun */ 777c478bd9Sstevel@tonic-gate 787c478bd9Sstevel@tonic-gate #include <stdio.h> 797c478bd9Sstevel@tonic-gate #include <setjmp.h> 807c478bd9Sstevel@tonic-gate 817c478bd9Sstevel@tonic-gate #define OLD_FSDB_COMPATIBILITY /* To support the obsoleted "-z" option */ 827c478bd9Sstevel@tonic-gate 837c478bd9Sstevel@tonic-gate #ifndef _PATH_BSHELL 847c478bd9Sstevel@tonic-gate #define _PATH_BSHELL "/bin/sh" 857c478bd9Sstevel@tonic-gate #endif /* _PATH_BSHELL */ 867c478bd9Sstevel@tonic-gate /* 877c478bd9Sstevel@tonic-gate * Defines from the 4.3-tahoe file system, for systems with the 4.2 or 4.3 887c478bd9Sstevel@tonic-gate * file system. 897c478bd9Sstevel@tonic-gate */ 907c478bd9Sstevel@tonic-gate #ifndef FS_42POSTBLFMT 917c478bd9Sstevel@tonic-gate #define cg_blktot(cgp) (((cgp))->cg_btot) 927c478bd9Sstevel@tonic-gate #define cg_blks(fs, cgp, cylno) (((cgp))->cg_b[cylno]) 937c478bd9Sstevel@tonic-gate #define cg_inosused(cgp) (((cgp))->cg_iused) 947c478bd9Sstevel@tonic-gate #define cg_blksfree(cgp) (((cgp))->cg_free) 957c478bd9Sstevel@tonic-gate #define cg_chkmagic(cgp) ((cgp)->cg_magic == CG_MAGIC) 967c478bd9Sstevel@tonic-gate #endif 977c478bd9Sstevel@tonic-gate 987c478bd9Sstevel@tonic-gate /* 997c478bd9Sstevel@tonic-gate * Never changing defines. 1007c478bd9Sstevel@tonic-gate */ 1017c478bd9Sstevel@tonic-gate #define OCTAL 8 /* octal base */ 1027c478bd9Sstevel@tonic-gate #define DECIMAL 10 /* decimal base */ 1037c478bd9Sstevel@tonic-gate #define HEX 16 /* hexadecimal base */ 1047c478bd9Sstevel@tonic-gate 1057c478bd9Sstevel@tonic-gate /* 1067c478bd9Sstevel@tonic-gate * Adjustable defines. 1077c478bd9Sstevel@tonic-gate */ 1087c478bd9Sstevel@tonic-gate #define NBUF 10 /* number of cache buffers */ 1097c478bd9Sstevel@tonic-gate #define PROMPTSIZE 80 /* size of user definable prompt */ 1107c478bd9Sstevel@tonic-gate #define MAXFILES 40000 /* max number of files ls can handle */ 1117c478bd9Sstevel@tonic-gate #define FIRST_DEPTH 10 /* default depth for find and ls */ 1127c478bd9Sstevel@tonic-gate #define SECOND_DEPTH 100 /* second try at depth (maximum) */ 1137c478bd9Sstevel@tonic-gate #define INPUTBUFFER 1040 /* size of input buffer */ 1147c478bd9Sstevel@tonic-gate #define BYTESPERLINE 16 /* bytes per line of /dxo output */ 1157c478bd9Sstevel@tonic-gate #define NREG 36 /* number of save registers */ 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate #define DEVPREFIX "/dev/" /* Uninteresting part of "special" */ 1187c478bd9Sstevel@tonic-gate 1197c478bd9Sstevel@tonic-gate #if defined(OLD_FSDB_COMPATIBILITY) 1207c478bd9Sstevel@tonic-gate #define FSDB_OPTIONS "o:wp:z:" 1217c478bd9Sstevel@tonic-gate #else 1227c478bd9Sstevel@tonic-gate #define FSDB_OPTIONS "o:wp:" 1237c478bd9Sstevel@tonic-gate #endif /* OLD_FSDB_COMPATIBILITY */ 1247c478bd9Sstevel@tonic-gate 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate /* 1277c478bd9Sstevel@tonic-gate * Values dependent on sizes of structs and such. 1287c478bd9Sstevel@tonic-gate */ 1297c478bd9Sstevel@tonic-gate #define NUMB 3 /* these three are arbitrary, */ 1307c478bd9Sstevel@tonic-gate #define BLOCK 5 /* but must be different from */ 1317c478bd9Sstevel@tonic-gate #define FRAGMENT 7 /* the rest (hence odd). */ 1327c478bd9Sstevel@tonic-gate #define BITSPERCHAR 8 /* couldn't find it anywhere */ 1337c478bd9Sstevel@tonic-gate #define CHAR (sizeof (char)) 1347c478bd9Sstevel@tonic-gate #define SHORT (sizeof (short)) 1357c478bd9Sstevel@tonic-gate #define LONG (sizeof (long)) 1367c478bd9Sstevel@tonic-gate #define U_OFFSET_T (sizeof (u_offset_t)) /* essentially "long long" */ 1377c478bd9Sstevel@tonic-gate #define INODE (sizeof (struct dinode)) 1387c478bd9Sstevel@tonic-gate #define DIRECTORY (sizeof (struct direct)) 1397c478bd9Sstevel@tonic-gate #define CGRP (sizeof (struct cg)) 1407c478bd9Sstevel@tonic-gate #define SB (sizeof (struct fs)) 1417c478bd9Sstevel@tonic-gate #define BLKSIZE (fs->fs_bsize) /* for clarity */ 1427c478bd9Sstevel@tonic-gate #define FRGSIZE (fs->fs_fsize) 1437c478bd9Sstevel@tonic-gate #define BLKSHIFT (fs->fs_bshift) 1447c478bd9Sstevel@tonic-gate #define FRGSHIFT (fs->fs_fshift) 1457c478bd9Sstevel@tonic-gate #define SHADOW_DATA (sizeof (struct ufs_fsd)) 1467c478bd9Sstevel@tonic-gate 1477c478bd9Sstevel@tonic-gate /* 1487c478bd9Sstevel@tonic-gate * Messy macros that would otherwise clutter up such glamorous code. 1497c478bd9Sstevel@tonic-gate */ 1507c478bd9Sstevel@tonic-gate #define itob(i) (((u_offset_t)itod(fs, (i)) << \ 1517c478bd9Sstevel@tonic-gate (u_offset_t)FRGSHIFT) + (u_offset_t)itoo(fs, (i)) * (u_offset_t)INODE) 1527c478bd9Sstevel@tonic-gate #define min(x, y) ((x) < (y) ? (x) : (y)) 1537c478bd9Sstevel@tonic-gate #define STRINGSIZE(d) ((long)d->d_reclen - \ 1547c478bd9Sstevel@tonic-gate ((long)&d->d_name[0] - (long)&d->d_ino)) 1557c478bd9Sstevel@tonic-gate #define letter(c) ((((c) >= 'a')&&((c) <= 'z')) ||\ 1567c478bd9Sstevel@tonic-gate (((c) >= 'A')&&((c) <= 'Z'))) 1577c478bd9Sstevel@tonic-gate #define digit(c) (((c) >= '0') && ((c) <= '9')) 1587c478bd9Sstevel@tonic-gate #define HEXLETTER(c) (((c) >= 'A') && ((c) <= 'F')) 1597c478bd9Sstevel@tonic-gate #define hexletter(c) (((c) >= 'a') && ((c) <= 'f')) 1607c478bd9Sstevel@tonic-gate #define octaldigit(c) (((c) >= '0') && ((c) <= '7')) 1617c478bd9Sstevel@tonic-gate #define uppertolower(c) ((c) - 'A' + 'a') 1627c478bd9Sstevel@tonic-gate #define hextodigit(c) ((c) - 'a' + 10) 1637c478bd9Sstevel@tonic-gate #define numtodigit(c) ((c) - '0') 1647c478bd9Sstevel@tonic-gate 1657c478bd9Sstevel@tonic-gate #if !defined(loword) 1667c478bd9Sstevel@tonic-gate #define loword(X) (((ushort_t *)&X)[1]) 1677c478bd9Sstevel@tonic-gate #endif /* loword */ 1687c478bd9Sstevel@tonic-gate 1697c478bd9Sstevel@tonic-gate #if !defined(lobyte) 1707c478bd9Sstevel@tonic-gate #define lobyte(X) (((unsigned char *)&X)[1]) 1717c478bd9Sstevel@tonic-gate #endif /* lobyte */ 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate /* 1747c478bd9Sstevel@tonic-gate * buffer cache structure. 1757c478bd9Sstevel@tonic-gate */ 1767c478bd9Sstevel@tonic-gate static struct lbuf { 1777c478bd9Sstevel@tonic-gate struct lbuf *fwd; 1787c478bd9Sstevel@tonic-gate struct lbuf *back; 1797c478bd9Sstevel@tonic-gate char *blkaddr; 1807c478bd9Sstevel@tonic-gate short valid; 1817c478bd9Sstevel@tonic-gate u_offset_t blkno; 1827c478bd9Sstevel@tonic-gate } lbuf[NBUF], bhdr; 1837c478bd9Sstevel@tonic-gate 1847c478bd9Sstevel@tonic-gate /* 1857c478bd9Sstevel@tonic-gate * used to hold save registers (see '<' and '>'). 1867c478bd9Sstevel@tonic-gate */ 1877c478bd9Sstevel@tonic-gate struct save_registers { 1887c478bd9Sstevel@tonic-gate u_offset_t sv_addr; 1897c478bd9Sstevel@tonic-gate u_offset_t sv_value; 1907c478bd9Sstevel@tonic-gate long sv_objsz; 1917c478bd9Sstevel@tonic-gate } regs[NREG]; 1927c478bd9Sstevel@tonic-gate 1937c478bd9Sstevel@tonic-gate /* 1947c478bd9Sstevel@tonic-gate * cd, find, and ls use this to hold filenames. Each filename is broken 1957c478bd9Sstevel@tonic-gate * up by a slash. In other words, /usr/src/adm would have a len field 1967c478bd9Sstevel@tonic-gate * of 2 (starting from 0), and filenames->fname[0-2] would hold usr, 1977c478bd9Sstevel@tonic-gate * src, and adm components of the pathname. 1987c478bd9Sstevel@tonic-gate */ 1997c478bd9Sstevel@tonic-gate static struct filenames { 2007c478bd9Sstevel@tonic-gate ino_t ino; /* inode */ 2017c478bd9Sstevel@tonic-gate long len; /* number of components */ 2027c478bd9Sstevel@tonic-gate char flag; /* flag if using SECOND_DEPTH allocator */ 2037c478bd9Sstevel@tonic-gate char find; /* flag if found by find */ 2047c478bd9Sstevel@tonic-gate char **fname; /* hold components of pathname */ 2057c478bd9Sstevel@tonic-gate } *filenames, *top; 2067c478bd9Sstevel@tonic-gate 2077c478bd9Sstevel@tonic-gate enum log_enum { LOG_NDELTAS, LOG_ALLDELTAS, LOG_CHECKSCAN }; 2087c478bd9Sstevel@tonic-gate #ifdef sun 2097c478bd9Sstevel@tonic-gate struct fs *fs; 2107c478bd9Sstevel@tonic-gate static union { 2117c478bd9Sstevel@tonic-gate struct fs un_filesystem; 2127c478bd9Sstevel@tonic-gate char un_sbsize[SBSIZE]; 2137c478bd9Sstevel@tonic-gate } fs_un; 2147c478bd9Sstevel@tonic-gate #define filesystem fs_un.un_filesystem 2157c478bd9Sstevel@tonic-gate #else 2167c478bd9Sstevel@tonic-gate struct fs filesystem, *fs; /* super block */ 2177c478bd9Sstevel@tonic-gate #endif /* sun */ 2187c478bd9Sstevel@tonic-gate 2197c478bd9Sstevel@tonic-gate /* 2207c478bd9Sstevel@tonic-gate * Global data. 2217c478bd9Sstevel@tonic-gate */ 2227c478bd9Sstevel@tonic-gate static char *input_path[MAXPATHLEN]; 2237c478bd9Sstevel@tonic-gate static char *stack_path[MAXPATHLEN]; 2247c478bd9Sstevel@tonic-gate static char *current_path[MAXPATHLEN]; 2257c478bd9Sstevel@tonic-gate static char input_buffer[INPUTBUFFER]; 2267c478bd9Sstevel@tonic-gate static char *prompt; 2277c478bd9Sstevel@tonic-gate static char *buffers; 2287c478bd9Sstevel@tonic-gate static char scratch[64]; 2297c478bd9Sstevel@tonic-gate static char BASE[] = "o u x"; 2307c478bd9Sstevel@tonic-gate static char PROMPT[PROMPTSIZE]; 2317c478bd9Sstevel@tonic-gate static char laststyle = '/'; 2327c478bd9Sstevel@tonic-gate static char lastpo = 'x'; 2337c478bd9Sstevel@tonic-gate static short input_pointer; 2347c478bd9Sstevel@tonic-gate static short current_pathp; 2357c478bd9Sstevel@tonic-gate static short stack_pathp; 2367c478bd9Sstevel@tonic-gate static short input_pathp; 2377c478bd9Sstevel@tonic-gate static short cmp_level; 2387c478bd9Sstevel@tonic-gate static int nfiles; 2397c478bd9Sstevel@tonic-gate static short type = NUMB; 2407c478bd9Sstevel@tonic-gate static short dirslot; 2417c478bd9Sstevel@tonic-gate static short fd; 2427c478bd9Sstevel@tonic-gate static short c_count; 2437c478bd9Sstevel@tonic-gate static short error; 2447c478bd9Sstevel@tonic-gate static short paren; 2457c478bd9Sstevel@tonic-gate static short trapped; 2467c478bd9Sstevel@tonic-gate static short doing_cd; 2477c478bd9Sstevel@tonic-gate static short doing_find; 2487c478bd9Sstevel@tonic-gate static short find_by_name; 2497c478bd9Sstevel@tonic-gate static short find_by_inode; 2507c478bd9Sstevel@tonic-gate static short long_list; 2517c478bd9Sstevel@tonic-gate static short recursive; 2527c478bd9Sstevel@tonic-gate static short objsz = SHORT; 2537c478bd9Sstevel@tonic-gate static short override = 0; 2547c478bd9Sstevel@tonic-gate static short wrtflag = O_RDONLY; 2557c478bd9Sstevel@tonic-gate static short base = HEX; 2567c478bd9Sstevel@tonic-gate static short acting_on_inode; 2577c478bd9Sstevel@tonic-gate static short acting_on_directory; 2587c478bd9Sstevel@tonic-gate static short should_print = 1; 2597c478bd9Sstevel@tonic-gate static short clear; 2607c478bd9Sstevel@tonic-gate static short star; 2617c478bd9Sstevel@tonic-gate static u_offset_t addr; 2627c478bd9Sstevel@tonic-gate static u_offset_t bod_addr; 2637c478bd9Sstevel@tonic-gate static u_offset_t value; 2647c478bd9Sstevel@tonic-gate static u_offset_t erraddr; 2657c478bd9Sstevel@tonic-gate static long errcur_bytes; 2667c478bd9Sstevel@tonic-gate static u_offset_t errino; 2677c478bd9Sstevel@tonic-gate static long errinum; 2687c478bd9Sstevel@tonic-gate static long cur_cgrp; 2697c478bd9Sstevel@tonic-gate static u_offset_t cur_ino; 2707c478bd9Sstevel@tonic-gate static long cur_inum; 2717c478bd9Sstevel@tonic-gate static u_offset_t cur_dir; 2727c478bd9Sstevel@tonic-gate static long cur_block; 2737c478bd9Sstevel@tonic-gate static long cur_bytes; 2747c478bd9Sstevel@tonic-gate static long find_ino; 2757c478bd9Sstevel@tonic-gate static u_offset_t filesize; 2767c478bd9Sstevel@tonic-gate static u_offset_t blocksize; 2777c478bd9Sstevel@tonic-gate static long stringsize; 2787c478bd9Sstevel@tonic-gate static long count = 1; 2797c478bd9Sstevel@tonic-gate static long commands; 2807c478bd9Sstevel@tonic-gate static long read_requests; 2817c478bd9Sstevel@tonic-gate static long actual_disk_reads; 2827c478bd9Sstevel@tonic-gate static jmp_buf env; 2837c478bd9Sstevel@tonic-gate static long maxfiles; 2847c478bd9Sstevel@tonic-gate static long cur_shad; 2857c478bd9Sstevel@tonic-gate 2867c478bd9Sstevel@tonic-gate #ifndef sun 2877c478bd9Sstevel@tonic-gate extern char *malloc(), *calloc(); 2887c478bd9Sstevel@tonic-gate #endif 2897c478bd9Sstevel@tonic-gate static char getachar(); 2907c478bd9Sstevel@tonic-gate static char *getblk(), *fmtentry(); 2917c478bd9Sstevel@tonic-gate 292d1a180b0Smaheshvs static offset_t get(short); 2937c478bd9Sstevel@tonic-gate static long bmap(); 2947c478bd9Sstevel@tonic-gate static long expr(); 2957c478bd9Sstevel@tonic-gate static long term(); 2967c478bd9Sstevel@tonic-gate static long getnumb(); 2977c478bd9Sstevel@tonic-gate static u_offset_t getdirslot(); 298d1a180b0Smaheshvs static unsigned long *print_check(unsigned long *, long *, short, int); 2997c478bd9Sstevel@tonic-gate 300d1a180b0Smaheshvs static void usage(char *); 301d1a180b0Smaheshvs static void ungetachar(char); 3027c478bd9Sstevel@tonic-gate static void getnextinput(); 3037c478bd9Sstevel@tonic-gate static void eat_spaces(); 304d1a180b0Smaheshvs static void restore_inode(ino_t); 3057c478bd9Sstevel@tonic-gate static void find(); 306d1a180b0Smaheshvs static void ls(struct filenames *, struct filenames *, short); 307d1a180b0Smaheshvs static void formatf(struct filenames *, struct filenames *); 3087c478bd9Sstevel@tonic-gate static void parse(); 309d1a180b0Smaheshvs static void follow_path(long, long); 3107c478bd9Sstevel@tonic-gate static void getname(); 311d1a180b0Smaheshvs static void freemem(struct filenames *, int); 312d1a180b0Smaheshvs static void print_path(char **, int); 3137c478bd9Sstevel@tonic-gate static void fill(); 314d1a180b0Smaheshvs static void put(u_offset_t, short); 315d1a180b0Smaheshvs static void insert(struct lbuf *); 3167c478bd9Sstevel@tonic-gate static void puta(); 317d1a180b0Smaheshvs static void fprnt(char, char); 3187c478bd9Sstevel@tonic-gate static void index(); 3197c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE 3207c478bd9Sstevel@tonic-gate static void printll 3217c478bd9Sstevel@tonic-gate (u_offset_t value, int fieldsz, int digits, int lead); 3227c478bd9Sstevel@tonic-gate #define print(value, fieldsz, digits, lead) \ 3237c478bd9Sstevel@tonic-gate printll((u_offset_t)value, fieldsz, digits, lead) 3247c478bd9Sstevel@tonic-gate #else /* !_LARGEFILE64_SOURCE */ 3257c478bd9Sstevel@tonic-gate static void print(long value, int fieldsz, int digits, int lead); 3267c478bd9Sstevel@tonic-gate #endif /* _LARGEFILE64_SOURCE */ 327d1a180b0Smaheshvs static void printsb(struct fs *); 328d1a180b0Smaheshvs static void printcg(struct cg *); 329d1a180b0Smaheshvs static void pbits(unsigned char *, int); 330d1a180b0Smaheshvs static void old_fsdb(int, char *); /* For old fsdb functionality */ 3317c478bd9Sstevel@tonic-gate 332d1a180b0Smaheshvs static int isnumber(char *); 333d1a180b0Smaheshvs static int icheck(u_offset_t); 334d1a180b0Smaheshvs static int cgrp_check(long); 3357c478bd9Sstevel@tonic-gate static int valid_addr(); 336d1a180b0Smaheshvs static int match(char *, int); 337d1a180b0Smaheshvs static int devcheck(short); 3387c478bd9Sstevel@tonic-gate static int bcomp(); 339d1a180b0Smaheshvs static int compare(char *, char *, short); 340d1a180b0Smaheshvs static int check_addr(short, short *, short *, short); 3417c478bd9Sstevel@tonic-gate static int fcmp(); 3427c478bd9Sstevel@tonic-gate static int ffcmp(); 3437c478bd9Sstevel@tonic-gate 344d1a180b0Smaheshvs static int getshadowslot(long); 345d1a180b0Smaheshvs static void getshadowdata(long *, int); 346d1a180b0Smaheshvs static void syncshadowscan(int); 347d1a180b0Smaheshvs static void log_display_header(void); 348d1a180b0Smaheshvs static void log_show(enum log_enum); 3497c478bd9Sstevel@tonic-gate 3507c478bd9Sstevel@tonic-gate #ifdef sun 3517c478bd9Sstevel@tonic-gate static void err(); 3527c478bd9Sstevel@tonic-gate #else 3537c478bd9Sstevel@tonic-gate static int err(); 3547c478bd9Sstevel@tonic-gate #endif /* sun */ 3557c478bd9Sstevel@tonic-gate 3567c478bd9Sstevel@tonic-gate /* Suboption vector */ 3577c478bd9Sstevel@tonic-gate static char *subopt_v[] = { 3587c478bd9Sstevel@tonic-gate #define OVERRIDE 0 3597c478bd9Sstevel@tonic-gate "o", 3607c478bd9Sstevel@tonic-gate #define NEW_PROMPT 1 3617c478bd9Sstevel@tonic-gate "p", 3627c478bd9Sstevel@tonic-gate #define WRITE_ENABLED 2 3637c478bd9Sstevel@tonic-gate "w", 3647c478bd9Sstevel@tonic-gate #define ALT_PROMPT 3 3657c478bd9Sstevel@tonic-gate "prompt", 3667c478bd9Sstevel@tonic-gate NULL 3677c478bd9Sstevel@tonic-gate }; 3687c478bd9Sstevel@tonic-gate 3697c478bd9Sstevel@tonic-gate /* 3707c478bd9Sstevel@tonic-gate * main - lines are read up to the unprotected ('\') newline and 3717c478bd9Sstevel@tonic-gate * held in an input buffer. Characters may be read from the 3727c478bd9Sstevel@tonic-gate * input buffer using getachar() and unread using ungetachar(). 3737c478bd9Sstevel@tonic-gate * Reading the whole line ahead allows the use of debuggers 3747c478bd9Sstevel@tonic-gate * which would otherwise be impossible since the debugger 3757c478bd9Sstevel@tonic-gate * and fsdb could not share stdin. 3767c478bd9Sstevel@tonic-gate */ 3777c478bd9Sstevel@tonic-gate 378d1a180b0Smaheshvs int 379d1a180b0Smaheshvs main(int argc, char *argv[]) 3807c478bd9Sstevel@tonic-gate { 3817c478bd9Sstevel@tonic-gate 382d1a180b0Smaheshvs char c, *cptr; 383d1a180b0Smaheshvs short i; 384d1a180b0Smaheshvs struct direct *dirp; 385d1a180b0Smaheshvs struct lbuf *bp; 3867c478bd9Sstevel@tonic-gate char *progname; 387*67a4bb8fSGary Mills volatile short colon; 388*67a4bb8fSGary Mills short mode; 3897c478bd9Sstevel@tonic-gate long temp; 3907c478bd9Sstevel@tonic-gate 3917c478bd9Sstevel@tonic-gate /* Options/Suboptions processing */ 3927c478bd9Sstevel@tonic-gate int opt; 3937c478bd9Sstevel@tonic-gate char *subopts; 3947c478bd9Sstevel@tonic-gate char *optval; 3957c478bd9Sstevel@tonic-gate 3967c478bd9Sstevel@tonic-gate /* 3977c478bd9Sstevel@tonic-gate * The following are used to support the old fsdb functionality 3987c478bd9Sstevel@tonic-gate * of clearing an inode. It's better to use 'clri'. 3997c478bd9Sstevel@tonic-gate */ 4007c478bd9Sstevel@tonic-gate int inum; /* Inode number to clear */ 4017c478bd9Sstevel@tonic-gate char *special; 4027c478bd9Sstevel@tonic-gate 4037c478bd9Sstevel@tonic-gate setbuf(stdin, NULL); 4047c478bd9Sstevel@tonic-gate progname = argv[0]; 4057c478bd9Sstevel@tonic-gate prompt = &PROMPT[0]; 4067c478bd9Sstevel@tonic-gate /* 4077c478bd9Sstevel@tonic-gate * Parse options. 4087c478bd9Sstevel@tonic-gate */ 4097c478bd9Sstevel@tonic-gate while ((opt = getopt(argc, argv, FSDB_OPTIONS)) != EOF) { 4107c478bd9Sstevel@tonic-gate switch (opt) { 4117c478bd9Sstevel@tonic-gate #if defined(OLD_FSDB_COMPATIBILITY) 4127c478bd9Sstevel@tonic-gate case 'z': /* Hack - Better to use clri */ 4137c478bd9Sstevel@tonic-gate (void) fprintf(stderr, "%s\n%s\n%s\n%s\n", 4147c478bd9Sstevel@tonic-gate "Warning: The '-z' option of 'fsdb_ufs' has been declared obsolete", 4157c478bd9Sstevel@tonic-gate "and may not be supported in a future version of Solaris.", 4167c478bd9Sstevel@tonic-gate "While this functionality is currently still supported, the", 4177c478bd9Sstevel@tonic-gate "recommended procedure to clear an inode is to use clri(1M)."); 4187c478bd9Sstevel@tonic-gate if (isnumber(optarg)) { 4197c478bd9Sstevel@tonic-gate inum = atoi(optarg); 4207c478bd9Sstevel@tonic-gate special = argv[optind]; 4217c478bd9Sstevel@tonic-gate /* Doesn't return */ 4227c478bd9Sstevel@tonic-gate old_fsdb(inum, special); 4237c478bd9Sstevel@tonic-gate } else { 4247c478bd9Sstevel@tonic-gate usage(progname); 4257c478bd9Sstevel@tonic-gate exit(31+1); 4267c478bd9Sstevel@tonic-gate } 4277c478bd9Sstevel@tonic-gate /* Should exit() before here */ 4287c478bd9Sstevel@tonic-gate /*NOTREACHED*/ 4297c478bd9Sstevel@tonic-gate #endif /* OLD_FSDB_COMPATIBILITY */ 4307c478bd9Sstevel@tonic-gate case 'o': 4317c478bd9Sstevel@tonic-gate /* UFS Specific Options */ 4327c478bd9Sstevel@tonic-gate subopts = optarg; 4337c478bd9Sstevel@tonic-gate while (*subopts != '\0') { 4347c478bd9Sstevel@tonic-gate switch (getsubopt(&subopts, subopt_v, 4357c478bd9Sstevel@tonic-gate &optval)) { 4367c478bd9Sstevel@tonic-gate case OVERRIDE: 4377c478bd9Sstevel@tonic-gate printf("error checking off\n"); 4387c478bd9Sstevel@tonic-gate override = 1; 4397c478bd9Sstevel@tonic-gate break; 4407c478bd9Sstevel@tonic-gate 4417c478bd9Sstevel@tonic-gate /* 4427c478bd9Sstevel@tonic-gate * Change the "-o prompt=foo" option to 4437c478bd9Sstevel@tonic-gate * "-o p=foo" to match documentation. 4447c478bd9Sstevel@tonic-gate * ALT_PROMPT continues support for the 4457c478bd9Sstevel@tonic-gate * undocumented "-o prompt=foo" option so 4467c478bd9Sstevel@tonic-gate * that we don't break anyone. 4477c478bd9Sstevel@tonic-gate */ 4487c478bd9Sstevel@tonic-gate case NEW_PROMPT: 4497c478bd9Sstevel@tonic-gate case ALT_PROMPT: 4507c478bd9Sstevel@tonic-gate if (optval == NULL) { 4517c478bd9Sstevel@tonic-gate (void) fprintf(stderr, 4527c478bd9Sstevel@tonic-gate "No prompt string\n"); 4537c478bd9Sstevel@tonic-gate usage(progname); 4547c478bd9Sstevel@tonic-gate } 4557c478bd9Sstevel@tonic-gate (void) strncpy(PROMPT, optval, 4567c478bd9Sstevel@tonic-gate PROMPTSIZE); 4577c478bd9Sstevel@tonic-gate break; 4587c478bd9Sstevel@tonic-gate 4597c478bd9Sstevel@tonic-gate case WRITE_ENABLED: 4607c478bd9Sstevel@tonic-gate /* suitable for open */ 4617c478bd9Sstevel@tonic-gate wrtflag = O_RDWR; 4627c478bd9Sstevel@tonic-gate break; 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate default: 4657c478bd9Sstevel@tonic-gate usage(progname); 4667c478bd9Sstevel@tonic-gate /* Should exit here */ 4677c478bd9Sstevel@tonic-gate } 4687c478bd9Sstevel@tonic-gate } 4697c478bd9Sstevel@tonic-gate break; 4707c478bd9Sstevel@tonic-gate 4717c478bd9Sstevel@tonic-gate default: 4727c478bd9Sstevel@tonic-gate usage(progname); 4737c478bd9Sstevel@tonic-gate } 4747c478bd9Sstevel@tonic-gate } 4757c478bd9Sstevel@tonic-gate 4767c478bd9Sstevel@tonic-gate if ((argc - optind) != 1) { /* Should just have "special" left */ 4777c478bd9Sstevel@tonic-gate usage(progname); 4787c478bd9Sstevel@tonic-gate } 4797c478bd9Sstevel@tonic-gate special = argv[optind]; 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate /* 4827c478bd9Sstevel@tonic-gate * Unless it's already been set, the default prompt includes the 4837c478bd9Sstevel@tonic-gate * name of the special device. 4847c478bd9Sstevel@tonic-gate */ 4857c478bd9Sstevel@tonic-gate if (*prompt == NULL) 4867c478bd9Sstevel@tonic-gate (void) sprintf(prompt, "%s > ", special); 4877c478bd9Sstevel@tonic-gate 4887c478bd9Sstevel@tonic-gate /* 4897c478bd9Sstevel@tonic-gate * Attempt to open the special file. 4907c478bd9Sstevel@tonic-gate */ 4917c478bd9Sstevel@tonic-gate if ((fd = open(special, wrtflag)) < 0) { 4927c478bd9Sstevel@tonic-gate perror(special); 4937c478bd9Sstevel@tonic-gate exit(1); 4947c478bd9Sstevel@tonic-gate } 4957c478bd9Sstevel@tonic-gate /* 4967c478bd9Sstevel@tonic-gate * Read in the super block and validate (not too picky). 4977c478bd9Sstevel@tonic-gate */ 4987c478bd9Sstevel@tonic-gate if (llseek(fd, (offset_t)(SBLOCK * DEV_BSIZE), 0) == -1) { 4997c478bd9Sstevel@tonic-gate perror(special); 5007c478bd9Sstevel@tonic-gate exit(1); 5017c478bd9Sstevel@tonic-gate } 5027c478bd9Sstevel@tonic-gate 5037c478bd9Sstevel@tonic-gate #ifdef sun 5047c478bd9Sstevel@tonic-gate if (read(fd, &filesystem, SBSIZE) != SBSIZE) { 5057c478bd9Sstevel@tonic-gate printf("%s: cannot read superblock\n", special); 5067c478bd9Sstevel@tonic-gate exit(1); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate #else 5097c478bd9Sstevel@tonic-gate if (read(fd, &filesystem, sizeof (filesystem)) != sizeof (filesystem)) { 5107c478bd9Sstevel@tonic-gate printf("%s: cannot read superblock\n", special); 5117c478bd9Sstevel@tonic-gate exit(1); 5127c478bd9Sstevel@tonic-gate } 5137c478bd9Sstevel@tonic-gate #endif /* sun */ 5147c478bd9Sstevel@tonic-gate 5157c478bd9Sstevel@tonic-gate fs = &filesystem; 5167c478bd9Sstevel@tonic-gate if ((fs->fs_magic != FS_MAGIC) && (fs->fs_magic != MTB_UFS_MAGIC)) { 5177c478bd9Sstevel@tonic-gate if (!override) { 5187c478bd9Sstevel@tonic-gate printf("%s: Bad magic number in file system\n", 5197c478bd9Sstevel@tonic-gate special); 5207c478bd9Sstevel@tonic-gate exit(1); 5217c478bd9Sstevel@tonic-gate } 5227c478bd9Sstevel@tonic-gate 5237c478bd9Sstevel@tonic-gate printf("WARNING: Bad magic number in file system. "); 5247c478bd9Sstevel@tonic-gate printf("Continue? (y/n): "); 5257c478bd9Sstevel@tonic-gate (void) fflush(stdout); 5267c478bd9Sstevel@tonic-gate if (gets(input_buffer) == NULL) { 5277c478bd9Sstevel@tonic-gate exit(1); 5287c478bd9Sstevel@tonic-gate } 5297c478bd9Sstevel@tonic-gate 5307c478bd9Sstevel@tonic-gate if (*input_buffer != 'y' && *input_buffer != 'Y') { 5317c478bd9Sstevel@tonic-gate exit(1); 5327c478bd9Sstevel@tonic-gate } 5337c478bd9Sstevel@tonic-gate } 5347c478bd9Sstevel@tonic-gate 5356451fdbcSvsakar if ((fs->fs_magic == FS_MAGIC && 5366451fdbcSvsakar (fs->fs_version != UFS_EFISTYLE4NONEFI_VERSION_2 && 5376451fdbcSvsakar fs->fs_version != UFS_VERSION_MIN)) || 5386451fdbcSvsakar (fs->fs_magic == MTB_UFS_MAGIC && 5397c478bd9Sstevel@tonic-gate (fs->fs_version > MTB_UFS_VERSION_1 || 5406451fdbcSvsakar fs->fs_version < MTB_UFS_VERSION_MIN))) { 5417c478bd9Sstevel@tonic-gate if (!override) { 5427c478bd9Sstevel@tonic-gate printf("%s: Unrecognized UFS version number: %d\n", 5437c478bd9Sstevel@tonic-gate special, fs->fs_version); 5447c478bd9Sstevel@tonic-gate exit(1); 5457c478bd9Sstevel@tonic-gate } 5467c478bd9Sstevel@tonic-gate 5477c478bd9Sstevel@tonic-gate printf("WARNING: Unrecognized UFS version number. "); 5487c478bd9Sstevel@tonic-gate printf("Continue? (y/n): "); 5497c478bd9Sstevel@tonic-gate (void) fflush(stdout); 5507c478bd9Sstevel@tonic-gate if (gets(input_buffer) == NULL) { 5517c478bd9Sstevel@tonic-gate exit(1); 5527c478bd9Sstevel@tonic-gate } 5537c478bd9Sstevel@tonic-gate 5547c478bd9Sstevel@tonic-gate if (*input_buffer != 'y' && *input_buffer != 'Y') { 5557c478bd9Sstevel@tonic-gate exit(1); 5567c478bd9Sstevel@tonic-gate } 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate #ifdef FS_42POSTBLFMT 5597c478bd9Sstevel@tonic-gate if (fs->fs_postblformat == FS_42POSTBLFMT) 5607c478bd9Sstevel@tonic-gate fs->fs_nrpos = 8; 5617c478bd9Sstevel@tonic-gate #endif 5627c478bd9Sstevel@tonic-gate printf("fsdb of %s %s -- last mounted on %s\n", 5637c478bd9Sstevel@tonic-gate special, 5647c478bd9Sstevel@tonic-gate (wrtflag == O_RDWR) ? "(Opened for write)" : "(Read only)", 5657c478bd9Sstevel@tonic-gate &fs->fs_fsmnt[0]); 5667c478bd9Sstevel@tonic-gate #ifdef sun 5677c478bd9Sstevel@tonic-gate printf("fs_clean is currently set to "); 5687c478bd9Sstevel@tonic-gate switch (fs->fs_clean) { 5697c478bd9Sstevel@tonic-gate 5707c478bd9Sstevel@tonic-gate case FSACTIVE: 5717c478bd9Sstevel@tonic-gate printf("FSACTIVE\n"); 5727c478bd9Sstevel@tonic-gate break; 5737c478bd9Sstevel@tonic-gate case FSCLEAN: 5747c478bd9Sstevel@tonic-gate printf("FSCLEAN\n"); 5757c478bd9Sstevel@tonic-gate break; 5767c478bd9Sstevel@tonic-gate case FSSTABLE: 5777c478bd9Sstevel@tonic-gate printf("FSSTABLE\n"); 5787c478bd9Sstevel@tonic-gate break; 5797c478bd9Sstevel@tonic-gate case FSBAD: 5807c478bd9Sstevel@tonic-gate printf("FSBAD\n"); 5817c478bd9Sstevel@tonic-gate break; 5827c478bd9Sstevel@tonic-gate case FSSUSPEND: 5837c478bd9Sstevel@tonic-gate printf("FSSUSPEND\n"); 5847c478bd9Sstevel@tonic-gate break; 5857c478bd9Sstevel@tonic-gate case FSLOG: 5867c478bd9Sstevel@tonic-gate printf("FSLOG\n"); 5877c478bd9Sstevel@tonic-gate break; 5887c478bd9Sstevel@tonic-gate case FSFIX: 5897c478bd9Sstevel@tonic-gate printf("FSFIX\n"); 5907c478bd9Sstevel@tonic-gate if (!override) { 5917c478bd9Sstevel@tonic-gate printf("%s: fsck may be running on this file system\n", 5927c478bd9Sstevel@tonic-gate special); 5937c478bd9Sstevel@tonic-gate exit(1); 5947c478bd9Sstevel@tonic-gate } 5957c478bd9Sstevel@tonic-gate 5967c478bd9Sstevel@tonic-gate printf("WARNING: fsck may be running on this file system. "); 5977c478bd9Sstevel@tonic-gate printf("Continue? (y/n): "); 5987c478bd9Sstevel@tonic-gate (void) fflush(stdout); 5997c478bd9Sstevel@tonic-gate if (gets(input_buffer) == NULL) { 6007c478bd9Sstevel@tonic-gate exit(1); 6017c478bd9Sstevel@tonic-gate } 6027c478bd9Sstevel@tonic-gate 6037c478bd9Sstevel@tonic-gate if (*input_buffer != 'y' && *input_buffer != 'Y') { 6047c478bd9Sstevel@tonic-gate exit(1); 6057c478bd9Sstevel@tonic-gate } 6067c478bd9Sstevel@tonic-gate break; 6077c478bd9Sstevel@tonic-gate default: 6087c478bd9Sstevel@tonic-gate printf("an unknown value (0x%x)\n", fs->fs_clean); 6097c478bd9Sstevel@tonic-gate break; 6107c478bd9Sstevel@tonic-gate } 6117c478bd9Sstevel@tonic-gate 6127c478bd9Sstevel@tonic-gate if (fs->fs_state == (FSOKAY - fs->fs_time)) { 6137c478bd9Sstevel@tonic-gate printf("fs_state consistent (fs_clean CAN be trusted)\n"); 6147c478bd9Sstevel@tonic-gate } else { 6157c478bd9Sstevel@tonic-gate printf("fs_state inconsistent (fs_clean CAN'T trusted)\n"); 6167c478bd9Sstevel@tonic-gate } 6177c478bd9Sstevel@tonic-gate #endif /* sun */ 6187c478bd9Sstevel@tonic-gate /* 6197c478bd9Sstevel@tonic-gate * Malloc buffers and set up cache. 6207c478bd9Sstevel@tonic-gate */ 6217c478bd9Sstevel@tonic-gate buffers = malloc(NBUF * BLKSIZE); 6227c478bd9Sstevel@tonic-gate bhdr.fwd = bhdr.back = &bhdr; 6237c478bd9Sstevel@tonic-gate for (i = 0; i < NBUF; i++) { 6247c478bd9Sstevel@tonic-gate bp = &lbuf[i]; 6257c478bd9Sstevel@tonic-gate bp->blkaddr = buffers + (i * BLKSIZE); 6267c478bd9Sstevel@tonic-gate bp->valid = 0; 6277c478bd9Sstevel@tonic-gate insert(bp); 6287c478bd9Sstevel@tonic-gate } 6297c478bd9Sstevel@tonic-gate /* 6307c478bd9Sstevel@tonic-gate * Malloc filenames structure. The space for the actual filenames 6317c478bd9Sstevel@tonic-gate * is allocated as it needs it. We estimate the size based on the 6327c478bd9Sstevel@tonic-gate * number of inodes(objects) in the filesystem and the number of 6337c478bd9Sstevel@tonic-gate * directories. The number of directories are padded by 3 because 6347c478bd9Sstevel@tonic-gate * each directory traversed during a "find" or "ls -R" needs 3 6357c478bd9Sstevel@tonic-gate * entries. 6367c478bd9Sstevel@tonic-gate */ 6377c478bd9Sstevel@tonic-gate maxfiles = (long)((((u_offset_t)fs->fs_ncg * (u_offset_t)fs->fs_ipg) - 6387c478bd9Sstevel@tonic-gate (u_offset_t)fs->fs_cstotal.cs_nifree) + 6397c478bd9Sstevel@tonic-gate ((u_offset_t)fs->fs_cstotal.cs_ndir * (u_offset_t)3)); 6407c478bd9Sstevel@tonic-gate 6417c478bd9Sstevel@tonic-gate filenames = (struct filenames *)calloc(maxfiles, 6427c478bd9Sstevel@tonic-gate sizeof (struct filenames)); 6437c478bd9Sstevel@tonic-gate if (filenames == NULL) { 6447c478bd9Sstevel@tonic-gate /* 6457c478bd9Sstevel@tonic-gate * If we could not allocate memory for all of files 6467c478bd9Sstevel@tonic-gate * in the filesystem then, back off to the old fixed 6477c478bd9Sstevel@tonic-gate * value. 6487c478bd9Sstevel@tonic-gate */ 6497c478bd9Sstevel@tonic-gate maxfiles = MAXFILES; 6507c478bd9Sstevel@tonic-gate filenames = (struct filenames *)calloc(maxfiles, 6517c478bd9Sstevel@tonic-gate sizeof (struct filenames)); 6527c478bd9Sstevel@tonic-gate if (filenames == NULL) { 6537c478bd9Sstevel@tonic-gate printf("out of memory\n"); 6547c478bd9Sstevel@tonic-gate exit(1); 6557c478bd9Sstevel@tonic-gate } 6567c478bd9Sstevel@tonic-gate } 6577c478bd9Sstevel@tonic-gate 6587c478bd9Sstevel@tonic-gate restore_inode(2); 6597c478bd9Sstevel@tonic-gate /* 6607c478bd9Sstevel@tonic-gate * Malloc a few filenames (needed by pwd for example). 6617c478bd9Sstevel@tonic-gate */ 6627c478bd9Sstevel@tonic-gate for (i = 0; i < MAXPATHLEN; i++) { 6637c478bd9Sstevel@tonic-gate input_path[i] = calloc(1, MAXNAMLEN); 6647c478bd9Sstevel@tonic-gate stack_path[i] = calloc(1, MAXNAMLEN); 6657c478bd9Sstevel@tonic-gate current_path[i] = calloc(1, MAXNAMLEN); 6667c478bd9Sstevel@tonic-gate if (current_path[i] == NULL) { 6677c478bd9Sstevel@tonic-gate printf("out of memory\n"); 6687c478bd9Sstevel@tonic-gate exit(1); 6697c478bd9Sstevel@tonic-gate } 6707c478bd9Sstevel@tonic-gate } 6717c478bd9Sstevel@tonic-gate current_pathp = -1; 6727c478bd9Sstevel@tonic-gate 6737c478bd9Sstevel@tonic-gate (void) signal(2, err); 6747c478bd9Sstevel@tonic-gate (void) setjmp(env); 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate getnextinput(); 6777c478bd9Sstevel@tonic-gate /* 6787c478bd9Sstevel@tonic-gate * Main loop and case statement. If an error condition occurs 6797c478bd9Sstevel@tonic-gate * initialization and recovery is attempted. 6807c478bd9Sstevel@tonic-gate */ 6817c478bd9Sstevel@tonic-gate for (;;) { 6827c478bd9Sstevel@tonic-gate if (error) { 6837c478bd9Sstevel@tonic-gate freemem(filenames, nfiles); 6847c478bd9Sstevel@tonic-gate nfiles = 0; 6857c478bd9Sstevel@tonic-gate c_count = 0; 6867c478bd9Sstevel@tonic-gate count = 1; 6877c478bd9Sstevel@tonic-gate star = 0; 6887c478bd9Sstevel@tonic-gate error = 0; 6897c478bd9Sstevel@tonic-gate paren = 0; 6907c478bd9Sstevel@tonic-gate acting_on_inode = 0; 6917c478bd9Sstevel@tonic-gate acting_on_directory = 0; 6927c478bd9Sstevel@tonic-gate should_print = 1; 6937c478bd9Sstevel@tonic-gate addr = erraddr; 6947c478bd9Sstevel@tonic-gate cur_ino = errino; 6957c478bd9Sstevel@tonic-gate cur_inum = errinum; 6967c478bd9Sstevel@tonic-gate cur_bytes = errcur_bytes; 6977c478bd9Sstevel@tonic-gate printf("?\n"); 6987c478bd9Sstevel@tonic-gate getnextinput(); 6997c478bd9Sstevel@tonic-gate if (error) 7007c478bd9Sstevel@tonic-gate continue; 7017c478bd9Sstevel@tonic-gate } 7027c478bd9Sstevel@tonic-gate c_count++; 7037c478bd9Sstevel@tonic-gate 7047c478bd9Sstevel@tonic-gate switch (c = getachar()) { 7057c478bd9Sstevel@tonic-gate 7067c478bd9Sstevel@tonic-gate case '\n': /* command end */ 7077c478bd9Sstevel@tonic-gate freemem(filenames, nfiles); 7087c478bd9Sstevel@tonic-gate nfiles = 0; 7097c478bd9Sstevel@tonic-gate if (should_print && laststyle == '=') { 7107c478bd9Sstevel@tonic-gate ungetachar(c); 7117c478bd9Sstevel@tonic-gate goto calc; 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate if (c_count == 1) { 7147c478bd9Sstevel@tonic-gate clear = 0; 7157c478bd9Sstevel@tonic-gate should_print = 1; 7167c478bd9Sstevel@tonic-gate erraddr = addr; 7177c478bd9Sstevel@tonic-gate errino = cur_ino; 7187c478bd9Sstevel@tonic-gate errinum = cur_inum; 7197c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 7207c478bd9Sstevel@tonic-gate switch (objsz) { 7217c478bd9Sstevel@tonic-gate case DIRECTORY: 7227c478bd9Sstevel@tonic-gate if ((addr = getdirslot( 7237c478bd9Sstevel@tonic-gate (long)dirslot+1)) == 0) 7247c478bd9Sstevel@tonic-gate should_print = 0; 7257c478bd9Sstevel@tonic-gate if (error) { 7267c478bd9Sstevel@tonic-gate ungetachar(c); 7277c478bd9Sstevel@tonic-gate continue; 7287c478bd9Sstevel@tonic-gate } 7297c478bd9Sstevel@tonic-gate break; 7307c478bd9Sstevel@tonic-gate case INODE: 7317c478bd9Sstevel@tonic-gate cur_inum++; 7327c478bd9Sstevel@tonic-gate addr = itob(cur_inum); 7337c478bd9Sstevel@tonic-gate if (!icheck(addr)) { 7347c478bd9Sstevel@tonic-gate cur_inum--; 7357c478bd9Sstevel@tonic-gate should_print = 0; 7367c478bd9Sstevel@tonic-gate } 7377c478bd9Sstevel@tonic-gate break; 7387c478bd9Sstevel@tonic-gate case CGRP: 7397c478bd9Sstevel@tonic-gate case SB: 7407c478bd9Sstevel@tonic-gate cur_cgrp++; 7417c478bd9Sstevel@tonic-gate addr = cgrp_check(cur_cgrp); 7427c478bd9Sstevel@tonic-gate if (addr == 0) { 7437c478bd9Sstevel@tonic-gate cur_cgrp--; 7447c478bd9Sstevel@tonic-gate continue; 7457c478bd9Sstevel@tonic-gate } 7467c478bd9Sstevel@tonic-gate break; 7477c478bd9Sstevel@tonic-gate case SHADOW_DATA: 7487c478bd9Sstevel@tonic-gate if ((addr = getshadowslot( 7497c478bd9Sstevel@tonic-gate (long)cur_shad + 1)) == 0) 7507c478bd9Sstevel@tonic-gate should_print = 0; 7517c478bd9Sstevel@tonic-gate if (error) { 7527c478bd9Sstevel@tonic-gate ungetachar(c); 7537c478bd9Sstevel@tonic-gate continue; 7547c478bd9Sstevel@tonic-gate } 7557c478bd9Sstevel@tonic-gate break; 7567c478bd9Sstevel@tonic-gate default: 7577c478bd9Sstevel@tonic-gate addr += objsz; 7587c478bd9Sstevel@tonic-gate cur_bytes += objsz; 7597c478bd9Sstevel@tonic-gate if (valid_addr() == 0) 7607c478bd9Sstevel@tonic-gate continue; 7617c478bd9Sstevel@tonic-gate } 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate if (type == NUMB) 7647c478bd9Sstevel@tonic-gate trapped = 0; 7657c478bd9Sstevel@tonic-gate if (should_print) 7667c478bd9Sstevel@tonic-gate switch (objsz) { 7677c478bd9Sstevel@tonic-gate case DIRECTORY: 7687c478bd9Sstevel@tonic-gate fprnt('?', 'd'); 7697c478bd9Sstevel@tonic-gate break; 7707c478bd9Sstevel@tonic-gate case INODE: 7717c478bd9Sstevel@tonic-gate fprnt('?', 'i'); 7727c478bd9Sstevel@tonic-gate if (!error) 7737c478bd9Sstevel@tonic-gate cur_ino = addr; 7747c478bd9Sstevel@tonic-gate break; 7757c478bd9Sstevel@tonic-gate case CGRP: 7767c478bd9Sstevel@tonic-gate fprnt('?', 'c'); 7777c478bd9Sstevel@tonic-gate break; 7787c478bd9Sstevel@tonic-gate case SB: 7797c478bd9Sstevel@tonic-gate fprnt('?', 's'); 7807c478bd9Sstevel@tonic-gate break; 7817c478bd9Sstevel@tonic-gate case SHADOW_DATA: 7827c478bd9Sstevel@tonic-gate fprnt('?', 'S'); 7837c478bd9Sstevel@tonic-gate break; 7847c478bd9Sstevel@tonic-gate case CHAR: 7857c478bd9Sstevel@tonic-gate case SHORT: 7867c478bd9Sstevel@tonic-gate case LONG: 7877c478bd9Sstevel@tonic-gate fprnt(laststyle, lastpo); 7887c478bd9Sstevel@tonic-gate } 7897c478bd9Sstevel@tonic-gate if (error) { 7907c478bd9Sstevel@tonic-gate ungetachar(c); 7917c478bd9Sstevel@tonic-gate continue; 7927c478bd9Sstevel@tonic-gate } 7937c478bd9Sstevel@tonic-gate c_count = colon = acting_on_inode = 0; 7947c478bd9Sstevel@tonic-gate acting_on_directory = 0; 7957c478bd9Sstevel@tonic-gate should_print = 1; 7967c478bd9Sstevel@tonic-gate getnextinput(); 7977c478bd9Sstevel@tonic-gate if (error) 7987c478bd9Sstevel@tonic-gate continue; 7997c478bd9Sstevel@tonic-gate erraddr = addr; 8007c478bd9Sstevel@tonic-gate errino = cur_ino; 8017c478bd9Sstevel@tonic-gate errinum = cur_inum; 8027c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 8037c478bd9Sstevel@tonic-gate continue; 8047c478bd9Sstevel@tonic-gate 8057c478bd9Sstevel@tonic-gate case '(': /* numeric expression or unknown command */ 8067c478bd9Sstevel@tonic-gate default: 8077c478bd9Sstevel@tonic-gate colon = 0; 8087c478bd9Sstevel@tonic-gate if (digit(c) || c == '(') { 8097c478bd9Sstevel@tonic-gate ungetachar(c); 8107c478bd9Sstevel@tonic-gate addr = expr(); 8117c478bd9Sstevel@tonic-gate type = NUMB; 8127c478bd9Sstevel@tonic-gate value = addr; 8137c478bd9Sstevel@tonic-gate continue; 8147c478bd9Sstevel@tonic-gate } 8157c478bd9Sstevel@tonic-gate printf("unknown command or bad syntax\n"); 8167c478bd9Sstevel@tonic-gate error++; 8177c478bd9Sstevel@tonic-gate continue; 8187c478bd9Sstevel@tonic-gate 8197c478bd9Sstevel@tonic-gate case '?': /* general print facilities */ 8207c478bd9Sstevel@tonic-gate case '/': 8217c478bd9Sstevel@tonic-gate fprnt(c, getachar()); 8227c478bd9Sstevel@tonic-gate continue; 8237c478bd9Sstevel@tonic-gate 8247c478bd9Sstevel@tonic-gate case ';': /* command separator and . */ 8257c478bd9Sstevel@tonic-gate case '\t': 8267c478bd9Sstevel@tonic-gate case ' ': 8277c478bd9Sstevel@tonic-gate case '.': 8287c478bd9Sstevel@tonic-gate continue; 8297c478bd9Sstevel@tonic-gate 8307c478bd9Sstevel@tonic-gate case ':': /* command indicator */ 8317c478bd9Sstevel@tonic-gate colon++; 8327c478bd9Sstevel@tonic-gate commands++; 8337c478bd9Sstevel@tonic-gate should_print = 0; 8347c478bd9Sstevel@tonic-gate stringsize = 0; 8357c478bd9Sstevel@tonic-gate trapped = 0; 8367c478bd9Sstevel@tonic-gate continue; 8377c478bd9Sstevel@tonic-gate 8387c478bd9Sstevel@tonic-gate case ',': /* count indicator */ 8397c478bd9Sstevel@tonic-gate colon = star = 0; 8407c478bd9Sstevel@tonic-gate if ((c = getachar()) == '*') { 8417c478bd9Sstevel@tonic-gate star = 1; 8427c478bd9Sstevel@tonic-gate count = BLKSIZE; 8437c478bd9Sstevel@tonic-gate } else { 8447c478bd9Sstevel@tonic-gate ungetachar(c); 8457c478bd9Sstevel@tonic-gate count = expr(); 8467c478bd9Sstevel@tonic-gate if (error) 8477c478bd9Sstevel@tonic-gate continue; 8487c478bd9Sstevel@tonic-gate if (!count) 8497c478bd9Sstevel@tonic-gate count = 1; 8507c478bd9Sstevel@tonic-gate } 8517c478bd9Sstevel@tonic-gate clear = 0; 8527c478bd9Sstevel@tonic-gate continue; 8537c478bd9Sstevel@tonic-gate 8547c478bd9Sstevel@tonic-gate case '+': /* address addition */ 8557c478bd9Sstevel@tonic-gate colon = 0; 8567c478bd9Sstevel@tonic-gate c = getachar(); 8577c478bd9Sstevel@tonic-gate ungetachar(c); 8587c478bd9Sstevel@tonic-gate if (c == '\n') 8597c478bd9Sstevel@tonic-gate temp = 1; 8607c478bd9Sstevel@tonic-gate else { 8617c478bd9Sstevel@tonic-gate temp = expr(); 8627c478bd9Sstevel@tonic-gate if (error) 8637c478bd9Sstevel@tonic-gate continue; 8647c478bd9Sstevel@tonic-gate } 8657c478bd9Sstevel@tonic-gate erraddr = addr; 8667c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 8677c478bd9Sstevel@tonic-gate switch (objsz) { 8687c478bd9Sstevel@tonic-gate case DIRECTORY: 8697c478bd9Sstevel@tonic-gate addr = getdirslot((long)(dirslot + temp)); 8707c478bd9Sstevel@tonic-gate if (error) 8717c478bd9Sstevel@tonic-gate continue; 8727c478bd9Sstevel@tonic-gate break; 8737c478bd9Sstevel@tonic-gate case INODE: 8747c478bd9Sstevel@tonic-gate cur_inum += temp; 8757c478bd9Sstevel@tonic-gate addr = itob(cur_inum); 8767c478bd9Sstevel@tonic-gate if (!icheck(addr)) { 8777c478bd9Sstevel@tonic-gate cur_inum -= temp; 8787c478bd9Sstevel@tonic-gate continue; 8797c478bd9Sstevel@tonic-gate } 8807c478bd9Sstevel@tonic-gate break; 8817c478bd9Sstevel@tonic-gate case CGRP: 8827c478bd9Sstevel@tonic-gate case SB: 8837c478bd9Sstevel@tonic-gate cur_cgrp += temp; 8847c478bd9Sstevel@tonic-gate if ((addr = cgrp_check(cur_cgrp)) == 0) { 8857c478bd9Sstevel@tonic-gate cur_cgrp -= temp; 8867c478bd9Sstevel@tonic-gate continue; 8877c478bd9Sstevel@tonic-gate } 8887c478bd9Sstevel@tonic-gate break; 8897c478bd9Sstevel@tonic-gate case SHADOW_DATA: 8907c478bd9Sstevel@tonic-gate addr = getshadowslot((long)(cur_shad + temp)); 8917c478bd9Sstevel@tonic-gate if (error) 8927c478bd9Sstevel@tonic-gate continue; 8937c478bd9Sstevel@tonic-gate break; 8947c478bd9Sstevel@tonic-gate 8957c478bd9Sstevel@tonic-gate default: 8967c478bd9Sstevel@tonic-gate laststyle = '/'; 8977c478bd9Sstevel@tonic-gate addr += temp * objsz; 8987c478bd9Sstevel@tonic-gate cur_bytes += temp * objsz; 8997c478bd9Sstevel@tonic-gate if (valid_addr() == 0) 9007c478bd9Sstevel@tonic-gate continue; 9017c478bd9Sstevel@tonic-gate } 9027c478bd9Sstevel@tonic-gate value = get(objsz); 9037c478bd9Sstevel@tonic-gate continue; 9047c478bd9Sstevel@tonic-gate 9057c478bd9Sstevel@tonic-gate case '-': /* address subtraction */ 9067c478bd9Sstevel@tonic-gate colon = 0; 9077c478bd9Sstevel@tonic-gate c = getachar(); 9087c478bd9Sstevel@tonic-gate ungetachar(c); 9097c478bd9Sstevel@tonic-gate if (c == '\n') 9107c478bd9Sstevel@tonic-gate temp = 1; 9117c478bd9Sstevel@tonic-gate else { 9127c478bd9Sstevel@tonic-gate temp = expr(); 9137c478bd9Sstevel@tonic-gate if (error) 9147c478bd9Sstevel@tonic-gate continue; 9157c478bd9Sstevel@tonic-gate } 9167c478bd9Sstevel@tonic-gate erraddr = addr; 9177c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 9187c478bd9Sstevel@tonic-gate switch (objsz) { 9197c478bd9Sstevel@tonic-gate case DIRECTORY: 9207c478bd9Sstevel@tonic-gate addr = getdirslot((long)(dirslot - temp)); 9217c478bd9Sstevel@tonic-gate if (error) 9227c478bd9Sstevel@tonic-gate continue; 9237c478bd9Sstevel@tonic-gate break; 9247c478bd9Sstevel@tonic-gate case INODE: 9257c478bd9Sstevel@tonic-gate cur_inum -= temp; 9267c478bd9Sstevel@tonic-gate addr = itob(cur_inum); 9277c478bd9Sstevel@tonic-gate if (!icheck(addr)) { 9287c478bd9Sstevel@tonic-gate cur_inum += temp; 9297c478bd9Sstevel@tonic-gate continue; 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate break; 9327c478bd9Sstevel@tonic-gate case CGRP: 9337c478bd9Sstevel@tonic-gate case SB: 9347c478bd9Sstevel@tonic-gate cur_cgrp -= temp; 9357c478bd9Sstevel@tonic-gate if ((addr = cgrp_check(cur_cgrp)) == 0) { 9367c478bd9Sstevel@tonic-gate cur_cgrp += temp; 9377c478bd9Sstevel@tonic-gate continue; 9387c478bd9Sstevel@tonic-gate } 9397c478bd9Sstevel@tonic-gate break; 9407c478bd9Sstevel@tonic-gate case SHADOW_DATA: 9417c478bd9Sstevel@tonic-gate addr = getshadowslot((long)(cur_shad - temp)); 9427c478bd9Sstevel@tonic-gate if (error) 9437c478bd9Sstevel@tonic-gate continue; 9447c478bd9Sstevel@tonic-gate break; 9457c478bd9Sstevel@tonic-gate default: 9467c478bd9Sstevel@tonic-gate laststyle = '/'; 9477c478bd9Sstevel@tonic-gate addr -= temp * objsz; 9487c478bd9Sstevel@tonic-gate cur_bytes -= temp * objsz; 9497c478bd9Sstevel@tonic-gate if (valid_addr() == 0) 9507c478bd9Sstevel@tonic-gate continue; 9517c478bd9Sstevel@tonic-gate } 9527c478bd9Sstevel@tonic-gate value = get(objsz); 9537c478bd9Sstevel@tonic-gate continue; 9547c478bd9Sstevel@tonic-gate 9557c478bd9Sstevel@tonic-gate case '*': /* address multiplication */ 9567c478bd9Sstevel@tonic-gate colon = 0; 9577c478bd9Sstevel@tonic-gate temp = expr(); 9587c478bd9Sstevel@tonic-gate if (error) 9597c478bd9Sstevel@tonic-gate continue; 9607c478bd9Sstevel@tonic-gate if (objsz != INODE && objsz != DIRECTORY) 9617c478bd9Sstevel@tonic-gate laststyle = '/'; 9627c478bd9Sstevel@tonic-gate addr *= temp; 9637c478bd9Sstevel@tonic-gate value = get(objsz); 9647c478bd9Sstevel@tonic-gate continue; 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate case '%': /* address division */ 9677c478bd9Sstevel@tonic-gate colon = 0; 9687c478bd9Sstevel@tonic-gate temp = expr(); 9697c478bd9Sstevel@tonic-gate if (error) 9707c478bd9Sstevel@tonic-gate continue; 9717c478bd9Sstevel@tonic-gate if (!temp) { 9727c478bd9Sstevel@tonic-gate printf("divide by zero\n"); 9737c478bd9Sstevel@tonic-gate error++; 9747c478bd9Sstevel@tonic-gate continue; 9757c478bd9Sstevel@tonic-gate } 9767c478bd9Sstevel@tonic-gate if (objsz != INODE && objsz != DIRECTORY) 9777c478bd9Sstevel@tonic-gate laststyle = '/'; 9787c478bd9Sstevel@tonic-gate addr /= temp; 9797c478bd9Sstevel@tonic-gate value = get(objsz); 9807c478bd9Sstevel@tonic-gate continue; 9817c478bd9Sstevel@tonic-gate 9827c478bd9Sstevel@tonic-gate case '=': { /* assignment operation */ 9837c478bd9Sstevel@tonic-gate short tbase; 9847c478bd9Sstevel@tonic-gate calc: 9857c478bd9Sstevel@tonic-gate tbase = base; 9867c478bd9Sstevel@tonic-gate 9877c478bd9Sstevel@tonic-gate c = getachar(); 9887c478bd9Sstevel@tonic-gate if (c == '\n') { 9897c478bd9Sstevel@tonic-gate ungetachar(c); 9907c478bd9Sstevel@tonic-gate c = lastpo; 9917c478bd9Sstevel@tonic-gate if (acting_on_inode == 1) { 9927c478bd9Sstevel@tonic-gate if (c != 'o' && c != 'd' && c != 'x' && 9937c478bd9Sstevel@tonic-gate c != 'O' && c != 'D' && c != 'X') { 9947c478bd9Sstevel@tonic-gate switch (objsz) { 9957c478bd9Sstevel@tonic-gate case LONG: 9967c478bd9Sstevel@tonic-gate c = lastpo = 'X'; 9977c478bd9Sstevel@tonic-gate break; 9987c478bd9Sstevel@tonic-gate case SHORT: 9997c478bd9Sstevel@tonic-gate c = lastpo = 'x'; 10007c478bd9Sstevel@tonic-gate break; 10017c478bd9Sstevel@tonic-gate case CHAR: 10027c478bd9Sstevel@tonic-gate c = lastpo = 'c'; 10037c478bd9Sstevel@tonic-gate } 10047c478bd9Sstevel@tonic-gate } 10057c478bd9Sstevel@tonic-gate } else { 10067c478bd9Sstevel@tonic-gate if (acting_on_inode == 2) 10077c478bd9Sstevel@tonic-gate c = lastpo = 't'; 10087c478bd9Sstevel@tonic-gate } 10097c478bd9Sstevel@tonic-gate } else if (acting_on_inode) 10107c478bd9Sstevel@tonic-gate lastpo = c; 10117c478bd9Sstevel@tonic-gate should_print = star = 0; 10127c478bd9Sstevel@tonic-gate count = 1; 10137c478bd9Sstevel@tonic-gate erraddr = addr; 10147c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 10157c478bd9Sstevel@tonic-gate switch (c) { 10167c478bd9Sstevel@tonic-gate case '"': /* character string */ 10177c478bd9Sstevel@tonic-gate if (type == NUMB) { 10187c478bd9Sstevel@tonic-gate blocksize = BLKSIZE; 10197c478bd9Sstevel@tonic-gate filesize = BLKSIZE * 2; 10207c478bd9Sstevel@tonic-gate cur_bytes = blkoff(fs, addr); 10217c478bd9Sstevel@tonic-gate if (objsz == DIRECTORY || 10227c478bd9Sstevel@tonic-gate objsz == INODE) 10237c478bd9Sstevel@tonic-gate lastpo = 'X'; 10247c478bd9Sstevel@tonic-gate } 10257c478bd9Sstevel@tonic-gate puta(); 10267c478bd9Sstevel@tonic-gate continue; 10277c478bd9Sstevel@tonic-gate case '+': /* =+ operator */ 10287c478bd9Sstevel@tonic-gate temp = expr(); 10297c478bd9Sstevel@tonic-gate value = get(objsz); 10307c478bd9Sstevel@tonic-gate if (!error) 10317c478bd9Sstevel@tonic-gate put(value+temp, objsz); 10327c478bd9Sstevel@tonic-gate continue; 10337c478bd9Sstevel@tonic-gate case '-': /* =- operator */ 10347c478bd9Sstevel@tonic-gate temp = expr(); 10357c478bd9Sstevel@tonic-gate value = get(objsz); 10367c478bd9Sstevel@tonic-gate if (!error) 10377c478bd9Sstevel@tonic-gate put(value-temp, objsz); 10387c478bd9Sstevel@tonic-gate continue; 10397c478bd9Sstevel@tonic-gate case 'b': 10407c478bd9Sstevel@tonic-gate case 'c': 10417c478bd9Sstevel@tonic-gate if (objsz == CGRP) 10427c478bd9Sstevel@tonic-gate fprnt('?', c); 10437c478bd9Sstevel@tonic-gate else 10447c478bd9Sstevel@tonic-gate fprnt('/', c); 10457c478bd9Sstevel@tonic-gate continue; 10467c478bd9Sstevel@tonic-gate case 'i': 10477c478bd9Sstevel@tonic-gate addr = cur_ino; 10487c478bd9Sstevel@tonic-gate fprnt('?', 'i'); 10497c478bd9Sstevel@tonic-gate continue; 10507c478bd9Sstevel@tonic-gate case 's': 10517c478bd9Sstevel@tonic-gate fprnt('?', 's'); 10527c478bd9Sstevel@tonic-gate continue; 10537c478bd9Sstevel@tonic-gate case 't': 10547c478bd9Sstevel@tonic-gate case 'T': 10557c478bd9Sstevel@tonic-gate laststyle = '='; 10567c478bd9Sstevel@tonic-gate printf("\t\t"); 10577c478bd9Sstevel@tonic-gate { 10587c478bd9Sstevel@tonic-gate /* 10597c478bd9Sstevel@tonic-gate * Truncation is intentional so 10607c478bd9Sstevel@tonic-gate * ctime is happy. 10617c478bd9Sstevel@tonic-gate */ 10627c478bd9Sstevel@tonic-gate time_t tvalue = (time_t)value; 10637c478bd9Sstevel@tonic-gate printf("%s", ctime(&tvalue)); 10647c478bd9Sstevel@tonic-gate } 10657c478bd9Sstevel@tonic-gate continue; 10667c478bd9Sstevel@tonic-gate case 'o': 10677c478bd9Sstevel@tonic-gate base = OCTAL; 10687c478bd9Sstevel@tonic-gate goto otx; 10697c478bd9Sstevel@tonic-gate case 'd': 10707c478bd9Sstevel@tonic-gate if (objsz == DIRECTORY) { 10717c478bd9Sstevel@tonic-gate addr = cur_dir; 10727c478bd9Sstevel@tonic-gate fprnt('?', 'd'); 10737c478bd9Sstevel@tonic-gate continue; 10747c478bd9Sstevel@tonic-gate } 10757c478bd9Sstevel@tonic-gate base = DECIMAL; 10767c478bd9Sstevel@tonic-gate goto otx; 10777c478bd9Sstevel@tonic-gate case 'x': 10787c478bd9Sstevel@tonic-gate base = HEX; 10797c478bd9Sstevel@tonic-gate otx: 10807c478bd9Sstevel@tonic-gate laststyle = '='; 10817c478bd9Sstevel@tonic-gate printf("\t\t"); 10827c478bd9Sstevel@tonic-gate if (acting_on_inode) 10837c478bd9Sstevel@tonic-gate print(value & 0177777L, 12, -8, 0); 10847c478bd9Sstevel@tonic-gate else 10857c478bd9Sstevel@tonic-gate print(addr & 0177777L, 12, -8, 0); 10867c478bd9Sstevel@tonic-gate printf("\n"); 10877c478bd9Sstevel@tonic-gate base = tbase; 10887c478bd9Sstevel@tonic-gate continue; 10897c478bd9Sstevel@tonic-gate case 'O': 10907c478bd9Sstevel@tonic-gate base = OCTAL; 10917c478bd9Sstevel@tonic-gate goto OTX; 10927c478bd9Sstevel@tonic-gate case 'D': 10937c478bd9Sstevel@tonic-gate base = DECIMAL; 10947c478bd9Sstevel@tonic-gate goto OTX; 10957c478bd9Sstevel@tonic-gate case 'X': 10967c478bd9Sstevel@tonic-gate base = HEX; 10977c478bd9Sstevel@tonic-gate OTX: 10987c478bd9Sstevel@tonic-gate laststyle = '='; 10997c478bd9Sstevel@tonic-gate printf("\t\t"); 11007c478bd9Sstevel@tonic-gate if (acting_on_inode) 11017c478bd9Sstevel@tonic-gate print(value, 12, -8, 0); 11027c478bd9Sstevel@tonic-gate else 11037c478bd9Sstevel@tonic-gate print(addr, 12, -8, 0); 11047c478bd9Sstevel@tonic-gate printf("\n"); 11057c478bd9Sstevel@tonic-gate base = tbase; 11067c478bd9Sstevel@tonic-gate continue; 11077c478bd9Sstevel@tonic-gate default: /* regular assignment */ 11087c478bd9Sstevel@tonic-gate ungetachar(c); 11097c478bd9Sstevel@tonic-gate value = expr(); 11107c478bd9Sstevel@tonic-gate if (error) 11117c478bd9Sstevel@tonic-gate printf("syntax error\n"); 11127c478bd9Sstevel@tonic-gate else 11137c478bd9Sstevel@tonic-gate put(value, objsz); 11147c478bd9Sstevel@tonic-gate continue; 11157c478bd9Sstevel@tonic-gate } 11167c478bd9Sstevel@tonic-gate } 11177c478bd9Sstevel@tonic-gate 11187c478bd9Sstevel@tonic-gate case '>': /* save current address */ 11197c478bd9Sstevel@tonic-gate colon = 0; 11207c478bd9Sstevel@tonic-gate should_print = 0; 11217c478bd9Sstevel@tonic-gate c = getachar(); 11227c478bd9Sstevel@tonic-gate if (!letter(c) && !digit(c)) { 11237c478bd9Sstevel@tonic-gate printf("invalid register specification, "); 11247c478bd9Sstevel@tonic-gate printf("must be letter or digit\n"); 11257c478bd9Sstevel@tonic-gate error++; 11267c478bd9Sstevel@tonic-gate continue; 11277c478bd9Sstevel@tonic-gate } 11287c478bd9Sstevel@tonic-gate if (letter(c)) { 11297c478bd9Sstevel@tonic-gate if (c < 'a') 11307c478bd9Sstevel@tonic-gate c = uppertolower(c); 11317c478bd9Sstevel@tonic-gate c = hextodigit(c); 11327c478bd9Sstevel@tonic-gate } else 11337c478bd9Sstevel@tonic-gate c = numtodigit(c); 11347c478bd9Sstevel@tonic-gate regs[c].sv_addr = addr; 11357c478bd9Sstevel@tonic-gate regs[c].sv_value = value; 11367c478bd9Sstevel@tonic-gate regs[c].sv_objsz = objsz; 11377c478bd9Sstevel@tonic-gate continue; 11387c478bd9Sstevel@tonic-gate 11397c478bd9Sstevel@tonic-gate case '<': /* restore saved address */ 11407c478bd9Sstevel@tonic-gate colon = 0; 11417c478bd9Sstevel@tonic-gate should_print = 0; 11427c478bd9Sstevel@tonic-gate c = getachar(); 11437c478bd9Sstevel@tonic-gate if (!letter(c) && !digit(c)) { 11447c478bd9Sstevel@tonic-gate printf("invalid register specification, "); 11457c478bd9Sstevel@tonic-gate printf("must be letter or digit\n"); 11467c478bd9Sstevel@tonic-gate error++; 11477c478bd9Sstevel@tonic-gate continue; 11487c478bd9Sstevel@tonic-gate } 11497c478bd9Sstevel@tonic-gate if (letter(c)) { 11507c478bd9Sstevel@tonic-gate if (c < 'a') 11517c478bd9Sstevel@tonic-gate c = uppertolower(c); 11527c478bd9Sstevel@tonic-gate c = hextodigit(c); 11537c478bd9Sstevel@tonic-gate } else 11547c478bd9Sstevel@tonic-gate c = numtodigit(c); 11557c478bd9Sstevel@tonic-gate addr = regs[c].sv_addr; 11567c478bd9Sstevel@tonic-gate value = regs[c].sv_value; 11577c478bd9Sstevel@tonic-gate objsz = regs[c].sv_objsz; 11587c478bd9Sstevel@tonic-gate continue; 11597c478bd9Sstevel@tonic-gate 11607c478bd9Sstevel@tonic-gate case 'a': 11617c478bd9Sstevel@tonic-gate if (colon) 11627c478bd9Sstevel@tonic-gate colon = 0; 11637c478bd9Sstevel@tonic-gate else 11647c478bd9Sstevel@tonic-gate goto no_colon; 11657c478bd9Sstevel@tonic-gate if (match("at", 2)) { /* access time */ 11667c478bd9Sstevel@tonic-gate acting_on_inode = 2; 11677c478bd9Sstevel@tonic-gate should_print = 1; 1168d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1169d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_atime; 11707c478bd9Sstevel@tonic-gate value = get(LONG); 11717c478bd9Sstevel@tonic-gate type = NULL; 11727c478bd9Sstevel@tonic-gate continue; 11737c478bd9Sstevel@tonic-gate } 11747c478bd9Sstevel@tonic-gate goto bad_syntax; 11757c478bd9Sstevel@tonic-gate 11767c478bd9Sstevel@tonic-gate case 'b': 11777c478bd9Sstevel@tonic-gate if (colon) 11787c478bd9Sstevel@tonic-gate colon = 0; 11797c478bd9Sstevel@tonic-gate else 11807c478bd9Sstevel@tonic-gate goto no_colon; 11817c478bd9Sstevel@tonic-gate if (match("block", 2)) { /* block conversion */ 11827c478bd9Sstevel@tonic-gate if (type == NUMB) { 11837c478bd9Sstevel@tonic-gate value = addr; 11847c478bd9Sstevel@tonic-gate cur_bytes = 0; 11857c478bd9Sstevel@tonic-gate blocksize = BLKSIZE; 11867c478bd9Sstevel@tonic-gate filesize = BLKSIZE * 2; 11877c478bd9Sstevel@tonic-gate } 11887c478bd9Sstevel@tonic-gate addr = value << FRGSHIFT; 11897c478bd9Sstevel@tonic-gate bod_addr = addr; 11907c478bd9Sstevel@tonic-gate value = get(LONG); 11917c478bd9Sstevel@tonic-gate type = BLOCK; 11927c478bd9Sstevel@tonic-gate dirslot = 0; 11937c478bd9Sstevel@tonic-gate trapped++; 11947c478bd9Sstevel@tonic-gate continue; 11957c478bd9Sstevel@tonic-gate } 11967c478bd9Sstevel@tonic-gate if (match("bs", 2)) { /* block size */ 11977c478bd9Sstevel@tonic-gate acting_on_inode = 1; 11987c478bd9Sstevel@tonic-gate should_print = 1; 11997c478bd9Sstevel@tonic-gate if (icheck(cur_ino) == 0) 12007c478bd9Sstevel@tonic-gate continue; 1201d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1202d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_blocks; 12037c478bd9Sstevel@tonic-gate value = get(LONG); 12047c478bd9Sstevel@tonic-gate type = NULL; 12057c478bd9Sstevel@tonic-gate continue; 12067c478bd9Sstevel@tonic-gate } 12077c478bd9Sstevel@tonic-gate if (match("base", 2)) { /* change/show base */ 12087c478bd9Sstevel@tonic-gate showbase: 12097c478bd9Sstevel@tonic-gate if ((c = getachar()) == '\n') { 12107c478bd9Sstevel@tonic-gate ungetachar(c); 12117c478bd9Sstevel@tonic-gate printf("base =\t\t"); 12127c478bd9Sstevel@tonic-gate switch (base) { 12137c478bd9Sstevel@tonic-gate case OCTAL: 12147c478bd9Sstevel@tonic-gate printf("OCTAL\n"); 12157c478bd9Sstevel@tonic-gate continue; 12167c478bd9Sstevel@tonic-gate case DECIMAL: 12177c478bd9Sstevel@tonic-gate printf("DECIMAL\n"); 12187c478bd9Sstevel@tonic-gate continue; 12197c478bd9Sstevel@tonic-gate case HEX: 12207c478bd9Sstevel@tonic-gate printf("HEX\n"); 12217c478bd9Sstevel@tonic-gate continue; 12227c478bd9Sstevel@tonic-gate } 12237c478bd9Sstevel@tonic-gate } 12247c478bd9Sstevel@tonic-gate if (c != '=') { 12257c478bd9Sstevel@tonic-gate printf("missing '='\n"); 12267c478bd9Sstevel@tonic-gate error++; 12277c478bd9Sstevel@tonic-gate continue; 12287c478bd9Sstevel@tonic-gate } 12297c478bd9Sstevel@tonic-gate value = expr(); 12307c478bd9Sstevel@tonic-gate switch (value) { 12317c478bd9Sstevel@tonic-gate default: 12327c478bd9Sstevel@tonic-gate printf("invalid base\n"); 12337c478bd9Sstevel@tonic-gate error++; 12347c478bd9Sstevel@tonic-gate break; 12357c478bd9Sstevel@tonic-gate case OCTAL: 12367c478bd9Sstevel@tonic-gate case DECIMAL: 12377c478bd9Sstevel@tonic-gate case HEX: 12387c478bd9Sstevel@tonic-gate base = (short)value; 12397c478bd9Sstevel@tonic-gate } 12407c478bd9Sstevel@tonic-gate goto showbase; 12417c478bd9Sstevel@tonic-gate } 12427c478bd9Sstevel@tonic-gate goto bad_syntax; 12437c478bd9Sstevel@tonic-gate 12447c478bd9Sstevel@tonic-gate case 'c': 12457c478bd9Sstevel@tonic-gate if (colon) 12467c478bd9Sstevel@tonic-gate colon = 0; 12477c478bd9Sstevel@tonic-gate else 12487c478bd9Sstevel@tonic-gate goto no_colon; 12497c478bd9Sstevel@tonic-gate if (match("cd", 2)) { /* change directory */ 12507c478bd9Sstevel@tonic-gate top = filenames - 1; 12517c478bd9Sstevel@tonic-gate eat_spaces(); 12527c478bd9Sstevel@tonic-gate if ((c = getachar()) == '\n') { 12537c478bd9Sstevel@tonic-gate ungetachar(c); 12547c478bd9Sstevel@tonic-gate current_pathp = -1; 12557c478bd9Sstevel@tonic-gate restore_inode(2); 12567c478bd9Sstevel@tonic-gate continue; 12577c478bd9Sstevel@tonic-gate } 12587c478bd9Sstevel@tonic-gate ungetachar(c); 12597c478bd9Sstevel@tonic-gate temp = cur_inum; 12607c478bd9Sstevel@tonic-gate doing_cd = 1; 12617c478bd9Sstevel@tonic-gate parse(); 12627c478bd9Sstevel@tonic-gate doing_cd = 0; 12637c478bd9Sstevel@tonic-gate if (nfiles != 1) { 12647c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 12657c478bd9Sstevel@tonic-gate if (!error) { 12667c478bd9Sstevel@tonic-gate print_path(input_path, 12677c478bd9Sstevel@tonic-gate (int)input_pathp); 12687c478bd9Sstevel@tonic-gate if (nfiles == 0) 12697c478bd9Sstevel@tonic-gate printf(" not found\n"); 12707c478bd9Sstevel@tonic-gate else 12717c478bd9Sstevel@tonic-gate printf(" ambiguous\n"); 12727c478bd9Sstevel@tonic-gate error++; 12737c478bd9Sstevel@tonic-gate } 12747c478bd9Sstevel@tonic-gate continue; 12757c478bd9Sstevel@tonic-gate } 12767c478bd9Sstevel@tonic-gate restore_inode(filenames->ino); 12777c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 12787c478bd9Sstevel@tonic-gate continue; 12797c478bd9Sstevel@tonic-gate if ((mode & IFMT) != IFDIR) { 12807c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 12817c478bd9Sstevel@tonic-gate print_path(input_path, 12827c478bd9Sstevel@tonic-gate (int)input_pathp); 12837c478bd9Sstevel@tonic-gate printf(" not a directory\n"); 12847c478bd9Sstevel@tonic-gate error++; 12857c478bd9Sstevel@tonic-gate continue; 12867c478bd9Sstevel@tonic-gate } 12877c478bd9Sstevel@tonic-gate for (i = 0; i <= top->len; i++) 12887c478bd9Sstevel@tonic-gate (void) strcpy(current_path[i], 12897c478bd9Sstevel@tonic-gate top->fname[i]); 12907c478bd9Sstevel@tonic-gate current_pathp = top->len; 12917c478bd9Sstevel@tonic-gate continue; 12927c478bd9Sstevel@tonic-gate } 12937c478bd9Sstevel@tonic-gate if (match("cg", 2)) { /* cylinder group */ 12947c478bd9Sstevel@tonic-gate if (type == NUMB) 12957c478bd9Sstevel@tonic-gate value = addr; 12967c478bd9Sstevel@tonic-gate if (value > fs->fs_ncg - 1) { 12977c478bd9Sstevel@tonic-gate printf("maximum cylinder group is "); 12987c478bd9Sstevel@tonic-gate print(fs->fs_ncg - 1, 8, -8, 0); 12997c478bd9Sstevel@tonic-gate printf("\n"); 13007c478bd9Sstevel@tonic-gate error++; 13017c478bd9Sstevel@tonic-gate continue; 13027c478bd9Sstevel@tonic-gate } 13037c478bd9Sstevel@tonic-gate type = objsz = CGRP; 13047c478bd9Sstevel@tonic-gate cur_cgrp = (long)value; 13057c478bd9Sstevel@tonic-gate addr = cgtod(fs, cur_cgrp) << FRGSHIFT; 13067c478bd9Sstevel@tonic-gate continue; 13077c478bd9Sstevel@tonic-gate } 13087c478bd9Sstevel@tonic-gate if (match("ct", 2)) { /* creation time */ 13097c478bd9Sstevel@tonic-gate acting_on_inode = 2; 13107c478bd9Sstevel@tonic-gate should_print = 1; 1311d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1312d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_ctime; 13137c478bd9Sstevel@tonic-gate value = get(LONG); 13147c478bd9Sstevel@tonic-gate type = NULL; 13157c478bd9Sstevel@tonic-gate continue; 13167c478bd9Sstevel@tonic-gate } 13177c478bd9Sstevel@tonic-gate goto bad_syntax; 13187c478bd9Sstevel@tonic-gate 13197c478bd9Sstevel@tonic-gate case 'd': 13207c478bd9Sstevel@tonic-gate if (colon) 13217c478bd9Sstevel@tonic-gate colon = 0; 13227c478bd9Sstevel@tonic-gate else 13237c478bd9Sstevel@tonic-gate goto no_colon; 13247c478bd9Sstevel@tonic-gate if (match("directory", 2)) { /* directory offsets */ 13257c478bd9Sstevel@tonic-gate if (type == NUMB) 13267c478bd9Sstevel@tonic-gate value = addr; 13277c478bd9Sstevel@tonic-gate objsz = DIRECTORY; 13287c478bd9Sstevel@tonic-gate type = DIRECTORY; 13297c478bd9Sstevel@tonic-gate addr = (u_offset_t)getdirslot((long)value); 13307c478bd9Sstevel@tonic-gate continue; 13317c478bd9Sstevel@tonic-gate } 13327c478bd9Sstevel@tonic-gate if (match("db", 2)) { /* direct block */ 13337c478bd9Sstevel@tonic-gate acting_on_inode = 1; 13347c478bd9Sstevel@tonic-gate should_print = 1; 13357c478bd9Sstevel@tonic-gate if (type == NUMB) 13367c478bd9Sstevel@tonic-gate value = addr; 13377c478bd9Sstevel@tonic-gate if (value >= NDADDR) { 13387c478bd9Sstevel@tonic-gate printf("direct blocks are 0 to "); 13397c478bd9Sstevel@tonic-gate print(NDADDR - 1, 0, 0, 0); 13407c478bd9Sstevel@tonic-gate printf("\n"); 13417c478bd9Sstevel@tonic-gate error++; 13427c478bd9Sstevel@tonic-gate continue; 13437c478bd9Sstevel@tonic-gate } 13447c478bd9Sstevel@tonic-gate addr = cur_ino; 13457c478bd9Sstevel@tonic-gate if (!icheck(addr)) 13467c478bd9Sstevel@tonic-gate continue; 13477c478bd9Sstevel@tonic-gate addr = (long) 1348d1a180b0Smaheshvs &((struct dinode *)(uintptr_t)cur_ino)-> 13497c478bd9Sstevel@tonic-gate di_db[value]; 13507c478bd9Sstevel@tonic-gate bod_addr = addr; 13517c478bd9Sstevel@tonic-gate cur_bytes = (value) * BLKSIZE; 13527c478bd9Sstevel@tonic-gate cur_block = (long)value; 13537c478bd9Sstevel@tonic-gate type = BLOCK; 13547c478bd9Sstevel@tonic-gate dirslot = 0; 13557c478bd9Sstevel@tonic-gate value = get(LONG); 13567c478bd9Sstevel@tonic-gate if (!value && !override) { 13577c478bd9Sstevel@tonic-gate printf("non existent block\n"); 13587c478bd9Sstevel@tonic-gate error++; 13597c478bd9Sstevel@tonic-gate } 13607c478bd9Sstevel@tonic-gate continue; 13617c478bd9Sstevel@tonic-gate } 13627c478bd9Sstevel@tonic-gate goto bad_syntax; 13637c478bd9Sstevel@tonic-gate 13647c478bd9Sstevel@tonic-gate case 'f': 13657c478bd9Sstevel@tonic-gate if (colon) 13667c478bd9Sstevel@tonic-gate colon = 0; 13677c478bd9Sstevel@tonic-gate else 13687c478bd9Sstevel@tonic-gate goto no_colon; 13697c478bd9Sstevel@tonic-gate if (match("find", 3)) { /* find command */ 13707c478bd9Sstevel@tonic-gate find(); 13717c478bd9Sstevel@tonic-gate continue; 13727c478bd9Sstevel@tonic-gate } 13737c478bd9Sstevel@tonic-gate if (match("fragment", 2)) { /* fragment conv. */ 13747c478bd9Sstevel@tonic-gate if (type == NUMB) { 13757c478bd9Sstevel@tonic-gate value = addr; 13767c478bd9Sstevel@tonic-gate cur_bytes = 0; 13777c478bd9Sstevel@tonic-gate blocksize = FRGSIZE; 13787c478bd9Sstevel@tonic-gate filesize = FRGSIZE * 2; 13797c478bd9Sstevel@tonic-gate } 13807c478bd9Sstevel@tonic-gate if (min(blocksize, filesize) - cur_bytes > 13817c478bd9Sstevel@tonic-gate FRGSIZE) { 13827c478bd9Sstevel@tonic-gate blocksize = cur_bytes + FRGSIZE; 13837c478bd9Sstevel@tonic-gate filesize = blocksize * 2; 13847c478bd9Sstevel@tonic-gate } 13857c478bd9Sstevel@tonic-gate addr = value << FRGSHIFT; 13867c478bd9Sstevel@tonic-gate bod_addr = addr; 13877c478bd9Sstevel@tonic-gate value = get(LONG); 13887c478bd9Sstevel@tonic-gate type = FRAGMENT; 13897c478bd9Sstevel@tonic-gate dirslot = 0; 13907c478bd9Sstevel@tonic-gate trapped++; 13917c478bd9Sstevel@tonic-gate continue; 13927c478bd9Sstevel@tonic-gate } 13937c478bd9Sstevel@tonic-gate if (match("file", 4)) { /* access as file */ 13947c478bd9Sstevel@tonic-gate acting_on_inode = 1; 13957c478bd9Sstevel@tonic-gate should_print = 1; 13967c478bd9Sstevel@tonic-gate if (type == NUMB) 13977c478bd9Sstevel@tonic-gate value = addr; 13987c478bd9Sstevel@tonic-gate addr = cur_ino; 13997c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 14007c478bd9Sstevel@tonic-gate continue; 14017c478bd9Sstevel@tonic-gate if (!override) { 14027c478bd9Sstevel@tonic-gate switch (mode & IFMT) { 14037c478bd9Sstevel@tonic-gate case IFCHR: 14047c478bd9Sstevel@tonic-gate case IFBLK: 14057c478bd9Sstevel@tonic-gate printf("special device\n"); 14067c478bd9Sstevel@tonic-gate error++; 14077c478bd9Sstevel@tonic-gate continue; 14087c478bd9Sstevel@tonic-gate } 14097c478bd9Sstevel@tonic-gate } 14107c478bd9Sstevel@tonic-gate if ((addr = (u_offset_t) 14117c478bd9Sstevel@tonic-gate (bmap((long)value) << FRGSHIFT)) == 0) 14127c478bd9Sstevel@tonic-gate continue; 14137c478bd9Sstevel@tonic-gate cur_block = (long)value; 14147c478bd9Sstevel@tonic-gate bod_addr = addr; 14157c478bd9Sstevel@tonic-gate type = BLOCK; 14167c478bd9Sstevel@tonic-gate dirslot = 0; 14177c478bd9Sstevel@tonic-gate continue; 14187c478bd9Sstevel@tonic-gate } 14197c478bd9Sstevel@tonic-gate if (match("fill", 4)) { /* fill */ 14207c478bd9Sstevel@tonic-gate if (getachar() != '=') { 14217c478bd9Sstevel@tonic-gate printf("missing '='\n"); 14227c478bd9Sstevel@tonic-gate error++; 14237c478bd9Sstevel@tonic-gate continue; 14247c478bd9Sstevel@tonic-gate } 14257c478bd9Sstevel@tonic-gate if (objsz == INODE || objsz == DIRECTORY || 14267c478bd9Sstevel@tonic-gate objsz == SHADOW_DATA) { 14277c478bd9Sstevel@tonic-gate printf( 14287c478bd9Sstevel@tonic-gate "can't fill inode or directory\n"); 14297c478bd9Sstevel@tonic-gate error++; 14307c478bd9Sstevel@tonic-gate continue; 14317c478bd9Sstevel@tonic-gate } 14327c478bd9Sstevel@tonic-gate fill(); 14337c478bd9Sstevel@tonic-gate continue; 14347c478bd9Sstevel@tonic-gate } 14357c478bd9Sstevel@tonic-gate goto bad_syntax; 14367c478bd9Sstevel@tonic-gate 14377c478bd9Sstevel@tonic-gate case 'g': 14387c478bd9Sstevel@tonic-gate if (colon) 14397c478bd9Sstevel@tonic-gate colon = 0; 14407c478bd9Sstevel@tonic-gate else 14417c478bd9Sstevel@tonic-gate goto no_colon; 14427c478bd9Sstevel@tonic-gate if (match("gid", 1)) { /* group id */ 14437c478bd9Sstevel@tonic-gate acting_on_inode = 1; 14447c478bd9Sstevel@tonic-gate should_print = 1; 1445d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1446d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_gid; 14477c478bd9Sstevel@tonic-gate value = get(SHORT); 14487c478bd9Sstevel@tonic-gate type = NULL; 14497c478bd9Sstevel@tonic-gate continue; 14507c478bd9Sstevel@tonic-gate } 14517c478bd9Sstevel@tonic-gate goto bad_syntax; 14527c478bd9Sstevel@tonic-gate 14537c478bd9Sstevel@tonic-gate case 'i': 14547c478bd9Sstevel@tonic-gate if (colon) 14557c478bd9Sstevel@tonic-gate colon = 0; 14567c478bd9Sstevel@tonic-gate else 14577c478bd9Sstevel@tonic-gate goto no_colon; 14587c478bd9Sstevel@tonic-gate if (match("inode", 2)) { /* i# to inode conversion */ 14597c478bd9Sstevel@tonic-gate if (c_count == 2) { 14607c478bd9Sstevel@tonic-gate addr = cur_ino; 14617c478bd9Sstevel@tonic-gate value = get(INODE); 14627c478bd9Sstevel@tonic-gate type = NULL; 14637c478bd9Sstevel@tonic-gate laststyle = '='; 14647c478bd9Sstevel@tonic-gate lastpo = 'i'; 14657c478bd9Sstevel@tonic-gate should_print = 1; 14667c478bd9Sstevel@tonic-gate continue; 14677c478bd9Sstevel@tonic-gate } 14687c478bd9Sstevel@tonic-gate if (type == NUMB) 14697c478bd9Sstevel@tonic-gate value = addr; 14707c478bd9Sstevel@tonic-gate addr = itob(value); 14717c478bd9Sstevel@tonic-gate if (!icheck(addr)) 14727c478bd9Sstevel@tonic-gate continue; 14737c478bd9Sstevel@tonic-gate cur_ino = addr; 14747c478bd9Sstevel@tonic-gate cur_inum = (long)value; 14757c478bd9Sstevel@tonic-gate value = get(INODE); 14767c478bd9Sstevel@tonic-gate type = NULL; 14777c478bd9Sstevel@tonic-gate continue; 14787c478bd9Sstevel@tonic-gate } 14797c478bd9Sstevel@tonic-gate if (match("ib", 2)) { /* indirect block */ 14807c478bd9Sstevel@tonic-gate acting_on_inode = 1; 14817c478bd9Sstevel@tonic-gate should_print = 1; 14827c478bd9Sstevel@tonic-gate if (type == NUMB) 14837c478bd9Sstevel@tonic-gate value = addr; 14847c478bd9Sstevel@tonic-gate if (value >= NIADDR) { 14857c478bd9Sstevel@tonic-gate printf("indirect blocks are 0 to "); 14867c478bd9Sstevel@tonic-gate print(NIADDR - 1, 0, 0, 0); 14877c478bd9Sstevel@tonic-gate printf("\n"); 14887c478bd9Sstevel@tonic-gate error++; 14897c478bd9Sstevel@tonic-gate continue; 14907c478bd9Sstevel@tonic-gate } 1491d1a180b0Smaheshvs addr = (long)&((struct dinode *)(uintptr_t) 1492d1a180b0Smaheshvs cur_ino)->di_ib[value]; 14937c478bd9Sstevel@tonic-gate cur_bytes = (NDADDR - 1) * BLKSIZE; 14947c478bd9Sstevel@tonic-gate temp = 1; 14957c478bd9Sstevel@tonic-gate for (i = 0; i < value; i++) { 14967c478bd9Sstevel@tonic-gate temp *= NINDIR(fs) * BLKSIZE; 14977c478bd9Sstevel@tonic-gate cur_bytes += temp; 14987c478bd9Sstevel@tonic-gate } 14997c478bd9Sstevel@tonic-gate type = BLOCK; 15007c478bd9Sstevel@tonic-gate dirslot = 0; 15017c478bd9Sstevel@tonic-gate value = get(LONG); 15027c478bd9Sstevel@tonic-gate if (!value && !override) { 15037c478bd9Sstevel@tonic-gate printf("non existent block\n"); 15047c478bd9Sstevel@tonic-gate error++; 15057c478bd9Sstevel@tonic-gate } 15067c478bd9Sstevel@tonic-gate continue; 15077c478bd9Sstevel@tonic-gate } 15087c478bd9Sstevel@tonic-gate goto bad_syntax; 15097c478bd9Sstevel@tonic-gate 15107c478bd9Sstevel@tonic-gate case 'l': 15117c478bd9Sstevel@tonic-gate if (colon) 15127c478bd9Sstevel@tonic-gate colon = 0; 15137c478bd9Sstevel@tonic-gate else 15147c478bd9Sstevel@tonic-gate goto no_colon; 15157c478bd9Sstevel@tonic-gate if (match("log_head", 8)) { 15167c478bd9Sstevel@tonic-gate log_display_header(); 15177c478bd9Sstevel@tonic-gate should_print = 0; 15187c478bd9Sstevel@tonic-gate continue; 15197c478bd9Sstevel@tonic-gate } 15207c478bd9Sstevel@tonic-gate if (match("log_delta", 9)) { 15217c478bd9Sstevel@tonic-gate log_show(LOG_NDELTAS); 15227c478bd9Sstevel@tonic-gate should_print = 0; 15237c478bd9Sstevel@tonic-gate continue; 15247c478bd9Sstevel@tonic-gate } 15257c478bd9Sstevel@tonic-gate if (match("log_show", 8)) { 15267c478bd9Sstevel@tonic-gate log_show(LOG_ALLDELTAS); 15277c478bd9Sstevel@tonic-gate should_print = 0; 15287c478bd9Sstevel@tonic-gate continue; 15297c478bd9Sstevel@tonic-gate } 15307c478bd9Sstevel@tonic-gate if (match("log_chk", 7)) { 15317c478bd9Sstevel@tonic-gate log_show(LOG_CHECKSCAN); 15327c478bd9Sstevel@tonic-gate should_print = 0; 15337c478bd9Sstevel@tonic-gate continue; 15347c478bd9Sstevel@tonic-gate } 15357c478bd9Sstevel@tonic-gate if (match("log_otodb", 9)) { 15367c478bd9Sstevel@tonic-gate if (log_lodb((u_offset_t)addr, &temp)) { 15377c478bd9Sstevel@tonic-gate addr = temp; 15387c478bd9Sstevel@tonic-gate should_print = 1; 15397c478bd9Sstevel@tonic-gate laststyle = '='; 15407c478bd9Sstevel@tonic-gate } else 15417c478bd9Sstevel@tonic-gate error++; 15427c478bd9Sstevel@tonic-gate continue; 15437c478bd9Sstevel@tonic-gate } 15447c478bd9Sstevel@tonic-gate if (match("ls", 2)) { /* ls command */ 15457c478bd9Sstevel@tonic-gate temp = cur_inum; 15467c478bd9Sstevel@tonic-gate recursive = long_list = 0; 15477c478bd9Sstevel@tonic-gate top = filenames - 1; 15487c478bd9Sstevel@tonic-gate for (;;) { 15497c478bd9Sstevel@tonic-gate eat_spaces(); 15507c478bd9Sstevel@tonic-gate if ((c = getachar()) == '-') { 15517c478bd9Sstevel@tonic-gate if ((c = getachar()) == 'R') { 15527c478bd9Sstevel@tonic-gate recursive = 1; 15537c478bd9Sstevel@tonic-gate continue; 15547c478bd9Sstevel@tonic-gate } else if (c == 'l') { 15557c478bd9Sstevel@tonic-gate long_list = 1; 15567c478bd9Sstevel@tonic-gate } else { 15577c478bd9Sstevel@tonic-gate printf( 15587c478bd9Sstevel@tonic-gate "unknown option "); 15597c478bd9Sstevel@tonic-gate printf("'%c'\n", c); 15607c478bd9Sstevel@tonic-gate error++; 15617c478bd9Sstevel@tonic-gate break; 15627c478bd9Sstevel@tonic-gate } 15637c478bd9Sstevel@tonic-gate } else 15647c478bd9Sstevel@tonic-gate ungetachar(c); 15657c478bd9Sstevel@tonic-gate if ((c = getachar()) == '\n') { 15667c478bd9Sstevel@tonic-gate if (c_count != 2) { 15677c478bd9Sstevel@tonic-gate ungetachar(c); 15687c478bd9Sstevel@tonic-gate break; 15697c478bd9Sstevel@tonic-gate } 15707c478bd9Sstevel@tonic-gate } 15717c478bd9Sstevel@tonic-gate c_count++; 15727c478bd9Sstevel@tonic-gate ungetachar(c); 15737c478bd9Sstevel@tonic-gate parse(); 15747c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 15757c478bd9Sstevel@tonic-gate if (error) 15767c478bd9Sstevel@tonic-gate break; 15777c478bd9Sstevel@tonic-gate } 15787c478bd9Sstevel@tonic-gate recursive = 0; 15797c478bd9Sstevel@tonic-gate if (error || nfiles == 0) { 15807c478bd9Sstevel@tonic-gate if (!error) { 15817c478bd9Sstevel@tonic-gate print_path(input_path, 15827c478bd9Sstevel@tonic-gate (int)input_pathp); 15837c478bd9Sstevel@tonic-gate printf(" not found\n"); 15847c478bd9Sstevel@tonic-gate } 15857c478bd9Sstevel@tonic-gate continue; 15867c478bd9Sstevel@tonic-gate } 15877c478bd9Sstevel@tonic-gate if (nfiles) { 15887c478bd9Sstevel@tonic-gate cmp_level = 0; 15897c478bd9Sstevel@tonic-gate qsort((char *)filenames, nfiles, 15907c478bd9Sstevel@tonic-gate sizeof (struct filenames), ffcmp); 15917c478bd9Sstevel@tonic-gate ls(filenames, filenames + (nfiles - 1), 0); 15927c478bd9Sstevel@tonic-gate } else { 15937c478bd9Sstevel@tonic-gate printf("no match\n"); 15947c478bd9Sstevel@tonic-gate error++; 15957c478bd9Sstevel@tonic-gate } 15967c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 15977c478bd9Sstevel@tonic-gate continue; 15987c478bd9Sstevel@tonic-gate } 15997c478bd9Sstevel@tonic-gate if (match("ln", 2)) { /* link count */ 16007c478bd9Sstevel@tonic-gate acting_on_inode = 1; 16017c478bd9Sstevel@tonic-gate should_print = 1; 1602d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1603d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_nlink; 16047c478bd9Sstevel@tonic-gate value = get(SHORT); 16057c478bd9Sstevel@tonic-gate type = NULL; 16067c478bd9Sstevel@tonic-gate continue; 16077c478bd9Sstevel@tonic-gate } 16087c478bd9Sstevel@tonic-gate goto bad_syntax; 16097c478bd9Sstevel@tonic-gate 16107c478bd9Sstevel@tonic-gate case 'm': 16117c478bd9Sstevel@tonic-gate if (colon) 16127c478bd9Sstevel@tonic-gate colon = 0; 16137c478bd9Sstevel@tonic-gate else 16147c478bd9Sstevel@tonic-gate goto no_colon; 16157c478bd9Sstevel@tonic-gate addr = cur_ino; 16167c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 16177c478bd9Sstevel@tonic-gate continue; 16187c478bd9Sstevel@tonic-gate if (match("mt", 2)) { /* modification time */ 16197c478bd9Sstevel@tonic-gate acting_on_inode = 2; 16207c478bd9Sstevel@tonic-gate should_print = 1; 1621d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1622d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_mtime; 16237c478bd9Sstevel@tonic-gate value = get(LONG); 16247c478bd9Sstevel@tonic-gate type = NULL; 16257c478bd9Sstevel@tonic-gate continue; 16267c478bd9Sstevel@tonic-gate } 16277c478bd9Sstevel@tonic-gate if (match("md", 2)) { /* mode */ 16287c478bd9Sstevel@tonic-gate acting_on_inode = 1; 16297c478bd9Sstevel@tonic-gate should_print = 1; 1630d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1631d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_mode; 16327c478bd9Sstevel@tonic-gate value = get(SHORT); 16337c478bd9Sstevel@tonic-gate type = NULL; 16347c478bd9Sstevel@tonic-gate continue; 16357c478bd9Sstevel@tonic-gate } 16367c478bd9Sstevel@tonic-gate if (match("maj", 2)) { /* major device number */ 16377c478bd9Sstevel@tonic-gate acting_on_inode = 1; 16387c478bd9Sstevel@tonic-gate should_print = 1; 16397c478bd9Sstevel@tonic-gate if (devcheck(mode)) 16407c478bd9Sstevel@tonic-gate continue; 1641d1a180b0Smaheshvs addr = (uintptr_t)&((struct dinode *)(uintptr_t) 1642d1a180b0Smaheshvs cur_ino)->di_ordev; 16437c478bd9Sstevel@tonic-gate { 16447c478bd9Sstevel@tonic-gate long dvalue; 16457c478bd9Sstevel@tonic-gate dvalue = get(LONG); 16467c478bd9Sstevel@tonic-gate value = major(dvalue); 16477c478bd9Sstevel@tonic-gate } 16487c478bd9Sstevel@tonic-gate type = NULL; 16497c478bd9Sstevel@tonic-gate continue; 16507c478bd9Sstevel@tonic-gate } 16517c478bd9Sstevel@tonic-gate if (match("min", 2)) { /* minor device number */ 16527c478bd9Sstevel@tonic-gate acting_on_inode = 1; 16537c478bd9Sstevel@tonic-gate should_print = 1; 16547c478bd9Sstevel@tonic-gate if (devcheck(mode)) 16557c478bd9Sstevel@tonic-gate continue; 1656d1a180b0Smaheshvs addr = (uintptr_t)&((struct dinode *)(uintptr_t) 1657d1a180b0Smaheshvs cur_ino)->di_ordev; 16587c478bd9Sstevel@tonic-gate { 16597c478bd9Sstevel@tonic-gate long dvalue; 16607c478bd9Sstevel@tonic-gate dvalue = (long)get(LONG); 16617c478bd9Sstevel@tonic-gate value = minor(dvalue); 16627c478bd9Sstevel@tonic-gate } 16637c478bd9Sstevel@tonic-gate type = NULL; 16647c478bd9Sstevel@tonic-gate continue; 16657c478bd9Sstevel@tonic-gate } 16667c478bd9Sstevel@tonic-gate goto bad_syntax; 16677c478bd9Sstevel@tonic-gate 16687c478bd9Sstevel@tonic-gate case 'n': 16697c478bd9Sstevel@tonic-gate if (colon) 16707c478bd9Sstevel@tonic-gate colon = 0; 16717c478bd9Sstevel@tonic-gate else 16727c478bd9Sstevel@tonic-gate goto no_colon; 16737c478bd9Sstevel@tonic-gate if (match("nm", 1)) { /* directory name */ 16747c478bd9Sstevel@tonic-gate objsz = DIRECTORY; 16757c478bd9Sstevel@tonic-gate acting_on_directory = 1; 16767c478bd9Sstevel@tonic-gate cur_dir = addr; 16777c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 16787c478bd9Sstevel@tonic-gate continue; 16797c478bd9Sstevel@tonic-gate /*LINTED*/ 16807c478bd9Sstevel@tonic-gate dirp = (struct direct *)(cptr+blkoff(fs, addr)); 16817c478bd9Sstevel@tonic-gate stringsize = (long)dirp->d_reclen - 16827c478bd9Sstevel@tonic-gate ((long)&dirp->d_name[0] - 16837c478bd9Sstevel@tonic-gate (long)&dirp->d_ino); 1684d1a180b0Smaheshvs addr = (long)&((struct direct *) 1685d1a180b0Smaheshvs (uintptr_t)addr)->d_name[0]; 16867c478bd9Sstevel@tonic-gate type = NULL; 16877c478bd9Sstevel@tonic-gate continue; 16887c478bd9Sstevel@tonic-gate } 16897c478bd9Sstevel@tonic-gate goto bad_syntax; 16907c478bd9Sstevel@tonic-gate 16917c478bd9Sstevel@tonic-gate case 'o': 16927c478bd9Sstevel@tonic-gate if (colon) 16937c478bd9Sstevel@tonic-gate colon = 0; 16947c478bd9Sstevel@tonic-gate else 16957c478bd9Sstevel@tonic-gate goto no_colon; 16967c478bd9Sstevel@tonic-gate if (match("override", 1)) { /* override flip flop */ 16977c478bd9Sstevel@tonic-gate override = !override; 16987c478bd9Sstevel@tonic-gate if (override) 16997c478bd9Sstevel@tonic-gate printf("error checking off\n"); 17007c478bd9Sstevel@tonic-gate else 17017c478bd9Sstevel@tonic-gate printf("error checking on\n"); 17027c478bd9Sstevel@tonic-gate continue; 17037c478bd9Sstevel@tonic-gate } 17047c478bd9Sstevel@tonic-gate goto bad_syntax; 17057c478bd9Sstevel@tonic-gate 17067c478bd9Sstevel@tonic-gate case 'p': 17077c478bd9Sstevel@tonic-gate if (colon) 17087c478bd9Sstevel@tonic-gate colon = 0; 17097c478bd9Sstevel@tonic-gate else 17107c478bd9Sstevel@tonic-gate goto no_colon; 17117c478bd9Sstevel@tonic-gate if (match("pwd", 2)) { /* print working dir */ 17127c478bd9Sstevel@tonic-gate print_path(current_path, (int)current_pathp); 17137c478bd9Sstevel@tonic-gate printf("\n"); 17147c478bd9Sstevel@tonic-gate continue; 17157c478bd9Sstevel@tonic-gate } 17167c478bd9Sstevel@tonic-gate if (match("prompt", 2)) { /* change prompt */ 17177c478bd9Sstevel@tonic-gate if ((c = getachar()) != '=') { 17187c478bd9Sstevel@tonic-gate printf("missing '='\n"); 17197c478bd9Sstevel@tonic-gate error++; 17207c478bd9Sstevel@tonic-gate continue; 17217c478bd9Sstevel@tonic-gate } 17227c478bd9Sstevel@tonic-gate if ((c = getachar()) != '"') { 17237c478bd9Sstevel@tonic-gate printf("missing '\"'\n"); 17247c478bd9Sstevel@tonic-gate error++; 17257c478bd9Sstevel@tonic-gate continue; 17267c478bd9Sstevel@tonic-gate } 17277c478bd9Sstevel@tonic-gate i = 0; 17287c478bd9Sstevel@tonic-gate prompt = &prompt[0]; 17297c478bd9Sstevel@tonic-gate while ((c = getachar()) != '"' && c != '\n') { 17307c478bd9Sstevel@tonic-gate prompt[i++] = c; 17317c478bd9Sstevel@tonic-gate if (i >= PROMPTSIZE) { 17327c478bd9Sstevel@tonic-gate printf("string too long\n"); 17337c478bd9Sstevel@tonic-gate error++; 17347c478bd9Sstevel@tonic-gate break; 17357c478bd9Sstevel@tonic-gate } 17367c478bd9Sstevel@tonic-gate } 17377c478bd9Sstevel@tonic-gate prompt[i] = '\0'; 17387c478bd9Sstevel@tonic-gate continue; 17397c478bd9Sstevel@tonic-gate } 17407c478bd9Sstevel@tonic-gate goto bad_syntax; 17417c478bd9Sstevel@tonic-gate 17427c478bd9Sstevel@tonic-gate case 'q': 17437c478bd9Sstevel@tonic-gate if (!colon) 17447c478bd9Sstevel@tonic-gate goto no_colon; 17457c478bd9Sstevel@tonic-gate if (match("quit", 1)) { /* quit */ 17467c478bd9Sstevel@tonic-gate if ((c = getachar()) != '\n') { 17477c478bd9Sstevel@tonic-gate error++; 17487c478bd9Sstevel@tonic-gate continue; 17497c478bd9Sstevel@tonic-gate } 17507c478bd9Sstevel@tonic-gate exit(0); 17517c478bd9Sstevel@tonic-gate } 17527c478bd9Sstevel@tonic-gate goto bad_syntax; 17537c478bd9Sstevel@tonic-gate 17547c478bd9Sstevel@tonic-gate case 's': 17557c478bd9Sstevel@tonic-gate if (colon) 17567c478bd9Sstevel@tonic-gate colon = 0; 17577c478bd9Sstevel@tonic-gate else 17587c478bd9Sstevel@tonic-gate goto no_colon; 17597c478bd9Sstevel@tonic-gate if (match("sb", 2)) { /* super block */ 17607c478bd9Sstevel@tonic-gate if (c_count == 2) { 17617c478bd9Sstevel@tonic-gate cur_cgrp = -1; 17627c478bd9Sstevel@tonic-gate type = objsz = SB; 17637c478bd9Sstevel@tonic-gate laststyle = '='; 17647c478bd9Sstevel@tonic-gate lastpo = 's'; 17657c478bd9Sstevel@tonic-gate should_print = 1; 17667c478bd9Sstevel@tonic-gate continue; 17677c478bd9Sstevel@tonic-gate } 17687c478bd9Sstevel@tonic-gate if (type == NUMB) 17697c478bd9Sstevel@tonic-gate value = addr; 17707c478bd9Sstevel@tonic-gate if (value > fs->fs_ncg - 1) { 17717c478bd9Sstevel@tonic-gate printf("maximum super block is "); 17727c478bd9Sstevel@tonic-gate print(fs->fs_ncg - 1, 8, -8, 0); 17737c478bd9Sstevel@tonic-gate printf("\n"); 17747c478bd9Sstevel@tonic-gate error++; 17757c478bd9Sstevel@tonic-gate continue; 17767c478bd9Sstevel@tonic-gate } 17777c478bd9Sstevel@tonic-gate type = objsz = SB; 17787c478bd9Sstevel@tonic-gate cur_cgrp = (long)value; 17797c478bd9Sstevel@tonic-gate addr = cgsblock(fs, cur_cgrp) << FRGSHIFT; 17807c478bd9Sstevel@tonic-gate continue; 17817c478bd9Sstevel@tonic-gate } 17827c478bd9Sstevel@tonic-gate if (match("shadow", 2)) { /* shadow inode data */ 17837c478bd9Sstevel@tonic-gate if (type == NUMB) 17847c478bd9Sstevel@tonic-gate value = addr; 17857c478bd9Sstevel@tonic-gate objsz = SHADOW_DATA; 17867c478bd9Sstevel@tonic-gate type = SHADOW_DATA; 17877c478bd9Sstevel@tonic-gate addr = getshadowslot(value); 17887c478bd9Sstevel@tonic-gate continue; 17897c478bd9Sstevel@tonic-gate } 17907c478bd9Sstevel@tonic-gate if (match("si", 2)) { /* shadow inode field */ 17917c478bd9Sstevel@tonic-gate acting_on_inode = 1; 17927c478bd9Sstevel@tonic-gate should_print = 1; 1793d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1794d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_shadow; 17957c478bd9Sstevel@tonic-gate value = get(LONG); 17967c478bd9Sstevel@tonic-gate type = NULL; 17977c478bd9Sstevel@tonic-gate continue; 17987c478bd9Sstevel@tonic-gate } 17997c478bd9Sstevel@tonic-gate 18007c478bd9Sstevel@tonic-gate if (match("sz", 2)) { /* file size */ 18017c478bd9Sstevel@tonic-gate acting_on_inode = 1; 18027c478bd9Sstevel@tonic-gate should_print = 1; 1803d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1804d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_size; 18057c478bd9Sstevel@tonic-gate value = get(U_OFFSET_T); 18067c478bd9Sstevel@tonic-gate type = NULL; 18077c478bd9Sstevel@tonic-gate objsz = U_OFFSET_T; 18087c478bd9Sstevel@tonic-gate laststyle = '='; 18097c478bd9Sstevel@tonic-gate lastpo = 'X'; 18107c478bd9Sstevel@tonic-gate continue; 18117c478bd9Sstevel@tonic-gate } 18127c478bd9Sstevel@tonic-gate goto bad_syntax; 18137c478bd9Sstevel@tonic-gate 18147c478bd9Sstevel@tonic-gate case 'u': 18157c478bd9Sstevel@tonic-gate if (colon) 18167c478bd9Sstevel@tonic-gate colon = 0; 18177c478bd9Sstevel@tonic-gate else 18187c478bd9Sstevel@tonic-gate goto no_colon; 18197c478bd9Sstevel@tonic-gate if (match("uid", 1)) { /* user id */ 18207c478bd9Sstevel@tonic-gate acting_on_inode = 1; 18217c478bd9Sstevel@tonic-gate should_print = 1; 1822d1a180b0Smaheshvs addr = (long)&((struct dinode *) 1823d1a180b0Smaheshvs (uintptr_t)cur_ino)->di_uid; 18247c478bd9Sstevel@tonic-gate value = get(SHORT); 18257c478bd9Sstevel@tonic-gate type = NULL; 18267c478bd9Sstevel@tonic-gate continue; 18277c478bd9Sstevel@tonic-gate } 18287c478bd9Sstevel@tonic-gate goto bad_syntax; 18297c478bd9Sstevel@tonic-gate 18307c478bd9Sstevel@tonic-gate case 'F': /* buffer status (internal use only) */ 18317c478bd9Sstevel@tonic-gate if (colon) 18327c478bd9Sstevel@tonic-gate colon = 0; 18337c478bd9Sstevel@tonic-gate else 18347c478bd9Sstevel@tonic-gate goto no_colon; 18357c478bd9Sstevel@tonic-gate for (bp = bhdr.fwd; bp != &bhdr; bp = bp->fwd) 18367c478bd9Sstevel@tonic-gate printf("%8" PRIx64 " %d\n", 18377c478bd9Sstevel@tonic-gate bp->blkno, bp->valid); 18387c478bd9Sstevel@tonic-gate printf("\n"); 18397c478bd9Sstevel@tonic-gate printf("# commands\t\t%ld\n", commands); 18407c478bd9Sstevel@tonic-gate printf("# read requests\t\t%ld\n", read_requests); 18417c478bd9Sstevel@tonic-gate printf("# actual disk reads\t%ld\n", actual_disk_reads); 18427c478bd9Sstevel@tonic-gate continue; 18437c478bd9Sstevel@tonic-gate no_colon: 18447c478bd9Sstevel@tonic-gate printf("a colon should precede a command\n"); 18457c478bd9Sstevel@tonic-gate error++; 18467c478bd9Sstevel@tonic-gate continue; 18477c478bd9Sstevel@tonic-gate bad_syntax: 18487c478bd9Sstevel@tonic-gate printf("more letters needed to distinguish command\n"); 18497c478bd9Sstevel@tonic-gate error++; 18507c478bd9Sstevel@tonic-gate continue; 18517c478bd9Sstevel@tonic-gate } 18527c478bd9Sstevel@tonic-gate } 18537c478bd9Sstevel@tonic-gate } 18547c478bd9Sstevel@tonic-gate 18557c478bd9Sstevel@tonic-gate /* 18567c478bd9Sstevel@tonic-gate * usage - print usage and exit 18577c478bd9Sstevel@tonic-gate */ 18587c478bd9Sstevel@tonic-gate static void 1859d1a180b0Smaheshvs usage(char *progname) 18607c478bd9Sstevel@tonic-gate { 18617c478bd9Sstevel@tonic-gate printf("usage: %s [options] special\n", progname); 18627c478bd9Sstevel@tonic-gate printf("options:\n"); 18637c478bd9Sstevel@tonic-gate printf("\t-o Specify ufs filesystem sepcific options\n"); 18647c478bd9Sstevel@tonic-gate printf(" Available suboptions are:\n"); 18657c478bd9Sstevel@tonic-gate printf("\t\t? display usage\n"); 18667c478bd9Sstevel@tonic-gate printf("\t\to override some error conditions\n"); 18677c478bd9Sstevel@tonic-gate printf("\t\tp=\"string\" set prompt to string\n"); 18687c478bd9Sstevel@tonic-gate printf("\t\tw open for write\n"); 18697c478bd9Sstevel@tonic-gate exit(1); 18707c478bd9Sstevel@tonic-gate } 18717c478bd9Sstevel@tonic-gate 18727c478bd9Sstevel@tonic-gate /* 18737c478bd9Sstevel@tonic-gate * getachar - get next character from input buffer. 18747c478bd9Sstevel@tonic-gate */ 18757c478bd9Sstevel@tonic-gate static char 18767c478bd9Sstevel@tonic-gate getachar() 18777c478bd9Sstevel@tonic-gate { 18787c478bd9Sstevel@tonic-gate return (input_buffer[input_pointer++]); 18797c478bd9Sstevel@tonic-gate } 18807c478bd9Sstevel@tonic-gate 18817c478bd9Sstevel@tonic-gate /* 18827c478bd9Sstevel@tonic-gate * ungetachar - return character to input buffer. 18837c478bd9Sstevel@tonic-gate */ 18847c478bd9Sstevel@tonic-gate static void 1885d1a180b0Smaheshvs ungetachar(char c) 18867c478bd9Sstevel@tonic-gate { 18877c478bd9Sstevel@tonic-gate if (input_pointer == 0) { 18887c478bd9Sstevel@tonic-gate printf("internal problem maintaining input buffer\n"); 18897c478bd9Sstevel@tonic-gate error++; 18907c478bd9Sstevel@tonic-gate return; 18917c478bd9Sstevel@tonic-gate } 18927c478bd9Sstevel@tonic-gate input_buffer[--input_pointer] = c; 18937c478bd9Sstevel@tonic-gate } 18947c478bd9Sstevel@tonic-gate 18957c478bd9Sstevel@tonic-gate /* 18967c478bd9Sstevel@tonic-gate * getnextinput - display the prompt and read an input line. 18977c478bd9Sstevel@tonic-gate * An input line is up to 128 characters terminated by the newline 18987c478bd9Sstevel@tonic-gate * character. Handle overflow, shell escape, and eof. 18997c478bd9Sstevel@tonic-gate */ 19007c478bd9Sstevel@tonic-gate static void 19017c478bd9Sstevel@tonic-gate getnextinput() 19027c478bd9Sstevel@tonic-gate { 1903d1a180b0Smaheshvs int i; 1904d1a180b0Smaheshvs char c; 1905d1a180b0Smaheshvs short pid, rpid; 19067c478bd9Sstevel@tonic-gate int retcode; 19077c478bd9Sstevel@tonic-gate 19087c478bd9Sstevel@tonic-gate newline: 19097c478bd9Sstevel@tonic-gate i = 0; 19107c478bd9Sstevel@tonic-gate printf("%s", prompt); 19117c478bd9Sstevel@tonic-gate ignore_eol: 19127c478bd9Sstevel@tonic-gate while ((c = getc(stdin)) != '\n' && !(c == '!' && i == 0) && 19137c478bd9Sstevel@tonic-gate !feof(stdin) && i <= INPUTBUFFER - 2) 19147c478bd9Sstevel@tonic-gate input_buffer[i++] = c; 19157c478bd9Sstevel@tonic-gate if (i > 0 && input_buffer[i - 1] == '\\') { 19167c478bd9Sstevel@tonic-gate input_buffer[i++] = c; 19177c478bd9Sstevel@tonic-gate goto ignore_eol; 19187c478bd9Sstevel@tonic-gate } 19197c478bd9Sstevel@tonic-gate if (feof(stdin)) { 19207c478bd9Sstevel@tonic-gate printf("\n"); 19217c478bd9Sstevel@tonic-gate exit(0); 19227c478bd9Sstevel@tonic-gate } 19237c478bd9Sstevel@tonic-gate if (c == '!') { 19247c478bd9Sstevel@tonic-gate if ((pid = fork()) == 0) { 19257c478bd9Sstevel@tonic-gate (void) execl(_PATH_BSHELL, "sh", "-t", 0); 19267c478bd9Sstevel@tonic-gate error++; 19277c478bd9Sstevel@tonic-gate return; 19287c478bd9Sstevel@tonic-gate } 19297c478bd9Sstevel@tonic-gate while ((rpid = wait(&retcode)) != pid && rpid != -1) 19307c478bd9Sstevel@tonic-gate ; 19317c478bd9Sstevel@tonic-gate printf("!\n"); 19327c478bd9Sstevel@tonic-gate goto newline; 19337c478bd9Sstevel@tonic-gate } 19347c478bd9Sstevel@tonic-gate if (c != '\n') 19357c478bd9Sstevel@tonic-gate printf("input truncated to 128 characters\n"); 19367c478bd9Sstevel@tonic-gate input_buffer[i] = '\n'; 19377c478bd9Sstevel@tonic-gate input_pointer = 0; 19387c478bd9Sstevel@tonic-gate } 19397c478bd9Sstevel@tonic-gate 19407c478bd9Sstevel@tonic-gate /* 19417c478bd9Sstevel@tonic-gate * eat_spaces - read extraneous spaces. 19427c478bd9Sstevel@tonic-gate */ 19437c478bd9Sstevel@tonic-gate static void 19447c478bd9Sstevel@tonic-gate eat_spaces() 19457c478bd9Sstevel@tonic-gate { 1946d1a180b0Smaheshvs char c; 19477c478bd9Sstevel@tonic-gate 19487c478bd9Sstevel@tonic-gate while ((c = getachar()) == ' ') 19497c478bd9Sstevel@tonic-gate ; 19507c478bd9Sstevel@tonic-gate ungetachar(c); 19517c478bd9Sstevel@tonic-gate } 19527c478bd9Sstevel@tonic-gate 19537c478bd9Sstevel@tonic-gate /* 19547c478bd9Sstevel@tonic-gate * restore_inode - set up all inode indicators so inum is now 19557c478bd9Sstevel@tonic-gate * the current inode. 19567c478bd9Sstevel@tonic-gate */ 19577c478bd9Sstevel@tonic-gate static void 1958d1a180b0Smaheshvs restore_inode(ino_t inum) 19597c478bd9Sstevel@tonic-gate { 19607c478bd9Sstevel@tonic-gate errinum = cur_inum = inum; 19617c478bd9Sstevel@tonic-gate addr = errino = cur_ino = itob(inum); 19627c478bd9Sstevel@tonic-gate } 19637c478bd9Sstevel@tonic-gate 19647c478bd9Sstevel@tonic-gate /* 19657c478bd9Sstevel@tonic-gate * match - return false if the input does not match string up to 19667c478bd9Sstevel@tonic-gate * upto letters. Then proceed to chew up extraneous letters. 19677c478bd9Sstevel@tonic-gate */ 19687c478bd9Sstevel@tonic-gate static int 1969d1a180b0Smaheshvs match(char *string, int upto) 19707c478bd9Sstevel@tonic-gate { 1971d1a180b0Smaheshvs int i, length = strlen(string) - 1; 1972d1a180b0Smaheshvs char c; 19737c478bd9Sstevel@tonic-gate int save_upto = upto; 19747c478bd9Sstevel@tonic-gate 19757c478bd9Sstevel@tonic-gate while (--upto) { 19767c478bd9Sstevel@tonic-gate string++; 19777c478bd9Sstevel@tonic-gate if ((c = getachar()) != *string) { 19787c478bd9Sstevel@tonic-gate for (i = save_upto - upto; i; i--) { 19797c478bd9Sstevel@tonic-gate ungetachar(c); 19807c478bd9Sstevel@tonic-gate c = *--string; 19817c478bd9Sstevel@tonic-gate } 19827c478bd9Sstevel@tonic-gate return (0); 19837c478bd9Sstevel@tonic-gate } 19847c478bd9Sstevel@tonic-gate length--; 19857c478bd9Sstevel@tonic-gate } 19867c478bd9Sstevel@tonic-gate while (length--) { 19877c478bd9Sstevel@tonic-gate string++; 19887c478bd9Sstevel@tonic-gate if ((c = getachar()) != *string) { 19897c478bd9Sstevel@tonic-gate ungetachar(c); 19907c478bd9Sstevel@tonic-gate return (1); 19917c478bd9Sstevel@tonic-gate } 19927c478bd9Sstevel@tonic-gate } 19937c478bd9Sstevel@tonic-gate return (1); 19947c478bd9Sstevel@tonic-gate } 19957c478bd9Sstevel@tonic-gate 19967c478bd9Sstevel@tonic-gate /* 19977c478bd9Sstevel@tonic-gate * expr - expression evaluator. Will evaluate expressions from 19987c478bd9Sstevel@tonic-gate * left to right with no operator precedence. Parentheses may 19997c478bd9Sstevel@tonic-gate * be used. 20007c478bd9Sstevel@tonic-gate */ 20017c478bd9Sstevel@tonic-gate static long 20027c478bd9Sstevel@tonic-gate expr() 20037c478bd9Sstevel@tonic-gate { 2004d1a180b0Smaheshvs long numb = 0, temp; 2005d1a180b0Smaheshvs char c; 20067c478bd9Sstevel@tonic-gate 20077c478bd9Sstevel@tonic-gate numb = term(); 20087c478bd9Sstevel@tonic-gate for (;;) { 20097c478bd9Sstevel@tonic-gate if (error) 20107c478bd9Sstevel@tonic-gate return (~0); /* error is set so value is ignored */ 20117c478bd9Sstevel@tonic-gate c = getachar(); 20127c478bd9Sstevel@tonic-gate switch (c) { 20137c478bd9Sstevel@tonic-gate 20147c478bd9Sstevel@tonic-gate case '+': 20157c478bd9Sstevel@tonic-gate numb += term(); 20167c478bd9Sstevel@tonic-gate continue; 20177c478bd9Sstevel@tonic-gate 20187c478bd9Sstevel@tonic-gate case '-': 20197c478bd9Sstevel@tonic-gate numb -= term(); 20207c478bd9Sstevel@tonic-gate continue; 20217c478bd9Sstevel@tonic-gate 20227c478bd9Sstevel@tonic-gate case '*': 20237c478bd9Sstevel@tonic-gate numb *= term(); 20247c478bd9Sstevel@tonic-gate continue; 20257c478bd9Sstevel@tonic-gate 20267c478bd9Sstevel@tonic-gate case '%': 20277c478bd9Sstevel@tonic-gate temp = term(); 20287c478bd9Sstevel@tonic-gate if (!temp) { 20297c478bd9Sstevel@tonic-gate printf("divide by zero\n"); 20307c478bd9Sstevel@tonic-gate error++; 20317c478bd9Sstevel@tonic-gate return (~0); 20327c478bd9Sstevel@tonic-gate } 20337c478bd9Sstevel@tonic-gate numb /= temp; 20347c478bd9Sstevel@tonic-gate continue; 20357c478bd9Sstevel@tonic-gate 20367c478bd9Sstevel@tonic-gate case ')': 20377c478bd9Sstevel@tonic-gate paren--; 20387c478bd9Sstevel@tonic-gate return (numb); 20397c478bd9Sstevel@tonic-gate 20407c478bd9Sstevel@tonic-gate default: 20417c478bd9Sstevel@tonic-gate ungetachar(c); 20427c478bd9Sstevel@tonic-gate if (paren && !error) { 20437c478bd9Sstevel@tonic-gate printf("missing ')'\n"); 20447c478bd9Sstevel@tonic-gate error++; 20457c478bd9Sstevel@tonic-gate } 20467c478bd9Sstevel@tonic-gate return (numb); 20477c478bd9Sstevel@tonic-gate } 20487c478bd9Sstevel@tonic-gate } 20497c478bd9Sstevel@tonic-gate } 20507c478bd9Sstevel@tonic-gate 20517c478bd9Sstevel@tonic-gate /* 20527c478bd9Sstevel@tonic-gate * term - used by expression evaluator to get an operand. 20537c478bd9Sstevel@tonic-gate */ 20547c478bd9Sstevel@tonic-gate static long 20557c478bd9Sstevel@tonic-gate term() 20567c478bd9Sstevel@tonic-gate { 2057d1a180b0Smaheshvs char c; 20587c478bd9Sstevel@tonic-gate 20597c478bd9Sstevel@tonic-gate switch (c = getachar()) { 20607c478bd9Sstevel@tonic-gate 20617c478bd9Sstevel@tonic-gate default: 20627c478bd9Sstevel@tonic-gate ungetachar(c); 20637c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 20647c478bd9Sstevel@tonic-gate case '+': 20657c478bd9Sstevel@tonic-gate return (getnumb()); 20667c478bd9Sstevel@tonic-gate 20677c478bd9Sstevel@tonic-gate case '-': 20687c478bd9Sstevel@tonic-gate return (-getnumb()); 20697c478bd9Sstevel@tonic-gate 20707c478bd9Sstevel@tonic-gate case '(': 20717c478bd9Sstevel@tonic-gate paren++; 20727c478bd9Sstevel@tonic-gate return (expr()); 20737c478bd9Sstevel@tonic-gate } 20747c478bd9Sstevel@tonic-gate } 20757c478bd9Sstevel@tonic-gate 20767c478bd9Sstevel@tonic-gate /* 20777c478bd9Sstevel@tonic-gate * getnumb - read a number from the input stream. A leading 20787c478bd9Sstevel@tonic-gate * zero signifies octal interpretation, a leading '0x' 20797c478bd9Sstevel@tonic-gate * signifies hexadecimal, and a leading '0t' signifies 20807c478bd9Sstevel@tonic-gate * decimal. If the first character is a character, 20817c478bd9Sstevel@tonic-gate * return an error. 20827c478bd9Sstevel@tonic-gate */ 20837c478bd9Sstevel@tonic-gate static long 20847c478bd9Sstevel@tonic-gate getnumb() 20857c478bd9Sstevel@tonic-gate { 20867c478bd9Sstevel@tonic-gate 2087d1a180b0Smaheshvs char c, savec; 20887c478bd9Sstevel@tonic-gate long number = 0, tbase, num; 20897c478bd9Sstevel@tonic-gate extern short error; 20907c478bd9Sstevel@tonic-gate 20917c478bd9Sstevel@tonic-gate c = getachar(); 20927c478bd9Sstevel@tonic-gate if (!digit(c)) { 20937c478bd9Sstevel@tonic-gate error++; 20947c478bd9Sstevel@tonic-gate ungetachar(c); 20957c478bd9Sstevel@tonic-gate return (-1); 20967c478bd9Sstevel@tonic-gate } 20977c478bd9Sstevel@tonic-gate if (c == '0') { 20987c478bd9Sstevel@tonic-gate tbase = OCTAL; 20997c478bd9Sstevel@tonic-gate if ((c = getachar()) == 'x') 21007c478bd9Sstevel@tonic-gate tbase = HEX; 21017c478bd9Sstevel@tonic-gate else if (c == 't') 21027c478bd9Sstevel@tonic-gate tbase = DECIMAL; 21037c478bd9Sstevel@tonic-gate else ungetachar(c); 21047c478bd9Sstevel@tonic-gate } else { 21057c478bd9Sstevel@tonic-gate tbase = base; 21067c478bd9Sstevel@tonic-gate ungetachar(c); 21077c478bd9Sstevel@tonic-gate } 21087c478bd9Sstevel@tonic-gate for (;;) { 21097c478bd9Sstevel@tonic-gate num = tbase; 21107c478bd9Sstevel@tonic-gate c = savec = getachar(); 21117c478bd9Sstevel@tonic-gate if (HEXLETTER(c)) 21127c478bd9Sstevel@tonic-gate c = uppertolower(c); 21137c478bd9Sstevel@tonic-gate switch (tbase) { 21147c478bd9Sstevel@tonic-gate case HEX: 21157c478bd9Sstevel@tonic-gate if (hexletter(c)) { 21167c478bd9Sstevel@tonic-gate num = hextodigit(c); 21177c478bd9Sstevel@tonic-gate break; 21187c478bd9Sstevel@tonic-gate } 21197c478bd9Sstevel@tonic-gate /*FALLTHRU*/ 21207c478bd9Sstevel@tonic-gate case DECIMAL: 21217c478bd9Sstevel@tonic-gate if (digit(c)) 21227c478bd9Sstevel@tonic-gate num = numtodigit(c); 21237c478bd9Sstevel@tonic-gate break; 21247c478bd9Sstevel@tonic-gate case OCTAL: 21257c478bd9Sstevel@tonic-gate if (octaldigit(c)) 21267c478bd9Sstevel@tonic-gate num = numtodigit(c); 21277c478bd9Sstevel@tonic-gate } 21287c478bd9Sstevel@tonic-gate if (num == tbase) 21297c478bd9Sstevel@tonic-gate break; 21307c478bd9Sstevel@tonic-gate number = number * tbase + num; 21317c478bd9Sstevel@tonic-gate } 21327c478bd9Sstevel@tonic-gate ungetachar(savec); 21337c478bd9Sstevel@tonic-gate return (number); 21347c478bd9Sstevel@tonic-gate } 21357c478bd9Sstevel@tonic-gate 21367c478bd9Sstevel@tonic-gate /* 21377c478bd9Sstevel@tonic-gate * find - the syntax is almost identical to the unix command. 21387c478bd9Sstevel@tonic-gate * find dir [-name pattern] [-inum number] 21397c478bd9Sstevel@tonic-gate * Note: only one of -name or -inum may be used at a time. 21407c478bd9Sstevel@tonic-gate * Also, the -print is not needed (implied). 21417c478bd9Sstevel@tonic-gate */ 21427c478bd9Sstevel@tonic-gate static void 21437c478bd9Sstevel@tonic-gate find() 21447c478bd9Sstevel@tonic-gate { 2145d1a180b0Smaheshvs struct filenames *fn; 2146d1a180b0Smaheshvs char c; 21477c478bd9Sstevel@tonic-gate long temp; 21487c478bd9Sstevel@tonic-gate short mode; 21497c478bd9Sstevel@tonic-gate 21507c478bd9Sstevel@tonic-gate eat_spaces(); 21517c478bd9Sstevel@tonic-gate temp = cur_inum; 21527c478bd9Sstevel@tonic-gate top = filenames - 1; 21537c478bd9Sstevel@tonic-gate doing_cd = 1; 21547c478bd9Sstevel@tonic-gate parse(); 21557c478bd9Sstevel@tonic-gate doing_cd = 0; 21567c478bd9Sstevel@tonic-gate if (nfiles != 1) { 21577c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 21587c478bd9Sstevel@tonic-gate if (!error) { 21597c478bd9Sstevel@tonic-gate print_path(input_path, (int)input_pathp); 21607c478bd9Sstevel@tonic-gate if (nfiles == 0) 21617c478bd9Sstevel@tonic-gate printf(" not found\n"); 21627c478bd9Sstevel@tonic-gate else 21637c478bd9Sstevel@tonic-gate printf(" ambiguous\n"); 21647c478bd9Sstevel@tonic-gate error++; 21657c478bd9Sstevel@tonic-gate return; 21667c478bd9Sstevel@tonic-gate } 21677c478bd9Sstevel@tonic-gate } 21687c478bd9Sstevel@tonic-gate restore_inode(filenames->ino); 21697c478bd9Sstevel@tonic-gate freemem(filenames, nfiles); 21707c478bd9Sstevel@tonic-gate nfiles = 0; 21717c478bd9Sstevel@tonic-gate top = filenames - 1; 21727c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 21737c478bd9Sstevel@tonic-gate return; 21747c478bd9Sstevel@tonic-gate if ((mode & IFMT) != IFDIR) { 21757c478bd9Sstevel@tonic-gate print_path(input_path, (int)input_pathp); 21767c478bd9Sstevel@tonic-gate printf(" not a directory\n"); 21777c478bd9Sstevel@tonic-gate error++; 21787c478bd9Sstevel@tonic-gate return; 21797c478bd9Sstevel@tonic-gate } 21807c478bd9Sstevel@tonic-gate eat_spaces(); 21817c478bd9Sstevel@tonic-gate if ((c = getachar()) != '-') { 21827c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 21837c478bd9Sstevel@tonic-gate printf("missing '-'\n"); 21847c478bd9Sstevel@tonic-gate error++; 21857c478bd9Sstevel@tonic-gate return; 21867c478bd9Sstevel@tonic-gate } 21877c478bd9Sstevel@tonic-gate find_by_name = find_by_inode = 0; 21887c478bd9Sstevel@tonic-gate c = getachar(); 21897c478bd9Sstevel@tonic-gate if (match("name", 4)) { 21907c478bd9Sstevel@tonic-gate eat_spaces(); 21917c478bd9Sstevel@tonic-gate find_by_name = 1; 21927c478bd9Sstevel@tonic-gate } else if (match("inum", 4)) { 21937c478bd9Sstevel@tonic-gate eat_spaces(); 21947c478bd9Sstevel@tonic-gate find_ino = expr(); 21957c478bd9Sstevel@tonic-gate if (error) { 21967c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 21977c478bd9Sstevel@tonic-gate return; 21987c478bd9Sstevel@tonic-gate } 21997c478bd9Sstevel@tonic-gate while ((c = getachar()) != '\n') 22007c478bd9Sstevel@tonic-gate ; 22017c478bd9Sstevel@tonic-gate ungetachar(c); 22027c478bd9Sstevel@tonic-gate find_by_inode = 1; 22037c478bd9Sstevel@tonic-gate } else { 22047c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 22057c478bd9Sstevel@tonic-gate printf("use -name or -inum with find\n"); 22067c478bd9Sstevel@tonic-gate error++; 22077c478bd9Sstevel@tonic-gate return; 22087c478bd9Sstevel@tonic-gate } 22097c478bd9Sstevel@tonic-gate doing_find = 1; 22107c478bd9Sstevel@tonic-gate parse(); 22117c478bd9Sstevel@tonic-gate doing_find = 0; 22127c478bd9Sstevel@tonic-gate if (error) { 22137c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 22147c478bd9Sstevel@tonic-gate return; 22157c478bd9Sstevel@tonic-gate } 22167c478bd9Sstevel@tonic-gate for (fn = filenames; fn <= top; fn++) { 22177c478bd9Sstevel@tonic-gate if (fn->find == 0) 22187c478bd9Sstevel@tonic-gate continue; 22197c478bd9Sstevel@tonic-gate printf("i#: "); 22207c478bd9Sstevel@tonic-gate print(fn->ino, 12, -8, 0); 22217c478bd9Sstevel@tonic-gate print_path(fn->fname, (int)fn->len); 22227c478bd9Sstevel@tonic-gate printf("\n"); 22237c478bd9Sstevel@tonic-gate } 22247c478bd9Sstevel@tonic-gate restore_inode((ino_t)temp); 22257c478bd9Sstevel@tonic-gate } 22267c478bd9Sstevel@tonic-gate 22277c478bd9Sstevel@tonic-gate /* 22287c478bd9Sstevel@tonic-gate * ls - do an ls. Should behave exactly as ls(1). 22297c478bd9Sstevel@tonic-gate * Only -R and -l is supported and -l gives different results. 22307c478bd9Sstevel@tonic-gate */ 22317c478bd9Sstevel@tonic-gate static void 2232d1a180b0Smaheshvs ls(struct filenames *fn0, struct filenames *fnlast, short level) 22337c478bd9Sstevel@tonic-gate { 2234d1a180b0Smaheshvs struct filenames *fn, *fnn; 22357c478bd9Sstevel@tonic-gate 22367c478bd9Sstevel@tonic-gate fn = fn0; 22377c478bd9Sstevel@tonic-gate for (;;) { 22387c478bd9Sstevel@tonic-gate fn0 = fn; 22397c478bd9Sstevel@tonic-gate if (fn0->len) { 22407c478bd9Sstevel@tonic-gate cmp_level = level; 22417c478bd9Sstevel@tonic-gate qsort((char *)fn0, fnlast - fn0 + 1, 22427c478bd9Sstevel@tonic-gate sizeof (struct filenames), fcmp); 22437c478bd9Sstevel@tonic-gate } 22447c478bd9Sstevel@tonic-gate for (fnn = fn, fn++; fn <= fnlast; fnn = fn, fn++) { 22457c478bd9Sstevel@tonic-gate if (fnn->len != fn->len && level == fnn->len - 1) 22467c478bd9Sstevel@tonic-gate break; 22477c478bd9Sstevel@tonic-gate if (fnn->len == 0) 22487c478bd9Sstevel@tonic-gate continue; 22497c478bd9Sstevel@tonic-gate if (strcmp(fn->fname[level], fnn->fname[level])) 22507c478bd9Sstevel@tonic-gate break; 22517c478bd9Sstevel@tonic-gate } 22527c478bd9Sstevel@tonic-gate if (fn0->len && level != fn0->len - 1) 22537c478bd9Sstevel@tonic-gate ls(fn0, fnn, level + 1); 22547c478bd9Sstevel@tonic-gate else { 22557c478bd9Sstevel@tonic-gate if (fn0 != filenames) 22567c478bd9Sstevel@tonic-gate printf("\n"); 22577c478bd9Sstevel@tonic-gate print_path(fn0->fname, (int)(fn0->len - 1)); 22587c478bd9Sstevel@tonic-gate printf(":\n"); 22597c478bd9Sstevel@tonic-gate if (fn0->len == 0) 22607c478bd9Sstevel@tonic-gate cmp_level = level; 22617c478bd9Sstevel@tonic-gate else 22627c478bd9Sstevel@tonic-gate cmp_level = level + 1; 22637c478bd9Sstevel@tonic-gate qsort((char *)fn0, fnn - fn0 + 1, 22647c478bd9Sstevel@tonic-gate sizeof (struct filenames), fcmp); 22657c478bd9Sstevel@tonic-gate formatf(fn0, fnn); 22667c478bd9Sstevel@tonic-gate nfiles -= fnn - fn0 + 1; 22677c478bd9Sstevel@tonic-gate } 22687c478bd9Sstevel@tonic-gate if (fn > fnlast) 22697c478bd9Sstevel@tonic-gate return; 22707c478bd9Sstevel@tonic-gate } 22717c478bd9Sstevel@tonic-gate } 22727c478bd9Sstevel@tonic-gate 22737c478bd9Sstevel@tonic-gate /* 22747c478bd9Sstevel@tonic-gate * formatf - code lifted from ls. 22757c478bd9Sstevel@tonic-gate */ 22767c478bd9Sstevel@tonic-gate static void 2277d1a180b0Smaheshvs formatf(struct filenames *fn0, struct filenames *fnlast) 22787c478bd9Sstevel@tonic-gate { 2279d1a180b0Smaheshvs struct filenames *fn; 22807c478bd9Sstevel@tonic-gate int width = 0, w, nentry = fnlast - fn0 + 1; 22817c478bd9Sstevel@tonic-gate int i, j, columns, lines; 22827c478bd9Sstevel@tonic-gate char *cp; 22837c478bd9Sstevel@tonic-gate 22847c478bd9Sstevel@tonic-gate if (long_list) { 22857c478bd9Sstevel@tonic-gate columns = 1; 22867c478bd9Sstevel@tonic-gate } else { 22877c478bd9Sstevel@tonic-gate for (fn = fn0; fn <= fnlast; fn++) { 22887c478bd9Sstevel@tonic-gate int len = strlen(fn->fname[cmp_level]) + 2; 22897c478bd9Sstevel@tonic-gate 22907c478bd9Sstevel@tonic-gate if (len > width) 22917c478bd9Sstevel@tonic-gate width = len; 22927c478bd9Sstevel@tonic-gate } 22937c478bd9Sstevel@tonic-gate width = (width + 8) &~ 7; 22947c478bd9Sstevel@tonic-gate columns = 80 / width; 22957c478bd9Sstevel@tonic-gate if (columns == 0) 22967c478bd9Sstevel@tonic-gate columns = 1; 22977c478bd9Sstevel@tonic-gate } 22987c478bd9Sstevel@tonic-gate lines = (nentry + columns - 1) / columns; 22997c478bd9Sstevel@tonic-gate for (i = 0; i < lines; i++) { 23007c478bd9Sstevel@tonic-gate for (j = 0; j < columns; j++) { 23017c478bd9Sstevel@tonic-gate fn = fn0 + j * lines + i; 23027c478bd9Sstevel@tonic-gate if (long_list) { 23037c478bd9Sstevel@tonic-gate printf("i#: "); 23047c478bd9Sstevel@tonic-gate print(fn->ino, 12, -8, 0); 23057c478bd9Sstevel@tonic-gate } 23067c478bd9Sstevel@tonic-gate if ((cp = fmtentry(fn)) == NULL) { 23077c478bd9Sstevel@tonic-gate printf("cannot read inode %ld\n", fn->ino); 23087c478bd9Sstevel@tonic-gate return; 23097c478bd9Sstevel@tonic-gate } 23107c478bd9Sstevel@tonic-gate printf("%s", cp); 23117c478bd9Sstevel@tonic-gate if (fn + lines > fnlast) { 23127c478bd9Sstevel@tonic-gate printf("\n"); 23137c478bd9Sstevel@tonic-gate break; 23147c478bd9Sstevel@tonic-gate } 23157c478bd9Sstevel@tonic-gate w = strlen(cp); 23167c478bd9Sstevel@tonic-gate while (w < width) { 23177c478bd9Sstevel@tonic-gate w = (w + 8) &~ 7; 23187c478bd9Sstevel@tonic-gate (void) putchar('\t'); 23197c478bd9Sstevel@tonic-gate } 23207c478bd9Sstevel@tonic-gate } 23217c478bd9Sstevel@tonic-gate } 23227c478bd9Sstevel@tonic-gate } 23237c478bd9Sstevel@tonic-gate 23247c478bd9Sstevel@tonic-gate /* 23257c478bd9Sstevel@tonic-gate * fmtentry - code lifted from ls. 23267c478bd9Sstevel@tonic-gate */ 23277c478bd9Sstevel@tonic-gate static char * 2328d1a180b0Smaheshvs fmtentry(struct filenames *fn) 23297c478bd9Sstevel@tonic-gate { 23307c478bd9Sstevel@tonic-gate static char fmtres[BUFSIZ]; 2331d1a180b0Smaheshvs struct dinode *ip; 2332d1a180b0Smaheshvs char *cptr, *cp, *dp; 23337c478bd9Sstevel@tonic-gate 23347c478bd9Sstevel@tonic-gate dp = &fmtres[0]; 23357c478bd9Sstevel@tonic-gate for (cp = fn->fname[cmp_level]; *cp; cp++) { 23367c478bd9Sstevel@tonic-gate if (*cp < ' ' || *cp >= 0177) 23377c478bd9Sstevel@tonic-gate *dp++ = '?'; 23387c478bd9Sstevel@tonic-gate else 23397c478bd9Sstevel@tonic-gate *dp++ = *cp; 23407c478bd9Sstevel@tonic-gate } 23417c478bd9Sstevel@tonic-gate addr = itob(fn->ino); 23427c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 23437c478bd9Sstevel@tonic-gate return (NULL); 23447c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 23457c478bd9Sstevel@tonic-gate /*LINTED*/ 23467c478bd9Sstevel@tonic-gate ip = (struct dinode *)cptr; 23477c478bd9Sstevel@tonic-gate switch (ip->di_mode & IFMT) { 23487c478bd9Sstevel@tonic-gate case IFDIR: 23497c478bd9Sstevel@tonic-gate *dp++ = '/'; 23507c478bd9Sstevel@tonic-gate break; 23517c478bd9Sstevel@tonic-gate case IFLNK: 23527c478bd9Sstevel@tonic-gate *dp++ = '@'; 23537c478bd9Sstevel@tonic-gate break; 23547c478bd9Sstevel@tonic-gate case IFSOCK: 23557c478bd9Sstevel@tonic-gate *dp++ = '='; 23567c478bd9Sstevel@tonic-gate break; 23577c478bd9Sstevel@tonic-gate #ifdef IFIFO 23587c478bd9Sstevel@tonic-gate case IFIFO: 23597c478bd9Sstevel@tonic-gate *dp++ = 'p'; 23607c478bd9Sstevel@tonic-gate break; 23617c478bd9Sstevel@tonic-gate #endif 23627c478bd9Sstevel@tonic-gate case IFCHR: 23637c478bd9Sstevel@tonic-gate case IFBLK: 23647c478bd9Sstevel@tonic-gate case IFREG: 23657c478bd9Sstevel@tonic-gate if (ip->di_mode & 0111) 23667c478bd9Sstevel@tonic-gate *dp++ = '*'; 23677c478bd9Sstevel@tonic-gate else 23687c478bd9Sstevel@tonic-gate *dp++ = ' '; 23697c478bd9Sstevel@tonic-gate break; 23707c478bd9Sstevel@tonic-gate default: 23717c478bd9Sstevel@tonic-gate *dp++ = '?'; 23727c478bd9Sstevel@tonic-gate 23737c478bd9Sstevel@tonic-gate } 23747c478bd9Sstevel@tonic-gate *dp++ = 0; 23757c478bd9Sstevel@tonic-gate return (fmtres); 23767c478bd9Sstevel@tonic-gate } 23777c478bd9Sstevel@tonic-gate 23787c478bd9Sstevel@tonic-gate /* 23797c478bd9Sstevel@tonic-gate * fcmp - routine used by qsort. Will sort first by name, then 23807c478bd9Sstevel@tonic-gate * then by pathname length if names are equal. Uses global 23817c478bd9Sstevel@tonic-gate * cmp_level to tell what component of the path name we are comparing. 23827c478bd9Sstevel@tonic-gate */ 23837c478bd9Sstevel@tonic-gate static int 2384d1a180b0Smaheshvs fcmp(struct filenames *f1, struct filenames *f2) 23857c478bd9Sstevel@tonic-gate { 23867c478bd9Sstevel@tonic-gate int value; 23877c478bd9Sstevel@tonic-gate 23887c478bd9Sstevel@tonic-gate if ((value = strcmp(f1->fname[cmp_level], f2->fname[cmp_level]))) 23897c478bd9Sstevel@tonic-gate return (value); 23907c478bd9Sstevel@tonic-gate return (f1->len - f2->len); 23917c478bd9Sstevel@tonic-gate } 23927c478bd9Sstevel@tonic-gate 23937c478bd9Sstevel@tonic-gate /* 23947c478bd9Sstevel@tonic-gate * ffcmp - routine used by qsort. Sort only by pathname length. 23957c478bd9Sstevel@tonic-gate */ 23967c478bd9Sstevel@tonic-gate static int 2397d1a180b0Smaheshvs ffcmp(struct filenames *f1, struct filenames *f2) 23987c478bd9Sstevel@tonic-gate { 23997c478bd9Sstevel@tonic-gate return (f1->len - f2->len); 24007c478bd9Sstevel@tonic-gate } 24017c478bd9Sstevel@tonic-gate 24027c478bd9Sstevel@tonic-gate /* 24037c478bd9Sstevel@tonic-gate * parse - set up the call to follow_path. 24047c478bd9Sstevel@tonic-gate */ 24057c478bd9Sstevel@tonic-gate static void 24067c478bd9Sstevel@tonic-gate parse() 24077c478bd9Sstevel@tonic-gate { 2408d1a180b0Smaheshvs int i; 24097c478bd9Sstevel@tonic-gate char c; 24107c478bd9Sstevel@tonic-gate 24117c478bd9Sstevel@tonic-gate stack_pathp = input_pathp = -1; 24127c478bd9Sstevel@tonic-gate if ((c = getachar()) == '/') { 24137c478bd9Sstevel@tonic-gate while ((c = getachar()) == '/') 24147c478bd9Sstevel@tonic-gate ; 24157c478bd9Sstevel@tonic-gate ungetachar(c); 24167c478bd9Sstevel@tonic-gate cur_inum = 2; 24177c478bd9Sstevel@tonic-gate c = getachar(); 24187c478bd9Sstevel@tonic-gate if ((c == '\n') || ((doing_cd) && (c == ' '))) { 24197c478bd9Sstevel@tonic-gate ungetachar(c); 24207c478bd9Sstevel@tonic-gate if (doing_cd) { 24217c478bd9Sstevel@tonic-gate top++; 24227c478bd9Sstevel@tonic-gate top->ino = 2; 24237c478bd9Sstevel@tonic-gate top->len = -1; 24247c478bd9Sstevel@tonic-gate nfiles = 1; 24257c478bd9Sstevel@tonic-gate return; 24267c478bd9Sstevel@tonic-gate } 24277c478bd9Sstevel@tonic-gate } else 24287c478bd9Sstevel@tonic-gate ungetachar(c); 24297c478bd9Sstevel@tonic-gate } else { 24307c478bd9Sstevel@tonic-gate ungetachar(c); 24317c478bd9Sstevel@tonic-gate stack_pathp = current_pathp; 24327c478bd9Sstevel@tonic-gate if (!doing_find) 24337c478bd9Sstevel@tonic-gate input_pathp = current_pathp; 24347c478bd9Sstevel@tonic-gate for (i = 0; i <= current_pathp; i++) { 24357c478bd9Sstevel@tonic-gate if (!doing_find) 24367c478bd9Sstevel@tonic-gate (void) strcpy(input_path[i], current_path[i]); 24377c478bd9Sstevel@tonic-gate (void) strcpy(stack_path[i], current_path[i]); 24387c478bd9Sstevel@tonic-gate } 24397c478bd9Sstevel@tonic-gate } 24407c478bd9Sstevel@tonic-gate getname(); 24417c478bd9Sstevel@tonic-gate follow_path((long)(stack_pathp + 1), cur_inum); 24427c478bd9Sstevel@tonic-gate } 24437c478bd9Sstevel@tonic-gate 24447c478bd9Sstevel@tonic-gate /* 24457c478bd9Sstevel@tonic-gate * follow_path - called by cd, find, and ls. 24467c478bd9Sstevel@tonic-gate * input_path holds the name typed by the user. 24477c478bd9Sstevel@tonic-gate * stack_path holds the name at the current depth. 24487c478bd9Sstevel@tonic-gate */ 24497c478bd9Sstevel@tonic-gate static void 2450d1a180b0Smaheshvs follow_path(long level, long inum) 24517c478bd9Sstevel@tonic-gate { 2452d1a180b0Smaheshvs struct direct *dirp; 2453d1a180b0Smaheshvs char **ccptr, *cptr; 2454d1a180b0Smaheshvs int i; 24557c478bd9Sstevel@tonic-gate struct filenames *tos, *bos, *fn, *fnn, *fnnn; 24567c478bd9Sstevel@tonic-gate long block; 24577c478bd9Sstevel@tonic-gate short mode; 24587c478bd9Sstevel@tonic-gate 24597c478bd9Sstevel@tonic-gate tos = top + 1; 24607c478bd9Sstevel@tonic-gate restore_inode((ino_t)inum); 24617c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 24627c478bd9Sstevel@tonic-gate return; 24637c478bd9Sstevel@tonic-gate if ((mode & IFMT) != IFDIR) 24647c478bd9Sstevel@tonic-gate return; 24657c478bd9Sstevel@tonic-gate block = cur_bytes = 0; 24667c478bd9Sstevel@tonic-gate while (cur_bytes < filesize) { 24677c478bd9Sstevel@tonic-gate if (block == 0 || bcomp(addr)) { 24687c478bd9Sstevel@tonic-gate error = 0; 24697c478bd9Sstevel@tonic-gate if ((addr = ((u_offset_t)bmap(block++) << 24707c478bd9Sstevel@tonic-gate (u_offset_t)FRGSHIFT)) == 0) 24717c478bd9Sstevel@tonic-gate break; 24727c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 24737c478bd9Sstevel@tonic-gate break; 24747c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 24757c478bd9Sstevel@tonic-gate } 24767c478bd9Sstevel@tonic-gate /*LINTED*/ 24777c478bd9Sstevel@tonic-gate dirp = (struct direct *)cptr; 24787c478bd9Sstevel@tonic-gate if (dirp->d_ino) { 24797c478bd9Sstevel@tonic-gate if (level > input_pathp || doing_find || 24807c478bd9Sstevel@tonic-gate compare(input_path[level], &dirp->d_name[0], 1)) { 24817c478bd9Sstevel@tonic-gate if ((doing_find) && 24827c478bd9Sstevel@tonic-gate ((strcmp(dirp->d_name, ".") == 0 || 24837c478bd9Sstevel@tonic-gate strcmp(dirp->d_name, "..") == 0))) 24847c478bd9Sstevel@tonic-gate goto duplicate; 24857c478bd9Sstevel@tonic-gate if (++top - filenames >= maxfiles) { 24867c478bd9Sstevel@tonic-gate printf("too many files\n"); 24877c478bd9Sstevel@tonic-gate error++; 24887c478bd9Sstevel@tonic-gate return; 24897c478bd9Sstevel@tonic-gate } 24907c478bd9Sstevel@tonic-gate top->fname = (char **)calloc(FIRST_DEPTH, sizeof (char **)); 24917c478bd9Sstevel@tonic-gate top->flag = 0; 24927c478bd9Sstevel@tonic-gate if (top->fname == 0) { 24937c478bd9Sstevel@tonic-gate printf("out of memory\n"); 24947c478bd9Sstevel@tonic-gate error++; 24957c478bd9Sstevel@tonic-gate return; 24967c478bd9Sstevel@tonic-gate } 24977c478bd9Sstevel@tonic-gate nfiles++; 24987c478bd9Sstevel@tonic-gate top->ino = dirp->d_ino; 24997c478bd9Sstevel@tonic-gate top->len = stack_pathp; 25007c478bd9Sstevel@tonic-gate top->find = 0; 25017c478bd9Sstevel@tonic-gate if (doing_find) { 25027c478bd9Sstevel@tonic-gate if (find_by_name) { 25037c478bd9Sstevel@tonic-gate if (compare(input_path[0], &dirp->d_name[0], 1)) 25047c478bd9Sstevel@tonic-gate top->find = 1; 25057c478bd9Sstevel@tonic-gate } else if (find_by_inode) 25067c478bd9Sstevel@tonic-gate if (find_ino == dirp->d_ino) 25077c478bd9Sstevel@tonic-gate top->find = 1; 25087c478bd9Sstevel@tonic-gate } 25097c478bd9Sstevel@tonic-gate if (top->len + 1 >= FIRST_DEPTH && top->flag == 0) { 25107c478bd9Sstevel@tonic-gate ccptr = (char **)calloc(SECOND_DEPTH, sizeof (char **)); 25117c478bd9Sstevel@tonic-gate if (ccptr == 0) { 25127c478bd9Sstevel@tonic-gate printf("out of memory\n"); 25137c478bd9Sstevel@tonic-gate error++; 25147c478bd9Sstevel@tonic-gate return; 25157c478bd9Sstevel@tonic-gate } 25167c478bd9Sstevel@tonic-gate for (i = 0; i < FIRST_DEPTH; i++) 25177c478bd9Sstevel@tonic-gate ccptr[i] = top->fname[i]; 25187c478bd9Sstevel@tonic-gate free((char *)top->fname); 25197c478bd9Sstevel@tonic-gate top->fname = ccptr; 25207c478bd9Sstevel@tonic-gate top->flag = 1; 25217c478bd9Sstevel@tonic-gate } 25227c478bd9Sstevel@tonic-gate if (top->len >= SECOND_DEPTH) { 25237c478bd9Sstevel@tonic-gate printf("maximum depth exceeded, try to cd lower\n"); 25247c478bd9Sstevel@tonic-gate error++; 25257c478bd9Sstevel@tonic-gate return; 25267c478bd9Sstevel@tonic-gate } 25277c478bd9Sstevel@tonic-gate /* 25287c478bd9Sstevel@tonic-gate * Copy current depth. 25297c478bd9Sstevel@tonic-gate */ 25307c478bd9Sstevel@tonic-gate for (i = 0; i <= stack_pathp; i++) { 25317c478bd9Sstevel@tonic-gate top->fname[i] = calloc(1, strlen(stack_path[i])+1); 25327c478bd9Sstevel@tonic-gate if (top->fname[i] == 0) { 25337c478bd9Sstevel@tonic-gate printf("out of memory\n"); 25347c478bd9Sstevel@tonic-gate error++; 25357c478bd9Sstevel@tonic-gate return; 25367c478bd9Sstevel@tonic-gate } 25377c478bd9Sstevel@tonic-gate (void) strcpy(top->fname[i], stack_path[i]); 25387c478bd9Sstevel@tonic-gate } 25397c478bd9Sstevel@tonic-gate /* 25407c478bd9Sstevel@tonic-gate * Check for '.' or '..' typed. 25417c478bd9Sstevel@tonic-gate */ 25427c478bd9Sstevel@tonic-gate if ((level <= input_pathp) && 25437c478bd9Sstevel@tonic-gate (strcmp(input_path[level], ".") == 0 || 25447c478bd9Sstevel@tonic-gate strcmp(input_path[level], "..") == 0)) { 25457c478bd9Sstevel@tonic-gate if (strcmp(input_path[level], "..") == 0 && 25467c478bd9Sstevel@tonic-gate top->len >= 0) { 25477c478bd9Sstevel@tonic-gate free(top->fname[top->len]); 25487c478bd9Sstevel@tonic-gate top->len -= 1; 25497c478bd9Sstevel@tonic-gate } 25507c478bd9Sstevel@tonic-gate } else { 25517c478bd9Sstevel@tonic-gate /* 25527c478bd9Sstevel@tonic-gate * Check for duplicates. 25537c478bd9Sstevel@tonic-gate */ 25547c478bd9Sstevel@tonic-gate if (!doing_cd && !doing_find) { 25557c478bd9Sstevel@tonic-gate for (fn = filenames; fn < top; fn++) { 25567c478bd9Sstevel@tonic-gate if (fn->ino == dirp->d_ino && 25577c478bd9Sstevel@tonic-gate fn->len == stack_pathp + 1) { 25587c478bd9Sstevel@tonic-gate for (i = 0; i < fn->len; i++) 25597c478bd9Sstevel@tonic-gate if (strcmp(fn->fname[i], stack_path[i])) 25607c478bd9Sstevel@tonic-gate break; 25617c478bd9Sstevel@tonic-gate if (i != fn->len || 25627c478bd9Sstevel@tonic-gate strcmp(fn->fname[i], dirp->d_name)) 25637c478bd9Sstevel@tonic-gate continue; 25647c478bd9Sstevel@tonic-gate freemem(top, 1); 25657c478bd9Sstevel@tonic-gate if (top == filenames) 25667c478bd9Sstevel@tonic-gate top = NULL; 25677c478bd9Sstevel@tonic-gate else 25687c478bd9Sstevel@tonic-gate top--; 25697c478bd9Sstevel@tonic-gate nfiles--; 25707c478bd9Sstevel@tonic-gate goto duplicate; 25717c478bd9Sstevel@tonic-gate } 25727c478bd9Sstevel@tonic-gate } 25737c478bd9Sstevel@tonic-gate } 25747c478bd9Sstevel@tonic-gate top->len += 1; 25757c478bd9Sstevel@tonic-gate top->fname[top->len] = calloc(1, 25767c478bd9Sstevel@tonic-gate strlen(&dirp->d_name[0])+1); 25777c478bd9Sstevel@tonic-gate if (top->fname[top->len] == 0) { 25787c478bd9Sstevel@tonic-gate printf("out of memory\n"); 25797c478bd9Sstevel@tonic-gate error++; 25807c478bd9Sstevel@tonic-gate return; 25817c478bd9Sstevel@tonic-gate } 25827c478bd9Sstevel@tonic-gate (void) strcpy(top->fname[top->len], &dirp->d_name[0]); 25837c478bd9Sstevel@tonic-gate } 25847c478bd9Sstevel@tonic-gate } 25857c478bd9Sstevel@tonic-gate } 25867c478bd9Sstevel@tonic-gate duplicate: 25877c478bd9Sstevel@tonic-gate addr += dirp->d_reclen; 25887c478bd9Sstevel@tonic-gate cptr += dirp->d_reclen; 25897c478bd9Sstevel@tonic-gate cur_bytes += dirp->d_reclen; 25907c478bd9Sstevel@tonic-gate } 25917c478bd9Sstevel@tonic-gate if (top < filenames) 25927c478bd9Sstevel@tonic-gate return; 25937c478bd9Sstevel@tonic-gate if ((doing_cd && level == input_pathp) || 25947c478bd9Sstevel@tonic-gate (!recursive && !doing_find && level > input_pathp)) 25957c478bd9Sstevel@tonic-gate return; 25967c478bd9Sstevel@tonic-gate bos = top; 25977c478bd9Sstevel@tonic-gate /* 25987c478bd9Sstevel@tonic-gate * Check newly added entries to determine if further expansion 25997c478bd9Sstevel@tonic-gate * is required. 26007c478bd9Sstevel@tonic-gate */ 26017c478bd9Sstevel@tonic-gate for (fn = tos; fn <= bos; fn++) { 26027c478bd9Sstevel@tonic-gate /* 26037c478bd9Sstevel@tonic-gate * Avoid '.' and '..' if beyond input. 26047c478bd9Sstevel@tonic-gate */ 26057c478bd9Sstevel@tonic-gate if ((recursive || doing_find) && (level > input_pathp) && 26067c478bd9Sstevel@tonic-gate (strcmp(fn->fname[fn->len], ".") == 0 || 26077c478bd9Sstevel@tonic-gate strcmp(fn->fname[fn->len], "..") == 0)) 26087c478bd9Sstevel@tonic-gate continue; 26097c478bd9Sstevel@tonic-gate restore_inode(fn->ino); 26107c478bd9Sstevel@tonic-gate if ((mode = icheck(cur_ino)) == 0) 26117c478bd9Sstevel@tonic-gate return; 26127c478bd9Sstevel@tonic-gate if ((mode & IFMT) == IFDIR || level < input_pathp) { 26137c478bd9Sstevel@tonic-gate /* 26147c478bd9Sstevel@tonic-gate * Set up current depth, remove current entry and 26157c478bd9Sstevel@tonic-gate * continue recursion. 26167c478bd9Sstevel@tonic-gate */ 26177c478bd9Sstevel@tonic-gate for (i = 0; i <= fn->len; i++) 26187c478bd9Sstevel@tonic-gate (void) strcpy(stack_path[i], fn->fname[i]); 26197c478bd9Sstevel@tonic-gate stack_pathp = fn->len; 26207c478bd9Sstevel@tonic-gate if (!doing_find && 26217c478bd9Sstevel@tonic-gate (!recursive || (recursive && level <= input_pathp))) { 26227c478bd9Sstevel@tonic-gate /* 26237c478bd9Sstevel@tonic-gate * Remove current entry by moving others up. 26247c478bd9Sstevel@tonic-gate */ 26257c478bd9Sstevel@tonic-gate freemem(fn, 1); 26267c478bd9Sstevel@tonic-gate fnn = fn; 26277c478bd9Sstevel@tonic-gate for (fnnn = fnn, fnn++; fnn <= top; fnnn = fnn, fnn++) { 26287c478bd9Sstevel@tonic-gate fnnn->ino = fnn->ino; 26297c478bd9Sstevel@tonic-gate fnnn->len = fnn->len; 26307c478bd9Sstevel@tonic-gate if (fnnn->len + 1 < FIRST_DEPTH) { 26317c478bd9Sstevel@tonic-gate fnnn->fname = (char **)calloc(FIRST_DEPTH, 26327c478bd9Sstevel@tonic-gate sizeof (char **)); 26337c478bd9Sstevel@tonic-gate fnnn->flag = 0; 26347c478bd9Sstevel@tonic-gate } else if (fnnn->len < SECOND_DEPTH) { 26357c478bd9Sstevel@tonic-gate fnnn->fname = (char **)calloc(SECOND_DEPTH, 26367c478bd9Sstevel@tonic-gate sizeof (char **)); 26377c478bd9Sstevel@tonic-gate fnnn->flag = 1; 26387c478bd9Sstevel@tonic-gate } else { 26397c478bd9Sstevel@tonic-gate printf("maximum depth exceeded, "); 26407c478bd9Sstevel@tonic-gate printf("try to cd lower\n"); 26417c478bd9Sstevel@tonic-gate error++; 26427c478bd9Sstevel@tonic-gate return; 26437c478bd9Sstevel@tonic-gate } 26447c478bd9Sstevel@tonic-gate for (i = 0; i <= fnn->len; i++) 26457c478bd9Sstevel@tonic-gate fnnn->fname[i] = fnn->fname[i]; 26467c478bd9Sstevel@tonic-gate } 26477c478bd9Sstevel@tonic-gate if (fn == tos) 26487c478bd9Sstevel@tonic-gate fn--; 26497c478bd9Sstevel@tonic-gate top--; 26507c478bd9Sstevel@tonic-gate bos--; 26517c478bd9Sstevel@tonic-gate nfiles--; 26527c478bd9Sstevel@tonic-gate } 26537c478bd9Sstevel@tonic-gate follow_path(level + 1, cur_inum); 26547c478bd9Sstevel@tonic-gate if (error) 26557c478bd9Sstevel@tonic-gate return; 26567c478bd9Sstevel@tonic-gate } 26577c478bd9Sstevel@tonic-gate } 26587c478bd9Sstevel@tonic-gate } 26597c478bd9Sstevel@tonic-gate 26607c478bd9Sstevel@tonic-gate /* 26617c478bd9Sstevel@tonic-gate * getname - break up the pathname entered by the user into components. 26627c478bd9Sstevel@tonic-gate */ 26637c478bd9Sstevel@tonic-gate static void 26647c478bd9Sstevel@tonic-gate getname() 26657c478bd9Sstevel@tonic-gate { 2666d1a180b0Smaheshvs int i; 26677c478bd9Sstevel@tonic-gate char c; 26687c478bd9Sstevel@tonic-gate 26697c478bd9Sstevel@tonic-gate if ((c = getachar()) == '\n') { 26707c478bd9Sstevel@tonic-gate ungetachar(c); 26717c478bd9Sstevel@tonic-gate return; 26727c478bd9Sstevel@tonic-gate } 26737c478bd9Sstevel@tonic-gate ungetachar(c); 26747c478bd9Sstevel@tonic-gate input_pathp++; 26757c478bd9Sstevel@tonic-gate clear: 26767c478bd9Sstevel@tonic-gate for (i = 0; i < MAXNAMLEN; i++) 26777c478bd9Sstevel@tonic-gate input_path[input_pathp][i] = '\0'; 26787c478bd9Sstevel@tonic-gate for (;;) { 26797c478bd9Sstevel@tonic-gate c = getachar(); 26807c478bd9Sstevel@tonic-gate if (c == '\\') { 26817c478bd9Sstevel@tonic-gate if ((int)strlen(input_path[input_pathp]) + 1 >= MAXNAMLEN) { 26827c478bd9Sstevel@tonic-gate printf("maximum name length exceeded, "); 26837c478bd9Sstevel@tonic-gate printf("truncating\n"); 26847c478bd9Sstevel@tonic-gate return; 26857c478bd9Sstevel@tonic-gate } 26867c478bd9Sstevel@tonic-gate input_path[input_pathp][strlen(input_path[input_pathp])] = c; 26877c478bd9Sstevel@tonic-gate input_path[input_pathp][strlen(input_path[input_pathp])] = 26887c478bd9Sstevel@tonic-gate getachar(); 26897c478bd9Sstevel@tonic-gate continue; 26907c478bd9Sstevel@tonic-gate } 26917c478bd9Sstevel@tonic-gate if (c == ' ' || c == '\n') { 26927c478bd9Sstevel@tonic-gate ungetachar(c); 26937c478bd9Sstevel@tonic-gate return; 26947c478bd9Sstevel@tonic-gate } 26957c478bd9Sstevel@tonic-gate if (!doing_find && c == '/') { 26967c478bd9Sstevel@tonic-gate if (++input_pathp >= MAXPATHLEN) { 26977c478bd9Sstevel@tonic-gate printf("maximum path length exceeded, "); 26987c478bd9Sstevel@tonic-gate printf("truncating\n"); 26997c478bd9Sstevel@tonic-gate input_pathp--; 27007c478bd9Sstevel@tonic-gate return; 27017c478bd9Sstevel@tonic-gate } 27027c478bd9Sstevel@tonic-gate goto clear; 27037c478bd9Sstevel@tonic-gate } 27047c478bd9Sstevel@tonic-gate if ((int)strlen(input_path[input_pathp]) >= MAXNAMLEN) { 27057c478bd9Sstevel@tonic-gate printf("maximum name length exceeded, truncating\n"); 27067c478bd9Sstevel@tonic-gate return; 27077c478bd9Sstevel@tonic-gate } 27087c478bd9Sstevel@tonic-gate input_path[input_pathp][strlen(input_path[input_pathp])] = c; 27097c478bd9Sstevel@tonic-gate } 27107c478bd9Sstevel@tonic-gate } 27117c478bd9Sstevel@tonic-gate 27127c478bd9Sstevel@tonic-gate /* 27137c478bd9Sstevel@tonic-gate * compare - check if a filename matches the pattern entered by the user. 27147c478bd9Sstevel@tonic-gate * Handles '*', '?', and '[]'. 27157c478bd9Sstevel@tonic-gate */ 27167c478bd9Sstevel@tonic-gate static int 2717d1a180b0Smaheshvs compare(char *s1, char *s2, short at_start) 27187c478bd9Sstevel@tonic-gate { 2719d1a180b0Smaheshvs char c, *s; 27207c478bd9Sstevel@tonic-gate 27217c478bd9Sstevel@tonic-gate s = s2; 27227c478bd9Sstevel@tonic-gate while ((c = *s1) != NULL) { 27237c478bd9Sstevel@tonic-gate if (c == '*') { 27247c478bd9Sstevel@tonic-gate if (at_start && s == s2 && !letter(*s2) && !digit(*s2)) 27257c478bd9Sstevel@tonic-gate return (0); 27267c478bd9Sstevel@tonic-gate if (*++s1 == 0) 27277c478bd9Sstevel@tonic-gate return (1); 27287c478bd9Sstevel@tonic-gate while (*s2) { 27297c478bd9Sstevel@tonic-gate if (compare(s1, s2, 0)) 27307c478bd9Sstevel@tonic-gate return (1); 27317c478bd9Sstevel@tonic-gate if (error) 27327c478bd9Sstevel@tonic-gate return (0); 27337c478bd9Sstevel@tonic-gate s2++; 27347c478bd9Sstevel@tonic-gate } 27357c478bd9Sstevel@tonic-gate } 27367c478bd9Sstevel@tonic-gate if (*s2 == 0) 27377c478bd9Sstevel@tonic-gate return (0); 27387c478bd9Sstevel@tonic-gate if (c == '\\') { 27397c478bd9Sstevel@tonic-gate s1++; 27407c478bd9Sstevel@tonic-gate goto compare_chars; 27417c478bd9Sstevel@tonic-gate } 27427c478bd9Sstevel@tonic-gate if (c == '?') { 27437c478bd9Sstevel@tonic-gate if (at_start && s == s2 && !letter(*s2) && !digit(*s2)) 27447c478bd9Sstevel@tonic-gate return (0); 27457c478bd9Sstevel@tonic-gate s1++; 27467c478bd9Sstevel@tonic-gate s2++; 27477c478bd9Sstevel@tonic-gate continue; 27487c478bd9Sstevel@tonic-gate } 27497c478bd9Sstevel@tonic-gate if (c == '[') { 27507c478bd9Sstevel@tonic-gate s1++; 27517c478bd9Sstevel@tonic-gate if (*s2 >= *s1++) { 27527c478bd9Sstevel@tonic-gate if (*s1++ != '-') { 27537c478bd9Sstevel@tonic-gate printf("missing '-'\n"); 27547c478bd9Sstevel@tonic-gate error++; 27557c478bd9Sstevel@tonic-gate return (0); 27567c478bd9Sstevel@tonic-gate } 27577c478bd9Sstevel@tonic-gate if (*s2 <= *s1++) { 27587c478bd9Sstevel@tonic-gate if (*s1++ != ']') { 27597c478bd9Sstevel@tonic-gate printf("missing ']'"); 27607c478bd9Sstevel@tonic-gate error++; 27617c478bd9Sstevel@tonic-gate return (0); 27627c478bd9Sstevel@tonic-gate } 27637c478bd9Sstevel@tonic-gate s2++; 27647c478bd9Sstevel@tonic-gate continue; 27657c478bd9Sstevel@tonic-gate } 27667c478bd9Sstevel@tonic-gate } 27677c478bd9Sstevel@tonic-gate } 27687c478bd9Sstevel@tonic-gate compare_chars: 27697c478bd9Sstevel@tonic-gate if (*s1++ == *s2++) 27707c478bd9Sstevel@tonic-gate continue; 27717c478bd9Sstevel@tonic-gate else 27727c478bd9Sstevel@tonic-gate return (0); 27737c478bd9Sstevel@tonic-gate } 27747c478bd9Sstevel@tonic-gate if (*s1 == *s2) 27757c478bd9Sstevel@tonic-gate return (1); 27767c478bd9Sstevel@tonic-gate return (0); 27777c478bd9Sstevel@tonic-gate } 27787c478bd9Sstevel@tonic-gate 27797c478bd9Sstevel@tonic-gate /* 27807c478bd9Sstevel@tonic-gate * freemem - free the memory allocated to the filenames structure. 27817c478bd9Sstevel@tonic-gate */ 27827c478bd9Sstevel@tonic-gate static void 2783d1a180b0Smaheshvs freemem(struct filenames *p, int numb) 27847c478bd9Sstevel@tonic-gate { 2785d1a180b0Smaheshvs int i, j; 27867c478bd9Sstevel@tonic-gate 27877c478bd9Sstevel@tonic-gate if (numb == 0) 27887c478bd9Sstevel@tonic-gate return; 27897c478bd9Sstevel@tonic-gate for (i = 0; i < numb; i++, p++) { 27907c478bd9Sstevel@tonic-gate for (j = 0; j <= p->len; j++) 27917c478bd9Sstevel@tonic-gate free(p->fname[j]); 27927c478bd9Sstevel@tonic-gate free((char *)p->fname); 27937c478bd9Sstevel@tonic-gate } 27947c478bd9Sstevel@tonic-gate } 27957c478bd9Sstevel@tonic-gate 27967c478bd9Sstevel@tonic-gate /* 27977c478bd9Sstevel@tonic-gate * print_path - print the pathname held in p. 27987c478bd9Sstevel@tonic-gate */ 27997c478bd9Sstevel@tonic-gate static void 2800d1a180b0Smaheshvs print_path(char *p[], int pntr) 28017c478bd9Sstevel@tonic-gate { 2802d1a180b0Smaheshvs int i; 28037c478bd9Sstevel@tonic-gate 28047c478bd9Sstevel@tonic-gate printf("/"); 28057c478bd9Sstevel@tonic-gate if (pntr >= 0) { 28067c478bd9Sstevel@tonic-gate for (i = 0; i < pntr; i++) 28077c478bd9Sstevel@tonic-gate printf("%s/", p[i]); 28087c478bd9Sstevel@tonic-gate printf("%s", p[pntr]); 28097c478bd9Sstevel@tonic-gate } 28107c478bd9Sstevel@tonic-gate } 28117c478bd9Sstevel@tonic-gate 28127c478bd9Sstevel@tonic-gate /* 28137c478bd9Sstevel@tonic-gate * fill - fill a section with a value or string. 28147c478bd9Sstevel@tonic-gate * addr,count:fill=[value, "string"]. 28157c478bd9Sstevel@tonic-gate */ 28167c478bd9Sstevel@tonic-gate static void 28177c478bd9Sstevel@tonic-gate fill() 28187c478bd9Sstevel@tonic-gate { 2819d1a180b0Smaheshvs char *cptr; 2820d1a180b0Smaheshvs int i; 28217c478bd9Sstevel@tonic-gate short eof_flag, end = 0, eof = 0; 28227c478bd9Sstevel@tonic-gate long temp, tcount; 28237c478bd9Sstevel@tonic-gate u_offset_t taddr; 28247c478bd9Sstevel@tonic-gate 28257c478bd9Sstevel@tonic-gate if (wrtflag == O_RDONLY) { 28267c478bd9Sstevel@tonic-gate printf("not opened for write '-w'\n"); 28277c478bd9Sstevel@tonic-gate error++; 28287c478bd9Sstevel@tonic-gate return; 28297c478bd9Sstevel@tonic-gate } 28307c478bd9Sstevel@tonic-gate temp = expr(); 28317c478bd9Sstevel@tonic-gate if (error) 28327c478bd9Sstevel@tonic-gate return; 28337c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 28347c478bd9Sstevel@tonic-gate return; 28357c478bd9Sstevel@tonic-gate if (type == NUMB) 28367c478bd9Sstevel@tonic-gate eof_flag = 0; 28377c478bd9Sstevel@tonic-gate else 28387c478bd9Sstevel@tonic-gate eof_flag = 1; 28397c478bd9Sstevel@tonic-gate taddr = addr; 28407c478bd9Sstevel@tonic-gate switch (objsz) { 28417c478bd9Sstevel@tonic-gate case LONG: 28427c478bd9Sstevel@tonic-gate addr &= ~(LONG - 1); 28437c478bd9Sstevel@tonic-gate break; 28447c478bd9Sstevel@tonic-gate case SHORT: 28457c478bd9Sstevel@tonic-gate addr &= ~(SHORT - 1); 28467c478bd9Sstevel@tonic-gate temp &= 0177777L; 28477c478bd9Sstevel@tonic-gate break; 28487c478bd9Sstevel@tonic-gate case CHAR: 28497c478bd9Sstevel@tonic-gate temp &= 0377; 28507c478bd9Sstevel@tonic-gate } 28517c478bd9Sstevel@tonic-gate cur_bytes -= taddr - addr; 28527c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 28537c478bd9Sstevel@tonic-gate tcount = check_addr(eof_flag, &end, &eof, 0); 28547c478bd9Sstevel@tonic-gate for (i = 0; i < tcount; i++) { 28557c478bd9Sstevel@tonic-gate switch (objsz) { 28567c478bd9Sstevel@tonic-gate case LONG: 28577c478bd9Sstevel@tonic-gate /*LINTED*/ 28587c478bd9Sstevel@tonic-gate *(long *)cptr = temp; 28597c478bd9Sstevel@tonic-gate break; 28607c478bd9Sstevel@tonic-gate case SHORT: 28617c478bd9Sstevel@tonic-gate /*LINTED*/ 28627c478bd9Sstevel@tonic-gate *(short *)cptr = temp; 28637c478bd9Sstevel@tonic-gate break; 28647c478bd9Sstevel@tonic-gate case CHAR: 28657c478bd9Sstevel@tonic-gate *cptr = temp; 28667c478bd9Sstevel@tonic-gate } 28677c478bd9Sstevel@tonic-gate cptr += objsz; 28687c478bd9Sstevel@tonic-gate } 28697c478bd9Sstevel@tonic-gate addr += (tcount - 1) * objsz; 28707c478bd9Sstevel@tonic-gate cur_bytes += (tcount - 1) * objsz; 28717c478bd9Sstevel@tonic-gate put((u_offset_t)temp, objsz); 28727c478bd9Sstevel@tonic-gate if (eof) { 28737c478bd9Sstevel@tonic-gate printf("end of file\n"); 28747c478bd9Sstevel@tonic-gate error++; 28757c478bd9Sstevel@tonic-gate } else if (end) { 28767c478bd9Sstevel@tonic-gate printf("end of block\n"); 28777c478bd9Sstevel@tonic-gate error++; 28787c478bd9Sstevel@tonic-gate } 28797c478bd9Sstevel@tonic-gate } 28807c478bd9Sstevel@tonic-gate 28817c478bd9Sstevel@tonic-gate /* 28827c478bd9Sstevel@tonic-gate * get - read a byte, short or long from the file system. 28837c478bd9Sstevel@tonic-gate * The entire block containing the desired item is read 28847c478bd9Sstevel@tonic-gate * and the appropriate data is extracted and returned. 28857c478bd9Sstevel@tonic-gate */ 28867c478bd9Sstevel@tonic-gate static offset_t 2887d1a180b0Smaheshvs get(short lngth) 28887c478bd9Sstevel@tonic-gate { 28897c478bd9Sstevel@tonic-gate 2890d1a180b0Smaheshvs char *bptr; 28917c478bd9Sstevel@tonic-gate u_offset_t temp = addr; 28927c478bd9Sstevel@tonic-gate 28937c478bd9Sstevel@tonic-gate objsz = lngth; 28947c478bd9Sstevel@tonic-gate if (objsz == INODE || objsz == SHORT) 28957c478bd9Sstevel@tonic-gate temp &= ~(SHORT - 1); 28967c478bd9Sstevel@tonic-gate else if (objsz == DIRECTORY || objsz == LONG || objsz == SHADOW_DATA) 28977c478bd9Sstevel@tonic-gate temp &= ~(LONG - 1); 28987c478bd9Sstevel@tonic-gate if ((bptr = getblk(temp)) == 0) 28997c478bd9Sstevel@tonic-gate return (-1); 29007c478bd9Sstevel@tonic-gate bptr += blkoff(fs, temp); 29017c478bd9Sstevel@tonic-gate switch (objsz) { 29027c478bd9Sstevel@tonic-gate case CHAR: 29037c478bd9Sstevel@tonic-gate return ((offset_t)*bptr); 29047c478bd9Sstevel@tonic-gate case SHORT: 29057c478bd9Sstevel@tonic-gate case INODE: 29067c478bd9Sstevel@tonic-gate /*LINTED*/ 29077c478bd9Sstevel@tonic-gate return ((offset_t)(*(short *)bptr)); 29087c478bd9Sstevel@tonic-gate case LONG: 29097c478bd9Sstevel@tonic-gate case DIRECTORY: 29107c478bd9Sstevel@tonic-gate case SHADOW_DATA: 29117c478bd9Sstevel@tonic-gate /*LINTED*/ 29127c478bd9Sstevel@tonic-gate return ((offset_t)(*(long *)bptr)); 29137c478bd9Sstevel@tonic-gate case U_OFFSET_T: 29147c478bd9Sstevel@tonic-gate /*LINTED*/ 29157c478bd9Sstevel@tonic-gate return (*(offset_t *)bptr); 29167c478bd9Sstevel@tonic-gate } 29177c478bd9Sstevel@tonic-gate return (0); 29187c478bd9Sstevel@tonic-gate } 29197c478bd9Sstevel@tonic-gate 29207c478bd9Sstevel@tonic-gate /* 29217c478bd9Sstevel@tonic-gate * cgrp_check - make sure that we don't bump the cylinder group 29227c478bd9Sstevel@tonic-gate * beyond the total number of cylinder groups or before the start. 29237c478bd9Sstevel@tonic-gate */ 29247c478bd9Sstevel@tonic-gate static int 2925d1a180b0Smaheshvs cgrp_check(long cgrp) 29267c478bd9Sstevel@tonic-gate { 29277c478bd9Sstevel@tonic-gate if (cgrp < 0) { 29287c478bd9Sstevel@tonic-gate if (objsz == CGRP) 29297c478bd9Sstevel@tonic-gate printf("beginning of cylinder groups\n"); 29307c478bd9Sstevel@tonic-gate else 29317c478bd9Sstevel@tonic-gate printf("beginning of super blocks\n"); 29327c478bd9Sstevel@tonic-gate error++; 29337c478bd9Sstevel@tonic-gate return (0); 29347c478bd9Sstevel@tonic-gate } 29357c478bd9Sstevel@tonic-gate if (cgrp >= fs->fs_ncg) { 29367c478bd9Sstevel@tonic-gate if (objsz == CGRP) 29377c478bd9Sstevel@tonic-gate printf("end of cylinder groups\n"); 29387c478bd9Sstevel@tonic-gate else 29397c478bd9Sstevel@tonic-gate printf("end of super blocks\n"); 29407c478bd9Sstevel@tonic-gate error++; 29417c478bd9Sstevel@tonic-gate return (0); 29427c478bd9Sstevel@tonic-gate } 29437c478bd9Sstevel@tonic-gate if (objsz == CGRP) 29447c478bd9Sstevel@tonic-gate return (cgtod(fs, cgrp) << FRGSHIFT); 29457c478bd9Sstevel@tonic-gate else 29467c478bd9Sstevel@tonic-gate return (cgsblock(fs, cgrp) << FRGSHIFT); 29477c478bd9Sstevel@tonic-gate } 29487c478bd9Sstevel@tonic-gate 29497c478bd9Sstevel@tonic-gate /* 29507c478bd9Sstevel@tonic-gate * icheck - make sure we can read the block containing the inode 29517c478bd9Sstevel@tonic-gate * and determine the filesize (0 if inode not allocated). Return 29527c478bd9Sstevel@tonic-gate * 0 if error otherwise return the mode. 29537c478bd9Sstevel@tonic-gate */ 2954d1a180b0Smaheshvs int 2955d1a180b0Smaheshvs icheck(u_offset_t address) 29567c478bd9Sstevel@tonic-gate { 2957d1a180b0Smaheshvs char *cptr; 2958d1a180b0Smaheshvs struct dinode *ip; 29597c478bd9Sstevel@tonic-gate 29607c478bd9Sstevel@tonic-gate if ((cptr = getblk(address)) == 0) 29617c478bd9Sstevel@tonic-gate return (0); 29627c478bd9Sstevel@tonic-gate cptr += blkoff(fs, address); 29637c478bd9Sstevel@tonic-gate /*LINTED*/ 29647c478bd9Sstevel@tonic-gate ip = (struct dinode *)cptr; 29657c478bd9Sstevel@tonic-gate if ((ip->di_mode & IFMT) == 0) { 29667c478bd9Sstevel@tonic-gate if (!override) { 29677c478bd9Sstevel@tonic-gate printf("inode not allocated\n"); 29687c478bd9Sstevel@tonic-gate error++; 29697c478bd9Sstevel@tonic-gate return (0); 29707c478bd9Sstevel@tonic-gate } 29717c478bd9Sstevel@tonic-gate blocksize = filesize = 0; 29727c478bd9Sstevel@tonic-gate } else { 29737c478bd9Sstevel@tonic-gate trapped++; 29747c478bd9Sstevel@tonic-gate filesize = ip->di_size; 29757c478bd9Sstevel@tonic-gate blocksize = filesize * 2; 29767c478bd9Sstevel@tonic-gate } 29777c478bd9Sstevel@tonic-gate return (ip->di_mode); 29787c478bd9Sstevel@tonic-gate } 29797c478bd9Sstevel@tonic-gate 29807c478bd9Sstevel@tonic-gate /* 29817c478bd9Sstevel@tonic-gate * getdirslot - get the address of the directory slot desired. 29827c478bd9Sstevel@tonic-gate */ 29837c478bd9Sstevel@tonic-gate static u_offset_t 2984d1a180b0Smaheshvs getdirslot(long slot) 29857c478bd9Sstevel@tonic-gate { 2986d1a180b0Smaheshvs char *cptr; 2987d1a180b0Smaheshvs struct direct *dirp; 2988d1a180b0Smaheshvs short i; 29897c478bd9Sstevel@tonic-gate char *string = &scratch[0]; 29907c478bd9Sstevel@tonic-gate short bod = 0, mode, temp; 29917c478bd9Sstevel@tonic-gate 29927c478bd9Sstevel@tonic-gate if (slot < 0) { 29937c478bd9Sstevel@tonic-gate slot = 0; 29947c478bd9Sstevel@tonic-gate bod++; 29957c478bd9Sstevel@tonic-gate } 29967c478bd9Sstevel@tonic-gate if (type != DIRECTORY) { 29977c478bd9Sstevel@tonic-gate if (type == BLOCK) 29987c478bd9Sstevel@tonic-gate string = "block"; 29997c478bd9Sstevel@tonic-gate else 30007c478bd9Sstevel@tonic-gate string = "fragment"; 30017c478bd9Sstevel@tonic-gate addr = bod_addr; 30027c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 30037c478bd9Sstevel@tonic-gate return (0); 30047c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 30057c478bd9Sstevel@tonic-gate cur_bytes = 0; 30067c478bd9Sstevel@tonic-gate /*LINTED*/ 30077c478bd9Sstevel@tonic-gate dirp = (struct direct *)cptr; 30087c478bd9Sstevel@tonic-gate for (dirslot = 0; dirslot < slot; dirslot++) { 30097c478bd9Sstevel@tonic-gate /*LINTED*/ 30107c478bd9Sstevel@tonic-gate dirp = (struct direct *)cptr; 30117c478bd9Sstevel@tonic-gate if (blocksize > filesize) { 30127c478bd9Sstevel@tonic-gate if (cur_bytes + (long)dirp->d_reclen >= 30137c478bd9Sstevel@tonic-gate filesize) { 30147c478bd9Sstevel@tonic-gate printf("end of file\n"); 30157c478bd9Sstevel@tonic-gate erraddr = addr; 30167c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 30177c478bd9Sstevel@tonic-gate stringsize = STRINGSIZE(dirp); 30187c478bd9Sstevel@tonic-gate error++; 30197c478bd9Sstevel@tonic-gate return (addr); 30207c478bd9Sstevel@tonic-gate } 30217c478bd9Sstevel@tonic-gate } else { 30227c478bd9Sstevel@tonic-gate if (cur_bytes + (long)dirp->d_reclen >= 30237c478bd9Sstevel@tonic-gate blocksize) { 30247c478bd9Sstevel@tonic-gate printf("end of %s\n", string); 30257c478bd9Sstevel@tonic-gate erraddr = addr; 30267c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 30277c478bd9Sstevel@tonic-gate stringsize = STRINGSIZE(dirp); 30287c478bd9Sstevel@tonic-gate error++; 30297c478bd9Sstevel@tonic-gate return (addr); 30307c478bd9Sstevel@tonic-gate } 30317c478bd9Sstevel@tonic-gate } 30327c478bd9Sstevel@tonic-gate cptr += dirp->d_reclen; 30337c478bd9Sstevel@tonic-gate addr += dirp->d_reclen; 30347c478bd9Sstevel@tonic-gate cur_bytes += dirp->d_reclen; 30357c478bd9Sstevel@tonic-gate } 30367c478bd9Sstevel@tonic-gate if (bod) { 30377c478bd9Sstevel@tonic-gate if (blocksize > filesize) 30387c478bd9Sstevel@tonic-gate printf("beginning of file\n"); 30397c478bd9Sstevel@tonic-gate else 30407c478bd9Sstevel@tonic-gate printf("beginning of %s\n", string); 30417c478bd9Sstevel@tonic-gate erraddr = addr; 30427c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 30437c478bd9Sstevel@tonic-gate error++; 30447c478bd9Sstevel@tonic-gate } 30457c478bd9Sstevel@tonic-gate stringsize = STRINGSIZE(dirp); 30467c478bd9Sstevel@tonic-gate return (addr); 30477c478bd9Sstevel@tonic-gate } else { 30487c478bd9Sstevel@tonic-gate addr = cur_ino; 30497c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 30507c478bd9Sstevel@tonic-gate return (0); 30517c478bd9Sstevel@tonic-gate if (!override && (mode & IFDIR) == 0) { 30527c478bd9Sstevel@tonic-gate printf("inode is not a directory\n"); 30537c478bd9Sstevel@tonic-gate error++; 30547c478bd9Sstevel@tonic-gate return (0); 30557c478bd9Sstevel@tonic-gate } 30567c478bd9Sstevel@tonic-gate temp = slot; 30577c478bd9Sstevel@tonic-gate i = cur_bytes = 0; 30587c478bd9Sstevel@tonic-gate for (;;) { 30597c478bd9Sstevel@tonic-gate if (i == 0 || bcomp(addr)) { 30607c478bd9Sstevel@tonic-gate error = 0; 30617c478bd9Sstevel@tonic-gate if ((addr = (bmap((long)i++) << FRGSHIFT)) == 0) 30627c478bd9Sstevel@tonic-gate break; 30637c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 30647c478bd9Sstevel@tonic-gate break; 30657c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 30667c478bd9Sstevel@tonic-gate } 30677c478bd9Sstevel@tonic-gate /*LINTED*/ 30687c478bd9Sstevel@tonic-gate dirp = (struct direct *)cptr; 30697c478bd9Sstevel@tonic-gate value = dirp->d_ino; 30707c478bd9Sstevel@tonic-gate if (!temp--) 30717c478bd9Sstevel@tonic-gate break; 30727c478bd9Sstevel@tonic-gate if (cur_bytes + (long)dirp->d_reclen >= filesize) { 30737c478bd9Sstevel@tonic-gate printf("end of file\n"); 30747c478bd9Sstevel@tonic-gate dirslot = slot - temp - 1; 30757c478bd9Sstevel@tonic-gate objsz = DIRECTORY; 30767c478bd9Sstevel@tonic-gate erraddr = addr; 30777c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 30787c478bd9Sstevel@tonic-gate stringsize = STRINGSIZE(dirp); 30797c478bd9Sstevel@tonic-gate error++; 30807c478bd9Sstevel@tonic-gate return (addr); 30817c478bd9Sstevel@tonic-gate } 30827c478bd9Sstevel@tonic-gate addr += dirp->d_reclen; 30837c478bd9Sstevel@tonic-gate cptr += dirp->d_reclen; 30847c478bd9Sstevel@tonic-gate cur_bytes += dirp->d_reclen; 30857c478bd9Sstevel@tonic-gate } 30867c478bd9Sstevel@tonic-gate dirslot = slot; 30877c478bd9Sstevel@tonic-gate objsz = DIRECTORY; 30887c478bd9Sstevel@tonic-gate if (bod) { 30897c478bd9Sstevel@tonic-gate printf("beginning of file\n"); 30907c478bd9Sstevel@tonic-gate erraddr = addr; 30917c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 30927c478bd9Sstevel@tonic-gate error++; 30937c478bd9Sstevel@tonic-gate } 30947c478bd9Sstevel@tonic-gate stringsize = STRINGSIZE(dirp); 30957c478bd9Sstevel@tonic-gate return (addr); 30967c478bd9Sstevel@tonic-gate } 30977c478bd9Sstevel@tonic-gate } 30987c478bd9Sstevel@tonic-gate 30997c478bd9Sstevel@tonic-gate 31007c478bd9Sstevel@tonic-gate /* 31017c478bd9Sstevel@tonic-gate * getshadowslot - get the address of the shadow data desired 31027c478bd9Sstevel@tonic-gate */ 31037c478bd9Sstevel@tonic-gate static int 3104d1a180b0Smaheshvs getshadowslot(long shadow) 31057c478bd9Sstevel@tonic-gate { 31067c478bd9Sstevel@tonic-gate struct ufs_fsd fsd; 31077c478bd9Sstevel@tonic-gate short bod = 0, mode; 31087c478bd9Sstevel@tonic-gate long taddr, tcurbytes; 31097c478bd9Sstevel@tonic-gate 31107c478bd9Sstevel@tonic-gate if (shadow < 0) { 31117c478bd9Sstevel@tonic-gate shadow = 0; 31127c478bd9Sstevel@tonic-gate bod++; 31137c478bd9Sstevel@tonic-gate } 31147c478bd9Sstevel@tonic-gate if (type != SHADOW_DATA) { 31157c478bd9Sstevel@tonic-gate if (shadow < cur_shad) { 31167c478bd9Sstevel@tonic-gate printf("can't scan shadow data in reverse\n"); 31177c478bd9Sstevel@tonic-gate error++; 31187c478bd9Sstevel@tonic-gate return (0); 31197c478bd9Sstevel@tonic-gate } 31207c478bd9Sstevel@tonic-gate } else { 31217c478bd9Sstevel@tonic-gate addr = cur_ino; 31227c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 31237c478bd9Sstevel@tonic-gate return (0); 31247c478bd9Sstevel@tonic-gate if (!override && (mode & IFMT) != IFSHAD) { 31257c478bd9Sstevel@tonic-gate printf("inode is not a shadow\n"); 31267c478bd9Sstevel@tonic-gate error++; 31277c478bd9Sstevel@tonic-gate return (0); 31287c478bd9Sstevel@tonic-gate } 31297c478bd9Sstevel@tonic-gate cur_bytes = 0; 31307c478bd9Sstevel@tonic-gate cur_shad = 0; 31317c478bd9Sstevel@tonic-gate syncshadowscan(1); /* force synchronization */ 31327c478bd9Sstevel@tonic-gate } 31337c478bd9Sstevel@tonic-gate 31347c478bd9Sstevel@tonic-gate for (; cur_shad < shadow; cur_shad++) { 31357c478bd9Sstevel@tonic-gate taddr = addr; 31367c478bd9Sstevel@tonic-gate tcurbytes = cur_bytes; 31377c478bd9Sstevel@tonic-gate getshadowdata((long *)&fsd, LONG + LONG); 31387c478bd9Sstevel@tonic-gate addr = taddr; 31397c478bd9Sstevel@tonic-gate cur_bytes = tcurbytes; 31407c478bd9Sstevel@tonic-gate if (cur_bytes + (long)fsd.fsd_size > filesize) { 31417c478bd9Sstevel@tonic-gate syncshadowscan(0); 31427c478bd9Sstevel@tonic-gate printf("end of file\n"); 31437c478bd9Sstevel@tonic-gate erraddr = addr; 31447c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 31457c478bd9Sstevel@tonic-gate error++; 31467c478bd9Sstevel@tonic-gate return (addr); 31477c478bd9Sstevel@tonic-gate } 31487c478bd9Sstevel@tonic-gate addr += fsd.fsd_size; 31497c478bd9Sstevel@tonic-gate cur_bytes += fsd.fsd_size; 31507c478bd9Sstevel@tonic-gate syncshadowscan(0); 31517c478bd9Sstevel@tonic-gate } 31527c478bd9Sstevel@tonic-gate if (type == SHADOW_DATA) 31537c478bd9Sstevel@tonic-gate objsz = SHADOW_DATA; 31547c478bd9Sstevel@tonic-gate if (bod) { 31557c478bd9Sstevel@tonic-gate printf("beginning of file\n"); 31567c478bd9Sstevel@tonic-gate erraddr = addr; 31577c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 31587c478bd9Sstevel@tonic-gate error++; 31597c478bd9Sstevel@tonic-gate } 31607c478bd9Sstevel@tonic-gate return (addr); 31617c478bd9Sstevel@tonic-gate } 31627c478bd9Sstevel@tonic-gate 31637c478bd9Sstevel@tonic-gate static void 3164d1a180b0Smaheshvs getshadowdata(long *buf, int len) 31657c478bd9Sstevel@tonic-gate { 31667c478bd9Sstevel@tonic-gate long tfsd; 31677c478bd9Sstevel@tonic-gate 31687c478bd9Sstevel@tonic-gate len /= LONG; 31697c478bd9Sstevel@tonic-gate for (tfsd = 0; tfsd < len; tfsd++) { 31707c478bd9Sstevel@tonic-gate buf[tfsd] = get(SHADOW_DATA); 31717c478bd9Sstevel@tonic-gate addr += LONG; 31727c478bd9Sstevel@tonic-gate cur_bytes += LONG; 31737c478bd9Sstevel@tonic-gate syncshadowscan(0); 31747c478bd9Sstevel@tonic-gate } 31757c478bd9Sstevel@tonic-gate } 31767c478bd9Sstevel@tonic-gate 31777c478bd9Sstevel@tonic-gate static void 3178d1a180b0Smaheshvs syncshadowscan(int force) 31797c478bd9Sstevel@tonic-gate { 31807c478bd9Sstevel@tonic-gate long curblkoff; 31817c478bd9Sstevel@tonic-gate if (type == SHADOW_DATA && (force || 31827c478bd9Sstevel@tonic-gate lblkno(fs, addr) != (bhdr.fwd)->blkno)) { 31837c478bd9Sstevel@tonic-gate curblkoff = blkoff(fs, cur_bytes); 31847c478bd9Sstevel@tonic-gate addr = bmap(lblkno(fs, cur_bytes)) << FRGSHIFT; 31857c478bd9Sstevel@tonic-gate addr += curblkoff; 31867c478bd9Sstevel@tonic-gate cur_bytes += curblkoff; 31877c478bd9Sstevel@tonic-gate (void) getblk(addr); 31887c478bd9Sstevel@tonic-gate objsz = SHADOW_DATA; 31897c478bd9Sstevel@tonic-gate } 31907c478bd9Sstevel@tonic-gate } 31917c478bd9Sstevel@tonic-gate 31927c478bd9Sstevel@tonic-gate 31937c478bd9Sstevel@tonic-gate 31947c478bd9Sstevel@tonic-gate /* 31957c478bd9Sstevel@tonic-gate * putf - print a byte as an ascii character if possible. 31967c478bd9Sstevel@tonic-gate * The exceptions are tabs, newlines, backslashes 31977c478bd9Sstevel@tonic-gate * and nulls which are printed as the standard C 31987c478bd9Sstevel@tonic-gate * language escapes. Characters which are not 31997c478bd9Sstevel@tonic-gate * recognized are printed as \?. 32007c478bd9Sstevel@tonic-gate */ 32017c478bd9Sstevel@tonic-gate static void 3202d1a180b0Smaheshvs putf(char c) 32037c478bd9Sstevel@tonic-gate { 32047c478bd9Sstevel@tonic-gate 32057c478bd9Sstevel@tonic-gate if (c <= 037 || c >= 0177 || c == '\\') { 32067c478bd9Sstevel@tonic-gate printf("\\"); 32077c478bd9Sstevel@tonic-gate switch (c) { 32087c478bd9Sstevel@tonic-gate case '\\': 32097c478bd9Sstevel@tonic-gate printf("\\"); 32107c478bd9Sstevel@tonic-gate break; 32117c478bd9Sstevel@tonic-gate case '\t': 32127c478bd9Sstevel@tonic-gate printf("t"); 32137c478bd9Sstevel@tonic-gate break; 32147c478bd9Sstevel@tonic-gate case '\n': 32157c478bd9Sstevel@tonic-gate printf("n"); 32167c478bd9Sstevel@tonic-gate break; 32177c478bd9Sstevel@tonic-gate case '\0': 32187c478bd9Sstevel@tonic-gate printf("0"); 32197c478bd9Sstevel@tonic-gate break; 32207c478bd9Sstevel@tonic-gate default: 32217c478bd9Sstevel@tonic-gate printf("?"); 32227c478bd9Sstevel@tonic-gate } 32237c478bd9Sstevel@tonic-gate } else { 32247c478bd9Sstevel@tonic-gate printf("%c", c); 32257c478bd9Sstevel@tonic-gate printf(" "); 32267c478bd9Sstevel@tonic-gate } 32277c478bd9Sstevel@tonic-gate } 32287c478bd9Sstevel@tonic-gate 32297c478bd9Sstevel@tonic-gate /* 32307c478bd9Sstevel@tonic-gate * put - write an item into the buffer for the current address 32317c478bd9Sstevel@tonic-gate * block. The value is checked to make sure that it will 32327c478bd9Sstevel@tonic-gate * fit in the size given without truncation. If successful, 32337c478bd9Sstevel@tonic-gate * the entire block is written back to the file system. 32347c478bd9Sstevel@tonic-gate */ 32357c478bd9Sstevel@tonic-gate static void 3236d1a180b0Smaheshvs put(u_offset_t item, short lngth) 32377c478bd9Sstevel@tonic-gate { 32387c478bd9Sstevel@tonic-gate 3239d1a180b0Smaheshvs char *bptr, *sbptr; 32407c478bd9Sstevel@tonic-gate long s_err, nbytes; 32417c478bd9Sstevel@tonic-gate long olditem; 32427c478bd9Sstevel@tonic-gate 32437c478bd9Sstevel@tonic-gate if (wrtflag == O_RDONLY) { 32447c478bd9Sstevel@tonic-gate printf("not opened for write '-w'\n"); 32457c478bd9Sstevel@tonic-gate error++; 32467c478bd9Sstevel@tonic-gate return; 32477c478bd9Sstevel@tonic-gate } 32487c478bd9Sstevel@tonic-gate objsz = lngth; 32497c478bd9Sstevel@tonic-gate if ((sbptr = getblk(addr)) == 0) 32507c478bd9Sstevel@tonic-gate return; 32517c478bd9Sstevel@tonic-gate bptr = sbptr + blkoff(fs, addr); 32527c478bd9Sstevel@tonic-gate switch (objsz) { 32537c478bd9Sstevel@tonic-gate case LONG: 32547c478bd9Sstevel@tonic-gate case DIRECTORY: 32557c478bd9Sstevel@tonic-gate /*LINTED*/ 32567c478bd9Sstevel@tonic-gate olditem = *(long *)bptr; 32577c478bd9Sstevel@tonic-gate /*LINTED*/ 32587c478bd9Sstevel@tonic-gate *(long *)bptr = item; 32597c478bd9Sstevel@tonic-gate break; 32607c478bd9Sstevel@tonic-gate case SHORT: 32617c478bd9Sstevel@tonic-gate case INODE: 32627c478bd9Sstevel@tonic-gate /*LINTED*/ 32637c478bd9Sstevel@tonic-gate olditem = (long)*(short *)bptr; 32647c478bd9Sstevel@tonic-gate item &= 0177777L; 32657c478bd9Sstevel@tonic-gate /*LINTED*/ 32667c478bd9Sstevel@tonic-gate *(short *)bptr = item; 32677c478bd9Sstevel@tonic-gate break; 32687c478bd9Sstevel@tonic-gate case CHAR: 32697c478bd9Sstevel@tonic-gate olditem = (long)*bptr; 32707c478bd9Sstevel@tonic-gate item &= 0377; 32717c478bd9Sstevel@tonic-gate *bptr = lobyte(loword(item)); 32727c478bd9Sstevel@tonic-gate break; 32737c478bd9Sstevel@tonic-gate default: 32747c478bd9Sstevel@tonic-gate error++; 32757c478bd9Sstevel@tonic-gate return; 32767c478bd9Sstevel@tonic-gate } 32777c478bd9Sstevel@tonic-gate if ((s_err = llseek(fd, (offset_t)(addr & fs->fs_bmask), 0)) == -1) { 32787c478bd9Sstevel@tonic-gate error++; 32797c478bd9Sstevel@tonic-gate printf("seek error : %" PRIx64 "\n", addr); 32807c478bd9Sstevel@tonic-gate return; 32817c478bd9Sstevel@tonic-gate } 32827c478bd9Sstevel@tonic-gate if ((nbytes = write(fd, sbptr, BLKSIZE)) != BLKSIZE) { 32837c478bd9Sstevel@tonic-gate error++; 32847c478bd9Sstevel@tonic-gate printf("write error : addr = %" PRIx64 "\n", addr); 32857c478bd9Sstevel@tonic-gate printf(" : s_err = %lx\n", s_err); 32867c478bd9Sstevel@tonic-gate printf(" : nbytes = %lx\n", nbytes); 32877c478bd9Sstevel@tonic-gate return; 32887c478bd9Sstevel@tonic-gate } 32897c478bd9Sstevel@tonic-gate if (!acting_on_inode && objsz != INODE && objsz != DIRECTORY) { 32907c478bd9Sstevel@tonic-gate index(base); 32917c478bd9Sstevel@tonic-gate print(olditem, 8, -8, 0); 32927c478bd9Sstevel@tonic-gate printf("\t=\t"); 32937c478bd9Sstevel@tonic-gate print(item, 8, -8, 0); 32947c478bd9Sstevel@tonic-gate printf("\n"); 32957c478bd9Sstevel@tonic-gate } else { 32967c478bd9Sstevel@tonic-gate if (objsz == DIRECTORY) { 32977c478bd9Sstevel@tonic-gate addr = cur_dir; 32987c478bd9Sstevel@tonic-gate fprnt('?', 'd'); 32997c478bd9Sstevel@tonic-gate } else { 33007c478bd9Sstevel@tonic-gate addr = cur_ino; 33017c478bd9Sstevel@tonic-gate objsz = INODE; 33027c478bd9Sstevel@tonic-gate fprnt('?', 'i'); 33037c478bd9Sstevel@tonic-gate } 33047c478bd9Sstevel@tonic-gate } 33057c478bd9Sstevel@tonic-gate } 33067c478bd9Sstevel@tonic-gate 33077c478bd9Sstevel@tonic-gate /* 33087c478bd9Sstevel@tonic-gate * getblk - check if the desired block is in the file system. 33097c478bd9Sstevel@tonic-gate * Search the incore buffers to see if the block is already 33107c478bd9Sstevel@tonic-gate * available. If successful, unlink the buffer control block 33117c478bd9Sstevel@tonic-gate * from its position in the buffer list and re-insert it at 33127c478bd9Sstevel@tonic-gate * the head of the list. If failure, use the last buffer 33137c478bd9Sstevel@tonic-gate * in the list for the desired block. Again, this control 33147c478bd9Sstevel@tonic-gate * block is placed at the head of the list. This process 33157c478bd9Sstevel@tonic-gate * will leave commonly requested blocks in the in-core buffers. 33167c478bd9Sstevel@tonic-gate * Finally, a pointer to the buffer is returned. 33177c478bd9Sstevel@tonic-gate */ 33187c478bd9Sstevel@tonic-gate static char * 3319d1a180b0Smaheshvs getblk(u_offset_t address) 33207c478bd9Sstevel@tonic-gate { 33217c478bd9Sstevel@tonic-gate 3322d1a180b0Smaheshvs struct lbuf *bp; 33237c478bd9Sstevel@tonic-gate long s_err, nbytes; 33247c478bd9Sstevel@tonic-gate unsigned long block; 33257c478bd9Sstevel@tonic-gate 33267c478bd9Sstevel@tonic-gate read_requests++; 33277c478bd9Sstevel@tonic-gate block = lblkno(fs, address); 33287c478bd9Sstevel@tonic-gate if (block >= fragstoblks(fs, fs->fs_size)) { 33297c478bd9Sstevel@tonic-gate printf("cannot read block %lu\n", block); 33307c478bd9Sstevel@tonic-gate error++; 33317c478bd9Sstevel@tonic-gate return (0); 33327c478bd9Sstevel@tonic-gate } 33337c478bd9Sstevel@tonic-gate for (bp = bhdr.fwd; bp != &bhdr; bp = bp->fwd) 33347c478bd9Sstevel@tonic-gate if (bp->valid && bp->blkno == block) 33357c478bd9Sstevel@tonic-gate goto xit; 33367c478bd9Sstevel@tonic-gate actual_disk_reads++; 33377c478bd9Sstevel@tonic-gate bp = bhdr.back; 33387c478bd9Sstevel@tonic-gate bp->blkno = block; 33397c478bd9Sstevel@tonic-gate bp->valid = 0; 33407c478bd9Sstevel@tonic-gate if ((s_err = llseek(fd, (offset_t)(address & fs->fs_bmask), 0)) == -1) { 33417c478bd9Sstevel@tonic-gate error++; 33427c478bd9Sstevel@tonic-gate printf("seek error : %" PRIx64 "\n", address); 33437c478bd9Sstevel@tonic-gate return (0); 33447c478bd9Sstevel@tonic-gate } 33457c478bd9Sstevel@tonic-gate if ((nbytes = read(fd, bp->blkaddr, BLKSIZE)) != BLKSIZE) { 33467c478bd9Sstevel@tonic-gate error++; 33477c478bd9Sstevel@tonic-gate printf("read error : addr = %" PRIx64 "\n", address); 33487c478bd9Sstevel@tonic-gate printf(" : s_err = %lx\n", s_err); 33497c478bd9Sstevel@tonic-gate printf(" : nbytes = %lx\n", nbytes); 33507c478bd9Sstevel@tonic-gate return (0); 33517c478bd9Sstevel@tonic-gate } 33527c478bd9Sstevel@tonic-gate bp->valid++; 33537c478bd9Sstevel@tonic-gate xit: bp->back->fwd = bp->fwd; 33547c478bd9Sstevel@tonic-gate bp->fwd->back = bp->back; 33557c478bd9Sstevel@tonic-gate insert(bp); 33567c478bd9Sstevel@tonic-gate return (bp->blkaddr); 33577c478bd9Sstevel@tonic-gate } 33587c478bd9Sstevel@tonic-gate 33597c478bd9Sstevel@tonic-gate /* 33607c478bd9Sstevel@tonic-gate * insert - place the designated buffer control block 33617c478bd9Sstevel@tonic-gate * at the head of the linked list of buffers. 33627c478bd9Sstevel@tonic-gate */ 33637c478bd9Sstevel@tonic-gate static void 3364d1a180b0Smaheshvs insert(struct lbuf *bp) 33657c478bd9Sstevel@tonic-gate { 33667c478bd9Sstevel@tonic-gate 33677c478bd9Sstevel@tonic-gate bp->back = &bhdr; 33687c478bd9Sstevel@tonic-gate bp->fwd = bhdr.fwd; 33697c478bd9Sstevel@tonic-gate bhdr.fwd->back = bp; 33707c478bd9Sstevel@tonic-gate bhdr.fwd = bp; 33717c478bd9Sstevel@tonic-gate } 33727c478bd9Sstevel@tonic-gate 33737c478bd9Sstevel@tonic-gate /* 33747c478bd9Sstevel@tonic-gate * err - called on interrupts. Set the current address 33757c478bd9Sstevel@tonic-gate * back to the last address stored in erraddr. Reset all 33767c478bd9Sstevel@tonic-gate * appropriate flags. A reset call is made to return 33777c478bd9Sstevel@tonic-gate * to the main loop; 33787c478bd9Sstevel@tonic-gate */ 33797c478bd9Sstevel@tonic-gate #ifdef sun 33807c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 33817c478bd9Sstevel@tonic-gate static void 3382d1a180b0Smaheshvs err(int sig) 33837c478bd9Sstevel@tonic-gate #else 33847c478bd9Sstevel@tonic-gate err() 33857c478bd9Sstevel@tonic-gate #endif /* sun */ 33867c478bd9Sstevel@tonic-gate { 33877c478bd9Sstevel@tonic-gate freemem(filenames, nfiles); 33887c478bd9Sstevel@tonic-gate nfiles = 0; 33897c478bd9Sstevel@tonic-gate (void) signal(2, err); 33907c478bd9Sstevel@tonic-gate addr = erraddr; 33917c478bd9Sstevel@tonic-gate cur_ino = errino; 33927c478bd9Sstevel@tonic-gate cur_inum = errinum; 33937c478bd9Sstevel@tonic-gate cur_bytes = errcur_bytes; 33947c478bd9Sstevel@tonic-gate error = 0; 33957c478bd9Sstevel@tonic-gate c_count = 0; 33967c478bd9Sstevel@tonic-gate printf("\n?\n"); 33977c478bd9Sstevel@tonic-gate (void) fseek(stdin, 0L, 2); 33987c478bd9Sstevel@tonic-gate longjmp(env, 0); 33997c478bd9Sstevel@tonic-gate } 34007c478bd9Sstevel@tonic-gate 34017c478bd9Sstevel@tonic-gate /* 34027c478bd9Sstevel@tonic-gate * devcheck - check that the given mode represents a 34037c478bd9Sstevel@tonic-gate * special device. The IFCHR bit is on for both 34047c478bd9Sstevel@tonic-gate * character and block devices. 34057c478bd9Sstevel@tonic-gate */ 34067c478bd9Sstevel@tonic-gate static int 3407d1a180b0Smaheshvs devcheck(short md) 34087c478bd9Sstevel@tonic-gate { 34097c478bd9Sstevel@tonic-gate if (override) 34107c478bd9Sstevel@tonic-gate return (0); 34117c478bd9Sstevel@tonic-gate switch (md & IFMT) { 34127c478bd9Sstevel@tonic-gate case IFCHR: 34137c478bd9Sstevel@tonic-gate case IFBLK: 34147c478bd9Sstevel@tonic-gate return (0); 34157c478bd9Sstevel@tonic-gate } 34167c478bd9Sstevel@tonic-gate 34177c478bd9Sstevel@tonic-gate printf("not character or block device\n"); 34187c478bd9Sstevel@tonic-gate error++; 34197c478bd9Sstevel@tonic-gate return (1); 34207c478bd9Sstevel@tonic-gate } 34217c478bd9Sstevel@tonic-gate 34227c478bd9Sstevel@tonic-gate /* 34237c478bd9Sstevel@tonic-gate * nullblk - return error if address is zero. This is done 34247c478bd9Sstevel@tonic-gate * to prevent block 0 from being used as an indirect block 34257c478bd9Sstevel@tonic-gate * for a large file or as a data block for a small file. 34267c478bd9Sstevel@tonic-gate */ 34277c478bd9Sstevel@tonic-gate static int 3428d1a180b0Smaheshvs nullblk(long bn) 34297c478bd9Sstevel@tonic-gate { 34307c478bd9Sstevel@tonic-gate if (bn != 0) 34317c478bd9Sstevel@tonic-gate return (0); 34327c478bd9Sstevel@tonic-gate printf("non existent block\n"); 34337c478bd9Sstevel@tonic-gate error++; 34347c478bd9Sstevel@tonic-gate return (1); 34357c478bd9Sstevel@tonic-gate } 34367c478bd9Sstevel@tonic-gate 34377c478bd9Sstevel@tonic-gate /* 34387c478bd9Sstevel@tonic-gate * puta - put ascii characters into a buffer. The string 34397c478bd9Sstevel@tonic-gate * terminates with a quote or newline. The leading quote, 34407c478bd9Sstevel@tonic-gate * which is optional for directory names, was stripped off 34417c478bd9Sstevel@tonic-gate * by the assignment case in the main loop. 34427c478bd9Sstevel@tonic-gate */ 34437c478bd9Sstevel@tonic-gate static void 34447c478bd9Sstevel@tonic-gate puta() 34457c478bd9Sstevel@tonic-gate { 3446d1a180b0Smaheshvs char *cptr, c; 3447d1a180b0Smaheshvs int i; 34487c478bd9Sstevel@tonic-gate char *sbptr; 34497c478bd9Sstevel@tonic-gate short terror = 0; 34507c478bd9Sstevel@tonic-gate long maxchars, s_err, nbytes, temp; 34517c478bd9Sstevel@tonic-gate u_offset_t taddr = addr; 34527c478bd9Sstevel@tonic-gate long tcount = 0, item, olditem = 0; 34537c478bd9Sstevel@tonic-gate 34547c478bd9Sstevel@tonic-gate if (wrtflag == O_RDONLY) { 34557c478bd9Sstevel@tonic-gate printf("not opened for write '-w'\n"); 34567c478bd9Sstevel@tonic-gate error++; 34577c478bd9Sstevel@tonic-gate return; 34587c478bd9Sstevel@tonic-gate } 34597c478bd9Sstevel@tonic-gate if ((sbptr = getblk(addr)) == 0) 34607c478bd9Sstevel@tonic-gate return; 34617c478bd9Sstevel@tonic-gate cptr = sbptr + blkoff(fs, addr); 34627c478bd9Sstevel@tonic-gate if (objsz == DIRECTORY) { 34637c478bd9Sstevel@tonic-gate if (acting_on_directory) 34647c478bd9Sstevel@tonic-gate maxchars = stringsize - 1; 34657c478bd9Sstevel@tonic-gate else 34667c478bd9Sstevel@tonic-gate maxchars = LONG; 34677c478bd9Sstevel@tonic-gate } else if (objsz == INODE) 34687c478bd9Sstevel@tonic-gate maxchars = objsz - (addr - cur_ino); 34697c478bd9Sstevel@tonic-gate else 34707c478bd9Sstevel@tonic-gate maxchars = min(blocksize - cur_bytes, filesize - cur_bytes); 34717c478bd9Sstevel@tonic-gate while ((c = getachar()) != '"') { 34727c478bd9Sstevel@tonic-gate if (tcount >= maxchars) { 34737c478bd9Sstevel@tonic-gate printf("string too long\n"); 34747c478bd9Sstevel@tonic-gate if (objsz == DIRECTORY) 34757c478bd9Sstevel@tonic-gate addr = cur_dir; 34767c478bd9Sstevel@tonic-gate else if (acting_on_inode || objsz == INODE) 34777c478bd9Sstevel@tonic-gate addr = cur_ino; 34787c478bd9Sstevel@tonic-gate else 34797c478bd9Sstevel@tonic-gate addr = taddr; 34807c478bd9Sstevel@tonic-gate erraddr = addr; 34817c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 34827c478bd9Sstevel@tonic-gate terror++; 34837c478bd9Sstevel@tonic-gate break; 34847c478bd9Sstevel@tonic-gate } 34857c478bd9Sstevel@tonic-gate tcount++; 34867c478bd9Sstevel@tonic-gate if (c == '\n') { 34877c478bd9Sstevel@tonic-gate ungetachar(c); 34887c478bd9Sstevel@tonic-gate break; 34897c478bd9Sstevel@tonic-gate } 34907c478bd9Sstevel@tonic-gate temp = (long)*cptr; 34917c478bd9Sstevel@tonic-gate olditem <<= BITSPERCHAR; 34927c478bd9Sstevel@tonic-gate olditem += temp & 0xff; 34937c478bd9Sstevel@tonic-gate if (c == '\\') { 34947c478bd9Sstevel@tonic-gate switch (c = getachar()) { 34957c478bd9Sstevel@tonic-gate case 't': 34967c478bd9Sstevel@tonic-gate *cptr++ = '\t'; 34977c478bd9Sstevel@tonic-gate break; 34987c478bd9Sstevel@tonic-gate case 'n': 34997c478bd9Sstevel@tonic-gate *cptr++ = '\n'; 35007c478bd9Sstevel@tonic-gate break; 35017c478bd9Sstevel@tonic-gate case '0': 35027c478bd9Sstevel@tonic-gate *cptr++ = '\0'; 35037c478bd9Sstevel@tonic-gate break; 35047c478bd9Sstevel@tonic-gate default: 35057c478bd9Sstevel@tonic-gate *cptr++ = c; 35067c478bd9Sstevel@tonic-gate break; 35077c478bd9Sstevel@tonic-gate } 35087c478bd9Sstevel@tonic-gate } 35097c478bd9Sstevel@tonic-gate else 35107c478bd9Sstevel@tonic-gate *cptr++ = c; 35117c478bd9Sstevel@tonic-gate } 35127c478bd9Sstevel@tonic-gate if (objsz == DIRECTORY && acting_on_directory) 35137c478bd9Sstevel@tonic-gate for (i = tcount; i <= maxchars; i++) 35147c478bd9Sstevel@tonic-gate *cptr++ = '\0'; 35157c478bd9Sstevel@tonic-gate if ((s_err = llseek(fd, (offset_t)(addr & fs->fs_bmask), 0)) == -1) { 35167c478bd9Sstevel@tonic-gate error++; 35177c478bd9Sstevel@tonic-gate printf("seek error : %" PRIx64 "\n", addr); 35187c478bd9Sstevel@tonic-gate return; 35197c478bd9Sstevel@tonic-gate } 35207c478bd9Sstevel@tonic-gate if ((nbytes = write(fd, sbptr, BLKSIZE)) != BLKSIZE) { 35217c478bd9Sstevel@tonic-gate error++; 35227c478bd9Sstevel@tonic-gate printf("write error : addr = %" PRIx64 "\n", addr); 35237c478bd9Sstevel@tonic-gate printf(" : s_err = %lx\n", s_err); 35247c478bd9Sstevel@tonic-gate printf(" : nbytes = %lx\n", nbytes); 35257c478bd9Sstevel@tonic-gate return; 35267c478bd9Sstevel@tonic-gate } 35277c478bd9Sstevel@tonic-gate if (!acting_on_inode && objsz != INODE && objsz != DIRECTORY) { 35287c478bd9Sstevel@tonic-gate addr += tcount; 35297c478bd9Sstevel@tonic-gate cur_bytes += tcount; 35307c478bd9Sstevel@tonic-gate taddr = addr; 35317c478bd9Sstevel@tonic-gate if (objsz != CHAR) { 35327c478bd9Sstevel@tonic-gate addr &= ~(objsz - 1); 35337c478bd9Sstevel@tonic-gate cur_bytes -= taddr - addr; 35347c478bd9Sstevel@tonic-gate } 35357c478bd9Sstevel@tonic-gate if (addr == taddr) { 35367c478bd9Sstevel@tonic-gate addr -= objsz; 35377c478bd9Sstevel@tonic-gate taddr = addr; 35387c478bd9Sstevel@tonic-gate } 35397c478bd9Sstevel@tonic-gate tcount = LONG - (taddr - addr); 35407c478bd9Sstevel@tonic-gate index(base); 35417c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 35427c478bd9Sstevel@tonic-gate return; 35437c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 35447c478bd9Sstevel@tonic-gate switch (objsz) { 35457c478bd9Sstevel@tonic-gate case LONG: 35467c478bd9Sstevel@tonic-gate /*LINTED*/ 35477c478bd9Sstevel@tonic-gate item = *(long *)cptr; 35487c478bd9Sstevel@tonic-gate if (tcount < LONG) { 35497c478bd9Sstevel@tonic-gate olditem <<= tcount * BITSPERCHAR; 35507c478bd9Sstevel@tonic-gate temp = 1; 35517c478bd9Sstevel@tonic-gate for (i = 0; i < (tcount*BITSPERCHAR); i++) 35527c478bd9Sstevel@tonic-gate temp <<= 1; 35537c478bd9Sstevel@tonic-gate olditem += item & (temp - 1); 35547c478bd9Sstevel@tonic-gate } 35557c478bd9Sstevel@tonic-gate break; 35567c478bd9Sstevel@tonic-gate case SHORT: 35577c478bd9Sstevel@tonic-gate /*LINTED*/ 35587c478bd9Sstevel@tonic-gate item = (long)*(short *)cptr; 35597c478bd9Sstevel@tonic-gate if (tcount < SHORT) { 35607c478bd9Sstevel@tonic-gate olditem <<= tcount * BITSPERCHAR; 35617c478bd9Sstevel@tonic-gate temp = 1; 35627c478bd9Sstevel@tonic-gate for (i = 0; i < (tcount * BITSPERCHAR); i++) 35637c478bd9Sstevel@tonic-gate temp <<= 1; 35647c478bd9Sstevel@tonic-gate olditem += item & (temp - 1); 35657c478bd9Sstevel@tonic-gate } 35667c478bd9Sstevel@tonic-gate olditem &= 0177777L; 35677c478bd9Sstevel@tonic-gate break; 35687c478bd9Sstevel@tonic-gate case CHAR: 35697c478bd9Sstevel@tonic-gate item = (long)*cptr; 35707c478bd9Sstevel@tonic-gate olditem &= 0377; 35717c478bd9Sstevel@tonic-gate } 35727c478bd9Sstevel@tonic-gate print(olditem, 8, -8, 0); 35737c478bd9Sstevel@tonic-gate printf("\t=\t"); 35747c478bd9Sstevel@tonic-gate print(item, 8, -8, 0); 35757c478bd9Sstevel@tonic-gate printf("\n"); 35767c478bd9Sstevel@tonic-gate } else { 35777c478bd9Sstevel@tonic-gate if (objsz == DIRECTORY) { 35787c478bd9Sstevel@tonic-gate addr = cur_dir; 35797c478bd9Sstevel@tonic-gate fprnt('?', 'd'); 35807c478bd9Sstevel@tonic-gate } else { 35817c478bd9Sstevel@tonic-gate addr = cur_ino; 35827c478bd9Sstevel@tonic-gate objsz = INODE; 35837c478bd9Sstevel@tonic-gate fprnt('?', 'i'); 35847c478bd9Sstevel@tonic-gate } 35857c478bd9Sstevel@tonic-gate } 35867c478bd9Sstevel@tonic-gate if (terror) 35877c478bd9Sstevel@tonic-gate error++; 35887c478bd9Sstevel@tonic-gate } 35897c478bd9Sstevel@tonic-gate 35907c478bd9Sstevel@tonic-gate /* 35917c478bd9Sstevel@tonic-gate * fprnt - print data. 'count' elements are printed where '*' will 35927c478bd9Sstevel@tonic-gate * print an entire blocks worth or up to the eof, whichever 35937c478bd9Sstevel@tonic-gate * occurs first. An error will occur if crossing a block boundary 35947c478bd9Sstevel@tonic-gate * is attempted since consecutive blocks don't usually have 35957c478bd9Sstevel@tonic-gate * meaning. Current print types: 35967c478bd9Sstevel@tonic-gate * / b - print as bytes (base sensitive) 35977c478bd9Sstevel@tonic-gate * c - print as characters 35987c478bd9Sstevel@tonic-gate * o O - print as octal shorts (longs) 35997c478bd9Sstevel@tonic-gate * d D - print as decimal shorts (longs) 36007c478bd9Sstevel@tonic-gate * x X - print as hexadecimal shorts (longs) 36017c478bd9Sstevel@tonic-gate * ? c - print as cylinder groups 36027c478bd9Sstevel@tonic-gate * d - print as directories 36037c478bd9Sstevel@tonic-gate * i - print as inodes 36047c478bd9Sstevel@tonic-gate * s - print as super blocks 36057c478bd9Sstevel@tonic-gate * S - print as shadow data 36067c478bd9Sstevel@tonic-gate */ 36077c478bd9Sstevel@tonic-gate static void 3608d1a180b0Smaheshvs fprnt(char style, char po) 36097c478bd9Sstevel@tonic-gate { 3610d1a180b0Smaheshvs int i; 3611d1a180b0Smaheshvs struct fs *sb; 3612d1a180b0Smaheshvs struct cg *cg; 3613d1a180b0Smaheshvs struct direct *dirp; 3614d1a180b0Smaheshvs struct dinode *ip; 36157c478bd9Sstevel@tonic-gate int tbase; 36167c478bd9Sstevel@tonic-gate char c, *cptr, *p; 36177c478bd9Sstevel@tonic-gate long tinode, tcount, temp; 36187c478bd9Sstevel@tonic-gate u_offset_t taddr; 36197c478bd9Sstevel@tonic-gate short offset, mode, end = 0, eof = 0, eof_flag; 36207c478bd9Sstevel@tonic-gate unsigned short *sptr; 36217c478bd9Sstevel@tonic-gate unsigned long *lptr; 36227c478bd9Sstevel@tonic-gate offset_t curoff, curioff; 36237c478bd9Sstevel@tonic-gate 36247c478bd9Sstevel@tonic-gate laststyle = style; 36257c478bd9Sstevel@tonic-gate lastpo = po; 36267c478bd9Sstevel@tonic-gate should_print = 0; 36277c478bd9Sstevel@tonic-gate if (count != 1) { 36287c478bd9Sstevel@tonic-gate if (clear) { 36297c478bd9Sstevel@tonic-gate count = 1; 36307c478bd9Sstevel@tonic-gate star = 0; 36317c478bd9Sstevel@tonic-gate clear = 0; 36327c478bd9Sstevel@tonic-gate } else 36337c478bd9Sstevel@tonic-gate clear = 1; 36347c478bd9Sstevel@tonic-gate } 36357c478bd9Sstevel@tonic-gate tcount = count; 36367c478bd9Sstevel@tonic-gate offset = blkoff(fs, addr); 36377c478bd9Sstevel@tonic-gate 36387c478bd9Sstevel@tonic-gate if (style == '/') { 36397c478bd9Sstevel@tonic-gate if (type == NUMB) 36407c478bd9Sstevel@tonic-gate eof_flag = 0; 36417c478bd9Sstevel@tonic-gate else 36427c478bd9Sstevel@tonic-gate eof_flag = 1; 36437c478bd9Sstevel@tonic-gate switch (po) { 36447c478bd9Sstevel@tonic-gate 36457c478bd9Sstevel@tonic-gate case 'c': /* print as characters */ 36467c478bd9Sstevel@tonic-gate case 'b': /* or bytes */ 36477c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 36487c478bd9Sstevel@tonic-gate return; 36497c478bd9Sstevel@tonic-gate cptr += offset; 36507c478bd9Sstevel@tonic-gate objsz = CHAR; 36517c478bd9Sstevel@tonic-gate tcount = check_addr(eof_flag, &end, &eof, 0); 36527c478bd9Sstevel@tonic-gate if (tcount) { 36537c478bd9Sstevel@tonic-gate for (i = 0; tcount--; i++) { 36547c478bd9Sstevel@tonic-gate if (i % 16 == 0) { 36557c478bd9Sstevel@tonic-gate if (i) 36567c478bd9Sstevel@tonic-gate printf("\n"); 36577c478bd9Sstevel@tonic-gate index(base); 36587c478bd9Sstevel@tonic-gate } 36597c478bd9Sstevel@tonic-gate if (po == 'c') { 36607c478bd9Sstevel@tonic-gate putf(*cptr++); 36617c478bd9Sstevel@tonic-gate if ((i + 1) % 16) 36627c478bd9Sstevel@tonic-gate printf(" "); 36637c478bd9Sstevel@tonic-gate } else { 36647c478bd9Sstevel@tonic-gate if ((i + 1) % 16 == 0) 36657c478bd9Sstevel@tonic-gate print(*cptr++ & 0377L, 36667c478bd9Sstevel@tonic-gate 2, -2, 0); 36677c478bd9Sstevel@tonic-gate else 36687c478bd9Sstevel@tonic-gate print(*cptr++ & 0377L, 36697c478bd9Sstevel@tonic-gate 4, -2, 0); 36707c478bd9Sstevel@tonic-gate } 36717c478bd9Sstevel@tonic-gate addr += CHAR; 36727c478bd9Sstevel@tonic-gate cur_bytes += CHAR; 36737c478bd9Sstevel@tonic-gate } 36747c478bd9Sstevel@tonic-gate printf("\n"); 36757c478bd9Sstevel@tonic-gate } 36767c478bd9Sstevel@tonic-gate addr -= CHAR; 36777c478bd9Sstevel@tonic-gate erraddr = addr; 36787c478bd9Sstevel@tonic-gate cur_bytes -= CHAR; 36797c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 36807c478bd9Sstevel@tonic-gate if (eof) { 36817c478bd9Sstevel@tonic-gate printf("end of file\n"); 36827c478bd9Sstevel@tonic-gate error++; 36837c478bd9Sstevel@tonic-gate } else if (end) { 36847c478bd9Sstevel@tonic-gate if (type == BLOCK) 36857c478bd9Sstevel@tonic-gate printf("end of block\n"); 36867c478bd9Sstevel@tonic-gate else 36877c478bd9Sstevel@tonic-gate printf("end of fragment\n"); 36887c478bd9Sstevel@tonic-gate error++; 36897c478bd9Sstevel@tonic-gate } 36907c478bd9Sstevel@tonic-gate return; 36917c478bd9Sstevel@tonic-gate 36927c478bd9Sstevel@tonic-gate case 'o': /* print as octal shorts */ 36937c478bd9Sstevel@tonic-gate tbase = OCTAL; 36947c478bd9Sstevel@tonic-gate goto otx; 36957c478bd9Sstevel@tonic-gate case 'd': /* print as decimal shorts */ 36967c478bd9Sstevel@tonic-gate tbase = DECIMAL; 36977c478bd9Sstevel@tonic-gate goto otx; 36987c478bd9Sstevel@tonic-gate case 'x': /* print as hex shorts */ 36997c478bd9Sstevel@tonic-gate tbase = HEX; 37007c478bd9Sstevel@tonic-gate otx: 37017c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 37027c478bd9Sstevel@tonic-gate return; 37037c478bd9Sstevel@tonic-gate taddr = addr; 37047c478bd9Sstevel@tonic-gate addr &= ~(SHORT - 1); 37057c478bd9Sstevel@tonic-gate cur_bytes -= taddr - addr; 37067c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 37077c478bd9Sstevel@tonic-gate /*LINTED*/ 37087c478bd9Sstevel@tonic-gate sptr = (unsigned short *)cptr; 37097c478bd9Sstevel@tonic-gate objsz = SHORT; 37107c478bd9Sstevel@tonic-gate tcount = check_addr(eof_flag, &end, &eof, 0); 37117c478bd9Sstevel@tonic-gate if (tcount) { 37127c478bd9Sstevel@tonic-gate for (i = 0; tcount--; i++) { 37137c478bd9Sstevel@tonic-gate sptr = (unsigned short *)print_check( 37147c478bd9Sstevel@tonic-gate /*LINTED*/ 37157c478bd9Sstevel@tonic-gate (unsigned long *)sptr, 37167c478bd9Sstevel@tonic-gate &tcount, tbase, i); 37177c478bd9Sstevel@tonic-gate switch (po) { 37187c478bd9Sstevel@tonic-gate case 'o': 37197c478bd9Sstevel@tonic-gate printf("%06o ", *sptr++); 37207c478bd9Sstevel@tonic-gate break; 37217c478bd9Sstevel@tonic-gate case 'd': 37227c478bd9Sstevel@tonic-gate printf("%05d ", *sptr++); 37237c478bd9Sstevel@tonic-gate break; 37247c478bd9Sstevel@tonic-gate case 'x': 37257c478bd9Sstevel@tonic-gate printf("%04x ", *sptr++); 37267c478bd9Sstevel@tonic-gate } 37277c478bd9Sstevel@tonic-gate addr += SHORT; 37287c478bd9Sstevel@tonic-gate cur_bytes += SHORT; 37297c478bd9Sstevel@tonic-gate } 37307c478bd9Sstevel@tonic-gate printf("\n"); 37317c478bd9Sstevel@tonic-gate } 37327c478bd9Sstevel@tonic-gate addr -= SHORT; 37337c478bd9Sstevel@tonic-gate erraddr = addr; 37347c478bd9Sstevel@tonic-gate cur_bytes -= SHORT; 37357c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 37367c478bd9Sstevel@tonic-gate if (eof) { 37377c478bd9Sstevel@tonic-gate printf("end of file\n"); 37387c478bd9Sstevel@tonic-gate error++; 37397c478bd9Sstevel@tonic-gate } else if (end) { 37407c478bd9Sstevel@tonic-gate if (type == BLOCK) 37417c478bd9Sstevel@tonic-gate printf("end of block\n"); 37427c478bd9Sstevel@tonic-gate else 37437c478bd9Sstevel@tonic-gate printf("end of fragment\n"); 37447c478bd9Sstevel@tonic-gate error++; 37457c478bd9Sstevel@tonic-gate } 37467c478bd9Sstevel@tonic-gate return; 37477c478bd9Sstevel@tonic-gate 37487c478bd9Sstevel@tonic-gate case 'O': /* print as octal longs */ 37497c478bd9Sstevel@tonic-gate tbase = OCTAL; 37507c478bd9Sstevel@tonic-gate goto OTX; 37517c478bd9Sstevel@tonic-gate case 'D': /* print as decimal longs */ 37527c478bd9Sstevel@tonic-gate tbase = DECIMAL; 37537c478bd9Sstevel@tonic-gate goto OTX; 37547c478bd9Sstevel@tonic-gate case 'X': /* print as hex longs */ 37557c478bd9Sstevel@tonic-gate tbase = HEX; 37567c478bd9Sstevel@tonic-gate OTX: 37577c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 37587c478bd9Sstevel@tonic-gate return; 37597c478bd9Sstevel@tonic-gate taddr = addr; 37607c478bd9Sstevel@tonic-gate addr &= ~(LONG - 1); 37617c478bd9Sstevel@tonic-gate cur_bytes -= taddr - addr; 37627c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 37637c478bd9Sstevel@tonic-gate /*LINTED*/ 37647c478bd9Sstevel@tonic-gate lptr = (unsigned long *)cptr; 37657c478bd9Sstevel@tonic-gate objsz = LONG; 37667c478bd9Sstevel@tonic-gate tcount = check_addr(eof_flag, &end, &eof, 0); 37677c478bd9Sstevel@tonic-gate if (tcount) { 37687c478bd9Sstevel@tonic-gate for (i = 0; tcount--; i++) { 37697c478bd9Sstevel@tonic-gate lptr = print_check(lptr, &tcount, 37707c478bd9Sstevel@tonic-gate tbase, i); 37717c478bd9Sstevel@tonic-gate switch (po) { 37727c478bd9Sstevel@tonic-gate case 'O': 37737c478bd9Sstevel@tonic-gate printf("%011lo ", *lptr++); 37747c478bd9Sstevel@tonic-gate break; 37757c478bd9Sstevel@tonic-gate case 'D': 37767c478bd9Sstevel@tonic-gate printf("%010lu ", *lptr++); 37777c478bd9Sstevel@tonic-gate break; 37787c478bd9Sstevel@tonic-gate case 'X': 37797c478bd9Sstevel@tonic-gate printf("%08lx ", *lptr++); 37807c478bd9Sstevel@tonic-gate } 37817c478bd9Sstevel@tonic-gate addr += LONG; 37827c478bd9Sstevel@tonic-gate cur_bytes += LONG; 37837c478bd9Sstevel@tonic-gate } 37847c478bd9Sstevel@tonic-gate printf("\n"); 37857c478bd9Sstevel@tonic-gate } 37867c478bd9Sstevel@tonic-gate addr -= LONG; 37877c478bd9Sstevel@tonic-gate erraddr = addr; 37887c478bd9Sstevel@tonic-gate cur_bytes -= LONG; 37897c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 37907c478bd9Sstevel@tonic-gate if (eof) { 37917c478bd9Sstevel@tonic-gate printf("end of file\n"); 37927c478bd9Sstevel@tonic-gate error++; 37937c478bd9Sstevel@tonic-gate } else if (end) { 37947c478bd9Sstevel@tonic-gate if (type == BLOCK) 37957c478bd9Sstevel@tonic-gate printf("end of block\n"); 37967c478bd9Sstevel@tonic-gate else 37977c478bd9Sstevel@tonic-gate printf("end of fragment\n"); 37987c478bd9Sstevel@tonic-gate error++; 37997c478bd9Sstevel@tonic-gate } 38007c478bd9Sstevel@tonic-gate return; 38017c478bd9Sstevel@tonic-gate 38027c478bd9Sstevel@tonic-gate default: 38037c478bd9Sstevel@tonic-gate error++; 38047c478bd9Sstevel@tonic-gate printf("no such print option\n"); 38057c478bd9Sstevel@tonic-gate return; 38067c478bd9Sstevel@tonic-gate } 38077c478bd9Sstevel@tonic-gate } else 38087c478bd9Sstevel@tonic-gate switch (po) { 38097c478bd9Sstevel@tonic-gate 38107c478bd9Sstevel@tonic-gate case 'c': /* print as cylinder group */ 38117c478bd9Sstevel@tonic-gate if (type != NUMB) 38127c478bd9Sstevel@tonic-gate if (cur_cgrp + count > fs->fs_ncg) { 38137c478bd9Sstevel@tonic-gate tcount = fs->fs_ncg - cur_cgrp; 38147c478bd9Sstevel@tonic-gate if (!star) 38157c478bd9Sstevel@tonic-gate end++; 38167c478bd9Sstevel@tonic-gate } 38177c478bd9Sstevel@tonic-gate addr &= ~(LONG - 1); 38187c478bd9Sstevel@tonic-gate for (/* void */; tcount--; /* void */) { 38197c478bd9Sstevel@tonic-gate erraddr = addr; 38207c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 38217c478bd9Sstevel@tonic-gate if (type != NUMB) { 38227c478bd9Sstevel@tonic-gate addr = cgtod(fs, cur_cgrp) 38237c478bd9Sstevel@tonic-gate << FRGSHIFT; 38247c478bd9Sstevel@tonic-gate cur_cgrp++; 38257c478bd9Sstevel@tonic-gate } 38267c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) { 38277c478bd9Sstevel@tonic-gate if (cur_cgrp) 38287c478bd9Sstevel@tonic-gate cur_cgrp--; 38297c478bd9Sstevel@tonic-gate return; 38307c478bd9Sstevel@tonic-gate } 38317c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 38327c478bd9Sstevel@tonic-gate /*LINTED*/ 38337c478bd9Sstevel@tonic-gate cg = (struct cg *)cptr; 38347c478bd9Sstevel@tonic-gate if (type == NUMB) { 38357c478bd9Sstevel@tonic-gate cur_cgrp = cg->cg_cgx + 1; 38367c478bd9Sstevel@tonic-gate type = objsz = CGRP; 38377c478bd9Sstevel@tonic-gate if (cur_cgrp + count - 1 > fs->fs_ncg) { 38387c478bd9Sstevel@tonic-gate tcount = fs->fs_ncg - cur_cgrp; 38397c478bd9Sstevel@tonic-gate if (!star) 38407c478bd9Sstevel@tonic-gate end++; 38417c478bd9Sstevel@tonic-gate } 38427c478bd9Sstevel@tonic-gate } 38437c478bd9Sstevel@tonic-gate if (! override && !cg_chkmagic(cg)) { 38447c478bd9Sstevel@tonic-gate printf("invalid cylinder group "); 38457c478bd9Sstevel@tonic-gate printf("magic word\n"); 38467c478bd9Sstevel@tonic-gate if (cur_cgrp) 38477c478bd9Sstevel@tonic-gate cur_cgrp--; 38487c478bd9Sstevel@tonic-gate error++; 38497c478bd9Sstevel@tonic-gate return; 38507c478bd9Sstevel@tonic-gate } 38517c478bd9Sstevel@tonic-gate printcg(cg); 38527c478bd9Sstevel@tonic-gate if (tcount) 38537c478bd9Sstevel@tonic-gate printf("\n"); 38547c478bd9Sstevel@tonic-gate } 38557c478bd9Sstevel@tonic-gate cur_cgrp--; 38567c478bd9Sstevel@tonic-gate if (end) { 38577c478bd9Sstevel@tonic-gate printf("end of cylinder groups\n"); 38587c478bd9Sstevel@tonic-gate error++; 38597c478bd9Sstevel@tonic-gate } 38607c478bd9Sstevel@tonic-gate return; 38617c478bd9Sstevel@tonic-gate 38627c478bd9Sstevel@tonic-gate case 'd': /* print as directories */ 38637c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) 38647c478bd9Sstevel@tonic-gate return; 38657c478bd9Sstevel@tonic-gate if (type == NUMB) { 38667c478bd9Sstevel@tonic-gate if (fragoff(fs, addr)) { 38677c478bd9Sstevel@tonic-gate printf("address must be at the "); 38687c478bd9Sstevel@tonic-gate printf("beginning of a fragment\n"); 38697c478bd9Sstevel@tonic-gate error++; 38707c478bd9Sstevel@tonic-gate return; 38717c478bd9Sstevel@tonic-gate } 38727c478bd9Sstevel@tonic-gate bod_addr = addr; 38737c478bd9Sstevel@tonic-gate type = FRAGMENT; 38747c478bd9Sstevel@tonic-gate dirslot = 0; 38757c478bd9Sstevel@tonic-gate cur_bytes = 0; 38767c478bd9Sstevel@tonic-gate blocksize = FRGSIZE; 38777c478bd9Sstevel@tonic-gate filesize = FRGSIZE * 2; 38787c478bd9Sstevel@tonic-gate } 38797c478bd9Sstevel@tonic-gate cptr += offset; 38807c478bd9Sstevel@tonic-gate objsz = DIRECTORY; 38817c478bd9Sstevel@tonic-gate while (tcount-- && cur_bytes < filesize && 38827c478bd9Sstevel@tonic-gate cur_bytes < blocksize && !bcomp(addr)) { 38837c478bd9Sstevel@tonic-gate /*LINTED*/ 38847c478bd9Sstevel@tonic-gate dirp = (struct direct *)cptr; 38857c478bd9Sstevel@tonic-gate tinode = dirp->d_ino; 38867c478bd9Sstevel@tonic-gate printf("i#: "); 38877c478bd9Sstevel@tonic-gate if (tinode == 0) 38887c478bd9Sstevel@tonic-gate printf("free\t"); 38897c478bd9Sstevel@tonic-gate else 38907c478bd9Sstevel@tonic-gate print(tinode, 12, -8, 0); 38917c478bd9Sstevel@tonic-gate printf("%s\n", &dirp->d_name[0]); 38927c478bd9Sstevel@tonic-gate erraddr = addr; 38937c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 38947c478bd9Sstevel@tonic-gate addr += dirp->d_reclen; 38957c478bd9Sstevel@tonic-gate cptr += dirp->d_reclen; 38967c478bd9Sstevel@tonic-gate cur_bytes += dirp->d_reclen; 38977c478bd9Sstevel@tonic-gate dirslot++; 38987c478bd9Sstevel@tonic-gate stringsize = STRINGSIZE(dirp); 38997c478bd9Sstevel@tonic-gate } 39007c478bd9Sstevel@tonic-gate addr = erraddr; 39017c478bd9Sstevel@tonic-gate cur_dir = addr; 39027c478bd9Sstevel@tonic-gate cur_bytes = errcur_bytes; 39037c478bd9Sstevel@tonic-gate dirslot--; 39047c478bd9Sstevel@tonic-gate if (tcount >= 0 && !star) { 39057c478bd9Sstevel@tonic-gate switch (type) { 39067c478bd9Sstevel@tonic-gate case FRAGMENT: 39077c478bd9Sstevel@tonic-gate printf("end of fragment\n"); 39087c478bd9Sstevel@tonic-gate break; 39097c478bd9Sstevel@tonic-gate case BLOCK: 39107c478bd9Sstevel@tonic-gate printf("end of block\n"); 39117c478bd9Sstevel@tonic-gate break; 39127c478bd9Sstevel@tonic-gate default: 39137c478bd9Sstevel@tonic-gate printf("end of directory\n"); 39147c478bd9Sstevel@tonic-gate } 39157c478bd9Sstevel@tonic-gate error++; 39167c478bd9Sstevel@tonic-gate } else 39177c478bd9Sstevel@tonic-gate error = 0; 39187c478bd9Sstevel@tonic-gate return; 39197c478bd9Sstevel@tonic-gate 39207c478bd9Sstevel@tonic-gate case 'i': /* print as inodes */ 39217c478bd9Sstevel@tonic-gate /*LINTED*/ 39227c478bd9Sstevel@tonic-gate if ((ip = (struct dinode *)getblk(addr)) == 0) 39237c478bd9Sstevel@tonic-gate return; 39247c478bd9Sstevel@tonic-gate for (i = 1; i < fs->fs_ncg; i++) 39257c478bd9Sstevel@tonic-gate if (addr < (cgimin(fs, i) << FRGSHIFT)) 39267c478bd9Sstevel@tonic-gate break; 39277c478bd9Sstevel@tonic-gate i--; 39287c478bd9Sstevel@tonic-gate offset /= INODE; 39297c478bd9Sstevel@tonic-gate temp = (addr - (cgimin(fs, i) << FRGSHIFT)) >> FRGSHIFT; 39307c478bd9Sstevel@tonic-gate temp = (i * fs->fs_ipg) + fragstoblks(fs, temp) * 39317c478bd9Sstevel@tonic-gate INOPB(fs) + offset; 39327c478bd9Sstevel@tonic-gate if (count + offset > INOPB(fs)) { 39337c478bd9Sstevel@tonic-gate tcount = INOPB(fs) - offset; 39347c478bd9Sstevel@tonic-gate if (!star) 39357c478bd9Sstevel@tonic-gate end++; 39367c478bd9Sstevel@tonic-gate } 39377c478bd9Sstevel@tonic-gate objsz = INODE; 39387c478bd9Sstevel@tonic-gate ip += offset; 39397c478bd9Sstevel@tonic-gate for (i = 0; tcount--; ip++, temp++) { 39407c478bd9Sstevel@tonic-gate if ((mode = icheck(addr)) == 0) 39417c478bd9Sstevel@tonic-gate if (!override) 39427c478bd9Sstevel@tonic-gate continue; 39437c478bd9Sstevel@tonic-gate p = " ugtrwxrwxrwx"; 39447c478bd9Sstevel@tonic-gate 39457c478bd9Sstevel@tonic-gate switch (mode & IFMT) { 39467c478bd9Sstevel@tonic-gate case IFDIR: 39477c478bd9Sstevel@tonic-gate c = 'd'; 39487c478bd9Sstevel@tonic-gate break; 39497c478bd9Sstevel@tonic-gate case IFCHR: 39507c478bd9Sstevel@tonic-gate c = 'c'; 39517c478bd9Sstevel@tonic-gate break; 39527c478bd9Sstevel@tonic-gate case IFBLK: 39537c478bd9Sstevel@tonic-gate c = 'b'; 39547c478bd9Sstevel@tonic-gate break; 39557c478bd9Sstevel@tonic-gate case IFREG: 39567c478bd9Sstevel@tonic-gate c = '-'; 39577c478bd9Sstevel@tonic-gate break; 39587c478bd9Sstevel@tonic-gate case IFLNK: 39597c478bd9Sstevel@tonic-gate c = 'l'; 39607c478bd9Sstevel@tonic-gate break; 39617c478bd9Sstevel@tonic-gate case IFSOCK: 39627c478bd9Sstevel@tonic-gate c = 's'; 39637c478bd9Sstevel@tonic-gate break; 39647c478bd9Sstevel@tonic-gate case IFSHAD: 39657c478bd9Sstevel@tonic-gate c = 'S'; 39667c478bd9Sstevel@tonic-gate break; 39677c478bd9Sstevel@tonic-gate case IFATTRDIR: 39687c478bd9Sstevel@tonic-gate c = 'A'; 39697c478bd9Sstevel@tonic-gate break; 39707c478bd9Sstevel@tonic-gate default: 39717c478bd9Sstevel@tonic-gate c = '?'; 39727c478bd9Sstevel@tonic-gate if (!override) 39737c478bd9Sstevel@tonic-gate goto empty; 39747c478bd9Sstevel@tonic-gate 39757c478bd9Sstevel@tonic-gate } 39767c478bd9Sstevel@tonic-gate printf("i#: "); 39777c478bd9Sstevel@tonic-gate print(temp, 12, -8, 0); 39787c478bd9Sstevel@tonic-gate printf(" md: "); 39797c478bd9Sstevel@tonic-gate printf("%c", c); 39807c478bd9Sstevel@tonic-gate for (mode = mode << 4; *++p; mode = mode << 1) { 39817c478bd9Sstevel@tonic-gate if (mode & IFREG) 39827c478bd9Sstevel@tonic-gate printf("%c", *p); 39837c478bd9Sstevel@tonic-gate else 39847c478bd9Sstevel@tonic-gate printf("-"); 39857c478bd9Sstevel@tonic-gate } 39867c478bd9Sstevel@tonic-gate printf(" uid: "); 39877c478bd9Sstevel@tonic-gate print(ip->di_uid, 8, -4, 0); 39887c478bd9Sstevel@tonic-gate printf(" gid: "); 39897c478bd9Sstevel@tonic-gate print(ip->di_gid, 8, -4, 0); 39907c478bd9Sstevel@tonic-gate printf("\n"); 39917c478bd9Sstevel@tonic-gate printf("ln: "); 39927c478bd9Sstevel@tonic-gate print((long)ip->di_nlink, 8, -4, 0); 39937c478bd9Sstevel@tonic-gate printf(" bs: "); 39947c478bd9Sstevel@tonic-gate print(ip->di_blocks, 12, -8, 0); 39957c478bd9Sstevel@tonic-gate printf("c_flags : "); 39967c478bd9Sstevel@tonic-gate print(ip->di_cflags, 12, -8, 0); 399785651ed9SJohn.Zolnowsky@Sun.COM printf(" sz : "); 39987c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE 39997c478bd9Sstevel@tonic-gate printll(ip->di_size, 20, -16, 0); 40007c478bd9Sstevel@tonic-gate #else /* !_LARGEFILE64_SOURCE */ 40017c478bd9Sstevel@tonic-gate print(ip->di_size, 12, -8, 0); 40027c478bd9Sstevel@tonic-gate #endif /* _LARGEFILE64_SOURCE */ 40037c478bd9Sstevel@tonic-gate if (ip->di_shadow) { 40047c478bd9Sstevel@tonic-gate printf(" si: "); 40057c478bd9Sstevel@tonic-gate print(ip->di_shadow, 12, -8, 0); 40067c478bd9Sstevel@tonic-gate } 40077c478bd9Sstevel@tonic-gate printf("\n"); 40087c478bd9Sstevel@tonic-gate if (ip->di_oeftflag) { 40097c478bd9Sstevel@tonic-gate printf("ai: "); 40107c478bd9Sstevel@tonic-gate print(ip->di_oeftflag, 12, -8, 0); 40117c478bd9Sstevel@tonic-gate printf("\n"); 40127c478bd9Sstevel@tonic-gate } 40137c478bd9Sstevel@tonic-gate printf("\n"); 40147c478bd9Sstevel@tonic-gate switch (ip->di_mode & IFMT) { 40157c478bd9Sstevel@tonic-gate case IFBLK: 40167c478bd9Sstevel@tonic-gate case IFCHR: 40177c478bd9Sstevel@tonic-gate printf("maj: "); 40187c478bd9Sstevel@tonic-gate print(major(ip->di_ordev), 4, -2, 0); 40197c478bd9Sstevel@tonic-gate printf(" min: "); 40207c478bd9Sstevel@tonic-gate print(minor(ip->di_ordev), 4, -2, 0); 40217c478bd9Sstevel@tonic-gate printf("\n"); 40227c478bd9Sstevel@tonic-gate break; 40237c478bd9Sstevel@tonic-gate default: 40247c478bd9Sstevel@tonic-gate /* 40257c478bd9Sstevel@tonic-gate * only display blocks below the 40267c478bd9Sstevel@tonic-gate * current file size 40277c478bd9Sstevel@tonic-gate */ 40287c478bd9Sstevel@tonic-gate curoff = 0LL; 40297c478bd9Sstevel@tonic-gate for (i = 0; i < NDADDR; ) { 40307c478bd9Sstevel@tonic-gate if (ip->di_size <= curoff) 40317c478bd9Sstevel@tonic-gate break; 40327c478bd9Sstevel@tonic-gate printf("db#%x: ", i); 40337c478bd9Sstevel@tonic-gate print(ip->di_db[i], 11, -8, 0); 40347c478bd9Sstevel@tonic-gate 40357c478bd9Sstevel@tonic-gate if (++i % 4 == 0) 40367c478bd9Sstevel@tonic-gate printf("\n"); 40377c478bd9Sstevel@tonic-gate else 40387c478bd9Sstevel@tonic-gate printf(" "); 40397c478bd9Sstevel@tonic-gate curoff += fs->fs_bsize; 40407c478bd9Sstevel@tonic-gate } 40417c478bd9Sstevel@tonic-gate if (i % 4) 40427c478bd9Sstevel@tonic-gate printf("\n"); 40437c478bd9Sstevel@tonic-gate 40447c478bd9Sstevel@tonic-gate /* 40457c478bd9Sstevel@tonic-gate * curioff keeps track of the number 40467c478bd9Sstevel@tonic-gate * of bytes covered by each indirect 40477c478bd9Sstevel@tonic-gate * pointer in the inode, and is added 40487c478bd9Sstevel@tonic-gate * to curoff each time to get the 40497c478bd9Sstevel@tonic-gate * actual offset into the file. 40507c478bd9Sstevel@tonic-gate */ 40517c478bd9Sstevel@tonic-gate curioff = fs->fs_bsize * 40527c478bd9Sstevel@tonic-gate (fs->fs_bsize / sizeof (daddr_t)); 40537c478bd9Sstevel@tonic-gate for (i = 0; i < NIADDR; i++) { 40547c478bd9Sstevel@tonic-gate if (ip->di_size <= curoff) 40557c478bd9Sstevel@tonic-gate break; 40567c478bd9Sstevel@tonic-gate printf("ib#%x: ", i); 40577c478bd9Sstevel@tonic-gate print(ip->di_ib[i], 11, -8, 0); 40587c478bd9Sstevel@tonic-gate printf(" "); 40597c478bd9Sstevel@tonic-gate curoff += curioff; 40607c478bd9Sstevel@tonic-gate curioff *= (fs->fs_bsize / 40617c478bd9Sstevel@tonic-gate sizeof (daddr_t)); 40627c478bd9Sstevel@tonic-gate } 40637c478bd9Sstevel@tonic-gate if (i) 40647c478bd9Sstevel@tonic-gate printf("\n"); 40657c478bd9Sstevel@tonic-gate break; 40667c478bd9Sstevel@tonic-gate } 40677c478bd9Sstevel@tonic-gate if (count == 1) { 40687c478bd9Sstevel@tonic-gate time_t t; 40697c478bd9Sstevel@tonic-gate 40707c478bd9Sstevel@tonic-gate t = ip->di_atime; 40717c478bd9Sstevel@tonic-gate printf("\taccessed: %s", ctime(&t)); 40727c478bd9Sstevel@tonic-gate t = ip->di_mtime; 40737c478bd9Sstevel@tonic-gate printf("\tmodified: %s", ctime(&t)); 40747c478bd9Sstevel@tonic-gate t = ip->di_ctime; 40757c478bd9Sstevel@tonic-gate printf("\tcreated : %s", ctime(&t)); 40767c478bd9Sstevel@tonic-gate } 40777c478bd9Sstevel@tonic-gate if (tcount) 40787c478bd9Sstevel@tonic-gate printf("\n"); 40797c478bd9Sstevel@tonic-gate empty: 40807c478bd9Sstevel@tonic-gate if (c == '?' && !override) { 40817c478bd9Sstevel@tonic-gate printf("i#: "); 40827c478bd9Sstevel@tonic-gate print(temp, 12, -8, 0); 40837c478bd9Sstevel@tonic-gate printf(" is unallocated\n"); 40847c478bd9Sstevel@tonic-gate if (count != 1) 40857c478bd9Sstevel@tonic-gate printf("\n"); 40867c478bd9Sstevel@tonic-gate } 40877c478bd9Sstevel@tonic-gate cur_ino = erraddr = addr; 40887c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 40897c478bd9Sstevel@tonic-gate cur_inum++; 40907c478bd9Sstevel@tonic-gate addr = addr + INODE; 40917c478bd9Sstevel@tonic-gate } 40927c478bd9Sstevel@tonic-gate addr = erraddr; 40937c478bd9Sstevel@tonic-gate cur_bytes = errcur_bytes; 40947c478bd9Sstevel@tonic-gate cur_inum--; 40957c478bd9Sstevel@tonic-gate if (end) { 40967c478bd9Sstevel@tonic-gate printf("end of block\n"); 40977c478bd9Sstevel@tonic-gate error++; 40987c478bd9Sstevel@tonic-gate } 40997c478bd9Sstevel@tonic-gate return; 41007c478bd9Sstevel@tonic-gate 41017c478bd9Sstevel@tonic-gate case 's': /* print as super block */ 41027c478bd9Sstevel@tonic-gate if (cur_cgrp == -1) { 41037c478bd9Sstevel@tonic-gate addr = SBLOCK * DEV_BSIZE; 41047c478bd9Sstevel@tonic-gate type = NUMB; 41057c478bd9Sstevel@tonic-gate } 41067c478bd9Sstevel@tonic-gate addr &= ~(LONG - 1); 41077c478bd9Sstevel@tonic-gate if (type != NUMB) 41087c478bd9Sstevel@tonic-gate if (cur_cgrp + count > fs->fs_ncg) { 41097c478bd9Sstevel@tonic-gate tcount = fs->fs_ncg - cur_cgrp; 41107c478bd9Sstevel@tonic-gate if (!star) 41117c478bd9Sstevel@tonic-gate end++; 41127c478bd9Sstevel@tonic-gate } 41137c478bd9Sstevel@tonic-gate for (/* void */; tcount--; /* void */) { 41147c478bd9Sstevel@tonic-gate erraddr = addr; 41157c478bd9Sstevel@tonic-gate cur_bytes = errcur_bytes; 41167c478bd9Sstevel@tonic-gate if (type != NUMB) { 41177c478bd9Sstevel@tonic-gate addr = cgsblock(fs, cur_cgrp) 41187c478bd9Sstevel@tonic-gate << FRGSHIFT; 41197c478bd9Sstevel@tonic-gate cur_cgrp++; 41207c478bd9Sstevel@tonic-gate } 41217c478bd9Sstevel@tonic-gate if ((cptr = getblk(addr)) == 0) { 41227c478bd9Sstevel@tonic-gate if (cur_cgrp) 41237c478bd9Sstevel@tonic-gate cur_cgrp--; 41247c478bd9Sstevel@tonic-gate return; 41257c478bd9Sstevel@tonic-gate } 41267c478bd9Sstevel@tonic-gate cptr += blkoff(fs, addr); 41277c478bd9Sstevel@tonic-gate /*LINTED*/ 41287c478bd9Sstevel@tonic-gate sb = (struct fs *)cptr; 41297c478bd9Sstevel@tonic-gate if (type == NUMB) { 41307c478bd9Sstevel@tonic-gate for (i = 0; i < fs->fs_ncg; i++) 41317c478bd9Sstevel@tonic-gate if (addr == cgsblock(fs, i) << 41327c478bd9Sstevel@tonic-gate FRGSHIFT) 41337c478bd9Sstevel@tonic-gate break; 41347c478bd9Sstevel@tonic-gate if (i == fs->fs_ncg) 41357c478bd9Sstevel@tonic-gate cur_cgrp = 0; 41367c478bd9Sstevel@tonic-gate else 41377c478bd9Sstevel@tonic-gate cur_cgrp = i + 1; 41387c478bd9Sstevel@tonic-gate type = objsz = SB; 41397c478bd9Sstevel@tonic-gate if (cur_cgrp + count - 1 > fs->fs_ncg) { 41407c478bd9Sstevel@tonic-gate tcount = fs->fs_ncg - cur_cgrp; 41417c478bd9Sstevel@tonic-gate if (!star) 41427c478bd9Sstevel@tonic-gate end++; 41437c478bd9Sstevel@tonic-gate } 41447c478bd9Sstevel@tonic-gate } 41457c478bd9Sstevel@tonic-gate if ((sb->fs_magic != FS_MAGIC) && 41467c478bd9Sstevel@tonic-gate (sb->fs_magic != MTB_UFS_MAGIC)) { 41477c478bd9Sstevel@tonic-gate cur_cgrp = 0; 41487c478bd9Sstevel@tonic-gate if (!override) { 41497c478bd9Sstevel@tonic-gate printf("invalid super block "); 41507c478bd9Sstevel@tonic-gate printf("magic word\n"); 41517c478bd9Sstevel@tonic-gate cur_cgrp--; 41527c478bd9Sstevel@tonic-gate error++; 41537c478bd9Sstevel@tonic-gate return; 41547c478bd9Sstevel@tonic-gate } 41557c478bd9Sstevel@tonic-gate } 41566451fdbcSvsakar if (sb->fs_magic == FS_MAGIC && 41576451fdbcSvsakar (sb->fs_version != 41586451fdbcSvsakar UFS_EFISTYLE4NONEFI_VERSION_2 && 41596451fdbcSvsakar sb->fs_version != UFS_VERSION_MIN)) { 41606451fdbcSvsakar cur_cgrp = 0; 41616451fdbcSvsakar if (!override) { 41626451fdbcSvsakar printf("invalid super block "); 41636451fdbcSvsakar printf("version number\n"); 41646451fdbcSvsakar cur_cgrp--; 41656451fdbcSvsakar error++; 41666451fdbcSvsakar return; 41676451fdbcSvsakar } 41686451fdbcSvsakar } 41697c478bd9Sstevel@tonic-gate if (sb->fs_magic == MTB_UFS_MAGIC && 41707c478bd9Sstevel@tonic-gate (sb->fs_version > MTB_UFS_VERSION_1 || 41717c478bd9Sstevel@tonic-gate sb->fs_version < MTB_UFS_VERSION_MIN)) { 41727c478bd9Sstevel@tonic-gate cur_cgrp = 0; 41737c478bd9Sstevel@tonic-gate if (!override) { 41747c478bd9Sstevel@tonic-gate printf("invalid super block "); 41756451fdbcSvsakar printf("version number\n"); 41767c478bd9Sstevel@tonic-gate cur_cgrp--; 41777c478bd9Sstevel@tonic-gate error++; 41787c478bd9Sstevel@tonic-gate return; 41797c478bd9Sstevel@tonic-gate } 41807c478bd9Sstevel@tonic-gate } 41817c478bd9Sstevel@tonic-gate if (cur_cgrp == 0) 41827c478bd9Sstevel@tonic-gate printf("\tsuper block:\n"); 41837c478bd9Sstevel@tonic-gate else { 41847c478bd9Sstevel@tonic-gate printf("\tsuper block in cylinder "); 41857c478bd9Sstevel@tonic-gate printf("group "); 41867c478bd9Sstevel@tonic-gate print(cur_cgrp - 1, 0, 0, 0); 41877c478bd9Sstevel@tonic-gate printf(":\n"); 41887c478bd9Sstevel@tonic-gate } 41897c478bd9Sstevel@tonic-gate printsb(sb); 41907c478bd9Sstevel@tonic-gate if (tcount) 41917c478bd9Sstevel@tonic-gate printf("\n"); 41927c478bd9Sstevel@tonic-gate } 41937c478bd9Sstevel@tonic-gate cur_cgrp--; 41947c478bd9Sstevel@tonic-gate if (end) { 41957c478bd9Sstevel@tonic-gate printf("end of super blocks\n"); 41967c478bd9Sstevel@tonic-gate error++; 41977c478bd9Sstevel@tonic-gate } 41987c478bd9Sstevel@tonic-gate return; 41997c478bd9Sstevel@tonic-gate 42007c478bd9Sstevel@tonic-gate case 'S': /* print as shadow data */ 42017c478bd9Sstevel@tonic-gate if (type == NUMB) { 42027c478bd9Sstevel@tonic-gate type = FRAGMENT; 42037c478bd9Sstevel@tonic-gate cur_shad = 0; 42047c478bd9Sstevel@tonic-gate cur_bytes = fragoff(fs, addr); 42057c478bd9Sstevel@tonic-gate bod_addr = addr - cur_bytes; 42067c478bd9Sstevel@tonic-gate /* no more than two fragments */ 42077c478bd9Sstevel@tonic-gate filesize = fragroundup(fs, 42087c478bd9Sstevel@tonic-gate bod_addr + FRGSIZE + 1); 42097c478bd9Sstevel@tonic-gate } 42107c478bd9Sstevel@tonic-gate objsz = SHADOW_DATA; 42117c478bd9Sstevel@tonic-gate while (tcount-- && 42127c478bd9Sstevel@tonic-gate (cur_bytes + SHADOW_DATA) <= filesize && 42137c478bd9Sstevel@tonic-gate (type != SHADOW_DATA || 42147c478bd9Sstevel@tonic-gate (cur_bytes + SHADOW_DATA)) <= blocksize) { 42157c478bd9Sstevel@tonic-gate /*LINTED*/ 42167c478bd9Sstevel@tonic-gate struct ufs_fsd fsd; 42177c478bd9Sstevel@tonic-gate long tcur_bytes; 42187c478bd9Sstevel@tonic-gate 42197c478bd9Sstevel@tonic-gate taddr = addr; 42207c478bd9Sstevel@tonic-gate tcur_bytes = cur_bytes; 42217c478bd9Sstevel@tonic-gate index(base); 42227c478bd9Sstevel@tonic-gate getshadowdata((long *)&fsd, LONG + LONG); 42237c478bd9Sstevel@tonic-gate printf(" type: "); 42247c478bd9Sstevel@tonic-gate print((long)fsd.fsd_type, 8, -8, 0); 42257c478bd9Sstevel@tonic-gate printf(" size: "); 42267c478bd9Sstevel@tonic-gate print((long)fsd.fsd_size, 8, -8, 0); 42277c478bd9Sstevel@tonic-gate tbase = fsd.fsd_size - LONG - LONG; 42287c478bd9Sstevel@tonic-gate if (tbase > 256) 42297c478bd9Sstevel@tonic-gate tbase = 256; 42307c478bd9Sstevel@tonic-gate for (i = 0; i < tbase; i++) { 42317c478bd9Sstevel@tonic-gate if (i % LONG == 0) { 42327c478bd9Sstevel@tonic-gate if (i % 16 == 0) { 42337c478bd9Sstevel@tonic-gate printf("\n"); 42347c478bd9Sstevel@tonic-gate index(base); 42357c478bd9Sstevel@tonic-gate } else 42367c478bd9Sstevel@tonic-gate printf(" "); 42377c478bd9Sstevel@tonic-gate getshadowdata(&temp, LONG); 42387c478bd9Sstevel@tonic-gate p = (char *)&temp; 42397c478bd9Sstevel@tonic-gate } else 42407c478bd9Sstevel@tonic-gate printf(" "); 42417c478bd9Sstevel@tonic-gate printf("%02x", (int)(*p++ & 0377L)); 42427c478bd9Sstevel@tonic-gate } 42437c478bd9Sstevel@tonic-gate printf("\n"); 42447c478bd9Sstevel@tonic-gate addr = taddr; 42457c478bd9Sstevel@tonic-gate cur_bytes = tcur_bytes; 42467c478bd9Sstevel@tonic-gate erraddr = addr; 42477c478bd9Sstevel@tonic-gate errcur_bytes = cur_bytes; 42487c478bd9Sstevel@tonic-gate addr += FSD_RECSZ((&fsd), fsd.fsd_size); 42497c478bd9Sstevel@tonic-gate cur_bytes += FSD_RECSZ((&fsd), fsd.fsd_size); 42507c478bd9Sstevel@tonic-gate cur_shad++; 42517c478bd9Sstevel@tonic-gate syncshadowscan(0); 42527c478bd9Sstevel@tonic-gate } 42537c478bd9Sstevel@tonic-gate addr = erraddr; 42547c478bd9Sstevel@tonic-gate cur_bytes = errcur_bytes; 42557c478bd9Sstevel@tonic-gate cur_shad--; 42567c478bd9Sstevel@tonic-gate if (tcount >= 0 && !star) { 42577c478bd9Sstevel@tonic-gate switch (type) { 42587c478bd9Sstevel@tonic-gate case FRAGMENT: 42597c478bd9Sstevel@tonic-gate printf("end of fragment\n"); 42607c478bd9Sstevel@tonic-gate break; 42617c478bd9Sstevel@tonic-gate default: 42627c478bd9Sstevel@tonic-gate printf("end of shadow data\n"); 42637c478bd9Sstevel@tonic-gate } 42647c478bd9Sstevel@tonic-gate error++; 42657c478bd9Sstevel@tonic-gate } else 42667c478bd9Sstevel@tonic-gate error = 0; 42677c478bd9Sstevel@tonic-gate return; 42687c478bd9Sstevel@tonic-gate default: 42697c478bd9Sstevel@tonic-gate error++; 42707c478bd9Sstevel@tonic-gate printf("no such print option\n"); 42717c478bd9Sstevel@tonic-gate return; 42727c478bd9Sstevel@tonic-gate } 42737c478bd9Sstevel@tonic-gate } 42747c478bd9Sstevel@tonic-gate 42757c478bd9Sstevel@tonic-gate /* 42767c478bd9Sstevel@tonic-gate * valid_addr - call check_addr to validate the current address. 42777c478bd9Sstevel@tonic-gate */ 42787c478bd9Sstevel@tonic-gate static int 42797c478bd9Sstevel@tonic-gate valid_addr() 42807c478bd9Sstevel@tonic-gate { 42817c478bd9Sstevel@tonic-gate short end = 0, eof = 0; 42827c478bd9Sstevel@tonic-gate long tcount = count; 42837c478bd9Sstevel@tonic-gate 42847c478bd9Sstevel@tonic-gate if (!trapped) 42857c478bd9Sstevel@tonic-gate return (1); 42867c478bd9Sstevel@tonic-gate if (cur_bytes < 0) { 42877c478bd9Sstevel@tonic-gate cur_bytes = 0; 42887c478bd9Sstevel@tonic-gate if (blocksize > filesize) { 42897c478bd9Sstevel@tonic-gate printf("beginning of file\n"); 42907c478bd9Sstevel@tonic-gate } else { 42917c478bd9Sstevel@tonic-gate if (type == BLOCK) 42927c478bd9Sstevel@tonic-gate printf("beginning of block\n"); 42937c478bd9Sstevel@tonic-gate else 42947c478bd9Sstevel@tonic-gate printf("beginning of fragment\n"); 42957c478bd9Sstevel@tonic-gate } 42967c478bd9Sstevel@tonic-gate error++; 42977c478bd9Sstevel@tonic-gate return (0); 42987c478bd9Sstevel@tonic-gate } 42997c478bd9Sstevel@tonic-gate count = 1; 43007c478bd9Sstevel@tonic-gate (void) check_addr(1, &end, &eof, (filesize < blocksize)); 43017c478bd9Sstevel@tonic-gate count = tcount; 43027c478bd9Sstevel@tonic-gate if (eof) { 43037c478bd9Sstevel@tonic-gate printf("end of file\n"); 43047c478bd9Sstevel@tonic-gate error++; 43057c478bd9Sstevel@tonic-gate return (0); 43067c478bd9Sstevel@tonic-gate } 43077c478bd9Sstevel@tonic-gate if (end == 2) { 43087c478bd9Sstevel@tonic-gate if (erraddr > addr) { 43097c478bd9Sstevel@tonic-gate if (type == BLOCK) 43107c478bd9Sstevel@tonic-gate printf("beginning of block\n"); 43117c478bd9Sstevel@tonic-gate else 43127c478bd9Sstevel@tonic-gate printf("beginning of fragment\n"); 43137c478bd9Sstevel@tonic-gate error++; 43147c478bd9Sstevel@tonic-gate return (0); 43157c478bd9Sstevel@tonic-gate } 43167c478bd9Sstevel@tonic-gate } 43177c478bd9Sstevel@tonic-gate if (end) { 43187c478bd9Sstevel@tonic-gate if (type == BLOCK) 43197c478bd9Sstevel@tonic-gate printf("end of block\n"); 43207c478bd9Sstevel@tonic-gate else 43217c478bd9Sstevel@tonic-gate printf("end of fragment\n"); 43227c478bd9Sstevel@tonic-gate error++; 43237c478bd9Sstevel@tonic-gate return (0); 43247c478bd9Sstevel@tonic-gate } 43257c478bd9Sstevel@tonic-gate return (1); 43267c478bd9Sstevel@tonic-gate } 43277c478bd9Sstevel@tonic-gate 43287c478bd9Sstevel@tonic-gate /* 43297c478bd9Sstevel@tonic-gate * check_addr - check if the address crosses the end of block or 43307c478bd9Sstevel@tonic-gate * end of file. Return the proper count. 43317c478bd9Sstevel@tonic-gate */ 43327c478bd9Sstevel@tonic-gate static int 4333d1a180b0Smaheshvs check_addr(short eof_flag, short *end, short *eof, short keep_on) 43347c478bd9Sstevel@tonic-gate { 43357c478bd9Sstevel@tonic-gate long temp, tcount = count, tcur_bytes = cur_bytes; 43367c478bd9Sstevel@tonic-gate u_offset_t taddr = addr; 43377c478bd9Sstevel@tonic-gate 43387c478bd9Sstevel@tonic-gate if (bcomp(addr + count * objsz - 1) || 43397c478bd9Sstevel@tonic-gate (keep_on && taddr < (bmap(cur_block) << FRGSHIFT))) { 43407c478bd9Sstevel@tonic-gate error = 0; 43417c478bd9Sstevel@tonic-gate addr = taddr; 43427c478bd9Sstevel@tonic-gate cur_bytes = tcur_bytes; 43437c478bd9Sstevel@tonic-gate if (keep_on) { 43447c478bd9Sstevel@tonic-gate if (addr < erraddr) { 43457c478bd9Sstevel@tonic-gate if (cur_bytes < 0) { 43467c478bd9Sstevel@tonic-gate (*end) = 2; 43477c478bd9Sstevel@tonic-gate return (0); /* Value ignored */ 43487c478bd9Sstevel@tonic-gate } 43497c478bd9Sstevel@tonic-gate temp = cur_block - lblkno(fs, cur_bytes); 43507c478bd9Sstevel@tonic-gate cur_block -= temp; 43517c478bd9Sstevel@tonic-gate if ((addr = bmap(cur_block) << FRGSHIFT) == 0) { 43527c478bd9Sstevel@tonic-gate cur_block += temp; 43537c478bd9Sstevel@tonic-gate return (0); /* Value ignored */ 43547c478bd9Sstevel@tonic-gate } 43557c478bd9Sstevel@tonic-gate temp = tcur_bytes - cur_bytes; 43567c478bd9Sstevel@tonic-gate addr += temp; 43577c478bd9Sstevel@tonic-gate cur_bytes += temp; 43587c478bd9Sstevel@tonic-gate return (0); /* Value ignored */ 43597c478bd9Sstevel@tonic-gate } else { 43607c478bd9Sstevel@tonic-gate if (cur_bytes >= filesize) { 43617c478bd9Sstevel@tonic-gate (*eof)++; 43627c478bd9Sstevel@tonic-gate return (0); /* Value ignored */ 43637c478bd9Sstevel@tonic-gate } 43647c478bd9Sstevel@tonic-gate temp = lblkno(fs, cur_bytes) - cur_block; 43657c478bd9Sstevel@tonic-gate cur_block += temp; 43667c478bd9Sstevel@tonic-gate if ((addr = bmap(cur_block) << FRGSHIFT) == 0) { 43677c478bd9Sstevel@tonic-gate cur_block -= temp; 43687c478bd9Sstevel@tonic-gate return (0); /* Value ignored */ 43697c478bd9Sstevel@tonic-gate } 43707c478bd9Sstevel@tonic-gate temp = tcur_bytes - cur_bytes; 43717c478bd9Sstevel@tonic-gate addr += temp; 43727c478bd9Sstevel@tonic-gate cur_bytes += temp; 43737c478bd9Sstevel@tonic-gate return (0); /* Value ignored */ 43747c478bd9Sstevel@tonic-gate } 43757c478bd9Sstevel@tonic-gate } 43767c478bd9Sstevel@tonic-gate tcount = (blkroundup(fs, addr+1)-addr) / objsz; 43777c478bd9Sstevel@tonic-gate if (!star) 43787c478bd9Sstevel@tonic-gate (*end) = 2; 43797c478bd9Sstevel@tonic-gate } 43807c478bd9Sstevel@tonic-gate addr = taddr; 43817c478bd9Sstevel@tonic-gate cur_bytes = tcur_bytes; 43827c478bd9Sstevel@tonic-gate if (eof_flag) { 43837c478bd9Sstevel@tonic-gate if (blocksize > filesize) { 43847c478bd9Sstevel@tonic-gate if (cur_bytes >= filesize) { 43857c478bd9Sstevel@tonic-gate tcount = 0; 43867c478bd9Sstevel@tonic-gate (*eof)++; 43877c478bd9Sstevel@tonic-gate } else if (tcount > (filesize - cur_bytes) / objsz) { 43887c478bd9Sstevel@tonic-gate tcount = (filesize - cur_bytes) / objsz; 43897c478bd9Sstevel@tonic-gate if (!star || tcount == 0) 43907c478bd9Sstevel@tonic-gate (*eof)++; 43917c478bd9Sstevel@tonic-gate } 43927c478bd9Sstevel@tonic-gate } else { 43937c478bd9Sstevel@tonic-gate if (cur_bytes >= blocksize) { 43947c478bd9Sstevel@tonic-gate tcount = 0; 43957c478bd9Sstevel@tonic-gate (*end)++; 43967c478bd9Sstevel@tonic-gate } else if (tcount > (blocksize - cur_bytes) / objsz) { 43977c478bd9Sstevel@tonic-gate tcount = (blocksize - cur_bytes) / objsz; 43987c478bd9Sstevel@tonic-gate if (!star || tcount == 0) 43997c478bd9Sstevel@tonic-gate (*end)++; 44007c478bd9Sstevel@tonic-gate } 44017c478bd9Sstevel@tonic-gate } 44027c478bd9Sstevel@tonic-gate } 44037c478bd9Sstevel@tonic-gate return (tcount); 44047c478bd9Sstevel@tonic-gate } 44057c478bd9Sstevel@tonic-gate 44067c478bd9Sstevel@tonic-gate /* 44077c478bd9Sstevel@tonic-gate * print_check - check if the index needs to be printed and delete 44087c478bd9Sstevel@tonic-gate * rows of zeros from the output. 44097c478bd9Sstevel@tonic-gate */ 44107c478bd9Sstevel@tonic-gate unsigned long * 4411d1a180b0Smaheshvs print_check(unsigned long *lptr, long *tcount, short tbase, int i) 44127c478bd9Sstevel@tonic-gate { 4413d1a180b0Smaheshvs int j, k, temp = BYTESPERLINE / objsz; 44147c478bd9Sstevel@tonic-gate short first_time = 0; 44157c478bd9Sstevel@tonic-gate unsigned long *tlptr; 44167c478bd9Sstevel@tonic-gate unsigned short *tsptr, *sptr; 44177c478bd9Sstevel@tonic-gate 44187c478bd9Sstevel@tonic-gate sptr = (unsigned short *)lptr; 44197c478bd9Sstevel@tonic-gate if (i == 0) 44207c478bd9Sstevel@tonic-gate first_time = 1; 44217c478bd9Sstevel@tonic-gate if (i % temp == 0) { 44227c478bd9Sstevel@tonic-gate if (*tcount >= temp - 1) { 44237c478bd9Sstevel@tonic-gate if (objsz == SHORT) 44247c478bd9Sstevel@tonic-gate tsptr = sptr; 44257c478bd9Sstevel@tonic-gate else 44267c478bd9Sstevel@tonic-gate tlptr = lptr; 44277c478bd9Sstevel@tonic-gate k = *tcount - 1; 44287c478bd9Sstevel@tonic-gate for (j = i; k--; j++) 44297c478bd9Sstevel@tonic-gate if (objsz == SHORT) { 44307c478bd9Sstevel@tonic-gate if (*tsptr++ != 0) 44317c478bd9Sstevel@tonic-gate break; 44327c478bd9Sstevel@tonic-gate } else { 44337c478bd9Sstevel@tonic-gate if (*tlptr++ != 0) 44347c478bd9Sstevel@tonic-gate break; 44357c478bd9Sstevel@tonic-gate } 44367c478bd9Sstevel@tonic-gate if (j > (i + temp - 1)) { 44377c478bd9Sstevel@tonic-gate j = (j - i) / temp; 44387c478bd9Sstevel@tonic-gate while (j-- > 0) { 44397c478bd9Sstevel@tonic-gate if (objsz == SHORT) 44407c478bd9Sstevel@tonic-gate sptr += temp; 44417c478bd9Sstevel@tonic-gate else 44427c478bd9Sstevel@tonic-gate lptr += temp; 44437c478bd9Sstevel@tonic-gate *tcount -= temp; 44447c478bd9Sstevel@tonic-gate i += temp; 44457c478bd9Sstevel@tonic-gate addr += BYTESPERLINE; 44467c478bd9Sstevel@tonic-gate cur_bytes += BYTESPERLINE; 44477c478bd9Sstevel@tonic-gate } 44487c478bd9Sstevel@tonic-gate if (first_time) 44497c478bd9Sstevel@tonic-gate printf("*"); 44507c478bd9Sstevel@tonic-gate else 44517c478bd9Sstevel@tonic-gate printf("\n*"); 44527c478bd9Sstevel@tonic-gate } 44537c478bd9Sstevel@tonic-gate if (i) 44547c478bd9Sstevel@tonic-gate printf("\n"); 44557c478bd9Sstevel@tonic-gate index(tbase); 44567c478bd9Sstevel@tonic-gate } else { 44577c478bd9Sstevel@tonic-gate if (i) 44587c478bd9Sstevel@tonic-gate printf("\n"); 44597c478bd9Sstevel@tonic-gate index(tbase); 44607c478bd9Sstevel@tonic-gate } 44617c478bd9Sstevel@tonic-gate } 44627c478bd9Sstevel@tonic-gate if (objsz == SHORT) 44637c478bd9Sstevel@tonic-gate /*LINTED*/ 44647c478bd9Sstevel@tonic-gate return ((unsigned long *)sptr); 44657c478bd9Sstevel@tonic-gate else 44667c478bd9Sstevel@tonic-gate return (lptr); 44677c478bd9Sstevel@tonic-gate } 44687c478bd9Sstevel@tonic-gate 44697c478bd9Sstevel@tonic-gate /* 44707c478bd9Sstevel@tonic-gate * index - print a byte index for the printout in base b 44717c478bd9Sstevel@tonic-gate * with leading zeros. 44727c478bd9Sstevel@tonic-gate */ 44737c478bd9Sstevel@tonic-gate static void 4474d1a180b0Smaheshvs index(int b) 44757c478bd9Sstevel@tonic-gate { 44767c478bd9Sstevel@tonic-gate int tbase = base; 44777c478bd9Sstevel@tonic-gate 44787c478bd9Sstevel@tonic-gate base = b; 44797c478bd9Sstevel@tonic-gate print(addr, 8, 8, 1); 44807c478bd9Sstevel@tonic-gate printf(":\t"); 44817c478bd9Sstevel@tonic-gate base = tbase; 44827c478bd9Sstevel@tonic-gate } 44837c478bd9Sstevel@tonic-gate 44847c478bd9Sstevel@tonic-gate /* 44857c478bd9Sstevel@tonic-gate * print - print out the value to digits places with/without 44867c478bd9Sstevel@tonic-gate * leading zeros and right/left justified in the current base. 44877c478bd9Sstevel@tonic-gate */ 44887c478bd9Sstevel@tonic-gate static void 44897c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE 44907c478bd9Sstevel@tonic-gate printll(u_offset_t value, int fieldsz, int digits, int lead) 44917c478bd9Sstevel@tonic-gate #else /* !_LARGEFILE64_SOURCE */ 44927c478bd9Sstevel@tonic-gate print(long value, int fieldsz, int digits, int lead) 44937c478bd9Sstevel@tonic-gate #endif /* _LARGEFILE64_SOURCE */ 44947c478bd9Sstevel@tonic-gate { 4495d1a180b0Smaheshvs int i, left = 0; 44967c478bd9Sstevel@tonic-gate char mode = BASE[base - OCTAL]; 44977c478bd9Sstevel@tonic-gate char *string = &scratch[0]; 44987c478bd9Sstevel@tonic-gate 44997c478bd9Sstevel@tonic-gate if (digits < 0) { 45007c478bd9Sstevel@tonic-gate left = 1; 45017c478bd9Sstevel@tonic-gate digits *= -1; 45027c478bd9Sstevel@tonic-gate } 45037c478bd9Sstevel@tonic-gate if (base != HEX) 45047c478bd9Sstevel@tonic-gate if (digits) 45057c478bd9Sstevel@tonic-gate digits = digits + (digits - 1)/((base >> 1) - 1) + 1; 45067c478bd9Sstevel@tonic-gate else 45077c478bd9Sstevel@tonic-gate digits = 1; 45087c478bd9Sstevel@tonic-gate if (lead) { 45097c478bd9Sstevel@tonic-gate if (left) 45107c478bd9Sstevel@tonic-gate (void) sprintf(string, "%%%c%d%d.%d" 45117c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE 45127c478bd9Sstevel@tonic-gate "ll" 45137c478bd9Sstevel@tonic-gate #endif /* _LARGEFILE64_SOURCE */ 45147c478bd9Sstevel@tonic-gate "%c", '-', 0, digits, lead, mode); 45157c478bd9Sstevel@tonic-gate else 45167c478bd9Sstevel@tonic-gate (void) sprintf(string, "%%%d%d.%d" 45177c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE 45187c478bd9Sstevel@tonic-gate "ll" 45197c478bd9Sstevel@tonic-gate #endif /* _LARGEFILE64_SOURCE */ 45207c478bd9Sstevel@tonic-gate "%c", 0, digits, lead, mode); 45217c478bd9Sstevel@tonic-gate } else { 45227c478bd9Sstevel@tonic-gate if (left) 45237c478bd9Sstevel@tonic-gate (void) sprintf(string, "%%%c%d" 45247c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE 45257c478bd9Sstevel@tonic-gate "ll" 45267c478bd9Sstevel@tonic-gate #endif /* _LARGEFILE64_SOURCE */ 45277c478bd9Sstevel@tonic-gate "%c", '-', digits, mode); 45287c478bd9Sstevel@tonic-gate else 45297c478bd9Sstevel@tonic-gate (void) sprintf(string, "%%%d" 45307c478bd9Sstevel@tonic-gate #ifdef _LARGEFILE64_SOURCE 45317c478bd9Sstevel@tonic-gate "ll" 45327c478bd9Sstevel@tonic-gate #endif /* _LARGEFILE64_SOURCE */ 45337c478bd9Sstevel@tonic-gate "%c", digits, mode); 45347c478bd9Sstevel@tonic-gate } 45357c478bd9Sstevel@tonic-gate printf(string, value); 45367c478bd9Sstevel@tonic-gate for (i = 0; i < fieldsz - digits; i++) 45377c478bd9Sstevel@tonic-gate printf(" "); 45387c478bd9Sstevel@tonic-gate } 45397c478bd9Sstevel@tonic-gate 45407c478bd9Sstevel@tonic-gate /* 45417c478bd9Sstevel@tonic-gate * Print out the contents of a superblock. 45427c478bd9Sstevel@tonic-gate */ 45437c478bd9Sstevel@tonic-gate static void 4544d1a180b0Smaheshvs printsb(struct fs *fs) 45457c478bd9Sstevel@tonic-gate { 45467c478bd9Sstevel@tonic-gate int c, i, j, k, size; 45477c478bd9Sstevel@tonic-gate caddr_t sip; 45487c478bd9Sstevel@tonic-gate time_t t; 45497c478bd9Sstevel@tonic-gate 45507c478bd9Sstevel@tonic-gate t = fs->fs_time; 45517c478bd9Sstevel@tonic-gate #ifdef FS_42POSTBLFMT 45527c478bd9Sstevel@tonic-gate if (fs->fs_postblformat == FS_42POSTBLFMT) 45537c478bd9Sstevel@tonic-gate fs->fs_nrpos = 8; 45547c478bd9Sstevel@tonic-gate printf("magic\t%lx\tformat\t%s\ttime\t%s", fs->fs_magic, 45557c478bd9Sstevel@tonic-gate fs->fs_postblformat == FS_42POSTBLFMT ? "static" : "dynamic", 45567c478bd9Sstevel@tonic-gate ctime(&t)); 45577c478bd9Sstevel@tonic-gate #else 45587c478bd9Sstevel@tonic-gate printf("magic\t%x\ttime\t%s", 45597c478bd9Sstevel@tonic-gate fs->fs_magic, ctime(&t)); 45607c478bd9Sstevel@tonic-gate #endif 45617c478bd9Sstevel@tonic-gate printf("version\t%x\n", fs->fs_version); 45627c478bd9Sstevel@tonic-gate printf("nbfree\t%ld\tndir\t%ld\tnifree\t%ld\tnffree\t%ld\n", 45637c478bd9Sstevel@tonic-gate fs->fs_cstotal.cs_nbfree, fs->fs_cstotal.cs_ndir, 45647c478bd9Sstevel@tonic-gate fs->fs_cstotal.cs_nifree, fs->fs_cstotal.cs_nffree); 45657c478bd9Sstevel@tonic-gate printf("ncg\t%ld\tncyl\t%ld\tsize\t%ld\tblocks\t%ld\n", 45667c478bd9Sstevel@tonic-gate fs->fs_ncg, fs->fs_ncyl, fs->fs_size, fs->fs_dsize); 45677c478bd9Sstevel@tonic-gate printf("bsize\t%ld\tshift\t%ld\tmask\t0x%08lx\n", 45687c478bd9Sstevel@tonic-gate fs->fs_bsize, fs->fs_bshift, fs->fs_bmask); 45697c478bd9Sstevel@tonic-gate printf("fsize\t%ld\tshift\t%ld\tmask\t0x%08lx\n", 45707c478bd9Sstevel@tonic-gate fs->fs_fsize, fs->fs_fshift, fs->fs_fmask); 45717c478bd9Sstevel@tonic-gate printf("frag\t%ld\tshift\t%ld\tfsbtodb\t%ld\n", 45727c478bd9Sstevel@tonic-gate fs->fs_frag, fs->fs_fragshift, fs->fs_fsbtodb); 45737c478bd9Sstevel@tonic-gate printf("cpg\t%ld\tbpg\t%ld\tfpg\t%ld\tipg\t%ld\n", 45747c478bd9Sstevel@tonic-gate fs->fs_cpg, fs->fs_fpg / fs->fs_frag, fs->fs_fpg, fs->fs_ipg); 45757c478bd9Sstevel@tonic-gate printf("minfree\t%ld%%\toptim\t%s\tmaxcontig %ld\tmaxbpg\t%ld\n", 45767c478bd9Sstevel@tonic-gate fs->fs_minfree, fs->fs_optim == FS_OPTSPACE ? "space" : "time", 45777c478bd9Sstevel@tonic-gate fs->fs_maxcontig, fs->fs_maxbpg); 45787c478bd9Sstevel@tonic-gate #ifdef FS_42POSTBLFMT 45797c478bd9Sstevel@tonic-gate #ifdef sun 45807c478bd9Sstevel@tonic-gate printf("rotdelay %ldms\tfs_id[0] 0x%lx\tfs_id[1] 0x%lx\trps\t%ld\n", 45817c478bd9Sstevel@tonic-gate fs->fs_rotdelay, fs->fs_id[0], fs->fs_id[1], fs->fs_rps); 45827c478bd9Sstevel@tonic-gate #else 45837c478bd9Sstevel@tonic-gate printf("rotdelay %dms\theadswitch %dus\ttrackseek %dus\trps\t%d\n", 45847c478bd9Sstevel@tonic-gate fs->fs_rotdelay, fs->fs_headswitch, fs->fs_trkseek, fs->fs_rps); 45857c478bd9Sstevel@tonic-gate #endif /* sun */ 45867c478bd9Sstevel@tonic-gate printf("ntrak\t%ld\tnsect\t%ld\tnpsect\t%ld\tspc\t%ld\n", 45877c478bd9Sstevel@tonic-gate fs->fs_ntrak, fs->fs_nsect, fs->fs_npsect, fs->fs_spc); 45887c478bd9Sstevel@tonic-gate printf("trackskew %ld\n", fs->fs_trackskew); 45897c478bd9Sstevel@tonic-gate #else 45907c478bd9Sstevel@tonic-gate printf("rotdelay %ldms\trps\t%ld\n", 45917c478bd9Sstevel@tonic-gate fs->fs_rotdelay, fs->fs_rps); 45927c478bd9Sstevel@tonic-gate printf("ntrak\t%ld\tnsect\t%ld\tspc\t%ld\n", 45937c478bd9Sstevel@tonic-gate fs->fs_ntrak, fs->fs_nsect, fs->fs_spc); 45947c478bd9Sstevel@tonic-gate #endif 45957c478bd9Sstevel@tonic-gate printf("si %ld\n", fs->fs_si); 45967c478bd9Sstevel@tonic-gate printf("nindir\t%ld\tinopb\t%ld\tnspf\t%ld\n", 45977c478bd9Sstevel@tonic-gate fs->fs_nindir, fs->fs_inopb, fs->fs_nspf); 45987c478bd9Sstevel@tonic-gate printf("sblkno\t%ld\tcblkno\t%ld\tiblkno\t%ld\tdblkno\t%ld\n", 45997c478bd9Sstevel@tonic-gate fs->fs_sblkno, fs->fs_cblkno, fs->fs_iblkno, fs->fs_dblkno); 46007c478bd9Sstevel@tonic-gate printf("sbsize\t%ld\tcgsize\t%ld\tcgoffset %ld\tcgmask\t0x%08lx\n", 46017c478bd9Sstevel@tonic-gate fs->fs_sbsize, fs->fs_cgsize, fs->fs_cgoffset, fs->fs_cgmask); 46027c478bd9Sstevel@tonic-gate printf("csaddr\t%ld\tcssize\t%ld\tshift\t%ld\tmask\t0x%08lx\n", 46037c478bd9Sstevel@tonic-gate fs->fs_csaddr, fs->fs_cssize, fs->fs_csshift, fs->fs_csmask); 46047c478bd9Sstevel@tonic-gate printf("cgrotor\t%ld\tfmod\t%d\tronly\t%d\n", 46057c478bd9Sstevel@tonic-gate fs->fs_cgrotor, fs->fs_fmod, fs->fs_ronly); 46067c478bd9Sstevel@tonic-gate #ifdef FS_42POSTBLFMT 46077c478bd9Sstevel@tonic-gate if (fs->fs_cpc != 0) 46087c478bd9Sstevel@tonic-gate printf("blocks available in each of %ld rotational positions", 46097c478bd9Sstevel@tonic-gate fs->fs_nrpos); 46107c478bd9Sstevel@tonic-gate else 46117c478bd9Sstevel@tonic-gate printf("insufficient space to maintain rotational tables\n"); 46127c478bd9Sstevel@tonic-gate #endif 46137c478bd9Sstevel@tonic-gate for (c = 0; c < fs->fs_cpc; c++) { 46147c478bd9Sstevel@tonic-gate printf("\ncylinder number %d:", c); 46157c478bd9Sstevel@tonic-gate #ifdef FS_42POSTBLFMT 46167c478bd9Sstevel@tonic-gate for (i = 0; i < fs->fs_nrpos; i++) { 46177c478bd9Sstevel@tonic-gate /*LINTED*/ 46187c478bd9Sstevel@tonic-gate if (fs_postbl(fs, c)[i] == -1) 46197c478bd9Sstevel@tonic-gate continue; 46207c478bd9Sstevel@tonic-gate printf("\n position %d:\t", i); 46217c478bd9Sstevel@tonic-gate /*LINTED*/ 46227c478bd9Sstevel@tonic-gate for (j = fs_postbl(fs, c)[i], k = 1; /* void */; 46237c478bd9Sstevel@tonic-gate j += fs_rotbl(fs)[j], k++) { 46247c478bd9Sstevel@tonic-gate printf("%5d", j); 46257c478bd9Sstevel@tonic-gate if (k % 12 == 0) 46267c478bd9Sstevel@tonic-gate printf("\n\t\t"); 46277c478bd9Sstevel@tonic-gate if (fs_rotbl(fs)[j] == 0) 46287c478bd9Sstevel@tonic-gate break; 46297c478bd9Sstevel@tonic-gate } 46307c478bd9Sstevel@tonic-gate } 46317c478bd9Sstevel@tonic-gate #else 46327c478bd9Sstevel@tonic-gate for (i = 0; i < NRPOS; i++) { 46337c478bd9Sstevel@tonic-gate if (fs->fs_postbl[c][i] == -1) 46347c478bd9Sstevel@tonic-gate continue; 46357c478bd9Sstevel@tonic-gate printf("\n position %d:\t", i); 46367c478bd9Sstevel@tonic-gate for (j = fs->fs_postbl[c][i], k = 1; /* void */; 46377c478bd9Sstevel@tonic-gate j += fs->fs_rotbl[j], k++) { 46387c478bd9Sstevel@tonic-gate printf("%5d", j); 46397c478bd9Sstevel@tonic-gate if (k % 12 == 0) 46407c478bd9Sstevel@tonic-gate printf("\n\t\t"); 46417c478bd9Sstevel@tonic-gate if (fs->fs_rotbl[j] == 0) 46427c478bd9Sstevel@tonic-gate break; 46437c478bd9Sstevel@tonic-gate } 46447c478bd9Sstevel@tonic-gate } 46457c478bd9Sstevel@tonic-gate #endif 46467c478bd9Sstevel@tonic-gate } 46477c478bd9Sstevel@tonic-gate printf("\ncs[].cs_(nbfree, ndir, nifree, nffree):"); 46487c478bd9Sstevel@tonic-gate sip = calloc(1, fs->fs_cssize); 46497c478bd9Sstevel@tonic-gate fs->fs_u.fs_csp = (struct csum *)sip; 46507c478bd9Sstevel@tonic-gate for (i = 0, j = 0; i < fs->fs_cssize; i += fs->fs_bsize, j++) { 46517c478bd9Sstevel@tonic-gate size = fs->fs_cssize - i < fs->fs_bsize ? 46527c478bd9Sstevel@tonic-gate fs->fs_cssize - i : fs->fs_bsize; 46537c478bd9Sstevel@tonic-gate (void) llseek(fd, 46547c478bd9Sstevel@tonic-gate (offset_t)fsbtodb(fs, (fs->fs_csaddr + j * fs->fs_frag)) 46557c478bd9Sstevel@tonic-gate * fs->fs_fsize / fsbtodb(fs, 1), 0); 46567c478bd9Sstevel@tonic-gate if (read(fd, sip, size) != size) { 46577c478bd9Sstevel@tonic-gate free(fs->fs_u.fs_csp); 46587c478bd9Sstevel@tonic-gate return; 46597c478bd9Sstevel@tonic-gate } 46607c478bd9Sstevel@tonic-gate sip += size; 46617c478bd9Sstevel@tonic-gate } 46627c478bd9Sstevel@tonic-gate for (i = 0; i < fs->fs_ncg; i++) { 46637c478bd9Sstevel@tonic-gate struct csum *cs = &fs->fs_cs(fs, i); 46647c478bd9Sstevel@tonic-gate if (i % 4 == 0) 46657c478bd9Sstevel@tonic-gate printf("\n "); 46667c478bd9Sstevel@tonic-gate printf("%d:(%ld,%ld,%ld,%ld) ", i, cs->cs_nbfree, cs->cs_ndir, 46677c478bd9Sstevel@tonic-gate cs->cs_nifree, cs->cs_nffree); 46687c478bd9Sstevel@tonic-gate } 46697c478bd9Sstevel@tonic-gate free(fs->fs_u.fs_csp); 46707c478bd9Sstevel@tonic-gate printf("\n"); 46717c478bd9Sstevel@tonic-gate if (fs->fs_ncyl % fs->fs_cpg) { 46727c478bd9Sstevel@tonic-gate printf("cylinders in last group %d\n", 46737c478bd9Sstevel@tonic-gate i = fs->fs_ncyl % fs->fs_cpg); 46747c478bd9Sstevel@tonic-gate printf("blocks in last group %ld\n", 46757c478bd9Sstevel@tonic-gate i * fs->fs_spc / NSPB(fs)); 46767c478bd9Sstevel@tonic-gate } 46777c478bd9Sstevel@tonic-gate } 46787c478bd9Sstevel@tonic-gate 46797c478bd9Sstevel@tonic-gate /* 46807c478bd9Sstevel@tonic-gate * Print out the contents of a cylinder group. 46817c478bd9Sstevel@tonic-gate */ 46827c478bd9Sstevel@tonic-gate static void 4683d1a180b0Smaheshvs printcg(struct cg *cg) 46847c478bd9Sstevel@tonic-gate { 46857c478bd9Sstevel@tonic-gate int i, j; 46867c478bd9Sstevel@tonic-gate time_t t; 46877c478bd9Sstevel@tonic-gate 46887c478bd9Sstevel@tonic-gate printf("\ncg %ld:\n", cg->cg_cgx); 46897c478bd9Sstevel@tonic-gate t = cg->cg_time; 46907c478bd9Sstevel@tonic-gate #ifdef FS_42POSTBLFMT 46917c478bd9Sstevel@tonic-gate printf("magic\t%lx\ttell\t%llx\ttime\t%s", 46927c478bd9Sstevel@tonic-gate fs->fs_postblformat == FS_42POSTBLFMT ? 46937c478bd9Sstevel@tonic-gate ((struct ocg *)cg)->cg_magic : cg->cg_magic, 46947c478bd9Sstevel@tonic-gate fsbtodb(fs, cgtod(fs, cg->cg_cgx)) * fs->fs_fsize / fsbtodb(fs, 1), 46957c478bd9Sstevel@tonic-gate ctime(&t)); 46967c478bd9Sstevel@tonic-gate #else 46977c478bd9Sstevel@tonic-gate printf("magic\t%x\ttell\t%llx\ttime\t%s", 46987c478bd9Sstevel@tonic-gate cg->cg_magic, 46997c478bd9Sstevel@tonic-gate fsbtodb(fs, cgtod(fs, cg->cg_cgx)) * fs->fs_fsize / fsbtodb(fs, 1), 47007c478bd9Sstevel@tonic-gate ctime(&t)); 47017c478bd9Sstevel@tonic-gate #endif 47027c478bd9Sstevel@tonic-gate printf("cgx\t%ld\tncyl\t%d\tniblk\t%d\tndblk\t%ld\n", 47037c478bd9Sstevel@tonic-gate cg->cg_cgx, cg->cg_ncyl, cg->cg_niblk, cg->cg_ndblk); 47047c478bd9Sstevel@tonic-gate printf("nbfree\t%ld\tndir\t%ld\tnifree\t%ld\tnffree\t%ld\n", 47057c478bd9Sstevel@tonic-gate cg->cg_cs.cs_nbfree, cg->cg_cs.cs_ndir, 47067c478bd9Sstevel@tonic-gate cg->cg_cs.cs_nifree, cg->cg_cs.cs_nffree); 47077c478bd9Sstevel@tonic-gate printf("rotor\t%ld\tirotor\t%ld\tfrotor\t%ld\nfrsum", 47087c478bd9Sstevel@tonic-gate cg->cg_rotor, cg->cg_irotor, cg->cg_frotor); 47097c478bd9Sstevel@tonic-gate for (i = 1, j = 0; i < fs->fs_frag; i++) { 47107c478bd9Sstevel@tonic-gate printf("\t%ld", cg->cg_frsum[i]); 47117c478bd9Sstevel@tonic-gate j += i * cg->cg_frsum[i]; 47127c478bd9Sstevel@tonic-gate } 47137c478bd9Sstevel@tonic-gate printf("\nsum of frsum: %d\niused:\t", j); 47147c478bd9Sstevel@tonic-gate pbits((unsigned char *)cg_inosused(cg), fs->fs_ipg); 47157c478bd9Sstevel@tonic-gate printf("free:\t"); 47167c478bd9Sstevel@tonic-gate pbits(cg_blksfree(cg), fs->fs_fpg); 47177c478bd9Sstevel@tonic-gate printf("b:\n"); 47187c478bd9Sstevel@tonic-gate for (i = 0; i < fs->fs_cpg; i++) { 47197c478bd9Sstevel@tonic-gate /*LINTED*/ 47207c478bd9Sstevel@tonic-gate if (cg_blktot(cg)[i] == 0) 47217c478bd9Sstevel@tonic-gate continue; 47227c478bd9Sstevel@tonic-gate /*LINTED*/ 47237c478bd9Sstevel@tonic-gate printf(" c%d:\t(%ld)\t", i, cg_blktot(cg)[i]); 47247c478bd9Sstevel@tonic-gate #ifdef FS_42POSTBLFMT 47257c478bd9Sstevel@tonic-gate for (j = 0; j < fs->fs_nrpos; j++) { 47267c478bd9Sstevel@tonic-gate if (fs->fs_cpc == 0 || 47277c478bd9Sstevel@tonic-gate /*LINTED*/ 47287c478bd9Sstevel@tonic-gate fs_postbl(fs, i % fs->fs_cpc)[j] == -1) 47297c478bd9Sstevel@tonic-gate continue; 47307c478bd9Sstevel@tonic-gate /*LINTED*/ 47317c478bd9Sstevel@tonic-gate printf(" %d", cg_blks(fs, cg, i)[j]); 47327c478bd9Sstevel@tonic-gate } 47337c478bd9Sstevel@tonic-gate #else 47347c478bd9Sstevel@tonic-gate for (j = 0; j < NRPOS; j++) { 47357c478bd9Sstevel@tonic-gate if (fs->fs_cpc == 0 || 47367c478bd9Sstevel@tonic-gate fs->fs_postbl[i % fs->fs_cpc][j] == -1) 47377c478bd9Sstevel@tonic-gate continue; 47387c478bd9Sstevel@tonic-gate printf(" %d", cg->cg_b[i][j]); 47397c478bd9Sstevel@tonic-gate } 47407c478bd9Sstevel@tonic-gate #endif 47417c478bd9Sstevel@tonic-gate printf("\n"); 47427c478bd9Sstevel@tonic-gate } 47437c478bd9Sstevel@tonic-gate } 47447c478bd9Sstevel@tonic-gate 47457c478bd9Sstevel@tonic-gate /* 47467c478bd9Sstevel@tonic-gate * Print out the contents of a bit array. 47477c478bd9Sstevel@tonic-gate */ 47487c478bd9Sstevel@tonic-gate static void 4749d1a180b0Smaheshvs pbits(unsigned char *cp, int max) 47507c478bd9Sstevel@tonic-gate { 4751d1a180b0Smaheshvs int i; 47527c478bd9Sstevel@tonic-gate int count = 0, j; 47537c478bd9Sstevel@tonic-gate 47547c478bd9Sstevel@tonic-gate for (i = 0; i < max; i++) 47557c478bd9Sstevel@tonic-gate if (isset(cp, i)) { 47567c478bd9Sstevel@tonic-gate if (count) 47577c478bd9Sstevel@tonic-gate printf(",%s", count % 6 ? " " : "\n\t"); 47587c478bd9Sstevel@tonic-gate count++; 47597c478bd9Sstevel@tonic-gate printf("%d", i); 47607c478bd9Sstevel@tonic-gate j = i; 47617c478bd9Sstevel@tonic-gate while ((i+1) < max && isset(cp, i+1)) 47627c478bd9Sstevel@tonic-gate i++; 47637c478bd9Sstevel@tonic-gate if (i != j) 47647c478bd9Sstevel@tonic-gate printf("-%d", i); 47657c478bd9Sstevel@tonic-gate } 47667c478bd9Sstevel@tonic-gate printf("\n"); 47677c478bd9Sstevel@tonic-gate } 47687c478bd9Sstevel@tonic-gate 47697c478bd9Sstevel@tonic-gate /* 47707c478bd9Sstevel@tonic-gate * bcomp - used to check for block over/under flows when stepping through 47717c478bd9Sstevel@tonic-gate * a file system. 47727c478bd9Sstevel@tonic-gate */ 47737c478bd9Sstevel@tonic-gate static int 47747c478bd9Sstevel@tonic-gate bcomp(addr) 47757c478bd9Sstevel@tonic-gate u_offset_t addr; 47767c478bd9Sstevel@tonic-gate { 47777c478bd9Sstevel@tonic-gate if (override) 47787c478bd9Sstevel@tonic-gate return (0); 47797c478bd9Sstevel@tonic-gate 47807c478bd9Sstevel@tonic-gate if (lblkno(fs, addr) == (bhdr.fwd)->blkno) 47817c478bd9Sstevel@tonic-gate return (0); 47827c478bd9Sstevel@tonic-gate error++; 47837c478bd9Sstevel@tonic-gate return (1); 47847c478bd9Sstevel@tonic-gate } 47857c478bd9Sstevel@tonic-gate 47867c478bd9Sstevel@tonic-gate /* 47877c478bd9Sstevel@tonic-gate * bmap - maps the logical block number of a file into 47887c478bd9Sstevel@tonic-gate * the corresponding physical block on the file 47897c478bd9Sstevel@tonic-gate * system. 47907c478bd9Sstevel@tonic-gate */ 47917c478bd9Sstevel@tonic-gate static long 4792d1a180b0Smaheshvs bmap(long bn) 47937c478bd9Sstevel@tonic-gate { 4794d1a180b0Smaheshvs int j; 4795d1a180b0Smaheshvs struct dinode *ip; 47967c478bd9Sstevel@tonic-gate int sh; 47977c478bd9Sstevel@tonic-gate long nb; 4798d1a180b0Smaheshvs char *cptr; 47997c478bd9Sstevel@tonic-gate 48007c478bd9Sstevel@tonic-gate if ((cptr = getblk(cur_ino)) == 0) 48017c478bd9Sstevel@tonic-gate return (0); 48027c478bd9Sstevel@tonic-gate 48037c478bd9Sstevel@tonic-gate cptr += blkoff(fs, cur_ino); 48047c478bd9Sstevel@tonic-gate 48057c478bd9Sstevel@tonic-gate /*LINTED*/ 48067c478bd9Sstevel@tonic-gate ip = (struct dinode *)cptr; 48077c478bd9Sstevel@tonic-gate 48087c478bd9Sstevel@tonic-gate if (bn < NDADDR) { 48097c478bd9Sstevel@tonic-gate nb = ip->di_db[bn]; 48107c478bd9Sstevel@tonic-gate return (nullblk(nb) ? 0L : nb); 48117c478bd9Sstevel@tonic-gate } 48127c478bd9Sstevel@tonic-gate 48137c478bd9Sstevel@tonic-gate sh = 1; 48147c478bd9Sstevel@tonic-gate bn -= NDADDR; 48157c478bd9Sstevel@tonic-gate for (j = NIADDR; j > 0; j--) { 48167c478bd9Sstevel@tonic-gate sh *= NINDIR(fs); 48177c478bd9Sstevel@tonic-gate if (bn < sh) 48187c478bd9Sstevel@tonic-gate break; 48197c478bd9Sstevel@tonic-gate bn -= sh; 48207c478bd9Sstevel@tonic-gate } 48217c478bd9Sstevel@tonic-gate if (j == 0) { 48227c478bd9Sstevel@tonic-gate printf("file too big\n"); 48237c478bd9Sstevel@tonic-gate error++; 48247c478bd9Sstevel@tonic-gate return (0L); 48257c478bd9Sstevel@tonic-gate } 48267c478bd9Sstevel@tonic-gate addr = (uintptr_t)&ip->di_ib[NIADDR - j]; 48277c478bd9Sstevel@tonic-gate nb = get(LONG); 48287c478bd9Sstevel@tonic-gate if (nb == 0) 48297c478bd9Sstevel@tonic-gate return (0L); 48307c478bd9Sstevel@tonic-gate for (; j <= NIADDR; j++) { 48317c478bd9Sstevel@tonic-gate sh /= NINDIR(fs); 48327c478bd9Sstevel@tonic-gate addr = (nb << FRGSHIFT) + ((bn / sh) % NINDIR(fs)) * LONG; 48337c478bd9Sstevel@tonic-gate if (nullblk(nb = get(LONG))) 48347c478bd9Sstevel@tonic-gate return (0L); 48357c478bd9Sstevel@tonic-gate } 48367c478bd9Sstevel@tonic-gate return (nb); 48377c478bd9Sstevel@tonic-gate } 48387c478bd9Sstevel@tonic-gate 48397c478bd9Sstevel@tonic-gate #if defined(OLD_FSDB_COMPATIBILITY) 48407c478bd9Sstevel@tonic-gate 48417c478bd9Sstevel@tonic-gate /* 48427c478bd9Sstevel@tonic-gate * The following are "tacked on" to support the old fsdb functionality 48437c478bd9Sstevel@tonic-gate * of clearing an inode. (All together now...) "It's better to use clri". 48447c478bd9Sstevel@tonic-gate */ 48457c478bd9Sstevel@tonic-gate 48467c478bd9Sstevel@tonic-gate #define ISIZE (sizeof (struct dinode)) 48477c478bd9Sstevel@tonic-gate #define NI (MAXBSIZE/ISIZE) 48487c478bd9Sstevel@tonic-gate 48497c478bd9Sstevel@tonic-gate 48507c478bd9Sstevel@tonic-gate static struct dinode di_buf[NI]; 48517c478bd9Sstevel@tonic-gate 48527c478bd9Sstevel@tonic-gate static union { 48537c478bd9Sstevel@tonic-gate char dummy[SBSIZE]; 48547c478bd9Sstevel@tonic-gate struct fs sblk; 48557c478bd9Sstevel@tonic-gate } sb_un; 48567c478bd9Sstevel@tonic-gate 48577c478bd9Sstevel@tonic-gate #define sblock sb_un.sblk 48587c478bd9Sstevel@tonic-gate 48597c478bd9Sstevel@tonic-gate static void 4860d1a180b0Smaheshvs old_fsdb(int inum, char *special) 48617c478bd9Sstevel@tonic-gate { 48627c478bd9Sstevel@tonic-gate int f; /* File descriptor for "special" */ 48637c478bd9Sstevel@tonic-gate int j; 48647c478bd9Sstevel@tonic-gate int status = 0; 48657c478bd9Sstevel@tonic-gate u_offset_t off; 48667c478bd9Sstevel@tonic-gate long gen; 48677c478bd9Sstevel@tonic-gate time_t t; 48687c478bd9Sstevel@tonic-gate 48697c478bd9Sstevel@tonic-gate f = open(special, 2); 48707c478bd9Sstevel@tonic-gate if (f < 0) { 48717c478bd9Sstevel@tonic-gate perror("open"); 48727c478bd9Sstevel@tonic-gate printf("cannot open %s\n", special); 48737c478bd9Sstevel@tonic-gate exit(31+4); 48747c478bd9Sstevel@tonic-gate } 48757c478bd9Sstevel@tonic-gate (void) llseek(f, (offset_t)SBLOCK * DEV_BSIZE, 0); 48767c478bd9Sstevel@tonic-gate if (read(f, &sblock, SBSIZE) != SBSIZE) { 48777c478bd9Sstevel@tonic-gate printf("cannot read %s\n", special); 48787c478bd9Sstevel@tonic-gate exit(31+4); 48797c478bd9Sstevel@tonic-gate } 48807c478bd9Sstevel@tonic-gate if (sblock.fs_magic != FS_MAGIC) { 48817c478bd9Sstevel@tonic-gate printf("bad super block magic number\n"); 48827c478bd9Sstevel@tonic-gate exit(31+4); 48837c478bd9Sstevel@tonic-gate } 48847c478bd9Sstevel@tonic-gate if (inum == 0) { 48857c478bd9Sstevel@tonic-gate printf("%d: is zero\n", inum); 48867c478bd9Sstevel@tonic-gate exit(31+1); 48877c478bd9Sstevel@tonic-gate } 48887c478bd9Sstevel@tonic-gate off = (u_offset_t)fsbtodb(&sblock, itod(&sblock, inum)) * DEV_BSIZE; 48897c478bd9Sstevel@tonic-gate (void) llseek(f, off, 0); 48907c478bd9Sstevel@tonic-gate if (read(f, (char *)di_buf, sblock.fs_bsize) != sblock.fs_bsize) { 48917c478bd9Sstevel@tonic-gate printf("%s: read error\n", special); 48927c478bd9Sstevel@tonic-gate status = 1; 48937c478bd9Sstevel@tonic-gate } 48947c478bd9Sstevel@tonic-gate if (status) 48957c478bd9Sstevel@tonic-gate exit(31+status); 48967c478bd9Sstevel@tonic-gate 48977c478bd9Sstevel@tonic-gate /* 48987c478bd9Sstevel@tonic-gate * Update the time in superblock, so fsck will check this filesystem. 48997c478bd9Sstevel@tonic-gate */ 49007c478bd9Sstevel@tonic-gate (void) llseek(f, (offset_t)(SBLOCK * DEV_BSIZE), 0); 49017c478bd9Sstevel@tonic-gate (void) time(&t); 49027c478bd9Sstevel@tonic-gate sblock.fs_time = (time32_t)t; 49037c478bd9Sstevel@tonic-gate if (write(f, &sblock, SBSIZE) != SBSIZE) { 49047c478bd9Sstevel@tonic-gate printf("cannot update %s\n", special); 49057c478bd9Sstevel@tonic-gate exit(35); 49067c478bd9Sstevel@tonic-gate } 49077c478bd9Sstevel@tonic-gate 49087c478bd9Sstevel@tonic-gate printf("clearing %u\n", inum); 49097c478bd9Sstevel@tonic-gate off = (u_offset_t)fsbtodb(&sblock, itod(&sblock, inum)) * DEV_BSIZE; 49107c478bd9Sstevel@tonic-gate (void) llseek(f, off, 0); 49117c478bd9Sstevel@tonic-gate read(f, (char *)di_buf, sblock.fs_bsize); 49127c478bd9Sstevel@tonic-gate j = itoo(&sblock, inum); 49137c478bd9Sstevel@tonic-gate gen = di_buf[j].di_gen; 49147c478bd9Sstevel@tonic-gate (void) memset((caddr_t)&di_buf[j], 0, ISIZE); 49157c478bd9Sstevel@tonic-gate di_buf[j].di_gen = gen + 1; 49167c478bd9Sstevel@tonic-gate (void) llseek(f, off, 0); 49177c478bd9Sstevel@tonic-gate write(f, (char *)di_buf, sblock.fs_bsize); 49187c478bd9Sstevel@tonic-gate exit(31+status); 49197c478bd9Sstevel@tonic-gate } 49207c478bd9Sstevel@tonic-gate 49217c478bd9Sstevel@tonic-gate static int 4922d1a180b0Smaheshvs isnumber(char *s) 49237c478bd9Sstevel@tonic-gate { 49247c478bd9Sstevel@tonic-gate register int c; 49257c478bd9Sstevel@tonic-gate 49267c478bd9Sstevel@tonic-gate if (s == NULL) 49277c478bd9Sstevel@tonic-gate return (0); 49287c478bd9Sstevel@tonic-gate while ((c = *s++) != NULL) 49297c478bd9Sstevel@tonic-gate if (c < '0' || c > '9') 49307c478bd9Sstevel@tonic-gate return (0); 49317c478bd9Sstevel@tonic-gate return (1); 49327c478bd9Sstevel@tonic-gate } 49337c478bd9Sstevel@tonic-gate #endif /* OLD_FSDB_COMPATIBILITY */ 49347c478bd9Sstevel@tonic-gate 49357c478bd9Sstevel@tonic-gate enum boolean { True, False }; 49367c478bd9Sstevel@tonic-gate extent_block_t *log_eb; 49377c478bd9Sstevel@tonic-gate ml_odunit_t *log_odi; 49387c478bd9Sstevel@tonic-gate int lufs_tid; /* last valid TID seen */ 49397c478bd9Sstevel@tonic-gate 49407c478bd9Sstevel@tonic-gate /* 49417c478bd9Sstevel@tonic-gate * no single value is safe to use to indicate 49427c478bd9Sstevel@tonic-gate * lufs_tid being invalid so we need a 49437c478bd9Sstevel@tonic-gate * seperate variable. 49447c478bd9Sstevel@tonic-gate */ 49457c478bd9Sstevel@tonic-gate enum boolean lufs_tid_valid; 49467c478bd9Sstevel@tonic-gate 49477c478bd9Sstevel@tonic-gate /* 49487c478bd9Sstevel@tonic-gate * log_get_header_info - get the basic info of the logging filesystem 49497c478bd9Sstevel@tonic-gate */ 49507c478bd9Sstevel@tonic-gate int 49517c478bd9Sstevel@tonic-gate log_get_header_info(void) 49527c478bd9Sstevel@tonic-gate { 49537c478bd9Sstevel@tonic-gate char *b; 49547c478bd9Sstevel@tonic-gate int nb; 49557c478bd9Sstevel@tonic-gate 49567c478bd9Sstevel@tonic-gate /* 49577c478bd9Sstevel@tonic-gate * Mark the global tid as invalid everytime we're called to 49587c478bd9Sstevel@tonic-gate * prevent any false positive responses. 49597c478bd9Sstevel@tonic-gate */ 49607c478bd9Sstevel@tonic-gate lufs_tid_valid = False; 49617c478bd9Sstevel@tonic-gate 49627c478bd9Sstevel@tonic-gate /* 49637c478bd9Sstevel@tonic-gate * See if we've already set up the header areas. The only problem 49647c478bd9Sstevel@tonic-gate * with this approach is we don't reread the on disk data though 49657c478bd9Sstevel@tonic-gate * it shouldn't matter since we don't operate on a live disk. 49667c478bd9Sstevel@tonic-gate */ 49677c478bd9Sstevel@tonic-gate if ((log_eb != NULL) && (log_odi != NULL)) 49687c478bd9Sstevel@tonic-gate return (1); 49697c478bd9Sstevel@tonic-gate 49707c478bd9Sstevel@tonic-gate /* 49717c478bd9Sstevel@tonic-gate * Either logging is disabled or we've not running 2.7. 49727c478bd9Sstevel@tonic-gate */ 49737c478bd9Sstevel@tonic-gate if (fs->fs_logbno == 0) { 49747c478bd9Sstevel@tonic-gate printf("Logging doesn't appear to be enabled on this disk\n"); 49757c478bd9Sstevel@tonic-gate return (0); 49767c478bd9Sstevel@tonic-gate } 49777c478bd9Sstevel@tonic-gate 49787c478bd9Sstevel@tonic-gate /* 49797c478bd9Sstevel@tonic-gate * To find the log we need to first pick up the block allocation 49807c478bd9Sstevel@tonic-gate * data. The block number for that data is fs_logbno in the 49817c478bd9Sstevel@tonic-gate * super block. 49827c478bd9Sstevel@tonic-gate */ 49837c478bd9Sstevel@tonic-gate if ((b = getblk((u_offset_t)ldbtob(logbtodb(fs, fs->fs_logbno)))) 49847c478bd9Sstevel@tonic-gate == 0) { 49857c478bd9Sstevel@tonic-gate printf("getblk() indicates an error with logging block\n"); 49867c478bd9Sstevel@tonic-gate return (0); 49877c478bd9Sstevel@tonic-gate } 49887c478bd9Sstevel@tonic-gate 49897c478bd9Sstevel@tonic-gate /* 49907c478bd9Sstevel@tonic-gate * Next we need to figure out how big the extent data structure 49917c478bd9Sstevel@tonic-gate * really is. It can't be more then fs_bsize and you could just 49927c478bd9Sstevel@tonic-gate * allocate that but, why get sloppy. 49937c478bd9Sstevel@tonic-gate * 1 is subtracted from nextents because extent_block_t contains 49947c478bd9Sstevel@tonic-gate * a single extent_t itself. 49957c478bd9Sstevel@tonic-gate */ 49967c478bd9Sstevel@tonic-gate log_eb = (extent_block_t *)b; 49977c478bd9Sstevel@tonic-gate if (log_eb->type != LUFS_EXTENTS) { 49987c478bd9Sstevel@tonic-gate printf("Extents block has invalid type (0x%x)\n", 49997c478bd9Sstevel@tonic-gate log_eb->type); 50007c478bd9Sstevel@tonic-gate return (0); 50017c478bd9Sstevel@tonic-gate } 50027c478bd9Sstevel@tonic-gate nb = sizeof (extent_block_t) + 50037c478bd9Sstevel@tonic-gate (sizeof (extent_t) * (log_eb->nextents - 1)); 50047c478bd9Sstevel@tonic-gate 50057c478bd9Sstevel@tonic-gate log_eb = (extent_block_t *)malloc(nb); 50067c478bd9Sstevel@tonic-gate if (log_eb == NULL) { 50077c478bd9Sstevel@tonic-gate printf("Failed to allocate memory for extent block log\n"); 50087c478bd9Sstevel@tonic-gate return (0); 50097c478bd9Sstevel@tonic-gate } 50107c478bd9Sstevel@tonic-gate memcpy(log_eb, b, nb); 50117c478bd9Sstevel@tonic-gate 50127c478bd9Sstevel@tonic-gate if (log_eb->nextbno != 0) 50137c478bd9Sstevel@tonic-gate /* 50147c478bd9Sstevel@tonic-gate * Currently, as of 11-Dec-1997 the field nextbno isn't 50157c478bd9Sstevel@tonic-gate * implemented. If someone starts using this sucker we'd 50167c478bd9Sstevel@tonic-gate * better warn somebody. 50177c478bd9Sstevel@tonic-gate */ 50187c478bd9Sstevel@tonic-gate printf("WARNING: extent block field nextbno is non-zero!\n"); 50197c478bd9Sstevel@tonic-gate 50207c478bd9Sstevel@tonic-gate /* 50217c478bd9Sstevel@tonic-gate * Now read in the on disk log structure. This is always in the 50227c478bd9Sstevel@tonic-gate * first block of the first extent. 50237c478bd9Sstevel@tonic-gate */ 50247c478bd9Sstevel@tonic-gate b = getblk((u_offset_t)ldbtob(logbtodb(fs, log_eb->extents[0].pbno))); 50257c478bd9Sstevel@tonic-gate log_odi = (ml_odunit_t *)malloc(sizeof (ml_odunit_t)); 50267c478bd9Sstevel@tonic-gate if (log_odi == NULL) { 50277c478bd9Sstevel@tonic-gate free(log_eb); 50287c478bd9Sstevel@tonic-gate log_eb = NULL; 50297c478bd9Sstevel@tonic-gate printf("Failed to allocate memory for ondisk structure\n"); 50307c478bd9Sstevel@tonic-gate return (0); 50317c478bd9Sstevel@tonic-gate } 50327c478bd9Sstevel@tonic-gate memcpy(log_odi, b, sizeof (ml_odunit_t)); 50337c478bd9Sstevel@tonic-gate 50347c478bd9Sstevel@tonic-gate /* 50357c478bd9Sstevel@tonic-gate * Consistency checks. 50367c478bd9Sstevel@tonic-gate */ 50377c478bd9Sstevel@tonic-gate if (log_odi->od_version != LUFS_VERSION_LATEST) { 50387c478bd9Sstevel@tonic-gate free(log_eb); 50397c478bd9Sstevel@tonic-gate log_eb = NULL; 50407c478bd9Sstevel@tonic-gate free(log_odi); 50417c478bd9Sstevel@tonic-gate log_odi = NULL; 50427c478bd9Sstevel@tonic-gate printf("Version mismatch in on-disk version of log data\n"); 50437c478bd9Sstevel@tonic-gate return (0); 50447c478bd9Sstevel@tonic-gate } else if (log_odi->od_badlog) { 50457c478bd9Sstevel@tonic-gate printf("WARNING: Log was marked as bad\n"); 50467c478bd9Sstevel@tonic-gate } 50477c478bd9Sstevel@tonic-gate 50487c478bd9Sstevel@tonic-gate return (1); 50497c478bd9Sstevel@tonic-gate } 50507c478bd9Sstevel@tonic-gate 5051d1a180b0Smaheshvs static void 50527c478bd9Sstevel@tonic-gate log_display_header(void) 50537c478bd9Sstevel@tonic-gate { 50547c478bd9Sstevel@tonic-gate int x; 50557c478bd9Sstevel@tonic-gate if (!log_get_header_info()) 50567c478bd9Sstevel@tonic-gate /* 50577c478bd9Sstevel@tonic-gate * No need to display anything here. The previous routine 50587c478bd9Sstevel@tonic-gate * has already done so. 50597c478bd9Sstevel@tonic-gate */ 50607c478bd9Sstevel@tonic-gate return; 50617c478bd9Sstevel@tonic-gate 50627c478bd9Sstevel@tonic-gate if (fs->fs_magic == FS_MAGIC) 50637c478bd9Sstevel@tonic-gate printf("Log block number: 0x%x\n------------------\n", 50647c478bd9Sstevel@tonic-gate fs->fs_logbno); 50657c478bd9Sstevel@tonic-gate else 50667c478bd9Sstevel@tonic-gate printf("Log frag number: 0x%x\n------------------\n", 50677c478bd9Sstevel@tonic-gate fs->fs_logbno); 50687c478bd9Sstevel@tonic-gate printf("Extent Info\n\t# Extents : %d\n\t# Bytes : 0x%x\n", 50697c478bd9Sstevel@tonic-gate log_eb->nextents, log_eb->nbytes); 50707c478bd9Sstevel@tonic-gate printf("\tNext Block : 0x%x\n\tExtent List\n\t--------\n", 50717c478bd9Sstevel@tonic-gate log_eb->nextbno); 50727c478bd9Sstevel@tonic-gate for (x = 0; x < log_eb->nextents; x++) 50737c478bd9Sstevel@tonic-gate printf("\t [%d] lbno 0x%08x pbno 0x%08x nbno 0x%08x\n", 50747c478bd9Sstevel@tonic-gate x, log_eb->extents[x].lbno, log_eb->extents[x].pbno, 50757c478bd9Sstevel@tonic-gate log_eb->extents[x].nbno); 50767c478bd9Sstevel@tonic-gate printf("\nOn Disk Info\n\tbol_lof : 0x%08x\n\teol_lof : 0x%08x\n", 50777c478bd9Sstevel@tonic-gate log_odi->od_bol_lof, log_odi->od_eol_lof); 50787c478bd9Sstevel@tonic-gate printf("\tlog_size : 0x%08x\n", 50797c478bd9Sstevel@tonic-gate log_odi->od_logsize); 50807c478bd9Sstevel@tonic-gate printf("\thead_lof : 0x%08x\tident : 0x%x\n", 50817c478bd9Sstevel@tonic-gate log_odi->od_head_lof, log_odi->od_head_ident); 50827c478bd9Sstevel@tonic-gate printf("\ttail_lof : 0x%08x\tident : 0x%x\n\thead_tid : 0x%08x\n", 50837c478bd9Sstevel@tonic-gate log_odi->od_tail_lof, log_odi->od_tail_ident, log_odi->od_head_tid); 50847c478bd9Sstevel@tonic-gate printf("\tcheck sum : 0x%08x\n", log_odi->od_chksum); 50857c478bd9Sstevel@tonic-gate if (log_odi->od_chksum != 50867c478bd9Sstevel@tonic-gate (log_odi->od_head_ident + log_odi->od_tail_ident)) 50877c478bd9Sstevel@tonic-gate printf("bad checksum: found 0x%08x, should be 0x%08x\n", 50887c478bd9Sstevel@tonic-gate log_odi->od_chksum, 50897c478bd9Sstevel@tonic-gate log_odi->od_head_ident + log_odi->od_tail_ident); 50907c478bd9Sstevel@tonic-gate if (log_odi->od_head_lof == log_odi->od_tail_lof) 50917c478bd9Sstevel@tonic-gate printf("\t --- Log is empty ---\n"); 50927c478bd9Sstevel@tonic-gate } 50937c478bd9Sstevel@tonic-gate 50947c478bd9Sstevel@tonic-gate /* 50957c478bd9Sstevel@tonic-gate * log_lodb -- logical log offset to disk block number 50967c478bd9Sstevel@tonic-gate */ 5097d1a180b0Smaheshvs int 50987c478bd9Sstevel@tonic-gate log_lodb(u_offset_t off, diskaddr_t *pblk) 50997c478bd9Sstevel@tonic-gate { 51007c478bd9Sstevel@tonic-gate uint32_t lblk = (uint32_t)btodb(off); 51017c478bd9Sstevel@tonic-gate int x; 51027c478bd9Sstevel@tonic-gate 5103594e4f22Sdmick if (!log_get_header_info()) 5104594e4f22Sdmick /* 5105594e4f22Sdmick * No need to display anything here. The previous routine 5106594e4f22Sdmick * has already done so. 5107594e4f22Sdmick */ 510882d3d86bSdmick return (0); 5109594e4f22Sdmick 51107c478bd9Sstevel@tonic-gate for (x = 0; x < log_eb->nextents; x++) 51117c478bd9Sstevel@tonic-gate if ((lblk >= log_eb->extents[x].lbno) && 51127c478bd9Sstevel@tonic-gate (lblk < (log_eb->extents[x].lbno + 51137c478bd9Sstevel@tonic-gate log_eb->extents[x].nbno))) { 51147c478bd9Sstevel@tonic-gate *pblk = (diskaddr_t)lblk - log_eb->extents[x].lbno + 51157c478bd9Sstevel@tonic-gate logbtodb(fs, log_eb->extents[x].pbno); 51167c478bd9Sstevel@tonic-gate return (1); 51177c478bd9Sstevel@tonic-gate } 51187c478bd9Sstevel@tonic-gate return (0); 51197c478bd9Sstevel@tonic-gate } 51207c478bd9Sstevel@tonic-gate 51217c478bd9Sstevel@tonic-gate /* 51227c478bd9Sstevel@tonic-gate * String names for the enumerated types. These are only used 51237c478bd9Sstevel@tonic-gate * for display purposes. 51247c478bd9Sstevel@tonic-gate */ 51257c478bd9Sstevel@tonic-gate char *dt_str[] = { 51267c478bd9Sstevel@tonic-gate "DT_NONE", "DT_SB", "DT_CG", "DT_SI", "DT_AB", 51277c478bd9Sstevel@tonic-gate "DT_ABZERO", "DT_DIR", "DT_INODE", "DT_FBI", 51287c478bd9Sstevel@tonic-gate "DT_QR", "DT_COMMIT", "DT_CANCEL", "DT_BOT", 51297c478bd9Sstevel@tonic-gate "DT_EOT", "DT_UD", "DT_SUD", "DT_SHAD", "DT_MAX" 51307c478bd9Sstevel@tonic-gate }; 51317c478bd9Sstevel@tonic-gate 51327c478bd9Sstevel@tonic-gate /* 51337c478bd9Sstevel@tonic-gate * log_read_log -- transfer information from the log and adjust offset 51347c478bd9Sstevel@tonic-gate */ 5135d1a180b0Smaheshvs int 51367c478bd9Sstevel@tonic-gate log_read_log(u_offset_t *addr, caddr_t va, int nb, uint32_t *chk) 51377c478bd9Sstevel@tonic-gate { 51387c478bd9Sstevel@tonic-gate int xfer; 51397c478bd9Sstevel@tonic-gate caddr_t bp; 51407c478bd9Sstevel@tonic-gate diskaddr_t pblk; 51417c478bd9Sstevel@tonic-gate sect_trailer_t *st; 51427c478bd9Sstevel@tonic-gate 51437c478bd9Sstevel@tonic-gate while (nb) { 51447c478bd9Sstevel@tonic-gate if (!log_lodb(*addr, &pblk)) { 51457c478bd9Sstevel@tonic-gate printf("Invalid log offset\n"); 51467c478bd9Sstevel@tonic-gate return (0); 51477c478bd9Sstevel@tonic-gate } 51487c478bd9Sstevel@tonic-gate 51497c478bd9Sstevel@tonic-gate /* 51507c478bd9Sstevel@tonic-gate * fsdb getblk() expects offsets not block number. 51517c478bd9Sstevel@tonic-gate */ 51527c478bd9Sstevel@tonic-gate if ((bp = getblk((u_offset_t)dbtob(pblk))) == NULL) 51537c478bd9Sstevel@tonic-gate return (0); 51547c478bd9Sstevel@tonic-gate 51557c478bd9Sstevel@tonic-gate xfer = MIN(NB_LEFT_IN_SECTOR(*addr), nb); 51567c478bd9Sstevel@tonic-gate if (va != NULL) { 51577c478bd9Sstevel@tonic-gate memcpy(va, bp + blkoff(fs, *addr), xfer); 51587c478bd9Sstevel@tonic-gate va += xfer; 51597c478bd9Sstevel@tonic-gate } 51607c478bd9Sstevel@tonic-gate nb -= xfer; 51617c478bd9Sstevel@tonic-gate *addr += xfer; 51627c478bd9Sstevel@tonic-gate 51637c478bd9Sstevel@tonic-gate /* 51647c478bd9Sstevel@tonic-gate * If the log offset is now at a sector trailer 51657c478bd9Sstevel@tonic-gate * run the checks if requested. 51667c478bd9Sstevel@tonic-gate */ 51677c478bd9Sstevel@tonic-gate if (NB_LEFT_IN_SECTOR(*addr) == 0) { 51687c478bd9Sstevel@tonic-gate if (chk != NULL) { 51697c478bd9Sstevel@tonic-gate st = (sect_trailer_t *) 51707c478bd9Sstevel@tonic-gate (bp + blkoff(fs, *addr)); 51717c478bd9Sstevel@tonic-gate if (*chk != st->st_ident) { 51727c478bd9Sstevel@tonic-gate printf( 51737c478bd9Sstevel@tonic-gate "Expected sector trailer id 0x%08x, but saw 0x%08x\n", 51747c478bd9Sstevel@tonic-gate *chk, st->st_ident); 51757c478bd9Sstevel@tonic-gate return (0); 51767c478bd9Sstevel@tonic-gate } else { 51777c478bd9Sstevel@tonic-gate *chk = st->st_ident + 1; 51787c478bd9Sstevel@tonic-gate /* 51797c478bd9Sstevel@tonic-gate * We update the on disk structure 51807c478bd9Sstevel@tonic-gate * transaction ID each time we see 51817c478bd9Sstevel@tonic-gate * one. By comparing this value 51827c478bd9Sstevel@tonic-gate * to the last valid DT_COMMIT record 51837c478bd9Sstevel@tonic-gate * we can determine if our log is 51847c478bd9Sstevel@tonic-gate * completely valid. 51857c478bd9Sstevel@tonic-gate */ 51867c478bd9Sstevel@tonic-gate log_odi->od_head_tid = st->st_tid; 51877c478bd9Sstevel@tonic-gate } 51887c478bd9Sstevel@tonic-gate } 51897c478bd9Sstevel@tonic-gate *addr += sizeof (sect_trailer_t); 51907c478bd9Sstevel@tonic-gate } 51917c478bd9Sstevel@tonic-gate if ((int32_t)*addr == log_odi->od_eol_lof) 51927c478bd9Sstevel@tonic-gate *addr = log_odi->od_bol_lof; 51937c478bd9Sstevel@tonic-gate } 51947c478bd9Sstevel@tonic-gate return (1); 51957c478bd9Sstevel@tonic-gate } 51967c478bd9Sstevel@tonic-gate 51977c478bd9Sstevel@tonic-gate u_offset_t 51987c478bd9Sstevel@tonic-gate log_nbcommit(u_offset_t a) 51997c478bd9Sstevel@tonic-gate { 52007c478bd9Sstevel@tonic-gate /* 52017c478bd9Sstevel@tonic-gate * Comments are straight from ufs_log.c 52027c478bd9Sstevel@tonic-gate * 52037c478bd9Sstevel@tonic-gate * log is the offset following the commit header. However, 52047c478bd9Sstevel@tonic-gate * if the commit header fell on the end-of-sector, then lof 52057c478bd9Sstevel@tonic-gate * has already been advanced to the beginning of the next 52067c478bd9Sstevel@tonic-gate * sector. So do nothgin. Otherwise, return the remaining 52077c478bd9Sstevel@tonic-gate * bytes in the sector. 52087c478bd9Sstevel@tonic-gate */ 52097c478bd9Sstevel@tonic-gate if ((a & (DEV_BSIZE - 1)) == 0) 52107c478bd9Sstevel@tonic-gate return (0); 52117c478bd9Sstevel@tonic-gate else 52127c478bd9Sstevel@tonic-gate return (NB_LEFT_IN_SECTOR(a)); 52137c478bd9Sstevel@tonic-gate } 52147c478bd9Sstevel@tonic-gate 52157c478bd9Sstevel@tonic-gate /* 52167c478bd9Sstevel@tonic-gate * log_show -- pretty print the deltas. The number of which is determined 52177c478bd9Sstevel@tonic-gate * by the log_enum arg. If LOG_ALLDELTAS the routine, as the 52187c478bd9Sstevel@tonic-gate * name implies dumps everything. If LOG_NDELTAS, the routine 52197c478bd9Sstevel@tonic-gate * will print out "count" deltas starting at "addr". If 52207c478bd9Sstevel@tonic-gate * LOG_CHECKSCAN then run through the log checking the st_ident 52217c478bd9Sstevel@tonic-gate * for valid data. 52227c478bd9Sstevel@tonic-gate */ 5223d1a180b0Smaheshvs static void 52247c478bd9Sstevel@tonic-gate log_show(enum log_enum l) 52257c478bd9Sstevel@tonic-gate { 52267c478bd9Sstevel@tonic-gate struct delta d; 52277c478bd9Sstevel@tonic-gate int32_t bol, eol; 52287c478bd9Sstevel@tonic-gate int x = 0; 52297c478bd9Sstevel@tonic-gate uint32_t chk; 52307c478bd9Sstevel@tonic-gate 52317c478bd9Sstevel@tonic-gate if (!log_get_header_info()) 52327c478bd9Sstevel@tonic-gate /* 52337c478bd9Sstevel@tonic-gate * No need to display any error messages here. The previous 52347c478bd9Sstevel@tonic-gate * routine has already done so. 52357c478bd9Sstevel@tonic-gate */ 52367c478bd9Sstevel@tonic-gate return; 52377c478bd9Sstevel@tonic-gate 52387c478bd9Sstevel@tonic-gate bol = log_odi->od_head_lof; 52397c478bd9Sstevel@tonic-gate eol = log_odi->od_tail_lof; 52407c478bd9Sstevel@tonic-gate chk = log_odi->od_head_ident; 52417c478bd9Sstevel@tonic-gate 52427c478bd9Sstevel@tonic-gate if (bol == eol) { 52437c478bd9Sstevel@tonic-gate if ((l == LOG_ALLDELTAS) || (l == LOG_CHECKSCAN)) { 52447c478bd9Sstevel@tonic-gate printf("Empty log.\n"); 52457c478bd9Sstevel@tonic-gate return; 52467c478bd9Sstevel@tonic-gate } else 52477c478bd9Sstevel@tonic-gate printf("WARNING: empty log. addr may generate bogus" 52487c478bd9Sstevel@tonic-gate " information"); 52497c478bd9Sstevel@tonic-gate } 52507c478bd9Sstevel@tonic-gate 52517c478bd9Sstevel@tonic-gate /* 52527c478bd9Sstevel@tonic-gate * Only reset the "addr" if we've been requested to show all 52537c478bd9Sstevel@tonic-gate * deltas in the log. 52547c478bd9Sstevel@tonic-gate */ 52557c478bd9Sstevel@tonic-gate if ((l == LOG_ALLDELTAS) || (l == LOG_CHECKSCAN)) 52567c478bd9Sstevel@tonic-gate addr = (u_offset_t)bol; 52577c478bd9Sstevel@tonic-gate 52587c478bd9Sstevel@tonic-gate if (l != LOG_CHECKSCAN) { 52597c478bd9Sstevel@tonic-gate printf(" Log Offset Delta Count Type\n"); 52607c478bd9Sstevel@tonic-gate printf("-----------------------------------------" 52617c478bd9Sstevel@tonic-gate "-----------------\n"); 52627c478bd9Sstevel@tonic-gate } 52637c478bd9Sstevel@tonic-gate 52647c478bd9Sstevel@tonic-gate while ((bol != eol) && ((l == LOG_ALLDELTAS) || 52657c478bd9Sstevel@tonic-gate (l == LOG_CHECKSCAN) || count--)) { 52667c478bd9Sstevel@tonic-gate if (!log_read_log(&addr, (caddr_t)&d, sizeof (d), 52677c478bd9Sstevel@tonic-gate ((l == LOG_ALLDELTAS) || (l == LOG_CHECKSCAN)) ? 52687c478bd9Sstevel@tonic-gate &chk : NULL)) 52697c478bd9Sstevel@tonic-gate /* 52707c478bd9Sstevel@tonic-gate * Two failures are possible. One from getblk() 52717c478bd9Sstevel@tonic-gate * which prints out a message or when we've hit 52727c478bd9Sstevel@tonic-gate * an invalid block which may or may not indicate 52737c478bd9Sstevel@tonic-gate * an error 52747c478bd9Sstevel@tonic-gate */ 52757c478bd9Sstevel@tonic-gate goto end_scan; 52767c478bd9Sstevel@tonic-gate 52777c478bd9Sstevel@tonic-gate if ((uint32_t)d.d_nb > log_odi->od_logsize) { 52787c478bd9Sstevel@tonic-gate printf("Bad delta entry. size out of bounds\n"); 52797c478bd9Sstevel@tonic-gate return; 52807c478bd9Sstevel@tonic-gate } 52817c478bd9Sstevel@tonic-gate if (l != LOG_CHECKSCAN) 52827c478bd9Sstevel@tonic-gate printf("[%04d] %08x %08x.%08x %08x %s\n", x++, bol, 52837c478bd9Sstevel@tonic-gate d.d_mof, d.d_nb, 52847c478bd9Sstevel@tonic-gate dt_str[d.d_typ >= DT_MAX ? DT_MAX : d.d_typ]); 52857c478bd9Sstevel@tonic-gate 52867c478bd9Sstevel@tonic-gate switch (d.d_typ) { 52877c478bd9Sstevel@tonic-gate case DT_CANCEL: 52887c478bd9Sstevel@tonic-gate case DT_ABZERO: 52897c478bd9Sstevel@tonic-gate /* 52907c478bd9Sstevel@tonic-gate * These two deltas don't have log space 52917c478bd9Sstevel@tonic-gate * associated with the entry even though 52927c478bd9Sstevel@tonic-gate * d_nb is non-zero. 52937c478bd9Sstevel@tonic-gate */ 52947c478bd9Sstevel@tonic-gate break; 52957c478bd9Sstevel@tonic-gate 52967c478bd9Sstevel@tonic-gate case DT_COMMIT: 52977c478bd9Sstevel@tonic-gate /* 52987c478bd9Sstevel@tonic-gate * Commit records have zero size yet, the 52997c478bd9Sstevel@tonic-gate * rest of the current disk block is avoided. 53007c478bd9Sstevel@tonic-gate */ 53017c478bd9Sstevel@tonic-gate addr += log_nbcommit(addr); 53027c478bd9Sstevel@tonic-gate lufs_tid = log_odi->od_head_tid; 53037c478bd9Sstevel@tonic-gate lufs_tid_valid = True; 53047c478bd9Sstevel@tonic-gate break; 53057c478bd9Sstevel@tonic-gate 53067c478bd9Sstevel@tonic-gate default: 53077c478bd9Sstevel@tonic-gate if (!log_read_log(&addr, NULL, d.d_nb, 53087c478bd9Sstevel@tonic-gate ((l == LOG_ALLDELTAS) || 53097c478bd9Sstevel@tonic-gate (l == LOG_CHECKSCAN)) ? &chk : NULL)) 53107c478bd9Sstevel@tonic-gate goto end_scan; 53117c478bd9Sstevel@tonic-gate break; 53127c478bd9Sstevel@tonic-gate } 53137c478bd9Sstevel@tonic-gate bol = (int32_t)addr; 53147c478bd9Sstevel@tonic-gate } 53157c478bd9Sstevel@tonic-gate 53167c478bd9Sstevel@tonic-gate end_scan: 53177c478bd9Sstevel@tonic-gate if (lufs_tid_valid == True) { 53187c478bd9Sstevel@tonic-gate if (lufs_tid == log_odi->od_head_tid) 53197c478bd9Sstevel@tonic-gate printf("scan -- okay\n"); 53207c478bd9Sstevel@tonic-gate else 53217c478bd9Sstevel@tonic-gate printf("scan -- some transactions have been lost\n"); 53227c478bd9Sstevel@tonic-gate } else { 53237c478bd9Sstevel@tonic-gate printf("scan -- failed to find a single valid transaction\n"); 53247c478bd9Sstevel@tonic-gate printf(" (possibly due to an empty log)\n"); 53257c478bd9Sstevel@tonic-gate } 53267c478bd9Sstevel@tonic-gate } 5327