1    	/*
2    	 * utils for pmlogextract
3    	 *
4    	 * Copyright (c) 1997-2002 Silicon Graphics, Inc.  All Rights Reserved.
5    	 * 
6    	 * This program is free software; you can redistribute it and/or modify it
7    	 * under the terms of the GNU General Public License as published by the
8    	 * Free Software Foundation; either version 2 of the License, or (at your
9    	 * option) any later version.
10   	 * 
11   	 * This program is distributed in the hope that it will be useful, but
12   	 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13   	 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14   	 * for more details.
15   	 */
16   	
17   	#include "pmapi.h"
18   	#include "impl.h"
19   	
20   	/*
21   	 * raw read of next log record - largely stolen from __pmLogRead in libpcp
22   	 */
23   	int
24   	_pmLogGet(__pmLogCtl *lcp, int vol, __pmPDU **pb)
25   	{
26   	    int		head;
27   	    int		tail;
28   	    int		sts;
29   	    long	offset;
30   	    char	*p;
31   	    __pmPDU	*lpb;
32   	    FILE	*f;
33   	
34   	    if (vol == PM_LOG_VOL_META)
35   		f = lcp->l_mdfp;
36   	    else
37   		f = lcp->l_mfp;
38   	
Event negative_return_fn: Function "ftell(f)" returns a negative number.
Event var_assign: Assigning: signed variable "offset" = "ftell".
Also see events: [negative_returns][negative_returns]
39   	    offset = ftell(f);
40   	#ifdef PCP_DEBUG
At conditional (1): "pmDebug & 0x80": Taking true branch.
41   	    if (pmDebug & DBG_TRACE_LOG) {
42   		fprintf(stderr, "_pmLogGet: fd=%d vol=%d posn=%ld ",
43   		    fileno(f), vol, offset);
44   	    }
45   	#endif
46   	
47   	again:
48   	    sts = (int)fread(&head, 1, sizeof(head), f);
At conditional (2): "sts != sizeof (head) /*4*/": Taking true branch.
49   	    if (sts != sizeof(head)) {
At conditional (3): "sts == 0": Taking true branch.
50   		if (sts == 0) {
51   	#ifdef PCP_DEBUG
At conditional (4): "pmDebug & 0x80": Taking true branch.
52   		    if (pmDebug & DBG_TRACE_LOG)
53   			fprintf(stderr, "AFTER end\n");
54   	#endif
Event negative_returns: "offset" is passed to a parameter that cannot be negative.
Also see events: [negative_return_fn][var_assign][negative_returns]
55   		    fseek(f, offset, SEEK_SET);
56   		    if (vol != PM_LOG_VOL_META) {
57   			if (lcp->l_curvol < lcp->l_maxvol) {
58   			    if (__pmLogChangeVol(lcp, lcp->l_curvol+1) == 0) {
59   				f = lcp->l_mfp;
60   				goto again;
61   			    }
62   			}
63   		    }
64   		    return PM_ERR_EOL;
65   		}
66   	#ifdef PCP_DEBUG
67   		if (pmDebug & DBG_TRACE_LOG)
68   		    fprintf(stderr, "Error: hdr fread=%d %s\n", sts, osstrerror());
69   	#endif
70   		if (sts > 0)
71   		    return PM_ERR_LOGREC;
72   		else
73   		    return -oserror();
74   	    }
75   	
76   	    if ((lpb = (__pmPDU *)malloc(ntohl(head))) == NULL) {
77   	#ifdef PCP_DEBUG
78   		if (pmDebug & DBG_TRACE_LOG)
79   		    fprintf(stderr, "Error: __pmFindPDUBuf(%d) %s\n",
80   			(int)ntohl(head), osstrerror());
81   	#endif
82   		fseek(f, offset, SEEK_SET);
83   		return -oserror();
84   	    }
85   	
86   	    lpb[0] = head;
87   	    if ((sts = (int)fread(&lpb[1], 1, ntohl(head) - sizeof(head), f)) != ntohl(head) - sizeof(head)) {
88   	#ifdef PCP_DEBUG
89   		if (pmDebug & DBG_TRACE_LOG)
90   		    fprintf(stderr, "Error: data fread=%d %s\n", sts, osstrerror());
91   	#endif
92   		if (sts == 0) {
Event negative_returns: "offset" is passed to a parameter that cannot be negative.
Also see events: [negative_return_fn][var_assign][negative_returns]
93   		    fseek(f, offset, SEEK_SET);
94   		    return PM_ERR_EOL;
95   		}
96   		else if (sts > 0)
97   		    return PM_ERR_LOGREC;
98   		else
99   		    return -oserror();
100  	    }
101  	
102  	
103  	    p = (char *)lpb;
104  	    memcpy(&tail, &p[ntohl(head) - sizeof(head)], sizeof(head));
105  	    if (head != tail) {
106  	#ifdef PCP_DEBUG
107  		if (pmDebug & DBG_TRACE_LOG)
108  		    fprintf(stderr, "Error: head-tail mismatch (%d-%d)\n",
109  			(int)ntohl(head), (int)ntohl(tail));
110  	#endif
111  		return PM_ERR_LOGREC;
112  	    }
113  	
114  	#ifdef PCP_DEBUG
115  	    if (pmDebug & DBG_TRACE_LOG) {
116  		if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
117  		    fprintf(stderr, "@");
118  		    if (sts >= 0) {
119  			struct timeval	stamp;
120  			__pmTimeval		*tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
121  			stamp.tv_sec = ntohl(tvp->tv_sec);
122  			stamp.tv_usec = ntohl(tvp->tv_usec);
123  			__pmPrintStamp(stderr, &stamp);
124  		    }
125  		    else
126  			fprintf(stderr, "unknown time");
127  		}
128  		fprintf(stderr, " len=%d (incl head+tail)\n", (int)ntohl(head));
129  	    }
130  	#endif
131  	
132  	#ifdef PCP_DEBUG
133  	    if (pmDebug & DBG_TRACE_PDU) {
134  		int		i, j;
135  		struct timeval	stamp;
136  		__pmTimeval	*tvp = (__pmTimeval *)&lpb[vol == PM_LOG_VOL_META ? 2 : 1];
137  		fprintf(stderr, "_pmLogGet");
138  		if (vol != PM_LOG_VOL_META || ntohl(lpb[1]) == TYPE_INDOM) {
139  		    fprintf(stderr, " timestamp=");
140  		    stamp.tv_sec = ntohl(tvp->tv_sec);
141  		    stamp.tv_usec = ntohl(tvp->tv_usec);
142  		    __pmPrintStamp(stderr, &stamp);
143  		}
144  		fprintf(stderr, " " PRINTF_P_PFX "%p ... " PRINTF_P_PFX "%p", lpb, &lpb[ntohl(head)/sizeof(__pmPDU) - 1]);
145  		fputc('\n', stderr);
146  		fprintf(stderr, "%03d: ", 0);
147  		for (j = 0, i = 0; j < ntohl(head)/sizeof(__pmPDU); j++) {
148  		    if (i == 8) {
149  			fprintf(stderr, "\n%03d: ", j);
150  			i = 0;
151  		    }
152  		    fprintf(stderr, "0x%x ", lpb[j]);
153  		    i++;
154  		}
155  		fputc('\n', stderr);
156  	    }
157  	#endif
158  	
159  	    *pb = lpb;
160  	    return 0;
161  	}
162  	
163  	int
164  	_pmLogPut(FILE *f, __pmPDU *pb)
165  	{
166  	    int		rlen = ntohl(pb[0]);
167  	    int		sts;
168  	
169  	#ifdef PCP_DEBUG
170  	    if (pmDebug & DBG_TRACE_LOG) {
171  		fprintf(stderr, "_pmLogPut: fd=%d rlen=%d\n",
172  		    fileno(f), rlen);
173  	    }
174  	#endif
175  	
176  	    if ((sts = (int)fwrite(pb, 1, rlen, f)) != rlen) {
177  	#ifdef PCP_DEBUG
178  		if (pmDebug & DBG_TRACE_LOG)
179  		    fprintf(stderr, "_pmLogPut: fwrite=%d %s\n", sts, osstrerror());
180  	#endif
181  		return -oserror();
182  	    }
183  	    return 0;
184  	}