|
|
1.1 root 1: /*
2: * File: ipcs.c
3: *
4: * Purpose: main driver for ipcs utility.
5: * Revision 1.1 92/10/08 bin
6: * Initial revision
7: *
8: */
9:
10: /*
11: * ----------------------------------------------------------------------
12: * Includes.
13: */
14: #include <stdio.h>
15: #include <coff.h>
16: #include <fcntl.h>
17: #include <errno.h>
18: #include <string.h>
19: #include "ipcs.h"
20: /*
21: * ----------------------------------------------------------------------
22: * Definitions.
23: * Constants.
24: * Macros with argument lists.
25: * Typedefs.
26: * Enums.
27: */
28:
29: /*
30: * ----------------------------------------------------------------------
31: * Functions.
32: * Import Functions.
33: * Export Functions.
34: * Local Functions.
35: */
36: int iMemSeek(); /* Seek in the virtual memory */
37: /*
38: * ----------------------------------------------------------------------
39: * Global data
40: */
41:
42: /* Option's flags. See man pages for more info */
43: short qflag = 0, /* message q */
44: mflag = 0, /* shared memory */
45: sflag = 0, /* semaphores */
46: bflag = 0, /* biggest */
47: cflag = 0, /* creator name */
48: oflag = 0, /* outstanding usage */
49: pflag = 0, /* process ID */
50: tflag = 0, /* time */
51: aflag = 0, /* include b, c, o, p, & t */
52: Cflag = 0, /* corefile */
53: Nflag = 0; /* namelist */
54:
55: int total_shmids = 0, /* total shared memory segs found */
56: total_sems = 0, /* total semaphores found */
57: usemsqs = 0; /* is msq in use */
58:
59: int SHMMNI, /* total # shared memory segments */
60: SEMMNI, /* total # semaphores */
61: NMSQID; /* total # message queues */
62:
63: /*
64: * ----------------------------------------------------------------------
65: * Code.
66: */
67: main(argc, argv)
68: int argc;
69: char *argv[];
70: {
71: char *opstring = "qmsbcoptaVC:N: ";
72: extern char *optarg;
73: char *namelist = NULL;
74: char *fname,
75: *tmpfname; /* kernel name */
76: int c;
77:
78: while ((c = getopt(argc, argv, opstring)) != EOF)
79: switch (c) {
80: case 'q':
81: qflag = 1;
82: break;
83: case 'm':
84: mflag = 1;
85: break;
86: case 's':
87: sflag = 1;
88: break;
89: case 'b':
90: bflag = 1;
91: break;
92: case 'c':
93: cflag = 1;
94: break;
95: case 'o':
96: oflag = 1;
97: break;
98: case 'p':
99: pflag = 1;
100: break;
101: case 't':
102: tflag = 1;
103: break;
104: case 'a':
105: aflag = 1;
106: break;
107: case 'C':
108: /* Cflag = 1;
109: * corefile = optarg;
110: * break;
111: */
112: fprintf(stderr,
113: "ipcs: Corefile option NOT yet supported\n");
114: exit(1);
115: case 'N':
116: Nflag = 1;
117: namelist = optarg;
118: break;
119: case 'V':
120: printf("ipcs version %s\n", VERSION);
121: exit(0);
122: default:
123: usage(c);
124: }
125:
126: set_flags();
127:
128: /* Get kernel name. */
129: tmpfname = (Nflag ? namelist : pick_nfile());
130: if ((fname = malloc(strlen(tmpfname) + 1)) == NULL) {
131: perror("ipcs: cannot malloc kernel name:");
132: exit(1);
133: }
134: strcpy(fname, tmpfname);
135:
136: getmaxnum(fname);
137: get_data(fname);
138:
139: /* Now we can print */
140: if (qflag)
141: print_q();
142: if (mflag)
143: print_m();
144: if (sflag)
145: print_s();
146:
147: exit(0);
148: }
149:
150: /*
151: * set_flags does some additional processing for flags
152: */
153: set_flags()
154: {
155: /* Default is all ipc */
156: if (!(qflag + mflag + sflag))
157: qflag = mflag = sflag = 1;
158:
159: /* use all print options */
160: if (aflag)
161: bflag = cflag = oflag = pflag = tflag = 1;
162: }
163:
164: /*
165: * Get the following values from the corefile:
166: * SHMMNI: max number of allowable shared memory segments
167: * SEMMNI: max number of allowable semaphore sets
168: * NMSQID: max number of allowable message queues
169: */
170: getmaxnum(fname)
171: char *fname; /* Kernel file name */
172: {
173: SYMENT sym[3]; /* The table of names to find */
174: int fd; /* corefile file descriptor */
175: int val; /* Read values buffer */
176: int i; /* Loop index */
177:
178: /* Initialise SYMENT array */
179: for (i = 0; i < 3; i++) {
180: sym[i]._n._n_n._n_zeroes = 0; /* stuff for coffnlist */
181: sym[i].n_type = -1;
182: }
183: strcpy(sym[0].n_name, "SHMMNI");
184: strcpy(sym[1].n_name, "SEMMNI");
185: strcpy(sym[2].n_name, "NMSQID");
186:
187: /* do lookups. coffnlist returns 0 on error. */
188: if (!coffnlist(fname, sym, NULL, 3)) {
189: fprintf(stderr, "ipcs: error obtaining values from %s\n",
190: fname);
191: exit(1);
192: }
193:
194: /* Now we got addresses of the variables. So, we can go to memory
195: * and read proper values. sym[i].n_value contains addresses of
196: * variables.
197: */
198: /* Get max number of allowable shared memory segments */
199: if ((fd = iMemSeek(sym[0].n_value, 0)) < 0) /* Open and seek the */
200: exit(1); /* proper file */
201: if (read(fd, &val, sizeof(int)) != sizeof(int)) {
202: fprintf(stderr, "ipcs: read value of SHMMNI error\n");
203: exit(1);
204: }
205: close(fd);
206: SHMMNI = val;
207:
208: /* Get max number of allowable semaphores */
209: if ((fd = iMemSeek(sym[1].n_value, 0)) < 0) /* Open and seek the */
210: exit(1); /* proper file */
211: if (read(fd, &val, sizeof(int)) != sizeof(int)) {
212: fprintf(stderr, "ipcs: read value of SEMMNI error\n");
213: exit(1);
214: }
215: close(fd);
216: SEMMNI = val;
217:
218: /* Get max number of allowable message queues */
219: if ((fd = iMemSeek(sym[2].n_value, 0)) < 0) /* Open and seek the */
220: exit(1); /* proper file */
221: if (read(fd, &val, sizeof(int)) != sizeof(int)) {
222: fprintf(stderr, "ipcs: read value of NMSQID error\n");
223: exit(1);
224: }
225: NMSQID = val;
226:
227: close(fd);
228: }
229:
230: /*
231: * iMemSeek opens file and seeks in the memory. Uses /dev/kmem for low memory
232: * and /dev/kmemhi for the high memory.
233: * Return descriptor to the proper memory device or -1 on error.
234: */
235: int iMemSeek(lWhere, iHow)
236: long lWhere;
237: int iHow;
238: {
239: int fd; /* File descriptor */
240: char *cpMemLow = "/dev/kmem"; /* Low memory device */
241: char *cpMemHigh = "/dev/kmemhi"; /* High memory device */
242: char *cpMem; /* Memory to use */
243: long lMemBorder = 0x80000000; /* Border between devices */
244: long lMemWhere; /* Point to seek */
245: char cErrBuf[32]; /* Error buffer */
246:
247: if (lWhere & lMemBorder) {
248: cpMem = cpMemHigh;
249: lMemWhere = lWhere ^ lMemBorder;
250: } else {
251: cpMem = cpMemLow;
252: lMemWhere = lWhere;
253: }
254: /* Open proper memory device */
255: if ((fd = open(cpMem, O_RDONLY)) < 0) {
256: sprintf(cErrBuf, "ipcs: cannot open %s", cpMem);
257: perror(cErrBuf);
258: return -1;
259: }
260: /* Seek to the requested position */
261: if (lseek(fd, lMemWhere, iHow) < 0) {
262: perror("ipcs: seek failed:");
263: close(fd);
264: return -1;
265: }
266: return fd;
267: }
268:
269: /*
270: * ipcs usage. Print message and die
271: */
272: usage(c)
273: int c;
274: {
275: fprintf(stderr, "ipcs: illegal option - %c\n", c);
276: fprintf(stderr, "usage: "
277: "ipcs [-abcmopqstV] [-C corefile] [-N namelist]\n");
278: exit(1);
279: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.