void afsdir::ls () { warnx ("files in directory %d:\n", (u_int32_t) ino); pentry (this, "."); pentry (parent, ".."); for (afsdirentry *e = firstentry (NULL); e; e = nextentry (e, NULL)) pentry (e->node, e->name); }
size_t sqFileWriteFromAt(SQFile *f, size_t count, char* byteArrayIndex, size_t startIndex) { /* Write count bytes to the given writable file starting at startIndex in the given byteArray. (See comment in sqFileReadIntoAt for interpretation of byteArray and startIndex). */ char *src; size_t bytesWritten; squeakFileOffsetType position; FILE *file; if (!(sqFileValid(f) && f->writable)) return interpreterProxy->success(false); pentry(sqFileWriteFromAt); file = getFile(f); if (f->lastOp == READ_OP) fseek(file, 0, SEEK_CUR); /* seek between reading and writing */ src = byteArrayIndex + startIndex; bytesWritten = fwrite(src, 1, count, file); position = ftell(file); if (position > getSize(f)) { setSize(f, position); /* update file size */ } if (bytesWritten != count) { interpreterProxy->success(false); } f->lastOp = WRITE_OP; return pexit(bytesWritten); }
sqInt sqFileSetPosition(SQFile *f, squeakFileOffsetType position) { /* Set the file's read/write head to the given position. */ if (!sqFileValid(f)) return interpreterProxy->success(false); if (f->isStdioStream) { pentry(sqFileSetPosition); /* support one character of pushback for stdio streams. */ if (!f->writable && f->lastChar != EOF) { squeakFileOffsetType currentPos = f->lastChar == EOF ? 0 : 1; if (currentPos == position) return pexit(1); if (currentPos - 1 == position) { ungetc(f->lastChar, getFile(f)); f->lastChar = EOF; return pexit(1); } } pfail(); return interpreterProxy->success(false); } fseek(getFile(f), position, SEEK_SET); f->lastOp = UNCOMMITTED; return 1; }
sqInt sqFileSync(SQFile *f) { /* Flush kernel-level buffers of any written/flushed data to disk */ if (!sqFileValid(f)) return interpreterProxy->success(false); pentry(sqFileSync); if (fsync(fileno(getFile(f))) != 0) return interpreterProxy->success(false); return 1; }
sqInt sqFileAtEnd(SQFile *f) { /* Return true if the file's read/write head is at the end of the file. */ if (!sqFileValid(f)) return interpreterProxy->success(false); pentry(sqFileAtEnd); if (f->isStdioStream) return pexit(feof(getFile(f))); return ftell(getFile(f)) >= getSize(f); }
squeakFileOffsetType sqFileGetPosition(SQFile *f) { /* Return the current position of the file's read/write head. */ squeakFileOffsetType position; if (!sqFileValid(f)) return interpreterProxy->success(false); pentry(sqFileGetPosition); if (f->isStdioStream && !f->writable) return pexit(f->lastChar == EOF ? 0 : 1); position = ftell(getFile(f)); if (position == -1) return interpreterProxy->success(false); return position; }
sqInt sqFileFlush(SQFile *f) { /* Flush stdio buffers of file */ if (!sqFileValid(f)) return interpreterProxy->success(false); pentry(sqFileFlush); /* * fflush() can fail for the same reasons write() can so errors must be checked but * sqFileFlush() must support being called on readonly files for historical reasons * so EBADF is ignored */ if (fflush(getFile(f)) != 0 && errno != EBADF) return interpreterProxy->success(false); return 1; }
/* verify memory or file */ static int verify_data(pgpv_t *pgp, const char *cmd, const char *inname, char *in, ssize_t cc) { pgpv_cursor_t cursor; const char *modifiers; size_t size; size_t cookie; char *data; int el; memset(&cursor, 0x0, sizeof(cursor)); if (strcasecmp(cmd, "cat") == 0) { if ((cookie = pgpv_verify(&cursor, pgp, in, cc)) != 0) { if ((size = pgpv_get_verified(&cursor, cookie, &data)) > 0) { write(STDOUT_FILENO, data, size); } return 1; } } else if (strcasecmp(cmd, "dump") == 0) { if ((cookie = pgpv_verify(&cursor, pgp, in, cc)) != 0) { size = pgpv_dump(pgp, &data); write(STDOUT_FILENO, data, size); return 1; } } else if (strcasecmp(cmd, "verify") == 0 || strcasecmp(cmd, "trust") == 0) { modifiers = (strcasecmp(cmd, "trust") == 0) ? "trust" : NULL; if (pgpv_verify(&cursor, pgp, in, cc)) { printf("Good signature for %s made ", inname); ptime(cursor.sigtime); el = pgpv_get_cursor_element(&cursor, 0); pentry(pgp, el, modifiers); return 1; } fprintf(stderr, "Signature did not match contents -- %s\n", cursor.why); } else { fprintf(stderr, "unrecognised command \"%s\"\n", cmd); } return 0; }
size_t sqFileReadIntoAt(SQFile *f, size_t count, char* byteArrayIndex, size_t startIndex) { /* Read count bytes from the given file into byteArray starting at startIndex. byteArray is the address of the first byte of a Squeak bytes object (e.g. String or ByteArray). startIndex is a zero-based index; that is a startIndex of 0 starts writing at the first byte of byteArray. */ char *dst; size_t bytesRead; FILE *file; #if COGMTVM sqInt myThreadIndex; #endif #if COGMTVM && SPURVM int wasPinned; sqInt bufferOop = (sqInt)byteArrayIndex - BaseHeaderSize; #endif if (!sqFileValid(f)) return interpreterProxy->success(false); pentry(sqFileReadIntoAt); file = getFile(f); if (f->writable) { if (f->isStdioStream) return interpreterProxy->success(false); if (f->lastOp == WRITE_OP) fseek(file, 0, SEEK_CUR); /* seek between writing and reading */ } dst = byteArrayIndex + startIndex; if (f->isStdioStream) { #if COGMTVM # if SPURVM if (!(wasPinned = interpreterProxy->isPinned(bufferOop))) { if (!(bufferOop = interpreterProxy->pinObject(bufferOop))) return 0; dst = bufferOop + BaseHeaderSize + startIndex; } # else if (interpreterProxy->isInMemory((sqInt)f) && interpreterProxy->isYoung((sqInt)f) || interpreterProxy->isInMemory((sqInt)dst) && interpreterProxy->isYoung((sqInt)dst)) { interpreterProxy->primitiveFailFor(PrimErrObjectMayMove); return 0; } # endif myThreadIndex = interpreterProxy->disownVM(DisownVMLockOutFullGC); #endif /* COGMTVM */ /* Line buffering in fread can't be relied upon, at least on Mac OS X * and mingw win32. So do it the hard way. */ bytesRead = 0; do { clearerr(file); if (fread(dst, 1, 1, file) == 1) { bytesRead += 1; if (dst[bytesRead-1] == '\n' || dst[bytesRead-1] == '\r') break; } } while (bytesRead <= 0 && ferror(file) && errno == EINTR); #if COGMTVM interpreterProxy->ownVM(myThreadIndex); # if SPURVM if (!wasPinned) interpreterProxy->unpinObject(bufferOop); # endif #endif /* COGMTVM */ } else do { clearerr(file); bytesRead = fread(dst, 1, count, file); } while (bytesRead <= 0 && ferror(file) && errno == EINTR); /* support for skipping back 1 character for stdio streams */ if (f->isStdioStream) if (bytesRead > 0) f->lastChar = dst[bytesRead-1]; f->lastOp = READ_OP; return pexit(bytesRead); }
void do_newuser(int argc, char *argv[]) { int i, l, n, nuid; char *p, *md, *q; Rune *r; Userid *s; Uid *ui, *u2; nuid = 10000; md = 0; if(argc == 2) { nuid = 1; argv[2] = ":"; } for(r = ichar; *r; r++) if(utfrune(argv[1], *r)) { print("illegal character in name\n"); return; } if(strlen(argv[1]) > NAMELEN-1) { print("name %s too long\n", argv[1]); return; } p = argv[2]; switch(*p) { case '?': ui = chkuid(argv[1], 1); if(ui == 0) return; pentry(buf, ui); n = strlen(buf); p = buf; while(n > PRINTSIZE-5) { q = p; p += PRINTSIZE-5; n -= PRINTSIZE-5; i = *p; *p = 0; print("%s", q); *p = i; } print("%s\n", p); return; case ':': if(chkuid(argv[1], 0)) return; while(uidtop(nuid) != 0) nuid++; if(cons.nuid >= conf.nuid) { print("conf.nuid too small (%ld)\n", conf.nuid); return; } wlock(&uidgc.uidlock); ui = &uid[cons.nuid++]; ui->uid = nuid; ui->lead = 0; if(nuid < 10000) { ui->lead = ui->uid; md = argv[1]; } strcpy(ui->name, argv[1]); ui->ngrp = 0; qsort(uid, cons.nuid, sizeof(uid[0]), byuid); wunlock(&uidgc.uidlock); break; case '=': ui = chkuid(argv[1], 1); if(ui == 0) return; p++; if(*p == '\0') { ui->lead = 0; break; } u2 = chkuid(p, 1); if(u2 == 0) return; ui->lead = u2->uid; break; case '+': ui = chkuid(argv[1], 1); if(ui == 0) return; p++; u2 = chkuid(p, 1); if(u2 == 0) return; if(u2->uid == ui->uid) return; if(cons.ngid+ui->ngrp+1 >= conf.gidspace) { print("conf.gidspace too small (%ld)\n", conf.gidspace); return; } for(i = 0; i < ui->ngrp; i++) { if(ui->gtab[i] == u2->uid) { print("member already in group\n"); return; } } wlock(&uidgc.uidlock); s = gidspace+cons.ngid; memmove(s, ui->gtab, ui->ngrp*sizeof(*s)); ui->gtab = s; s[ui->ngrp++] = u2->uid; cons.ngid += ui->ngrp+1; wunlock(&uidgc.uidlock); break; case '-': ui = chkuid(argv[1], 1); if(ui == 0) return; p++; u2 = chkuid(p, 1); if(u2 == 0) return; for(i = 0; i < ui->ngrp; i++) if(ui->gtab[i] == u2->uid) break; if(i == ui->ngrp) { print("%s not in group\n", p); return; } wlock(&uidgc.uidlock); s = ui->gtab+i; ui->ngrp--; memmove(s, s+1, (ui->ngrp-i)*sizeof(*s)); wunlock(&uidgc.uidlock); break; default: if(chkuid(argv[2], 0)) return; for(r = ichar; *r; r++) if(utfrune(argv[2], *r)) { print("illegal character in name\n"); return; } ui = chkuid(argv[1], 1); if(ui == 0) return; if(strlen(argv[2]) > NAMELEN-1) { print("name %s too long\n", argv[2]); return; } wlock(&uidgc.uidlock); strcpy(ui->name, argv[2]); wunlock(&uidgc.uidlock); break; } if(walkto("/adm/users") || con_open(FID2, OWRITE|OTRUNC)) { print("can't open /adm/users for write\n"); return; } cons.offset = 0; for(i = 0; i < cons.nuid; i++) { pentry(buf, &uid[i]); l = strlen(buf); n = con_write(FID2, buf, cons.offset, l); if(l != n) print("short write on /adm/users\n"); cons.offset += n; } if(md != 0) { sprint(buf, "create /usr/%s %s %s 755 d", md, md, md); print("%s\n", buf); cmd_exec(buf); } }