Annotation of researchv10no/cmd/weather/xwe.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.