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