void copy_to_md_fp(FILE *tmp, FILE *out) { static char buf[TOC_ENTRY_SIZE]; char *s; int i, j; fprintf(out, "\n"); fprintf(out, "%s\n", toc_start); fprintf(out, "\n"); for( i = 0; i < toc_cnt; i++ ) { for( j = 0; j < toc_level[i]; j++) fprintf(out, " "); fprintf(out, "* [%s](#%s)\n", getentry(toc[i]), getref(toc[i])); } fprintf(out, "\n"); fprintf(out, "%s\n", toc_end); fprintf(out, "\n"); for(;;) { s = fgets(buf, TOC_ENTRY_SIZE, tmp); if ( s == NULL ) return; fputs(buf, out); } }
int getacl(const char *pathp, aclent_t *aclpbuf) { acl_t acl = NULL, default_acl = NULL; struct stat st; if (stat(pathp, &st) != 0) { return -1; } acl = acl_get_file(pathp, ACL_TYPE_ACCESS); if(acl == NULL && (errno == ENOSYS || errno == ENOTSUP)) { acl = acl_from_mode(st.st_mode); if (acl == NULL) { return -1; } } if (S_ISDIR(st.st_mode)) { default_acl = acl_get_file(pathp, ACL_TYPE_DEFAULT); if ((default_acl != NULL) && (acl_entries(default_acl) == 0)) { acl_free(default_acl); default_acl = NULL; } } acl_entry_t acl_entry; int ret = acl_get_entry(acl, ACL_FIRST_ENTRY, &acl_entry); int i = 0; while(ret > 0) { aclpbuf[i++] = getentry(acl_entry, st, 0); ret = acl_get_entry(acl, ACL_NEXT_ENTRY, &acl_entry); } acl_free(acl); if((default_acl != NULL) && (ret != -1)) { ret = acl_get_entry(default_acl, ACL_FIRST_ENTRY, &acl_entry); while(ret > 0) { aclpbuf[i++] = getentry(acl_entry, st, ACL_DEFAULT); ret = acl_get_entry(default_acl, ACL_NEXT_ENTRY, &acl_entry); } acl_free(default_acl); } return i; }
static int GetEntryFromDisk(void* entries, unsigned entry, struct DirectoryEntry* result) { struct DiskEntryGetterStruct* parameters; parameters = (struct DiskEntryGetterStruct*) entries; return getentry(parameters->handle, parameters->cluster, ENTRY, entry, 0, result); }
static int GetSlotFromDisk(void* entries, int entry, int slot, struct DirectoryEntry* result) { struct DiskEntryGetterStruct* parameters; parameters = (struct DiskEntryGetterStruct*) entries; return getentry(parameters->handle, parameters->cluster, SLOT, entry, slot, result); }
int userdb_change(const char *filename, const struct userentry *uep, int create) { /* possible values for `create' are: * 0: never create a new record (return 1 if not already there). * 1: create a new record if required. * 2: fail (and return 1) if already exists (ie, force creation) * -1: delete an existing record (return 1 if it doesn't exist). * return values are: * 0: OK * 1: Value for `create' prevented us from going ahead * 2: Wanted to create a new record, but there is no room. */ static struct userentry ue; int n, initial, i, place; FILE *file; initbyuserid(filename,"r+b",F_WRLCK,uep->userid,uep->access,&file,&initial,&n); i= initial; place= -1; for(;;) { getentry(file,&ue,filename); if (!ue.userid[0]) { if (place==-1) place= i; } else if (!strncmp(uep->userid,ue.userid,USERID_MAXLEN)) /* && (uep->access < 0 || uep->access == ue.access)) */ { if (create==2) { ufclose(file,filename); return 1; } place=i; break; } i= nextentry(file,i,n,filename); if (i == initial) { /* OK, we didn't find it. We may have found a space, though */ if (create<=0) { ufclose(file,filename); return 1; } if (place==-1) { ufclose(file,filename); return 2; } break; } } if (fseek(file,sizeof(struct userentry)*place,SEEK_SET)) ohshite("User database `%s' unseekable for update",filename); if (create<0) { ue.userid[0]= 0; ue.secretbytes= 0; ue.disabled= 0; memset(ue.secret,0,SECRET_MAXBYTES); uep= &ue; } else { assert(uep->access >= 0); } errno=0; if (fwrite(uep,sizeof(*uep),1,file)!=1) ohshite("User database `%s' unwriteable",filename); if (ufclose(file,filename)) ohshite("User database `%s' uncloseable",filename); return 0; }
struct fielddesc * getentry(char *fmt) { static int initialized = 0; struct fielddesc *table = formattable; if (!initialized) { initialized = 1; #ifdef CTYPES_UNICODE if (sizeof(wchar_t) == sizeof(short)) getentry("u")->pffi_type = &ffi_type_sshort; else if (sizeof(wchar_t) == sizeof(int)) getentry("u")->pffi_type = &ffi_type_sint; else if (sizeof(wchar_t) == sizeof(long)) getentry("u")->pffi_type = &ffi_type_slong; #endif } for (; table->code; ++table) { if (table->code == fmt[0]) return table; } return NULL; }
static DirEntry * find_entry(DirPage0 *page0, const char *name) { DirEntry *entry; unsigned short i; for (i = ntohs(page0->dheader.hash[hashentry (name)]); i != 0; i = ntohs(entry->next)) { entry = getentry (page0, (unsigned short)(i - 1)); if (strcmp (entry->name, name) == 0) return entry; } return NULL; }
static int calcsize(const char *fmt, const formatdef *f) { const formatdef *e; const char *s; char c; int size, num, itemsize, x; s = fmt; size = 0; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { x = num*10 + (c - '0'); if (x/10 != num) { PyErr_SetString( StructError, "overflow in item count"); return -1; } num = x; } if (c == '\0') break; } else num = 1; e = getentry(c, f); if (e == NULL) return -1; itemsize = e->size; size = align(size, c, e); x = num * itemsize; size += x; if (x/itemsize != num || size < 0) { PyErr_SetString(StructError, "total struct size too long"); return -1; } } return size; }
const struct userentry *userdb_find(const char *filename, const char userid[USERID_MAXLEN], int ac) { static struct userentry ue; int n, initial, i; FILE *file; initbyuserid(filename,"rb",F_RDLCK,userid,ac,&file,&initial,&n); i= initial; for(;;) { getentry(file,&ue,filename); if (!strncmp(userid,ue.userid,USERID_MAXLEN) && (ac<0 || ue.access == ac)) { ufclose(file,filename); return &ue; } i= nextentry(file,i,n,filename); if (i == initial) { ufclose(file,filename); return 0; } } }
void main(int argc, char **argv) { int i; long a, ae; char *p; Entry e; Binit(&boutbuf, 1, OWRITE); dict = &dicts[0]; ARGBEGIN { case 'd': p = ARGF(); dict = 0; if(p) { for(i=0; dicts[i].name; i++) if(strcmp(p, dicts[i].name)==0) { dict = &dicts[i]; break; } } if(!dict) { err("unknown dictionary: %s", p); exits("nodict"); } break; case 'D': debug++; break; ARGEND } USED(argc,argv); bdict = Bopen(dict->path, OREAD); ae = Bseek(bdict, 0, 2); if(!bdict) { err("can't open dictionary %s", dict->path); exits("nodict"); } for(a = 0; a < ae; a = (*dict->nextoff)(a+1)) { linelen = 0; e = getentry(a); Bprint(bout, "%ld\t", a); linelen = 4; /* only has to be approx right */ (*dict->printentry)(e, 'h'); } exits(0); }
extern int tcconf_getvalue(tcconf_section_t *sec, char *name, char *fmt, ...) { va_list args; tcc_entry *te; int n; tcref(sec); if(!(te = getvalue(sec->sec, name, &sec))){ tcfree(sec); return -1; } va_start(args, fmt); n = getentry(sec, te, fmt, args, NULL); va_end(args); tcfree(sec); return n < 0? -n: n; }
static int tcconf_nextvalue_vc(tcconf_section_t *ts, char *name, void **state, char **rname, char *fmt, va_list args, tccompare_fn cmp) { v_state *vs; tcc_entry *te; int n = 0; if(!(vs = vstate(ts, name, state))) return -1; while(vs->ml){ n = tcconf_nextvalue_vc(vs->sec, vs->n, &vs->vsr, rname, fmt, args, cmp); if(!vs->vsr){ tcconf_section_t *ms = next_merge(vs->ts, vs); tcfree(vs->sec); if(ms){ vs->sec = ms; } else { vs->sec = vs->ts; } } if(n > 0){ return n; } } te = tclist_prev_matched(vs->sec->sec->entries, &vs->li, vs->n, cmp); if(te){ n = getentry(vs->sec, te, fmt, args, NULL); if(rname) *rname = te->value.key; } else { *state = NULL; vsfree(vs); } return n < 0? -n: n; }
static void readfile(void) { char s[4]; profiledata *d; profilenode *p; size_t i; unsigned long n; int b; /* When reading the profiling output file, we assume that if it begins and * ends with the magic sequence of characters then it is a valid profiling * output file from the mpatrol library. There are probably an infinite * number of checks we could do to ensure that the rest of the data in the * file is valid, but that would be overcomplicated and probably slow this * program down. However, if the file is only partially written then the * getentry() function will catch the error before we do something silly. */ getentry(s, sizeof(char), 4, 0); if (memcmp(s, MP_PROFMAGIC, 4) != 0) { fprintf(stderr, "%s: Invalid file format\n", progname); exit(EXIT_FAILURE); } /* The following test allows us to read profiling output files that were * produced on a different processor architecture. If the next word in the * file does not contain the value 1 then we have to byte-swap any further * data that we read from the file. Note that this test only works if the * word size is the same on both machines. */ getentry(&i, sizeof(size_t), 1, 0); b = (i != 1); /* Get the version number of the mpatrol library which produced the * profiling output file. The profiling file format changed to include the * version number at mpatrol 1.3.0 so we can't reliably read files produced * before then. We also assume that we can't read files produced by later * versions of mpatrol. */ getentry(&version, sizeof(unsigned long), 1, b); if (version < 10300) { fprintf(stderr, "%s: Profiling file version too old\n", progname); exit(EXIT_FAILURE); } else if (version / 100 > MP_VERNUM / 100) { fprintf(stderr, "%s: Profiling file version too new\n", progname); exit(EXIT_FAILURE); } getentry(&sbound, sizeof(size_t), 1, b); getentry(&mbound, sizeof(size_t), 1, b); getentry(&lbound, sizeof(size_t), 1, b); /* Read the allocation and deallocation bins. */ getentry(&binsize, sizeof(size_t), 1, b); if (binsize > 0) { if (((acounts = (size_t *) malloc(binsize * sizeof(size_t))) == NULL) || ((dcounts = (size_t *) malloc(binsize * sizeof(size_t))) == NULL)) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } getentry(acounts, sizeof(size_t), binsize, b); getentry(&atotals, sizeof(size_t), 1, b); getentry(dcounts, sizeof(size_t), binsize, b); getentry(&dtotals, sizeof(size_t), 1, b); for (i = 0; i < binsize; i++) { acount += acounts[i]; dcount += dcounts[i]; if (i == binsize - 1) { atotal += atotals; dtotal += dtotals; } else { atotal += acounts[i] * (i + 1); dtotal += dcounts[i] * (i + 1); } } } /* Read the profiling data structures. */ getentry(&datasize, sizeof(size_t), 1, b); if (datasize > 0) { if ((data = (profiledata *) malloc(datasize * sizeof(profiledata))) == NULL) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } for (i = 0; i < datasize; i++) { getentry(&n, sizeof(unsigned long), 1, b); d = &data[n - 1]; getentry(d->acount, sizeof(size_t), 4, b); getentry(d->atotal, sizeof(size_t), 4, b); getentry(d->dcount, sizeof(size_t), 4, b); getentry(d->dtotal, sizeof(size_t), 4, b); } } /* Read the statistics for every call site. */ getentry(&nodesize, sizeof(size_t), 1, b); if (nodesize > 0) { if ((nodes = (profilenode *) malloc(nodesize * sizeof(profilenode))) == NULL) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } for (i = 0; i < nodesize; i++) { getentry(&n, sizeof(unsigned long), 1, b); p = &nodes[n - 1]; getentry(&p->parent, sizeof(unsigned long), 1, b); getentry(&p->addr, sizeof(void *), 1, b); getentry(&p->symbol, sizeof(unsigned long), 1, b); getentry(&p->name, sizeof(unsigned long), 1, b); getentry(&p->data, sizeof(unsigned long), 1, b); __mp_treeinsert(&proftree, &p->node, (unsigned long) p->addr); cleardata(&p->tdata); p->flags = 0; } } /* Read the table containing the symbol addresses. */ getentry(&i, sizeof(size_t), 1, b); if (i > 0) { if ((addrs = (void **) malloc(i * sizeof(void *))) == NULL) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } getentry(addrs, sizeof(void *), i, b); } /* Read the string table containing the symbol names. */ getentry(&i, sizeof(size_t), 1, b); if (i > 0) { if ((symbols = (char *) malloc(i * sizeof(char))) == NULL) { fprintf(stderr, "%s: Out of memory\n", progname); exit(EXIT_FAILURE); } getentry(symbols, sizeof(char), i, 0); } getentry(s, sizeof(char), 4, 0); if (memcmp(s, MP_PROFMAGIC, 4) != 0) { fprintf(stderr, "%s: Invalid file format\n", progname); exit(EXIT_FAILURE); } }
/* Read an event from the tracing output file. */ #if MP_GUI_SUPPORT static int readevent(XtPointer p) #else /* MP_GUI_SUPPORT */ static int readevent(void) #endif /* MP_GUI_SUPPORT */ { char s[4]; allocation *f; char *g, *h; void *a; size_t i, l, m; unsigned long n, t, u; if (refill(1)) switch (*bufferpos) { case 'A': bufferpos++; bufferlen--; currentevent++; n = getuleb128(); a = (void *) getuleb128(); l = getuleb128(); getsource(&t, &g, &h, &u); f = newalloc(n, currentevent, a, l); stats.acount++; stats.atotal += l; if (stats.pcount < stats.acount - stats.fcount) stats.pcount = stats.acount - stats.fcount; if (stats.ptotal < stats.atotal - stats.ftotal) stats.ptotal = stats.atotal - stats.ftotal; if ((stats.lsize == 0) || (stats.lsize > l)) stats.lsize = l; if (stats.usize < l) stats.usize = l; if (verbose) { fprintf(stdout, "%6lu alloc %6lu " MP_POINTER " %8lu" " %6lu %8lu\n", currentevent, n, a, l, stats.acount - stats.fcount, stats.atotal - stats.ftotal); if (displaysource) printsource(t, g, h, u); } if (hatffile != NULL) fprintf(hatffile, "1 %lu 0x%lx\n", l, a); if (f->entry != NULL) { if ((m = slotentry(f)) > maxslots) maxslots = m; fprintf(simfile, " {%lu, %lu, 0},\n", m, l); } #if MP_GUI_SUPPORT if (usegui) { if (addrbase == NULL) addrbase = (void *) __mp_rounddown((unsigned long) a, 1024); drawmemory(a, l, algc); return 0; } #endif /* MP_GUI_SUPPORT */ return 1; case 'R': bufferpos++; bufferlen--; currentevent++; n = getuleb128(); a = (void *) getuleb128(); l = getuleb128(); getsource(&t, &g, &h, &u); if (f = (allocation *) __mp_search(alloctree.root, n)) { if (f->time != 0) fprintf(stderr, "%s: Allocation index `%lu' has already " "been freed\n", progname, n); stats.acount++; stats.atotal += l; stats.fcount++; stats.ftotal += f->size; if (stats.pcount < stats.acount - stats.fcount) stats.pcount = stats.acount - stats.fcount; if (stats.ptotal < stats.atotal - stats.ftotal) stats.ptotal = stats.atotal - stats.ftotal; if ((stats.lsize == 0) || (stats.lsize > l)) stats.lsize = l; if (stats.usize < l) stats.usize = l; if (verbose) { fprintf(stdout, "%6lu realloc %6lu " MP_POINTER " %8lu %6lu %8lu\n", currentevent, n, a, l, stats.acount - stats.fcount, stats.atotal - stats.ftotal); if (displaysource) printsource(t, g, h, u); } if (hatffile != NULL) fprintf(hatffile, "4 %lu 0x%lx 0x%lx\n", l, f->addr, a); if (f->entry != NULL) { m = slotentry(f); fprintf(simfile, " {%lu, %lu, 1},\n", m, l); } #if MP_GUI_SUPPORT if (usegui) { drawmemory(f->addr, f->size, frgc); drawmemory(a, l, algc); } #endif /* MP_GUI_SUPPORT */ f->addr = a; f->size = l; } else fprintf(stderr, "%s: Unknown allocation index `%lu'\n", progname, n); #if MP_GUI_SUPPORT if (usegui) return 0; #endif /* MP_GUI_SUPPORT */ return 1; case 'F': bufferpos++; bufferlen--; currentevent++; n = getuleb128(); getsource(&t, &g, &h, &u); if (f = (allocation *) __mp_search(alloctree.root, n)) { if (f->time != 0) fprintf(stderr, "%s: Allocation index `%lu' has already " "been freed\n", progname, n); f->time = currentevent - f->event; stats.fcount++; stats.ftotal += f->size; if (verbose) { fprintf(stdout, "%6lu free %6lu " MP_POINTER " %8lu " "%6lu %6lu %8lu\n", currentevent, n, f->addr, f->size, f->time, stats.acount - stats.fcount, stats.atotal - stats.ftotal); if (displaysource) printsource(t, g, h, u); } if (hatffile != NULL) fprintf(hatffile, "2 0x%lx\n", f->addr); if (f->entry != NULL) { fprintf(simfile, " {%lu, 0, 0},\n", slotentry(f)); __mp_freeslot(&table, f->entry); f->entry = NULL; } #if MP_GUI_SUPPORT if (usegui) drawmemory(f->addr, f->size, frgc); #endif /* MP_GUI_SUPPORT */ } else fprintf(stderr, "%s: Unknown allocation index `%lu'\n", progname, n); #if MP_GUI_SUPPORT if (usegui) return 0; #endif /* MP_GUI_SUPPORT */ return 1; case 'H': bufferpos++; bufferlen--; a = (void *) getuleb128(); l = getuleb128(); if (verbose) fprintf(stdout, " reserve " MP_POINTER " %8lu\n", a, l); stats.rcount++; stats.rtotal += l; #if MP_GUI_SUPPORT if (usegui) { if (addrbase == NULL) addrbase = (void *) __mp_rounddown((unsigned long) a, 1024); drawmemory(a, l, frgc); return 0; } #endif /* MP_GUI_SUPPORT */ return 1; case 'I': bufferpos++; bufferlen--; a = (void *) getuleb128(); l = getuleb128(); if (verbose) fprintf(stdout, " internal " MP_POINTER " %8lu\n", a, l); stats.icount++; stats.itotal += l; #if MP_GUI_SUPPORT if (usegui) { drawmemory(a, l, ingc); return 0; } #endif /* MP_GUI_SUPPORT */ return 1; default: break; } if ((hatffile != NULL) && (hatffile != stdout) && (hatffile != stderr)) fclose(hatffile); if (simfile != NULL) { fputs(" {0, 0, 0}\n};\n\n\n", simfile); fputs("int main(void)\n{\n", simfile); fprintf(simfile, " void *p[%lu];\n", maxslots); fputs(" event *e;\n\n", simfile); fputs(" for (e = events; e->index != 0; e++)\n", simfile); fputs(" if (e->resize)\n", simfile); fputs(" {\n", simfile); fputs(" if ((p[e->index - 1] = realloc(p[e->index - 1], " "e->size)) == NULL)\n", simfile); fputs(" {\n", simfile); fputs(" fputs(\"out of memory\\n\", stderr);\n", simfile); fputs(" exit(EXIT_FAILURE);\n", simfile); fputs(" }\n", simfile); fputs(" }\n", simfile); fputs(" else if (e->size == 0)\n", simfile); fputs(" free(p[e->index - 1]);\n", simfile); fputs(" else if ((p[e->index - 1] = malloc(e->size)) == NULL)\n", simfile); fputs(" {\n", simfile); fputs(" fputs(\"out of memory\\n\", stderr);\n", simfile); fputs(" exit(EXIT_FAILURE);\n", simfile); fputs(" }\n", simfile); fputs(" return EXIT_SUCCESS;\n}\n", simfile); if ((simfile != stdout) && (simfile != stderr)) fclose(simfile); } getentry(s, sizeof(char), 4, 0); if (memcmp(s, MP_TRACEMAGIC, 4) != 0) { fprintf(stderr, "%s: Invalid file format\n", progname); exit(EXIT_FAILURE); } if (verbose) fputc('\n', stdout); showstats(); for (i = 0; i < MP_NAMECACHE_SIZE; i++) { if (funcnames[i] != NULL) free(funcnames[i]); if (filenames[i] != NULL) free(filenames[i]); } freeallocs(); fclose(tracefile); #if MP_GUI_SUPPORT if (usegui) return 1; #endif /* MP_GUI_SUPPORT */ return 0; }
/****************************************************************************** * * Call the python object with all arguments * */ static void _CallPythonObject(void *mem, ffi_type *restype, SETFUNC setfunc, PyObject *callable, PyObject *converters, void **pArgs) { int i; PyObject *result; PyObject *arglist = NULL; int nArgs; #ifdef WITH_THREAD PyGILState_STATE state = PyGILState_Ensure(); #endif nArgs = PySequence_Length(converters); /* Hm. What to return in case of error? For COM, 0xFFFFFFFF seems better than 0. */ if (nArgs < 0) { PrintError("BUG: PySequence_Length"); goto Done; } arglist = PyTuple_New(nArgs); if (!arglist) { PrintError("PyTuple_New()"); goto Done; } for (i = 0; i < nArgs; ++i) { /* Note: new reference! */ PyObject *cnv = PySequence_GetItem(converters, i); StgDictObject *dict; if (cnv) dict = PyType_stgdict(cnv); else { PrintError("Getting argument converter %d\n", i); goto Done; } if (dict && dict->getfunc && !IsSimpleSubType(cnv)) { PyObject *v = dict->getfunc(*pArgs, dict->size); if (!v) { PrintError("create argument %d:\n", i); Py_DECREF(cnv); goto Done; } PyTuple_SET_ITEM(arglist, i, v); /* XXX XXX XX We have the problem that c_byte or c_short have dict->size of 1 resp. 4, but these parameters are pushed as sizeof(int) bytes. BTW, the same problem occurrs when they are pushed as parameters */ } else if (dict) { /* Hm, shouldn't we use CData_AtAddress() or something like that instead? */ CDataObject *obj = (CDataObject *)PyObject_CallFunctionObjArgs(cnv, NULL); if (!obj) { PrintError("create argument %d:\n", i); Py_DECREF(cnv); goto Done; } if (!CDataObject_Check(obj)) { Py_DECREF(obj); Py_DECREF(cnv); PrintError("unexpected result of create argument %d:\n", i); goto Done; } memcpy(obj->b_ptr, *pArgs, dict->size); PyTuple_SET_ITEM(arglist, i, (PyObject *)obj); #ifdef MS_WIN32 TryAddRef(dict, obj); #endif } else { PyErr_SetString(PyExc_TypeError, "cannot build parameter"); PrintError("Parsing argument %d\n", i); Py_DECREF(cnv); goto Done; } Py_DECREF(cnv); /* XXX error handling! */ pArgs++; } #define CHECK(what, x) \ if (x == NULL) _AddTraceback(what, __FILE__, __LINE__ - 1), PyErr_Print() result = PyObject_CallObject(callable, arglist); CHECK("'calling callback function'", result); if ((restype != &ffi_type_void) && result) { PyObject *keep; assert(setfunc); #ifdef WORDS_BIGENDIAN /* See the corresponding code in callproc.c, around line 961 */ if (restype->type != FFI_TYPE_FLOAT && restype->size < sizeof(ffi_arg)) mem = (char *)mem + sizeof(ffi_arg) - restype->size; #endif keep = setfunc(mem, result, 0); CHECK("'converting callback result'", keep); /* keep is an object we have to keep alive so that the result stays valid. If there is no such object, the setfunc will have returned Py_None. If there is such an object, we have no choice than to keep it alive forever - but a refcount and/or memory leak will be the result. EXCEPT when restype is py_object - Python itself knows how to manage the refcount of these objects. */ if (keep == NULL) /* Could not convert callback result. */ PyErr_WriteUnraisable(callable); else if (keep == Py_None) /* Nothing to keep */ Py_DECREF(keep); else if (setfunc != getentry("O")->setfunc) { if (-1 == PyErr_Warn(PyExc_RuntimeWarning, "memory leak in callback function.")) PyErr_WriteUnraisable(callable); } } Py_XDECREF(result); Done: Py_XDECREF(arglist); #ifdef WITH_THREAD PyGILState_Release(state); #endif }
/* * Get info for interfaces group. Mimics getmib interface as much as possible * to be substituted later if SunSoft decides to extend its mib2 interface. */ static int getif(mib2_ifEntry_t *ifbuf, size_t size, req_e req_type, mib2_ifEntry_t *resp, size_t *length, int (*comp)(void *, void *), void *arg) { int i, ret, idx = 1; int ifsd; static char *buf = NULL; static int bufsize = 0; struct ifconf ifconf; struct ifreq *ifrp; mib2_ifEntry_t *ifp; mib2_ipNetToMediaEntry_t Media; int nentries = size / sizeof(mib2_ifEntry_t); found_e result = NOT_FOUND; if ((ifsd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { return -1; } if (!buf) { bufsize = 10240; buf = malloc(bufsize); if (!buf) { ret = -1; goto Return; } } ifconf.ifc_buf = buf; ifconf.ifc_len = bufsize; while (ioctl(ifsd, SIOCGIFCONF, &ifconf) == -1) { bufsize += 10240; free(buf); buf = malloc(bufsize); if (!buf) { ret = -1; goto Return; } ifconf.ifc_buf = buf; ifconf.ifc_len = bufsize; } Again: for (i = 0, ifp = (mib2_ifEntry_t *) ifbuf, ifrp = ifconf.ifc_req; ((char *) ifrp < ((char *) ifconf.ifc_buf + ifconf.ifc_len)) && (i < nentries); i++, ifp++, ifrp++, idx++) { DEBUGMSGTL(("kernel_sunos5", "...... getif %s\n", ifrp->ifr_name)); if (ioctl(ifsd, SIOCGIFFLAGS, ifrp) < 0) { ret = -1; DEBUGMSGTL(("kernel_sunos5", "...... SIOCGIFFLAGS failed\n")); goto Return; } memset(ifp, 0, sizeof(mib2_ifEntry_t)); ifp->ifIndex = idx; ifp->ifDescr.o_length = strlen(ifrp->ifr_name); strcpy(ifp->ifDescr.o_bytes, ifrp->ifr_name); ifp->ifAdminStatus = (ifrp->ifr_flags & IFF_RUNNING) ? 1 : 2; ifp->ifOperStatus = (ifrp->ifr_flags & IFF_UP) ? 1 : 2; ifp->ifLastChange = 0; /* Who knows ... */ if (ioctl(ifsd, SIOCGIFMTU, ifrp) < 0) { ret = -1; DEBUGMSGTL(("kernel_sunos5", "...... SIOCGIFMTU failed\n")); goto Return; } ifp->ifMtu = ifrp->ifr_metric; ifp->ifType = 1; ifp->ifSpeed = 0; if ((getKstat(ifrp->ifr_name, "ifspeed", &ifp->ifSpeed) == 0) && (ifp->ifSpeed != 0)) { /* * check for SunOS patch with half implemented ifSpeed */ if (ifp->ifSpeed < 10000) { ifp->ifSpeed *= 1000000; } } else if (getKstat(ifrp->ifr_name, "ifSpeed", &ifp->ifSpeed) == 0) { /* * this is good */ } switch (ifrp->ifr_name[0]) { case 'l': /* le / lo / lane (ATM LAN Emulation) */ if (ifrp->ifr_name[1] == 'o') { if (!ifp->ifSpeed) ifp->ifSpeed = 127000000; ifp->ifType = 24; } else if (ifrp->ifr_name[1] == 'e') { if (!ifp->ifSpeed) ifp->ifSpeed = 10000000; ifp->ifType = 6; } else if (ifrp->ifr_name[1] == 'a') { if (!ifp->ifSpeed) ifp->ifSpeed = 155000000; ifp->ifType = 37; } break; case 'g': /* ge (gigabit ethernet card) */ if (!ifp->ifSpeed) ifp->ifSpeed = 1000000000; ifp->ifType = 6; break; case 'h': /* hme (SBus card) */ case 'e': /* eri (PCI card) */ case 'b': /* be */ case 'd': /* dmfe -- found on netra X1 */ if (!ifp->ifSpeed) ifp->ifSpeed = 100000000; ifp->ifType = 6; break; case 'f': /* fa (Fore ATM */ if (!ifp->ifSpeed) ifp->ifSpeed = 155000000; ifp->ifType = 37; break; case 'q': /* qe (QuadEther)/qa (Fore ATM)/qfe (QuadFastEther)*/ if (ifrp->ifr_name[1] == 'a') { if (!ifp->ifSpeed) ifp->ifSpeed = 155000000; ifp->ifType = 37; } else if (ifrp->ifr_name[1] == 'e') { if (!ifp->ifSpeed) ifp->ifSpeed = 10000000; ifp->ifType = 6; } else if (ifrp->ifr_name[1] == 'f') { if (!ifp->ifSpeed) ifp->ifSpeed = 100000000; ifp->ifType = 6; } break; } if (!strchr(ifrp->ifr_name, ':')) { Counter l_tmp; if (getKstat(ifrp->ifr_name, "ipackets", &ifp->ifInUcastPkts) < 0){ ret = -1; goto Return; } if (getKstat(ifrp->ifr_name, "rbytes", &ifp->ifInOctets) < 0) { ifp->ifInOctets = ifp->ifInUcastPkts * 308; /* XXX */ } if (getKstat(ifrp->ifr_name, "opackets",&ifp->ifOutUcastPkts) < 0){ ret = -1; goto Return; } if (getKstat(ifrp->ifr_name, "obytes", &ifp->ifOutOctets) < 0) { ifp->ifOutOctets = ifp->ifOutUcastPkts * 308; /* XXX */ } if (ifp->ifType == 24) /* Loopback */ continue; if (getKstat(ifrp->ifr_name, "ierrors", &ifp->ifInErrors) < 0) { ret = -1; goto Return; } if (getKstat(ifrp->ifr_name, "oerrors", &ifp->ifOutErrors) < 0) { ret = -1; goto Return; } if (getKstat(ifrp->ifr_name, "brdcstrcv",&ifp->ifInNUcastPkts)==0&& getKstat(ifrp->ifr_name, "multircv", &l_tmp) == 0) { ifp->ifInNUcastPkts += l_tmp; } if (getKstat(ifrp->ifr_name,"brdcstxmt",&ifp->ifOutNUcastPkts)==0&& getKstat(ifrp->ifr_name, "multixmt", &l_tmp) == 0) { ifp->ifOutNUcastPkts += l_tmp; } } /* * An attempt to determine the physical address of the interface. * There should be a more elegant solution using DLPI, but "the margin * is too small to put it here ..." */ if (ioctl(ifsd, SIOCGIFADDR, ifrp) < 0) { ret = -1; goto Return; } if (getMibstat(MIB_IP_NET, &Media, sizeof(mib2_ipNetToMediaEntry_t), GET_EXACT, &Name_cmp, ifrp) == 0) { ifp->ifPhysAddress = Media.ipNetToMediaPhysAddress; } } if ((req_type == GET_NEXT) && (result == NEED_NEXT)) { /* * End of buffer, so "next" is the first item in the next buffer */ req_type = GET_FIRST; } result = getentry(req_type, (void *) ifbuf, size, sizeof(mib2_ifEntry_t), (void *)resp, comp, arg); if ((result != FOUND) && (i == nentries) && ((char *)ifrp < (char *)ifconf.ifc_buf + ifconf.ifc_len)) { /* * We reached the end of supplied buffer, but there is * some more stuff to read, so continue. */ ifconf.ifc_len -= i * sizeof(struct ifreq); ifconf.ifc_req = ifrp; goto Again; } if (result != FOUND) { ret = 2; } else { if ((char *)ifrp < (char *)ifconf.ifc_buf + ifconf.ifc_len) { ret = 1; /* Found and more data to fetch */ } else { ret = 0; /* Found and no more data */ } *length = i * sizeof(mib2_ifEntry_t); /* Actual cache length */ } Return: close(ifsd); return ret; }
static int getmib(int groupname, int subgroupname, void *statbuf, size_t size, size_t entrysize, req_e req_type, void *resp, size_t *length, int (*comp)(void *, void *), void *arg) { int rc, ret = 0, flags; char buf[BUFSIZE]; struct strbuf strbuf; struct T_optmgmt_req *tor = (struct T_optmgmt_req *) buf; struct T_optmgmt_ack *toa = (struct T_optmgmt_ack *) buf; struct T_error_ack *tea = (struct T_error_ack *) buf; struct opthdr *req; found_e result = FOUND; DEBUGMSGTL(("kernel_sunos5", "...... getmib (%d, %d, ...)\n", groupname, subgroupname)); /* * Open the stream driver and push all MIB-related modules */ if (sd == -1) { /* First time */ if ((sd = open(STREAM_DEV, O_RDWR)) == -1) { ret = -1; goto Return; } if (ioctl(sd, I_PUSH, "arp") == -1) { ret = -1; goto Return; } if (ioctl(sd, I_PUSH, "tcp") == -1) { ret = -1; goto Return; } if (ioctl(sd, I_PUSH, "udp") == -1) { ret = -1; goto Return; } DEBUGMSGTL(("kernel_sunos5", "...... modules pushed OK\n")); } /* * First, use bigger buffer, to accelerate skipping unwanted messages */ strbuf.buf = buf; strbuf.maxlen = BUFSIZE; tor->PRIM_type = T_OPTMGMT_REQ; tor->OPT_offset = sizeof(struct T_optmgmt_req); tor->OPT_length = sizeof(struct opthdr); #ifdef MI_T_CURRENT tor->MGMT_flags = MI_T_CURRENT; /* Solaris < 2.6 */ #else tor->MGMT_flags = T_CURRENT; /* Solaris 2.6 */ #endif req = (struct opthdr *)(tor + 1); req->level = groupname; req->name = subgroupname; req->len = 0; strbuf.len = tor->OPT_length + tor->OPT_offset; flags = 0; if ((rc = putmsg(sd, &strbuf, NULL, flags))) { ret = -2; goto Return; } req = (struct opthdr *) (toa + 1); for (;;) { flags = 0; if ((rc = getmsg(sd, &strbuf, NULL, &flags)) == -1) { ret = -EIO; break; } if (rc == 0 && strbuf.len >= sizeof(struct T_optmgmt_ack) && toa->PRIM_type == T_OPTMGMT_ACK && toa->MGMT_flags == T_SUCCESS && req->len == 0) { ret = 2; break; } if (strbuf.len >= sizeof(struct T_error_ack) && tea->PRIM_type == T_ERROR_ACK) { /* Protocol error */ ret = -((tea->TLI_error == TSYSERR) ? tea->UNIX_error : EPROTO); break; } if (rc != MOREDATA || strbuf.len < sizeof(struct T_optmgmt_ack) || toa->PRIM_type != T_OPTMGMT_ACK || toa->MGMT_flags != T_SUCCESS) { ret = -ENOMSG; /* No more messages */ break; } /* * The order in which we get the statistics is determined by the kernel * and not by the group name, so we have to loop until we get the * required statistics. */ if (req->level != groupname || req->name != subgroupname) { strbuf.maxlen = BUFSIZE; strbuf.buf = buf; do { rc = getmsg(sd, NULL, &strbuf, &flags); } while (rc == MOREDATA); continue; } /* * Now when we found our stat, switch buffer to a caller-provided * one. Manipulating the size of it one can control performance, * reducing the number of getmsg calls */ strbuf.buf = statbuf; strbuf.maxlen = size; strbuf.len = 0; flags = 0; do { rc = getmsg(sd, NULL, &strbuf, &flags); switch (rc) { case -1: rc = -ENOSR; goto Return; default: rc = -ENODATA; goto Return; case MOREDATA: case 0: if (req_type == GET_NEXT && result == NEED_NEXT) /* * End of buffer, so "next" is the first item in the next * buffer */ req_type = GET_FIRST; result = getentry(req_type, (void *) strbuf.buf, strbuf.len, entrysize, resp, comp, arg); *length = strbuf.len; /* To use in caller for cacheing */ break; } } while (rc == MOREDATA && result != FOUND); if (result == FOUND) { /* Search is successful */ if (rc != MOREDATA) { ret = 0; /* Found and no more data */ } else { ret = 1; /* Found and there is another unread data block */ } break; } else { /* Restore buffers, continue search */ strbuf.buf = buf; strbuf.maxlen = BUFSIZE; } } Return: ioctl(sd, I_FLUSH, FLUSHRW); DEBUGMSGTL(("kernel_sunos5", "...... getmib returns %d\n", ret)); return ret; }
/* * get MIB-II statistics. It maintaines a simple cache which buffers the last * read block of MIB statistics (which may contain the whole table). It calls * *comp to compare every entry with an entry pointed by arg. *comp should * return 0 if comparison is successful. Req_type may be GET_FIRST, GET_EXACT, * GET_NEXT. If search is successful getMibstat returns 0, otherwise 1. */ int getMibstat(mibgroup_e grid, void *resp, size_t entrysize, req_e req_type, int (*comp) (void *, void *), void *arg) { int ret, rc = -1, mibgr, mibtb, cache_valid; size_t length; mibcache *cachep; found_e result = NOT_FOUND; void *ep; /* * We assume that Mibcache is initialized in mibgroup_e enum order so we * don't check the validity of index here. */ DEBUGMSGTL(("kernel_sunos5", "getMibstat (%d, *, %d, %d, *, *)\n", grid, entrysize, req_type)); cachep = &Mibcache[grid]; mibgr = Mibmap[grid].group; mibtb = Mibmap[grid].table; if (cachep->cache_addr == (void *) -1) /* Hasn't been initialized yet */ init_mibcache_element(cachep); if (cachep->cache_size == 0) { /* Memory allocation problems */ cachep->cache_addr = resp; /* So use caller supplied address instead of cache */ cachep->cache_size = entrysize; cachep->cache_last_found = 0; } if (req_type != GET_NEXT) cachep->cache_last_found = 0; cache_valid = (cachep->cache_time > 0); DEBUGMSGTL(("kernel_sunos5","... cache_valid %d time %ld ttl %d now %ld\n", cache_valid, cachep->cache_time, cachep->cache_ttl, time(NULL))); if (cache_valid) { /* * Is it really? */ if (cachep->cache_comp != (void *)comp || cachep->cache_arg != arg) { cache_valid = 0; /* Nope. */ } } if (cache_valid) { /* * Entry is valid, let's try to find a match */ if (req_type == GET_NEXT) { result = getentry(req_type, (void *)((char *)cachep->cache_addr + (cachep->cache_last_found * entrysize)), cachep->cache_length - (cachep->cache_last_found * entrysize), entrysize, &ep, comp, arg); } else { result = getentry(req_type, cachep->cache_addr, cachep->cache_length, entrysize, &ep, comp, arg); } } if ((cache_valid == 0) || (result == NOT_FOUND) || (result == NEED_NEXT && cachep->cache_flags & CACHE_MOREDATA)) { /* * Either the cache is old, or we haven't found anything, or need the * next item which hasn't been read yet. In any case, fill the cache * up and try to find our entry. */ if (grid == MIB_INTERFACES) { rc = getif((mib2_ifEntry_t *) cachep->cache_addr, cachep->cache_size, req_type, (mib2_ifEntry_t *) & ep, &length, comp, arg); } else { rc = getmib(mibgr, mibtb, cachep->cache_addr, cachep->cache_size, entrysize, req_type, &ep, &length, comp, arg); } if (rc >= 0) { /* Cache has been filled up */ cachep->cache_time = cachep->cache_ttl; cachep->cache_length = length; if (rc == 1) /* Found but there are more unread data */ cachep->cache_flags |= CACHE_MOREDATA; else cachep->cache_flags &= ~CACHE_MOREDATA; cachep->cache_comp = (void *) comp; cachep->cache_arg = arg; } else { cachep->cache_comp = NULL; cachep->cache_arg = NULL; } } DEBUGMSGTL(("kernel_sunos5", "... result %d rc %d\n", result, rc)); if (result == FOUND || rc == 0 || rc == 1) { /* * Entry has been found, deliver it */ if (resp != NULL) { memcpy(resp, ep, entrysize); } ret = 0; cachep->cache_last_found = ((char *)ep - (char *)cachep->cache_addr) / entrysize; } else { ret = 1; /* Not found */ } DEBUGMSGTL(("kernel_sunos5", "... getMibstat returns %d\n", ret)); return ret; }
int fdir_remove (fbuf *dir, const char *name, AFSFid *fid) { int i; unsigned len = dir->len; DirPage0 *page0; DirPage1 *page; unsigned hash_value; DirEntry *entry = NULL; DirEntry *prev_entry; unsigned pageno; int found; unsigned npages; page0 = (DirPage0 *)fbuf_buf(dir); npages = ntohs(page0->header.pg_pgcount); if (npages < len / AFSDIR_PAGESIZE) npages = len / AFSDIR_PAGESIZE; hash_value = hashentry (name); i = ntohs(page0->dheader.hash[hash_value]); found = i == 0; prev_entry = NULL; while (!found) { entry = getentry (page0, i - 1); if (strcmp (entry->name, name) == 0) { found = TRUE; } else { i = ntohs(entry->next); if (i == 0) found = TRUE; prev_entry = entry; } } if (i == 0) return ENOENT; else { if (fid) { fid->Vnode = ntohl(entry->fid.Vnode); fid->Unique = ntohl(entry->fid.Unique); } if (prev_entry == NULL) page0->dheader.hash[hash_value] = entry->next; else prev_entry->next = entry->next; pageno = (i - 1) / ENTRIESPERPAGE; page = getpage (page0, pageno); remove_from_page (page0, page, pageno, (i - 1) % ENTRIESPERPAGE); if (pageno == npages - 1 && is_page_empty (page0, pageno)) { do { len -= AFSDIR_PAGESIZE; --pageno; --npages; } while(is_page_empty(page0, pageno)); page0->header.pg_pgcount = htons(npages); fbuf_truncate (dir, len); } return 0; } }
/* * Collect the requested quota information. */ struct quotause * getprivs(long id, int quotatype, char *fspath) { struct fstab *fs; struct quotause *qup, *quptail; struct quotause *quphead; int qcmd, qupsize, fd; char *qfpathname; static int warned = 0; setfsent(); quphead = quptail = NULL; qcmd = QCMD(Q_GETQUOTA, quotatype); while ((fs = getfsent())) { if (fspath && *fspath && strcmp(fspath, fs->fs_spec) && strcmp(fspath, fs->fs_file)) continue; if (strcmp(fs->fs_vfstype, "ufs")) continue; if (!hasquota(fs, quotatype, &qfpathname)) continue; qupsize = sizeof(*qup) + strlen(qfpathname); if ((qup = (struct quotause *)malloc(qupsize)) == NULL) errx(2, "out of memory"); if (quotactl(fs->fs_file, qcmd, id, &qup->dqblk) != 0) { if (errno == EOPNOTSUPP && !warned) { warned++; warnx("warning: quotas are not compiled into this kernel"); sleep(3); } if ((fd = open(qfpathname, O_RDONLY)) < 0) { fd = open(qfpathname, O_RDWR|O_CREAT, 0640); if (fd < 0 && errno != ENOENT) { warn("%s", qfpathname); free(qup); continue; } warnx("creating quota file %s", qfpathname); sleep(3); fchown(fd, getuid(), getentry(quotagroup, GRPQUOTA)); fchmod(fd, 0640); } lseek(fd, (long)(id * sizeof(struct ufs_dqblk)), L_SET); switch (read(fd, &qup->dqblk, sizeof(struct ufs_dqblk))) { case 0: /* EOF */ /* * Convert implicit 0 quota (EOF) * into an explicit one (zero'ed dqblk) */ bzero((caddr_t)&qup->dqblk, sizeof(struct ufs_dqblk)); break; case sizeof(struct ufs_dqblk): /* OK */ break; default: /* ERROR */ warn("read error in %s", qfpathname); close(fd); free(qup); continue; } close(fd); } strcpy(qup->qfname, qfpathname); strcpy(qup->fsname, fs->fs_file); if (quphead == NULL) quphead = qup; else quptail->next = qup; quptail = qup; qup->next = NULL; } endfsent(); return (quphead); }
static PyObject * struct_pack(PyObject *self, PyObject *args) { const formatdef *f, *e; PyObject *format, *result, *v; char *fmt; int size, num; int i, n; char *s, *res, *restart, *nres; char c; if (args == NULL || !PyTuple_Check(args) || (n = PyTuple_Size(args)) < 1) { PyErr_SetString(PyExc_TypeError, "struct.pack requires at least one argument"); return NULL; } format = PyTuple_GetItem(args, 0); fmt = PyString_AsString(format); if (!fmt) return NULL; f = whichtable(&fmt); size = calcsize(fmt, f); if (size < 0) return NULL; result = PyString_FromStringAndSize((char *)NULL, size); if (result == NULL) return NULL; s = fmt; i = 1; res = restart = PyString_AsString(result); while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') num = num*10 + (c - '0'); if (c == '\0') break; } else num = 1; e = getentry(c, f); if (e == NULL) goto fail; nres = restart + align((int)(res-restart), c, e); /* Fill padd bytes with zeros */ while (res < nres) *res++ = '\0'; if (num == 0 && c != 's') continue; do { if (c == 'x') { /* doesn't consume arguments */ memset(res, '\0', num); res += num; break; } if (i >= n) { PyErr_SetString(StructError, "insufficient arguments to pack"); goto fail; } v = PyTuple_GetItem(args, i++); if (v == NULL) goto fail; if (c == 's') { /* num is string size, not repeat count */ int n; if (!PyString_Check(v)) { PyErr_SetString(StructError, "argument for 's' must be a string"); goto fail; } n = PyString_Size(v); if (n > num) n = num; if (n > 0) memcpy(res, PyString_AsString(v), n); if (n < num) memset(res+n, '\0', num-n); res += num; break; } else if (c == 'p') { /* num is string size + 1, to fit in the count byte */ int n; num--; /* now num is max string size */ if (!PyString_Check(v)) { PyErr_SetString(StructError, "argument for 'p' must be a string"); goto fail; } n = PyString_Size(v); if (n > num) n = num; if (n > 0) memcpy(res+1, PyString_AsString(v), n); if (n < num) /* no real need, just to be nice */ memset(res+1+n, '\0', num-n); if (n > 255) n = 255; *res++ = n; /* store the length byte */ res += num; break; } else { if (e->pack(res, v, e) < 0) goto fail; res += e->size; } } while (--num > 0); } if (i < n) { PyErr_SetString(StructError, "too many arguments for pack format"); goto fail; } return result; fail: Py_DECREF(result); return NULL; }
static int prepare_s(PyStructObject *self) { const formatdef *f; const formatdef *e; formatcode *codes; const char *s; const char *fmt; char c; Py_ssize_t size, len, num, itemsize; fmt = PyBytes_AS_STRING(self->s_format); f = whichtable((char **)&fmt); s = fmt; size = 0; len = 0; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { /* overflow-safe version of if (num*10 + (c - '0') > PY_SSIZE_T_MAX) { ... } */ if (num >= PY_SSIZE_T_MAX / 10 && ( num > PY_SSIZE_T_MAX / 10 || (c - '0') > PY_SSIZE_T_MAX % 10)) goto overflow; num = num*10 + (c - '0'); } if (c == '\0') { PyErr_SetString(StructError, "repeat count given without format specifier"); return -1; } } else num = 1; e = getentry(c, f); if (e == NULL) return -1; switch (c) { case 's': /* fall through */ case 'p': len++; break; case 'x': break; default: len += num; break; } itemsize = e->size; size = align(size, c, e); if (size == -1) goto overflow; /* if (size + num * itemsize > PY_SSIZE_T_MAX) { ... } */ if (num > (PY_SSIZE_T_MAX - size) / itemsize) goto overflow; size += num * itemsize; } /* check for overflow */ if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) { PyErr_NoMemory(); return -1; } self->s_size = size; self->s_len = len; codes = (formatcode *) PyMem_MALLOC((len + 1) * sizeof(formatcode)); if (codes == NULL) { PyErr_NoMemory(); return -1; } /* Free any s_codes value left over from a previous initialization. */ if (self->s_codes != NULL) PyMem_FREE(self->s_codes); self->s_codes = codes; s = fmt; size = 0; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') num = num*10 + (c - '0'); if (c == '\0') break; } else num = 1; e = getentry(c, f); size = align(size, c, e); if (c == 's' || c == 'p') { codes->offset = size; codes->size = num; codes->fmtdef = e; codes++; size += num; } else if (c == 'x') { size += num; } else { while (--num >= 0) { codes->offset = size; codes->size = e->size; codes->fmtdef = e; codes++; size += e->size; } } } codes->fmtdef = NULL; codes->offset = size; codes->size = 0; return 0; overflow: PyErr_SetString(StructError, "total struct size too long"); return -1; }
/* * bitfields extension: * bitsize != 0: this is a bit field. * pbitofs points to the current bit offset, this will be updated. * prev_desc points to the type of the previous bitfield, if any. */ PyObject * CField_FromDesc(PyObject *desc, Py_ssize_t index, Py_ssize_t *pfield_size, int bitsize, int *pbitofs, Py_ssize_t *psize, Py_ssize_t *poffset, Py_ssize_t *palign, int pack, int big_endian) { CFieldObject *self; PyObject *proto; Py_ssize_t size, align, length; SETFUNC setfunc = NULL; GETFUNC getfunc = NULL; StgDictObject *dict; int fieldtype; #define NO_BITFIELD 0 #define NEW_BITFIELD 1 #define CONT_BITFIELD 2 #define EXPAND_BITFIELD 3 self = (CFieldObject *)PyObject_CallObject((PyObject *)&CField_Type, NULL); if (self == NULL) return NULL; dict = PyType_stgdict(desc); if (!dict) { PyErr_SetString(PyExc_TypeError, "has no _stginfo_"); Py_DECREF(self); return NULL; } if (bitsize /* this is a bitfield request */ && *pfield_size /* we have a bitfield open */ #ifdef MS_WIN32 /* MSVC, GCC with -mms-bitfields */ && dict->size * 8 == *pfield_size #else /* GCC */ && dict->size * 8 <= *pfield_size #endif && (*pbitofs + bitsize) <= *pfield_size) { /* continue bit field */ fieldtype = CONT_BITFIELD; #ifndef MS_WIN32 } else if (bitsize /* this is a bitfield request */ && *pfield_size /* we have a bitfield open */ && dict->size * 8 >= *pfield_size && (*pbitofs + bitsize) <= dict->size * 8) { /* expand bit field */ fieldtype = EXPAND_BITFIELD; #endif } else if (bitsize) { /* start new bitfield */ fieldtype = NEW_BITFIELD; *pbitofs = 0; *pfield_size = dict->size * 8; } else { /* not a bit field */ fieldtype = NO_BITFIELD; *pbitofs = 0; *pfield_size = 0; } size = dict->size; length = dict->length; proto = desc; /* Field descriptors for 'c_char * n' are be scpecial cased to return a Python string instead of an Array object instance... */ if (ArrayTypeObject_Check(proto)) { StgDictObject *adict = PyType_stgdict(proto); StgDictObject *idict; if (adict && adict->proto) { idict = PyType_stgdict(adict->proto); if (!idict) { PyErr_SetString(PyExc_TypeError, "has no _stginfo_"); Py_DECREF(self); return NULL; } if (idict->getfunc == getentry("c")->getfunc) { struct fielddesc *fd = getentry("s"); getfunc = fd->getfunc; setfunc = fd->setfunc; } #ifdef CTYPES_UNICODE if (idict->getfunc == getentry("u")->getfunc) { struct fielddesc *fd = getentry("U"); getfunc = fd->getfunc; setfunc = fd->setfunc; } #endif } } self->setfunc = setfunc; self->getfunc = getfunc; self->index = index; Py_INCREF(proto); self->proto = proto; switch (fieldtype) { case NEW_BITFIELD: if (big_endian) self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; else self->size = (bitsize << 16) + *pbitofs; *pbitofs = bitsize; /* fall through */ case NO_BITFIELD: if (pack) align = min(pack, dict->align); else align = dict->align; if (align && *poffset % align) { Py_ssize_t delta = align - (*poffset % align); *psize += delta; *poffset += delta; } if (bitsize == 0) self->size = size; *psize += size; self->offset = *poffset; *poffset += size; *palign = align; break; case EXPAND_BITFIELD: *poffset += dict->size - *pfield_size/8; *psize += dict->size - *pfield_size/8; *pfield_size = dict->size * 8; if (big_endian) self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; else self->size = (bitsize << 16) + *pbitofs; self->offset = *poffset - size; /* poffset is already updated for the NEXT field */ *pbitofs += bitsize; break; case CONT_BITFIELD: if (big_endian) self->size = (bitsize << 16) + *pfield_size - *pbitofs - bitsize; else self->size = (bitsize << 16) + *pbitofs; self->offset = *poffset - size; /* poffset is already updated for the NEXT field */ *pbitofs += bitsize; break; } return (PyObject *)self; }
static int prepare_s(PyStructObject *self) { const formatdef *f; const formatdef *e; formatcode *codes; const char *s; const char *fmt; char c; Py_ssize_t size, len, num, itemsize, x; fmt = PyBytes_AS_STRING(self->s_format); f = whichtable((char **)&fmt); s = fmt; size = 0; len = 0; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') { x = num*10 + (c - '0'); if (x/10 != num) { PyErr_SetString( StructError, "overflow in item count"); return -1; } num = x; } if (c == '\0') break; } else num = 1; e = getentry(c, f); if (e == NULL) return -1; switch (c) { case 's': /* fall through */ case 'p': len++; break; case 'x': break; default: len += num; break; } itemsize = e->size; size = align(size, c, e); x = num * itemsize; size += x; if (x/itemsize != num || size < 0) { PyErr_SetString(StructError, "total struct size too long"); return -1; } } /* check for overflow */ if ((len + 1) > (PY_SSIZE_T_MAX / sizeof(formatcode))) { PyErr_NoMemory(); return -1; } self->s_size = size; self->s_len = len; codes = PyMem_MALLOC((len + 1) * sizeof(formatcode)); if (codes == NULL) { PyErr_NoMemory(); return -1; } self->s_codes = codes; s = fmt; size = 0; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') num = num*10 + (c - '0'); if (c == '\0') break; } else num = 1; e = getentry(c, f); size = align(size, c, e); if (c == 's' || c == 'p') { codes->offset = size; codes->size = num; codes->fmtdef = e; codes++; size += num; } else if (c == 'x') { size += num; } else { while (--num >= 0) { codes->offset = size; codes->size = e->size; codes->fmtdef = e; codes++; size += e->size; } } } codes->fmtdef = NULL; codes->offset = size; codes->size = 0; return 0; }
static int getentry(tcconf_section_t *ts, tcc_entry *te, char *fmt, va_list args, char **tail) { char *f = fmt, *p; int n = 0; tclist_item_t *li = NULL; tcc_value *tv; va_list ac; while((p = strchr(f, '%')) != NULL){ void *dest; int type = 0; if((tv = tclist_next(te->value.values, &li)) == NULL) break; f = p; if(tv->type == TCC_REF && strcmp(tv->value.string, "NULL")){ tcconf_section_t *rs = tcref(ts); tcc_entry *re; int r; if(!(re = getvalue(rs->sec, tv->value.string, &rs))){ n = -n; break; } #ifdef __va_copy __va_copy(ac, args); #else ac = args; #endif r = getentry(ts, re, f, ac, &f); tcfree(rs); if(r < 0){ n += -r; break; } n += r; while(r--) va_arg(args, void *); continue; } dest = va_arg(args, void *); f++; while(!(type & TCC_TYPEMASK) && *f){ switch(*f){ case 's': type |= TCC_STRING; break; case 'd': case 'i': type |= TCC_INTEGER; break; case 'f': type |= TCC_FLOAT; break; case 'l': type |= TCC_LONG; break; case 'u': type |= TCC_UNSIGNED; break; case 'z': type |= TCC_IGNORE; break; } f++; } if(cp_val(ts, tv, type, dest) < 0){ fprintf(stderr, "Type mismatch in '%s'.\n", te->value.key); n = -n; break; } else { n++; } } if(tail) *tail = f; if(li) tclist_unlock(te->value.values, li); return n; }
int main(int argc, char **argv) { struct quotause *qup, *protoprivs, *curprivs; long id, protoid; long long lim; int i, quotatype, range, tmpfd; uid_t startuid, enduid; u_int32_t *limp; char *protoname, *cp, *oldoptarg, ch; int eflag = 0, tflag = 0, pflag = 0; char *fspath = NULL; char buf[MAXLOGNAME]; if (argc < 2) usage(); if (getuid()) errx(1, "permission denied"); quotatype = USRQUOTA; protoprivs = NULL; curprivs = NULL; protoname = NULL; while ((ch = getopt(argc, argv, "ugtf:p:e:")) != -1) { switch(ch) { case 'f': fspath = optarg; break; case 'p': protoname = optarg; pflag++; break; case 'g': quotatype = GRPQUOTA; break; case 'u': quotatype = USRQUOTA; break; case 't': tflag++; break; case 'e': if ((qup = malloc(sizeof(*qup))) == NULL) errx(2, "out of memory"); bzero(qup, sizeof(*qup)); i = 0; oldoptarg = optarg; for (cp = optarg; (cp = strsep(&optarg, ":")) != NULL; i++) { if (cp != oldoptarg) *(cp - 1) = ':'; limp = NULL; switch (i) { case 0: strlcpy(qup->fsname, cp, sizeof(qup->fsname)); break; case 1: limp = &qup->dqblk.dqb_bsoftlimit; break; case 2: limp = &qup->dqblk.dqb_bhardlimit; break; case 3: limp = &qup->dqblk.dqb_isoftlimit; break; case 4: limp = &qup->dqblk.dqb_ihardlimit; break; default: warnx("incorrect quota specification: " "%s", oldoptarg); usage(); break; /* XXX: report an error */ } if (limp != NULL) { lim = strtoll(cp, NULL, 10); if (lim < 0 || lim > UINT_MAX) errx(1, "invalid limit value: " "%lld", lim); *limp = (u_int32_t)lim; } } qup->dqblk.dqb_bsoftlimit = btodb((off_t)qup->dqblk.dqb_bsoftlimit * 1024); qup->dqblk.dqb_bhardlimit = btodb((off_t)qup->dqblk.dqb_bhardlimit * 1024); if (protoprivs == NULL) { protoprivs = curprivs = qup; } else { curprivs->next = qup; curprivs = qup; } eflag++; pflag++; break; default: usage(); } } argc -= optind; argv += optind; if (pflag) { if (protoprivs == NULL) { if ((protoid = getentry(protoname, quotatype)) == -1) exit(1); protoprivs = getprivs(protoid, quotatype, fspath); for (qup = protoprivs; qup; qup = qup->next) { qup->dqblk.dqb_btime = 0; qup->dqblk.dqb_itime = 0; } } for (; argc-- > 0; argv++) { if (strspn(*argv, "0123456789-") == strlen(*argv) && (cp = strchr(*argv, '-')) != NULL) { *cp++ = '\0'; startuid = atoi(*argv); enduid = atoi(cp); if (enduid < startuid) errx(1, "ending uid (%d) must be >= starting uid (%d) when using uid ranges", enduid, startuid); range = 1; } else { startuid = enduid = 0; range = 0; } for ( ; startuid <= enduid; startuid++) { if (range) snprintf(buf, sizeof(buf), "%d", startuid); else snprintf(buf, sizeof(buf), "%s", *argv); if ((id = getentry(buf, quotatype)) < 0) continue; if (eflag) { for (qup = protoprivs; qup; qup = qup->next) { curprivs = getprivs(id, quotatype, qup->fsname); if (curprivs == NULL) continue; strcpy(qup->qfname, curprivs->qfname); strcpy(qup->fsname, curprivs->fsname); } } putprivs(id, quotatype, protoprivs); } } exit(0); } tmpfd = mkstemp(tmpfil); fchown(tmpfd, getuid(), getgid()); if (tflag) { protoprivs = getprivs(0, quotatype, fspath); if (writetimes(protoprivs, tmpfd, quotatype) == 0) exit(1); if (editit(tmpfil) && readtimes(protoprivs, tmpfil)) putprivs(0, quotatype, protoprivs); freeprivs(protoprivs); close(tmpfd); unlink(tmpfil); exit(0); } for ( ; argc > 0; argc--, argv++) { if ((id = getentry(*argv, quotatype)) == -1) continue; curprivs = getprivs(id, quotatype, fspath); if (writeprivs(curprivs, tmpfd, *argv, quotatype) == 0) continue; if (editit(tmpfil) && readprivs(curprivs, tmpfil)) putprivs(id, quotatype, curprivs); freeprivs(curprivs); } close(tmpfd); unlink(tmpfil); exit(0); }
static PyObject * struct_unpack(PyObject *self, PyObject *args) { const formatdef *f, *e; char *str, *start, *fmt, *s; char c; int len, size, num; PyObject *res, *v; if (!PyArg_ParseTuple(args, "ss#:unpack", &fmt, &start, &len)) return NULL; f = whichtable(&fmt); size = calcsize(fmt, f); if (size < 0) return NULL; if (size != len) { PyErr_SetString(StructError, "unpack str size does not match format"); return NULL; } res = PyList_New(0); if (res == NULL) return NULL; str = start; s = fmt; while ((c = *s++) != '\0') { if (isspace(Py_CHARMASK(c))) continue; if ('0' <= c && c <= '9') { num = c - '0'; while ('0' <= (c = *s++) && c <= '9') num = num*10 + (c - '0'); if (c == '\0') break; } else num = 1; e = getentry(c, f); if (e == NULL) goto fail; str = start + align((int)(str-start), c, e); if (num == 0 && c != 's') continue; do { if (c == 'x') { str += num; break; } if (c == 's') { /* num is string size, not repeat count */ v = PyString_FromStringAndSize(str, num); if (v == NULL) goto fail; str += num; num = 0; } else if (c == 'p') { /* num is string buffer size, not repeat count */ int n = *(unsigned char*)str; /* first byte (unsigned) is string size */ if (n >= num) n = num-1; v = PyString_FromStringAndSize(str+1, n); if (v == NULL) goto fail; str += num; num = 0; } else { v = e->unpack(str, e); if (v == NULL) goto fail; str += e->size; } if (v == NULL || PyList_Append(res, v) < 0) goto fail; Py_DECREF(v); } while (--num > 0); } v = PyList_AsTuple(res); Py_DECREF(res); return v; fail: Py_DECREF(res); return NULL; }
int main(int argc, char **argv) { uid_t uid; char *basename; int opt; int i; int tmpfd = -1; basename = argv[0]; if (argc < 2) { usage(); } if (quotactl(Q_SYNC, (char *)NULL, 0, (caddr_t)NULL) < 0 && errno == EINVAL) { (void) printf("Warning: " "Quotas are not compiled into this kernel\n"); (void) sleep(3); } if (getuid()) { (void) fprintf(stderr, "%s: permission denied\n", basename); exit(32); } setupfs(); if (fsqlist == NULL) { (void) fprintf(stderr, "%s: no UFS filesystems with %s file\n", MNTTAB, QFNAME); exit(32); } tmpfd = mkstemp(tmpfil); if (tmpfd == -1 || fchown(tmpfd, getuid(), getgid()) == -1) { fprintf(stderr, "failure in temporary file %s\n", tmpfil); exit(32); } (void) close(tmpfd); while ((opt = getopt(argc, argv, "p:tV")) != EOF) switch (opt) { case 't': gettimes(0); if (editit()) puttimes(0); (void) unlink(tmpfil); exit(0); /*NOTREACHED*/ case 'p': uid = getentry(optarg); if (uid > MAXUID) { (void) unlink(tmpfil); exit(32); } getprivs(uid); if (optind == argc) { (void) unlink(tmpfil); usage(); } for (i = optind; i < argc; i++) { uid = getentry(argv[i]); if (uid > MAXUID) { (void) unlink(tmpfil); exit(32); } getdiscq(uid); putprivs(uid); } (void) unlink(tmpfil); exit(0); /*NOTREACHED*/ case 'V': /* Print command line */ { char *optt; int optc; (void) printf("edquota -F UFS"); for (optc = 1; optc < argc; optc++) { optt = argv[optc]; if (optt) (void) printf(" %s ", optt); } (void) putchar('\n'); } break; case '?': usage(); } for (i = optind; i < argc; i++) { uid = getentry(argv[i]); if (uid > MAXUID) continue; getprivs(uid); if (editit()) putprivs(uid); if (uid == 0) { (void) printf("edquota: Note that uid 0's quotas " "are used as default values for other users,\n"); (void) printf("not as a limit on the uid 0 user.\n"); } } (void) unlink(tmpfil); return (0); }
/* Retrive the (optional) _pack_ attribute from a type, the _fields_ attribute, and create an StgDictObject. Used for Structure and Union subclasses. */ int StructUnionType_update_stgdict(PyObject *type, PyObject *fields, int isStruct) { StgDictObject *stgdict, *basedict; Py_ssize_t len, offset, size, align, i; Py_ssize_t union_size, total_align; Py_ssize_t field_size = 0; int bitofs; PyObject *isPacked; int pack = 0; Py_ssize_t ffi_ofs; int big_endian; /* HACK Alert: I cannot be bothered to fix ctypes.com, so there has to be a way to use the old, broken sematics: _fields_ are not extended but replaced in subclasses. XXX Remove this in ctypes 1.0! */ int use_broken_old_ctypes_semantics; if (fields == NULL) return 0; #ifdef WORDS_BIGENDIAN big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 0 : 1; #else big_endian = PyObject_HasAttrString(type, "_swappedbytes_") ? 1 : 0; #endif use_broken_old_ctypes_semantics = \ PyObject_HasAttrString(type, "_use_broken_old_ctypes_structure_semantics_"); isPacked = PyObject_GetAttrString(type, "_pack_"); if (isPacked) { pack = PyInt_AsLong(isPacked); if (pack < 0 || PyErr_Occurred()) { Py_XDECREF(isPacked); PyErr_SetString(PyExc_ValueError, "_pack_ must be a non-negative integer"); return -1; } Py_DECREF(isPacked); } else PyErr_Clear(); len = PySequence_Length(fields); if (len == -1) { PyErr_SetString(PyExc_TypeError, "'_fields_' must be a sequence of pairs"); return -1; } stgdict = PyType_stgdict(type); if (!stgdict) return -1; /* If this structure/union is already marked final we cannot assign _fields_ anymore. */ if (stgdict->flags & DICTFLAG_FINAL) {/* is final ? */ PyErr_SetString(PyExc_AttributeError, "_fields_ is final"); return -1; } if (stgdict->format) { PyMem_Free(stgdict->format); stgdict->format = NULL; } if (stgdict->ffi_type_pointer.elements) PyMem_Free(stgdict->ffi_type_pointer.elements); basedict = PyType_stgdict((PyObject *)((PyTypeObject *)type)->tp_base); if (basedict && !use_broken_old_ctypes_semantics) { size = offset = basedict->size; align = basedict->align; union_size = 0; total_align = align ? align : 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (basedict->length + len + 1)); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; } memset(stgdict->ffi_type_pointer.elements, 0, sizeof(ffi_type *) * (basedict->length + len + 1)); memcpy(stgdict->ffi_type_pointer.elements, basedict->ffi_type_pointer.elements, sizeof(ffi_type *) * (basedict->length)); ffi_ofs = basedict->length; } else { offset = 0; size = 0; align = 0; union_size = 0; total_align = 1; stgdict->ffi_type_pointer.type = FFI_TYPE_STRUCT; stgdict->ffi_type_pointer.elements = PyMem_Malloc(sizeof(ffi_type *) * (len + 1)); if (stgdict->ffi_type_pointer.elements == NULL) { PyErr_NoMemory(); return -1; } memset(stgdict->ffi_type_pointer.elements, 0, sizeof(ffi_type *) * (len + 1)); ffi_ofs = 0; } assert(stgdict->format == NULL); if (isStruct && !isPacked) { stgdict->format = alloc_format_string(NULL, "T{"); } else { /* PEP3118 doesn't support union, or packed structures (well, only standard packing, but we dont support the pep for that). Use 'B' for bytes. */ stgdict->format = alloc_format_string(NULL, "B"); } #define realdict ((PyObject *)&stgdict->dict) for (i = 0; i < len; ++i) { PyObject *name = NULL, *desc = NULL; PyObject *pair = PySequence_GetItem(fields, i); PyObject *prop; StgDictObject *dict; int bitsize = 0; if (!pair || !PyArg_ParseTuple(pair, "OO|i", &name, &desc, &bitsize)) { PyErr_SetString(PyExc_AttributeError, "'_fields_' must be a sequence of pairs"); Py_XDECREF(pair); return -1; } dict = PyType_stgdict(desc); if (dict == NULL) { Py_DECREF(pair); PyErr_Format(PyExc_TypeError, #if (PY_VERSION_HEX < 0x02050000) "second item in _fields_ tuple (index %d) must be a C type", #else "second item in _fields_ tuple (index %zd) must be a C type", #endif i); return -1; } stgdict->ffi_type_pointer.elements[ffi_ofs + i] = &dict->ffi_type_pointer; if (dict->flags & (TYPEFLAG_ISPOINTER | TYPEFLAG_HASPOINTER)) stgdict->flags |= TYPEFLAG_HASPOINTER; dict->flags |= DICTFLAG_FINAL; /* mark field type final */ if (PyTuple_Size(pair) == 3) { /* bits specified */ switch(dict->ffi_type_pointer.type) { case FFI_TYPE_UINT8: case FFI_TYPE_UINT16: case FFI_TYPE_UINT32: case FFI_TYPE_SINT64: case FFI_TYPE_UINT64: break; case FFI_TYPE_SINT8: case FFI_TYPE_SINT16: case FFI_TYPE_SINT32: if (dict->getfunc != getentry("c")->getfunc #ifdef CTYPES_UNICODE && dict->getfunc != getentry("u")->getfunc #endif ) break; /* else fall through */ default: PyErr_Format(PyExc_TypeError, "bit fields not allowed for type %s", ((PyTypeObject *)desc)->tp_name); Py_DECREF(pair); return -1; } if (bitsize <= 0 || bitsize > dict->size * 8) { PyErr_SetString(PyExc_ValueError, "number of bits invalid for bit field"); Py_DECREF(pair); return -1; } } else bitsize = 0; if (isStruct && !isPacked) { char *fieldfmt = dict->format ? dict->format : "B"; char *fieldname = PyString_AsString(name); char *ptr; Py_ssize_t len = strlen(fieldname) + strlen(fieldfmt); char *buf = alloca(len + 2 + 1); sprintf(buf, "%s:%s:", fieldfmt, fieldname); ptr = stgdict->format; stgdict->format = alloc_format_string(stgdict->format, buf); PyMem_Free(ptr); if (stgdict->format == NULL) { Py_DECREF(pair); return -1; } } if (isStruct) { prop = CField_FromDesc(desc, i, &field_size, bitsize, &bitofs, &size, &offset, &align, pack, big_endian); } else /* union */ { size = 0; offset = 0; align = 0; prop = CField_FromDesc(desc, i, &field_size, bitsize, &bitofs, &size, &offset, &align, pack, big_endian); union_size = max(size, union_size); } total_align = max(align, total_align); if (!prop) { Py_DECREF(pair); return -1; } if (-1 == PyObject_SetAttr(type, name, prop)) { Py_DECREF(prop); Py_DECREF(pair); return -1; } Py_DECREF(pair); Py_DECREF(prop); } #undef realdict if (isStruct && !isPacked) { char *ptr = stgdict->format; stgdict->format = alloc_format_string(stgdict->format, "}"); PyMem_Free(ptr); if (stgdict->format == NULL) return -1; } if (!isStruct) size = union_size; /* Adjust the size according to the alignment requirements */ size = ((size + total_align - 1) / total_align) * total_align; stgdict->ffi_type_pointer.alignment = Py_SAFE_DOWNCAST(total_align, Py_ssize_t, unsigned short); stgdict->ffi_type_pointer.size = size; stgdict->size = size; stgdict->align = total_align; stgdict->length = len; /* ADD ffi_ofs? */ /* We did check that this flag was NOT set above, it must not have been set until now. */ if (stgdict->flags & DICTFLAG_FINAL) { PyErr_SetString(PyExc_AttributeError, "Structure or union cannot contain itself"); return -1; } stgdict->flags |= DICTFLAG_FINAL; return MakeAnonFields(type); }
static int check_dir (const char *filename) { struct stat statbuf; int fd; fbuf the_fbuf; DirPage0 *page0; unsigned i, j; unsigned ind; unsigned len; int ret = 0; unsigned npages = 0; unsigned page_entry_count; unsigned hash_entry_count; unsigned noverfill; uint8_t **my_bitmaps = NULL; fd = open (filename, O_RDONLY | O_BINARY, 0); if (fd < 0) err (1, "open %s", filename); if (fstat (fd, &statbuf) < 0) err (1, "stat %s", filename); len = statbuf.st_size; if (len == 0) errx (1, "length == 0"); if (len % AFSDIR_PAGESIZE != 0) errx (1, "length %% AFSDIR_PAGESIZE != 0"); ret = fbuf_create (&the_fbuf, fd, len, FBUF_READ|FBUF_PRIVATE); if (ret) err (1, "fbuf_create"); page0 = (DirPage0 *)(the_fbuf.buf); printf ("size = %u, pages = %u, pgcount = %u\n", len, len / AFSDIR_PAGESIZE, ntohs(page0->header.pg_pgcount)); if (len / AFSDIR_PAGESIZE != ntohs(page0->header.pg_pgcount)) { ret = 1; goto out; } npages = len / AFSDIR_PAGESIZE; my_bitmaps = malloc (npages * sizeof(*my_bitmaps)); if (my_bitmaps == NULL) err (1, "malloc %lu", (unsigned long)npages * sizeof(*my_bitmaps)); printf ("map: "); for (i = 0; i < min(npages, MAXPAGES); ++i) { printf ("%u ", page0->dheader.map[i]); } printf ("\n"); page_entry_count = 0; for (i = 0; i < npages; ++i) { PageHeader *ph = (PageHeader *)((char *)page0 + i * AFSDIR_PAGESIZE); int start; size_t sz = ENTRIESPERPAGE / 8 * sizeof(*my_bitmaps[i]); my_bitmaps[i] = malloc (sz); if (my_bitmaps[i] == NULL) err (1, "malloc %lu", (unsigned long)sz); memset (my_bitmaps[i], 0, sz); if (ph->pg_tag != htons(AFSDIRMAGIC)) { printf ("page %d: wrong tag: %u\n", i, htons(ph->pg_tag)); ret = 1; goto out; } printf ("page %d: count = %u, tag = %u, freecount = %u\n", i, ntohs(ph->pg_pgcount), htons(ph->pg_tag), ph->pg_freecount); if (i == 0) { if (ph->pg_freecount != 51) { printf ("freecount should be 51!\n"); ret = 1; goto out; } if (ntohs(ph->pg_pgcount) != npages) { printf ("pgcount should be %u!\n", npages); ret = 1; goto out; } } else { if (ph->pg_freecount != 63) { printf ("freecount should be 63!\n"); ret = 1; goto out; } if (ntohs(ph->pg_pgcount) != 0) { printf ("pgcount should be 0!\n"); ret = 1; goto out; } } if (i == 0) start = 13; else start = 1; for (j = start; j < ENTRIESPERPAGE; ++j) { if (ph->pg_bitmap[j / 8] & (1 << (j % 8))) ++page_entry_count; } } printf ("page entry count = %u\n", page_entry_count); hash_entry_count = 0; noverfill = 0; for (i = 0; i < ADIRHASHSIZE; ++i) { const DirEntry *entry; for(ind = ntohs(page0->dheader.hash[i]); ind; ind = ntohs(entry->next)) { DirPage1 *page_n; int len; unsigned off; unsigned pageno; entry = getentry (page0, ind - 1); if (verbose) printf ("%s - %ld.%ld\n", entry->name, (long)ntohl(entry->fid.Vnode), (long)ntohl(entry->fid.Unique)); if (hashentry (entry->name) != i) printf ("wrong name here? hash = %u, name = *%s*\n", i, entry->name); pageno = (ind) / ENTRIESPERPAGE; off = (ind) % ENTRIESPERPAGE; page_n = (DirPage1 *)((char *)page0 + AFSDIR_PAGESIZE * pageno); if (!(page_n->header.pg_bitmap[off / 8] & (1 << (off % 8)))) { printf ("page %d: off %u not set\n", (ind - 1) / ENTRIESPERPAGE, off); } my_bitmaps[pageno][off / 8] |= (1 << (off % 8)); len = strlen(entry->name); while (len > 15) { len -= sizeof(DirEntry); ++noverfill; ++off; my_bitmaps[pageno][off / 8] |= (1 << (off % 8)); } ++hash_entry_count; } } for (i = 0; i < npages; ++i) { DirPage1 *page_n; int j; unsigned unused; if (i == 0) unused = 13; else unused = 1; for (j = 0; j < unused; ++j) my_bitmaps[i][j / 8] |= (1 << (j % 8)); page_n = (DirPage1 *)((char *)page0 + AFSDIR_PAGESIZE * i); if (memcmp (my_bitmaps[i], page_n->header.pg_bitmap, sizeof(my_bitmaps[i])) != 0) { printf ("page %i: bitmaps differ\n" "actual: ", i); for (j = 0; j < ENTRIESPERPAGE / 8; ++j) printf ("%02x ", page_n->header.pg_bitmap[j]); printf ("\n" "calculated: "); for (j = 0; j < ENTRIESPERPAGE / 8; ++j) printf ("%02x ", my_bitmaps[i][j]); printf ("\n"); } } printf ("hash entry count = %u, noverfill = %u, sum = %u\n", hash_entry_count, noverfill, hash_entry_count + noverfill); if (hash_entry_count + noverfill != page_entry_count) ret = 1; out: fbuf_end (&the_fbuf); close (fd); if (my_bitmaps) { for (i = 0; i < npages; ++i) free (my_bitmaps[i]); free (my_bitmaps); } return ret; }