| 93 |  | int     noaction = 0;           /* take no action? */ | 
| 94 |  |  | 
| 95 |  | char    *remsh;                 /* remote shell program/script */ | 
| 96 | < | char    rendopt[2048] = "";     /* rendering options */ | 
| 96 | > | char    rendopt[2048];          /* rendering options */ | 
| 97 |  | char    rresopt[32];            /* rendering resolution options */ | 
| 98 |  | char    fresopt[32];            /* filter resolution options */ | 
| 99 |  | int     pfiltalways;            /* always use pfilt? */ | 
| 108 |  | }       *pslot;                 /* process slots */ | 
| 109 |  | int     npslots;                /* number of process slots */ | 
| 110 |  |  | 
| 111 | – | int     lastpid;                /* ID of last completed background process */ | 
| 112 | – | PSERVER *lastpserver;           /* last process server used */ | 
| 113 | – |  | 
| 111 |  | #define phostname(ps)   ((ps)->hostname[0] ? (ps)->hostname : astat.host) | 
| 112 |  |  | 
| 113 |  | struct pslot    *findpslot(); | 
| 114 |  |  | 
| 115 | + | PSERVER *lastpserver;           /* last process server with error */ | 
| 116 | + |  | 
| 117 |  | VIEW    *getview(); | 
| 118 |  | char    *getexp(); | 
| 119 |  |  | 
| 230 |  | } | 
| 231 |  | /* assume it is dead */ | 
| 232 |  | } | 
| 233 | < | if (strcmp(cfname, astat.cfname) && astat.tnext != 0) { /* other's */ | 
| 233 | > | if (strcmp(cfname, astat.cfname) && astat.pid != 0) {   /* other's */ | 
| 234 |  | fprintf(stderr, "%s: unfinished job \"%s\"\n", | 
| 235 |  | progname, astat.cfname); | 
| 236 |  | return(-1); | 
| 300 |  | setdefaults()                   /* set default values */ | 
| 301 |  | { | 
| 302 |  | extern char     *atos(); | 
| 303 | + | int     decades; | 
| 304 |  | char    buf[256]; | 
| 305 |  |  | 
| 306 |  | if (vdef(ANIMATE)) { | 
| 334 |  | quit(1); | 
| 335 |  | } | 
| 336 |  | if (!vdef(BASENAME)) { | 
| 337 | < | sprintf(buf, "%s/frame%%03d", vval(DIRECTORY)); | 
| 337 | > | decades = (int)log10((double)vint(END)) + 1; | 
| 338 | > | if (decades < 3) decades = 3; | 
| 339 | > | sprintf(buf, "%s/frame%%0%dd", vval(DIRECTORY), decades); | 
| 340 |  | vval(BASENAME) = savqstr(buf); | 
| 341 |  | vdef(BASENAME)++; | 
| 342 |  | } | 
| 484 |  | i = sscanf(vval(RESOLUTION), "%d %d %f", &xres, &yres, &pa); | 
| 485 |  | mult = vflt(OVERSAMP); | 
| 486 |  | if (i == 3) { | 
| 487 | < | sprintf(rresopt, "-x %d -y %d -pa %f", (int)(mult*xres), | 
| 487 | > | sprintf(rresopt, "-x %d -y %d -pa %.3f", (int)(mult*xres), | 
| 488 |  | (int)(mult*yres), pa); | 
| 489 | < | sprintf(fresopt, "-x %d -y %d -pa %f", xres, yres, pa); | 
| 489 | > | sprintf(fresopt, "-x %d -y %d -pa %.3f", xres, yres, pa); | 
| 490 |  | } else if (i) { | 
| 491 |  | if (i == 1) yres = xres; | 
| 492 |  | sprintf(rresopt, "-x %d -y %d", (int)(mult*xres), | 
| 514 |  | /* figure # frames per batch */ | 
| 515 |  | d1 = mult*xres*mult*yres*4;             /* space for orig. picture */ | 
| 516 |  | if ((i=vint(INTERP)) || atoi(vval(MBLUR))) | 
| 517 | < | d1 += mult*xres*mult*yres*4;    /* space for z-buffer */ | 
| 517 | > | d1 += mult*xres*mult*yres*sizeof(float);        /* Z-buffer */ | 
| 518 |  | d2 = xres*yres*4;                       /* space for final picture */ | 
| 519 |  | frames_batch = (i+1)*(vflt(DISKSPACE)*1048576.-d1)/(d1+i*d2); | 
| 520 |  | if (frames_batch < i+2) { | 
| 843 |  | while (*arcnext) arcnext++; | 
| 844 |  | strcpy(arcnext, ".unf"); | 
| 845 |  | arcnext += 4; | 
| 846 | < | if (usepinterp || vint(INTERP)) {       /* and z-buf */ | 
| 846 | > | if (usepinterp || vint(INTERP)) {       /* and Z-buf */ | 
| 847 |  | *arcnext++ = ' '; | 
| 848 |  | sprintf(arcnext, vval(BASENAME), | 
| 849 |  | frame-vint(INTERP)-1); | 
| 901 |  | strcat(combuf, viewopt(vp)); | 
| 902 |  | if (vbool(RTRACE)) | 
| 903 |  | sprintf(combuf+strlen(combuf), " -ff -fr '%s -w0 %s'", | 
| 904 | < | rendopt, vval(OCTREE)); | 
| 904 | > | rendopt+1, vval(OCTREE)); | 
| 905 |  | if (vdef(PINTERP)) | 
| 906 |  | sprintf(combuf+strlen(combuf), " %s", vval(PINTERP)); | 
| 907 |  | if (usepfilt) | 
| 989 |  | } | 
| 990 |  | while (n > viewnum) {           /* scan to desired view */ | 
| 991 |  | if (fgets(linebuf, sizeof(linebuf), viewfp) == NULL) | 
| 992 | < | return(viewnum==1 ? &curview : NULL); | 
| 992 | > | return(viewnum==1 ? &curview : (VIEW *)NULL); | 
| 993 |  | if (isview(linebuf) && sscanview(&curview, linebuf) > 0) | 
| 994 |  | viewnum++; | 
| 995 |  | } | 
| 1022 |  | if (n == 0) {                           /* signal to close file */ | 
| 1023 |  | if (expfp != NULL) { | 
| 1024 |  | fclose(expfp); | 
| 1025 | + | free((char *)exppos); | 
| 1026 |  | expfp = NULL; | 
| 1027 |  | } | 
| 1028 |  | return(NULL); | 
| 1029 | < | } | 
| 1029 | > | } else if (n > vint(END))               /* request past end (error?) */ | 
| 1030 | > | return(NULL); | 
| 1031 |  | if (!vdef(EXPOSURE))                    /* no setting (auto) */ | 
| 1032 |  | return(NULL); | 
| 1033 |  | if (isflt(vval(EXPOSURE)))              /* always the same */ | 
| 1065 |  | } | 
| 1066 |  | curfrm++; | 
| 1067 |  | cp = fskip(expval);                     /* check format */ | 
| 1068 | < | if (cp == NULL || *cp != '\n') { | 
| 1068 | > | if (cp != NULL) | 
| 1069 | > | while (isspace(*cp)) | 
| 1070 | > | *cp++ = '\0'; | 
| 1071 | > | if (cp == NULL || *cp) { | 
| 1072 |  | fprintf(stderr, | 
| 1073 |  | "%s: exposure format error on line %d\n", | 
| 1074 |  | vval(EXPOSURE), curfrm); | 
| 1075 |  | quit(1); | 
| 1076 |  | } | 
| 1070 | – | *cp = '\0'; | 
| 1077 |  | } | 
| 1078 |  | return(expval);                         /* return value */ | 
| 1079 |  | } | 
| 1103 |  | int     status; | 
| 1104 |  | { | 
| 1105 |  | register PROC   *pp; | 
| 1106 | + | register struct pslot   *psl; | 
| 1107 |  |  | 
| 1108 |  | pp = ps->proc + pn; | 
| 1109 |  | if (pp->elen) {                 /* pass errors */ | 
| 1115 |  | if (ps->hostname[0]) | 
| 1116 |  | status = 1;     /* because rsh doesn't return status */ | 
| 1117 |  | } | 
| 1118 | + | lastpserver = NULL; | 
| 1119 | + | psl = findpslot(pp->pid);       /* check for bruncom() slot */ | 
| 1120 | + | if (psl->pid) { | 
| 1121 | + | if (status) { | 
| 1122 | + | if (psl->rcvf != NULL)  /* attempt recovery */ | 
| 1123 | + | status = (*psl->rcvf)(psl->fout); | 
| 1124 | + | if (status) { | 
| 1125 | + | fprintf(stderr, | 
| 1126 | + | "%s: error rendering frame %d\n", | 
| 1127 | + | progname, psl->fout); | 
| 1128 | + | quit(1); | 
| 1129 | + | } | 
| 1130 | + | lastpserver = ps; | 
| 1131 | + | } | 
| 1132 | + | psl->pid = 0;                   /* free process slot */ | 
| 1133 | + | } else if (status) | 
| 1134 | + | lastpserver = ps; | 
| 1135 |  | freestr(pp->com);               /* free command string */ | 
| 1112 | – | lastpid = pp->pid;              /* record PID for bwait() */ | 
| 1113 | – | lastpserver = ps;               /* record server for serverdown() */ | 
| 1136 |  | return(status); | 
| 1137 |  | } | 
| 1138 |  |  | 
| 1140 |  | int | 
| 1141 |  | serverdown()                    /* check status of last process server */ | 
| 1142 |  | { | 
| 1143 | + | if (lastpserver == NULL || !lastpserver->hostname[0]) | 
| 1144 | + | return(0); | 
| 1145 |  | if (pserverOK(lastpserver))     /* server still up? */ | 
| 1146 |  | return(0); | 
| 1147 |  | delpserver(lastpserver);        /* else delete it */ | 
| 1168 |  | printf("\t%s\n", com);  /* echo command */ | 
| 1169 |  | return(0); | 
| 1170 |  | } | 
| 1171 | < | /* else start it when we can */ | 
| 1172 | < | while ((pid = startjob(NULL, savestr(com), donecom)) == -1) | 
| 1171 | > | com = savestr(com);             /* else start it when we can */ | 
| 1172 | > | while ((pid = startjob(NULL, com, donecom)) == -1) | 
| 1173 |  | bwait(1); | 
| 1174 |  | if (!silent) {                          /* echo command */ | 
| 1175 |  | PSERVER *ps; | 
| 1191 |  | int     ncoms; | 
| 1192 |  | { | 
| 1193 |  | int     status; | 
| 1170 | – | register struct pslot   *psl; | 
| 1194 |  |  | 
| 1195 |  | if (noaction) | 
| 1196 |  | return; | 
| 1197 |  | while ((status = wait4job(NULL, -1)) != -1) { | 
| 1198 | < | psl = findpslot(lastpid); | 
| 1199 | < | if (status) {           /* attempt recovery */ | 
| 1200 | < | serverdown();   /* check server */ | 
| 1178 | < | if (psl->rcvf == NULL || (*psl->rcvf)(psl->fout)) { | 
| 1179 | < | fprintf(stderr, | 
| 1180 | < | "%s: error rendering frame %d\n", | 
| 1181 | < | progname, psl->fout); | 
| 1182 | < | quit(1); | 
| 1183 | < | } | 
| 1184 | < | } | 
| 1185 | < | psl->pid = 0;           /* free process slot */ | 
| 1186 | < | if (!--ncoms) | 
| 1187 | < | return;         /* done enough */ | 
| 1198 | > | serverdown();           /* update server status */ | 
| 1199 | > | if (--ncoms == 0) | 
| 1200 | > | break;          /* done enough */ | 
| 1201 |  | } | 
| 1202 |  | } | 
| 1203 |  |  | 
| 1209 |  | { | 
| 1210 |  | int     retstatus = 0; | 
| 1211 |  | int     hostcopies; | 
| 1212 | < | char    com1buf[10240], *com1, *endcom1; | 
| 1212 | > | char    buf[10240], *com1, *s; | 
| 1213 |  | int     status; | 
| 1214 | + | int     pfd; | 
| 1215 | + | register int    n; | 
| 1216 |  | register PSERVER        *ps; | 
| 1217 |  |  | 
| 1218 |  | if (!silent) | 
| 1224 |  | for (ps = pslist; ps != NULL; ps = ps->next) { | 
| 1225 |  | hostcopies = 0; | 
| 1226 |  | if (maxcopies > 1 && ps->nprocs > 1 && ppins != NULL) { | 
| 1227 | < | strcpy(com1=com1buf, com);      /* build -PP command */ | 
| 1227 | > | strcpy(com1=buf, com);  /* build -PP command */ | 
| 1228 |  | sprintf(com1+(ppins-com), " -PP %s/%s.persist", | 
| 1229 |  | vval(DIRECTORY), phostname(ps)); | 
| 1230 |  | strcat(com1, ppins); | 
| 1231 | < | endcom1 = com1 + strlen(com1); | 
| 1217 | < | sprintf(endcom1, "; kill `sed -n '1s/^[^ ]* //p' %s/%s.persist`", | 
| 1218 | < | vval(DIRECTORY), phostname(ps)); | 
| 1219 | < | } else { | 
| 1231 | > | } else | 
| 1232 |  | com1 = com; | 
| 1233 | < | endcom1 = NULL; | 
| 1233 | > | while (maxcopies > 0) { | 
| 1234 | > | s = savestr(com1); | 
| 1235 | > | if (startjob(ps, s, donecom) != -1) { | 
| 1236 | > | sleep(20); | 
| 1237 | > | hostcopies++; | 
| 1238 | > | maxcopies--; | 
| 1239 | > | } else { | 
| 1240 | > | freestr(s); | 
| 1241 | > | break; | 
| 1242 | > | } | 
| 1243 |  | } | 
| 1223 | – | while (maxcopies > 0 && | 
| 1224 | – | startjob(ps, savestr(com1), donecom) != -1) { | 
| 1225 | – | sleep(10); | 
| 1226 | – | hostcopies++; | 
| 1227 | – | maxcopies--; | 
| 1228 | – | if (endcom1 != NULL) | 
| 1229 | – | *endcom1 = '\0'; | 
| 1230 | – | } | 
| 1244 |  | if (!silent && hostcopies) { | 
| 1245 |  | if (hostcopies > 1) | 
| 1246 |  | printf("\t%d duplicate processes", hostcopies); | 
| 1252 |  | } | 
| 1253 |  | /* wait for jobs to finish */ | 
| 1254 |  | while ((status = wait4job(NULL, -1)) != -1) | 
| 1255 | < | if (status) | 
| 1256 | < | retstatus += !serverdown();     /* check server */ | 
| 1255 | > | retstatus += status && !serverdown(); | 
| 1256 | > | /* terminate parallel rpict's */ | 
| 1257 | > | for (ps = pslist; ps != NULL; ps = ps->next) { | 
| 1258 | > | sprintf(buf, "%s/%s.persist", vval(DIRECTORY), phostname(ps)); | 
| 1259 | > | if ((pfd = open(buf, O_RDONLY)) >= 0) { | 
| 1260 | > | n = read(pfd, buf, sizeof(buf)-1);      /* get PID */ | 
| 1261 | > | buf[n] = '\0'; | 
| 1262 | > | close(pfd); | 
| 1263 | > | for (n = 0; buf[n] && !isspace(buf[n]); n++) | 
| 1264 | > | ; | 
| 1265 | > | /* terminate */ | 
| 1266 | > | sprintf(buf, "kill -ALRM %d", atoi(buf+n)); | 
| 1267 | > | wait4job(ps, startjob(ps, buf, NULL)); | 
| 1268 | > | } | 
| 1269 | > | } | 
| 1270 |  | return(retstatus); | 
| 1271 |  | } | 
| 1272 |  |  |