Img* dssread(char *file) { int nx, ny, scale, sumall; Pix *p, *pend; uint8_t buf[21]; Biobuf *bp; Img *ip; if(debug) Bprint(&bout, "reading %s\n", file); bp = Bopen(file, OREAD); if(bp == 0) return 0; if(Bread(bp, buf, sizeof(buf)) != sizeof(buf) || buf[0] != 0xdd || buf[1] != 0x99){ werrstr("bad format"); return 0; } nx = getlong(buf+2); ny = getlong(buf+6); scale = getlong(buf+10); sumall = getlong(buf+14); if(debug) fprint(2, "%s: nx=%d, ny=%d, scale=%d, sumall=%d, nbitplanes=%d,%d,%d\n", file, nx, ny, scale, sumall, buf[18], buf[19], buf[20]); ip = malloc(sizeof(Img) + (nx*ny-1)*sizeof(int)); if(ip == 0){ Bterm(bp); werrstr("no memory"); return 0; } ip->nx = nx; ip->ny = ny; dodecode(bp, ip->a, nx, ny, buf+18); ip->a[0] = sumall; /* sum of all pixels */ Bterm(bp); if(scale > 1){ p = ip->a; pend = &ip->a[nx*ny]; while(p < pend) *p++ *= scale; } hinv(ip->a, nx, ny); return ip; }
void untcx_and_exec_nfs(char *expath, char *untemp, char *targ, char *argv[]) { struct stat tostat; /* Stat buffer to check on lengths */ int mtime; int owner, group; int perms; /* Saved permissions to restore on target exec */ int infd, outfd; /* In and out file descriptors */ struct flock lck; /* File lock structure */ char *c; int len; /* Stat executable and grab permissions */ #ifdef AIX if(seteuid(getuid()) < 0) { perror("seteuid"); exit(-1); } #else if(setreuid(geteuid(), getuid()) < 0) { perror("setreuid"); exit(-1); } #endif if(stat(expath, &tostat) < 0) { perror(argv[0]); exit(-1); } perms = (tostat.st_mode & 0777); mtime = tostat.st_mtime; owner = tostat.st_uid; group = tostat.st_gid; /* resolve first stage of argv[0] */ if(getwd(cwd) == NULL) { (void)fprintf(stderr, "Get Working Directory Error: %s\n", cwd); exit(-1); } if(*argv[0] == '/') (void)strcpy(realdir, argv[0]); else (void)sprintf(realdir, "%s/%s", cwd, argv[0]); if((c = strrchr(realdir, '/')) == NULL) { (void)fprintf(stderr, "Help! Internal corruption of variables!\n"); exit(-1); } c++; (void)strcpy(execname, c); *c = '\0'; if(chdir(realdir) < 0) { perror(realdir); exit(-1); } if(getwd(realdir) == NULL) { (void)fprintf(stderr, "Get Working Directory Error: %s\n", cwd); exit(-1); } for(c = realdir; *c; c++) if(*c == '/') *c = '='; (void)sprintf(linkpath, "%s/%s", ENFSDIR, realdir); if(mkdir(linkpath, 0777) < 0) { if(errno != EEXIST) { perror(linkpath); exit(-1); } } else (void)chmod(linkpath, 0777); (void)strcat(linkpath,"/"); (void)strcat(linkpath, execname); if(chdir(cwd) < 0) { perror(cwd); exit(-1); } #ifdef AIX if(seteuid(0) < 0) { perror("seteuid"); exit(-1); } #else if(setreuid(geteuid(), getuid()) < 0) { perror("setreuid"); exit(-1); } #endif /* Statistics done! Now try to unpack and run it! */ for(;;PUSLEEP(10000)) { if(stat(targ, &tostat) >= 0) { if(mtime > tostat.st_mtime) { if(strcmp(linkpath, targ) == 0) (void)unlink(linkpath); (void)unlink(targ); } else { if(strcmp(linkpath, targ) == 0) { if(try_to_exec(targ, linkpath, argv) < 0) exit(-1); else continue; } else if((len = readlink(linkpath, realdir, MAXPATHLEN)) >= 0 && strncmp(realdir, targ, len) == 0) { if(try_to_exec(targ, linkpath, argv) < 0) exit(-1); else continue; } else { (void)unlink(linkpath); if(symlink(targ, linkpath) < 0) { perror(linkpath); exit(-1); } if(try_to_exec(targ, linkpath, argv) < 0) exit(-1); else continue; } } } else { /* If symlink to file is there, then get rid of it! */ if((len = readlink(linkpath, realdir, MAXPATHLEN)) >= 0 && strncmp(realdir, targ, len) == 0) (void)unlink(linkpath); } #ifdef AIX if(seteuid(getuid()) < 0) { perror("seteuid"); exit(-1); } #else if(setreuid(geteuid(), getuid()) < 0) { perror("setreuid"); exit(-1); } #endif if((infd = open(expath, O_RDONLY)) < 0) { perror(expath); exit(-1); } #ifdef AIX if(seteuid(0) < 0) { perror("seteuid"); exit(-1); } #else if(setreuid(geteuid(), getuid()) < 0) { perror("setreuid"); exit(-1); } #endif if(! is_tcx(infd)) { (void)close(infd); if(try_to_exec(expath, argv[0], argv) < 0) exit(-1); continue; } /* File is in packed format. Unpack it */ if((outfd = open(untemp, O_EXCL | O_CREAT | O_WRONLY)) < 0) { if(errno != EEXIST) { perror(untemp); exit(-1); } if((outfd = open(untemp, O_WRONLY | O_TRUNC)) < 0) { perror(untemp); exit(-1); } } lck.l_type = F_WRLCK; lck.l_whence = 0; lck.l_start = 0; lck.l_len = 0; if(fcntl(outfd, F_SETLK, &lck) < 0) { (void)close(infd); (void)close(outfd); continue; } /* Start decompressing executable */ if(dodecode(infd, outfd) != 0) { if(unlink(untemp) < 0) perror(untemp); exit(-1); } (void)close(infd); /* Now set execute permissions on the beastie */ if(chmod(untemp, perms) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } if(chown(untemp, owner, group) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } /* Rename untemporary file to target executable and close target */ if(rename(untemp, targ) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } (void)close(outfd); /* Now create symlink from linkpath to targ if they are not equal */ if(strcmp(linkpath, targ) != 0 && symlink(targ, linkpath) < 0) { perror(linkpath); exit(-1); } /* Everything OK! Now go exec the executable. */ if(try_to_exec(targ, linkpath, argv) < 0) exit(-1); } /* for */ } /* untcx_and_exec_nfs */
void just_untcx(char *expath, char *untemp) { struct stat tostat; /* Stat buffer to check on lengths */ int owner, group; int perms; /* Saved permissions to restore on target exec */ int infd, outfd; /* In and out file descriptors */ struct flock lck; /* File lock structure */ /* Stat executable and grab permissions */ if(stat(expath, &tostat) < 0) { perror(expath); exit(-1); } perms = (tostat.st_mode & 0777); owner = tostat.st_uid; group = tostat.st_gid; if((infd = open(expath, O_RDWR)) < 0) { perror(expath); exit(-1); } lck.l_type = F_WRLCK; lck.l_whence = 0; lck.l_start = 0; lck.l_len = 0; if(fcntl(infd, F_SETLK, &lck) < 0) { perror(expath); exit(-1); } if(! is_tcx(infd)) { (void)fprintf(stderr, "File does not appear to be in tcx format. Aborting\n"); exit(-1); } /* File is in packed format. Unpack it */ if((outfd = open(untemp, O_WRONLY | O_CREAT | O_EXCL)) < 0) { if(errno != EEXIST) { perror(untemp); exit(-1); } if((outfd = open(untemp, O_WRONLY | O_TRUNC)) < 0) { perror(untemp); exit(-1); } } /* Start decompressing executable */ if(dodecode(infd, outfd) != 0) { if(unlink(untemp) < 0) perror(untemp); exit(-1); } (void)close(outfd); /* Now set execute permissions on the beastie */ if(chmod(untemp, perms) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } if(chown(untemp, owner, group) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } /* Rename untemporary file to target executable and close target */ if(rename(untemp, expath) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } (void)close(infd); return; } /* just_untcx */
void untcx_and_exec_local(char *expath, char *untemp, char *argv[]) { struct stat tostat; /* Stat buffer to check on lengths */ int owner, group; int perms; /* Saved permissions to restore on target exec */ int infd, outfd; /* In and out file descriptors */ struct flock lck; /* File lock structure */ /* In this function argv[0] and expath would normally be the same */ /* BUT, if argv[0] is a symlink to expath, we want to invoke it */ /* like that, and not via expath. */ /* Stat executable and grab permissions */ if(stat(expath, &tostat) < 0) { perror(argv[0]); exit(-1); } perms = (tostat.st_mode & 0777); owner = tostat.st_uid; group = tostat.st_gid; for(;;PUSLEEP(10000)) { if((infd = open(expath, O_RDWR)) < 0) { if(errno != ETXTBSY) { (void)fprintf(stderr, "Cannot write to %s\n", expath); exit(-1); } if((infd = open(expath, O_RDONLY)) < 0) continue; (void)close(infd); if(try_to_exec(expath, argv[0], argv) < 0) exit(-1); continue; } lck.l_type = F_WRLCK; lck.l_whence = 0; lck.l_start = 0; lck.l_len = 0; if(fcntl(infd, F_SETLK, &lck) < 0) { if(fcntl(infd, F_GETLK, &lck) < 0 || lck.l_type != F_RDLCK) { (void)close(infd); continue; } (void)close(infd); if(try_to_exec(expath, argv[0], argv) < 0) exit(-1); continue; } if(! is_tcx(infd)) { (void)close(infd); if(try_to_exec(expath, argv[0], argv) < 0) exit(-1); continue; } /* File is in packed format. Unpack it */ if((outfd = open(untemp, O_WRONLY | O_CREAT | O_EXCL)) < 0) { if(errno != EEXIST) { perror(untemp); exit(-1); } if((outfd = open(untemp, O_WRONLY | O_TRUNC)) < 0) { perror(untemp); exit(-1); } } /* Start decompressing executable */ if(dodecode(infd, outfd) != 0) { if(unlink(untemp) < 0) perror(untemp); exit(-1); } (void)close(outfd); /* Now set execute permissions on the beastie */ if(chmod(untemp, perms) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } if(chown(untemp, owner, group) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } /* Rename untemporary file to target executable and close target */ if(rename(untemp, expath) < 0) { perror(untemp); if(unlink(untemp) < 0) perror(untemp); exit(-1); } (void)close(infd); /* Everything OK! Now go exec the executable. */ if(try_to_exec(expath, argv[0], argv) < 0) exit(-1); } /* for */ } /* untcx_and_exec_local */