|
|
1.1 root 1: # include "stdio.h"
2: # include "cbt.h"
3: # include "ctype.h"
4: # include "assert.h"
5: # include "math.h"
6: # include "/usr/weather/progs/weath.h"
7: # define SAME 0
8:
9: char gdport[200], gdhap[200];
10: char *strchr();
11: double md=1000., dist(), xabs();
12: int abear;
13: bfile *bf;
14: bfile *happenfile;
15: char *direct[] =
16: {"N", "NE", "E", "SE", "S", "SW", "W", "NW", "N", "xx", "yy"};
17:
18: main(argc,argv)
19: char *argv[];
20: {
21: char line[100], request[100], rka[100], rra[300], from[100], fromloc[100];
22: char sna[100], *s, *excite();
23: mbuf key, rkey, rrec;
24: bfile *townfile;
25: FILE *fpat, *fair, *hpat, *hap;
26: double lat, lng, fromlat, fromlng;
27: int a1, a2, b1, b2, x, y, townfind, nf, j;
28: townfile = bopen("//usr/spool/town/ustowns", 0);
29: if (townfile==NULL)
30: {
31: fprintf(stderr, "No town list - is /crp mounted?\n");
32: exit(1);
33: }
34: happenfile = bopen("//usr/spool/town/happen", 0);
35: assert(happenfile!=NULL);
36: bf = bopen("/usr/spool/weather/air", 0);
37: assert(bf!=NULL);
38: fpat = fopen("/usr/spool/town/cityindex", "r");
39: assert(fpat!=NULL);
40: fair = fopen("/usr/spool/town/citypatch", "r");
41: assert(fair!=NULL);
42: hpat = fopen("/usr/spool/town/hapindex", "r");
43: hap = fopen("/usr/spool/town/haplist", "r");
44: rkey.mdata = rka; rrec.mdata = rra;
45: nf=0;
46: if (argc>1)
47: concat (from, argc, argv);
48: else
49: strcpy(from, "murray hill, nj");
50: lcase(from);
51: key.mdata = from; key.mlen = strlen(from);
52: bseek(townfile, key);
53: while (bread(townfile, &rkey, &rrec)==NULL)
54: {
55: if (strncmp(from, rkey.mdata, key.mlen)==SAME)
56: {
57: rrec.mdata[rrec.mlen]=0;
58: rkey.mdata[rkey.mlen]=0;
59: strcpy(fromloc, rrec.mdata);
60: strcpy(request, rkey.mdata);
61: nf++;
62: }
63: else
64: break;
65: }
66: if (nf<1)
67: printf("No such place: %s\n", from);
68: else if (nf>1)
69: printf("More than one such place: %s\n", from);
70: else
71: {
72: sscanf(fromloc, "%lf%lf", &fromlat, &fromlng);
73: caps(request);
74: printf(" [Reference point: %s (%.3f N, %.3f W)]\n", request, fromlat, fromlng);
75: }
76: while (gets(request))
77: {
78: if (strlen(request)==0)
79: continue;
80: if (strcmp(request, "q")==SAME)
81: break;
82: lcase(request);
83: townfind=0;
84: key.mdata = request; key.mlen = strlen(request);
85: bseek(townfile, key);
86: while (bread(townfile, &rkey, &rrec)==NULL)
87: {
88: rkey.mdata[rkey.mlen]=0;
89: rrec.mdata[rrec.mlen]=0;
90: if (strncmp(rkey.mdata, request, key.mlen)!=SAME)
91: break;
92: townfind++;
93: md=1000;
94: sscanf(rra, "%lf%lf", &lat, &lng);
95: caps(rka);
96: printf("%s: (%.3f N, %.3f W)", rka, lat, lng);
97: strcpy(sna, rka);
98: if (nf==1)
99: printf(" %.1f miles %s",
100: dist(fromlat, fromlng, lat, lng),
101: direct[bearing(fromlat, fromlng, lat, lng)]);
102: printf("\n");
103: printf("Zip code %5.5s. ", rra+15);
104: for(s=rra; *s; s++)
105: ;
106: s-=3;
107: switch(*s)
108: {
109: case '0': puts("Less than 2500 people."); break;
110: case '2': puts("2,500 to 5,000 people."); break;
111: case '3': puts("Between 5,000 and 10,000 people."); break;
112: case '4': puts("10,000 to 25,000 people."); break;
113: case '5': puts("25,000 to 50,000 people."); break;
114: case '6': puts("50,000 to 100,000 people."); break;
115: case '7': puts("Between 100,000 and 250,000 people."); break;
116: case '8': puts("Population over 250,000 but below 500,000."); break;
117: case '9': puts("Population exceeds 500,000."); break;
118: default: puts(""); break;
119: }
120: a1 = lat/4;
121: /* floating remainder not defined, so... */
122: if ( lat - 4.0*a1 >2.0)
123: a2 = a1+1;
124: else
125: a2 = a1-1;
126: b1 = lng/4;
127: if (lng - 4.0*b1 > 2.0)
128: b2 = b1+1;
129: else
130: b2 = b1-1;
131: if (*s!= '8' && *s!='9')
132: {
133: rewind(fpat);
134: while (fgets(line, 100, fpat))
135: {
136: x = atoi(line);
137: y = atoi(line+3);
138: if ((x==a1 || x==a2) && (y==b1 || y==b2))
139: ckair(line+6, lat, lng, fair);
140: }
141: if (md<1000.)
142: {
143: caps(gdport+6);
144: if (strncmp(rka, gdport+6, strlen(rka)))
145: printf(" Nearest city: %s, %5.1f miles %s\n",
146: gdport+6, md, direct[abear]);
147: }
148: }
149: weather(lat, lng);
150: lcase(rka);
151: j = bseek(happenfile, rkey);
152: if (j==1)
153: {
154: bread(happenfile, NULL, &rrec);
155: rrec.mdata[rrec.mlen]=0;
156: bput(rrec.mdata);
157: }
158: else
159: {
160: printf("Nothing much has happened lately in %s.\n", sna);
161: rewind (hpat);
162: md=1000.;
163: if (xabs(lat-(4.0*a1+2.0)) <= 1.80)
164: a2=a1;
165: if (xabs(lng-(4.0*b1+2.0)) <= 1.80)
166: b2=b1;
167: while (fgets(line, 100, hpat))
168: {
169: x = atoi(line);
170: y = atoi(line+3);
171: if ( (x==a1 || x==a2) && (y==b1 || y==b2))
172: ckcit (line+6, lat, lng, hap);
173: }
174: if (md<1000.)
175: {
176: strcpy(rka, gdhap+6);
177: caps(gdhap+6);
178: rkey.mlen = strlen(rka);
179: j = bseek (happenfile, rkey);
180: if (j==1)
181: {
182: bread(happenfile, NULL, &rrec);
183: if (md>0)
184: printf("But, %.1f miles away in %s %s, \n", md, excite(md), gdhap+6);
185: else
186: printf("But, nearby in %s %s, \n", excite(md+1.5), gdhap+6);
187: rrec.mdata[rrec.mlen]=0;
188: bput(rrec.mdata);
189: }
190: }
191: }
192: printf("\n");
193: }
194: if (townfind==0)
195: fprintf(stderr, "Town name not in our file\n");
196: }
197: exit(0);
198: }
199: bput(s)
200: char *s;
201: {
202: int col=0;
203: char buff[2048], *p;
204: p=buff;
205: while (*s)
206: {
207: if (col==0)
208: {
209: while (col++ < 5)
210: *p++ = ' ';
211: }
212: if (*s==' ' && col>60)
213: {
214: *p++ = '\n';
215: col=0;
216: }
217: else
218: {
219: *p++ = *s;
220: col++;
221: }
222: s++;
223: }
224: *p=0;
225: printf("%s", buff);
226: }
227: concat (out, ac, av)
228: char *out, *av[];
229: {
230: int i;
231: out[0]=0;
232: for(i=1; i<ac; i++)
233: {
234: strcat(out, av[i]);
235: if (i+1<ac)
236: strcat(out, " ");
237: }
238: return;
239: }
240: ckair(pos, lat, lng, fair)
241: FILE *fair;
242: char *pos;
243: double lat, lng;
244: {
245: char airport[200], opat[5], *s;
246: long fpt, atol();
247: double alat, alng, atof(), d;
248: fpt = atol(pos);
249: fseek (fair, fpt, 0);
250: opat[0]=0;
251: while (fgets(airport, 200, fair))
252: {
253: if (opat[0] && strncmp(opat, airport, 5)!=SAME)
254: break;
255: strncpy(opat, airport, 5);
256: for(s=airport; *s!='\t'; s++)
257: ;
258: *s++ = 0;
259: alat= atof(s);
260: while (*s!=' ')s++;
261: alng = atof(++s);
262: while (*s++ != ' ');
263: d = dist(lat, lng, alat, alng);
264: if (md>d)
265: {
266: md=d;
267: strcpy(gdport, airport);
268: abear = bearing (lat, lng, alat, alng);
269: }
270: }
271: }
272: double
273: dist (aplat, aplon, bplat, bplon)
274: double aplon, aplat, bplon, bplat;
275: {
276: /* this code is from the picadad manual. I don't pretend
277: to understand it. */
278: double as, bs, ac, bc, p, cd, d, er;
279: double rad=0.0174532925;
280: er = aplon-bplon;
281: if (er<0) er= -er;
282: if (er<0.001)
283: {
284: d = aplat-bplat;
285: if (d<0) d= -d;
286: return(d*69.055);
287: }
288: as = sin(rad*aplat);
289: bs = sin(rad*bplat);
290: ac = cos(rad*aplat);
291: bc = cos(rad*bplat);
292: p = cos(er*rad);
293: cd = (as*bs+ac*bc*p);
294: return( acos(cd)*3956.56);
295: }
296: bearing (lat, lng, alat, alng)
297: double lat, lng, alat, alng;
298: { /* gives bearing of alat, alng from lat, lng as 0-7 */
299: # define PI 3.1415926
300: double dlat, dlng, b;
301: dlat = alat-lat;
302: dlng = (alng-lng)*cos(PI*(lat+alat)/360.);
303: b = atan2(-dlng, dlat); /* range -pi to +pi */
304: b = b*(180./PI);
305: if (b<0) b=360+b;
306: return( (int) (b+22.5)/45.0);
307: }
308: lcase (s)
309: char *s;
310: {
311: int c;
312: for( ; c= *s; s++)
313: if (isupper(c))
314: *s = tolower(c);
315: }
316: caps(s)
317: char *s;
318: {
319: int c;
320: if (islower(*s)) *s = toupper(*s);
321: for( s++; c= *s; s++)
322: {
323: if (islower(c) && (s[-1]==' ' || s[-1]=='-'))
324: if (strncmp(s, "of ", 3)!=SAME)
325: *s = toupper(c);
326: if (*s==',') break;
327: }
328: for(s++; c= *s; s++)
329: if (islower(c)) *s=toupper(c);
330: }
331: ckcit(pos, lat, lng, fair)
332: FILE *fair;
333: char *pos;
334: double lat, lng;
335: {
336: char citline[200], opat[5], *s;
337: long fpt, atol();
338: double alat, alng, atof(), d;
339: fpt = atol(pos);
340: fseek (fair, fpt, 0);
341: opat[0]=0;
342: while (fgets(citline, 200, fair))
343: {
344: if (opat[0] && strncmp(opat, citline, 5)!=SAME)
345: break;
346: strncpy(opat, citline, 5);
347: for(s=citline; *s!='\t'; s++)
348: ;
349: *s++ = 0;
350: if (!ishap(s))continue;
351: alat= atof(s);
352: while (*s!=' ')s++;
353: alng = atof(++s);
354: while (*s++ != ' ');
355: d = dist(lat, lng, alat, alng);
356: if (md>d)
357: {
358: md=d;
359: strcpy(gdhap, citline);
360: }
361: }
362: }
363: ishap(s)
364: char *s;
365: {
366: while (*s)s++;
367: if (s[-3]=='x') return(1);
368: else return(0);
369: }
370: double
371: xabs(x)
372: double x;
373: {
374: return (x>= 0. ? x : -x);
375: }
376: char *
377: excite(x)
378: double x;
379: {
380: /* choose at random from a list of words */
381: switch(( (int)x)%5)
382: {
383: case 0: return("exciting");
384: case 1: return("swinging");
385: case 2: return("nearby");
386: case 3: return("the bright lights of");
387: case 4: return("booming");
388: }
389: return("exciting");
390: }
391: weather(north, west)
392: double north, west;
393: {
394: double d, dist(), md=5000., tnf, twf;
395: char tn[10], tw[10], *x, *y, fname[100], *vis(), odata[2000], *airname();
396: struct wline *wp, *bwp;
397: int n, w, f, kbear, isair;
398: n = north;
399: n = n-n%4;
400: w = west;
401: w = w-w%4;
402: bwp=NULL;
403: sprintf(fname, "/usr/spool/weather/obs/%.2d.%.2d", n, w);
404: f = open(fname, 0);
405: if (f<0) return;
406: n=read(f, odata, 2000);
407: assert(n<2000);
408: for(wp=(struct wline *)odata; (char *)wp <odata+n; wp++)
409: {
410: if (wp->anam[0]== '-')
411: continue;
412: strncpy(tn, wp->nlat, 5); tn[5]=0;
413: strncpy(tw, wp->nlng, 6); tw[6]=0;
414: d = dist(tnf=atof(tn), twf=atof(tw), north, west);
415: if (d<md)
416: {
417: md=d;
418: kbear = bearing(north, west, tnf, twf);
419: bwp=wp;
420: }
421: }
422: close(f);
423: if (bwp==NULL) return;
424: strncpy(tn, bwp->anam, 3); tn[3]=0;
425: x = airname(tn);
426: x = strchr(x, ' ');
427: while (isspace(*x))x++;
428: for(y=x+1; *y != ','; y++)
429: if (isupper(*y) && y[-1]!=' ')
430: *y = tolower(*y);
431: y = strchr(x, '*');
432: if (y==NULL)
433: isair=1;
434: else
435: {
436: *y=0;
437: isair=0;
438: }
439: strncpy(tw, bwp->wweath, 6); tw[6]=0;
440: y = vis(tw, bwp->wcloud[0]);
441: if (y==NULL) return;
442: printf("%.1f miles %s at%s %s,\n", md, direct[kbear],
443: isair ? " the airport in" : "", x);
444: printf(" temperature %.3s, weather%s\n", bwp->wtemp, y);
445: }
446: char *
447: vis(s, cloud)
448: char *s;
449: {
450: int d;
451: static char temp[50];
452: while (isspace(*s)) s++;
453: d= atoi(s);
454: while (isdigit(*s)) s++;
455: if (!isalpha(*s))
456: {
457: switch(cloud)
458: {
459: case 'C': s= "clear"; break;
460: case 'P': s= "partly cloudy"; break;
461: case 'O': s= "overcast"; break;
462: default: s= "ordinary"; break;
463: }
464: sprintf(temp, " %s, visibility %d miles", s, d);
465: return(temp);
466: }
467: temp[0]=0;
468: for( ; *s; s++)
469: switch(*s)
470: {
471: case 'A': strcat(temp, " hail"); break;
472: case 'D': strcat(temp, " dust"); break;
473: case 'F': strcat(temp, " fog"); break;
474: case 'H': strcat(temp, " haze"); break;
475: case 'I': if (s[1]=='P') strcat(temp, " sleet"); break;
476: case 'K': strcat(temp, " smoke"); break;
477: case 'L': strcat(temp, " drizzle"); break;
478: case 'R': strcat(temp, " rain"); break;
479: case 'W': strcat(temp, " showers"); break;
480: case 'S': strcat(temp, " snow"); break;
481: case 'T': strcat(temp, " thunderstorms"); break;
482: case 'Z': strcat(temp, " freezing"); break;
483: case ' ':
484: case '-': break;
485: default: return(NULL);
486: }
487: return(temp);
488: }
489: char *
490: airname(s)
491: char *s;
492: {
493: int i;
494: mbuf key, rkey, rec;
495: static char rb[100], rkb[100];
496: key.mdata = s;
497: key.mlen = strlen(s);
498: i=bseek(bf, key);
499: if (i!=1) return(NULL);
500: rkey.mdata =rkb; rec.mdata = rb;
501: bread(bf, &rkey, &rec);
502: rkey.mdata[rkey.mlen]=0;
503: assert(strcmp(rkey.mdata, key.mdata)==0);
504: rkey.mdata[rkey.mlen]=0;
505: rec.mdata[rec.mlen]=0;
506: return(rec.mdata);
507: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.