ship *new_ship(const ship_type * stype, region * r, const struct locale *lang) { static char buffer[32]; ship *sh = (ship *)calloc(1, sizeof(ship)); const char *sname = 0; if (!sh) abort(); assert(stype); sh->no = newcontainerid(); sh->coast = NODIRECTION; sh->type = stype; sh->region = r; if (lang) { sname = LOC(lang, stype->_name); if (!sname) { sname = LOC(lang, parameters[P_SHIP]); } } if (!sname) { sname = parameters[P_SHIP]; } assert(sname); snprintf(buffer, sizeof(buffer), "%s %s", sname, itoa36(sh->no)); sh->name = str_strdup(buffer); shash(sh); if (r) { addlist(&r->ships, sh); } return sh; }
/* * stop using a dependency file. Free it if it is no longer linked in. */ void releasedf(Dfile *df) { Dfile **l, *d; QLock *lk; int i; if(df == nil) return; /* remove from hash chain */ i = shash(df->path, Ndfhash); l = &dfhash[i]; lk = &dfhlock[i]; qlock(lk); lock(df); df->use--; if(df->old == 0 || df->use > 0){ unlock(df); qunlock(lk); return; } for(d = *l; d; d = *l){ if(d == df){ *l = d->next; break; } l = &d->next; } unlock(df); qunlock(lk); /* now we know it is unreferenced, remove it */ freedf(df); }
/* * get a cracked dependency file */ Dfile* getdf(char *path) { Dfile *df, **l; QLock *lk; Dir *d; int i, fd; Biobuf *b; i = shash(path, Ndfhash); l = &dfhash[i]; lk = &dfhlock[i]; qlock(lk); for(df = *l; df; df = *l){ if(strcmp(path, df->path) == 0) break; l = &df->next; } d = dirstat(path); if(df){ if(d!=nil && d->qid.type == df->qid.type && d->qid.vers == df->qid.vers && d->qid.vers == df->qid.vers){ free(path); lock(df); df->use++; unlock(df); goto Return; } *l = df->next; freedf(df); } fd = open(path, OREAD); if(d == nil || fd < 0){ close(fd); goto Return; } df = emalloc(sizeof(*df)); b = emalloc(sizeof(Biobuf)); Binit(b, fd, OREAD); df->qid = d->qid; df->path = path; crackdf(df, b, d->length, path); Bterm(b); free(b); df->next = *l; *l = df; df->use = 1; Return: qunlock(lk); free(d); return df; }
/* * search a dependency file for a symbol */ Symbol* dfsearch(Dfile *df, char *name) { Symbol *dp; if(df == nil) return nil; for(dp = df->dhash[shash(name, df->hlen)]; dp; dp = dp->next) if(strcmp(dp->sym, name) == 0) return dp; return nil; }
static int l_new(lua_State * L) { struct leasing_t * e = lua_newuserdata(L, sizeof(struct leasing_t)); e->b = luaL_optnumber(L, 1, 0); e->c = luaL_optnumber(L, 2, 1); e->d = luaL_optnumber(L, 3, 1); if(lua_isstring(L, 4)) { const char * type = luaL_optstring(L, 4, "linear"); switch(shash(type)) { case 0x0b7641e0: /* "linear" */ e->func = linear; break; case 0x95154938: /* "sine-in" */ e->func = sine_in; break; case 0x37be8b19: /* "sine-out" */ e->func = sine_out; break; case 0x44a1b9fd: /* "sine-in-out" */ e->func = sine_in_out; break; case 0x1632ec54: /* "quad-in" */ e->func = quad_in; break; case 0xdc9091b5: /* "quad-out" */ e->func = quad_out; break; case 0x93d38b19: /* "quad-in-out" */ e->func = quad_in_out; break; case 0xf3c312af: /* "cubic-in" */ e->func = cubic_in; break; case 0x6c258370: /* "cubic-out" */ e->func = cubic_out; break; case 0x6f7566f4: /* "cubic-in-out" */ e->func = cubic_in_out; break; case 0xddb3bd56: /* "quart-in" */ e->func = quart_in; break; case 0x942b82f7: /* "quart-out" */ e->func = quart_out; break; case 0xe1790d1b: /* "quart-in-out" */ e->func = quart_in_out; break; case 0xf014a05a: /* "quint-in" */ e->func = quint_in; break; case 0xf2a8c67b: /* "quint-out" */ e->func = quint_out; break; case 0x2fdbd21f: /* "quint-in-out" */ e->func = quint_in_out; break; case 0x828d04e5: /* "expo-in" */ e->func = expo_in; break; case 0xd42dbc66: /* "expo-out" */ e->func = expo_out; break; case 0x59b9842a: /* "expo-in-out" */ e->func = expo_in_out; break; case 0xc5b8c66a: /* "circ-in" */ e->func = circ_in; break; case 0x7cd1ae8b: /* "circ-out" */ e->func = circ_out; break; case 0xe844802f: /* "circ-in-out" */ e->func = circ_in_out; break; case 0x650a381a: /* "back-in" */ e->func = back_in; break; case 0x0651563b: /* "back-out" */ e->func = back_out; break; case 0xd15749df: /* "back-in-out" */ e->func = back_in_out; break; case 0x21ed4e6e: /* "elastic-in" */ e->func = elastic_in; break; case 0x5f97370f: /* "elastic-out" */ e->func = elastic_out; break; case 0xdbc56a33: /* "elastic-in-out" */ e->func = elastic_in_out; break; case 0x3077fd85: /* "bounce-in" */ e->func = bounce_in; break; case 0x3f77c906: /* "bounce-out" */ e->func = bounce_out; break; case 0x7fafccca: /* "bounce-in-out" */ e->func = bounce_in_out; break; default: e->func = linear; break; } } else if(lua_istable(L, 4) && (lua_rawlen(L, 4) == 4)) { double x1, y1; double x2, y2; lua_rawgeti(L, 4, 1); x1 = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, 4, 2); y1 = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, 4, 3); x2 = lua_tonumber(L, -1); lua_pop(L, 1); lua_rawgeti(L, 4, 4); y2 = lua_tonumber(L, -1); lua_pop(L, 1); e->cx = 3.0 * x1; e->bx = 3.0 * (x2 - x1) - e->cx; e->ax = 1.0 - e->cx - e->bx; e->cy = 3.0 * y1; e->by = 3.0 * (y2 - y1) - e->cy; e->ay = 1.0 - e->cy - e->by; if(x1 > 0) e->start = y1 / x1; else if(!y1 && (x2 > 0)) e->start = y2 / x2; else e->start = 0; if(x2 < 1) e->end = (y2 - 1) / (x2 - 1); else if((x2 == 1) && (x1 < 1)) e->end = (y1 - 1) / (x1 - 1); else e->end = 0; e->func = cubic_bezier; } else { e->func = linear; } luaL_setmetatable(L, MT_EASING); return 1; }
void crackdf(Dfile *df, Biobuf *b, uint len, char *dpath) { char *name; char *field[3]; char path[512]; int n, inc, ok, npath; Symbol **l, *dp, *next; File *f, *ef; Dir *d; inc = 32; df->flen = inc; df->file = emalloc(df->flen*sizeof(File)); df->nfile = 0; df->hlen = 1 + len/8; df->dhash = emalloc(df->hlen*sizeof(Symbol*)); l = nil; while((n = awk(b, field, 3)) > 0){ if(n != 2) continue; name = field[1]; switch(*field[0]){ case 'F': if(df->flen == df->nfile){ df->flen += inc; df->file = realloc(df->file, df->flen*sizeof(File)); if(df->file == nil) fatal(mallocerr); memset(&df->file[df->nfile], 0, inc*sizeof(File)); } f = &df->file[df->nfile++]; f->name = strdup(name); l = &f->ref; /* fall through and define as a symbol */ case 'D': if(l == nil) continue; newsym(name, df->nfile-1, &(df->dhash[shash(name, df->hlen)])); break; case 'R': if(l == nil) continue; newsym(name, 0, l); break; } } ef = &df->file[df->nfile]; /* stat the files to get sizes */ npath = strlen(dpath); if(npath+1+1 >= sizeof path) fatal(Etoolong); memmove(path, dpath, npath+1); /* include NUL */ name = strrchr(path, '/') + 1; for(f = df->file; f < ef; f++){ n = strlen(f->name); if(npath+1+n+3+1 > sizeof path) fatal(Etoolong); memmove(name, f->name, n+1); /* include NUL */ ok = access(path, AEXIST); if(ok < 0){ strcpy(name+n, ".Z"); ok = access(path, AEXIST); if(ok < 0){ strcpy(name+n, ".gz"); ok = access(path, AEXIST); } } if(ok >= 0){ free(f->name); f->name = strdup(name); if(f->name == nil) fatal(mallocerr); } d = dirstat(path); if(d){ f->len = d->length; f->mode = d->mode; f->mtime = d->mtime; free(d); }else{ f->len = 0; f->mode = 0; f->mtime = 0; } f->fd = -1; } /* resolve all file references */ for(f = df->file; f < ef; f++) dfresolve(df, f-df->file); /* free the referenced symbols, don't need them anymore */ for(f = df->file; f < ef; f++){ f->tarlen += 2*Tblocksize; /* tars trailing 0 blocks */ for(dp = f->ref; dp != nil; dp = next){ next = dp->next; free(dp); } f->ref = nil; } }
void outlist(char *code0, char *key) { ub4 hash; hash = PHASH(key, strlen(key)); printf("/* %4d */ 0x%s%04X, /* %-25s */\n", hash, code0, shash(key), key); }
OverInfo * GetOverInfo(const char *group) { OverInfo **pov = &OvHash[shash(group) & OVHMASK]; OverInfo *ov; while ((ov = *pov) != NULL) { if (strcmp(group, ov->ov_Group) == 0) break; pov = &ov->ov_Next; } if (ov == NULL) { OverExpire save; struct stat st; char *path; int iter = 0; artno_t endNo = 0; bzero(&st, sizeof(st)); /* * If our cache has grown too large, attempt to free up * a bunch of overview structures. Depending on the load, * we may not be able to. */ if (NumOverInfo >= OV_CACHE_MAX) { int i; int freeup = OV_CACHE_MAX / 2; static int OI = 0; for (i = 0; i < OVHSIZE && freeup; ++i) { int ai = OI; OI = (ai + 1) & OVHMASK; pov = &OvHash[ai]; while ((ov = *pov) != NULL) { if (ov->ov_Refs == 0) { *pov = ov->ov_Next; FreeOverInfo(ov); --NumOverInfo; --freeup; } else { pov = &ov->ov_Next; } } } } ov = zalloc(&SysMemPool, sizeof(OverInfo)); ov->ov_Group = zallocStr(&SysMemPool, group); GetOverExpire(group, &save); ov->ov_LimitSecs = save.oe_LimitDays * 24.0 * 60.0 * 60.0; { const char *rec; int recLen; if ((rec = KPDBReadRecord(KDBActive, group, KP_LOCK, &recLen)) == NULL) { return(NULL); } iter = strtol(KPDBGetField(rec, recLen, "ITER", NULL, "0"), NULL, 10); endNo = strtoll(KPDBGetField(rec, recLen, "NE", NULL, "-1"), NULL, 10); KPDBUnlock(KDBActive, rec); } path = zalloc(&SysMemPool, strlen(MyGroupHome) + 48); again: { const char *gfname = GFName(group, GRPFTYPE_OVER, 0, 1, iter, &DOpts.ReaderGroupHashMethod); sprintf(path, "%s/%s", MyGroupHome, gfname); ov->ov_OFd = -1; if (MakeGroupDirectory(path) == -1) logit(LOG_ERR, "Error on overview dir open/create: %s (%s)", path, strerror(errno)); else ov->ov_OFd = xopen(O_RDWR|O_CREAT, 0644, "%s", path); } if (ov->ov_OFd < 0) { logit(LOG_ERR, "Error on overview open/create for group %s: %s (%s)", group, path, strerror(errno)); FreeOverInfo(ov); ov = NULL; } else { OverHead oh; int r; /* * Leave a shared lock on the over.* file so expireover knows when * it is OK to resize the file. If the file was renamed-over, * we have to re-open it. */ hflock(ov->ov_OFd, 4, XLOCK_SH); if (fstat(ov->ov_OFd, &st) < 0 || st.st_nlink == 0) { hflock(ov->ov_OFd, 4, XLOCK_UN); close(ov->ov_OFd); ov->ov_OFd = -1; goto again; } /* * check if new overview file or illegal overview file and size * accordingly */ r = (read(ov->ov_OFd, &oh, sizeof(oh)) != sizeof(oh)); if (r == 0 && st.st_size == 0) { r = -1; } if (r == 0 && oh.oh_ByteOrder != OH_BYTEORDER) { logit(LOG_CRIT, "Incorrect overview byte order for %s (%s)", group, path); r = -1; } if (r == 0 && oh.oh_Version > OH_VERSION) { logit(LOG_CRIT, "Incorrect overview version for %s (%s)", group, path); r = -1; } if (r != 0) { hflock(ov->ov_OFd, 0, XLOCK_EX); /* * we have to test again after we got the lock in case * another process had a lock and adjusted the file. */ lseek(ov->ov_OFd, 0L, 0); if (read(ov->ov_OFd, &oh, sizeof(oh)) != sizeof(oh) || oh.oh_ByteOrder != OH_BYTEORDER ) { /* * If 'aInitArts' option not given in expireCtl */ if (save.oe_InitArts == 0) save.oe_InitArts = DEFARTSINGROUP; ftruncate(ov->ov_OFd, 0); st.st_size = sizeof(oh) + sizeof(OverArt) * save.oe_InitArts; FileAllocSpace(ov->ov_OFd, 0, st.st_size); fsync(ov->ov_OFd); lseek(ov->ov_OFd, 0L, 0); bzero(&oh, sizeof(oh)); oh.oh_Version = OH_VERSION; oh.oh_ByteOrder = OH_BYTEORDER; oh.oh_HeadSize = sizeof(oh); oh.oh_MaxArts = save.oe_InitArts; strncpy(oh.oh_Gname, group, sizeof(oh.oh_Gname) - 1); oh.oh_DataEntries = save.oe_DataSize; write(ov->ov_OFd, &oh, sizeof(oh)); fsync(ov->ov_OFd); } hflock(ov->ov_OFd, 0, XLOCK_UN); } if (oh.oh_Version < 3) oh.oh_DataEntries = OD_HARTS; if ((oh.oh_DataEntries<=0) || ((oh.oh_DataEntries ^ (oh.oh_DataEntries - 1)) != (oh.oh_DataEntries << 1) - 1)) oh.oh_DataEntries = OD_HARTS; if (oh.oh_Version > 1 && strcmp(oh.oh_Gname, group) != 0) { hflock(ov->ov_OFd, 4, XLOCK_UN); close(ov->ov_OFd); ov->ov_OFd = -1; iter++; goto again; } if (iter > 0) { char tsBuf[64]; sprintf(tsBuf,"%06d", iter); KPDBWrite(KDBActive, group, "ITER", tsBuf, 0); } ov->ov_Iter = iter; ov->ov_endNo = endNo; ov->ov_Size = st.st_size; ov->ov_MaxArts = (st.st_size - oh.oh_HeadSize) / sizeof(OverArt); ov->ov_DataEntryMask = oh.oh_DataEntries - 1; ov->ov_Head = xmap(NULL, ov->ov_Size, PROT_READ, MAP_SHARED, ov->ov_OFd, 0); if (ov->ov_Head == NULL) { logit(LOG_ERR, "Error on overview mmap for group %s (%s)", group, strerror(errno)); FreeOverInfo(ov); ov = NULL; } else { xadvise(ov->ov_Head, ov->ov_Size, XADV_SEQUENTIAL); ++NumOverInfo; pov = &OvHash[shash(group) & OVHMASK]; ov->ov_Next = *pov; *pov = ov; } } zfree(&SysMemPool, path, strlen(MyGroupHome) + 48); } if (ov) ++ov->ov_Refs; return(ov); }