|
|
1.1 ! root 1: # include "stdio.h" ! 2: # include "cbt.h" ! 3: # include "ctype.h" ! 4: # include "assert.h" ! 5: # include "weath.h" ! 6: # include "signal.h" ! 7: # include "setjmp.h" ! 8: # include "math.h" ! 9: # include "sys/types.h" ! 10: # include "time.h" ! 11: # include "sys/timeb.h" ! 12: # define SAME 0 ! 13: ! 14: double md=1000., dist(); ! 15: struct timeb ftb; ! 16: bfile *bf; ! 17: char *index(), *timezone(), *relhum(); ! 18: struct tm *localtime(); ! 19: bfile *townfile; ! 20: int marine=0, intr(); ! 21: jmp_buf env; ! 22: char *direct[] = ! 23: {"N", "NE", "E", "SE", "S", "SW", "W", "NW", "N", "xx", "yy"}; ! 24: ! 25: main(argc,argv) ! 26: char *argv[]; ! 27: { ! 28: char request[100]; ! 29: townfile = bopen("/usr/mel/ustowns/ustownsn", 0); ! 30: if (townfile==NULL) ! 31: { ! 32: fprintf(stderr, "No town list - is /crp mounted?\n"); ! 33: exit(1); ! 34: } ! 35: bf = bopen("/data/weather/airn", 0); ! 36: assert(bf!=NULL); ! 37: ftime(&ftb); ! 38: argc--; argv++; ! 39: while (argc>0 && argv[0][0]=='-') ! 40: { ! 41: switch(argv[0][1]) ! 42: { ! 43: case 'm': marine=1; break; ! 44: case 'h': strcpy(request, "murray hill, nj"); break; ! 45: default: ! 46: fprintf(stderr, "Unknown arg: %s\n", argv[0]); ! 47: break; ! 48: } ! 49: argc--; argv++; ! 50: } ! 51: if (argc>1) ! 52: { ! 53: fprintf(stderr, "Sorry: weather changed to expect town on standard input.\n"); ! 54: fprintf(stderr, "Default MH is now 'weather -h'\n"); ! 55: return(0); ! 56: } ! 57: if (request[0]) ! 58: wprint(request); ! 59: else ! 60: while (1) /* this loop is basically while (gets(request)) with interrupt */ ! 61: { ! 62: setjmp(env); ! 63: signal(SIGINT, SIG_DFL); ! 64: if (gets(request)==NULL) ! 65: break; ! 66: signal(SIGINT, intr); ! 67: wprint(request); ! 68: } ! 69: return(0); ! 70: } ! 71: wprint(request) ! 72: char *request; ! 73: { ! 74: char sna[100], rka[100], rra[300]; ! 75: double lat, lng; ! 76: mbuf key, rkey, rrec; ! 77: int townfind; ! 78: rkey.mdata = rka; rrec.mdata = rra; ! 79: lcase(request); ! 80: while (isspace(*request)) request++; ! 81: if (*request==0) return; ! 82: townfind=0; ! 83: key.mdata = request; key.mlen = strlen(request); ! 84: bseek(townfile, key); ! 85: while (bread(townfile, &rkey, &rrec)==NULL) ! 86: { ! 87: rkey.mdata[rkey.mlen]=0; ! 88: rrec.mdata[rrec.mlen]=0; ! 89: if (strncmp(rkey.mdata, request, key.mlen)!=SAME) ! 90: break; ! 91: townfind++; ! 92: md=1000; ! 93: sscanf(rra, "%lf%lf", &lat, &lng); ! 94: caps(rka); ! 95: printf("%s: (%.3f N, %.3f W)\n", rka, lat, lng); ! 96: strcpy(sna, rka); ! 97: /* floating remainder not defined, so... */ ! 98: weather(lat, lng); ! 99: lfmfore(lat, lng); ! 100: forecast(lat, lng); ! 101: } ! 102: if (townfind==0) ! 103: fprintf(stderr, "No such town\n"); ! 104: return; ! 105: } ! 106: concat (out, ac, av) ! 107: char *out, *av[]; ! 108: { ! 109: int i; ! 110: out[0]=0; ! 111: for(i=1; i<ac; i++) ! 112: { ! 113: strcat(out, av[i]); ! 114: if (i+1<ac) ! 115: strcat(out, " "); ! 116: } ! 117: return; ! 118: } ! 119: double ! 120: dist (aplat, aplon, bplat, bplon) ! 121: double aplon, aplat, bplon, bplat; ! 122: { ! 123: /* this code is from the picadad manual. I don't pretend ! 124: to understand it. */ ! 125: double as, bs, ac, bc, p, cd, d, er; ! 126: double rad=0.0174532925; ! 127: er = aplon-bplon; ! 128: if (er<0) er= -er; ! 129: if (er<0.001) ! 130: { ! 131: d = aplat-bplat; ! 132: if (d<0) d= -d; ! 133: return(d*69.055); ! 134: } ! 135: as = sin(rad*aplat); ! 136: bs = sin(rad*bplat); ! 137: ac = cos(rad*aplat); ! 138: bc = cos(rad*bplat); ! 139: p = cos(er*rad); ! 140: cd = (as*bs+ac*bc*p); ! 141: return( acos(cd)*3956.56); ! 142: } ! 143: bearing (lat, lng, alat, alng) ! 144: double lat, lng, alat, alng; ! 145: { /* gives bearing of alat, alng from lat, lng as 0-7 */ ! 146: # define PI 3.1415926 ! 147: double dlat, dlng, b; ! 148: dlat = alat-lat; ! 149: dlng = (alng-lng)*cos(PI*(lat+alat)/360.); ! 150: b = atan2(-dlng, dlat); /* range -pi to +pi */ ! 151: b = b*(180./PI); ! 152: if (b<0) b=360+b; ! 153: return( (int) (b+22.5)/45.0); ! 154: } ! 155: lcase (s) ! 156: char *s; ! 157: { ! 158: int c; ! 159: for( ; c= *s; s++) ! 160: if (isupper(c)) ! 161: *s = tolower(c); ! 162: } ! 163: caps(s) ! 164: char *s; ! 165: { ! 166: int c; ! 167: if (islower(*s)) *s = toupper(*s); ! 168: for( s++; c= *s; s++) ! 169: { ! 170: if (islower(c) && (s[-1]==' ' || s[-1]=='-')) ! 171: if (strncmp(s, "of ", 3)!=SAME) ! 172: *s = toupper(c); ! 173: if (*s==',') break; ! 174: } ! 175: for(s++; c= *s; s++) ! 176: if (islower(c)) *s=toupper(c); ! 177: } ! 178: weather(north, west) ! 179: double north, west; ! 180: { ! 181: double d, dist(), md=5000., tnf, twf; ! 182: char tn[10], tw[10], *x, *y, fname[100], *vis(), odata[2000], *airname(); ! 183: char *ampm, *tz, tb[10]; ! 184: int hr, min; ! 185: struct wline *wp, *bwp; ! 186: int n, w, f, kbear, isair, windsp, wdir, gust; ! 187: n = north; ! 188: n = n-n%4; ! 189: w = west; ! 190: w = w-w%4; ! 191: bwp=NULL; ! 192: sprintf(fname, "/data/weather/obs/%.2d.%.2d", n, w); ! 193: f = open(fname, 0); ! 194: if (f<0) return; ! 195: printf("fname %s\n", fname); ! 196: n=read(f, odata, 2000); ! 197: assert(n<2000); ! 198: /* next line is for(wp=odata; wp<odata+n; wp++) after delinting */ ! 199: for(wp=(struct wline *) odata; wp< (struct wline *)(odata+n); wp++) ! 200: { ! 201: strncpy(tn, wp->nlat, 5); tn[5]=0; ! 202: strncpy(tw, wp->nlng, 6); tw[6]=0; ! 203: d = dist(tnf=atof(tn), twf=atof(tw), north, west); ! 204: printf("airport %.3s dist %f\n", wp, d); ! 205: if (d<md) ! 206: { ! 207: md=d; ! 208: kbear = bearing(north, west, tnf, twf); ! 209: bwp=wp; ! 210: } ! 211: } ! 212: close(f); ! 213: if (bwp==NULL) return; ! 214: strncpy(tn, bwp->anam, 3); tn[3]=0; ! 215: x = airname(tn); ! 216: x = index(x, ' '); ! 217: while (isspace(*x))x++; ! 218: for(y=x+1; *y != ','; y++) ! 219: if (isupper(*y) && isalpha(y[-1])) ! 220: *y = tolower(*y); ! 221: y = index(x, '*'); ! 222: if (y==NULL) ! 223: isair=1; ! 224: else ! 225: { ! 226: *y=0; ! 227: isair=0; ! 228: } ! 229: strncpy(tw, bwp->wweath, 6); tw[6]=0; ! 230: y = vis(tw, bwp->wcloud[0]); ! 231: if (y==NULL) return; ! 232: printf("%.1f miles %s at%s %s", md, direct[kbear], ! 233: isair ? " the airport in" : "", x); ! 234: strncpy(tb, bwp->wtime, 4); tb[4]=0; ! 235: hr = atoi(tb); ! 236: min = hr%100; ! 237: hr = hr/100; ! 238: hr = hr - ftb.timezone/60; ! 239: if (ftb.dstflag) hr++; ! 240: if (hr < 0) hr+=24; ! 241: ampm = (hr>11) ? "PM" : "AM"; ! 242: if (hr>12) hr -= 12; ! 243: tz = timezone(ftb.timezone, ftb.dstflag); ! 244: printf(" (%d:%.2d %s %s):\n", hr, min, ampm, tz); ! 245: strncpy(tb, bwp->wtemp, 3); tb[3]=0; ! 246: strncpy(tn, bwp->wdewpt, 3); tn[3]=0; ! 247: printf(" temperature %.3s, humidity %s, weather%s", ! 248: bwp->wtemp, relhum(atoi(tb), atoi(tn)), y); ! 249: windsp = atoi(bwp->wwind+2); ! 250: if (windsp >10) ! 251: { ! 252: bwp->wwind[2]=0; ! 253: wdir = atoi(bwp->wwind); ! 254: if (bwp->wwind[4]=='G') ! 255: gust = atoi(bwp->wwind+5); ! 256: else ! 257: gust=0; ! 258: wdir = (wdir*10+22.5)/45.0; ! 259: printf(",\n winds at %d knots", windsp); ! 260: printf(" from the %s", direct[wdir]); ! 261: if (gust) printf(" gusting to %d", gust); ! 262: } ! 263: printf("\n"); ! 264: } ! 265: char * ! 266: vis(s, cloud) ! 267: char *s; ! 268: { ! 269: int d; ! 270: static char temp[80]; ! 271: char tb[30]; ! 272: while (isspace(*s)) s++; ! 273: d= atoi(s); ! 274: while (isdigit(*s)) s++; ! 275: if (!isalpha(*s)) ! 276: { ! 277: switch(cloud) ! 278: { ! 279: case 'C': s= "clear"; break; ! 280: case 'P': s= "partly cloudy"; break; ! 281: case 'O': s= "overcast"; break; ! 282: default: s= "ordinary"; break; ! 283: } ! 284: sprintf(temp, " %s, visibility %d miles", s, d); ! 285: return(temp); ! 286: } ! 287: temp[0]=0; ! 288: for( ; *s; s++) ! 289: switch(*s) ! 290: { ! 291: case 'A': strcat(temp, " hail"); break; ! 292: case 'D': strcat(temp, " dust"); break; ! 293: case 'F': strcat(temp, " fog"); break; ! 294: case 'H': strcat(temp, " haze"); break; ! 295: case 'I': if (s[1]=='P') strcat(temp, " sleet"); break; ! 296: case 'K': strcat(temp, " smoke"); break; ! 297: case 'L': strcat(temp, " drizzle"); break; ! 298: case 'R': strcat(temp, " rain"); break; ! 299: case 'W': strcat(temp, " showers"); break; ! 300: case 'S': strcat(temp, " snow"); break; ! 301: case 'T': strcat(temp, " thunderstorms"); break; ! 302: case 'Z': strcat(temp, " freezing"); break; ! 303: case ' ': ! 304: case '-': break; ! 305: default: return(NULL); ! 306: } ! 307: sprintf(tb, ", visibility %d miles", d); ! 308: strcat(temp, tb); ! 309: return(temp); ! 310: } ! 311: char * ! 312: airname(s) ! 313: char *s; ! 314: { ! 315: int i; ! 316: mbuf key, rkey, rec; ! 317: static char rb[100], rkb[100]; ! 318: key.mdata = s; ! 319: key.mlen = strlen(s); ! 320: i=bseek(bf, key); ! 321: if (i!=1) return(NULL); ! 322: rkey.mdata =rkb; rec.mdata = rb; ! 323: bread(bf, &rkey, &rec); ! 324: rkey.mdata[rkey.mlen]=0; ! 325: assert(strcmp(rkey.mdata, key.mdata)==0); ! 326: rkey.mdata[rkey.mlen]=0; ! 327: rec.mdata[rec.mlen]=0; ! 328: return(rec.mdata); ! 329: } ! 330: lfmfore(north, west) ! 331: double north, west; ! 332: { ! 333: double d, dist(), md=5000., tnf, twf; ! 334: char aname[10], *x, *y, fname[60], xl[30], ln[60], lf1[60], ltime[20]; ! 335: int n, w, in, jw, iw, jn; ! 336: int p1, p2, max, min, hr, dy; char *ampm, *revampm, *tz; ! 337: FILE *f; ! 338: n = north; ! 339: n = n-n%4; ! 340: w = west; ! 341: w = w-w%4; ! 342: in = jn = n; ! 343: if ( (int) north %4 >=2) jn+=4; else in-=4; ! 344: iw = jw = w; ! 345: if ( (int) west %4 >=2 ) jw+=4; else iw-=4; ! 346: aname[0]=0; ! 347: for(n=in; n<=jn; n+=4) ! 348: for(w=iw; w<=jw; w+=4) ! 349: { ! 350: sprintf(fname, "/data/weather/lfm/%.2d.%.2d", n, w); ! 351: f = fopen(fname, "r"); ! 352: if (f==NULL) continue; ! 353: while (fgets(xl, 20, f)) ! 354: { ! 355: tnf = atof(xl+4); ! 356: twf = atof(xl+9); ! 357: d = dist(tnf, twf, north, west); ! 358: if (d<md) ! 359: { ! 360: md=d; ! 361: strncpy(aname, xl, 3); ! 362: aname[3]=0; ! 363: } ! 364: } ! 365: fclose(f); ! 366: } ! 367: if (aname[0]==0) return; ! 368: sprintf(fname, "/data/weather/lfm/%s", aname); ! 369: f = fopen(fname, "r"); ! 370: if (f==NULL) return; ! 371: puts(""); ! 372: fgets(ln, 60, f); ! 373: trimnl(ln); ! 374: for(x=ln+1; *x!= ','; x++) ! 375: if (isupper(*x) && isalpha(x[-1])) ! 376: *x = tolower(*x); ! 377: y = index(ln, '*'); ! 378: if (y!=NULL) *y=0; ! 379: printf("Next 48 hours at %s\n", ln); ! 380: while (fgets(lf1, 60, f)) ! 381: { ! 382: sscanf(lf1, "%s %d %d %d %d", ltime, &max, &min, &p1, &p2); ! 383: hr = atoi(ltime+3); ! 384: dy = atoi(ltime); ! 385: hr = hr - ftb.timezone/60; ! 386: hr += 12; /* question is whether the periods end or start as shown ! 387: in forecast ; this converts to ending */ ! 388: if (hr>=24) ! 389: { ! 390: /* this should not be executed ever,since orign hr is 0 or 12 and ! 391: then we subract 4; */ ! 392: hr-=24; dy++; ! 393: } ! 394: if (ftb.dstflag) hr++; ! 395: if (hr<0) { ! 396: hr += 24; ! 397: dy = down(dy); ! 398: } ! 399: ampm = (hr>11) ? "PM" : "AM"; ! 400: revampm = (hr>11) ? "AM" : "PM"; ! 401: if (hr>12) hr -= 12; ! 402: tz = timezone(ftb.timezone, ftb.dstflag); ! 403: printf("To %d %s %s /%d: high %d low %d, prob. precip. to %d %s %d%% to %d %s %d%%\n", ! 404: hr, ampm, tz, dy, max, min, hr, revampm, p1, hr, ampm, p2); ! 405: } ! 406: fclose(f); ! 407: } ! 408: int monlen[12] = ! 409: /*Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec */ ! 410: { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; ! 411: down(dy) ! 412: { /* subtracts one from the day */ ! 413: struct tm *tp; ! 414: int mn; ! 415: if (--dy>0) return(dy); ! 416: tp = localtime(&ftb.time); ! 417: mn = tp->tm_mon; ! 418: if (tp->tm_mday<10) mn--; ! 419: dy = monlen[mn]; ! 420: if (dy==28 && tp->tm_year%4==0) ! 421: dy++; ! 422: return(dy); ! 423: } ! 424: forecast(north, west) ! 425: double north, west; ! 426: { ! 427: double d, dist(), md=5000., tnf, twf; ! 428: char aname[10], fname[100], xl[30]; ! 429: int n, w, in, jw, iw, jn; ! 430: FILE *f; ! 431: n = north; ! 432: n = n-n%4; ! 433: w = west; ! 434: w = w-w%4; ! 435: in = jn = n; ! 436: if ( (int) north %4 >=2) jn+=4; else in-=4; ! 437: iw = jw = w; ! 438: if ( (int) west %4 >=2 ) jw+=4; else iw-=4; ! 439: aname[0]=0; ! 440: for(n=in; n<=jn; n+=4) ! 441: for(w=iw; w<=jw; w+=4) ! 442: { ! 443: sprintf(fname, "/data/weather/fore/f_%.2d.%.2d", n, w); ! 444: f = fopen(fname, "r"); ! 445: if (f==NULL) continue; ! 446: while (fgets(xl, 20, f)) ! 447: { ! 448: tnf = atof(xl+4); ! 449: twf = atof(xl+9); ! 450: d = dist(tnf, twf, north, west); ! 451: if (d<md) ! 452: { ! 453: md=d; ! 454: strncpy(aname, xl, 3); ! 455: aname[3]=0; ! 456: } ! 457: } ! 458: fclose(f); ! 459: } ! 460: if (aname[0]==0) return; ! 461: sprintf(fname, "/data/weather/fore/f_%s", aname); ! 462: f = fopen(fname, "r"); ! 463: if (f!=NULL) ! 464: { ! 465: puts(""); ! 466: while (fgets(fname, 100, f)) ! 467: fputs(fname, stdout); ! 468: fclose(f); ! 469: } ! 470: if (marine) ! 471: { ! 472: sprintf(fname, "/data/weather/fore/m_%s", aname); ! 473: f = fopen(fname, "r"); ! 474: if (f!=NULL) ! 475: { ! 476: if (f==NULL) return; ! 477: puts(""); ! 478: while (fgets(fname, 100, f)) ! 479: fputs(fname, stdout); ! 480: fclose(f); ! 481: } ! 482: } ! 483: puts(""); ! 484: } ! 485: trimnl(s) ! 486: char *s; ! 487: { ! 488: while (*s)s++; ! 489: if (*--s=='\n')*s=0; ! 490: } ! 491: intr() ! 492: { ! 493: longjmp(env, 0); ! 494: } ! 495: struct table { ! 496: int temp; ! 497: int rh[15]; ! 498: }tab[21] = { ! 499: {100,100,94,88,83,78,73,69,65,61,57,53,45,38,32,27}, ! 500: {95,100,94,88,83,78,73,68,64,60,56,53,44,37,31,26}, ! 501: {90,100,94,88,83,77,73,68,64,59,56,52,44,37,31,25}, ! 502: {85,100,94,88,82,77,72,67,63,58,55,51,43,36,30,25}, ! 503: {80,100,94,88,82,77,72,67,62,58,54,51,42,35,29,24}, ! 504: {75,100,94,87,82,76,71,66,62,58,54,50,42,34,28,23}, ! 505: {70,100,93,87,81,76,71,66,61,57,53,49,41,34,28,23}, ! 506: {65,100,93,87,81,75,70,65,61,57,52,49,40,33,27,22}, ! 507: {60,100,93,87,81,75,70,65,60,56,52,48,39,32,26,21}, ! 508: {55,100,93,86,80,75,69,64,59,55,51,47,39,31,25,20}, ! 509: {50,100,93,86,80,74,69,64,59,54,50,46,38,31,25,20}, ! 510: {45,100,93,86,80,74,68,63,58,54,49,46,37,30,24,19}, ! 511: {40,100,93,86,79,73,68,62,57,53,49,45,36,29,23,18}, ! 512: {35,100,92,85,79,73,67,61,57,52,48,44,35,28,22,18}, ! 513: {30,100,92,85,78,72,66,61,56,51,47,43,34,27,21,17}, ! 514: {25,100,92,85,78,72,66,60,55,51,46,42,33,26,21,16}, ! 515: {20,100,92,84,77,71,65,60,54,50,45,41,33,25,20,15}, ! 516: {15,100,92,84,77,70,64,59,54,49,44,40,32,25,19,14}, ! 517: {10,100,92,84,76,70,64,58,53,48,43,39,31,24,18,14}, ! 518: {5,100,92,83,76,69,63,57,52,47,42,38,30,23,17,13}, ! 519: {0,100,91,83,75,68,63,56,51,46,41,37,29,22,16,12} ! 520: }; ! 521: int ddline[15] = {0,2,4,6,8,10,12,14,16,18,20,25,30,35,40}; ! 522: char * ! 523: relhum(temp, dewpt) ! 524: { ! 525: int del1,del2,dd, i, j; ! 526: static char val[20]; ! 527: dd = temp - dewpt; ! 528: if (dd < 0) ! 529: return("??"); ! 530: if (dd > 40) ! 531: return("dry"); ! 532: temp = ((temp+2)/5)*5; ! 533: for (i=0;i<15;i++) { ! 534: if (dd <= ddline[i]) { ! 535: del1 = ddline[i]-dd; ! 536: del2 = ddline[i]-ddline[i-1]; ! 537: break; ! 538: } ! 539: } ! 540: for(j=0;j<22;j++) { ! 541: if (j==21) ! 542: return("??"); ! 543: else if (tab[j].temp == temp) { ! 544: sprintf(val, "%d", ! 545: tab[j].rh[i]+((del1*(tab[j].rh[i-1]-tab[j].rh[i]))/del2)); ! 546: return(val); ! 547: } ! 548: } ! 549: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.