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