File: util.c

package info (click to toggle)
xbanner 1.31-13
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 1,108 kB
  • ctags: 832
  • sloc: ansic: 5,084; sh: 263; csh: 168; makefile: 150
file content (312 lines) | stat: -rw-r--r-- 6,452 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
#include "xb_config.h"

#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <string.h>
#include <stdlib.h>

#ifndef vms
#include <malloc.h>
#endif

#include <X11/Xlib.h>
#include <X11/Xatom.h>

#include "xbanner.h"

#if !defined(HAS_USLEEP) && !defined(linux)

/* Ultrix has no usleep(), so I wrote it myself... */
#if !defined(vms)
_inline void usleep(const unsigned long usec)
{
  unsigned long diff=0;
  struct timeval start,now;

  gettimeofday(&start,NULL);	/* POSIX compliant, so should be OK */
  while(usec > diff)
  {
    gettimeofday(&now,NULL);
    diff = (now.tv_sec - start.tv_sec)*1000000L + (now.tv_usec - start.tv_usec);
  }
}
#else /* OpenVMS part ... */
void usleep(const unsigned long usec)
{
  lib$wait((float)usec/10000.0);
}
#endif /* vms */
#endif /* !def HAS_USLEEP */

#if defined(vms) || ( !defined(HAS_STRCMPI) && !defined(linux) && !defined(__BSD__) )

/* 2 functions to do case-insensitive comparison of strings */
int strcasecmp(char *s1,char *s2)
{
  while(toupper(*s1)==toupper(*s2) && *s1!='\0' && *s2!='\0')
  {
    s1++;
    s2++;
  }
  return (toupper(*s1)-toupper(*s2));
}

int strncasecmp(char *s1,char *s2,int n)
{
  while(toupper(*s1)==toupper(*s2) && n>=0 && *s1!='\0' && *s2!='\0')
  {
    n--;
    s1++;
    s2++;
  }
  return (toupper(*s1)-toupper(*s2));
}
#endif

/* from here on - stuff that I actually use... */

/* check if the property exists */
Bool XBPropExists(Display *disp,Window root,Atom xprop)
{
  int   num;
  Atom *proplist;

  /* get the list of properties of the root window */
  proplist=XListProperties(disp,root,&num);
  if(proplist==NULL || num==0)
    return False;

  /* look for our property... */
  do {
    num--;
    if(proplist[num] == xprop)
      return True;
  } while(num);

  return False;
}

/* check if a line is empty or a comment */
_inline Bool emptyline(char *s)
{
  char *p=s;

  while(isspace(*p))	/* skip the whitespaces */
    p++;
  if(*p=='#' || *p=='\0' || *p=='\r' || *p=='\n' || *p=='!')
    return True;
  return False;
}

/*
   general routine that takes a string, compares with a NULL terminated
   list of keywords and returns the index into the keyword list.
   May also print an error if not found
*/
int get_keyword(char *line, char *keywords[], char *err)
{
  int i;
  for(i=0;keywords[i]!=NULL;i++)
    if(strcmpi(keywords[i],line)==0)
      break;
  if(keywords[i]==NULL)
  {
    fprintf(stderr,"%s: %s:\n'%s'.\n",PRGCLASS,err,line);
    return -1;
  }
  return i;
}

/* check if s contains a color GradSpec */

/* #### NEEDS REWORK #### */

Bool is_grad_line(char *s)
{
  int parts=0;

  /* what's a typical color-gradient line? comma separated word list */
  while(*s)
  {
    if(is_sep(*s))	/* look for valid separators */
      parts++;
    else if(!isalnum(*s) && !isspace(*s) && *s!='#')
      return False;
    s++;
  }
  if(parts>0)
    return True;
  return False;    
}

/* some things needed for error reporting over the root window */
Bool show_errors=SHOW_ERR_DEFVAL;
char er_msg[1024] = " XBanner MSG: ";
char errline[256];	/* global for sprintf's */
Bool new_errors=False;

