# include "stdio.h" # include "ctype.h" # include "assert.h" # include "cbt.h" # include "weath.h" # include "time.h" struct tm *gmtime(); # define SURFACE 1 # define LFMFORE 2 # define FORECAST 3 # define MARINE 4 mbuf key, rec, rkey; char kb[100], rb[100], rkb[100]; int day; bfile *bf; char *index(), *vis(), *airport(); double atof(); main() { char line[400], line2[400]; int kind=0, k; long clock; time(&clock); day = gmtime(&clock)->tm_yday; chdir ("/usr/spool/weather"); bf = bopen("airn", 0); assert(bf!=NULL); while (gets(line)) { k = strlen(line); if (k==0) continue; if (k==8 && strncmp(line+3, "00", 2)==0) { printf("found something, line %s\n",line); unfore(); switch(atoi(line+5)) { case 200: /* new england */ case 201: /* eastern states */ case 202: /* midatlantic */ case 203: /* southeastern */ case 204: /* great lakes */ case 205: /* ohio valley */ case 206: /* northern plains */ case 207: /* great plains */ case 208: /* gulf coast */ case 209: /* northern rockies */ case 210: /* southwestern */ case 211: /* pacific northwest */ case 212: /* pacific */ case 290: /* alaska */ case 291: /* hawaii */ kind = SURFACE; continue; case 431: kind = LFMFORE; continue; case 307: case 308: case 309: kind = FORECAST; continue; case 313: kind = MARINE; continue; } kind=0; continue; } switch(kind) { case SURFACE: surf(line); break; case LFMFORE: if (strlen(line)>5 && line[3]==' ' && isupper(line[0]) && isupper(line[1])) { gets(line2); if (startwith(line2, "POF")) gets(line2); lfmfore(line, line2); } else if (strncmp(line, "DATE/GMT", 8)==0) lfmtimeset(line); break; case FORECAST: case MARINE: realfore(line, kind); break; } } } surf(line) char *line; { int nv, nw, i, cloud; char *v[50], *w[50], *s, *p, *aname; double north, west; printf("surface lin %s\n",line); if (strlen(line)<10) return; if (!isalpha(line[0])) return; s=line; while ( (s=index (s, '/')) && !hasnxt(s)) s++; if (s==NULL) return; while (s>line && *s!= ' ')s--; *s++ = 0; nv = getargs(line, v); nw = getargs(s, w); aname = airport(v[0]); printf("airport %s aname %s\n", v[0], aname? aname: "NULL"); if (aname==NULL) return; for(i=0; i<nw; i++) { int q; q = strlen(w[i]); if (q==4 && isdigit(w[i][0])) break; if (q>4 && isdigit(w[i][0]) && w[i][4]=='G') break; } if (i==nw || i<2) return; p = vis(v[nv-1]); if (p==NULL ) return; north = atof(aname); west = atof(index(aname, ' ')); s= v[nv-2]; /* last kind of cloud cover */ while (isdigit(*s) || *s=='-') s++; if (strcmp(s, "OVC")==0) cloud = 'O'; else if (strcmp(s, "BKN")==0) cloud = 'P'; else if (strcmp(s, "SCT")==0) cloud = 'P'; else if (strcmp(s, "CLR")==0) cloud = 'C'; else cloud = 'X'; if (nottime(v[2])) return; if (!alldigs(w[i-2])) return; /* temp must be digits */ if (!alldigs(w[i-1])) return; /* dewpoint must be digits */ update( v[0], north, west, v[2], w[i-2], w[i-1], v[nv-1], w[i], cloud, w[i+1]); } char * vis(s) char *s; { int d; static char temp[50]; d= atoi(s); while (isdigit(*s)) s++; if (*s==0) { sprintf(temp, " ordinary, visibility %d miles", d); return(temp); } temp[0]=0; for( ; *s; s++) switch(*s) { case 'A': strcat(temp, " hail"); break; case 'D': strcat(temp, " dust"); break; case 'F': strcat(temp, " fog"); break; case 'H': strcat(temp, " haze"); break; case 'I': if (s[1]=='P') strcat(temp, " sleet"); break; case 'K': strcat(temp, " smoke"); break; case 'L': strcat(temp, " drizzle"); break; case 'R': strcat(temp, " rain"); break; case 'W': strcat(temp, " showers"); break; case 'S': strcat(temp, " snow"); break; case 'T': strcat(temp, " thunderstorms"); break; case 'Z': strcat(temp, " freezing"); break; case '-': break; default: return(NULL); } return(temp); } char lfmt1[10], lfmt2[10]; lfmfore( l1, l2) char *l1, *l2; { char *s, fname[100], xl[20], *p, *t; FILE *tf; int p1, p2, p3, p4, max1, min1, max2, min2; l1[3]=0; s=airport(l1); if(s==NULL) return; sscanf(l1+4, "%*s %d %d %d %d", &p1, &p2, &p3, &p4); sscanf(l2, "%s %d %d %d %d", xl, &max1, &min1, &max2, &min2); if (p1<0 || p1>100) return; if (p2<0 || p2>100) return; if (p3<0 || p3>100) return; if (p4<0 || p4>100) return; if (max1>150 || max2>150 || min1>150 || min2>150) return; if (strncmp(xl, "MN", 2)==0) { int t; t = max1; max1 = min1; min1 = t; t = max2; max2 = min2; min2 = t; } sprintf(fname, "lfm/%s", l1); tf = fopen(fname, "w"); if (tf) { p = index(s, '\t'); if (p==NULL) return; fprintf(tf, "%s\n", p+1); fprintf(tf, "%s %d %d %d %d\n", lfmt1, max1, min1, p1, p2); fprintf(tf, "%s %d %d %d %d\n", lfmt2, max2, min2, p3, p4); fclose(tf); airmark ("lfm/", l1); } return; } lfmtimeset(s) char *s; { sscanf(s, "%*s %s %*s %s", lfmt1, lfmt2); } char * airport(s) char *s; { int i; key.mdata = s; key.mlen = strlen(s); i=bseek(bf, key); if (i!=1) return(NULL); rkey.mdata =rkb; rec.mdata = rb; bread(bf, &rkey, &rec); assert(strcmp(rkey.mdata, key.mdata)==0); rkey.mdata[rkey.mlen]=0; rec.mdata[rec.mlen]=0; return(rec.mdata); } update (acode, north, west, wtime, temp, humid, weath, wind, cloud, press) double north, west; char *acode, *temp, *weath, *wind, *humid, *wtime, *press; { char fname[30], odata[2000], *p, *s, wtt[100]; struct wline *wp; int n, w, f; n = north; n = n-n%4; w = west; w = w-w%4; sprintf(fname, "obs/%.2d.%.2d", n, w); f = open(fname, 2); if (f>=0) { n=read(f, odata, 2000); assert(n<2000); for(wp=(struct wline *)odata; ( (char *)wp ) <odata+n; wp++) { if (atoi(wp->wday)+1<day) strncpy(wp->anam, "---", 3); } for(wp=(struct wline *)odata; ( (char *)wp ) <odata+n; wp++) { if (strncmp(wp->anam, acode, 3)==0) break; } if ((char *)wp >=odata+n) for(wp=(struct wline *)odata; ( (char *)wp ) <odata+n; wp++) { if (strncmp(wp->anam, "---", 3)==0) break; } } else { f = creat(fname, 0666); wp = (struct wline *)odata; n=0; } sprintf(wtt, "%.3s%5.2f%6.2f%4.4s%3.3s%3.3s%-6.6s%-7.7s%c%3.3s%03d\n", acode, north, west, wtime, temp, humid, weath, wind, cloud, press, day); strncpy(wp->anam, wtt, sizeof(*wp)); lseek (f, 0L, 0); if (n<= ( (char *)wp - odata )) n+= sizeof(*wp); write(f, odata, n); close(f); } nottime(s) char *s; { int c; if (strlen(s)!=4) return(1); while ( c = *s++ ) if (!isdigit(c)) return(1); return(0); } static FILE *ff = NULL; realfore(line, kind) char *line; { char fname[50]; if (kind==FORECAST && strncmp(line+3, " FP", 3)==0) { unfore(); line[3]=0; sprintf(fname, "fore/f_%s", line); ff = fopen(fname, "w"); airmark ("fore/f_", line); } if (kind==FORECAST && strncmp(line, "FPUS", 4)==0) { unfore(); line[10]=0; sprintf(fname, "fore/f_%s", line+7); ff = fopen(fname, "w"); airmark ("fore/f_", line+7); } if (kind==MARINE && strncmp(line+3, " FZ", 3)==0) { unfore(); line[3]=0; sprintf(fname, "fore/m_%s", line); ff = fopen(fname, "w"); airmark ("fore/f_", line); } if (ff!=NULL) fprintf(ff, "%s\n", line); } unfore() { if (ff!=NULL) fclose(ff); } airmark(code, aname) char *code, *aname; { char fname[100], *s, xl[30]; double nor, wes; int n, w; FILE *tf; s=airport(aname); if (s==NULL) return; sscanf(s, "%lfN %lfW", &nor, &wes); n = nor; n = n - n%4; w = wes; w = w - w%4; sprintf(fname, "%s%.2d.%.2d", code, n, w); tf = fopen(fname, "r"); if (tf!=NULL) { while (fgets(xl, 20, tf)) { xl[3]=0; if (strcmp(xl, aname)==0) { fclose(tf); return; } } fclose(tf); } tf = fopen(fname, "a"); if (tf==NULL) return; fprintf(tf, "%3.3s %5.2f %6.2f\n", aname, nor, wes); fclose(tf); } hasnxt(s) char *s; { /* checks for more than one slash */ if (s==NULL) return(1); s++; while (*s && !isspace(*s)) if (*s=='/') return(1); else s++; return(0); } alldigs(s) char *s; { int c; while (c = *s++) if (!isdigit(c) && c!='-') return(0); return(1); } startwith(s, t) char *s, *t; {/* true if s starts with t*/ while (isspace(*s)) s++; if (strncmp(s, t, strlen(t)) == 0) return(1); return(0); }