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

unix.superglobalmegacorp.com

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