Annotation of researchv10dc/ipc/bin/pupu/pull.c, revision 1.1.1.1

1.1       root        1: 
                      2:        static char     SCCSID[] = "@(#)pull.c  2.1 DKHOST 85/01/15";
                      3: 
                      4: #include       <sys/types.h>
                      5: #include       "sysexits.h"
                      6: #include       <signal.h>
                      7: #include       "tdefs.h"
                      8: #include       "udefs.h"
                      9: #include       <stdio.h>
                     10: #include       <errno.h>
                     11: #include       <string.h>
                     12: #include       <varargs.h>
                     13: #include       "pupu.h"
                     14: #include       <ndir.h>
                     15: 
                     16:        Efn     takefile, fetchrequest, setdirectory, terminate;
                     17:        Efn     takelink, confirmed, remoteerror, alldone;
                     18: 
                     19:        Sexp    pulltable[] = {
                     20:                'F',    takefile,
                     21:                'L',    takelink,
                     22:                'S',    fetchrequest,
                     23:                'D',    setdirectory,
                     24:                'X',    terminate,
                     25:                0,      0
                     26:        };
                     27: 
                     28:        Sexp    fetchtable[] = {
                     29:                'F',    takefile,
                     30:                'L',    takelink,
                     31:                'c',    confirmed,
                     32:                'e',    remoteerror,
                     33:                'X',    alldone,
                     34:                0,      0
                     35:        };
                     36: 
                     37:        Eexp    justquit[];
                     38: 
                     39:        Sint    dochown;
                     40: 
                     41:        EcharP  below();
                     42:        EpwP    getpwnam();
                     43: 
                     44: pull(fd, names, directory, errfcn, options)
                     45:        PfnP    errfcn;
                     46:        PcharP  *names, directory, options;
                     47: {
                     48:        begin(fd, errfcn, "local", ".");
                     49: 
                     50:        dochown = (geteuid() == 0);
                     51: 
                     52:        if(setjmp(giveup))
                     53:                return(lasterror);
                     54: 
                     55:        sendinit(options);
                     56: 
                     57:        setbase(directory);
                     58: 
                     59:        while(*names)
                     60:                fetchfile(*names++);
                     61: 
                     62:        msginit('X');
                     63:        msgsend();
                     64:        msgwait(justquit);
                     65: 
                     66:        signal(SIGALRM, alarmwas);
                     67:        return(lasterror);
                     68: }
                     69: 
                     70: fetchfile(name)
                     71:        PcharP  name;
                     72: {
                     73:        msginit('S');
                     74: 
                     75:        msgfmt("%s", name);
                     76: 
                     77:        msgconf(fetchtable);
                     78: }
                     79: 
                     80: fetchrequest()
                     81: {
                     82:        Achar   name[NAMELEN];
                     83: 
                     84:        msgtake("%s", name);
                     85: 
                     86:        sendfile(name);
                     87: 
                     88:        reply('c');
                     89: 
                     90:        return(0);
                     91: }
                     92: 
                     93: ppremote(fd)
                     94: {
                     95:        begin(fd, (TfnP) 0, "remote", ".");
                     96: 
                     97:        dochown = (geteuid() == 0);
                     98: 
                     99:        if(setjmp(giveup))
                    100:                return(lasterror);
                    101: 
                    102:        msgwait(inittable);
                    103: 
                    104:        msgwait(pulltable);
                    105: 
                    106:        signal(SIGALRM, alarmwas);
                    107:        return(lasterror);
                    108: }
                    109: 
                    110: setdirectory()
                    111: {
                    112:        setbase(&buf[H_DATA]);
                    113: 
                    114:        reply('c');
                    115: 
                    116:        return(0);
                    117: }
                    118: 
                    119: setbase(p)
                    120:        RcharP  p;
                    121: {
                    122:        RcharP  q;
                    123:        RpwP    pw;
                    124: 
                    125:        if(*p == '/')
                    126:                strcpy(basedir, p);
                    127:        else if(*p == '~'){
                    128:                if(q = strchr(++p, '/'))
                    129:                        *q++ = '\0';
                    130: 
                    131:                if(*p){
                    132:                        if(pw = getpwnam(p))
                    133:                                strcpy(basedir, pw->pw_dir);
                    134:                        else
                    135:                                err("No passwd entry for", p, -EX_NOUSER);
                    136:                }else{
                    137:                        curdir(basedir);
                    138:                        strcpy(wdir, basedir);
                    139:                }
                    140: 
                    141:                if(q){
                    142:                        strcat(basedir, "/");
                    143:                        strcat(basedir, q);
                    144:                }
                    145:        }else{
                    146:                curdir(basedir);
                    147:                strcpy(wdir, basedir);
                    148: 
                    149:                if(strcmp(p, ".") != 0){
                    150:                        strcat(basedir, "/");
                    151:                        strcat(basedir, p);
                    152:                }
                    153:        }
                    154: 
                    155: db(stderr, "setdirectory %s\n", basedir);
                    156:        changedir(basedir);
                    157: 
                    158:        return(0);
                    159: }
                    160: 
                    161: changedir(newdir)
                    162:        PcharP  newdir;
                    163: {
                    164:        RcharP  p;
                    165: 
                    166:        if(!(p = below(wdir, newdir)))
                    167:                p = newdir;
                    168: 
                    169:        if(*p){
                    170:                if(chdir(p) < 0 && (makedirectory(p), chdir(p) < 0))
                    171:                        err("Can't chdir to", p, EX_NOINPUT);
                    172: 
                    173:                strcpy(wdir, newdir);
                    174:        }
                    175: db(stderr, "changedir newdir %s p %s wdir %s\n", newdir, p, wdir);
                    176: }
                    177: 
                    178:        PcharP
                    179: below(ref, check)
                    180:        RcharP  ref, check;
                    181: {
                    182:        Rint    len;
                    183: 
                    184:        len = strlen(ref);
                    185: 
                    186:        if(strncmp(ref, check, len) != 0)
                    187:                return(NIL);
                    188: 
                    189:        check += len;
                    190: 
                    191:        if(*check == '/')
                    192:                return(check+1);
                    193:        if(*check)
                    194:                return(NIL);
                    195:        return(check);
                    196: }
                    197: 
                    198: takefile()
                    199: {
                    200:        RcharP  p;
                    201:        Rint    haderr;
                    202:        Achar   type;
                    203:        Achar   name[NAMELEN];
                    204:        Aint    mode, uid, gid;
                    205:        Along   mtime;
                    206:        time_t  timea[2];
                    207: 
                    208:        msgtake("%c", &type);
                    209:        msgtake("%s", name);
                    210:        msgtake("%o", &mode);
                    211:        msgtake("%d", &uid);
                    212:        msgtake("%d", &gid);
                    213:        msgtake("%ld", &mtime);
                    214: 
                    215:        sprintf(wholename, "%s/%s", basedir, name);
                    216: 
                    217:        p = strrchr(wholename, '/');
                    218:        *p = '\0';
                    219: 
                    220:        changedir(wholename);
                    221: 
                    222:        *p++ = '/';
                    223: 
                    224:        switch(type){
                    225:        case 'r':
                    226:                haderr = pluckregular(p);
                    227:                break;
                    228: 
                    229:        case 'd':
                    230:                makedirectory(p);
                    231:                haderr = 0;
                    232:                break;
                    233: 
                    234:        case 'c':
                    235:                haderr = pluckspecial(p, S_IFCHR);
                    236:                break;
                    237: 
                    238:        case 'b':
                    239:                haderr = pluckspecial(p, S_IFBLK);
                    240:                break;
                    241: 
                    242:        case 'p':
                    243:                haderr = pluckspecial(p, S_IFIFO);
                    244:        }
                    245: 
                    246:        reply('c');
                    247: 
                    248:        if(haderr)
                    249:                return(0);
                    250: 
                    251:        chmod(p, mode);
                    252: 
                    253:        timea[0] = time((TlongP) 0);
                    254:        timea[1] = mtime;
                    255: 
                    256:        if(timea[1] >= timea[0])
                    257:                timea[1] = timea[0] - 1;
                    258: 
                    259:        utime(p, timea);
                    260: 
                    261:        if(dochown)
                    262:                chown(p, uid, gid);
                    263: 
                    264:        return(0);
                    265: }
                    266: 
                    267: pluckregular(p)
                    268:        PcharP  p;
                    269: {
                    270:        Rint    ffd, len;
                    271: 
                    272:        if((ffd = creatn(p, 0200)) < 0
                    273:          && (chmod(p, 0200), (ffd = creatn(p, 0200)) < 0)){
                    274: 
                    275:                warn("Can't create", wholename, EX_CANTCREAT);
                    276: 
                    277:                while(msgread(cfd, buf, sizeof(buf)) > 0);
                    278: 
                    279:                return(BAD);
                    280:        }
                    281: 
                    282:        currentfile = wholename;
                    283:        timeoutmsg = "File reception timed out";
                    284: 
                    285:        alarm(RTIMEOUT);
                    286: 
                    287:        while((len = msgread(cfd, buf, sizeof(buf))) > 0){
                    288: db(stderr, "len %d\n", len);
                    289:                if(write(ffd, buf, len) != len){
                    290:                        warn("Write failed on", wholename, EX_IOERR);
                    291:                        while((len = msgread(cfd, buf, sizeof(buf))) > 0);
                    292:                }
                    293:                alarm(RTIMEOUT);
                    294:        }
                    295: 
                    296:        alarm(0);
                    297: 
                    298:        if(len < 0)
                    299:                stopnow(EX_IOERR);
                    300: 
                    301:        closen(ffd);
                    302: 
                    303:        return(GOOD);
                    304: }
                    305: 
                    306: pluckspecial(name, mode)
                    307:        PcharP  name;
                    308: {
                    309:        Rint    dev;
                    310:        Aint    maj, min;
                    311: 
                    312:        unlink(name);
                    313: 
                    314:        if(mode == S_IFIFO)
                    315:                dev = 0;
                    316:        else{
                    317:                msgtake("%d", &maj);
                    318:                msgtake("%d", &min);
                    319: 
                    320:                dev = makedev(maj, min);
                    321:        }
                    322: 
                    323:        if(mknod(name, mode, dev) < 0){
                    324:                warn("Can't mknod", wholename, EX_CANTCREAT);
                    325:                return(BAD);
                    326:        }
                    327: 
                    328:        return(GOOD);
                    329: }
                    330: 
                    331: takelink()
                    332: {
                    333:        RcharP  p;
                    334:        Achar   name[NAMELEN], prev[NAMELEN];
                    335: 
                    336:        msgtake("%s", name);
                    337:        msgtake("%s", prev);
                    338: 
                    339:        sprintf(wholename, "%s/%s", basedir, name);
                    340: 
                    341:        p = strrchr(wholename, '/');
                    342:        *p = '\0';
                    343:        changedir(wholename);
                    344:        *p++ = '/';
                    345: 
                    346:        sprintf(buf, "%s/%s", basedir, prev);
                    347: 
                    348:        if((link(buf, p) < 0) && (unlink(p), (link(buf, p) < 0)))
                    349:                warn("Can't link to", wholename, EX_CANTCREAT);
                    350: 
                    351:        reply('c');
                    352: 
                    353:        return(0);
                    354: }
                    355: 
                    356: makedirectory(p)
                    357:        PcharP  p;
                    358: {
                    359:        RcharP  q;
                    360:        Aint    pid, n, result;
                    361:        Achar   temp[NAMELEN];
                    362: 
                    363: db(stderr, "makedirectory %s\n", p);
                    364:        sprintf(temp, "%s/", p);
                    365: 
                    366:        q = temp;
                    367:        if(*q == '/')
                    368:                q++;
                    369: 
                    370:        while(q = strchr(q, '/')){
                    371:                *q = '\0';
                    372: 
                    373:                if(access(temp, 1) < 0){
                    374: db(stderr, "mkdir %s\n", temp);
                    375:                        if((pid = fork()) == 0){
                    376:                                freopen("/dev/null", "w", stderr);
                    377:                                execl("/bin/mkdir", "mkdir", temp, 0);
                    378:                                err("No mkdir", NIL, EX_UNAVAILABLE);
                    379:                                /* NOTREACHED */
                    380:                        }
                    381:                        while((n = wait(&result)) > 0 && n != pid);
                    382: 
                    383:                        if(result != 0)
                    384:                                warn("Can't make directory", temp, -EX_CANTCREAT);
                    385:                }
                    386: 
                    387:                *q++ = '/';
                    388:        }
                    389: }
                    390: 
                    391: terminate()
                    392: {
                    393:        msginit('x');
                    394:        msgfmt("%d", lasterror);
                    395:        msgsend();
                    396: 
                    397:        return(1);
                    398: }

unix.superglobalmegacorp.com

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