/* add an error/warning to the warning line */
static _inline void add_err(char *s)
{
  new_errors=True;
  strcat(er_msg,"# ");	/* for clarity */
  strcat(er_msg,s);
  strcat(er_msg," ");
}

/* actually draw the error line on the root window */
void display_errors(Display *disp,GC mgc)
{
  XFontStruct  *xfont;
  XCharStruct	xchrs;
  int dir,fasc,fdsc,lbear;      /* font ascent/descent/dir/bearing	*/
  int final_x,final_y;		/* where the text will finally appear	*/

  if(!new_errors)	/* nothing to display */
    return;

  /* some active things for the X server to do about the font... */
  xfont = XLoadQueryFont(disp,"fixed");		/* ask for the 'fixed'font */
  if(xfont == NULL)
  {
    fprintf(stderr,"%s: Could not get the font...\n",PRGCLASS);
    exit(1);
  }
  XSetFont(disp,mgc,xfont->fid);	/* make the GC use this font */
  /* get the font information */
  XQueryTextExtents(disp,xfont->fid,er_msg,strlen(er_msg),
  			&dir,&fasc,&fdsc,&xchrs);
  lbear = (xfont->per_char[0]).lbearing; /* important not to draw outside */

  /* calculate location */
  final_x = 16 + abs(lbear);
  final_y = 16 + fasc;

  /* get the colors - use BlackPixel and WhitePixel which are guaranteed */
  XSetForeground(disp,mgc,BlackPixel(disp,DefaultScreen(disp)));
  XSetBackground(disp,mgc,WhitePixel(disp,DefaultScreen(disp)));

  /* Draw the text and its BG */
  XDrawImageString(disp,RootWindow(disp,DefaultScreen(disp)),mgc,final_x,final_y,er_msg,strlen(er_msg));
  /* make sure the X server did this */
  XSync(disp,False);
}

void error(Display *disp,GC mgc, char *s, Bool Fatal)
{
  add_err(s);					/* add the error */
  fprintf(stderr,"%s: %s\n",PRGCLASS,s);	/* print to stderr */

  if(Fatal)		/* check if we need to exit */
  {
    if(show_errors)
      display_errors(disp,mgc);
    exit(1);
  }
}

/* generic routine that splits up a comma sep. line to components */
int split_names(char *line,char names[MAX_CYCS][MAX_CYCNAME])
{
  char *s = line;
  int idx=0;
  int j=0;

  while(*s)
  {
    if(is_sep(*s))
    {
      names[idx][j]='\0';
      j=0; idx++;
      s++; continue;
    }
    else
      names[idx][j]= *s;
    s++; j++;
  }
  names[idx][j]='\0';
  idx++;
  return idx;
} /* split names */

/* parse a string for environment variables */
static int do_env(char *env, char *dst, int *len)
{
  int ln=0;
  char *token;
  char *val;

  if(*env=='@')
  {
    *dst='@';
    *len = 1;
    return 1;
  }

  token = (char*)malloc(strlen(env)+1);
  if(token==NULL)
  {
    *len=1;
    free(token);
    return 1;
  }

  *len = 0;

  if(*env=='{')
  {
    *len = 2;	/* the { and the } */
    env++;
    while(*env!='}' && *env!='\0')
      token[ln++] = *env++;
  }
  else
  {
    while(isalnum(*env))
      token[ln++] = *env++;
  }
  token[ln]='\0';
  *len += ln;

  val=getenv(token);
  if(val==NULL)
  {
    *dst='\0';
    return 0;
  }
  strcpy(dst,val);
  free(token);
  return strlen(dst);
}

Bool parse_env(char *line)
{
  char *new,*k,*s;
  int len;

  new = (char*)malloc(MAX_BANNER_LEN);
  if(new==NULL)
  {
    fprintf(stderr,"%s: Couldn't allocate memory for env-var parsing.\n",PRGCLASS);
    return False;
  }
  k = new;
  s = line;

  while(*s)
  {
    if(*s == '$')
    {
      new += do_env(s+1,new,&len);
      s += len+1;
    }
    else
      *new++ = *s++;
  }
  *new='\0';
  strcpy(line,k);
  free(k);

  return True;
}