├── .github └── workflows │ ├── c.yml │ └── coverity.yml ├── .gitignore ├── 9ball.ico ├── 9ball.png ├── 9ball.rc ├── CONTRIBUTORS ├── LICENSE ├── Make.config ├── Make.irix ├── Make.osx ├── Make.osx-x11 ├── Make.pthread ├── Make.sun ├── Make.unix ├── Make.win32 ├── Makefile ├── README.md ├── args.h ├── cpu-bl.c ├── cpu.c ├── drawterm.h ├── drawterm.ico ├── drawterm.rc ├── drawterm.res ├── exportfs ├── Makefile ├── exportfs.c ├── exportfs.h └── exportsrv.c ├── gui-osx ├── Makefile ├── alloc.c ├── cload.c ├── draw.c ├── keycodes.h ├── load.c ├── screen.c └── wstrtoutf.c ├── gui-win32 ├── Makefile ├── alloc.c ├── cload.c ├── draw.c ├── load.c ├── r16.c ├── r16.h └── screen.c ├── gui-x11 ├── Makefile ├── keysym2ucs-x11.c ├── keysym2ucs.h └── x11.c ├── include ├── 9windows.h ├── auth.h ├── authsrv.h ├── cursor.h ├── draw.h ├── dtos.h ├── fcall.h ├── ip.h ├── keyboard.h ├── lib.h ├── libc.h ├── libsec.h ├── memdraw.h ├── memlayer.h ├── mp.h ├── u.h ├── unix.h ├── user.h ├── x └── x.c ├── kern ├── Makefile ├── allocb.c ├── cache.c ├── chan.c ├── dat.h ├── data.c ├── dev.c ├── devaudio-none.c ├── devaudio-sun.c ├── devaudio-unix.c ├── devaudio.c ├── devaudio.h ├── devcons.c ├── devdraw.c ├── devfs-posix.c ├── devfs-win32.c ├── devip-posix.c ├── devip-win32.c ├── devip.c ├── devip.h ├── devlfd.c ├── devmnt.c ├── devmouse.c ├── devpipe.c ├── devroot.c ├── devssl.c ├── devtab.c ├── devtls.c ├── error.c ├── error.h ├── exportfs.c ├── fns.h ├── netif.h ├── parse.c ├── pgrp.c ├── posix.c ├── procinit.c ├── qio.c ├── qlock.c ├── rendez.c ├── rwlock.c ├── screen.h ├── sleep.c ├── smalloc.c ├── stub.c ├── syscall.c ├── sysfile.c ├── sysproc.c ├── term.c ├── uart.c ├── waserror.c ├── win32.c └── x ├── latin1.c ├── lib └── codereview │ ├── codereview.cfg │ └── codereview.py ├── libauth ├── Makefile ├── attr.c ├── auth_attr.c ├── auth_challenge.c ├── auth_getuserpasswd.c ├── auth_proxy.c ├── auth_respond.c ├── auth_rpc.c ├── auth_userpasswd.c ├── authlocal.h └── httpauth.c ├── libauthsrv ├── Makefile ├── _asgetticket.c ├── _asrdresp.c ├── authdial.c ├── convA2M.c ├── convM2A.c ├── convM2PR.c ├── convM2T.c ├── convM2TR.c ├── convPR2M.c ├── convT2M.c ├── convTR2M.c ├── nvcsum.c ├── opasstokey.c ├── passtokey.c └── readnvram.c ├── libc ├── Makefile ├── charstod.c ├── cleanname.c ├── convD2M.c ├── convM2D.c ├── convM2S.c ├── convS2M.c ├── crypt.c ├── dial.c ├── dirfstat.c ├── dirfwstat.c ├── dirmodefmt.c ├── dirstat.c ├── dirwstat.c ├── dofmt.c ├── dorfmt.c ├── encodefmt.c ├── fcallfmt.c ├── fltfmt.c ├── fmt.c ├── fmtdef.h ├── fmtfd.c ├── fmtfdflush.c ├── fmtlock.c ├── fmtprint.c ├── fmtquote.c ├── fmtrune.c ├── fmtstr.c ├── fmtvprint.c ├── fprint.c ├── frand.c ├── getfields.c ├── getpid.c ├── lnrand.c ├── lock.c ├── lrand.c ├── mallocz.c ├── nan.h ├── nan64.c ├── netmkaddr.c ├── nrand.c ├── nsec.c ├── pow10.c ├── print.c ├── pushssl.c ├── pushtls.c ├── rand.c ├── read9pmsg.c ├── readn.c ├── rune.c ├── runefmtstr.c ├── runeseprint.c ├── runesmprint.c ├── runesnprint.c ├── runesprint.c ├── runestrcat.c ├── runestrchr.c ├── runestrcmp.c ├── runestrcpy.c ├── runestrdup.c ├── runestrecpy.c ├── runestrlen.c ├── runestrncat.c ├── runestrncmp.c ├── runestrncpy.c ├── runestrrchr.c ├── runestrstr.c ├── runetype.c ├── runevseprint.c ├── runevsmprint.c ├── runevsnprint.c ├── seprint.c ├── smprint.c ├── snprint.c ├── sprint.c ├── strecpy.c ├── strtod.c ├── strtod.h ├── strtoll.c ├── sysfatal.c ├── time.c ├── tokenize.c ├── truerand.c ├── u16.c ├── u32.c ├── u64.c ├── utf.h ├── utfdef.h ├── utfecpy.c ├── utflen.c ├── utfnlen.c ├── utfrrune.c ├── utfrune.c ├── utfutf.c ├── vfprint.c ├── vseprint.c ├── vsmprint.c └── vsnprint.c ├── libdraw ├── Makefile ├── alloc.c ├── arith.c ├── bytesperline.c ├── chan.c ├── defont.c ├── drawrepl.c ├── icossin.c ├── icossin2.c ├── rectclip.c └── rgb.c ├── libip ├── Makefile ├── bo.c ├── classmask.c ├── eipfmt.c ├── ipaux.c └── parseip.c ├── libmemdraw ├── Makefile ├── alloc.c ├── alpha.hoc ├── arc.c ├── arctest.c ├── cload.c ├── cmap.c ├── cread.c ├── defont.c ├── draw.c ├── drawtest.c ├── ellipse.c ├── fillpoly.c ├── hwdraw.c ├── iprint.c ├── line.c ├── load.c ├── mkcmap.c ├── openmemsubfont.c ├── poly.c ├── read.c ├── string.c ├── subfont.c ├── times ├── unload.c └── write.c ├── libmemlayer ├── Makefile ├── draw.c ├── lalloc.c ├── layerop.c ├── ldelete.c ├── lhide.c ├── line.c ├── load.c ├── lorigin.c ├── lsetrefresh.c ├── ltofront.c ├── ltorear.c └── unload.c ├── libmp ├── Makefile ├── betomp.c ├── crt.c ├── crttest.c ├── dat.h ├── letomp.c ├── mpadd.c ├── mpaux.c ├── mpcmp.c ├── mpdigdiv.c ├── mpdiv.c ├── mpeuclid.c ├── mpexp.c ├── mpextendedgcd.c ├── mpfactorial.c ├── mpfmt.c ├── mpinvert.c ├── mpleft.c ├── mpmod.c ├── mpmul.c ├── mprand.c ├── mpright.c ├── mpsub.c ├── mptobe.c ├── mptoi.c ├── mptole.c ├── mptoui.c ├── mptouv.c ├── mptov.c ├── mpvecadd.c ├── mpveccmp.c ├── mpvecdigmuladd.c ├── mpvecsub.c ├── os.h ├── reduce └── strtomp.c ├── libsec ├── Makefile ├── aes.c ├── blowfish.c ├── chacha.c ├── chachatest.c ├── decodepem.c ├── des.c ├── des3CBC.c ├── des3ECB.c ├── desCBC.c ├── desECB.c ├── desmodes.c ├── dsaalloc.c ├── dsagen.c ├── dsaprimes.c ├── dsaprivtopub.c ├── dsasign.c ├── dsaverify.c ├── egalloc.c ├── egdecrypt.c ├── egencrypt.c ├── eggen.c ├── egprivtopub.c ├── egsign.c ├── egtest.c ├── egverify.c ├── fastrand.c ├── genprime.c ├── genrandom.c ├── gensafeprime.c ├── genstrongprime.c ├── hmac.c ├── hmactest.c ├── md4.c ├── md4test.c ├── md5.c ├── md5block.c ├── md5pickle.c ├── nfastrand.c ├── os.h ├── primetest.c ├── prng.c ├── probably_prime.c ├── rc4.c ├── readcert.c ├── rsaalloc.c ├── rsadecrypt.c ├── rsaencrypt.c ├── rsafill.c ├── rsagen.c ├── rsaprivtopub.c ├── rsatest.c ├── sha1.c ├── sha1block.c ├── sha1pickle.c ├── sha2_128.c ├── sha2_64.c ├── sha2block128.c ├── sha2block64.c ├── sha2test.c ├── smallprimes.c ├── smallprimetest.c ├── thumb.c ├── tlshand.c └── x509.c ├── main.c ├── posix-386 ├── Makefile ├── getcallerpc.c ├── md5block.spp ├── sha1block.spp └── tas.c ├── posix-amd64 ├── Makefile ├── getcallerpc.c ├── md5block.c ├── sha1block.c └── tas.c ├── posix-arm ├── Makefile ├── getcallerpc.c ├── md5block.c ├── sha1block.c └── tas.c ├── posix-factotum.c ├── posix-mips ├── Makefile ├── getcallerpc.c ├── md5block.c ├── sha1block.c └── tas.s ├── posix-port ├── Makefile ├── getcallerpc.c ├── md5block.c └── sha1block.c ├── posix-power ├── Makefile ├── getcallerpc.c ├── md5block.c ├── sha1block.c └── tas.c ├── posix-sun4u ├── Makefile ├── getcallerpc.c ├── md5block.c ├── sha1block.c └── tas.s ├── readcons.c ├── resource.h ├── secstore.c ├── win32-386 ├── Makefile ├── getcallerpc.c ├── md5block.spp ├── sha1block.spp └── tas.c └── win32-factotum.c /.github/workflows/c.yml: -------------------------------------------------------------------------------- 1 | name: C 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | pull_request: 7 | branches: [ main ] 8 | 9 | jobs: 10 | build: 11 | 12 | runs-on: ubuntu-latest 13 | 14 | steps: 15 | - uses: actions/checkout@v3 16 | - name: make clean 17 | run: CONF=unix make clean 18 | - name: make 19 | run: CONF=unix make 20 | -------------------------------------------------------------------------------- /.github/workflows/coverity.yml: -------------------------------------------------------------------------------- 1 | name: Coverity Scan 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | 7 | env: 8 | CONF: unix 9 | 10 | jobs: 11 | coverity: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - uses: actions/checkout@v3 15 | - uses: vapier/coverity-scan-action@v1 16 | with: 17 | email: ${{ secrets.COVERITY_SCAN_EMAIL }} 18 | token: ${{ secrets.COVERITY_SCAN_TOKEN }} 19 | command: make 20 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | drawterm.log 2 | state 3 | state.old 4 | state.journal 5 | drawterm 6 | *.o 7 | *.a 8 | -------------------------------------------------------------------------------- /9ball.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9fans/drawterm/6f30fc8502ade6fd510d6ef8280686ada7b60964/9ball.ico -------------------------------------------------------------------------------- /9ball.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9fans/drawterm/6f30fc8502ade6fd510d6ef8280686ada7b60964/9ball.png -------------------------------------------------------------------------------- /9ball.rc: -------------------------------------------------------------------------------- 1 | IDI_ICON1 ICON DISCARDABLE "9ball.ico" 2 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This file lists people who have contributed code to 2 | # drawterm, as recorded by the Mercurial and CVS logs. 3 | # The list is incomplete but a start. 4 | # My thanks to the people not listed here too. 5 | 6 | Andrey Mirtchovski 7 | Erik Quanstrom 8 | David du Colombier <0intro@gmail.com> 9 | Russ Cox 10 | Yaroslav 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright © 2021 Plan 9 Foundation 2 | Portions Copyright © 2005 Russ Cox, MIT 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 18 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 19 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 20 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 21 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Make.config: -------------------------------------------------------------------------------- 1 | AUDIO=none 2 | include $(ROOT)/Make.$(CONF) 3 | -------------------------------------------------------------------------------- /Make.irix: -------------------------------------------------------------------------------- 1 | # Unix 2 | PTHREAD= # for Mac 3 | #PTHREAD=-pthread 4 | AR=ar 5 | AS=as 6 | ASFLAGS=-c -mips3 7 | RANLIB=true 8 | X11=/usr/X11R6 9 | #CC=gcc 10 | #CFLAGS=-Wall -Wno-missing-braces -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -I$(X11)/include -D_THREAD_SAFE $(PTHREAD) -O2 11 | CC=cc 12 | CFLAGS=-g -O2 -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -I$(X11)/include -DIRIX 13 | O=o 14 | OS=posix 15 | GUI=x11 16 | LDADD=-L$(X11)/lib -lX11 -g -lpthread 17 | LDFLAGS=$(PTHREAD) 18 | TARG=drawterm 19 | MAKE=gmake 20 | 21 | all: default 22 | 23 | libmachdep.a: 24 | (cd posix-mips && $(MAKE)) 25 | -------------------------------------------------------------------------------- /Make.osx: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | PTHREAD= # for Mac 3 | AR=ar 4 | AS=as 5 | RANLIB=ranlib 6 | CC=gcc 7 | CFLAGS=-Wall -Wno-missing-braces -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -D_THREAD_SAFE $(PTHREAD) -O2 8 | O=o 9 | OS=posix 10 | GUI=osx 11 | LDADD=-ggdb -framework Carbon -framework QuickTime 12 | LDFLAGS=$(PTHREAD) 13 | TARG=drawterm 14 | AUDIO=none 15 | 16 | all: default 17 | 18 | libmachdep.a: 19 | arch=`uname -m|sed 's/i.86/386/;s/Power Macintosh/power/;s/x86_64/amd64/'`; \ 20 | (cd posix-$$arch && make) 21 | -------------------------------------------------------------------------------- /Make.osx-x11: -------------------------------------------------------------------------------- 1 | # Mac OS X 2 | PTHREAD= # for Mac 3 | AR=ar 4 | AS=as 5 | RANLIB=ranlib 6 | X11=/usr/X11R6 7 | CC=gcc 8 | CFLAGS=-Wall -Wno-missing-braces -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -I$(X11)/include -D_THREAD_SAFE $(PTHREAD) -O2 9 | O=o 10 | OS=posix 11 | GUI=x11 12 | LDADD=-L$(X11)/lib -lX11 -ggdb 13 | LDFLAGS=$(PTHREAD) 14 | TARG=drawterm 15 | AUDIO=none 16 | 17 | all: default 18 | 19 | libmachdep.a: 20 | arch=`uname -m|sed 's/i.86/386/;s/Power Macintosh/power/;s/x86_64/amd64/'`; \ 21 | (cd posix-$$arch && make) 22 | -------------------------------------------------------------------------------- /Make.pthread: -------------------------------------------------------------------------------- 1 | # Unix 2 | #PTHREAD= # for Mac 3 | PTHREAD=-pthread -DPTHREAD 4 | AR=ar 5 | AS=no-as-here 6 | RANLIB=ranlib 7 | X11=/usr/X11R6 8 | CC=gcc 9 | CFLAGS=-Wall -Wno-missing-braces -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -I$(X11)/include -D_THREAD_SAFE $(PTHREAD) -O2 10 | O=o 11 | OS=posix 12 | GUI=x11 13 | LDADD=-L$(X11)/lib64 -L$(X11)/lib -lX11 -ggdb 14 | LDFLAGS=$(PTHREAD) 15 | TARG=drawterm 16 | # AUDIO=none 17 | AUDIO=unix 18 | 19 | all: default 20 | 21 | libmachdep.a: 22 | (cd posix-port && make) 23 | -------------------------------------------------------------------------------- /Make.sun: -------------------------------------------------------------------------------- 1 | # Sun-specific 2 | PTHREAD= 3 | AR=ar 4 | AS=as 5 | RANLIB=ranlib 6 | X11=/usr/X11R6 7 | CC=cc 8 | CFLAGS=-xCC -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -g -D_THREAD_SAFE 9 | O=o 10 | OS=posix 11 | GUI=x11 12 | LDADD=-L$(X11)/lib -lX11 -lrt -lpthread -lsocket -lnsl 13 | LDFLAGS= 14 | TARG=drawterm 15 | AUDIO=none 16 | 17 | all: default 18 | 19 | libmachdep.a: 20 | arch=`uname -m|sed 's/i.86/386/;s/Power Macintosh/power/'`; \ 21 | (cd posix-$$arch && make) 22 | -------------------------------------------------------------------------------- /Make.unix: -------------------------------------------------------------------------------- 1 | # Unix 2 | #PTHREAD= # for Mac 3 | PTHREAD=-pthread 4 | AR=ar 5 | AS=as 6 | RANLIB=ranlib 7 | X11=/usr/X11R6 8 | CC=gcc 9 | CFLAGS=-Wall -Wno-missing-braces -fno-strict-aliasing -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -I$(X11)/include -D_THREAD_SAFE $(PTHREAD) -O2 10 | O=o 11 | OS=posix 12 | GUI=x11 13 | LDADD=-L$(X11)/lib64 -L$(X11)/lib -lX11 -ggdb 14 | LDFLAGS=$(PTHREAD) 15 | TARG=drawterm 16 | # AUDIO=none 17 | AUDIO=unix 18 | 19 | all: default 20 | 21 | libmachdep.a: 22 | arch=`uname -m|sed 's/i.86/386/;s/Power Macintosh/power/; s/x86_64/amd64/'`; \ 23 | (cd posix-$$arch && make) 24 | -------------------------------------------------------------------------------- /Make.win32: -------------------------------------------------------------------------------- 1 | # Windows via mingw32 2 | # MING=mingw32- is necessary if you're cross-compiling 3 | # on another platform. Otherwise the binaries are just 4 | # named gcc, etc. 5 | 6 | MING=i686-w64-mingw32- 7 | #MING= 8 | AR=$(MING)ar 9 | CC=$(MING)gcc 10 | AS=$(MING)as 11 | RANLIB=$(MING)ranlib 12 | WINDRES=$(MING)windres 13 | CFLAGS=-Wall -Wno-missing-braces -I$(ROOT)/include -I$(ROOT) -I$(ROOT)/kern -c -D_X86_ -DIS_32 -DWINDOWS -DUNICODE -O2 -fcommon 14 | O=o 15 | FS=fs-win32 16 | IP=win32 17 | OS=win32 18 | GUI=win32 19 | LDFLAGS=-mwindows 20 | LDADD=-lkernel32 -ladvapi32 -lgdi32 -lmpr -lwsock32 -lmsvcrt -lmingw32 21 | TARG=drawterm.exe 22 | XOFILES=9ball.$O 23 | 24 | # Windows via MSVC 25 | #AR=??? 26 | #CC=cl 27 | #CFLAGS=-c -nologo -W3 -YX -Zi -MT -Zl -Iinclude -DWINDOWS 28 | #O=obj 29 | #FS=fs-win32 30 | #IP=win32 31 | #OS=win32 32 | #GUI=win32 33 | 34 | all: default 35 | 36 | # for root 37 | libmachdep.a: 38 | (cd win32-386; make) 39 | 40 | 9ball.$O: 9ball.rc 9ball.ico 41 | $(WINDRES) -i 9ball.rc -o 9ball.o 42 | 43 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | ROOT=. 2 | 3 | include Make.config 4 | 5 | OFILES=\ 6 | main.$O\ 7 | cpu.$O\ 8 | readcons.$O\ 9 | secstore.$O\ 10 | latin1.$O\ 11 | $(OS)-factotum.$O\ 12 | $(XOFILES)\ 13 | 14 | LIBS1=\ 15 | kern/libkern.a\ 16 | exportfs/libexportfs.a\ 17 | libauth/libauth.a\ 18 | libauthsrv/libauthsrv.a\ 19 | libsec/libsec.a\ 20 | libmp/libmp.a\ 21 | libmemdraw/libmemdraw.a\ 22 | libmemlayer/libmemlayer.a\ 23 | libdraw/libdraw.a\ 24 | gui-$(GUI)/libgui.a\ 25 | libc/libc.a\ 26 | libip/libip.a\ 27 | 28 | # stupid gcc 29 | LIBS=$(LIBS1) $(LIBS1) $(LIBS1) libmachdep.a 30 | 31 | default: $(TARG) 32 | $(TARG): $(OFILES) $(LIBS) 33 | $(CC) $(LDFLAGS) -o $(TARG) $(OFILES) $(LIBS) $(LDADD) 34 | 35 | %.$O: %.c 36 | $(CC) $(CFLAGS) $*.c 37 | 38 | clean: 39 | rm -f *.o */*.o */*.a *.a drawterm drawterm.exe 40 | 41 | kern/libkern.a: 42 | (cd kern; $(MAKE)) 43 | 44 | exportfs/libexportfs.a: 45 | (cd exportfs; $(MAKE)) 46 | 47 | libauth/libauth.a: 48 | (cd libauth; $(MAKE)) 49 | 50 | libauthsrv/libauthsrv.a: 51 | (cd libauthsrv; $(MAKE)) 52 | 53 | libmp/libmp.a: 54 | (cd libmp; $(MAKE)) 55 | 56 | libsec/libsec.a: 57 | (cd libsec; $(MAKE)) 58 | 59 | libmemdraw/libmemdraw.a: 60 | (cd libmemdraw; $(MAKE)) 61 | 62 | libmemlayer/libmemlayer.a: 63 | (cd libmemlayer; $(MAKE)) 64 | 65 | libdraw/libdraw.a: 66 | (cd libdraw; $(MAKE)) 67 | 68 | libc/libc.a: 69 | (cd libc; $(MAKE)) 70 | 71 | libip/libip.a: 72 | (cd libip; $(MAKE)) 73 | 74 | gui-$(GUI)/libgui.a: 75 | (cd gui-$(GUI); $(MAKE)) 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://github.com/9fans/drawterm/workflows/C/badge.svg)](https://github.com/9fans/drawterm/actions/workflows/c.yml) 2 | [![Coverity Scan Build Status](https://scan.coverity.com/projects/9fans-drawterm/badge.svg)](https://scan.coverity.com/projects/9fans-drawterm) 3 | 4 | INSTALLATION 5 | -------------- 6 | To build on Unix, run CONF=unix make. 7 | 8 | To build on Solaris using Sun cc, run CONF=sun make. 9 | 10 | To build on Windows, you need Mingw. See http://www.mingw.org. 11 | Edit Make.config to uncomment the Windows section 12 | and comment out the rest. Then run CONF=win32 make. 13 | 14 | (You can download nmake from 15 | http://support.microsoft.com/default.aspx?scid=kb;en-us;Q132084 16 | Rename it to make.exe and put it in your path somewhere. 17 | ) 18 | 19 | I haven't tested the Windows build on Windows itself. 20 | I cross-compile using mingw32 on Linux. 21 | 22 | 23 | SOURCE 24 | ------ 25 | Use Git: git clone https://github.com/9fans/drawterm 26 | In the Plan 9 distribution: /sys/src/cmd/unix/drawterm/ (sometimes out of date) 27 | 28 | 29 | HELP 30 | ---- 31 | Issue tracker: https://github.com/9fans/drawterm/issues 32 | 33 | 34 | TO DO: 35 | ------ 36 | 37 | - Should import latest /dev/draw to allow resize of window 38 | 39 | - Should copy 9term code and make console window a real 40 | 9term window instead. 41 | 42 | - Should implement /dev/label. 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /args.h: -------------------------------------------------------------------------------- 1 | extern char *argv0; 2 | #define ARGBEGIN for((argv0? 0: (argv0=*argv)),argv++,argc--;\ 3 | argv[0] && argv[0][0]=='-' && argv[0][1];\ 4 | argc--, argv++) {\ 5 | char *_args, *_argt;\ 6 | Rune _argc;\ 7 | _args = &argv[0][1];\ 8 | if(_args[0]=='-' && _args[1]==0){\ 9 | argc--; argv++; break;\ 10 | }\ 11 | _argc = 0;\ 12 | while(*_args && (_args += chartorune(&_argc, _args)))\ 13 | switch(_argc) 14 | #define ARGEND SET(_argt);USED(_argt); USED(_argc); USED(_args);}USED(argv); USED(argc); 15 | #define ARGF() (_argt=_args, _args="",\ 16 | (*_argt? _argt: argv[1]? (argc--, *++argv): 0)) 17 | #define ARGC() _argc 18 | 19 | #define EARGF(x) (_argt=_args, _args="",\ 20 | (*_argt? _argt: argv[1]? (argc--, *++argv): (x, (char*)0))) 21 | -------------------------------------------------------------------------------- /drawterm.h: -------------------------------------------------------------------------------- 1 | extern int havesecstore(char *addr, char *owner); 2 | extern char *secstore; 3 | extern char secstorebuf[65536]; 4 | extern char *secstorefetch(char *addr, char *owner, char *passwd); 5 | extern char *authserver; 6 | extern char *readcons(char *prompt, char *def, int secret); 7 | extern int exportfs(int, int); 8 | extern char *user; 9 | extern char *getkey(char*, char*); 10 | extern char *findkey(char**, char*); 11 | extern int dialfactotum(void); 12 | extern char *getuser(void); 13 | extern void cpumain(int, char**); 14 | -------------------------------------------------------------------------------- /drawterm.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9fans/drawterm/6f30fc8502ade6fd510d6ef8280686ada7b60964/drawterm.ico -------------------------------------------------------------------------------- /drawterm.res: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9fans/drawterm/6f30fc8502ade6fd510d6ef8280686ada7b60964/drawterm.res -------------------------------------------------------------------------------- /exportfs/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libexportfs.a 4 | 5 | OFILES=\ 6 | exportfs.$O\ 7 | exportsrv.$O 8 | 9 | default: $(LIB) 10 | $(LIB): $(OFILES) 11 | $(AR) r $(LIB) $(OFILES) 12 | $(RANLIB) $(LIB) 13 | 14 | %.$O: %.c 15 | $(CC) $(CFLAGS) $*.c 16 | 17 | -------------------------------------------------------------------------------- /gui-osx/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libgui.a 4 | 5 | OFILES=\ 6 | alloc.$O\ 7 | cload.$O\ 8 | draw.$O\ 9 | load.$O\ 10 | screen.$O 11 | 12 | default: $(LIB) 13 | $(LIB): $(OFILES) 14 | $(AR) r $(LIB) $(OFILES) 15 | $(RANLIB) $(LIB) 16 | 17 | %.$O: %.c 18 | $(CC) $(CFLAGS) $*.c 19 | 20 | -------------------------------------------------------------------------------- /gui-osx/alloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | Memimage* 7 | allocmemimage(Rectangle r, ulong chan) 8 | { 9 | return _allocmemimage(r, chan); 10 | } 11 | 12 | void 13 | freememimage(Memimage *i) 14 | { 15 | _freememimage(i); 16 | } 17 | 18 | void 19 | memfillcolor(Memimage *i, ulong val) 20 | { 21 | _memfillcolor(i, val); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /gui-osx/cload.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) 8 | { 9 | return _cloadmemimage(i, r, data, ndata); 10 | } 11 | -------------------------------------------------------------------------------- /gui-osx/draw.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void 7 | memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp, Memimage *mask, Point mp, int op) 8 | { 9 | _memimagedraw(_memimagedrawsetup(dst, r, src, sp, mask, mp, op)); 10 | } 11 | 12 | ulong 13 | pixelbits(Memimage *m, Point p) 14 | { 15 | return _pixelbits(m, p); 16 | } 17 | 18 | void 19 | memimageinit(void) 20 | { 21 | _memimageinit(); 22 | } 23 | -------------------------------------------------------------------------------- /gui-osx/load.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) 8 | { 9 | return _loadmemimage(i, r, data, ndata); 10 | } 11 | -------------------------------------------------------------------------------- /gui-osx/wstrtoutf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | wstrutflen(Rune *s) 6 | { 7 | int n; 8 | 9 | for(n=0; *s; n+=runelen(*s),s++) 10 | ; 11 | return n; 12 | } 13 | 14 | int 15 | wstrtoutf(char *s, Rune *t, int n) 16 | { 17 | int i; 18 | char *s0; 19 | 20 | s0 = s; 21 | if(n <= 0) 22 | return wstrutflen(t)+1; 23 | while(*t) { 24 | if(n < UTFmax+1 && n < runelen(*t)+1) { 25 | *s = 0; 26 | return i+wstrutflen(t)+1; 27 | } 28 | i = runetochar(s, t); 29 | s += i; 30 | n -= i; 31 | t++; 32 | } 33 | *s = 0; 34 | return s-s0; 35 | } 36 | -------------------------------------------------------------------------------- /gui-win32/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libgui.a 4 | 5 | OFILES=\ 6 | alloc.$O\ 7 | cload.$O\ 8 | draw.$O\ 9 | load.$O\ 10 | screen.$O\ 11 | r16.$O 12 | 13 | default: $(LIB) 14 | $(LIB): $(OFILES) 15 | $(AR) r $(LIB) $(OFILES) 16 | $(RANLIB) $(LIB) 17 | 18 | %.$O: %.c 19 | $(CC) $(CFLAGS) $*.c 20 | 21 | -------------------------------------------------------------------------------- /gui-win32/alloc.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | Memimage* 7 | allocmemimage(Rectangle r, ulong chan) 8 | { 9 | return _allocmemimage(r, chan); 10 | } 11 | 12 | void 13 | freememimage(Memimage *i) 14 | { 15 | _freememimage(i); 16 | } 17 | 18 | void 19 | memfillcolor(Memimage *i, ulong val) 20 | { 21 | _memfillcolor(i, val); 22 | } 23 | 24 | -------------------------------------------------------------------------------- /gui-win32/cload.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) 8 | { 9 | return _cloadmemimage(i, r, data, ndata); 10 | } 11 | -------------------------------------------------------------------------------- /gui-win32/draw.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | void 7 | memimagedraw(Memimage *dst, Rectangle r, Memimage *src, Point sp, Memimage *mask, Point mp, int op) 8 | { 9 | _memimagedraw(_memimagedrawsetup(dst, r, src, sp, mask, mp, op)); 10 | } 11 | 12 | ulong 13 | pixelbits(Memimage *m, Point p) 14 | { 15 | return _pixelbits(m, p); 16 | } 17 | 18 | void 19 | memimageinit(void) 20 | { 21 | _memimageinit(); 22 | } 23 | -------------------------------------------------------------------------------- /gui-win32/load.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | loadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) 8 | { 9 | return _loadmemimage(i, r, data, ndata); 10 | } 11 | -------------------------------------------------------------------------------- /gui-win32/r16.h: -------------------------------------------------------------------------------- 1 | typedef unsigned short Rune16; 2 | 3 | wchar_t *widen(char *s); 4 | char *narrowen(wchar_t *ws); 5 | int widebytes(wchar_t *ws); 6 | int runes16len(Rune16*); 7 | int rune16nlen(Rune16*, int); 8 | Rune16* runes16dup(Rune16*); 9 | Rune16* utftorunes16(Rune16*, char*, int); 10 | char* runes16toutf(char*, Rune16*, int); 11 | int runes16cmp(Rune16*, Rune16*); 12 | void* smalloc(ulong); 13 | -------------------------------------------------------------------------------- /gui-x11/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libgui.a 4 | 5 | OFILES=\ 6 | x11.$O\ 7 | keysym2ucs-x11.$O 8 | 9 | default: $(LIB) 10 | $(LIB): $(OFILES) 11 | $(AR) r $(LIB) $(OFILES) 12 | $(RANLIB) $(LIB) 13 | 14 | -------------------------------------------------------------------------------- /gui-x11/keysym2ucs.h: -------------------------------------------------------------------------------- 1 | /* $XFree86: xc/programs/xterm/keysym2ucs.h,v 1.1 1999/06/12 15:37:18 dawes Exp $ */ 2 | /* 3 | * This module converts keysym values into the corresponding ISO 10646-1 4 | * (UCS, Unicode) values. 5 | */ 6 | 7 | #include 8 | 9 | long keysym2ucs(KeySym keysym); 10 | -------------------------------------------------------------------------------- /include/9windows.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | /* disable various silly warnings */ 15 | #ifdef MSVC 16 | #pragma warning( disable : 4245 4305 4244 4102 4761 4090 4028 4024) 17 | #endif 18 | 19 | typedef __int64 p9_vlong; 20 | typedef unsigned __int64 p9_uvlong; 21 | typedef unsigned uintptr; 22 | -------------------------------------------------------------------------------- /include/cursor.h: -------------------------------------------------------------------------------- 1 | struct Cursor 2 | { 3 | Point offset; 4 | uchar clr[2*16]; 5 | uchar set[2*16]; 6 | }; 7 | -------------------------------------------------------------------------------- /include/dtos.h: -------------------------------------------------------------------------------- 1 | #if defined(linux) || defined(IRIX) || defined(SOLARIS) || defined(OSF1) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__) || defined(__sun) || defined(sun) || defined(__OpenBSD__) 2 | # include "unix.h" 3 | # ifdef __APPLE__ 4 | # define panic dt_panic 5 | # endif 6 | #elif defined(WINDOWS) 7 | # include "9windows.h" 8 | # define main mymain 9 | #else 10 | # error "Define an OS" 11 | #endif 12 | 13 | #ifdef IRIX 14 | typedef int socklen_t; 15 | #endif 16 | -------------------------------------------------------------------------------- /include/ip.h: -------------------------------------------------------------------------------- 1 | enum 2 | { 3 | IPaddrlen= 16, 4 | IPv4addrlen= 4, 5 | IPv4off= 12, 6 | }; 7 | 8 | uchar* defmask(uchar*); 9 | void maskip(uchar*, uchar*, uchar*); 10 | int eipfmt(Fmt*); 11 | int isv4(uchar*); 12 | vlong parseip(uchar*, char*); 13 | vlong parseipmask(uchar*, char*); 14 | char* v4parseip(uchar*, char*); 15 | char* v4parsecidr(uchar*, uchar*, char*); 16 | 17 | void hnputv(void*, uvlong); 18 | void hnputl(void*, uint); 19 | void hnputs(void*, ushort); 20 | uvlong nhgetv(void*); 21 | uint nhgetl(void*); 22 | ushort nhgets(void*); 23 | 24 | int v6tov4(uchar*, uchar*); 25 | void v4tov6(uchar*, uchar*); 26 | 27 | #define ipcmp(x, y) memcmp(x, y, IPaddrlen) 28 | #define ipmove(x, y) memmove(x, y, IPaddrlen) 29 | 30 | extern uchar IPv4bcast[IPaddrlen]; 31 | extern uchar IPv4bcastobs[IPaddrlen]; 32 | extern uchar IPv4allsys[IPaddrlen]; 33 | extern uchar IPv4allrouter[IPaddrlen]; 34 | extern uchar IPnoaddr[IPaddrlen]; 35 | extern uchar v4prefix[IPaddrlen]; 36 | extern uchar IPallbits[IPaddrlen]; 37 | 38 | #define CLASS(p) ((*(uchar*)(p))>>6) 39 | -------------------------------------------------------------------------------- /include/keyboard.h: -------------------------------------------------------------------------------- 1 | #ifdef PLAN9 2 | #pragma src "/sys/src/libdraw" 3 | #pragma lib "libdraw.a" 4 | #endif 5 | 6 | typedef struct Keyboardctl Keyboardctl; 7 | typedef struct Channel Channel; 8 | 9 | struct Keyboardctl 10 | { 11 | Channel *c; /* chan(Rune)[20] */ 12 | 13 | char *file; 14 | int consfd; /* to cons file */ 15 | int ctlfd; /* to ctl file */ 16 | int pid; /* of slave proc */ 17 | }; 18 | 19 | 20 | extern Keyboardctl* initkeyboard(char*); 21 | extern int ctlkeyboard(Keyboardctl*, char*); 22 | extern void closekeyboard(Keyboardctl*); 23 | 24 | enum { 25 | KF= 0xF000, /* Rune: beginning of private Unicode space */ 26 | Kdel= 0x7F, 27 | Spec= 0xF800, 28 | /* KF|1, KF|2, ..., KF|0xC is F1, F2, ..., F12 */ 29 | Khome= KF|0x0D, 30 | Kup= KF|0x0E, 31 | Kpgup= KF|0x0F, 32 | Kprint= KF|0x10, 33 | Kleft= KF|0x11, 34 | Kright= KF|0x12, 35 | Kdown= Spec|0x00, 36 | Kview= Spec|0x00, 37 | Kpgdown= KF|0x13, 38 | Kins= KF|0x14, 39 | Kend= KF|0x18, 40 | 41 | Kalt= KF|0x15, 42 | Kshift= KF|0x16, 43 | Kctl= KF|0x17, 44 | }; 45 | 46 | -------------------------------------------------------------------------------- /include/libc.h: -------------------------------------------------------------------------------- 1 | #include "lib.h" 2 | #include "user.h" 3 | 4 | -------------------------------------------------------------------------------- /include/u.h: -------------------------------------------------------------------------------- 1 | #include "dtos.h" 2 | 3 | /* avoid name conflicts */ 4 | #undef accept 5 | #undef listen 6 | 7 | /* sys calls */ 8 | #undef bind 9 | #undef chdir 10 | #undef close 11 | #undef create 12 | #undef dup 13 | #undef export 14 | #undef fstat 15 | #undef fwstat 16 | #undef mount 17 | #undef open 18 | #undef start 19 | #undef read 20 | #undef remove 21 | #undef seek 22 | #undef stat 23 | #undef write 24 | #undef wstat 25 | #undef unmount 26 | #undef pipe 27 | -------------------------------------------------------------------------------- /include/unix.h: -------------------------------------------------------------------------------- 1 | #undef _FORTIFY_SOURCE /* stupid ubuntu warnings */ 2 | #define __BSD_VISIBLE 1 /* FreeBSD 5.x */ 3 | #define _BSD_SOURCE 1 4 | #define _NETBSD_SOURCE 1 /* NetBSD */ 5 | #define _SVID_SOURCE 1 6 | #define _DEFAULT_SOURCE 1 7 | #if !defined(__APPLE__) && !defined(__OpenBSD__) 8 | # define _XOPEN_SOURCE 1000 9 | # define _XOPEN_SOURCE_EXTENDED 1 10 | #endif 11 | #define _LARGEFILE64_SOURCE 1 12 | #define _FILE_OFFSET_BITS 64 13 | 14 | 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #ifdef PTHREAD 30 | #include 31 | #endif 32 | 33 | typedef long long p9_vlong; 34 | typedef unsigned long long p9_uvlong; 35 | typedef uintptr_t uintptr; 36 | -------------------------------------------------------------------------------- /include/x: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/9fans/drawterm/6f30fc8502ade6fd510d6ef8280686ada7b60964/include/x -------------------------------------------------------------------------------- /include/x.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void 4 | main(void) 5 | { 6 | } 7 | -------------------------------------------------------------------------------- /kern/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libkern.a 4 | 5 | OFILES=\ 6 | allocb.$O\ 7 | cache.$O\ 8 | chan.$O\ 9 | data.$O\ 10 | dev.$O\ 11 | devaudio.$O\ 12 | devaudio-$(AUDIO).$O\ 13 | devcons.$O\ 14 | devdraw.$O\ 15 | devfs-$(OS).$O\ 16 | devip.$O\ 17 | devip-$(OS).$O\ 18 | devlfd.$O\ 19 | devmnt.$O\ 20 | devmouse.$O\ 21 | devpipe.$O\ 22 | devroot.$O\ 23 | devssl.$O\ 24 | devtls.$O\ 25 | devtab.$O\ 26 | error.$O\ 27 | parse.$O\ 28 | pgrp.$O\ 29 | procinit.$O\ 30 | rwlock.$O\ 31 | sleep.$O\ 32 | smalloc.$O\ 33 | stub.$O\ 34 | sysfile.$O\ 35 | sysproc.$O\ 36 | qio.$O\ 37 | qlock.$O\ 38 | term.$O\ 39 | uart.$O\ 40 | waserror.$O\ 41 | $(OS).$O 42 | 43 | default: $(LIB) 44 | $(LIB): $(OFILES) 45 | $(AR) r $(LIB) $(OFILES) 46 | $(RANLIB) $(LIB) 47 | 48 | %.$O: %.c 49 | $(CC) $(CFLAGS) $*.c 50 | 51 | -------------------------------------------------------------------------------- /kern/cache.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | 8 | void 9 | cinit(void) 10 | { 11 | } 12 | 13 | void 14 | copen(Chan *c) 15 | { 16 | USED(c); 17 | } 18 | 19 | int 20 | cread(Chan *c, uchar *buf, int len, vlong off) 21 | { 22 | USED(c); 23 | USED(buf); 24 | USED(len); 25 | USED(off); 26 | 27 | return 0; 28 | } 29 | 30 | void 31 | cupdate(Chan *c, uchar *buf, int len, vlong off) 32 | { 33 | USED(c); 34 | USED(buf); 35 | USED(len); 36 | USED(off); 37 | } 38 | 39 | void 40 | cwrite(Chan* c, uchar *buf, int len, vlong off) 41 | { 42 | USED(c); 43 | USED(buf); 44 | USED(len); 45 | USED(off); 46 | } 47 | -------------------------------------------------------------------------------- /kern/data.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | Proc *up; 8 | Conf conf = 9 | { 10 | 1, 11 | 100, 12 | 0, 13 | 1024*1024*1024, 14 | 1024*1024*1024, 15 | 1024*1024*1024, 16 | 1024*1024*1024, 17 | 1024*1024*1024, 18 | 1024*1024*1024, 19 | 1024*1024*1024, 20 | 1024*1024*1024, 21 | 1024*1024*1024, 22 | 1024*1024*1024, 23 | 1024*1024*1024, 24 | 1024*1024*1024, 25 | 0, 26 | }; 27 | 28 | char *eve = "eve"; 29 | ulong kerndate; 30 | int cpuserver; 31 | char hostdomain[] = "drawterm.net"; 32 | -------------------------------------------------------------------------------- /kern/devaudio-none.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Linux and BSD 3 | */ 4 | #include "u.h" 5 | #include "lib.h" 6 | #include "dat.h" 7 | #include "fns.h" 8 | #include "error.h" 9 | #include "devaudio.h" 10 | 11 | /* maybe this should return -1 instead of sysfatal */ 12 | void 13 | audiodevopen(void) 14 | { 15 | error("no audio support"); 16 | } 17 | 18 | void 19 | audiodevclose(void) 20 | { 21 | error("no audio support"); 22 | } 23 | 24 | int 25 | audiodevread(void *a, int n) 26 | { 27 | error("no audio support"); 28 | return -1; 29 | } 30 | 31 | int 32 | audiodevwrite(void *a, int n) 33 | { 34 | error("no audio support"); 35 | return -1; 36 | } 37 | 38 | void 39 | audiodevsetvol(int what, int left, int right) 40 | { 41 | error("no audio support"); 42 | } 43 | 44 | void 45 | audiodevgetvol(int what, int *left, int *right) 46 | { 47 | error("no audio support"); 48 | } 49 | 50 | -------------------------------------------------------------------------------- /kern/devaudio.h: -------------------------------------------------------------------------------- 1 | enum 2 | { 3 | Fmono = 1, 4 | Fin = 2, 5 | Fout = 4, 6 | 7 | Vaudio = 0, 8 | Vsynth, 9 | Vcd, 10 | Vline, 11 | Vmic, 12 | Vspeaker, 13 | Vtreb, 14 | Vbass, 15 | Vspeed, 16 | Vpcm, 17 | Nvol, 18 | }; 19 | 20 | void audiodevopen(void); 21 | void audiodevclose(void); 22 | int audiodevread(void*, int); 23 | int audiodevwrite(void*, int); 24 | void audiodevgetvol(int, int*, int*); 25 | void audiodevsetvol(int, int, int); 26 | -------------------------------------------------------------------------------- /kern/devip.h: -------------------------------------------------------------------------------- 1 | enum 2 | { 3 | S_TCP, 4 | S_UDP 5 | }; 6 | 7 | int so_socket(int, unsigned char*); 8 | void so_connect(int, unsigned char*, unsigned short); 9 | void so_getsockname(int, unsigned char*, unsigned short*); 10 | void so_bind(int, int, unsigned short, unsigned char*); 11 | void so_listen(int); 12 | int so_send(int, void*, int, int); 13 | int so_recv(int, void*, int, int); 14 | int so_accept(int, unsigned char*, unsigned short*); 15 | int so_getservbyname(char*, char*, char*); 16 | int so_gethostbyname(char*, char**, int); 17 | 18 | char* hostlookup(char*); 19 | 20 | -------------------------------------------------------------------------------- /kern/devtab.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | extern Dev consdevtab; 8 | extern Dev rootdevtab; 9 | extern Dev pipedevtab; 10 | extern Dev ssldevtab; 11 | extern Dev tlsdevtab; 12 | extern Dev mousedevtab; 13 | extern Dev drawdevtab; 14 | extern Dev ipdevtab; 15 | extern Dev fsdevtab; 16 | extern Dev mntdevtab; 17 | extern Dev lfddevtab; 18 | extern Dev audiodevtab; 19 | 20 | Dev *devtab[] = { 21 | &rootdevtab, 22 | &consdevtab, 23 | &pipedevtab, 24 | &ssldevtab, 25 | &tlsdevtab, 26 | &mousedevtab, 27 | &drawdevtab, 28 | &ipdevtab, 29 | &fsdevtab, 30 | &mntdevtab, 31 | &lfddevtab, 32 | &audiodevtab, 33 | 0 34 | }; 35 | 36 | -------------------------------------------------------------------------------- /kern/procinit.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | Rgrp *thergrp; 8 | 9 | void 10 | procinit0(void) 11 | { 12 | Proc *p; 13 | 14 | p = newproc(); 15 | p->fgrp = dupfgrp(nil); 16 | p->rgrp = newrgrp(); 17 | p->pgrp = newpgrp(); 18 | _setproc(p); 19 | 20 | up->slash = namec("#/", Atodir, 0, 0); 21 | cnameclose(up->slash->name); 22 | up->slash->name = newcname("/"); 23 | up->dot = cclone(up->slash); 24 | } 25 | 26 | Ref pidref; 27 | 28 | Proc* 29 | newproc(void) 30 | { 31 | Proc *p; 32 | 33 | p = mallocz(sizeof(Proc), 1); 34 | p->pid = incref(&pidref); 35 | strcpy(p->user, eve); 36 | p->syserrstr = p->errbuf0; 37 | p->errstr = p->errbuf1; 38 | strcpy(p->text, "drawterm"); 39 | osnewproc(p); 40 | return p; 41 | } 42 | 43 | int 44 | kproc(char *name, void (*fn)(void*), void *arg) 45 | { 46 | Proc *p; 47 | 48 | p = newproc(); 49 | p->fn = fn; 50 | p->arg = arg; 51 | p->slash = cclone(up->slash); 52 | p->dot = cclone(up->dot); 53 | p->rgrp = up->rgrp; 54 | if(p->rgrp) 55 | incref(&p->rgrp->ref); 56 | p->pgrp = up->pgrp; 57 | if(up->pgrp) 58 | incref(&up->pgrp->ref); 59 | p->fgrp = up->fgrp; 60 | if(p->fgrp) 61 | incref(&p->fgrp->ref); 62 | strecpy(p->text, p->text+sizeof p->text, name); 63 | 64 | osproc(p); 65 | return p->pid; 66 | } 67 | 68 | -------------------------------------------------------------------------------- /kern/qlock.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | 6 | static void 7 | queue(Proc **first, Proc **last) 8 | { 9 | Proc *t; 10 | 11 | t = *last; 12 | if(t == 0) 13 | *first = up; 14 | else 15 | t->qnext = up; 16 | *last = up; 17 | up->qnext = 0; 18 | } 19 | 20 | static Proc* 21 | dequeue(Proc **first, Proc **last) 22 | { 23 | Proc *t; 24 | 25 | t = *first; 26 | if(t == 0) 27 | return 0; 28 | *first = t->qnext; 29 | if(*first == 0) 30 | *last = 0; 31 | return t; 32 | } 33 | 34 | void 35 | qlock(QLock *q) 36 | { 37 | lock(&q->lk); 38 | 39 | if(q->hold == 0) { 40 | q->hold = up; 41 | unlock(&q->lk); 42 | return; 43 | } 44 | 45 | /* 46 | * Can't assert this because of RWLock 47 | assert(q->hold != up); 48 | */ 49 | 50 | queue((Proc**)&q->first, (Proc**)&q->last); 51 | unlock(&q->lk); 52 | procsleep(); 53 | } 54 | 55 | int 56 | canqlock(QLock *q) 57 | { 58 | lock(&q->lk); 59 | if(q->hold == 0) { 60 | q->hold = up; 61 | unlock(&q->lk); 62 | return 1; 63 | } 64 | unlock(&q->lk); 65 | return 0; 66 | } 67 | 68 | void 69 | qunlock(QLock *q) 70 | { 71 | Proc *p; 72 | 73 | lock(&q->lk); 74 | /* 75 | * Can't assert this because of RWlock 76 | assert(q->hold == CT); 77 | */ 78 | p = dequeue((Proc**)&q->first, (Proc**)&q->last); 79 | if(p) { 80 | q->hold = p; 81 | unlock(&q->lk); 82 | procwakeup(p); 83 | } else { 84 | q->hold = 0; 85 | unlock(&q->lk); 86 | } 87 | } 88 | 89 | int 90 | holdqlock(QLock *q) 91 | { 92 | return q->hold == up; 93 | } 94 | 95 | -------------------------------------------------------------------------------- /kern/rendez.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | void 8 | sleep(Rendez *r, int (*f)(void*), void *arg) 9 | { 10 | int s; 11 | 12 | s = splhi(); 13 | 14 | lock(&r->lk); 15 | lock(&up->rlock); 16 | if(r->p){ 17 | print("double sleep %lud %lud\n", r->p->pid, up->pid); 18 | dumpstack(); 19 | } 20 | 21 | /* 22 | * Wakeup only knows there may be something to do by testing 23 | * r->p in order to get something to lock on. 24 | * Flush that information out to memory in case the sleep is 25 | * committed. 26 | */ 27 | r->p = up; 28 | 29 | if((*f)(arg) || up->notepending){ 30 | /* 31 | * if condition happened or a note is pending 32 | * never mind 33 | */ 34 | r->p = nil; 35 | unlock(&up->rlock); 36 | unlock(&r->lk); 37 | } else { 38 | /* 39 | * now we are committed to 40 | * change state and call scheduler 41 | */ 42 | up->state = Wakeme; 43 | up->r = r; 44 | 45 | /* statistics */ 46 | /* m->cs++; */ 47 | 48 | unlock(&up->rlock); 49 | unlock(&r->lk); 50 | 51 | procsleep(); 52 | } 53 | 54 | if(up->notepending) { 55 | up->notepending = 0; 56 | splx(s); 57 | error(Eintr); 58 | } 59 | 60 | splx(s); 61 | } 62 | 63 | Proc* 64 | wakeup(Rendez *r) 65 | { 66 | Proc *p; 67 | int s; 68 | 69 | s = splhi(); 70 | 71 | lock(&r->lk); 72 | p = r->p; 73 | 74 | if(p != nil){ 75 | lock(&p->rlock); 76 | if(p->state != Wakeme || p->r != r) 77 | panic("wakeup: state"); 78 | r->p = nil; 79 | p->r = nil; 80 | p->state = Running; 81 | procwakeup(p); 82 | unlock(&p->rlock); 83 | } 84 | unlock(&r->lk); 85 | 86 | splx(s); 87 | 88 | return p; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /kern/rwlock.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | void 8 | rlock(RWlock *l) 9 | { 10 | qlock(&l->x); /* wait here for writers and exclusion */ 11 | lock(&l->lk); 12 | l->readers++; 13 | canqlock(&l->k); /* block writers if we are the first reader */ 14 | unlock(&l->lk); 15 | qunlock(&l->x); 16 | } 17 | 18 | void 19 | runlock(RWlock *l) 20 | { 21 | lock(&l->lk); 22 | if(--l->readers == 0) /* last reader out allows writers */ 23 | qunlock(&l->k); 24 | unlock(&l->lk); 25 | } 26 | 27 | void 28 | wlock(RWlock *l) 29 | { 30 | qlock(&l->x); /* wait here for writers and exclusion */ 31 | qlock(&l->k); /* wait here for last reader */ 32 | } 33 | 34 | void 35 | wunlock(RWlock *l) 36 | { 37 | qunlock(&l->k); 38 | qunlock(&l->x); 39 | } 40 | -------------------------------------------------------------------------------- /kern/screen.h: -------------------------------------------------------------------------------- 1 | typedef struct Mouseinfo Mouseinfo; 2 | typedef struct Mousestate Mousestate; 3 | typedef struct Cursorinfo Cursorinfo; 4 | typedef struct Screeninfo Screeninfo; 5 | 6 | #define Mousequeue 16 /* queue can only have Mousequeue-1 elements */ 7 | #define Mousewindow 500 /* mouse event window in millisec */ 8 | 9 | struct Mousestate { 10 | int buttons; 11 | Point xy; 12 | ulong msec; 13 | }; 14 | 15 | struct Mouseinfo { 16 | Lock lk; 17 | Mousestate queue[Mousequeue]; 18 | int ri, wi; 19 | int lastb; 20 | int trans; 21 | int open; 22 | Rendez r; 23 | }; 24 | 25 | struct Cursorinfo { 26 | Lock lk; 27 | Point offset; 28 | uchar clr[2*16]; 29 | uchar set[2*16]; 30 | }; 31 | 32 | struct Screeninfo { 33 | Lock lk; 34 | Memimage *newsoft; 35 | int reshaped; 36 | int depth; 37 | int dibtype; 38 | }; 39 | 40 | extern Memimage *gscreen; 41 | extern Mouseinfo mouse; 42 | extern Cursorinfo cursor; 43 | extern Screeninfo screen; 44 | 45 | void screeninit(void); 46 | void screenload(Rectangle, int, uchar *, Point, int); 47 | 48 | void getcolor(ulong, ulong*, ulong*, ulong*); 49 | void setcolor(ulong, ulong, ulong, ulong); 50 | 51 | void refreshrect(Rectangle); 52 | 53 | void cursorarrow(void); 54 | void setcursor(void); 55 | void mouseset(Point); 56 | void drawflushr(Rectangle); 57 | void flushmemscreen(Rectangle); 58 | uchar *attachscreen(Rectangle*, ulong*, int*, int*, int*, void**); 59 | 60 | void drawqlock(void); 61 | void drawqunlock(void); 62 | int drawcanqlock(void); 63 | void terminit(void); 64 | -------------------------------------------------------------------------------- /kern/sleep.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | void 8 | sleep(Rendez *r, int (*f)(void*), void *arg) 9 | { 10 | int s; 11 | 12 | s = splhi(); 13 | 14 | lock(&r->lk); 15 | lock(&up->rlock); 16 | if(r->p){ 17 | print("double sleep %lud %lud\n", r->p->pid, up->pid); 18 | dumpstack(); 19 | } 20 | 21 | /* 22 | * Wakeup only knows there may be something to do by testing 23 | * r->p in order to get something to lock on. 24 | * Flush that information out to memory in case the sleep is 25 | * committed. 26 | */ 27 | r->p = up; 28 | 29 | if((*f)(arg) || up->notepending){ 30 | /* 31 | * if condition happened or a note is pending 32 | * never mind 33 | */ 34 | r->p = nil; 35 | unlock(&up->rlock); 36 | unlock(&r->lk); 37 | } else { 38 | /* 39 | * now we are committed to 40 | * change state and call scheduler 41 | */ 42 | up->state = Wakeme; 43 | up->r = r; 44 | 45 | /* statistics */ 46 | /* m->cs++; */ 47 | 48 | unlock(&up->rlock); 49 | unlock(&r->lk); 50 | 51 | procsleep(); 52 | } 53 | 54 | if(up->notepending) { 55 | up->notepending = 0; 56 | splx(s); 57 | error(Eintr); 58 | } 59 | 60 | splx(s); 61 | } 62 | 63 | Proc* 64 | wakeup(Rendez *r) 65 | { 66 | Proc *p; 67 | int s; 68 | 69 | s = splhi(); 70 | 71 | lock(&r->lk); 72 | p = r->p; 73 | 74 | if(p != nil){ 75 | lock(&p->rlock); 76 | if(p->state != Wakeme || p->r != r) 77 | panic("wakeup: state"); 78 | r->p = nil; 79 | p->r = nil; 80 | p->state = Running; 81 | procwakeup(p); 82 | unlock(&p->rlock); 83 | } 84 | unlock(&r->lk); 85 | 86 | splx(s); 87 | 88 | return p; 89 | } 90 | 91 | -------------------------------------------------------------------------------- /kern/smalloc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | void* 8 | smalloc(ulong n) 9 | { 10 | return mallocz(n, 1); 11 | } 12 | 13 | void* 14 | malloc(ulong n) 15 | { 16 | return mallocz(n, 1); 17 | } 18 | 19 | -------------------------------------------------------------------------------- /kern/sysproc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | long 8 | sysexits(uintptr_t *arg) 9 | { 10 | char *status; 11 | char *inval = "invalid exit string"; 12 | char buf[ERRMAX]; 13 | 14 | status = (char*)arg[0]; 15 | if(status){ 16 | if(waserror()) 17 | status = inval; 18 | else{ 19 | validaddr((ulong)status, 1, 0); 20 | if(vmemchr(status, 0, ERRMAX) == 0){ 21 | memmove(buf, status, ERRMAX); 22 | buf[ERRMAX-1] = 0; 23 | status = buf; 24 | } 25 | } 26 | poperror(); 27 | 28 | } 29 | pexit(status, 1); 30 | return 0; /* not reached */ 31 | } 32 | 33 | -------------------------------------------------------------------------------- /kern/uart.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | extern int panicking; 8 | void 9 | uartputs(char *s, int n) 10 | { 11 | if(panicking) 12 | write(1, s, n); 13 | } 14 | 15 | 16 | -------------------------------------------------------------------------------- /kern/waserror.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "lib.h" 3 | #include "dat.h" 4 | #include "fns.h" 5 | #include "error.h" 6 | 7 | Label* 8 | pwaserror(void) 9 | { 10 | if(up->nerrlab == NERR) 11 | panic("error stack overflow"); 12 | return &up->errlab[up->nerrlab++]; 13 | } 14 | 15 | void 16 | nexterror(void) 17 | { 18 | longjmp(up->errlab[--up->nerrlab].buf, 1); 19 | } 20 | 21 | void 22 | error(char *e) 23 | { 24 | kstrcpy(up->errstr, e, ERRMAX); 25 | setjmp(up->errlab[NERR-1].buf); 26 | nexterror(); 27 | } 28 | -------------------------------------------------------------------------------- /lib/codereview/codereview.cfg: -------------------------------------------------------------------------------- 1 | # defaultcc: plan9port-dev@googlegroups.com 2 | -------------------------------------------------------------------------------- /libauth/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | 4 | LIB=libauth.a 5 | OFILES=\ 6 | attr.$O\ 7 | auth_attr.$O\ 8 | auth_challenge.$O\ 9 | auth_getuserpasswd.$O\ 10 | auth_proxy.$O\ 11 | auth_respond.$O\ 12 | auth_rpc.$O\ 13 | auth_userpasswd.$O\ 14 | 15 | default: $(LIB) 16 | $(LIB): $(OFILES) 17 | $(AR) r $(LIB) $(OFILES) 18 | $(RANLIB) $(LIB) 19 | 20 | %.$O: %.c 21 | $(CC) $(CFLAGS) $*.c 22 | 23 | -------------------------------------------------------------------------------- /libauth/auth_attr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "authlocal.h" 6 | 7 | Attr* 8 | auth_attr(AuthRpc *rpc) 9 | { 10 | if(auth_rpc(rpc, "attr", nil, 0) != ARok) 11 | return nil; 12 | return _parseattr(rpc->arg); 13 | } 14 | -------------------------------------------------------------------------------- /libauth/auth_getuserpasswd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "authlocal.h" 5 | 6 | enum { 7 | ARgiveup = 100, 8 | }; 9 | 10 | static int 11 | dorpc(AuthRpc *rpc, char *verb, char *val, int len, AuthGetkey *getkey) 12 | { 13 | int ret; 14 | 15 | for(;;){ 16 | if((ret = auth_rpc(rpc, verb, val, len)) != ARneedkey && ret != ARbadkey) 17 | return ret; 18 | if(getkey == 0) 19 | return ARgiveup; /* don't know how */ 20 | if((*getkey)(rpc->arg) < 0) 21 | return ARgiveup; /* user punted */ 22 | } 23 | } 24 | 25 | UserPasswd* 26 | auth_getuserpasswd(AuthGetkey *getkey, char *fmt, ...) 27 | { 28 | AuthRpc *rpc; 29 | char *f[3], *p, *params; 30 | int fd; 31 | va_list arg; 32 | UserPasswd *up; 33 | 34 | up = nil; 35 | rpc = nil; 36 | params = nil; 37 | 38 | fd = open("/mnt/factotum/rpc", ORDWR); 39 | if(fd < 0) 40 | goto out; 41 | rpc = auth_allocrpc(fd); 42 | if(rpc == nil) 43 | goto out; 44 | quotefmtinstall(); /* just in case */ 45 | va_start(arg, fmt); 46 | params = vsmprint(fmt, arg); 47 | va_end(arg); 48 | if(params == nil) 49 | goto out; 50 | 51 | if(dorpc(rpc, "start", params, strlen(params), getkey) != ARok 52 | || dorpc(rpc, "read", nil, 0, getkey) != ARok) 53 | goto out; 54 | 55 | rpc->arg[rpc->narg] = '\0'; 56 | if(tokenize(rpc->arg, f, 2) != 2){ 57 | werrstr("bad answer from factotum"); 58 | goto out; 59 | } 60 | up = malloc(sizeof(*up)+rpc->narg+1); 61 | if(up == nil) 62 | goto out; 63 | p = (char*)&up[1]; 64 | strcpy(p, f[0]); 65 | up->user = p; 66 | p += strlen(p)+1; 67 | strcpy(p, f[1]); 68 | up->passwd = p; 69 | 70 | out: 71 | free(params); 72 | auth_freerpc(rpc); 73 | close(fd); 74 | return up; 75 | } 76 | -------------------------------------------------------------------------------- /libauth/auth_userpasswd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include "authlocal.h" 6 | 7 | /* 8 | * compute the proper response. We encrypt the ascii of 9 | * challenge number, with trailing binary zero fill. 10 | * This process was derived empirically. 11 | * this was copied from inet's guard. 12 | */ 13 | static void 14 | netresp(char *key, long chal, char *answer) 15 | { 16 | uchar buf[8]; 17 | 18 | memset(buf, 0, 8); 19 | sprint((char *)buf, "%lud", chal); 20 | if(encrypt(key, buf, 8) < 0) 21 | abort(); 22 | chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]; 23 | sprint(answer, "%.8lux", chal); 24 | } 25 | 26 | AuthInfo* 27 | auth_userpasswd(char *user, char *passwd) 28 | { 29 | char key[DESKEYLEN], resp[16]; 30 | AuthInfo *ai; 31 | Chalstate *ch; 32 | 33 | /* 34 | * Probably we should have a factotum protocol 35 | * to check a raw password. For now, we use 36 | * p9cr, which is simplest to speak. 37 | */ 38 | if((ch = auth_challenge("user=%q proto=p9cr role=server", user)) == nil) 39 | return nil; 40 | 41 | passtokey(key, passwd); 42 | netresp(key, atol(ch->chal), resp); 43 | memset(key, 0, sizeof key); 44 | 45 | ch->resp = resp; 46 | ch->nresp = strlen(resp); 47 | ai = auth_response(ch); 48 | auth_freechal(ch); 49 | return ai; 50 | } 51 | -------------------------------------------------------------------------------- /libauth/authlocal.h: -------------------------------------------------------------------------------- 1 | extern AuthInfo* _fauth_proxy(int fd, AuthRpc *rpc, AuthGetkey *getkey, char *params); 2 | -------------------------------------------------------------------------------- /libauth/httpauth.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | /* deprecated. 7 | This is the mechanism that put entries in /sys/lib/httpd.rewrite 8 | and passwords on the authserver in /sys/lib/httppasswords, which 9 | was awkward to administer. Instead, use local .httplogin files, 10 | which are implemented in sys/src/cmd/ip/httpd/authorize.c */ 11 | 12 | int 13 | httpauth(char *name, char *password) 14 | { 15 | int afd; 16 | Ticketreq tr; 17 | Ticket t; 18 | char key[DESKEYLEN]; 19 | char buf[512]; 20 | 21 | afd = authdial(nil, nil); 22 | if(afd < 0) 23 | return -1; 24 | 25 | /* send ticket request to AS */ 26 | memset(&tr, 0, sizeof(tr)); 27 | strcpy(tr.uid, name); 28 | tr.type = AuthHttp; 29 | convTR2M(&tr, buf); 30 | if(write(afd, buf, TICKREQLEN) != TICKREQLEN){ 31 | close(afd); 32 | return -1; 33 | } 34 | if(_asrdresp(afd, buf, TICKETLEN) < 0){ 35 | close(afd); 36 | return -1; 37 | } 38 | close(afd); 39 | 40 | /* 41 | * use password and try to decrypt the 42 | * ticket. If it doesn't work we've got a bad password, 43 | * give up. 44 | */ 45 | passtokey(key, password); 46 | convM2T(buf, &t, key); 47 | if(t.num != AuthHr || strcmp(t.cuid, tr.uid)) 48 | return -1; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /libauthsrv/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libauthsrv.a 4 | 5 | OFILES=\ 6 | _asgetticket.$O\ 7 | _asrdresp.$O\ 8 | convA2M.$O\ 9 | convM2A.$O\ 10 | convM2PR.$O\ 11 | convM2T.$O\ 12 | convM2TR.$O\ 13 | convPR2M.$O\ 14 | convT2M.$O\ 15 | convTR2M.$O\ 16 | nvcsum.$O\ 17 | opasstokey.$O\ 18 | passtokey.$O\ 19 | 20 | default: $(LIB) 21 | $(LIB): $(OFILES) 22 | $(AR) r $(LIB) $(OFILES) 23 | $(RANLIB) $(LIB) 24 | 25 | %.$O: %.c 26 | $(CC) $(CFLAGS) $*.c 27 | 28 | -------------------------------------------------------------------------------- /libauthsrv/_asgetticket.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static char *pbmsg = "AS protocol botch"; 6 | 7 | int 8 | _asgetticket(int fd, char *trbuf, char *tbuf) 9 | { 10 | if(write(fd, trbuf, TICKREQLEN) < 0){ 11 | close(fd); 12 | werrstr(pbmsg); 13 | return -1; 14 | } 15 | return _asrdresp(fd, tbuf, 2*TICKETLEN); 16 | } 17 | -------------------------------------------------------------------------------- /libauthsrv/_asrdresp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static char *pbmsg = "AS protocol botch"; 6 | 7 | int 8 | _asrdresp(int fd, char *buf, int len) 9 | { 10 | int n; 11 | char error[64]; 12 | 13 | if(read(fd, buf, 1) != 1){ 14 | werrstr(pbmsg); 15 | return -1; 16 | } 17 | 18 | n = len; 19 | switch(buf[0]){ 20 | case AuthOK: 21 | if(readn(fd, buf, len) != len){ 22 | werrstr(pbmsg); 23 | return -1; 24 | } 25 | break; 26 | case AuthErr: 27 | if(readn(fd, error, sizeof error) != sizeof error){ 28 | werrstr(pbmsg); 29 | return -1; 30 | } 31 | error[sizeof error-1] = '\0'; 32 | werrstr("remote: %s", error); 33 | return -1; 34 | case AuthOKvar: 35 | if(readn(fd, error, 5) != 5){ 36 | werrstr(pbmsg); 37 | return -1; 38 | } 39 | error[5] = 0; 40 | n = atoi(error); 41 | if(n <= 0 || n > len){ 42 | werrstr(pbmsg); 43 | return -1; 44 | } 45 | memset(buf, 0, len); 46 | if(readn(fd, buf, n) != n){ 47 | werrstr(pbmsg); 48 | return -1; 49 | } 50 | break; 51 | default: 52 | werrstr(pbmsg); 53 | return -1; 54 | } 55 | return n; 56 | } 57 | -------------------------------------------------------------------------------- /libauthsrv/authdial.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int 8 | authdial(char *netroot, char *dom) 9 | { 10 | char *p; 11 | int rv; 12 | 13 | if(dom == nil) 14 | /* look for one relative to my machine */ 15 | return dial(netmkaddr("$auth", netroot, "ticket"), 0, 0, 0); 16 | 17 | /* look up an auth server in an authentication domain */ 18 | p = csgetvalue(netroot, "authdom", dom, "auth", nil); 19 | 20 | /* if that didn't work, just try the IP domain */ 21 | if(p == nil) 22 | p = csgetvalue(netroot, "dom", dom, "auth", nil); 23 | /* 24 | * if that didn't work, try p9auth.$dom. this is very helpful if 25 | * you can't edit /lib/ndb. 26 | */ 27 | if(p == nil) 28 | p = smprint("p9auth.%s", dom); 29 | if(p == nil){ /* should no longer ever happen */ 30 | werrstr("no auth server found for %s", dom); 31 | return -1; 32 | } 33 | rv = dial(netmkaddr(p, netroot, "ticket"), 0, 0, 0); 34 | free(p); 35 | return rv; 36 | } 37 | -------------------------------------------------------------------------------- /libauthsrv/convA2M.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) *p++ = f->x 6 | #define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 7 | #define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(p, f->x, n); p += n 10 | 11 | int 12 | convA2M(Authenticator *f, char *ap, char *key) 13 | { 14 | int n; 15 | uchar *p; 16 | 17 | p = (uchar*)ap; 18 | CHAR(num); 19 | STRING(chal, CHALLEN); 20 | LONG(id); 21 | n = p - (uchar*)ap; 22 | if(key) 23 | encrypt(key, ap, n); 24 | return n; 25 | } 26 | -------------------------------------------------------------------------------- /libauthsrv/convM2A.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) f->x = *p++ 6 | #define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 7 | #define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(f->x, p, n); p += n 10 | 11 | void 12 | convM2A(char *ap, Authenticator *f, char *key) 13 | { 14 | uchar *p; 15 | 16 | if(key) 17 | decrypt(key, ap, AUTHENTLEN); 18 | p = (uchar*)ap; 19 | CHAR(num); 20 | STRING(chal, CHALLEN); 21 | LONG(id); 22 | USED(p); 23 | } 24 | -------------------------------------------------------------------------------- /libauthsrv/convM2PR.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) f->x = *p++ 6 | #define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 7 | #define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(f->x, p, n); p += n 10 | 11 | void 12 | convM2PR(char *ap, Passwordreq *f, char *key) 13 | { 14 | uchar *p; 15 | 16 | p = (uchar*)ap; 17 | if(key) 18 | decrypt(key, ap, PASSREQLEN); 19 | CHAR(num); 20 | STRING(old, ANAMELEN); 21 | f->old[ANAMELEN-1] = 0; 22 | STRING(new, ANAMELEN); 23 | f->new[ANAMELEN-1] = 0; 24 | CHAR(changesecret); 25 | STRING(secret, SECRETLEN); 26 | f->secret[SECRETLEN-1] = 0; 27 | USED(p); 28 | } 29 | -------------------------------------------------------------------------------- /libauthsrv/convM2T.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) f->x = *p++ 6 | #define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 7 | #define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(f->x, p, n); p += n 10 | 11 | void 12 | convM2T(char *ap, Ticket *f, char *key) 13 | { 14 | uchar *p; 15 | 16 | if(key) 17 | decrypt(key, ap, TICKETLEN); 18 | p = (uchar*)ap; 19 | CHAR(num); 20 | STRING(chal, CHALLEN); 21 | STRING(cuid, ANAMELEN); 22 | f->cuid[ANAMELEN-1] = 0; 23 | STRING(suid, ANAMELEN); 24 | f->suid[ANAMELEN-1] = 0; 25 | STRING(key, DESKEYLEN); 26 | USED(p); 27 | } 28 | 29 | -------------------------------------------------------------------------------- /libauthsrv/convM2TR.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) f->x = *p++ 6 | #define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 7 | #define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(f->x, p, n); p += n 10 | 11 | void 12 | convM2TR(char *ap, Ticketreq *f) 13 | { 14 | uchar *p; 15 | 16 | p = (uchar*)ap; 17 | CHAR(type); 18 | STRING(authid, ANAMELEN); 19 | f->authid[ANAMELEN-1] = 0; 20 | STRING(authdom, DOMLEN); 21 | f->authdom[DOMLEN-1] = 0; 22 | STRING(chal, CHALLEN); 23 | STRING(hostid, ANAMELEN); 24 | f->hostid[ANAMELEN-1] = 0; 25 | STRING(uid, ANAMELEN); 26 | f->uid[ANAMELEN-1] = 0; 27 | USED(p); 28 | } 29 | -------------------------------------------------------------------------------- /libauthsrv/convPR2M.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) *p++ = f->x 6 | #define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 7 | #define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(p, f->x, n); p += n 10 | 11 | int 12 | convPR2M(Passwordreq *f, char *ap, char *key) 13 | { 14 | int n; 15 | uchar *p; 16 | 17 | p = (uchar*)ap; 18 | CHAR(num); 19 | STRING(old, ANAMELEN); 20 | STRING(new, ANAMELEN); 21 | CHAR(changesecret); 22 | STRING(secret, SECRETLEN); 23 | n = p - (uchar*)ap; 24 | if(key) 25 | encrypt(key, ap, n); 26 | return n; 27 | } 28 | 29 | -------------------------------------------------------------------------------- /libauthsrv/convT2M.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) *p++ = f->x 6 | #define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 7 | #define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(p, f->x, n); p += n 10 | 11 | int 12 | convT2M(Ticket *f, char *ap, char *key) 13 | { 14 | int n; 15 | uchar *p; 16 | 17 | p = (uchar*)ap; 18 | CHAR(num); 19 | STRING(chal, CHALLEN); 20 | STRING(cuid, ANAMELEN); 21 | STRING(suid, ANAMELEN); 22 | STRING(key, DESKEYLEN); 23 | n = p - (uchar*)ap; 24 | if(key) 25 | encrypt(key, ap, n); 26 | return n; 27 | } 28 | -------------------------------------------------------------------------------- /libauthsrv/convTR2M.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define CHAR(x) *p++ = f->x 6 | #define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 7 | #define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 8 | #define LONG(x) VLONG(f->x) 9 | #define STRING(x,n) memmove(p, f->x, n); p += n 10 | 11 | int 12 | convTR2M(Ticketreq *f, char *ap) 13 | { 14 | int n; 15 | uchar *p; 16 | 17 | p = (uchar*)ap; 18 | CHAR(type); 19 | STRING(authid, 28); /* BUG */ 20 | STRING(authdom, DOMLEN); 21 | STRING(chal, CHALLEN); 22 | STRING(hostid, 28); /* BUG */ 23 | STRING(uid, 28); /* BUG */ 24 | n = p - (uchar*)ap; 25 | return n; 26 | } 27 | 28 | -------------------------------------------------------------------------------- /libauthsrv/nvcsum.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | uchar 6 | nvcsum(void *vmem, int n) 7 | { 8 | uchar *mem, sum; 9 | int i; 10 | 11 | sum = 9; 12 | mem = vmem; 13 | for(i = 0; i < n; i++) 14 | sum += mem[i]; 15 | return sum; 16 | } 17 | -------------------------------------------------------------------------------- /libauthsrv/opasstokey.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | opasstokey(char *key, char *p) 7 | { 8 | uchar t[10]; 9 | int c, n; 10 | 11 | n = strlen(p); 12 | memset(t, ' ', sizeof t); 13 | if(n < 5) 14 | return 0; 15 | if(n > 10) 16 | n = 10; 17 | memcpy((char*)t, p, n); 18 | if(n >= 9){ 19 | c = p[8] & 0xf; 20 | if(n == 10) 21 | c += p[9] << 4; 22 | for(n = 0; n < 8; n++) 23 | if(c & (1 << n)) 24 | t[n] -= ' '; 25 | } 26 | for(n = 0; n < 7; n++) 27 | key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1))); 28 | return 1; 29 | } 30 | -------------------------------------------------------------------------------- /libauthsrv/passtokey.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | passtokey(char *key, char *p) 7 | { 8 | uchar buf[ANAMELEN], *t; 9 | int i, n; 10 | 11 | n = strlen(p); 12 | if(n >= ANAMELEN) 13 | n = ANAMELEN-1; 14 | memset(buf, ' ', 8); 15 | t = buf; 16 | strncpy((char*)t, p, n); 17 | t[n] = 0; 18 | memset(key, 0, DESKEYLEN); 19 | for(;;){ 20 | for(i = 0; i < DESKEYLEN; i++) 21 | key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1))); 22 | if(n <= 8) 23 | return 1; 24 | n -= 8; 25 | t += 8; 26 | if(n < 8){ 27 | t -= 8 - n; 28 | n = 8; 29 | } 30 | encrypt(key, t, 8); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /libc/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libc.a 4 | 5 | OFILES=\ 6 | charstod.$O\ 7 | cleanname.$O\ 8 | convD2M.$O\ 9 | convM2D.$O\ 10 | convM2S.$O\ 11 | convS2M.$O\ 12 | crypt.$O\ 13 | dial.$O\ 14 | dirfstat.$O\ 15 | dirfwstat.$O\ 16 | dirmodefmt.$O\ 17 | dirstat.$O\ 18 | dirwstat.$O\ 19 | dofmt.$O\ 20 | dorfmt.$O\ 21 | encodefmt.$O\ 22 | fcallfmt.$O\ 23 | fltfmt.$O\ 24 | fmt.$O\ 25 | fmtfd.$O\ 26 | fmtfdflush.$O\ 27 | fmtlock.$O\ 28 | fmtprint.$O\ 29 | fmtquote.$O\ 30 | fmtrune.$O\ 31 | fmtstr.$O\ 32 | fmtvprint.$O\ 33 | fprint.$O\ 34 | getfields.$O\ 35 | getpid.$O\ 36 | lock.$O\ 37 | mallocz.$O\ 38 | nan64.$O\ 39 | netmkaddr.$O\ 40 | nsec.$O\ 41 | pow10.$O\ 42 | pushssl.$O\ 43 | pushtls.$O\ 44 | read9pmsg.$O\ 45 | readn.$O\ 46 | rune.$O\ 47 | runefmtstr.$O\ 48 | runeseprint.$O\ 49 | runesmprint.$O\ 50 | runesnprint.$O\ 51 | runesprint.$O\ 52 | runestrchr.$O\ 53 | runestrlen.$O\ 54 | runestrstr.$O\ 55 | runetype.$O\ 56 | runevseprint.$O\ 57 | runevsmprint.$O\ 58 | runevsnprint.$O\ 59 | seprint.$O\ 60 | smprint.$O\ 61 | snprint.$O\ 62 | sprint.$O\ 63 | strecpy.$O\ 64 | strtod.$O\ 65 | strtoll.$O\ 66 | sysfatal.$O\ 67 | time.$O\ 68 | tokenize.$O\ 69 | truerand.$O\ 70 | u16.$O\ 71 | u32.$O\ 72 | u64.$O\ 73 | utfecpy.$O\ 74 | utflen.$O\ 75 | utfnlen.$O\ 76 | utfrrune.$O\ 77 | utfrune.$O\ 78 | utfutf.$O\ 79 | vfprint.$O\ 80 | vseprint.$O\ 81 | vsmprint.$O\ 82 | vsnprint.$O 83 | 84 | default: $(LIB) 85 | $(LIB): $(OFILES) 86 | $(AR) r $(LIB) $(OFILES) 87 | $(RANLIB) $(LIB) 88 | 89 | %.$O: %.c 90 | $(CC) $(CFLAGS) $*.c 91 | 92 | -------------------------------------------------------------------------------- /libc/charstod.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | /* 6 | * Reads a floating-point number by interpreting successive characters 7 | * returned by (*f)(vp). The last call it makes to f terminates the 8 | * scan, so is not a character in the number. It may therefore be 9 | * necessary to back up the input stream up one byte after calling charstod. 10 | */ 11 | 12 | double 13 | fmtcharstod(int(*f)(void*), void *vp) 14 | { 15 | double num, dem; 16 | int neg, eneg, dig, exp, c; 17 | 18 | num = 0; 19 | neg = 0; 20 | dig = 0; 21 | exp = 0; 22 | eneg = 0; 23 | 24 | c = (*f)(vp); 25 | while(c == ' ' || c == '\t') 26 | c = (*f)(vp); 27 | if(c == '-' || c == '+'){ 28 | if(c == '-') 29 | neg = 1; 30 | c = (*f)(vp); 31 | } 32 | while(c >= '0' && c <= '9'){ 33 | num = num*10 + c-'0'; 34 | c = (*f)(vp); 35 | } 36 | if(c == '.') 37 | c = (*f)(vp); 38 | while(c >= '0' && c <= '9'){ 39 | num = num*10 + c-'0'; 40 | dig++; 41 | c = (*f)(vp); 42 | } 43 | if(c == 'e' || c == 'E'){ 44 | c = (*f)(vp); 45 | if(c == '-' || c == '+'){ 46 | if(c == '-'){ 47 | dig = -dig; 48 | eneg = 1; 49 | } 50 | c = (*f)(vp); 51 | } 52 | while(c >= '0' && c <= '9'){ 53 | exp = exp*10 + c-'0'; 54 | c = (*f)(vp); 55 | } 56 | } 57 | exp -= dig; 58 | if(exp < 0){ 59 | exp = -exp; 60 | eneg = !eneg; 61 | } 62 | dem = __fmtpow10(exp); 63 | if(eneg) 64 | num /= dem; 65 | else 66 | num *= dem; 67 | if(neg) 68 | return -num; 69 | return num; 70 | } 71 | -------------------------------------------------------------------------------- /libc/cleanname.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * In place, rewrite name to compress multiple /, eliminate ., and process .. 6 | */ 7 | #define SEP(x) ((x)=='/' || (x) == 0) 8 | char* 9 | cleanname(char *name) 10 | { 11 | char *p, *q, *dotdot; 12 | int rooted; 13 | 14 | rooted = name[0] == '/'; 15 | 16 | /* 17 | * invariants: 18 | * p points at beginning of path element we're considering. 19 | * q points just past the last path element we wrote (no slash). 20 | * dotdot points just past the point where .. cannot backtrack 21 | * any further (no slash). 22 | */ 23 | p = q = dotdot = name+rooted; 24 | while(*p) { 25 | if(p[0] == '/') /* null element */ 26 | p++; 27 | else if(p[0] == '.' && SEP(p[1])) 28 | p += 1; /* don't count the separator in case it is nul */ 29 | else if(p[0] == '.' && p[1] == '.' && SEP(p[2])) { 30 | p += 2; 31 | if(q > dotdot) { /* can backtrack */ 32 | while(--q > dotdot && *q != '/') 33 | ; 34 | } else if(!rooted) { /* /.. is / but ./../ is .. */ 35 | if(q != name) 36 | *q++ = '/'; 37 | *q++ = '.'; 38 | *q++ = '.'; 39 | dotdot = q; 40 | } 41 | } else { /* real path element */ 42 | if(q != name+rooted) 43 | *q++ = '/'; 44 | while((*q = *p) != '/' && *q != 0) 45 | p++, q++; 46 | } 47 | } 48 | if(q == name) /* empty string is really ``.'' */ 49 | *q++ = '.'; 50 | *q = '\0'; 51 | return name; 52 | } 53 | -------------------------------------------------------------------------------- /libc/crypt.c: -------------------------------------------------------------------------------- 1 | /* 2 | * Data Encryption Standard 3 | * D.P.Mitchell 83/06/08. 4 | * 5 | * block_cipher(key, block, decrypting) 6 | * 7 | * these routines use the non-standard 7 byte format 8 | * for DES keys. 9 | */ 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | /* 16 | * destructively encrypt the buffer, which 17 | * must be at least 8 characters long. 18 | */ 19 | int 20 | encrypt(void *key, void *vbuf, int n) 21 | { 22 | ulong ekey[32]; 23 | uchar *buf; 24 | int i, r; 25 | 26 | if(n < 8) 27 | return 0; 28 | key_setup(key, ekey); 29 | buf = vbuf; 30 | n--; 31 | r = n % 7; 32 | n /= 7; 33 | for(i = 0; i < n; i++){ 34 | block_cipher(ekey, buf, 0); 35 | buf += 7; 36 | } 37 | if(r) 38 | block_cipher(ekey, buf - 7 + r, 0); 39 | return 1; 40 | } 41 | 42 | /* 43 | * destructively decrypt the buffer, which 44 | * must be at least 8 characters long. 45 | */ 46 | int 47 | decrypt(void *key, void *vbuf, int n) 48 | { 49 | ulong ekey[128]; 50 | uchar *buf; 51 | int i, r; 52 | 53 | if(n < 8) 54 | return 0; 55 | key_setup(key, ekey); 56 | buf = vbuf; 57 | n--; 58 | r = n % 7; 59 | n /= 7; 60 | buf += n * 7; 61 | if(r) 62 | block_cipher(ekey, buf - 7 + r, 1); 63 | for(i = 0; i < n; i++){ 64 | buf -= 7; 65 | block_cipher(ekey, buf, 1); 66 | } 67 | return 1; 68 | } 69 | -------------------------------------------------------------------------------- /libc/dirfstat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | enum 6 | { 7 | DIRSIZE = STATFIXLEN + 16 * 4 /* enough for encoded stat buf + some reasonable strings */ 8 | }; 9 | 10 | Dir* 11 | dirfstat(int fd) 12 | { 13 | Dir *d; 14 | uchar *buf; 15 | int n, nd, i; 16 | 17 | nd = DIRSIZE; 18 | for(i=0; i<2; i++){ /* should work by the second try */ 19 | d = malloc(sizeof(Dir) + BIT16SZ + nd); 20 | if(d == nil) 21 | return nil; 22 | buf = (uchar*)&d[1]; 23 | n = fstat(fd, buf, BIT16SZ+nd); 24 | if(n < BIT16SZ){ 25 | free(d); 26 | return nil; 27 | } 28 | nd = GBIT16(buf); /* upper bound on size of Dir + strings */ 29 | if(nd <= n){ 30 | convM2D(buf, n, d, (char*)&d[1]); 31 | return d; 32 | } 33 | /* else sizeof(Dir)+BIT16SZ+nd is plenty */ 34 | free(d); 35 | } 36 | return nil; 37 | } 38 | -------------------------------------------------------------------------------- /libc/dirfwstat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | dirfwstat(int fd, Dir *d) 7 | { 8 | uchar *buf; 9 | int r; 10 | 11 | r = sizeD2M(d); 12 | buf = malloc(r); 13 | if(buf == nil) 14 | return -1; 15 | convD2M(d, buf, r); 16 | r = fwstat(fd, buf, r); 17 | free(buf); 18 | return r; 19 | } 20 | -------------------------------------------------------------------------------- /libc/dirmodefmt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static char *modes[] = 6 | { 7 | "---", 8 | "--x", 9 | "-w-", 10 | "-wx", 11 | "r--", 12 | "r-x", 13 | "rw-", 14 | "rwx", 15 | }; 16 | 17 | static void 18 | rwx(long m, char *s) 19 | { 20 | strncpy(s, modes[m], 3); 21 | } 22 | 23 | int 24 | dirmodefmt(Fmt *f) 25 | { 26 | static char buf[16]; 27 | ulong m; 28 | 29 | m = va_arg(f->args, ulong); 30 | 31 | if(m & DMDIR) 32 | buf[0]='d'; 33 | else if(m & DMAPPEND) 34 | buf[0]='a'; 35 | else if(m & DMAUTH) 36 | buf[0]='A'; 37 | else 38 | buf[0]='-'; 39 | if(m & DMEXCL) 40 | buf[1]='l'; 41 | else 42 | buf[1]='-'; 43 | rwx((m>>6)&7, buf+2); 44 | rwx((m>>3)&7, buf+5); 45 | rwx((m>>0)&7, buf+8); 46 | buf[11] = 0; 47 | return fmtstrcpy(f, buf); 48 | } 49 | -------------------------------------------------------------------------------- /libc/dirstat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | enum 6 | { 7 | DIRSIZE = STATFIXLEN + 16 * 4 /* enough for encoded stat buf + some reasonable strings */ 8 | }; 9 | 10 | Dir* 11 | dirstat(char *name) 12 | { 13 | Dir *d; 14 | uchar *buf; 15 | int n, nd, i; 16 | 17 | nd = DIRSIZE; 18 | for(i=0; i<2; i++){ /* should work by the second try */ 19 | d = malloc(sizeof(Dir) + BIT16SZ + nd); 20 | if(d == nil) 21 | return nil; 22 | buf = (uchar*)&d[1]; 23 | n = stat(name, buf, BIT16SZ+nd); 24 | if(n < BIT16SZ){ 25 | free(d); 26 | return nil; 27 | } 28 | nd = GBIT16((uchar*)buf); /* upper bound on size of Dir + strings */ 29 | if(nd <= n){ 30 | convM2D(buf, n, d, (char*)&d[1]); 31 | return d; 32 | } 33 | /* else sizeof(Dir)+BIT16SZ+nd is plenty */ 34 | free(d); 35 | } 36 | return nil; 37 | } 38 | -------------------------------------------------------------------------------- /libc/dirwstat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | dirwstat(char *name, Dir *d) 7 | { 8 | uchar *buf; 9 | int r; 10 | 11 | r = sizeD2M(d); 12 | buf = malloc(r); 13 | if(buf == nil) 14 | return -1; 15 | convD2M(d, buf, r); 16 | r = wstat(name, buf, r); 17 | free(buf); 18 | return r; 19 | } 20 | -------------------------------------------------------------------------------- /libc/dorfmt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | /* format the output into f->to and return the number of characters fmted */ 6 | 7 | int 8 | dorfmt(Fmt *f, const Rune *fmt) 9 | { 10 | Rune *rt, *rs; 11 | int r; 12 | char *t, *s; 13 | int nfmt; 14 | 15 | nfmt = f->nfmt; 16 | for(;;){ 17 | if(f->runes){ 18 | rt = f->to; 19 | rs = f->stop; 20 | while((r = *fmt++) && r != '%'){ 21 | FMTRCHAR(f, rt, rs, r); 22 | } 23 | f->nfmt += rt - (Rune *)f->to; 24 | f->to = rt; 25 | if(!r) 26 | return f->nfmt - nfmt; 27 | f->stop = rs; 28 | }else{ 29 | t = f->to; 30 | s = f->stop; 31 | while((r = *fmt++) && r != '%'){ 32 | FMTRUNE(f, t, f->stop, r); 33 | } 34 | f->nfmt += t - (char *)f->to; 35 | f->to = t; 36 | if(!r) 37 | return f->nfmt - nfmt; 38 | f->stop = s; 39 | } 40 | 41 | fmt = __fmtdispatch(f, (Rune*)fmt, 1); 42 | if(fmt == nil) 43 | return -1; 44 | } 45 | return 0; /* not reached */ 46 | } 47 | -------------------------------------------------------------------------------- /libc/encodefmt.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | encodefmt(Fmt *f) 7 | { 8 | char *out; 9 | char *buf; 10 | int len; 11 | int ilen; 12 | int rv; 13 | uchar *b; 14 | char *p; 15 | char obuf[64]; // rsc optimization 16 | 17 | if(!(f->flags&FmtPrec) || f->prec < 1) 18 | goto error; 19 | 20 | b = va_arg(f->args, uchar*); 21 | if(b == 0) 22 | return fmtstrcpy(f, ""); 23 | 24 | ilen = f->prec; 25 | f->prec = 0; 26 | f->flags &= ~FmtPrec; 27 | switch(f->r){ 28 | case '<': 29 | len = (8*ilen+4)/5 + 3; 30 | break; 31 | case '[': 32 | len = (8*ilen+5)/6 + 4; 33 | break; 34 | case 'H': 35 | len = 2*ilen + 1; 36 | break; 37 | default: 38 | goto error; 39 | } 40 | 41 | if(len > sizeof(obuf)){ 42 | buf = malloc(len); 43 | if(buf == nil) 44 | goto error; 45 | } else 46 | buf = obuf; 47 | 48 | // convert 49 | out = buf; 50 | switch(f->r){ 51 | case '<': 52 | rv = enc32(out, len, b, ilen); 53 | break; 54 | case '[': 55 | rv = enc64(out, len, b, ilen); 56 | break; 57 | case 'H': 58 | rv = enc16(out, len, b, ilen); 59 | if(rv >= 0 && (f->flags & FmtLong)) 60 | for(p = buf; *p; p++) 61 | *p = tolower(*p); 62 | break; 63 | default: 64 | rv = -1; 65 | break; 66 | } 67 | if(rv < 0) 68 | goto error; 69 | 70 | fmtstrcpy(f, buf); 71 | if(buf != obuf) 72 | free(buf); 73 | return 0; 74 | 75 | error: 76 | return fmtstrcpy(f, ""); 77 | } 78 | -------------------------------------------------------------------------------- /libc/fmtfd.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "fmtdef.h" 5 | 6 | /* 7 | * public routine for final flush of a formatting buffer 8 | * to a file descriptor; returns total char count. 9 | */ 10 | int 11 | fmtfdflush(Fmt *f) 12 | { 13 | if(__fmtFdFlush(f) <= 0) 14 | return -1; 15 | return f->nfmt; 16 | } 17 | 18 | /* 19 | * initialize an output buffer for buffered printing 20 | */ 21 | int 22 | fmtfdinit(Fmt *f, int fd, char *buf, int size) 23 | { 24 | f->runes = 0; 25 | f->start = buf; 26 | f->to = buf; 27 | f->stop = buf + size; 28 | f->flush = __fmtFdFlush; 29 | f->farg = (void*)(uintptr_t)fd; 30 | f->nfmt = 0; 31 | return 0; 32 | } 33 | -------------------------------------------------------------------------------- /libc/fmtfdflush.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include "fmtdef.h" 5 | 6 | /* 7 | * generic routine for flushing a formatting buffer 8 | * to a file descriptor 9 | */ 10 | int 11 | __fmtFdFlush(Fmt *f) 12 | { 13 | int n; 14 | 15 | n = (char*)f->to - (char*)f->start; 16 | if(n && write((uintptr_t)f->farg, f->start, n) != n) 17 | return 0; 18 | f->to = f->start; 19 | return 1; 20 | } 21 | -------------------------------------------------------------------------------- /libc/fmtlock.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static Lock fmtl; 5 | 6 | void 7 | __fmtlock(void) 8 | { 9 | lock(&fmtl); 10 | } 11 | 12 | void 13 | __fmtunlock(void) 14 | { 15 | unlock(&fmtl); 16 | } 17 | -------------------------------------------------------------------------------- /libc/fmtprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | /* 6 | * format a string into the output buffer 7 | * designed for formats which themselves call fmt, 8 | * but ignore any width flags 9 | */ 10 | int 11 | fmtprint(Fmt *f, char *fmt, ...) 12 | { 13 | va_list va; 14 | int n; 15 | 16 | f->flags = 0; 17 | f->width = 0; 18 | f->prec = 0; 19 | VA_COPY(va, f->args); 20 | VA_END(f->args); 21 | va_start(f->args, fmt); 22 | n = dofmt(f, fmt); 23 | va_end(f->args); 24 | f->flags = 0; 25 | f->width = 0; 26 | f->prec = 0; 27 | VA_COPY(f->args,va); 28 | VA_END(va); 29 | if(n >= 0) 30 | return 0; 31 | return n; 32 | } 33 | 34 | -------------------------------------------------------------------------------- /libc/fmtrune.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | fmtrune(Fmt *f, int r) 7 | { 8 | Rune *rt; 9 | char *t; 10 | int n; 11 | 12 | if(f->runes){ 13 | rt = (Rune*)f->to; 14 | FMTRCHAR(f, rt, f->stop, r); 15 | f->to = rt; 16 | n = 1; 17 | }else{ 18 | t = (char*)f->to; 19 | FMTRUNE(f, t, f->stop, r); 20 | n = t - (char*)f->to; 21 | f->to = t; 22 | } 23 | f->nfmt += n; 24 | return 0; 25 | } 26 | -------------------------------------------------------------------------------- /libc/fmtstr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | char* 6 | fmtstrflush(Fmt *f) 7 | { 8 | if(f->start == nil) 9 | return nil; 10 | *(char*)f->to = '\0'; 11 | return (char*)f->start; 12 | } 13 | -------------------------------------------------------------------------------- /libc/fmtvprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | 6 | /* 7 | * format a string into the output buffer 8 | * designed for formats which themselves call fmt, 9 | * but ignore any width flags 10 | */ 11 | int 12 | fmtvprint(Fmt *f, char *fmt, va_list args) 13 | { 14 | va_list va; 15 | int n; 16 | 17 | f->flags = 0; 18 | f->width = 0; 19 | f->prec = 0; 20 | VA_COPY(va,f->args); 21 | VA_END(f->args); 22 | VA_COPY(f->args,args); 23 | n = dofmt(f, fmt); 24 | f->flags = 0; 25 | f->width = 0; 26 | f->prec = 0; 27 | VA_END(f->args); 28 | VA_COPY(f->args,va); 29 | VA_END(va); 30 | if(n >= 0) 31 | return 0; 32 | return n; 33 | } 34 | 35 | -------------------------------------------------------------------------------- /libc/fprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | fprint(int fd, char *fmt, ...) 7 | { 8 | int n; 9 | va_list args; 10 | 11 | va_start(args, fmt); 12 | n = vfprint(fd, fmt, args); 13 | va_end(args); 14 | return n; 15 | } 16 | -------------------------------------------------------------------------------- /libc/frand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MASK 0x7fffffffL 5 | #define NORM (1.0/(1.0+MASK)) 6 | 7 | double 8 | frand(void) 9 | { 10 | double x; 11 | 12 | do { 13 | x = lrand() * NORM; 14 | x = (x + lrand()) * NORM; 15 | } while(x >= 1); 16 | return x; 17 | } 18 | -------------------------------------------------------------------------------- /libc/getfields.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | getfields(char *str, char **args, int max, int mflag, char *set) 6 | { 7 | Rune r; 8 | int nr, intok, narg; 9 | 10 | if(max <= 0) 11 | return 0; 12 | 13 | narg = 0; 14 | args[narg] = str; 15 | if(!mflag) 16 | narg++; 17 | intok = 0; 18 | for(;; str += nr) { 19 | nr = chartorune(&r, str); 20 | if(r == 0) 21 | break; 22 | if(utfrune(set, r)) { 23 | if(narg >= max) 24 | break; 25 | *str = 0; 26 | intok = 0; 27 | args[narg] = str + nr; 28 | if(!mflag) 29 | narg++; 30 | } else { 31 | if(!intok && mflag) 32 | narg++; 33 | intok = 1; 34 | } 35 | } 36 | return narg; 37 | } 38 | -------------------------------------------------------------------------------- /libc/getpid.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | getpid(void) 6 | { 7 | char b[20]; 8 | int f; 9 | 10 | memset(b, 0, sizeof(b)); 11 | f = open("#c/pid", 0); 12 | if(f >= 0) { 13 | read(f, b, sizeof(b)); 14 | close(f); 15 | } 16 | return atol(b); 17 | } 18 | -------------------------------------------------------------------------------- /libc/lnrand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MASK 0x7fffffffL 5 | 6 | long 7 | lnrand(long n) 8 | { 9 | long slop, v; 10 | 11 | if(n < 0) 12 | return n; 13 | slop = MASK % n; 14 | do 15 | v = lrand(); 16 | while(v <= slop); 17 | return v % n; 18 | } 19 | -------------------------------------------------------------------------------- /libc/lrand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * algorithm by 6 | * D. P. Mitchell & J. A. Reeds 7 | */ 8 | 9 | #define LEN 607 10 | #define TAP 273 11 | #define MASK 0x7fffffffL 12 | #define A 48271 13 | #define M 2147483647 14 | #define Q 44488 15 | #define R 3399 16 | #define NORM (1.0/(1.0+MASK)) 17 | 18 | static ulong rng_vec[LEN]; 19 | static ulong* rng_tap = rng_vec; 20 | static ulong* rng_feed = 0; 21 | static Lock lk; 22 | 23 | static void 24 | isrand(long seed) 25 | { 26 | long lo, hi, x; 27 | int i; 28 | 29 | rng_tap = rng_vec; 30 | rng_feed = rng_vec+LEN-TAP; 31 | seed = seed%M; 32 | if(seed < 0) 33 | seed += M; 34 | if(seed == 0) 35 | seed = 89482311; 36 | x = seed; 37 | /* 38 | * Initialize by x[n+1] = 48271 * x[n] mod (2**31 - 1) 39 | */ 40 | for(i = -20; i < LEN; i++) { 41 | hi = x / Q; 42 | lo = x % Q; 43 | x = A*lo - R*hi; 44 | if(x < 0) 45 | x += M; 46 | if(i >= 0) 47 | rng_vec[i] = x; 48 | } 49 | } 50 | 51 | void 52 | srand(long seed) 53 | { 54 | lock(&lk); 55 | isrand(seed); 56 | unlock(&lk); 57 | } 58 | 59 | long 60 | lrand(void) 61 | { 62 | ulong x; 63 | 64 | lock(&lk); 65 | 66 | rng_tap--; 67 | if(rng_tap < rng_vec) { 68 | if(rng_feed == 0) { 69 | isrand(1); 70 | rng_tap--; 71 | } 72 | rng_tap += LEN; 73 | } 74 | rng_feed--; 75 | if(rng_feed < rng_vec) 76 | rng_feed += LEN; 77 | x = (*rng_feed + *rng_tap) & MASK; 78 | *rng_feed = x; 79 | 80 | unlock(&lk); 81 | 82 | return x; 83 | } 84 | -------------------------------------------------------------------------------- /libc/mallocz.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | void* 5 | mallocz(ulong n, int clr) 6 | { 7 | void *v; 8 | 9 | v = malloc(n); 10 | if(v && clr) 11 | memset(v, 0, n); 12 | return v; 13 | } 14 | -------------------------------------------------------------------------------- /libc/nan.h: -------------------------------------------------------------------------------- 1 | extern double __NaN(void); 2 | extern double __Inf(int); 3 | extern int __isNaN(double); 4 | extern int __isInf(double, int); 5 | -------------------------------------------------------------------------------- /libc/nan64.c: -------------------------------------------------------------------------------- 1 | /* 2 | * 64-bit IEEE not-a-number routines. 3 | * This is big/little-endian portable assuming that 4 | * the 64-bit doubles and 64-bit integers have the 5 | * same byte ordering. 6 | */ 7 | 8 | #include 9 | #include 10 | #include "fmtdef.h" 11 | 12 | #if defined (__APPLE__) || (__powerpc__) 13 | #define _NEEDLL 14 | #endif 15 | 16 | static uvlong uvnan = ((uvlong)0x7FF00000<<32)|0x00000001; 17 | static uvlong uvinf = ((uvlong)0x7FF00000<<32)|0x00000000; 18 | static uvlong uvneginf = ((uvlong)0xFFF00000<<32)|0x00000000; 19 | 20 | double 21 | __NaN(void) 22 | { 23 | uvlong *p; 24 | 25 | /* gcc complains about "return *(double*)&uvnan;" */ 26 | p = &uvnan; 27 | return *(double*)p; 28 | } 29 | 30 | int 31 | __isNaN(double d) 32 | { 33 | uvlong x; 34 | double *p; 35 | 36 | p = &d; 37 | x = *(uvlong*)p; 38 | return (ulong)(x>>32)==0x7FF00000 && !__isInf(d, 0); 39 | } 40 | 41 | double 42 | __Inf(int sign) 43 | { 44 | uvlong *p; 45 | 46 | if(sign < 0) 47 | p = &uvinf; 48 | else 49 | p = &uvneginf; 50 | return *(double*)p; 51 | } 52 | 53 | int 54 | __isInf(double d, int sign) 55 | { 56 | uvlong x; 57 | double *p; 58 | 59 | p = &d; 60 | x = *(uvlong*)p; 61 | if(sign == 0) 62 | return x==uvinf || x==uvneginf; 63 | else if(sign > 0) 64 | return x==uvinf; 65 | else 66 | return x==uvneginf; 67 | } 68 | -------------------------------------------------------------------------------- /libc/netmkaddr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | * make an address, add the defaults 7 | */ 8 | char * 9 | netmkaddr(char *linear, char *defnet, char *defsrv) 10 | { 11 | static char addr[256]; 12 | char *cp; 13 | 14 | /* 15 | * dump network name 16 | */ 17 | cp = strchr(linear, '!'); 18 | if(cp == 0){ 19 | if(defnet==0){ 20 | if(defsrv) 21 | snprint(addr, sizeof(addr), "net!%s!%s", 22 | linear, defsrv); 23 | else 24 | snprint(addr, sizeof(addr), "net!%s", linear); 25 | } 26 | else { 27 | if(defsrv) 28 | snprint(addr, sizeof(addr), "%s!%s!%s", defnet, 29 | linear, defsrv); 30 | else 31 | snprint(addr, sizeof(addr), "%s!%s", defnet, 32 | linear); 33 | } 34 | return addr; 35 | } 36 | 37 | /* 38 | * if there is already a service, use it 39 | */ 40 | cp = strchr(cp+1, '!'); 41 | if(cp) 42 | return linear; 43 | 44 | /* 45 | * add default service 46 | */ 47 | if(defsrv == 0) 48 | return linear; 49 | snprint(addr, sizeof(addr), "%s!%s", linear, defsrv); 50 | 51 | return addr; 52 | } 53 | -------------------------------------------------------------------------------- /libc/nrand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #define MASK 0x7fffffffL 5 | 6 | int 7 | nrand(int n) 8 | { 9 | long slop, v; 10 | 11 | if(n < 0) 12 | return n; 13 | slop = MASK % n; 14 | do 15 | v = lrand(); 16 | while(v <= slop); 17 | return v % n; 18 | } 19 | -------------------------------------------------------------------------------- /libc/nsec.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static uvlong order = (uvlong) 0x0001020304050607ULL; 5 | 6 | static void 7 | be2vlong(vlong *to, uchar *f) 8 | { 9 | uchar *t, *o; 10 | int i; 11 | 12 | t = (uchar*)to; 13 | o = (uchar*)ℴ 14 | for(i = 0; i < 8; i++) 15 | t[o[i]] = f[i]; 16 | } 17 | 18 | /* 19 | * After a fork with fd's copied, both fd's are pointing to 20 | * the same Chan structure. Since the offset is kept in the Chan 21 | * structure, the seek's and read's in the two processes can 22 | * compete at moving the offset around. Hence the retry loop. 23 | * 24 | * Since the bintime version doesn't need a seek, it doesn't 25 | * have the loop. 26 | */ 27 | vlong 28 | nsec(void) 29 | { 30 | char b[12+1]; 31 | static int f = -1; 32 | static int usebintime; 33 | int retries; 34 | vlong t; 35 | 36 | if(f < 0){ 37 | usebintime = 1; 38 | f = open("/dev/bintime", OREAD|OCEXEC); 39 | if(f < 0){ 40 | usebintime = 0; 41 | f = open("/dev/nsec", OREAD|OCEXEC); 42 | if(f < 0) 43 | return 0; 44 | } 45 | } 46 | 47 | if(usebintime){ 48 | if(read(f, b, sizeof(uvlong)) < 0) 49 | goto error; 50 | be2vlong(&t, (uchar*)b); 51 | return t; 52 | } else { 53 | for(retries = 0; retries < 100; retries++){ 54 | if(seek(f, 0, 0) >= 0 && read(f, b, sizeof(b)-1) >= 0){ 55 | b[sizeof(b)-1] = 0; 56 | return strtoll(b, 0, 0); 57 | } 58 | } 59 | } 60 | 61 | error: 62 | close(f); 63 | f = -1; 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /libc/pow10.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | /* 6 | * this table might overflow 127-bit exponent representations. 7 | * in that case, truncate it after 1.0e38. 8 | * it is important to get all one can from this 9 | * routine since it is used in atof to scale numbers. 10 | * the presumption is that C converts fp numbers better 11 | * than multipication of lower powers of 10. 12 | */ 13 | 14 | static 15 | double tab[] = 16 | { 17 | 1.0e0, 1.0e1, 1.0e2, 1.0e3, 1.0e4, 1.0e5, 1.0e6, 1.0e7, 1.0e8, 1.0e9, 18 | 1.0e10,1.0e11,1.0e12,1.0e13,1.0e14,1.0e15,1.0e16,1.0e17,1.0e18,1.0e19, 19 | 1.0e20,1.0e21,1.0e22,1.0e23,1.0e24,1.0e25,1.0e26,1.0e27,1.0e28,1.0e29, 20 | 1.0e30,1.0e31,1.0e32,1.0e33,1.0e34,1.0e35,1.0e36,1.0e37,1.0e38,1.0e39, 21 | 1.0e40,1.0e41,1.0e42,1.0e43,1.0e44,1.0e45,1.0e46,1.0e47,1.0e48,1.0e49, 22 | 1.0e50,1.0e51,1.0e52,1.0e53,1.0e54,1.0e55,1.0e56,1.0e57,1.0e58,1.0e59, 23 | 1.0e60,1.0e61,1.0e62,1.0e63,1.0e64,1.0e65,1.0e66,1.0e67,1.0e68,1.0e69, 24 | }; 25 | 26 | double 27 | __fmtpow10(int n) 28 | { 29 | int m; 30 | 31 | if(n < 0) { 32 | n = -n; 33 | if(n < (int)(sizeof(tab)/sizeof(tab[0]))) 34 | return 1/tab[n]; 35 | m = n/2; 36 | return __fmtpow10(-m) * __fmtpow10(m-n); 37 | } 38 | if(n < (int)(sizeof(tab)/sizeof(tab[0]))) 39 | return tab[n]; 40 | m = n/2; 41 | return __fmtpow10(m) * __fmtpow10(n-m); 42 | } 43 | -------------------------------------------------------------------------------- /libc/print.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | print(char *fmt, ...) 7 | { 8 | int n; 9 | va_list args; 10 | 11 | va_start(args, fmt); 12 | n = vfprint(1, fmt, args); 13 | va_end(args); 14 | return n; 15 | } 16 | -------------------------------------------------------------------------------- /libc/pushssl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * Since the SSL device uses decimal file descriptors to name channels, 6 | * it is impossible for a user-level file server to stand in for the kernel device. 7 | * Thus we hard-code #D rather than use /net/ssl. 8 | */ 9 | 10 | int 11 | pushssl(int fd, char *alg, char *secin, char *secout, int *cfd) 12 | { 13 | char buf[8]; 14 | char dname[64]; 15 | int n, data, ctl; 16 | 17 | ctl = open("#D/ssl/clone", ORDWR); 18 | if(ctl < 0) 19 | return -1; 20 | n = read(ctl, buf, sizeof(buf)-1); 21 | if(n < 0) 22 | goto error; 23 | buf[n] = 0; 24 | sprint(dname, "#D/ssl/%s/data", buf); 25 | data = open(dname, ORDWR); 26 | if(data < 0) 27 | goto error; 28 | if(fprint(ctl, "fd %d", fd) < 0 || 29 | fprint(ctl, "secretin %s", secin) < 0 || 30 | fprint(ctl, "secretout %s", secout) < 0 || 31 | fprint(ctl, "alg %s", alg) < 0){ 32 | close(data); 33 | goto error; 34 | } 35 | close(fd); 36 | if(cfd != 0) 37 | *cfd = ctl; 38 | else 39 | close(ctl); 40 | return data; 41 | error: 42 | close(ctl); 43 | return -1; 44 | } 45 | -------------------------------------------------------------------------------- /libc/rand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | rand(void) 6 | { 7 | return lrand() & 0x7fff; 8 | } 9 | -------------------------------------------------------------------------------- /libc/read9pmsg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | read9pmsg(int fd, void *abuf, uint n) 7 | { 8 | int m, len; 9 | uchar *buf; 10 | 11 | buf = abuf; 12 | 13 | /* read count */ 14 | m = readn(fd, buf, BIT32SZ); 15 | if(m != BIT32SZ){ 16 | if(m < 0) 17 | return -1; 18 | return 0; 19 | } 20 | 21 | len = GBIT32(buf); 22 | if(len <= BIT32SZ || len > n){ 23 | werrstr("bad length in 9P2000 message header"); 24 | return -1; 25 | } 26 | len -= BIT32SZ; 27 | m = readn(fd, buf+BIT32SZ, len); 28 | if(m < len) 29 | return 0; 30 | return BIT32SZ+m; 31 | } 32 | -------------------------------------------------------------------------------- /libc/readn.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | long 5 | readn(int f, void *av, long n) 6 | { 7 | char *a; 8 | long m, t; 9 | 10 | a = av; 11 | t = 0; 12 | while(t < n){ 13 | m = read(f, a+t, n-t); 14 | if(m <= 0){ 15 | if(t == 0) 16 | return m; 17 | break; 18 | } 19 | t += m; 20 | } 21 | return t; 22 | } 23 | -------------------------------------------------------------------------------- /libc/runefmtstr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | Rune* 6 | runefmtstrflush(Fmt *f) 7 | { 8 | if(f->start == nil) 9 | return nil; 10 | *(Rune*)f->to = '\0'; 11 | return f->start; 12 | } 13 | -------------------------------------------------------------------------------- /libc/runeseprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | Rune* 6 | runeseprint(Rune *buf, Rune *e, char *fmt, ...) 7 | { 8 | Rune *p; 9 | va_list args; 10 | 11 | va_start(args, fmt); 12 | p = runevseprint(buf, e, fmt, args); 13 | va_end(args); 14 | return p; 15 | } 16 | -------------------------------------------------------------------------------- /libc/runesmprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | Rune* 6 | runesmprint(char *fmt, ...) 7 | { 8 | va_list args; 9 | Rune *p; 10 | 11 | va_start(args, fmt); 12 | p = runevsmprint(fmt, args); 13 | va_end(args); 14 | return p; 15 | } 16 | -------------------------------------------------------------------------------- /libc/runesnprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | runesnprint(Rune *buf, int len, char *fmt, ...) 7 | { 8 | int n; 9 | va_list args; 10 | 11 | va_start(args, fmt); 12 | n = runevsnprint(buf, len, fmt, args); 13 | va_end(args); 14 | return n; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /libc/runesprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | runesprint(Rune *buf, char *fmt, ...) 7 | { 8 | int n; 9 | va_list args; 10 | 11 | va_start(args, fmt); 12 | n = runevsnprint(buf, 256, fmt, args); 13 | va_end(args); 14 | return n; 15 | } 16 | -------------------------------------------------------------------------------- /libc/runestrcat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrcat(Rune *s1, Rune *s2) 6 | { 7 | 8 | runestrcpy(runestrchr(s1, 0), s2); 9 | return s1; 10 | } 11 | -------------------------------------------------------------------------------- /libc/runestrchr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrchr(Rune *s, Rune c) 6 | { 7 | Rune c0 = c; 8 | Rune c1; 9 | 10 | if(c == 0) { 11 | while(*s++) 12 | ; 13 | return s-1; 14 | } 15 | 16 | while((c1 = *s++)) 17 | if(c1 == c0) 18 | return s-1; 19 | return 0; 20 | } 21 | -------------------------------------------------------------------------------- /libc/runestrcmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | runestrcmp(Rune *s1, Rune *s2) 6 | { 7 | Rune c1, c2; 8 | 9 | for(;;) { 10 | c1 = *s1++; 11 | c2 = *s2++; 12 | if(c1 != c2) { 13 | if(c1 > c2) 14 | return 1; 15 | return -1; 16 | } 17 | if(c1 == 0) 18 | return 0; 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /libc/runestrcpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrcpy(Rune *s1, Rune *s2) 6 | { 7 | Rune *os1; 8 | 9 | os1 = s1; 10 | while(*s1++ = *s2++) 11 | ; 12 | return os1; 13 | } 14 | -------------------------------------------------------------------------------- /libc/runestrdup.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrdup(Rune *s) 6 | { 7 | Rune *ns; 8 | 9 | ns = malloc(sizeof(Rune)*(runestrlen(s) + 1)); 10 | if(ns == 0) 11 | return 0; 12 | 13 | return runestrcpy(ns, s); 14 | } 15 | -------------------------------------------------------------------------------- /libc/runestrecpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrecpy(Rune *s1, Rune *es1, Rune *s2) 6 | { 7 | if(s1 >= es1) 8 | return s1; 9 | 10 | while(*s1++ = *s2++){ 11 | if(s1 == es1){ 12 | *--s1 = '\0'; 13 | break; 14 | } 15 | } 16 | return s1; 17 | } 18 | -------------------------------------------------------------------------------- /libc/runestrlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | long 5 | runestrlen(Rune *s) 6 | { 7 | 8 | return runestrchr(s, 0) - s; 9 | } 10 | -------------------------------------------------------------------------------- /libc/runestrncat.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrncat(Rune *s1, Rune *s2, long n) 6 | { 7 | Rune *os1; 8 | 9 | os1 = s1; 10 | s1 = runestrchr(s1, 0); 11 | while(*s1++ = *s2++) 12 | if(--n < 0) { 13 | s1[-1] = 0; 14 | break; 15 | } 16 | return os1; 17 | } 18 | -------------------------------------------------------------------------------- /libc/runestrncmp.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | runestrncmp(Rune *s1, Rune *s2, long n) 6 | { 7 | Rune c1, c2; 8 | 9 | while(n > 0) { 10 | c1 = *s1++; 11 | c2 = *s2++; 12 | n--; 13 | if(c1 != c2) { 14 | if(c1 > c2) 15 | return 1; 16 | return -1; 17 | } 18 | if(c1 == 0) 19 | break; 20 | } 21 | return 0; 22 | } 23 | -------------------------------------------------------------------------------- /libc/runestrncpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrncpy(Rune *s1, Rune *s2, long n) 6 | { 7 | int i; 8 | Rune *os1; 9 | 10 | os1 = s1; 11 | for(i = 0; i < n; i++) 12 | if((*s1++ = *s2++) == 0) { 13 | while(++i < n) 14 | *s1++ = 0; 15 | return os1; 16 | } 17 | return os1; 18 | } 19 | -------------------------------------------------------------------------------- /libc/runestrrchr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | Rune* 5 | runestrrchr(Rune *s, Rune c) 6 | { 7 | Rune *r; 8 | 9 | if(c == 0) 10 | return runestrchr(s, 0); 11 | r = 0; 12 | while(s = runestrchr(s, c)) 13 | r = s++; 14 | return r; 15 | } 16 | -------------------------------------------------------------------------------- /libc/runestrstr.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | /* 5 | * Return pointer to first occurrence of s2 in s1, 6 | * 0 if none 7 | */ 8 | Rune* 9 | runestrstr(Rune *s1, Rune *s2) 10 | { 11 | Rune *p, *pa, *pb; 12 | int c0, c; 13 | 14 | c0 = *s2; 15 | if(c0 == 0) 16 | return s1; 17 | s2++; 18 | for(p=runestrchr(s1, c0); p; p=runestrchr(p+1, c0)) { 19 | pa = p; 20 | for(pb=s2;; pb++) { 21 | c = *pb; 22 | if(c == 0) 23 | return p; 24 | if(c != *++pa) 25 | break; 26 | } 27 | } 28 | return 0; 29 | } 30 | -------------------------------------------------------------------------------- /libc/runevseprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | Rune* 6 | runevseprint(Rune *buf, Rune *e, char *fmt, va_list args) 7 | { 8 | Fmt f; 9 | 10 | if(e <= buf) 11 | return nil; 12 | f.runes = 1; 13 | f.start = buf; 14 | f.to = buf; 15 | f.stop = e - 1; 16 | f.flush = 0; 17 | f.farg = nil; 18 | f.nfmt = 0; 19 | VA_COPY(f.args,args); 20 | dofmt(&f, fmt); 21 | VA_END(f.args); 22 | *(Rune*)f.to = '\0'; 23 | return (Rune*)f.to; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libc/runevsmprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | static int 6 | runeFmtStrFlush(Fmt *f) 7 | { 8 | Rune *s; 9 | int n, d; 10 | 11 | if(f->start == nil) 12 | return 0; 13 | n = (uintptr)f->farg; 14 | n *= 2; 15 | d = (Rune*)f->to - (Rune*)f->start; 16 | s = realloc(f->start, sizeof(Rune)*n); 17 | if(s == nil){ 18 | f->farg = nil; 19 | f->to = nil; 20 | f->stop = nil; 21 | free(f->start); 22 | return 0; 23 | } 24 | f->start = s; 25 | f->farg = (void*)(uintptr)n; 26 | f->to = (Rune*)f->start + d; 27 | f->stop = (Rune*)f->start + n - 1; 28 | return 1; 29 | } 30 | 31 | int 32 | runefmtstrinit(Fmt *f) 33 | { 34 | int n; 35 | 36 | memset(f, 0, sizeof *f); 37 | f->runes = 1; 38 | n = 32; 39 | f->start = malloc(sizeof(Rune)*n); 40 | if(f->start == nil) 41 | return -1; 42 | f->to = f->start; 43 | f->stop = (Rune*)f->start + n - 1; 44 | f->flush = runeFmtStrFlush; 45 | f->farg = (void*)(uintptr)n; 46 | f->nfmt = 0; 47 | return 0; 48 | } 49 | 50 | /* 51 | * print into an allocated string buffer 52 | */ 53 | Rune* 54 | runevsmprint(char *fmt, va_list args) 55 | { 56 | Fmt f; 57 | int n; 58 | 59 | if(runefmtstrinit(&f) < 0) 60 | return nil; 61 | VA_COPY(f.args,args); 62 | n = dofmt(&f, fmt); 63 | VA_END(f.args); 64 | if(f.start == nil) 65 | return nil; 66 | if(n < 0){ 67 | free(f.start); 68 | return nil; 69 | } 70 | *(Rune*)f.to = '\0'; 71 | return (Rune*)f.start; 72 | } 73 | -------------------------------------------------------------------------------- /libc/runevsnprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | runevsnprint(Rune *buf, int len, char *fmt, va_list args) 7 | { 8 | Fmt f; 9 | 10 | if(len <= 0) 11 | return -1; 12 | f.runes = 1; 13 | f.start = buf; 14 | f.to = buf; 15 | f.stop = buf + len - 1; 16 | f.flush = 0; 17 | f.farg = nil; 18 | f.nfmt = 0; 19 | VA_COPY(f.args,args); 20 | dofmt(&f, fmt); 21 | VA_END(f.args); 22 | *(Rune*)f.to = '\0'; 23 | return (Rune*)f.to - buf; 24 | } 25 | -------------------------------------------------------------------------------- /libc/seprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | char* 6 | seprint(char *buf, char *e, char *fmt, ...) 7 | { 8 | char *p; 9 | va_list args; 10 | 11 | va_start(args, fmt); 12 | p = vseprint(buf, e, fmt, args); 13 | va_end(args); 14 | return p; 15 | } 16 | -------------------------------------------------------------------------------- /libc/smprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | char* 6 | smprint(char *fmt, ...) 7 | { 8 | va_list args; 9 | char *p; 10 | 11 | va_start(args, fmt); 12 | p = vsmprint(fmt, args); 13 | va_end(args); 14 | return p; 15 | } 16 | -------------------------------------------------------------------------------- /libc/snprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | snprint(char *buf, int len, char *fmt, ...) 7 | { 8 | int n; 9 | va_list args; 10 | 11 | va_start(args, fmt); 12 | n = vsnprint(buf, len, fmt, args); 13 | va_end(args); 14 | return n; 15 | } 16 | 17 | -------------------------------------------------------------------------------- /libc/sprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | sprint(char *buf, char *fmt, ...) 7 | { 8 | int n; 9 | uint len; 10 | va_list args; 11 | 12 | len = 1<<30; /* big number, but sprint is deprecated anyway */ 13 | /* 14 | * on PowerPC, the stack is near the top of memory, so 15 | * we must be sure not to overflow a 32-bit pointer. 16 | */ 17 | if((uintptr)buf+len < (uintptr)buf) 18 | len = -(uintptr)buf-1; 19 | 20 | va_start(args, fmt); 21 | n = vsnprint(buf, len, fmt, args); 22 | va_end(args); 23 | return n; 24 | } 25 | -------------------------------------------------------------------------------- /libc/strecpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char* 5 | strecpy(char *to, char *e, char *from) 6 | { 7 | if(to >= e) 8 | return to; 9 | to = memccpy(to, from, '\0', e - to); 10 | if(to == nil){ 11 | to = e - 1; 12 | *to = '\0'; 13 | }else{ 14 | to--; 15 | } 16 | return to; 17 | } 18 | -------------------------------------------------------------------------------- /libc/strtod.h: -------------------------------------------------------------------------------- 1 | extern double __NaN(void); 2 | extern double __Inf(int); 3 | extern double __isNaN(double); 4 | extern double __isInf(double, int); 5 | -------------------------------------------------------------------------------- /libc/strtoll.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #define VLONG_MAX ((vlong)~(((uvlong)1)<<63)) 4 | #define VLONG_MIN ((vlong)(((uvlong)1)<<63)) 5 | vlong 6 | strtoll(const char *nptr, char **endptr, int base) 7 | { 8 | char *p; 9 | vlong n, nn, m; 10 | int c, ovfl, v, neg, ndig; 11 | p = (char*)nptr; 12 | neg = 0; 13 | n = 0; 14 | ndig = 0; 15 | ovfl = 0; 16 | /* 17 | * White space 18 | */ 19 | for(;; p++) { 20 | switch(*p) { 21 | case ' ': 22 | case '\t': 23 | case '\n': 24 | case '\f': 25 | case '\r': 26 | case '\v': 27 | continue; 28 | } 29 | break; 30 | } 31 | /* 32 | * Sign 33 | */ 34 | if(*p=='-' || *p=='+') 35 | if(*p++ == '-') 36 | neg = 1; 37 | /* 38 | * Base 39 | */ 40 | if(base==0){ 41 | base = 10; 42 | if(*p == '0') { 43 | base = 8; 44 | if(p[1]=='x' || p[1]=='X') { 45 | p += 2; 46 | base = 16; 47 | } 48 | } 49 | } else 50 | if(base==16 && *p=='0') { 51 | if(p[1]=='x' || p[1]=='X') 52 | p += 2; 53 | } else 54 | if(base<0 || 36= base) 72 | break; 73 | if(n > m) 74 | ovfl = 1; 75 | nn = n*base + v; 76 | if(nn < n) 77 | ovfl = 1; 78 | n = nn; 79 | } 80 | Return: 81 | if(ndig == 0) 82 | p = (char*)nptr; 83 | if(endptr) 84 | *endptr = p; 85 | if(ovfl){ 86 | if(neg) 87 | return VLONG_MIN; 88 | return VLONG_MAX; 89 | } 90 | if(neg) 91 | return -n; 92 | return n; 93 | } 94 | -------------------------------------------------------------------------------- /libc/sysfatal.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | static void 5 | _sysfatalimpl(char *fmt, va_list arg) 6 | { 7 | char buf[1024]; 8 | 9 | vseprint(buf, buf+sizeof(buf), fmt, arg); 10 | if(argv0) 11 | fprint(2, "%s: %s\n", argv0, buf); 12 | else 13 | fprint(2, "%s\n", buf); 14 | #undef write 15 | write(2, buf, strlen(buf)); 16 | write(2, "\n", 1); 17 | panic("sysfatal"); 18 | } 19 | 20 | void (*_sysfatal)(char *fmt, va_list arg) = _sysfatalimpl; 21 | 22 | void 23 | sysfatal(char *fmt, ...) 24 | { 25 | va_list arg; 26 | 27 | va_start(arg, fmt); 28 | (*_sysfatal)(fmt, arg); 29 | va_end(arg); 30 | } 31 | -------------------------------------------------------------------------------- /libc/time.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | /* 6 | * After a fork with fd's copied, both fd's are pointing to 7 | * the same Chan structure. Since the offset is kept in the Chan 8 | * structure, the seek's and read's in the two processes can 9 | * compete at moving the offset around. Hence the unusual loop 10 | * in the middle of this routine. 11 | */ 12 | static long 13 | oldtime(long *tp) 14 | { 15 | char b[20]; 16 | static int f = -1; 17 | int i, retries; 18 | long t; 19 | 20 | memset(b, 0, sizeof(b)); 21 | for(retries = 0; retries < 100; retries++){ 22 | if(f < 0) 23 | f = open("/dev/time", OREAD|OCEXEC); 24 | if(f < 0) 25 | break; 26 | if(seek(f, 0, 0) < 0 || (i = read(f, b, sizeof(b))) < 0){ 27 | close(f); 28 | f = -1; 29 | } else { 30 | if(i != 0) 31 | break; 32 | } 33 | } 34 | t = atol(b); 35 | if(tp) 36 | *tp = t; 37 | return t; 38 | } 39 | 40 | long 41 | time(long *tp) 42 | { 43 | vlong t; 44 | 45 | t = nsec()/((vlong)1000000000); 46 | if(t == 0) 47 | t = oldtime(0); 48 | if(tp != nil) 49 | *tp = t; 50 | return t; 51 | } 52 | -------------------------------------------------------------------------------- /libc/truerand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | ulong 5 | truerand(void) 6 | { 7 | ulong x; 8 | static int randfd = -1; 9 | 10 | if(randfd < 0) 11 | randfd = open("/dev/random", OREAD|OCEXEC); 12 | if(randfd < 0) 13 | sysfatal("can't open /dev/random"); 14 | if(read(randfd, &x, sizeof(x)) != sizeof(x)) 15 | sysfatal("can't read /dev/random"); 16 | return x; 17 | } 18 | -------------------------------------------------------------------------------- /libc/u16.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | static char t16e[] = "0123456789ABCDEF"; 4 | 5 | int 6 | dec16(uchar *out, int lim, char *in, int n) 7 | { 8 | int c, w = 0, i = 0; 9 | uchar *start = out; 10 | uchar *eout = out + lim; 11 | 12 | while(n-- > 0){ 13 | c = *in++; 14 | if('0' <= c && c <= '9') 15 | c = c - '0'; 16 | else if('a' <= c && c <= 'z') 17 | c = c - 'a' + 10; 18 | else if('A' <= c && c <= 'Z') 19 | c = c - 'A' + 10; 20 | else 21 | continue; 22 | w = (w<<4) + c; 23 | i++; 24 | if(i == 2){ 25 | if(out + 1 > eout) 26 | goto exhausted; 27 | *out++ = w; 28 | w = 0; 29 | i = 0; 30 | } 31 | } 32 | exhausted: 33 | return out - start; 34 | } 35 | 36 | int 37 | enc16(char *out, int lim, uchar *in, int n) 38 | { 39 | uint c; 40 | char *eout = out + lim; 41 | char *start = out; 42 | 43 | while(n-- > 0){ 44 | c = *in++; 45 | if(out + 2 >= eout) 46 | goto exhausted; 47 | *out++ = t16e[c>>4]; 48 | *out++ = t16e[c&0xf]; 49 | } 50 | exhausted: 51 | *out = 0; 52 | return out - start; 53 | } 54 | -------------------------------------------------------------------------------- /libc/utfdef.h: -------------------------------------------------------------------------------- 1 | #define uchar _utfuchar 2 | #define ushort _utfushort 3 | #define uint _utfuint 4 | #define ulong _utfulong 5 | #define vlong _utfvlong 6 | #define uvlong _utfuvlong 7 | 8 | typedef unsigned char uchar; 9 | typedef unsigned short ushort; 10 | typedef unsigned int uint; 11 | typedef unsigned long ulong; 12 | 13 | #define nelem(x) (sizeof(x)/sizeof((x)[0])) 14 | #define nil ((void*)0) 15 | -------------------------------------------------------------------------------- /libc/utfecpy.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char* 5 | utfecpy(char *to, char *e, char *from) 6 | { 7 | char *end; 8 | 9 | if(to >= e) 10 | return to; 11 | end = memccpy(to, from, '\0', e - to); 12 | if(end == nil){ 13 | end = e-1; 14 | while(end>to && (*--end&0xC0)==0x80) 15 | ; 16 | *end = '\0'; 17 | }else{ 18 | end--; 19 | } 20 | return end; 21 | } 22 | -------------------------------------------------------------------------------- /libc/utflen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | utflen(char *s) 6 | { 7 | int c; 8 | long n; 9 | Rune rune; 10 | 11 | n = 0; 12 | for(;;) { 13 | c = *(uchar*)s; 14 | if(c < Runeself) { 15 | if(c == 0) 16 | return n; 17 | s++; 18 | } else 19 | s += chartorune(&rune, s); 20 | n++; 21 | } 22 | return 0; 23 | } 24 | -------------------------------------------------------------------------------- /libc/utfnlen.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | int 5 | utfnlen(char *s, long m) 6 | { 7 | int c; 8 | long n; 9 | Rune rune; 10 | char *es; 11 | 12 | es = s + m; 13 | for(n = 0; s < es; n++) { 14 | c = *(uchar*)s; 15 | if(c < Runeself){ 16 | if(c == '\0') 17 | break; 18 | s++; 19 | continue; 20 | } 21 | if(!fullrune(s, es-s)) 22 | break; 23 | s += chartorune(&rune, s); 24 | } 25 | return n; 26 | } 27 | -------------------------------------------------------------------------------- /libc/utfrrune.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char* 5 | utfrrune(char *s, long c) 6 | { 7 | long c1; 8 | Rune r; 9 | char *s1; 10 | 11 | if(c < Runesync) /* not part of utf sequence */ 12 | return strrchr(s, c); 13 | 14 | s1 = 0; 15 | for(;;) { 16 | c1 = *(uchar*)s; 17 | if(c1 < Runeself) { /* one byte rune */ 18 | if(c1 == 0) 19 | return s1; 20 | if(c1 == c) 21 | s1 = s; 22 | s++; 23 | continue; 24 | } 25 | c1 = chartorune(&r, s); 26 | if(r == c) 27 | s1 = s; 28 | s += c1; 29 | } 30 | return 0; 31 | } 32 | -------------------------------------------------------------------------------- /libc/utfrune.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | char* 5 | utfrune(char *s, long c) 6 | { 7 | long c1; 8 | Rune r; 9 | int n; 10 | 11 | if(c < Runesync) /* not part of utf sequence */ 12 | return strchr(s, c); 13 | 14 | for(;;) { 15 | c1 = *(uchar*)s; 16 | if(c1 < Runeself) { /* one byte rune */ 17 | if(c1 == 0) 18 | return 0; 19 | if(c1 == c) 20 | return s; 21 | s++; 22 | continue; 23 | } 24 | n = chartorune(&r, s); 25 | if(r == c) 26 | return s; 27 | s += n; 28 | } 29 | return 0; 30 | } 31 | -------------------------------------------------------------------------------- /libc/utfutf.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | 5 | /* 6 | * Return pointer to first occurrence of s2 in s1, 7 | * 0 if none 8 | */ 9 | char* 10 | utfutf(char *s1, char *s2) 11 | { 12 | char *p; 13 | long f, n1, n2; 14 | Rune r; 15 | 16 | n1 = chartorune(&r, s2); 17 | f = r; 18 | if(f <= Runesync) /* represents self */ 19 | return strstr(s1, s2); 20 | 21 | n2 = strlen(s2); 22 | for(p=s1; (p=utfrune(p, f)); p+=n1) 23 | if(strncmp(p, s2, n2) == 0) 24 | return p; 25 | return 0; 26 | } 27 | -------------------------------------------------------------------------------- /libc/vfprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | vfprint(int fd, char *fmt, va_list args) 7 | { 8 | Fmt f; 9 | char buf[256]; 10 | int n; 11 | 12 | fmtfdinit(&f, fd, buf, sizeof(buf)); 13 | VA_COPY(f.args,args); 14 | n = dofmt(&f, fmt); 15 | VA_END(f.args); 16 | if(n > 0 && __fmtFdFlush(&f) == 0) 17 | return -1; 18 | return n; 19 | } 20 | -------------------------------------------------------------------------------- /libc/vseprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | char* 6 | vseprint(char *buf, char *e, char *fmt, va_list args) 7 | { 8 | Fmt f; 9 | 10 | if(e <= buf) 11 | return nil; 12 | f.runes = 0; 13 | f.start = buf; 14 | f.to = buf; 15 | f.stop = e - 1; 16 | f.flush = 0; 17 | f.farg = nil; 18 | f.nfmt = 0; 19 | VA_COPY(f.args,args); 20 | dofmt(&f, fmt); 21 | VA_END(f.args); 22 | *(char*)f.to = '\0'; 23 | return (char*)f.to; 24 | } 25 | 26 | -------------------------------------------------------------------------------- /libc/vsmprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | static int 6 | fmtStrFlush(Fmt *f) 7 | { 8 | char *s; 9 | int n, d; 10 | 11 | if(f->start == nil) 12 | return 0; 13 | n = (uintptr)f->farg; 14 | n *= 2; 15 | d = (char*)f->to - (char*)f->start; 16 | s = realloc(f->start, n); 17 | if(s == nil){ 18 | f->farg = nil; 19 | f->to = nil; 20 | f->stop = nil; 21 | free(f->start); 22 | return 0; 23 | } 24 | f->start = s; 25 | f->farg = (void*)(uintptr)n; 26 | f->to = (char*)f->start + d; 27 | f->stop = (char*)f->start + n - 1; 28 | return 1; 29 | } 30 | 31 | int 32 | fmtstrinit(Fmt *f) 33 | { 34 | int n; 35 | 36 | memset(f, 0, sizeof *f); 37 | f->runes = 0; 38 | n = 32; 39 | f->start = malloc(n); 40 | if(f->start == nil) 41 | return -1; 42 | f->to = f->start; 43 | f->stop = (char*)f->start + n - 1; 44 | f->flush = fmtStrFlush; 45 | f->farg = (void*)(uintptr)n; 46 | f->nfmt = 0; 47 | return 0; 48 | } 49 | 50 | /* 51 | * print into an allocated string buffer 52 | */ 53 | char* 54 | vsmprint(char *fmt, va_list args) 55 | { 56 | Fmt f; 57 | int n; 58 | 59 | if(fmtstrinit(&f) < 0) 60 | return nil; 61 | VA_COPY(f.args,args); 62 | n = dofmt(&f, fmt); 63 | VA_END(f.args); 64 | if(n < 0){ 65 | free(f.start); 66 | return nil; 67 | } 68 | return fmtstrflush(&f); 69 | } 70 | -------------------------------------------------------------------------------- /libc/vsnprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "fmtdef.h" 4 | 5 | int 6 | vsnprint(char *buf, int len, char *fmt, va_list args) 7 | { 8 | Fmt f; 9 | 10 | if(len <= 0) 11 | return -1; 12 | f.runes = 0; 13 | f.start = buf; 14 | f.to = buf; 15 | f.stop = buf + len - 1; 16 | f.flush = 0; 17 | f.farg = nil; 18 | f.nfmt = 0; 19 | VA_COPY(f.args,args); 20 | dofmt(&f, fmt); 21 | VA_END(f.args); 22 | *(char*)f.to = '\0'; 23 | return (char*)f.to - buf; 24 | } 25 | -------------------------------------------------------------------------------- /libdraw/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libdraw.a 4 | 5 | OFILES=\ 6 | alloc.$O\ 7 | arith.$O\ 8 | bytesperline.$O\ 9 | chan.$O\ 10 | defont.$O\ 11 | drawrepl.$O\ 12 | icossin.$O\ 13 | icossin2.$O\ 14 | rectclip.$O\ 15 | rgb.$O 16 | 17 | default: $(LIB) 18 | $(LIB): $(OFILES) 19 | $(AR) r $(LIB) $(OFILES) 20 | $(RANLIB) $(LIB) 21 | 22 | %.$O: %.c 23 | $(CC) $(CFLAGS) $*.c 24 | 25 | -------------------------------------------------------------------------------- /libdraw/bytesperline.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static 6 | int 7 | unitsperline(Rectangle r, int d, int bitsperunit) 8 | { 9 | ulong l, t; 10 | 11 | if(d <= 0 || d > 32) /* being called wrong. d is image depth. */ 12 | abort(); 13 | 14 | if(r.min.x >= 0){ 15 | l = (r.max.x*d+bitsperunit-1)/bitsperunit; 16 | l -= (r.min.x*d)/bitsperunit; 17 | }else{ /* make positive before divide */ 18 | t = (-r.min.x*d+bitsperunit-1)/bitsperunit; 19 | l = t+(r.max.x*d+bitsperunit-1)/bitsperunit; 20 | } 21 | return l; 22 | } 23 | 24 | int 25 | wordsperline(Rectangle r, int d) 26 | { 27 | return unitsperline(r, d, 8*sizeof(ulong)); 28 | } 29 | 30 | int 31 | bytesperline(Rectangle r, int d) 32 | { 33 | return unitsperline(r, d, 8); 34 | } 35 | -------------------------------------------------------------------------------- /libdraw/chan.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | static char channames[] = "rgbkamx"; 6 | char* 7 | chantostr(char *buf, ulong cc) 8 | { 9 | ulong c, rc; 10 | char *p; 11 | 12 | if(chantodepth(cc) == 0) 13 | return nil; 14 | 15 | /* reverse the channel descriptor so we can easily generate the string in the right order */ 16 | rc = 0; 17 | for(c=cc; c; c>>=8){ 18 | rc <<= 8; 19 | rc |= c&0xFF; 20 | } 21 | 22 | p = buf; 23 | for(c=rc; c; c>>=8) { 24 | *p++ = channames[TYPE(c)]; 25 | *p++ = '0'+NBITS(c); 26 | } 27 | *p = 0; 28 | 29 | return buf; 30 | } 31 | 32 | /* avoid pulling in ctype when using with drawterm etc. */ 33 | static int 34 | xisspace(char c) 35 | { 36 | return c==' ' || c== '\t' || c=='\r' || c=='\n'; 37 | } 38 | 39 | ulong 40 | strtochan(char *s) 41 | { 42 | char *p, *q; 43 | ulong c; 44 | int t, n; 45 | 46 | c = 0; 47 | p=s; 48 | while(*p && xisspace(*p)) 49 | p++; 50 | 51 | while(*p && !xisspace(*p)){ 52 | if((q = strchr(channames, p[0])) == nil) 53 | return 0; 54 | t = q-channames; 55 | if(p[1] < '0' || p[1] > '9') 56 | return 0; 57 | n = p[1]-'0'; 58 | c = (c<<8) | __DC(t, n); 59 | p += 2; 60 | } 61 | return c; 62 | } 63 | 64 | int 65 | chantodepth(ulong c) 66 | { 67 | int n; 68 | 69 | for(n=0; c; c>>=8){ 70 | if(TYPE(c) >= NChan || NBITS(c) > 8 || NBITS(c) <= 0) 71 | return 0; 72 | n += NBITS(c); 73 | } 74 | if(n==0 || (n>8 && n%8) || (n<8 && 8%n)) 75 | return 0; 76 | return n; 77 | } 78 | -------------------------------------------------------------------------------- /libdraw/drawrepl.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | drawreplxy(int min, int max, int x) 7 | { 8 | int sx; 9 | 10 | sx = (x-min)%(max-min); 11 | if(sx < 0) 12 | sx += max-min; 13 | return sx+min; 14 | } 15 | 16 | Point 17 | drawrepl(Rectangle r, Point p) 18 | { 19 | p.x = drawreplxy(r.min.x, r.max.x, p.x); 20 | p.y = drawreplxy(r.min.y, r.max.y, p.y); 21 | return p; 22 | } 23 | 24 | -------------------------------------------------------------------------------- /libdraw/rectclip.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | int 6 | rectclip(Rectangle *rp, Rectangle b) /* first by reference, second by value */ 7 | { 8 | Rectangle *bp = &b; 9 | /* 10 | * Expand rectXrect() in line for speed 11 | */ 12 | if((rp->min.xmax.x && bp->min.xmax.x && 13 | rp->min.ymax.y && bp->min.ymax.y)==0) 14 | return 0; 15 | /* They must overlap */ 16 | if(rp->min.x < bp->min.x) 17 | rp->min.x = bp->min.x; 18 | if(rp->min.y < bp->min.y) 19 | rp->min.y = bp->min.y; 20 | if(rp->max.x > bp->max.x) 21 | rp->max.x = bp->max.x; 22 | if(rp->max.y > bp->max.y) 23 | rp->max.y = bp->max.y; 24 | return 1; 25 | } 26 | -------------------------------------------------------------------------------- /libip/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libip.a 4 | 5 | OFILES=\ 6 | eipfmt.$O\ 7 | parseip.$O\ 8 | classmask.$O\ 9 | bo.$O\ 10 | ipaux.$O\ 11 | 12 | default: $(LIB) 13 | $(LIB): $(OFILES) 14 | $(AR) r $(LIB) $(OFILES) 15 | $(RANLIB) $(LIB) 16 | 17 | %.$O: %.c 18 | $(CC) $(CFLAGS) $*.c 19 | 20 | -------------------------------------------------------------------------------- /libip/bo.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | void 6 | hnputv(void *p, uvlong v) 7 | { 8 | uchar *a; 9 | 10 | a = p; 11 | a[0] = v>>56; 12 | a[1] = v>>48; 13 | a[2] = v>>40; 14 | a[3] = v>>32; 15 | a[4] = v>>24; 16 | a[5] = v>>16; 17 | a[6] = v>>8; 18 | a[7] = v; 19 | } 20 | 21 | void 22 | hnputl(void *p, uint v) 23 | { 24 | uchar *a; 25 | 26 | a = p; 27 | a[0] = v>>24; 28 | a[1] = v>>16; 29 | a[2] = v>>8; 30 | a[3] = v; 31 | } 32 | 33 | void 34 | hnputs(void *p, ushort v) 35 | { 36 | uchar *a; 37 | 38 | a = p; 39 | a[0] = v>>8; 40 | a[1] = v; 41 | } 42 | 43 | uvlong 44 | nhgetv(void *p) 45 | { 46 | uchar *a; 47 | uvlong v; 48 | 49 | a = p; 50 | v = (uvlong)a[0]<<56; 51 | v |= (uvlong)a[1]<<48; 52 | v |= (uvlong)a[2]<<40; 53 | v |= (uvlong)a[3]<<32; 54 | v |= a[4]<<24; 55 | v |= a[5]<<16; 56 | v |= a[6]<<8; 57 | v |= a[7]<<0; 58 | return v; 59 | } 60 | 61 | uint 62 | nhgetl(void *p) 63 | { 64 | uchar *a; 65 | 66 | a = p; 67 | return (a[0]<<24)|(a[1]<<16)|(a[2]<<8)|(a[3]<<0); 68 | } 69 | 70 | ushort 71 | nhgets(void *p) 72 | { 73 | uchar *a; 74 | 75 | a = p; 76 | return (a[0]<<8)|(a[1]<<0); 77 | } 78 | -------------------------------------------------------------------------------- /libmemdraw/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libmemdraw.a 4 | 5 | OFILES=\ 6 | alloc.$O\ 7 | arc.$O\ 8 | cload.$O\ 9 | cmap.$O\ 10 | cread.$O\ 11 | defont.$O\ 12 | draw.$O\ 13 | ellipse.$O\ 14 | fillpoly.$O\ 15 | hwdraw.$O\ 16 | line.$O\ 17 | load.$O\ 18 | openmemsubfont.$O\ 19 | poly.$O\ 20 | read.$O\ 21 | string.$O\ 22 | subfont.$O\ 23 | unload.$O\ 24 | write.$O 25 | 26 | default: $(LIB) 27 | $(LIB): $(OFILES) 28 | $(AR) r $(LIB) $(OFILES) 29 | $(RANLIB) $(LIB) 30 | 31 | %.$O: %.c 32 | $(CC) $(CFLAGS) $*.c 33 | 34 | -------------------------------------------------------------------------------- /libmemdraw/alpha.hoc: -------------------------------------------------------------------------------- 1 | func f(x) { 2 | return x-x%1 3 | } 4 | 5 | func pixel(dr, dg, db, da, sr, sg, sb, sa, m) { 6 | M = 255-f((sa*m)/255) 7 | print f((sr*m+dr*M)/255), " ", f((sg*m+dg*M)/255), " ", f((sb*m+db*M)/255), " ", f((sa*m+da*M)/255), "\n" 8 | return 0 9 | } 10 | -------------------------------------------------------------------------------- /libmemdraw/arctest.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | extern int drawdebug; 8 | void 9 | main(int argc, char **argv) 10 | { 11 | char cc; 12 | Memimage *x; 13 | Point c = {208,871}; 14 | int a = 441; 15 | int b = 441; 16 | int thick = 0; 17 | Point sp = {0,0}; 18 | int alpha = 51; 19 | int phi = 3; 20 | vlong t0, t1; 21 | int i, n; 22 | vlong del; 23 | 24 | memimageinit(); 25 | 26 | x = allocmemimage(Rect(0,0,1000,1000), CMAP8); 27 | n = atoi(argv[1]); 28 | 29 | t0 = nsec(); 30 | t0 = nsec(); 31 | t0 = nsec(); 32 | t1 = nsec(); 33 | del = t1-t0; 34 | t0 = nsec(); 35 | for(i=0; i 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | _cloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) 8 | { 9 | int y, bpl, c, cnt, offs; 10 | uchar mem[NMEM], *memp, *omemp, *emem, *linep, *elinep, *u, *eu; 11 | 12 | if(!rectinrect(r, i->r)) 13 | return -1; 14 | bpl = bytesperline(r, i->depth); 15 | u = data; 16 | eu = data+ndata; 17 | memp = mem; 18 | emem = mem+NMEM; 19 | y = r.min.y; 20 | linep = byteaddr(i, Pt(r.min.x, y)); 21 | elinep = linep+bpl; 22 | for(;;){ 23 | if(linep == elinep){ 24 | if(++y == r.max.y) 25 | break; 26 | linep = byteaddr(i, Pt(r.min.x, y)); 27 | elinep = linep+bpl; 28 | } 29 | if(u == eu){ /* buffer too small */ 30 | return -1; 31 | } 32 | c = *u++; 33 | if(c >= 128){ 34 | for(cnt=c-128+1; cnt!=0 ;--cnt){ 35 | if(u == eu){ /* buffer too small */ 36 | return -1; 37 | } 38 | if(linep == elinep){ /* phase error */ 39 | return -1; 40 | } 41 | *linep++ = *u; 42 | *memp++ = *u++; 43 | if(memp == emem) 44 | memp = mem; 45 | } 46 | } 47 | else{ 48 | if(u == eu) /* short buffer */ 49 | return -1; 50 | offs = *u++ + ((c&3)<<8)+1; 51 | if(memp-mem < offs) 52 | omemp = memp+(NMEM-offs); 53 | else 54 | omemp = memp-offs; 55 | for(cnt=(c>>2)+NMATCH; cnt!=0; --cnt){ 56 | if(linep == elinep) /* phase error */ 57 | return -1; 58 | *linep++ = *omemp; 59 | *memp++ = *omemp++; 60 | if(omemp == emem) 61 | omemp = mem; 62 | if(memp == emem) 63 | memp = mem; 64 | } 65 | } 66 | } 67 | return u-data; 68 | } 69 | -------------------------------------------------------------------------------- /libmemdraw/defont.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | Memsubfont* 7 | getmemdefont(void) 8 | { 9 | char *hdr, *p; 10 | int n; 11 | Fontchar *fc; 12 | Memsubfont *f; 13 | int ld; 14 | Rectangle r; 15 | Memdata *md; 16 | Memimage *i; 17 | 18 | /* 19 | * make sure data is word-aligned. this is true with Plan 9 compilers 20 | * but not in general. the byte order is right because the data is 21 | * declared as char*, not ulong*. 22 | */ 23 | p = (char*)defontdata; 24 | n = (uintptr)p & 3; 25 | if(n != 0){ 26 | memmove(p+(4-n), p, sizeofdefont-n); 27 | p += 4-n; 28 | } 29 | ld = atoi(p+0*12); 30 | r.min.x = atoi(p+1*12); 31 | r.min.y = atoi(p+2*12); 32 | r.max.x = atoi(p+3*12); 33 | r.max.y = atoi(p+4*12); 34 | 35 | md = mallocz(sizeof(Memdata), 1); 36 | if(md == nil) 37 | return nil; 38 | 39 | p += 5*12; 40 | 41 | md->base = nil; /* so freememimage doesn't free p */ 42 | md->bdata = (uchar*)p; /* ick */ 43 | md->ref = 1; 44 | md->allocd = 1; /* so freememimage does free md */ 45 | 46 | i = allocmemimaged(r, drawld2chan[ld], md, nil); 47 | if(i == nil){ 48 | free(md); 49 | return nil; 50 | } 51 | 52 | hdr = p+Dy(r)*i->width*sizeof(ulong); 53 | n = atoi(hdr); 54 | p = hdr+3*12; 55 | fc = malloc(sizeof(Fontchar)*(n+1)); 56 | if(fc == 0){ 57 | freememimage(i); 58 | return 0; 59 | } 60 | _unpackinfo(fc, (uchar*)p, n); 61 | f = allocmemsubfont("*default*", n, atoi(hdr+12), atoi(hdr+24), fc, i); 62 | if(f == 0){ 63 | freememimage(i); 64 | free(fc); 65 | return 0; 66 | } 67 | return f; 68 | } 69 | -------------------------------------------------------------------------------- /libmemdraw/hwdraw.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | hwdraw(Memdrawparam *p) 8 | { 9 | USED(p); 10 | return 0; /* could not satisfy request */ 11 | } 12 | 13 | -------------------------------------------------------------------------------- /libmemdraw/iprint.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | iprint(char *fmt,...) 8 | { 9 | USED(fmt); 10 | return -1; 11 | } 12 | 13 | -------------------------------------------------------------------------------- /libmemdraw/openmemsubfont.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | Memsubfont* 7 | openmemsubfont(char *name) 8 | { 9 | Memsubfont *sf; 10 | Memimage *i; 11 | Fontchar *fc; 12 | int fd, n; 13 | char hdr[3*12+4+1]; 14 | uchar *p; 15 | 16 | fd = open(name, OREAD); 17 | if(fd < 0) 18 | return nil; 19 | p = nil; 20 | i = readmemimage(fd); 21 | if(i == nil) 22 | goto Err; 23 | if(read(fd, hdr, 3*12) != 3*12){ 24 | werrstr("openmemsubfont: header read error: %r"); 25 | goto Err; 26 | } 27 | n = atoi(hdr); 28 | p = malloc(6*(n+1)); 29 | if(p == nil) 30 | goto Err; 31 | if(read(fd, p, 6*(n+1)) != 6*(n+1)){ 32 | werrstr("openmemsubfont: fontchar read error: %r"); 33 | goto Err; 34 | } 35 | fc = malloc(sizeof(Fontchar)*(n+1)); 36 | if(fc == nil) 37 | goto Err; 38 | _unpackinfo(fc, p, n); 39 | sf = allocmemsubfont(name, n, atoi(hdr+12), atoi(hdr+24), fc, i); 40 | if(sf == nil){ 41 | free(fc); 42 | goto Err; 43 | } 44 | free(p); 45 | return sf; 46 | Err: 47 | close(fd); 48 | if (i != nil) 49 | freememimage(i); 50 | if (p != nil) 51 | free(p); 52 | return nil; 53 | } 54 | -------------------------------------------------------------------------------- /libmemdraw/poly.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void 8 | mempoly(Memimage *dst, Point *vert, int nvert, int end0, int end1, int radius, Memimage *src, Point sp, int op) 9 | { 10 | int i, e0, e1; 11 | Point d; 12 | 13 | if(nvert < 2) 14 | return; 15 | d = subpt(sp, vert[0]); 16 | for(i=1; i 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | Point 8 | memimagestring(Memimage *b, Point p, Memimage *color, Point cp, Memsubfont *f, char *cs) 9 | { 10 | int w, width; 11 | uchar *s; 12 | Rune c; 13 | Fontchar *i; 14 | 15 | s = (uchar*)cs; 16 | for(; (c=*s); p.x+=width, cp.x+=width){ 17 | width = 0; 18 | if(c < Runeself) 19 | s++; 20 | else{ 21 | w = chartorune(&c, (char*)s); 22 | if(w == 0){ 23 | s++; 24 | continue; 25 | } 26 | s += w; 27 | } 28 | if(c >= f->n) 29 | continue; 30 | // i = f->info+c; 31 | i = &(f->info[c]); 32 | width = i->width; 33 | memdraw(b, Rect(p.x+i->left, p.y+i->top, p.x+i->left+(i[1].x-i[0].x), p.y+i->bottom), 34 | color, cp, f->bits, Pt(i->x, i->top), SoverD); 35 | } 36 | return p; 37 | } 38 | 39 | Point 40 | memsubfontwidth(Memsubfont *f, char *cs) 41 | { 42 | Rune c; 43 | Point p; 44 | uchar *s; 45 | Fontchar *i; 46 | int w, width; 47 | 48 | p = Pt(0, f->height); 49 | s = (uchar*)cs; 50 | for(; (c=*s); p.x+=width){ 51 | width = 0; 52 | if(c < Runeself) 53 | s++; 54 | else{ 55 | w = chartorune(&c, (char*)s); 56 | if(w == 0){ 57 | s++; 58 | continue; 59 | } 60 | s += w; 61 | } 62 | if(c >= f->n) 63 | continue; 64 | i = f->info+c; 65 | width = i->width; 66 | } 67 | return p; 68 | } 69 | -------------------------------------------------------------------------------- /libmemdraw/subfont.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | Memsubfont* 7 | allocmemsubfont(char *name, int n, int height, int ascent, Fontchar *info, Memimage *i) 8 | { 9 | Memsubfont *f; 10 | 11 | f = malloc(sizeof(Memsubfont)); 12 | if(f == 0) 13 | return 0; 14 | f->n = n; 15 | f->height = height; 16 | f->ascent = ascent; 17 | f->info = info; 18 | f->bits = i; 19 | if(name) 20 | f->name = strdup(name); 21 | else 22 | f->name = 0; 23 | return f; 24 | } 25 | 26 | void 27 | freememsubfont(Memsubfont *f) 28 | { 29 | if(f == 0) 30 | return; 31 | free(f->info); /* note: f->info must have been malloc'ed! */ 32 | freememimage(f->bits); 33 | free(f); 34 | } 35 | -------------------------------------------------------------------------------- /libmemdraw/times: -------------------------------------------------------------------------------- 1 | draw1: 6M for draw 0,0,100,100 no repl 2 | draw3: 4M for draw 0,0,100,100 no repl 3 | just read src, dst - 250k 4 | mask reading - 650k 5 | write dst - 100k 6 | alpha calculation - 3000k 7 | 8 | olddraw: 10M for draw 0, 0, 1000, 1000 no repl all ldepth 3 9 | 44M for draw 0, 0, 1000, 1000 src, mask ldepth 2 dst ldepth 3 10 | draw4: 160M for draw 0, 0, 1000, 1000 no repl all r8g8b8 11 | null loop: 10k 12 | src, dst reading: 13-15M each 13 | mask reading: 30M 14 | alpha calculation loop: 90M 15 | null alpha loop: 2M 16 | minimal loop control +20M 17 | alpha calculation with divides +190M 18 | alpha calculation wtih shifts +70M 19 | writeback: 11M 20 | -------------------------------------------------------------------------------- /libmemdraw/unload.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | int 7 | unloadmemimage(Memimage *i, Rectangle r, uchar *data, int ndata) 8 | { 9 | int y, l; 10 | uchar *q; 11 | 12 | if(!rectinrect(r, i->r)) 13 | return -1; 14 | l = bytesperline(r, i->depth); 15 | if(ndata < l*Dy(r)) 16 | return -1; 17 | ndata = l*Dy(r); 18 | q = byteaddr(i, r.min); 19 | for(y=r.min.y; ywidth*sizeof(ulong); 22 | data += l; 23 | } 24 | return ndata; 25 | } 26 | -------------------------------------------------------------------------------- /libmemlayer/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libmemlayer.a 4 | 5 | OFILES=\ 6 | draw.$O\ 7 | lalloc.$O\ 8 | layerop.$O\ 9 | ldelete.$O\ 10 | lhide.$O\ 11 | line.$O\ 12 | load.$O\ 13 | lorigin.$O\ 14 | lsetrefresh.$O\ 15 | ltofront.$O\ 16 | ltorear.$O\ 17 | unload.$O 18 | 19 | default: $(LIB) 20 | $(LIB): $(OFILES) 21 | $(AR) r $(LIB) $(OFILES) 22 | $(RANLIB) $(LIB) 23 | 24 | %.$O: %.c 25 | $(CC) $(CFLAGS) $*.c 26 | 27 | -------------------------------------------------------------------------------- /libmemlayer/ldelete.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void 8 | memldelete(Memimage *i) 9 | { 10 | Memscreen *s; 11 | Memlayer *l; 12 | 13 | l = i->layer; 14 | /* free backing store and disconnect refresh, to make pushback fast */ 15 | freememimage(l->save); 16 | l->save = nil; 17 | l->refreshptr = nil; 18 | memltorear(i); 19 | 20 | /* window is now the rearmost; clean up screen structures and deallocate */ 21 | s = i->layer->screen; 22 | if(s->fill){ 23 | i->clipr = i->r; 24 | memdraw(i, i->r, s->fill, i->r.min, nil, i->r.min, S); 25 | } 26 | if(l->front){ 27 | l->front->layer->rear = nil; 28 | s->rearmost = l->front; 29 | }else{ 30 | s->frontmost = nil; 31 | s->rearmost = nil; 32 | } 33 | free(l); 34 | freememimage(i); 35 | } 36 | 37 | /* 38 | * Just free the data structures, don't do graphics 39 | */ 40 | void 41 | memlfree(Memimage *i) 42 | { 43 | Memlayer *l; 44 | 45 | l = i->layer; 46 | freememimage(l->save); 47 | free(l); 48 | freememimage(i); 49 | } 50 | 51 | void 52 | _memlsetclear(Memscreen *s) 53 | { 54 | Memimage *i, *j; 55 | Memlayer *l; 56 | 57 | for(i=s->rearmost; i; i=i->layer->front){ 58 | l = i->layer; 59 | l->clear = rectinrect(l->screenr, l->screen->image->clipr); 60 | if(l->clear) 61 | for(j=l->front; j; j=j->layer->front) 62 | if(rectXrect(l->screenr, j->layer->screenr)){ 63 | l->clear = 0; 64 | break; 65 | } 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /libmemlayer/load.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int 8 | memload(Memimage *dst, Rectangle r, uchar *data, int n, int iscompressed) 9 | { 10 | int (*loadfn)(Memimage*, Rectangle, uchar*, int); 11 | Memimage *tmp; 12 | Memlayer *dl; 13 | Rectangle lr; 14 | int dx; 15 | 16 | loadfn = loadmemimage; 17 | if(iscompressed) 18 | loadfn = cloadmemimage; 19 | 20 | Top: 21 | dl = dst->layer; 22 | if(dl == nil) 23 | return loadfn(dst, r, data, n); 24 | 25 | /* 26 | * Convert to screen coordinates. 27 | */ 28 | lr = r; 29 | r.min.x += dl->delta.x; 30 | r.min.y += dl->delta.y; 31 | r.max.x += dl->delta.x; 32 | r.max.y += dl->delta.y; 33 | dx = dl->delta.x&(7/dst->depth); 34 | if(dl->clear && dx==0){ 35 | dst = dl->screen->image; 36 | goto Top; 37 | } 38 | 39 | /* 40 | * dst is an obscured layer or data is unaligned 41 | */ 42 | if(dl->save && dx==0){ 43 | n = loadfn(dl->save, lr, data, n); 44 | if(n > 0) 45 | memlexpose(dst, r); 46 | return n; 47 | } 48 | tmp = allocmemimage(lr, dst->chan); 49 | if(tmp == nil) 50 | return -1; 51 | n = loadfn(tmp, lr, data, n); 52 | memdraw(dst, lr, tmp, lr.min, nil, lr.min, S); 53 | freememimage(tmp); 54 | return n; 55 | } 56 | -------------------------------------------------------------------------------- /libmemlayer/lsetrefresh.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int 8 | memlsetrefresh(Memimage *i, Refreshfn fn, void *ptr) 9 | { 10 | Memlayer *l; 11 | 12 | l = i->layer; 13 | if(l->refreshfn!=0 && fn!=0){ /* just change functions */ 14 | l->refreshfn = fn; 15 | l->refreshptr = ptr; 16 | return 1; 17 | } 18 | 19 | if(l->refreshfn == 0){ /* is using backup image; just free it */ 20 | freememimage(l->save); 21 | l->save = nil; 22 | l->refreshfn = fn; 23 | l->refreshptr = ptr; 24 | return 1; 25 | } 26 | 27 | l->save = allocmemimage(i->r, i->chan); 28 | if(l->save == nil) 29 | return 0; 30 | /* easiest way is just to update the entire save area */ 31 | l->refreshfn(i, i->r, l->refreshptr); 32 | l->refreshfn = 0; 33 | l->refreshptr = nil; 34 | return 1; 35 | } 36 | -------------------------------------------------------------------------------- /libmemlayer/ltofront.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | /* 8 | * Pull i towards top of screen, just behind front 9 | */ 10 | static 11 | void 12 | _memltofront(Memimage *i, Memimage *front, int fill) 13 | { 14 | Memlayer *l; 15 | Memscreen *s; 16 | Memimage *f, *ff, *rr; 17 | Rectangle x; 18 | int overlap; 19 | 20 | l = i->layer; 21 | s = l->screen; 22 | while(l->front != front){ 23 | f = l->front; 24 | x = l->screenr; 25 | overlap = rectclip(&x, f->layer->screenr); 26 | if(overlap){ 27 | memlhide(f, x); 28 | f->layer->clear = 0; 29 | } 30 | /* swap l and f in screen's list */ 31 | ff = f->layer->front; 32 | rr = l->rear; 33 | if(ff == nil) 34 | s->frontmost = i; 35 | else 36 | ff->layer->rear = i; 37 | if(rr == nil) 38 | s->rearmost = f; 39 | else 40 | rr->layer->front = f; 41 | l->front = ff; 42 | l->rear = f; 43 | f->layer->front = i; 44 | f->layer->rear = rr; 45 | if(overlap && fill) 46 | memlexpose(i, x); 47 | } 48 | } 49 | 50 | void 51 | _memltofrontfill(Memimage *i, int fill) 52 | { 53 | _memltofront(i, nil, fill); 54 | _memlsetclear(i->layer->screen); 55 | } 56 | 57 | void 58 | memltofront(Memimage *i) 59 | { 60 | _memltofront(i, nil, 1); 61 | _memlsetclear(i->layer->screen); 62 | } 63 | 64 | void 65 | memltofrontn(Memimage **ip, int n) 66 | { 67 | Memimage *i, *front; 68 | Memscreen *s; 69 | 70 | if(n == 0) 71 | return; 72 | front = nil; 73 | while(--n >= 0){ 74 | i = *ip++; 75 | _memltofront(i, front, 1); 76 | front = i; 77 | } 78 | s = front->layer->screen; 79 | _memlsetclear(s); 80 | } 81 | -------------------------------------------------------------------------------- /libmemlayer/ltorear.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | void 8 | _memltorear(Memimage *i, Memimage *rear) 9 | { 10 | Memlayer *l; 11 | Memscreen *s; 12 | Memimage *f, *r, *rr; 13 | Rectangle x; 14 | int overlap; 15 | 16 | l = i->layer; 17 | s = l->screen; 18 | while(l->rear != rear){ 19 | r = l->rear; 20 | x = l->screenr; 21 | overlap = rectclip(&x, r->layer->screenr); 22 | if(overlap){ 23 | memlhide(i, x); 24 | l->clear = 0; 25 | } 26 | /* swap l and r in screen's list */ 27 | rr = r->layer->rear; 28 | f = l->front; 29 | if(rr == nil) 30 | s->rearmost = i; 31 | else 32 | rr->layer->front = i; 33 | if(f == nil) 34 | s->frontmost = r; 35 | else 36 | f->layer->rear = r; 37 | l->rear = rr; 38 | l->front = r; 39 | r->layer->rear = i; 40 | r->layer->front = f; 41 | if(overlap) 42 | memlexpose(r, x); 43 | } 44 | } 45 | 46 | void 47 | memltorear(Memimage *i) 48 | { 49 | _memltorear(i, nil); 50 | _memlsetclear(i->layer->screen); 51 | } 52 | 53 | void 54 | memltorearn(Memimage **ip, int n) 55 | { 56 | Memimage *i, *rear; 57 | Memscreen *s; 58 | 59 | if(n == 0) 60 | return; 61 | rear = nil; 62 | while(--n >= 0){ 63 | i = *ip++; 64 | _memltorear(i, rear); 65 | rear = i; 66 | } 67 | s = rear->layer->screen; 68 | _memlsetclear(s); 69 | } 70 | -------------------------------------------------------------------------------- /libmemlayer/unload.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | int 8 | memunload(Memimage *src, Rectangle r, uchar *data, int n) 9 | { 10 | Memimage *tmp; 11 | Memlayer *dl; 12 | Rectangle lr; 13 | int dx; 14 | 15 | Top: 16 | dl = src->layer; 17 | if(dl == nil) 18 | return unloadmemimage(src, r, data, n); 19 | 20 | /* 21 | * Convert to screen coordinates. 22 | */ 23 | lr = r; 24 | r.min.x += dl->delta.x; 25 | r.min.y += dl->delta.y; 26 | r.max.x += dl->delta.x; 27 | r.max.y += dl->delta.y; 28 | dx = dl->delta.x&(7/src->depth); 29 | if(dl->clear && dx==0){ 30 | src = dl->screen->image; 31 | goto Top; 32 | } 33 | 34 | /* 35 | * src is an obscured layer or data is unaligned 36 | */ 37 | if(dl->save && dx==0){ 38 | if(dl->refreshfn != 0) 39 | return -1; /* can't unload window if it's not Refbackup */ 40 | if(n > 0) 41 | memlhide(src, r); 42 | n = unloadmemimage(dl->save, lr, data, n); 43 | return n; 44 | } 45 | tmp = allocmemimage(lr, src->chan); 46 | if(tmp == nil) 47 | return -1; 48 | memdraw(tmp, lr, src, lr.min, nil, lr.min, S); 49 | n = unloadmemimage(tmp, lr, data, n); 50 | freememimage(tmp); 51 | return n; 52 | } 53 | -------------------------------------------------------------------------------- /libmp/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | # N.B. This is used only for secstore. It needn't be fast. 4 | 5 | LIB=libmp.a 6 | 7 | OFILES=\ 8 | betomp.$O\ 9 | crt.$O\ 10 | letomp.$O\ 11 | mpadd.$O\ 12 | mpaux.$O\ 13 | mpcmp.$O\ 14 | mpfactorial.$O\ 15 | mpdigdiv.$O\ 16 | mpdiv.$O\ 17 | mpeuclid.$O\ 18 | mpexp.$O\ 19 | mpextendedgcd.$O\ 20 | mpfmt.$O\ 21 | mpinvert.$O\ 22 | mpleft.$O\ 23 | mpmod.$O\ 24 | mpmul.$O\ 25 | mprand.$O\ 26 | mpright.$O\ 27 | mpsub.$O\ 28 | mptobe.$O\ 29 | mptoi.$O\ 30 | mptole.$O\ 31 | mptoui.$O\ 32 | mptouv.$O\ 33 | mptov.$O\ 34 | mpvecadd.$O\ 35 | mpveccmp.$O\ 36 | mpvecdigmuladd.$O\ 37 | mpvecsub.$O\ 38 | strtomp.$O 39 | 40 | default: $(LIB) 41 | $(LIB): $(OFILES) 42 | $(AR) r $(LIB) $(OFILES) 43 | $(RANLIB) $(LIB) 44 | 45 | %.$O: %.c 46 | $(CC) $(CFLAGS) $*.c 47 | 48 | -------------------------------------------------------------------------------- /libmp/betomp.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // convert a big-endian byte array (most significant byte first) to an mpint 6 | mpint* 7 | betomp(uchar *p, uint n, mpint *b) 8 | { 9 | int m, s; 10 | mpdigit x; 11 | 12 | if(b == nil){ 13 | b = mpnew(0); 14 | setmalloctag(b, getcallerpc(&p)); 15 | } 16 | 17 | // dump leading zeros 18 | while(*p == 0 && n > 1){ 19 | p++; 20 | n--; 21 | } 22 | 23 | // get the space 24 | mpbits(b, n*8); 25 | b->top = DIGITS(n*8); 26 | m = b->top-1; 27 | 28 | // first digit might not be Dbytes long 29 | s = ((n-1)*8)%Dbits; 30 | x = 0; 31 | for(; n > 0; n--){ 32 | x |= ((mpdigit)(*p++)) << s; 33 | s -= 8; 34 | if(s < 0){ 35 | b->p[m--] = x; 36 | s = Dbits-8; 37 | x = 0; 38 | } 39 | } 40 | 41 | return b; 42 | } 43 | -------------------------------------------------------------------------------- /libmp/crttest.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | void 6 | testcrt(mpint **p) 7 | { 8 | CRTpre *crt; 9 | CRTres *res; 10 | mpint *m, *x, *y; 11 | 12 | fmtinstall('B', mpfmt); 13 | 14 | // get a modulus and a test number 15 | m = mpnew(1024+160); 16 | mpmul(p[0], p[1], m); 17 | x = mpnew(1024+160); 18 | mpadd(m, mpone, x); 19 | 20 | // do the precomputation for crt conversion 21 | crt = crtpre(2, p); 22 | 23 | // convert x to residues 24 | res = crtin(crt, x); 25 | 26 | // convert back 27 | y = mpnew(1024+160); 28 | crtout(crt, res, y); 29 | print("x %B\ny %B\n", x, y); 30 | mpfree(m); 31 | mpfree(x); 32 | mpfree(y); 33 | } 34 | 35 | void 36 | main(void) 37 | { 38 | int i; 39 | mpint *p[2]; 40 | long start; 41 | 42 | start = time(0); 43 | for(i = 0; i < 10; i++){ 44 | p[0] = mpnew(1024); 45 | p[1] = mpnew(1024); 46 | DSAprimes(p[0], p[1], nil); 47 | testcrt(p); 48 | mpfree(p[0]); 49 | mpfree(p[1]); 50 | } 51 | print("%ld secs with more\n", time(0)-start); 52 | exits(0); 53 | } 54 | -------------------------------------------------------------------------------- /libmp/dat.h: -------------------------------------------------------------------------------- 1 | #define mpdighi (mpdigit)(1U<<(Dbits-1)) 2 | #define DIGITS(x) ((Dbits - 1 + (x))/Dbits) 3 | 4 | // for converting between int's and mpint's 5 | #define MAXUINT ((uint)-1) 6 | #define MAXINT (MAXUINT>>1) 7 | #define MININT (MAXINT+1) 8 | 9 | // for converting between vlongs's and mpint's 10 | #define MAXUVLONG (~0ULL) 11 | #define MAXVLONG (MAXUVLONG>>1) 12 | #define MINVLONG (MAXVLONG+1ULL) 13 | -------------------------------------------------------------------------------- /libmp/letomp.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // convert a little endian byte array (least significant byte first) to an mpint 6 | mpint* 7 | letomp(uchar *s, uint n, mpint *b) 8 | { 9 | int i=0, m = 0; 10 | mpdigit x=0; 11 | 12 | if(b == nil) 13 | b = mpnew(0); 14 | mpbits(b, 8*n); 15 | for(; n > 0; n--){ 16 | x |= ((mpdigit)(*s++)) << i; 17 | i += 8; 18 | if(i == Dbits){ 19 | b->p[m++] = x; 20 | i = 0; 21 | x = 0; 22 | } 23 | } 24 | if(i > 0) 25 | b->p[m++] = x; 26 | b->top = m; 27 | return b; 28 | } 29 | -------------------------------------------------------------------------------- /libmp/mpadd.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // sum = abs(b1) + abs(b2), i.e., add the magnitudes 6 | void 7 | mpmagadd(mpint *b1, mpint *b2, mpint *sum) 8 | { 9 | int m, n; 10 | mpint *t; 11 | 12 | // get the sizes right 13 | if(b2->top > b1->top){ 14 | t = b1; 15 | b1 = b2; 16 | b2 = t; 17 | } 18 | n = b1->top; 19 | m = b2->top; 20 | if(n == 0){ 21 | mpassign(mpzero, sum); 22 | return; 23 | } 24 | if(m == 0){ 25 | mpassign(b1, sum); 26 | return; 27 | } 28 | mpbits(sum, (n+1)*Dbits); 29 | sum->top = n+1; 30 | 31 | mpvecadd(b1->p, n, b2->p, m, sum->p); 32 | sum->sign = 1; 33 | 34 | mpnorm(sum); 35 | } 36 | 37 | // sum = b1 + b2 38 | void 39 | mpadd(mpint *b1, mpint *b2, mpint *sum) 40 | { 41 | int sign; 42 | 43 | if(b1->sign != b2->sign){ 44 | if(b1->sign < 0) 45 | mpmagsub(b2, b1, sum); 46 | else 47 | mpmagsub(b1, b2, sum); 48 | } else { 49 | sign = b1->sign; 50 | mpmagadd(b1, b2, sum); 51 | if(sum->top != 0) 52 | sum->sign = sign; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /libmp/mpcmp.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // return neg, 0, pos as abs(b1)-abs(b2) is neg, 0, pos 6 | int 7 | mpmagcmp(mpint *b1, mpint *b2) 8 | { 9 | int i; 10 | 11 | i = b1->top - b2->top; 12 | if(i) 13 | return i; 14 | 15 | return mpveccmp(b1->p, b1->top, b2->p, b2->top); 16 | } 17 | 18 | // return neg, 0, pos as b1-b2 is neg, 0, pos 19 | int 20 | mpcmp(mpint *b1, mpint *b2) 21 | { 22 | if(b1->sign != b2->sign) 23 | return b1->sign - b2->sign; 24 | if(b1->sign < 0) 25 | return mpmagcmp(b2, b1); 26 | else 27 | return mpmagcmp(b1, b2); 28 | } 29 | -------------------------------------------------------------------------------- /libmp/mpdigdiv.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // 6 | // divide two digits by one and return quotient 7 | // 8 | void 9 | mpdigdiv(mpdigit *dividend, mpdigit divisor, mpdigit *quotient) 10 | { 11 | mpdigit hi, lo, q, x, y; 12 | int i; 13 | 14 | hi = dividend[1]; 15 | lo = dividend[0]; 16 | 17 | // return highest digit value if the result >= 2**32 18 | if(hi >= divisor || divisor == 0){ 19 | divisor = 0; 20 | *quotient = ~divisor; 21 | return; 22 | } 23 | 24 | // at this point we know that hi < divisor 25 | // just shift and subtract till we're done 26 | q = 0; 27 | x = divisor; 28 | for(i = Dbits-1; hi > 0 && i >= 0; i--){ 29 | x >>= 1; 30 | if(x > hi) 31 | continue; 32 | y = divisor< lo) 34 | continue; 35 | if(y > lo) 36 | hi--; 37 | lo -= y; 38 | hi -= x; 39 | q |= 1< 3 | 4 | // extended euclid 5 | // 6 | // For a and b it solves, d = gcd(a,b) and finds x and y s.t. 7 | // ax + by = d 8 | // 9 | // Handbook of Applied Cryptography, Menezes et al, 1997, pg 67 10 | 11 | void 12 | mpeuclid(mpint *a, mpint *b, mpint *d, mpint *x, mpint *y) 13 | { 14 | mpint *tmp, *x0, *x1, *x2, *y0, *y1, *y2, *q, *r; 15 | 16 | if(a->sign<0 || b->sign<0) 17 | sysfatal("mpeuclid: negative arg"); 18 | 19 | if(mpcmp(a, b) < 0){ 20 | tmp = a; 21 | a = b; 22 | b = tmp; 23 | tmp = x; 24 | x = y; 25 | y = tmp; 26 | } 27 | 28 | if(b->top == 0){ 29 | mpassign(a, d); 30 | mpassign(mpone, x); 31 | mpassign(mpzero, y); 32 | return; 33 | } 34 | 35 | a = mpcopy(a); 36 | b = mpcopy(b); 37 | x0 = mpnew(0); 38 | x1 = mpcopy(mpzero); 39 | x2 = mpcopy(mpone); 40 | y0 = mpnew(0); 41 | y1 = mpcopy(mpone); 42 | y2 = mpcopy(mpzero); 43 | q = mpnew(0); 44 | r = mpnew(0); 45 | 46 | while(b->top != 0 && b->sign > 0){ 47 | // q = a/b 48 | // r = a mod b 49 | mpdiv(a, b, q, r); 50 | // x0 = x2 - qx1 51 | mpmul(q, x1, x0); 52 | mpsub(x2, x0, x0); 53 | // y0 = y2 - qy1 54 | mpmul(q, y1, y0); 55 | mpsub(y2, y0, y0); 56 | // rotate values 57 | tmp = a; 58 | a = b; 59 | b = r; 60 | r = tmp; 61 | tmp = x2; 62 | x2 = x1; 63 | x1 = x0; 64 | x0 = tmp; 65 | tmp = y2; 66 | y2 = y1; 67 | y1 = y0; 68 | y0 = tmp; 69 | } 70 | 71 | mpassign(a, d); 72 | mpassign(x2, x); 73 | mpassign(y2, y); 74 | 75 | mpfree(x0); 76 | mpfree(x1); 77 | mpfree(x2); 78 | mpfree(y0); 79 | mpfree(y1); 80 | mpfree(y2); 81 | mpfree(q); 82 | mpfree(r); 83 | mpfree(a); 84 | mpfree(b); 85 | } 86 | -------------------------------------------------------------------------------- /libmp/mpexp.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // res = b**e 6 | // 7 | // knuth, vol 2, pp 398-400 8 | 9 | enum { 10 | Freeb= 0x1, 11 | Freee= 0x2, 12 | Freem= 0x4, 13 | }; 14 | 15 | //int expdebug; 16 | 17 | void 18 | mpexp(mpint *b, mpint *e, mpint *m, mpint *res) 19 | { 20 | mpint *t[2]; 21 | int tofree; 22 | mpdigit d, bit; 23 | int i, j; 24 | 25 | i = mpcmp(e,mpzero); 26 | if(i==0){ 27 | mpassign(mpone, res); 28 | return; 29 | } 30 | if(i<0) 31 | sysfatal("mpexp: negative exponent"); 32 | 33 | t[0] = mpcopy(b); 34 | t[1] = res; 35 | 36 | tofree = 0; 37 | if(res == b){ 38 | b = mpcopy(b); 39 | tofree |= Freeb; 40 | } 41 | if(res == e){ 42 | e = mpcopy(e); 43 | tofree |= Freee; 44 | } 45 | if(res == m){ 46 | m = mpcopy(m); 47 | tofree |= Freem; 48 | } 49 | 50 | // skip first bit 51 | i = e->top-1; 52 | d = e->p[i]; 53 | for(bit = mpdighi; (bit & d) == 0; bit >>= 1) 54 | ; 55 | bit >>= 1; 56 | 57 | j = 0; 58 | for(;;){ 59 | for(; bit != 0; bit >>= 1){ 60 | mpmul(t[j], t[j], t[j^1]); 61 | if(bit & d) 62 | mpmul(t[j^1], b, t[j]); 63 | else 64 | j ^= 1; 65 | if(m != nil && t[j]->top > m->top){ 66 | mpmod(t[j], m, t[j^1]); 67 | j ^= 1; 68 | } 69 | } 70 | if(--i < 0) 71 | break; 72 | bit = mpdighi; 73 | d = e->p[i]; 74 | } 75 | if(m != nil){ 76 | mpmod(t[j], m, t[j^1]); 77 | j ^= 1; 78 | } 79 | if(t[j] == res){ 80 | mpfree(t[j^1]); 81 | } else { 82 | mpassign(t[j], res); 83 | mpfree(t[j]); 84 | } 85 | 86 | if(tofree){ 87 | if(tofree & Freeb) 88 | mpfree(b); 89 | if(tofree & Freee) 90 | mpfree(e); 91 | if(tofree & Freem) 92 | mpfree(m); 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /libmp/mpfactorial.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | #include "dat.h" 5 | 6 | mpint* 7 | mpfactorial(ulong n) 8 | { 9 | int i; 10 | ulong k; 11 | unsigned cnt; 12 | int max, mmax; 13 | mpdigit p, pp[2]; 14 | mpint *r, *s, *stk[31]; 15 | 16 | cnt = 0; 17 | max = mmax = -1; 18 | p = 1; 19 | r = mpnew(0); 20 | for(k=2; k<=n; k++){ 21 | pp[0] = 0; 22 | pp[1] = 0; 23 | mpvecdigmuladd(&p, 1, (mpdigit)k, pp); 24 | if(pp[1] == 0) /* !overflow */ 25 | p = pp[0]; 26 | else{ 27 | cnt++; 28 | if((cnt & 1) == 0){ 29 | s = stk[max]; 30 | mpbits(r, Dbits*(s->top+1+1)); 31 | memset(r->p, 0, Dbytes*(s->top+1+1)); 32 | mpvecmul(s->p, s->top, &p, 1, r->p); 33 | r->sign = 1; 34 | r->top = s->top+1+1; /* XXX: norm */ 35 | mpassign(r, s); 36 | for(i=4; (cnt & (i-1)) == 0; i=i<<1){ 37 | mpmul(stk[max], stk[max-1], r); 38 | mpassign(r, stk[max-1]); 39 | max--; 40 | } 41 | }else{ 42 | max++; 43 | if(max > mmax){ 44 | mmax++; 45 | if(max >= nelem(stk)) 46 | abort(); 47 | stk[max] = mpnew(Dbits); 48 | } 49 | stk[max]->top = 1; 50 | stk[max]->p[0] = p; 51 | } 52 | p = (mpdigit)k; 53 | } 54 | } 55 | if(max < 0){ 56 | mpbits(r, Dbits); 57 | r->top = 1; 58 | r->sign = 1; 59 | r->p[0] = p; 60 | }else{ 61 | s = stk[max--]; 62 | mpbits(r, Dbits*(s->top+1+1)); 63 | memset(r->p, 0, Dbytes*(s->top+1+1)); 64 | mpvecmul(s->p, s->top, &p, 1, r->p); 65 | r->sign = 1; 66 | r->top = s->top+1+1; /* XXX: norm */ 67 | } 68 | 69 | while(max >= 0) 70 | mpmul(r, stk[max--], r); 71 | for(max=mmax; max>=0; max--) 72 | mpfree(stk[max]); 73 | mpnorm(r); 74 | return r; 75 | } 76 | -------------------------------------------------------------------------------- /libmp/mpinvert.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | 4 | #define iseven(a) (((a)->p[0] & 1) == 0) 5 | 6 | // use extended gcd to find the multiplicative inverse 7 | // res = b**-1 mod m 8 | void 9 | mpinvert(mpint *b, mpint *m, mpint *res) 10 | { 11 | mpint *dc1, *dc2; // don't care 12 | 13 | dc1 = mpnew(0); 14 | dc2 = mpnew(0); 15 | mpextendedgcd(b, m, dc1, res, dc2); 16 | if(mpcmp(dc1, mpone) != 0) 17 | abort(); 18 | mpmod(res, m, res); 19 | mpfree(dc1); 20 | mpfree(dc2); 21 | } 22 | -------------------------------------------------------------------------------- /libmp/mpleft.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // res = b << shift 6 | void 7 | mpleft(mpint *b, int shift, mpint *res) 8 | { 9 | int d, l, r, i, otop; 10 | mpdigit this, last; 11 | 12 | res->sign = b->sign; 13 | if(b->top==0){ 14 | res->top = 0; 15 | return; 16 | } 17 | 18 | // a negative left shift is a right shift 19 | if(shift < 0){ 20 | mpright(b, -shift, res); 21 | return; 22 | } 23 | 24 | // b and res may be the same so remember the old top 25 | otop = b->top; 26 | 27 | // shift 28 | mpbits(res, otop*Dbits + shift); // overkill 29 | res->top = DIGITS(otop*Dbits + shift); 30 | d = shift/Dbits; 31 | l = shift - d*Dbits; 32 | r = Dbits - l; 33 | 34 | if(l == 0){ 35 | for(i = otop-1; i >= 0; i--) 36 | res->p[i+d] = b->p[i]; 37 | } else { 38 | last = 0; 39 | for(i = otop-1; i >= 0; i--) { 40 | this = b->p[i]; 41 | res->p[i+d+1] = (last<>r); 42 | last = this; 43 | } 44 | res->p[d] = last<p[i] = 0; 48 | 49 | // normalize 50 | while(res->top > 0 && res->p[res->top-1] == 0) 51 | res->top--; 52 | } 53 | -------------------------------------------------------------------------------- /libmp/mpmod.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // remainder = b mod m 6 | // 7 | // knuth, vol 2, pp 398-400 8 | 9 | void 10 | mpmod(mpint *b, mpint *m, mpint *remainder) 11 | { 12 | mpdiv(b, m, nil, remainder); 13 | if(remainder->sign < 0) 14 | mpadd(m, remainder, remainder); 15 | } 16 | -------------------------------------------------------------------------------- /libmp/mprand.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | #include "dat.h" 5 | 6 | mpint* 7 | mprand(int bits, void (*gen)(uchar*, int), mpint *b) 8 | { 9 | int n, m; 10 | mpdigit mask; 11 | uchar *p; 12 | 13 | n = DIGITS(bits); 14 | if(b == nil) 15 | b = mpnew(bits); 16 | else 17 | mpbits(b, bits); 18 | 19 | p = malloc(n*Dbytes); 20 | if(p == nil) 21 | return nil; 22 | (*gen)(p, n*Dbytes); 23 | betomp(p, n*Dbytes, b); 24 | free(p); 25 | 26 | // make sure we don't give too many bits 27 | m = bits%Dbits; 28 | n--; 29 | if(m > 0){ 30 | mask = 1; 31 | mask <<= m; 32 | mask--; 33 | b->p[n] &= mask; 34 | } 35 | 36 | for(; n >= 0; n--) 37 | if(b->p[n] != 0) 38 | break; 39 | b->top = n+1; 40 | b->sign = 1; 41 | return b; 42 | } 43 | -------------------------------------------------------------------------------- /libmp/mpright.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // res = b >> shift 6 | void 7 | mpright(mpint *b, int shift, mpint *res) 8 | { 9 | int d, l, r, i; 10 | mpdigit this, last; 11 | 12 | res->sign = b->sign; 13 | if(b->top==0){ 14 | res->top = 0; 15 | return; 16 | } 17 | 18 | // a negative right shift is a left shift 19 | if(shift < 0){ 20 | mpleft(b, -shift, res); 21 | return; 22 | } 23 | 24 | if(res != b) 25 | mpbits(res, b->top*Dbits - shift); 26 | d = shift/Dbits; 27 | r = shift - d*Dbits; 28 | l = Dbits - r; 29 | 30 | // shift all the bits out == zero 31 | if(d>=b->top){ 32 | res->top = 0; 33 | return; 34 | } 35 | 36 | // special case digit shifts 37 | if(r == 0){ 38 | for(i = 0; i < b->top-d; i++) 39 | res->p[i] = b->p[i+d]; 40 | } else { 41 | last = b->p[d]; 42 | for(i = 0; i < b->top-d-1; i++){ 43 | this = b->p[i+d+1]; 44 | res->p[i] = (this<>r); 45 | last = this; 46 | } 47 | res->p[i++] = last>>r; 48 | } 49 | while(i > 0 && res->p[i-1] == 0) 50 | i--; 51 | res->top = i; 52 | if(i==0) 53 | res->sign = 1; 54 | } 55 | -------------------------------------------------------------------------------- /libmp/mpsub.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // diff = abs(b1) - abs(b2), i.e., subtract the magnitudes 6 | void 7 | mpmagsub(mpint *b1, mpint *b2, mpint *diff) 8 | { 9 | int n, m, sign; 10 | mpint *t; 11 | 12 | // get the sizes right 13 | if(mpmagcmp(b1, b2) < 0){ 14 | sign = -1; 15 | t = b1; 16 | b1 = b2; 17 | b2 = t; 18 | } else 19 | sign = 1; 20 | n = b1->top; 21 | m = b2->top; 22 | if(m == 0){ 23 | mpassign(b1, diff); 24 | diff->sign = sign; 25 | return; 26 | } 27 | mpbits(diff, n*Dbits); 28 | 29 | mpvecsub(b1->p, n, b2->p, m, diff->p); 30 | diff->sign = sign; 31 | diff->top = n; 32 | mpnorm(diff); 33 | } 34 | 35 | // diff = b1 - b2 36 | void 37 | mpsub(mpint *b1, mpint *b2, mpint *diff) 38 | { 39 | int sign; 40 | 41 | if(b1->sign != b2->sign){ 42 | sign = b1->sign; 43 | mpmagadd(b1, b2, diff); 44 | diff->sign = sign; 45 | return; 46 | } 47 | 48 | sign = b1->sign; 49 | mpmagsub(b1, b2, diff); 50 | if(diff->top != 0) 51 | diff->sign *= sign; 52 | } 53 | -------------------------------------------------------------------------------- /libmp/mptobe.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // convert an mpint into a big endian byte array (most significant byte first) 6 | // return number of bytes converted 7 | // if p == nil, allocate and result array 8 | int 9 | mptobe(mpint *b, uchar *p, uint n, uchar **pp) 10 | { 11 | int i, j, suppress; 12 | mpdigit x; 13 | uchar *e, *s, c; 14 | 15 | if(p == nil){ 16 | n = (b->top+1)*Dbytes; 17 | p = malloc(n); 18 | setmalloctag(p, getcallerpc(&b)); 19 | } 20 | if(p == nil) 21 | return -1; 22 | if(pp != nil) 23 | *pp = p; 24 | memset(p, 0, n); 25 | 26 | // special case 0 27 | if(b->top == 0){ 28 | if(n < 1) 29 | return -1; 30 | else 31 | return 1; 32 | } 33 | 34 | s = p; 35 | e = s+n; 36 | suppress = 1; 37 | for(i = b->top-1; i >= 0; i--){ 38 | x = b->p[i]; 39 | for(j = Dbits-8; j >= 0; j -= 8){ 40 | c = x>>j; 41 | if(c == 0 && suppress) 42 | continue; 43 | if(p >= e) 44 | return -1; 45 | *p++ = c; 46 | suppress = 0; 47 | } 48 | } 49 | 50 | // guarantee at least one byte 51 | if(s == p){ 52 | if(p >= e) 53 | return -1; 54 | *p++ = 0; 55 | } 56 | 57 | return p - s; 58 | } 59 | -------------------------------------------------------------------------------- /libmp/mptoi.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | /* 6 | * this code assumes that mpdigit is at least as 7 | * big as an int. 8 | */ 9 | 10 | mpint* 11 | itomp(int i, mpint *b) 12 | { 13 | if(b == nil) 14 | b = mpnew(0); 15 | mpassign(mpzero, b); 16 | if(i != 0) 17 | b->top = 1; 18 | if(i < 0){ 19 | b->sign = -1; 20 | *b->p = -i; 21 | } else 22 | *b->p = i; 23 | return b; 24 | } 25 | 26 | int 27 | mptoi(mpint *b) 28 | { 29 | uint x; 30 | 31 | if(b->top==0) 32 | return 0; 33 | x = *b->p; 34 | if(b->sign > 0){ 35 | if(b->top > 1 || (x > MAXINT)) 36 | x = (int)MAXINT; 37 | else 38 | x = (int)x; 39 | } else { 40 | if(b->top > 1 || x > MAXINT+1) 41 | x = (int)MININT; 42 | else 43 | x = -(int)x; 44 | } 45 | return x; 46 | } 47 | -------------------------------------------------------------------------------- /libmp/mptole.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // convert an mpint into a little endian byte array (least significant byte first) 6 | 7 | // return number of bytes converted 8 | // if p == nil, allocate and result array 9 | int 10 | mptole(mpint *b, uchar *p, uint n, uchar **pp) 11 | { 12 | int i, j; 13 | mpdigit x; 14 | uchar *e, *s; 15 | 16 | if(p == nil){ 17 | n = (b->top+1)*Dbytes; 18 | p = malloc(n); 19 | } 20 | if(pp != nil) 21 | *pp = p; 22 | if(p == nil) 23 | return -1; 24 | memset(p, 0, n); 25 | 26 | // special case 0 27 | if(b->top == 0){ 28 | if(n < 1) 29 | return -1; 30 | else 31 | return 0; 32 | } 33 | 34 | s = p; 35 | e = s+n; 36 | for(i = 0; i < b->top-1; i++){ 37 | x = b->p[i]; 38 | for(j = 0; j < Dbytes; j++){ 39 | if(p >= e) 40 | return -1; 41 | *p++ = x; 42 | x >>= 8; 43 | } 44 | } 45 | x = b->p[i]; 46 | while(x > 0){ 47 | if(p >= e) 48 | return -1; 49 | *p++ = x; 50 | x >>= 8; 51 | } 52 | 53 | return p - s; 54 | } 55 | -------------------------------------------------------------------------------- /libmp/mptoui.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | /* 6 | * this code assumes that mpdigit is at least as 7 | * big as an int. 8 | */ 9 | 10 | mpint* 11 | uitomp(uint i, mpint *b) 12 | { 13 | if(b == nil) 14 | b = mpnew(0); 15 | mpassign(mpzero, b); 16 | if(i != 0) 17 | b->top = 1; 18 | *b->p = i; 19 | return b; 20 | } 21 | 22 | uint 23 | mptoui(mpint *b) 24 | { 25 | uint x; 26 | 27 | x = *b->p; 28 | if(b->sign < 0) 29 | x = 0; 30 | else if(b->top > 1 || (sizeof(mpdigit) > sizeof(uint) && x > MAXUINT)) 31 | x = MAXUINT; 32 | return x; 33 | } 34 | -------------------------------------------------------------------------------- /libmp/mptouv.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | #define VLDIGITS (sizeof(vlong)/sizeof(mpdigit)) 6 | 7 | /* 8 | * this code assumes that a vlong is an integral number of 9 | * mpdigits long. 10 | */ 11 | mpint* 12 | uvtomp(uvlong v, mpint *b) 13 | { 14 | int s; 15 | 16 | if(b == nil) 17 | b = mpnew(VLDIGITS*sizeof(mpdigit)); 18 | else 19 | mpbits(b, VLDIGITS*sizeof(mpdigit)); 20 | mpassign(mpzero, b); 21 | if(v == 0) 22 | return b; 23 | for(s = 0; s < VLDIGITS && v != 0; s++){ 24 | b->p[s] = v; 25 | v >>= sizeof(mpdigit)*8; 26 | } 27 | b->top = s; 28 | return b; 29 | } 30 | 31 | uvlong 32 | mptouv(mpint *b) 33 | { 34 | uvlong v; 35 | int s; 36 | 37 | if(b->top == 0) 38 | return 0LL; 39 | 40 | mpnorm(b); 41 | if(b->top > VLDIGITS) 42 | return MAXVLONG; 43 | 44 | v = 0ULL; 45 | for(s = 0; s < b->top; s++) 46 | v |= (uvlong)b->p[s]<<(s*sizeof(mpdigit)*8); 47 | 48 | return v; 49 | } 50 | -------------------------------------------------------------------------------- /libmp/mptov.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | #define VLDIGITS (sizeof(vlong)/sizeof(mpdigit)) 6 | 7 | /* 8 | * this code assumes that a vlong is an integral number of 9 | * mpdigits long. 10 | */ 11 | mpint* 12 | vtomp(vlong v, mpint *b) 13 | { 14 | int s; 15 | uvlong uv; 16 | 17 | if(b == nil) 18 | b = mpnew(VLDIGITS*sizeof(mpdigit)); 19 | else 20 | mpbits(b, VLDIGITS*sizeof(mpdigit)); 21 | mpassign(mpzero, b); 22 | if(v == 0) 23 | return b; 24 | if(v < 0){ 25 | b->sign = -1; 26 | uv = -v; 27 | } else 28 | uv = v; 29 | for(s = 0; s < VLDIGITS && uv != 0; s++){ 30 | b->p[s] = uv; 31 | uv >>= sizeof(mpdigit)*8; 32 | } 33 | b->top = s; 34 | return b; 35 | } 36 | 37 | vlong 38 | mptov(mpint *b) 39 | { 40 | uvlong v; 41 | int s; 42 | 43 | if(b->top == 0) 44 | return 0LL; 45 | 46 | mpnorm(b); 47 | if(b->top > VLDIGITS){ 48 | if(b->sign > 0) 49 | return (vlong)MAXVLONG; 50 | else 51 | return (vlong)MINVLONG; 52 | } 53 | 54 | v = 0ULL; 55 | for(s = 0; s < b->top; s++) 56 | v |= b->p[s]<<(s*sizeof(mpdigit)*8); 57 | 58 | if(b->sign > 0){ 59 | if(v > MAXVLONG) 60 | v = MAXVLONG; 61 | } else { 62 | if(v > MINVLONG) 63 | v = MINVLONG; 64 | else 65 | v = -(vlong)v; 66 | } 67 | 68 | return (vlong)v; 69 | } 70 | -------------------------------------------------------------------------------- /libmp/mpvecadd.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // prereq: alen >= blen, sum has at least blen+1 digits 6 | void 7 | mpvecadd(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *sum) 8 | { 9 | int i, carry; 10 | mpdigit x, y; 11 | 12 | carry = 0; 13 | for(i = 0; i < blen; i++){ 14 | x = *a++; 15 | y = *b++; 16 | x += carry; 17 | if(x < carry) 18 | carry = 1; 19 | else 20 | carry = 0; 21 | x += y; 22 | if(x < y) 23 | carry++; 24 | *sum++ = x; 25 | } 26 | for(; i < alen; i++){ 27 | x = *a++ + carry; 28 | if(x < carry) 29 | carry = 1; 30 | else 31 | carry = 0; 32 | *sum++ = x; 33 | } 34 | *sum = carry; 35 | } 36 | -------------------------------------------------------------------------------- /libmp/mpveccmp.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | int 6 | mpveccmp(mpdigit *a, int alen, mpdigit *b, int blen) 7 | { 8 | mpdigit x; 9 | 10 | while(alen > blen) 11 | if(a[--alen] != 0) 12 | return 1; 13 | while(blen > alen) 14 | if(b[--blen] != 0) 15 | return -1; 16 | while(alen > 0){ 17 | --alen; 18 | x = a[alen] - b[alen]; 19 | if(x == 0) 20 | continue; 21 | if(x > a[alen]) 22 | return -1; 23 | else 24 | return 1; 25 | } 26 | return 0; 27 | } 28 | -------------------------------------------------------------------------------- /libmp/mpvecsub.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include "dat.h" 4 | 5 | // prereq: a >= b, alen >= blen, diff has at least alen digits 6 | void 7 | mpvecsub(mpdigit *a, int alen, mpdigit *b, int blen, mpdigit *diff) 8 | { 9 | int i, borrow; 10 | mpdigit x, y; 11 | 12 | borrow = 0; 13 | for(i = 0; i < blen; i++){ 14 | x = *a++; 15 | y = *b++; 16 | y += borrow; 17 | if(y < borrow) 18 | borrow = 1; 19 | else 20 | borrow = 0; 21 | if(x < y) 22 | borrow++; 23 | *diff++ = x - y; 24 | } 25 | for(; i < alen; i++){ 26 | x = *a++; 27 | y = x - borrow; 28 | if(y > x) 29 | borrow = 1; 30 | else 31 | borrow = 0; 32 | *diff++ = y; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /libmp/os.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | -------------------------------------------------------------------------------- /libmp/reduce: -------------------------------------------------------------------------------- 1 | O=$1 2 | shift 3 | objtype=$1 4 | shift 5 | 6 | ls -p ../$objtype/*.[cs] >[2]/dev/null | sed 's/..$//' > /tmp/reduce.$pid 7 | # 8 | # if empty directory, just return the input files 9 | # 10 | if (! ~ $status '|') { 11 | echo $* 12 | rm /tmp/reduce.$pid 13 | exit 0 14 | } 15 | echo $* | tr ' ' \012 | grep -v -f /tmp/reduce.$pid | tr \012 ' ' 16 | rm /tmp/reduce.$pid 17 | -------------------------------------------------------------------------------- /libsec/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=libsec.a 4 | 5 | OFILES=\ 6 | aes.$O\ 7 | blowfish.$O\ 8 | chacha.$O\ 9 | decodepem.$O\ 10 | des.$O\ 11 | des3CBC.$O\ 12 | des3ECB.$O\ 13 | desCBC.$O\ 14 | desECB.$O\ 15 | desmodes.$O\ 16 | dsaalloc.$O\ 17 | dsagen.$O\ 18 | dsaprimes.$O\ 19 | dsaprivtopub.$O\ 20 | dsasign.$O\ 21 | dsaverify.$O\ 22 | egalloc.$O\ 23 | egdecrypt.$O\ 24 | egencrypt.$O\ 25 | eggen.$O\ 26 | egprivtopub.$O\ 27 | egsign.$O\ 28 | egverify.$O\ 29 | fastrand.$O\ 30 | genprime.$O\ 31 | genrandom.$O\ 32 | gensafeprime.$O\ 33 | genstrongprime.$O\ 34 | hmac.$O\ 35 | md4.$O\ 36 | md5.$O\ 37 | md5pickle.$O\ 38 | nfastrand.$O\ 39 | prng.$O\ 40 | probably_prime.$O\ 41 | rc4.$O\ 42 | rsaalloc.$O\ 43 | rsadecrypt.$O\ 44 | rsaencrypt.$O\ 45 | rsafill.$O\ 46 | rsagen.$O\ 47 | rsaprivtopub.$O\ 48 | sha1.$O\ 49 | sha1pickle.$O\ 50 | sha2_64.$O\ 51 | sha2block64.$O\ 52 | sha2_128.$O\ 53 | sha2block128.$O\ 54 | smallprimes.$O\ 55 | 56 | default: $(LIB) 57 | $(LIB): $(OFILES) 58 | $(AR) r $(LIB) $(OFILES) 59 | $(RANLIB) $(LIB) 60 | 61 | %.$O: %.c 62 | $(CC) $(CFLAGS) $*.c 63 | 64 | -------------------------------------------------------------------------------- /libsec/des3CBC.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // Because of the way that non multiple of 8 6 | // buffers are handled, the decryptor must 7 | // be fed buffers of the same size as the 8 | // encryptor 9 | 10 | 11 | // If the length is not a multiple of 8, I encrypt 12 | // the overflow to be compatible with lacy's cryptlib 13 | void 14 | des3CBCencrypt(uchar *p, int len, DES3state *s) 15 | { 16 | uchar *p2, *ip, *eip; 17 | 18 | for(; len >= 8; len -= 8){ 19 | p2 = p; 20 | ip = s->ivec; 21 | for(eip = ip+8; ip < eip; ) 22 | *p2++ ^= *ip++; 23 | triple_block_cipher(s->expanded, p, DES3EDE); 24 | memmove(s->ivec, p, 8); 25 | p += 8; 26 | } 27 | 28 | if(len > 0){ 29 | ip = s->ivec; 30 | triple_block_cipher(s->expanded, ip, DES3EDE); 31 | for(eip = ip+len; ip < eip; ) 32 | *p++ ^= *ip++; 33 | } 34 | } 35 | 36 | void 37 | des3CBCdecrypt(uchar *p, int len, DES3state *s) 38 | { 39 | uchar *ip, *eip, *tp; 40 | uchar tmp[8]; 41 | 42 | for(; len >= 8; len -= 8){ 43 | memmove(tmp, p, 8); 44 | triple_block_cipher(s->expanded, p, DES3DED); 45 | tp = tmp; 46 | ip = s->ivec; 47 | for(eip = ip+8; ip < eip; ){ 48 | *p++ ^= *ip; 49 | *ip++ = *tp++; 50 | } 51 | } 52 | 53 | if(len > 0){ 54 | ip = s->ivec; 55 | triple_block_cipher(s->expanded, ip, DES3EDE); 56 | for(eip = ip+len; ip < eip; ) 57 | *p++ ^= *ip++; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /libsec/des3ECB.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // I wasn't sure what to do when the buffer was not 6 | // a multiple of 8. I did what lacy's cryptolib did 7 | // to be compatible, but it looks dangerous to me 8 | // since its encrypting plain text with the key. -- presotto 9 | 10 | void 11 | des3ECBencrypt(uchar *p, int len, DES3state *s) 12 | { 13 | int i; 14 | uchar tmp[8]; 15 | 16 | for(; len >= 8; len -= 8){ 17 | triple_block_cipher(s->expanded, p, DES3EDE); 18 | p += 8; 19 | } 20 | 21 | if(len > 0){ 22 | for (i=0; i<8; i++) 23 | tmp[i] = i; 24 | triple_block_cipher(s->expanded, tmp, DES3EDE); 25 | for (i = 0; i < len; i++) 26 | p[i] ^= tmp[i]; 27 | } 28 | } 29 | 30 | void 31 | des3ECBdecrypt(uchar *p, int len, DES3state *s) 32 | { 33 | int i; 34 | uchar tmp[8]; 35 | 36 | for(; len >= 8; len -= 8){ 37 | triple_block_cipher(s->expanded, p, DES3DED); 38 | p += 8; 39 | } 40 | 41 | if(len > 0){ 42 | for (i=0; i<8; i++) 43 | tmp[i] = i; 44 | triple_block_cipher(s->expanded, tmp, DES3EDE); 45 | for (i = 0; i < len; i++) 46 | p[i] ^= tmp[i]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /libsec/desCBC.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // Because of the way that non multiple of 8 6 | // buffers are handled, the decryptor must 7 | // be fed buffers of the same size as the 8 | // encryptor 9 | 10 | 11 | // If the length is not a multiple of 8, I encrypt 12 | // the overflow to be compatible with lacy's cryptlib 13 | void 14 | desCBCencrypt(uchar *p, int len, DESstate *s) 15 | { 16 | uchar *p2, *ip, *eip; 17 | 18 | for(; len >= 8; len -= 8){ 19 | p2 = p; 20 | ip = s->ivec; 21 | for(eip = ip+8; ip < eip; ) 22 | *p2++ ^= *ip++; 23 | block_cipher(s->expanded, p, 0); 24 | memmove(s->ivec, p, 8); 25 | p += 8; 26 | } 27 | 28 | if(len > 0){ 29 | ip = s->ivec; 30 | block_cipher(s->expanded, ip, 0); 31 | for(eip = ip+len; ip < eip; ) 32 | *p++ ^= *ip++; 33 | } 34 | } 35 | 36 | void 37 | desCBCdecrypt(uchar *p, int len, DESstate *s) 38 | { 39 | uchar *ip, *eip, *tp; 40 | uchar tmp[8]; 41 | 42 | for(; len >= 8; len -= 8){ 43 | memmove(tmp, p, 8); 44 | block_cipher(s->expanded, p, 1); 45 | tp = tmp; 46 | ip = s->ivec; 47 | for(eip = ip+8; ip < eip; ){ 48 | *p++ ^= *ip; 49 | *ip++ = *tp++; 50 | } 51 | } 52 | 53 | if(len > 0){ 54 | ip = s->ivec; 55 | block_cipher(s->expanded, ip, 0); 56 | for(eip = ip+len; ip < eip; ) 57 | *p++ ^= *ip++; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /libsec/desECB.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // I wasn't sure what to do when the buffer was not 6 | // a multiple of 8. I did what lacy's cryptolib did 7 | // to be compatible, but it looks dangerous to me 8 | // since its encrypting plain text with the key. -- presotto 9 | 10 | void 11 | desECBencrypt(uchar *p, int len, DESstate *s) 12 | { 13 | int i; 14 | uchar tmp[8]; 15 | 16 | for(; len >= 8; len -= 8){ 17 | block_cipher(s->expanded, p, 0); 18 | p += 8; 19 | } 20 | 21 | if(len > 0){ 22 | for (i=0; i<8; i++) 23 | tmp[i] = i; 24 | block_cipher(s->expanded, tmp, 0); 25 | for (i = 0; i < len; i++) 26 | p[i] ^= tmp[i]; 27 | } 28 | } 29 | 30 | void 31 | desECBdecrypt(uchar *p, int len, DESstate *s) 32 | { 33 | int i; 34 | uchar tmp[8]; 35 | 36 | for(; len >= 8; len -= 8){ 37 | block_cipher(s->expanded, p, 1); 38 | p += 8; 39 | } 40 | 41 | if(len > 0){ 42 | for (i=0; i<8; i++) 43 | tmp[i] = i; 44 | block_cipher(s->expanded, tmp, 0); 45 | for (i = 0; i < len; i++) 46 | p[i] ^= tmp[i]; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /libsec/desmodes.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | 4 | /* 5 | * these routines use the 64bit format for 6 | * DES keys. 7 | */ 8 | 9 | void 10 | setupDESstate(DESstate *s, uchar key[8], uchar *ivec) 11 | { 12 | memset(s, 0, sizeof(*s)); 13 | memmove(s->key, key, sizeof(s->key)); 14 | des_key_setup(key, s->expanded); 15 | if(ivec) 16 | memmove(s->ivec, ivec, 8); 17 | s->setup = 0xdeadbeef; 18 | } 19 | 20 | void 21 | setupDES3state(DES3state *s, uchar key[3][8], uchar *ivec) 22 | { 23 | memset(s, 0, sizeof(*s)); 24 | memmove(s->key, key, sizeof(s->key)); 25 | des_key_setup(key[0], s->expanded[0]); 26 | des_key_setup(key[1], s->expanded[1]); 27 | des_key_setup(key[2], s->expanded[2]); 28 | if(ivec) 29 | memmove(s->ivec, ivec, 8); 30 | s->setup = 0xdeadbeef; 31 | } 32 | -------------------------------------------------------------------------------- /libsec/dsaalloc.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | DSApub* 6 | dsapuballoc(void) 7 | { 8 | DSApub *dsa; 9 | 10 | dsa = mallocz(sizeof(*dsa), 1); 11 | if(dsa == nil) 12 | sysfatal("dsapuballoc"); 13 | return dsa; 14 | } 15 | 16 | void 17 | dsapubfree(DSApub *dsa) 18 | { 19 | if(dsa == nil) 20 | return; 21 | mpfree(dsa->p); 22 | mpfree(dsa->q); 23 | mpfree(dsa->alpha); 24 | mpfree(dsa->key); 25 | free(dsa); 26 | } 27 | 28 | 29 | DSApriv* 30 | dsaprivalloc(void) 31 | { 32 | DSApriv *dsa; 33 | 34 | dsa = mallocz(sizeof(*dsa), 1); 35 | if(dsa == nil) 36 | sysfatal("dsaprivalloc"); 37 | return dsa; 38 | } 39 | 40 | void 41 | dsaprivfree(DSApriv *dsa) 42 | { 43 | if(dsa == nil) 44 | return; 45 | mpfree(dsa->pub.p); 46 | mpfree(dsa->pub.q); 47 | mpfree(dsa->pub.alpha); 48 | mpfree(dsa->pub.key); 49 | mpfree(dsa->secret); 50 | free(dsa); 51 | } 52 | 53 | DSAsig* 54 | dsasigalloc(void) 55 | { 56 | DSAsig *dsa; 57 | 58 | dsa = mallocz(sizeof(*dsa), 1); 59 | if(dsa == nil) 60 | sysfatal("dsasigalloc"); 61 | return dsa; 62 | } 63 | 64 | void 65 | dsasigfree(DSAsig *dsa) 66 | { 67 | if(dsa == nil) 68 | return; 69 | mpfree(dsa->r); 70 | mpfree(dsa->s); 71 | free(dsa); 72 | } 73 | -------------------------------------------------------------------------------- /libsec/dsagen.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | DSApriv* 6 | dsagen(DSApub *opub) 7 | { 8 | DSApub *pub; 9 | DSApriv *priv; 10 | mpint *exp; 11 | mpint *g; 12 | mpint *r; 13 | int bits; 14 | 15 | priv = dsaprivalloc(); 16 | pub = &priv->pub; 17 | 18 | if(opub != nil){ 19 | pub->p = mpcopy(opub->p); 20 | pub->q = mpcopy(opub->q); 21 | } else { 22 | pub->p = mpnew(0); 23 | pub->q = mpnew(0); 24 | DSAprimes(pub->q, pub->p, nil); 25 | } 26 | bits = Dbits*pub->p->top; 27 | 28 | pub->alpha = mpnew(0); 29 | pub->key = mpnew(0); 30 | priv->secret = mpnew(0); 31 | 32 | // find a generator alpha of the multiplicative 33 | // group Z*p, i.e., of order n = p-1. We use the 34 | // fact that q divides p-1 to reduce the exponent. 35 | exp = mpnew(0); 36 | g = mpnew(0); 37 | r = mpnew(0); 38 | mpsub(pub->p, mpone, exp); 39 | mpdiv(exp, pub->q, exp, r); 40 | if(mpcmp(r, mpzero) != 0) 41 | sysfatal("dsagen foul up"); 42 | while(1){ 43 | mprand(bits, genrandom, g); 44 | mpmod(g, pub->p, g); 45 | mpexp(g, exp, pub->p, pub->alpha); 46 | if(mpcmp(pub->alpha, mpone) != 0) 47 | break; 48 | } 49 | mpfree(g); 50 | mpfree(exp); 51 | 52 | // create the secret key 53 | mprand(bits, genrandom, priv->secret); 54 | mpmod(priv->secret, pub->p, priv->secret); 55 | mpexp(pub->alpha, priv->secret, pub->p, pub->key); 56 | 57 | return priv; 58 | } 59 | -------------------------------------------------------------------------------- /libsec/dsaprivtopub.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | DSApub* 6 | dsaprivtopub(DSApriv *priv) 7 | { 8 | DSApub *pub; 9 | 10 | pub = dsapuballoc(); 11 | pub->p = mpcopy(priv->pub.p); 12 | pub->q = mpcopy(priv->pub.q); 13 | pub->alpha = mpcopy(priv->pub.alpha); 14 | pub->key = mpcopy(priv->pub.key); 15 | return pub; 16 | } 17 | -------------------------------------------------------------------------------- /libsec/dsasign.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | DSAsig* 6 | dsasign(DSApriv *priv, mpint *m) 7 | { 8 | DSApub *pub = &priv->pub; 9 | DSAsig *sig; 10 | mpint *qm1, *k, *kinv, *r, *s; 11 | mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha; 12 | int qlen = mpsignif(q); 13 | 14 | qm1 = mpnew(0); 15 | kinv = mpnew(0); 16 | r = mpnew(0); 17 | s = mpnew(0); 18 | k = mpnew(0); 19 | mpsub(pub->q, mpone, qm1); 20 | 21 | // find a k that has an inverse mod q 22 | while(1){ 23 | mprand(qlen, genrandom, k); 24 | if((mpcmp(mpone, k) > 0) || (mpcmp(k, pub->q) >= 0)) 25 | continue; 26 | mpextendedgcd(k, q, r, kinv, s); 27 | if(mpcmp(r, mpone) != 0) 28 | sysfatal("dsasign: pub->q not prime"); 29 | break; 30 | } 31 | 32 | // make kinv positive 33 | mpmod(kinv, pub->q, kinv); 34 | 35 | // r = ((alpha**k) mod p) mod q 36 | mpexp(alpha, k, p, r); 37 | mpmod(r, q, r); 38 | 39 | // s = (kinv*(m + ar)) mod q 40 | mpmul(r, priv->secret, s); 41 | mpadd(s, m, s); 42 | mpmul(s, kinv, s); 43 | mpmod(s, q, s); 44 | 45 | sig = dsasigalloc(); 46 | sig->r = r; 47 | sig->s = s; 48 | mpfree(qm1); 49 | mpfree(k); 50 | mpfree(kinv); 51 | return sig; 52 | } 53 | -------------------------------------------------------------------------------- /libsec/dsaverify.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | int 6 | dsaverify(DSApub *pub, DSAsig *sig, mpint *m) 7 | { 8 | int rv = -1; 9 | mpint *u1, *u2, *v, *sinv; 10 | 11 | if(mpcmp(sig->r, mpone) < 0 || mpcmp(sig->r, pub->q) >= 0) 12 | return rv; 13 | if(mpcmp(sig->s, mpone) < 0 || mpcmp(sig->s, pub->q) >= 0) 14 | return rv; 15 | u1 = mpnew(0); 16 | u2 = mpnew(0); 17 | v = mpnew(0); 18 | sinv = mpnew(0); 19 | 20 | // find (s**-1) mod q, make sure it exists 21 | mpextendedgcd(sig->s, pub->q, u1, sinv, v); 22 | if(mpcmp(u1, mpone) != 0) 23 | goto out; 24 | 25 | // u1 = (sinv * m) mod q, u2 = (r * sinv) mod q 26 | mpmul(sinv, m, u1); 27 | mpmod(u1, pub->q, u1); 28 | mpmul(sig->r, sinv, u2); 29 | mpmod(u2, pub->q, u2); 30 | 31 | // v = (((alpha**u1)*(key**u2)) mod p) mod q 32 | mpexp(pub->alpha, u1, pub->p, sinv); 33 | mpexp(pub->key, u2, pub->p, v); 34 | mpmul(sinv, v, v); 35 | mpmod(v, pub->p, v); 36 | mpmod(v, pub->q, v); 37 | 38 | if(mpcmp(v, sig->r) == 0) 39 | rv = 0; 40 | out: 41 | mpfree(v); 42 | mpfree(u1); 43 | mpfree(u2); 44 | mpfree(sinv); 45 | return rv; 46 | } 47 | -------------------------------------------------------------------------------- /libsec/egalloc.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | EGpub* 6 | egpuballoc(void) 7 | { 8 | EGpub *eg; 9 | 10 | eg = mallocz(sizeof(*eg), 1); 11 | if(eg == nil) 12 | sysfatal("egpuballoc"); 13 | return eg; 14 | } 15 | 16 | void 17 | egpubfree(EGpub *eg) 18 | { 19 | if(eg == nil) 20 | return; 21 | mpfree(eg->p); 22 | mpfree(eg->alpha); 23 | mpfree(eg->key); 24 | free(eg); 25 | } 26 | 27 | 28 | EGpriv* 29 | egprivalloc(void) 30 | { 31 | EGpriv *eg; 32 | 33 | eg = mallocz(sizeof(*eg), 1); 34 | if(eg == nil) 35 | sysfatal("egprivalloc"); 36 | return eg; 37 | } 38 | 39 | void 40 | egprivfree(EGpriv *eg) 41 | { 42 | if(eg == nil) 43 | return; 44 | mpfree(eg->pub.p); 45 | mpfree(eg->pub.alpha); 46 | mpfree(eg->pub.key); 47 | mpfree(eg->secret); 48 | free(eg); 49 | } 50 | 51 | EGsig* 52 | egsigalloc(void) 53 | { 54 | EGsig *eg; 55 | 56 | eg = mallocz(sizeof(*eg), 1); 57 | if(eg == nil) 58 | sysfatal("egsigalloc"); 59 | return eg; 60 | } 61 | 62 | void 63 | egsigfree(EGsig *eg) 64 | { 65 | if(eg == nil) 66 | return; 67 | mpfree(eg->r); 68 | mpfree(eg->s); 69 | free(eg); 70 | } 71 | -------------------------------------------------------------------------------- /libsec/egdecrypt.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | mpint* 6 | egdecrypt(EGpriv *priv, mpint *in, mpint *out) 7 | { 8 | EGpub *pub = &priv->pub; 9 | mpint *gamma, *delta; 10 | mpint *p = pub->p; 11 | int plen = mpsignif(p)+1; 12 | int shift = ((plen+Dbits-1)/Dbits)*Dbits; 13 | 14 | if(out == nil) 15 | out = mpnew(0); 16 | gamma = mpnew(0); 17 | delta = mpnew(0); 18 | mpright(in, shift, gamma); 19 | mpleft(gamma, shift, delta); 20 | mpsub(in, delta, delta); 21 | mpexp(gamma, priv->secret, p, out); 22 | mpinvert(out, p, gamma); 23 | mpmul(gamma, delta, out); 24 | mpmod(out, p, out); 25 | mpfree(gamma); 26 | mpfree(delta); 27 | return out; 28 | } 29 | -------------------------------------------------------------------------------- /libsec/egencrypt.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | mpint* 6 | egencrypt(EGpub *pub, mpint *in, mpint *out) 7 | { 8 | mpint *m, *k, *gamma, *delta, *pm1; 9 | mpint *p = pub->p, *alpha = pub->alpha; 10 | int plen = mpsignif(p); 11 | int shift = ((plen+Dbits)/Dbits)*Dbits; 12 | // in libcrypt version, (int)(LENGTH(pub->p)*sizeof(NumType)*CHARBITS); 13 | 14 | if(out == nil) 15 | out = mpnew(0); 16 | pm1 = mpnew(0); 17 | m = mpnew(0); 18 | gamma = mpnew(0); 19 | delta = mpnew(0); 20 | mpmod(in, p, m); 21 | while(1){ 22 | k = mprand(plen, genrandom, nil); 23 | if((mpcmp(mpone, k) <= 0) && (mpcmp(k, pm1) < 0)) 24 | break; 25 | } 26 | mpexp(alpha, k, p, gamma); 27 | mpexp(pub->key, k, p, delta); 28 | mpmul(m, delta, delta); 29 | mpmod(delta, p, delta); 30 | mpleft(gamma, shift, out); 31 | mpadd(delta, out, out); 32 | mpfree(pm1); 33 | mpfree(m); 34 | mpfree(k); 35 | mpfree(gamma); 36 | mpfree(delta); 37 | return out; 38 | } 39 | -------------------------------------------------------------------------------- /libsec/eggen.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | EGpriv* 6 | eggen(int nlen, int rounds) 7 | { 8 | EGpub *pub; 9 | EGpriv *priv; 10 | 11 | priv = egprivalloc(); 12 | pub = &priv->pub; 13 | pub->p = mpnew(0); 14 | pub->alpha = mpnew(0); 15 | pub->key = mpnew(0); 16 | priv->secret = mpnew(0); 17 | gensafeprime(pub->p, pub->alpha, nlen, rounds); 18 | mprand(nlen-1, genrandom, priv->secret); 19 | mpexp(pub->alpha, priv->secret, pub->p, pub->key); 20 | return priv; 21 | } 22 | -------------------------------------------------------------------------------- /libsec/egprivtopub.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | EGpub* 6 | egprivtopub(EGpriv *priv) 7 | { 8 | EGpub *pub; 9 | 10 | pub = egpuballoc(); 11 | if(pub == nil) 12 | return nil; 13 | pub->p = mpcopy(priv->pub.p); 14 | pub->alpha = mpcopy(priv->pub.alpha); 15 | pub->key = mpcopy(priv->pub.key); 16 | return pub; 17 | } 18 | -------------------------------------------------------------------------------- /libsec/egsign.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | EGsig* 6 | egsign(EGpriv *priv, mpint *m) 7 | { 8 | EGpub *pub = &priv->pub; 9 | EGsig *sig; 10 | mpint *pm1, *k, *kinv, *r, *s; 11 | mpint *p = pub->p, *alpha = pub->alpha; 12 | int plen = mpsignif(p); 13 | 14 | pm1 = mpnew(0); 15 | kinv = mpnew(0); 16 | r = mpnew(0); 17 | s = mpnew(0); 18 | k = mpnew(0); 19 | mpsub(p, mpone, pm1); 20 | while(1){ 21 | mprand(plen, genrandom, k); 22 | if((mpcmp(mpone, k) > 0) || (mpcmp(k, pm1) >= 0)) 23 | continue; 24 | mpextendedgcd(k, pm1, r, kinv, s); 25 | if(mpcmp(r, mpone) != 0) 26 | continue; 27 | break; 28 | } 29 | mpmod(kinv, pm1, kinv); // make kinv positive 30 | mpexp(alpha, k, p, r); 31 | mpmul(priv->secret, r, s); 32 | mpmod(s, pm1, s); 33 | mpsub(m, s, s); 34 | mpmul(kinv, s, s); 35 | mpmod(s, pm1, s); 36 | sig = egsigalloc(); 37 | sig->r = r; 38 | sig->s = s; 39 | mpfree(pm1); 40 | mpfree(k); 41 | mpfree(kinv); 42 | return sig; 43 | } 44 | -------------------------------------------------------------------------------- /libsec/egtest.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | void 6 | main(void) 7 | { 8 | EGpriv *sk; 9 | mpint *m, *gamma, *delta, *in, *out; 10 | int plen, shift; 11 | 12 | fmtinstall('B', mpconv); 13 | 14 | sk = egprivalloc(); 15 | sk->pub.p = uitomp(2357, nil); 16 | sk->pub.alpha = uitomp(2, nil); 17 | sk->pub.key = uitomp(1185, nil); 18 | sk->secret = uitomp(1751, nil); 19 | 20 | m = uitomp(2035, nil); 21 | 22 | plen = mpsignif(sk->pub.p)+1; 23 | shift = ((plen+Dbits-1)/Dbits)*Dbits; 24 | gamma = uitomp(1430, nil); 25 | delta = uitomp(697, nil); 26 | out = mpnew(0); 27 | in = mpnew(0); 28 | mpleft(gamma, shift, in); 29 | mpadd(delta, in, in); 30 | egdecrypt(sk, in, out); 31 | 32 | if(mpcmp(m, out) != 0) 33 | print("decrypt failed to recover message\n"); 34 | } 35 | -------------------------------------------------------------------------------- /libsec/egverify.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | int 6 | egverify(EGpub *pub, EGsig *sig, mpint *m) 7 | { 8 | mpint *p = pub->p, *alpha = pub->alpha; 9 | mpint *r = sig->r, *s = sig->s; 10 | mpint *v1, *v2, *rs; 11 | int rv = -1; 12 | 13 | if(mpcmp(r, mpone) < 0 || mpcmp(r, p) >= 0) 14 | return rv; 15 | v1 = mpnew(0); 16 | rs = mpnew(0); 17 | v2 = mpnew(0); 18 | mpexp(pub->key, r, p, v1); 19 | mpexp(r, s, p, rs); 20 | mpmul(v1, rs, v1); 21 | mpmod(v1, p, v1); 22 | mpexp(alpha, m, p, v2); 23 | if(mpcmp(v1, v2) == 0) 24 | rv = 0; 25 | mpfree(v1); 26 | mpfree(rs); 27 | mpfree(v2); 28 | return rv; 29 | } 30 | -------------------------------------------------------------------------------- /libsec/fastrand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | /* 6 | * use the X917 random number generator to create random 7 | * numbers (faster than truerand() but not as random). 8 | */ 9 | ulong 10 | fastrand(void) 11 | { 12 | ulong x; 13 | 14 | genrandom((uchar*)&x, sizeof x); 15 | return x; 16 | } 17 | -------------------------------------------------------------------------------- /libsec/genprime.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // generate a probable prime. accuracy is the miller-rabin interations 6 | void 7 | genprime(mpint *p, int n, int accuracy) 8 | { 9 | mpdigit x; 10 | 11 | // generate n random bits with high and low bits set 12 | mpbits(p, n); 13 | genrandom((uchar*)p->p, (n+7)/8); 14 | p->top = (n+Dbits-1)/Dbits; 15 | x = 1; 16 | x <<= ((n-1)%Dbits); 17 | p->p[p->top-1] &= (x-1); 18 | p->p[p->top-1] |= x; 19 | p->p[0] |= 1; 20 | 21 | // keep icrementing till it looks prime 22 | for(;;){ 23 | if(probably_prime(p, accuracy)) 24 | break; 25 | mpadd(p, mptwo, p); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /libsec/genrandom.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | typedef struct State{ 6 | QLock lock; 7 | int seeded; 8 | uvlong seed; 9 | DES3state des3; 10 | } State; 11 | static State x917state; 12 | 13 | static void 14 | X917(uchar *rand, int nrand) 15 | { 16 | int i, m, n8; 17 | uvlong I, x; 18 | 19 | /* 1. Compute intermediate value I = Ek(time). */ 20 | I = nsec(); 21 | triple_block_cipher(x917state.des3.expanded, (uchar*)&I, 0); /* two-key EDE */ 22 | 23 | /* 2. x[i] = Ek(I^seed); seed = Ek(x[i]^I); */ 24 | m = (nrand+7)/8; 25 | for(i=0; i8) ? 8 : nrand; 29 | memcpy(rand, (uchar*)&x, n8); 30 | rand += 8; 31 | nrand -= 8; 32 | x ^= I; 33 | triple_block_cipher(x917state.des3.expanded, (uchar*)&x, 0); 34 | x917state.seed = x; 35 | } 36 | } 37 | 38 | static void 39 | X917init(void) 40 | { 41 | int n; 42 | uchar mix[128]; 43 | uchar key3[3][8]; 44 | ulong *ulp; 45 | 46 | ulp = (ulong*)key3; 47 | for(n = 0; n < sizeof(key3)/sizeof(ulong); n++) 48 | ulp[n] = truerand(); 49 | setupDES3state(&x917state.des3, key3, nil); 50 | X917(mix, sizeof mix); 51 | x917state.seeded = 1; 52 | } 53 | 54 | void 55 | genrandom(uchar *p, int n) 56 | { 57 | qlock(&x917state.lock); 58 | if(x917state.seeded == 0) 59 | X917init(); 60 | X917(p, n); 61 | qunlock(&x917state.lock); 62 | } 63 | -------------------------------------------------------------------------------- /libsec/gensafeprime.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // find a prime p of length n and a generator alpha of Z^*_p 6 | // Alg 4.86 Menezes et al () Handbook, p.164 7 | void 8 | gensafeprime(mpint *p, mpint *alpha, int n, int accuracy) 9 | { 10 | mpint *q, *b; 11 | 12 | q = mpnew(n-1); 13 | while(1){ 14 | genprime(q, n-1, accuracy); 15 | mpleft(q, 1, p); 16 | mpadd(p, mpone, p); // p = 2*q+1 17 | if(probably_prime(p, accuracy)) 18 | break; 19 | } 20 | // now find a generator alpha of the multiplicative 21 | // group Z*_p of order p-1=2q 22 | b = mpnew(0); 23 | while(1){ 24 | mprand(n, genrandom, alpha); 25 | mpmod(alpha, p, alpha); 26 | mpmul(alpha, alpha, b); 27 | mpmod(b, p, b); 28 | if(mpcmp(b, mpone) == 0) 29 | continue; 30 | mpexp(alpha, q, p, b); 31 | if(mpcmp(b, mpone) != 0) 32 | break; 33 | } 34 | mpfree(b); 35 | mpfree(q); 36 | } 37 | -------------------------------------------------------------------------------- /libsec/genstrongprime.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // Gordon's algorithm for generating a strong prime 6 | // Menezes et al () Handbook, p.150 7 | void 8 | genstrongprime(mpint *p, int n, int accuracy) 9 | { 10 | mpint *s, *t, *r, *i; 11 | 12 | if(n < 64) 13 | n = 64; 14 | 15 | s = mpnew(n/2); 16 | genprime(s, (n/2)-16, accuracy); 17 | t = mpnew(n/2); 18 | genprime(t, n-mpsignif(s)-32, accuracy); 19 | 20 | // first r = 2it + 1 that's prime 21 | i = mpnew(16); 22 | r = mpnew(0); 23 | itomp(0x8000, i); 24 | mpleft(t, 1, t); // 2t 25 | mpmul(i, t, r); // 2it 26 | mpadd(r, mpone, r); // 2it + 1 27 | for(;;){ 28 | if(probably_prime(r, 18)) 29 | break; 30 | mpadd(r, t, r); // r += 2t 31 | } 32 | 33 | // p0 = 2(s**(r-2) mod r)s - 1 34 | itomp(2, p); 35 | mpsub(r, p, p); 36 | mpexp(s, p, r, p); 37 | mpmul(s, p, p); 38 | mpleft(p, 1, p); 39 | mpsub(p, mpone, p); 40 | 41 | // first p = p0 + 2irs that's prime 42 | itomp(0x8000, i); 43 | mpleft(r, 1, r); // 2r 44 | mpmul(r, s, r); // 2rs 45 | mpmul(r, i, i); // 2irs 46 | mpadd(p, i, p); // p0 + 2irs 47 | for(;;){ 48 | if(probably_prime(p, accuracy)) 49 | break; 50 | mpadd(p, r, p); // p += 2rs 51 | } 52 | 53 | mpfree(i); 54 | mpfree(s); 55 | mpfree(r); 56 | mpfree(t); 57 | } 58 | -------------------------------------------------------------------------------- /libsec/hmac.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | 4 | /* rfc2104 */ 5 | DigestState* 6 | hmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s, 7 | DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen) 8 | { 9 | int i; 10 | uchar pad[Hmacblksz+1], innerdigest[256]; 11 | 12 | if(xlen > sizeof(innerdigest)) 13 | return nil; 14 | if(klen > Hmacblksz) 15 | return nil; 16 | 17 | /* first time through */ 18 | if(s == nil || s->seeded == 0){ 19 | memset(pad, 0x36, Hmacblksz); 20 | pad[Hmacblksz] = 0; 21 | for(i = 0; i < klen; i++) 22 | pad[i] ^= key[i]; 23 | s = (*x)(pad, Hmacblksz, nil, s); 24 | if(s == nil) 25 | return nil; 26 | } 27 | 28 | s = (*x)(p, len, nil, s); 29 | if(digest == nil) 30 | return s; 31 | 32 | /* last time through */ 33 | memset(pad, 0x5c, Hmacblksz); 34 | pad[Hmacblksz] = 0; 35 | for(i = 0; i < klen; i++) 36 | pad[i] ^= key[i]; 37 | (*x)(nil, 0, innerdigest, s); 38 | s = (*x)(pad, Hmacblksz, nil, nil); 39 | (*x)(innerdigest, xlen, digest, s); 40 | return nil; 41 | } 42 | -------------------------------------------------------------------------------- /libsec/hmactest.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | uchar key[] = "Jefe"; 6 | uchar data[] = "what do ya want for nothing?"; 7 | 8 | void 9 | main(void) 10 | { 11 | int i; 12 | uchar hash[MD5dlen]; 13 | 14 | hmac_md5(data, strlen((char*)data), key, 4, hash, nil); 15 | for(i=0; i 3 | #include 4 | 5 | char *tests[] = { 6 | "", 7 | "a", 8 | "abc", 9 | "message digest", 10 | "abcdefghijklmnopqrstuvwxyz", 11 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 12 | "12345678901234567890123456789012345678901234567890123456789012345678901234567890", 13 | 0 14 | }; 15 | 16 | void 17 | main(void) 18 | { 19 | char **pp; 20 | uchar *p; 21 | int i; 22 | uchar digest[MD5dlen]; 23 | 24 | for(pp = tests; *pp; pp++){ 25 | p = (uchar*)*pp; 26 | md4(p, strlen(*pp), digest, 0); 27 | for(i = 0; i < MD5dlen; i++) 28 | print("%2.2ux", digest[i]); 29 | print("\n"); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /libsec/md5pickle.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | 4 | char* 5 | md5pickle(MD5state *s) 6 | { 7 | char *p; 8 | int m, n; 9 | 10 | m = 17+4*9+4*((s->blen+3)/3 + 1); 11 | p = malloc(m); 12 | if(p == nil) 13 | return p; 14 | n = sprint(p, "%16.16llux %8.8ux %8.8ux %8.8ux %8.8ux ", 15 | s->len, 16 | s->state[0], s->state[1], s->state[2], 17 | s->state[3]); 18 | enc64(p+n, m-n, s->buf, s->blen); 19 | return p; 20 | } 21 | 22 | MD5state* 23 | md5unpickle(char *p) 24 | { 25 | MD5state *s; 26 | 27 | s = malloc(sizeof(*s)); 28 | if(s == nil) 29 | return nil; 30 | s->len = strtoull(p, &p, 16); 31 | s->state[0] = strtoul(p, &p, 16); 32 | s->state[1] = strtoul(p, &p, 16); 33 | s->state[2] = strtoul(p, &p, 16); 34 | s->state[3] = strtoul(p, &p, 16); 35 | s->blen = dec64(s->buf, sizeof(s->buf), p, strlen(p)); 36 | s->malloced = 1; 37 | s->seeded = 1; 38 | return s; 39 | } 40 | -------------------------------------------------------------------------------- /libsec/nfastrand.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #define Maxrand ((1UL<<31)-1) 6 | 7 | ulong 8 | nfastrand(ulong n) 9 | { 10 | ulong m, r; 11 | 12 | /* 13 | * set m to the maximum multiple of n <= 2^31-1 14 | * so we want a random number < m. 15 | */ 16 | if(n > Maxrand) 17 | sysfatal("nfastrand: n too large"); 18 | 19 | m = Maxrand - Maxrand % n; 20 | while((r = fastrand()) >= m) 21 | ; 22 | return r%n; 23 | } 24 | -------------------------------------------------------------------------------- /libsec/os.h: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | -------------------------------------------------------------------------------- /libsec/prng.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // 6 | // just use the libc prng to fill a buffer 7 | // 8 | void 9 | prng(uchar *p, int n) 10 | { 11 | uchar *e; 12 | 13 | for(e = p+n; p < e; p++) 14 | *p = rand(); 15 | } 16 | -------------------------------------------------------------------------------- /libsec/readcert.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | static char* 8 | readfile(char *name) 9 | { 10 | int fd; 11 | char *s; 12 | Dir *d; 13 | 14 | fd = open(name, OREAD); 15 | if(fd < 0) 16 | return nil; 17 | if((d = dirfstat(fd)) == nil) { 18 | close(fd); 19 | return nil; 20 | } 21 | s = malloc(d->length + 1); 22 | if(s == nil || readn(fd, s, d->length) != d->length){ 23 | free(s); 24 | free(d); 25 | close(fd); 26 | return nil; 27 | } 28 | close(fd); 29 | s[d->length] = '\0'; 30 | free(d); 31 | return s; 32 | } 33 | 34 | uchar* 35 | readcert(char *filename, int *pcertlen) 36 | { 37 | char *pem; 38 | uchar *binary; 39 | 40 | pem = readfile(filename); 41 | if(pem == nil){ 42 | werrstr("can't read %s: %r", filename); 43 | return nil; 44 | } 45 | binary = decodePEM(pem, "CERTIFICATE", pcertlen, nil); 46 | free(pem); 47 | if(binary == nil){ 48 | werrstr("can't parse %s", filename); 49 | return nil; 50 | } 51 | return binary; 52 | } 53 | 54 | PEMChain * 55 | readcertchain(char *filename) 56 | { 57 | char *chfile; 58 | 59 | chfile = readfile(filename); 60 | if (chfile == nil) { 61 | werrstr("can't read %s: %r", filename); 62 | return nil; 63 | } 64 | return decodepemchain(chfile, "CERTIFICATE"); 65 | } 66 | 67 | -------------------------------------------------------------------------------- /libsec/rsaalloc.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | RSApub* 6 | rsapuballoc(void) 7 | { 8 | RSApub *rsa; 9 | 10 | rsa = mallocz(sizeof(*rsa), 1); 11 | if(rsa == nil) 12 | sysfatal("rsapuballoc"); 13 | return rsa; 14 | } 15 | 16 | void 17 | rsapubfree(RSApub *rsa) 18 | { 19 | if(rsa == nil) 20 | return; 21 | mpfree(rsa->ek); 22 | mpfree(rsa->n); 23 | free(rsa); 24 | } 25 | 26 | 27 | RSApriv* 28 | rsaprivalloc(void) 29 | { 30 | RSApriv *rsa; 31 | 32 | rsa = mallocz(sizeof(*rsa), 1); 33 | if(rsa == nil) 34 | sysfatal("rsaprivalloc"); 35 | return rsa; 36 | } 37 | 38 | void 39 | rsaprivfree(RSApriv *rsa) 40 | { 41 | if(rsa == nil) 42 | return; 43 | mpfree(rsa->pub.ek); 44 | mpfree(rsa->pub.n); 45 | mpfree(rsa->dk); 46 | mpfree(rsa->p); 47 | mpfree(rsa->q); 48 | mpfree(rsa->kp); 49 | mpfree(rsa->kq); 50 | mpfree(rsa->c2); 51 | free(rsa); 52 | } 53 | -------------------------------------------------------------------------------- /libsec/rsadecrypt.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | // decrypt rsa using garner's algorithm for the chinese remainder theorem 6 | // seminumerical algorithms, knuth, pp 253-254 7 | // applied cryptography, menezes et al, pg 612 8 | mpint* 9 | rsadecrypt(RSApriv *rsa, mpint *in, mpint *out) 10 | { 11 | mpint *v1, *v2; 12 | 13 | if(out == nil) 14 | out = mpnew(0); 15 | 16 | // convert in to modular representation 17 | v1 = mpnew(0); 18 | mpmod(in, rsa->p, v1); 19 | v2 = mpnew(0); 20 | mpmod(in, rsa->q, v2); 21 | 22 | // exponentiate the modular rep 23 | mpexp(v1, rsa->kp, rsa->p, v1); 24 | mpexp(v2, rsa->kq, rsa->q, v2); 25 | 26 | // out = v1 + p*((v2-v1)*c2 mod q) 27 | mpsub(v2, v1, v2); 28 | mpmul(v2, rsa->c2, v2); 29 | mpmod(v2, rsa->q, v2); 30 | mpmul(v2, rsa->p, out); 31 | mpadd(v1, out, out); 32 | 33 | mpfree(v1); 34 | mpfree(v2); 35 | 36 | return out; 37 | } 38 | -------------------------------------------------------------------------------- /libsec/rsaencrypt.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | mpint* 6 | rsaencrypt(RSApub *rsa, mpint *in, mpint *out) 7 | { 8 | if(out == nil) 9 | out = mpnew(0); 10 | mpexp(in, rsa->ek, rsa->n, out); 11 | return out; 12 | } 13 | -------------------------------------------------------------------------------- /libsec/rsafill.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | RSApriv* 6 | rsafill(mpint *n, mpint *e, mpint *d, mpint *p, mpint *q) 7 | { 8 | mpint *c2, *kq, *kp, *x; 9 | RSApriv *rsa; 10 | 11 | // make sure we're not being hoodwinked 12 | if(!probably_prime(p, 10) || !probably_prime(q, 10)){ 13 | werrstr("rsafill: p or q not prime"); 14 | return nil; 15 | } 16 | x = mpnew(0); 17 | mpmul(p, q, x); 18 | if(mpcmp(n, x) != 0){ 19 | werrstr("rsafill: n != p*q"); 20 | mpfree(x); 21 | return nil; 22 | } 23 | c2 = mpnew(0); 24 | mpsub(p, mpone, c2); 25 | mpsub(q, mpone, x); 26 | mpmul(c2, x, x); 27 | mpmul(e, d, c2); 28 | mpmod(c2, x, x); 29 | if(mpcmp(x, mpone) != 0){ 30 | werrstr("rsafill: e*d != 1 mod (p-1)*(q-1)"); 31 | mpfree(x); 32 | mpfree(c2); 33 | return nil; 34 | } 35 | 36 | // compute chinese remainder coefficient 37 | mpinvert(p, q, c2); 38 | 39 | // for crt a**k mod p == (a**(k mod p-1)) mod p 40 | kq = mpnew(0); 41 | kp = mpnew(0); 42 | mpsub(p, mpone, x); 43 | mpmod(d, x, kp); 44 | mpsub(q, mpone, x); 45 | mpmod(d, x, kq); 46 | 47 | rsa = rsaprivalloc(); 48 | rsa->pub.ek = mpcopy(e); 49 | rsa->pub.n = mpcopy(n); 50 | rsa->dk = mpcopy(d); 51 | rsa->kp = kp; 52 | rsa->kq = kq; 53 | rsa->p = mpcopy(p); 54 | rsa->q = mpcopy(q); 55 | rsa->c2 = c2; 56 | 57 | mpfree(x); 58 | 59 | return rsa; 60 | } 61 | 62 | -------------------------------------------------------------------------------- /libsec/rsaprivtopub.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | 5 | RSApub* 6 | rsaprivtopub(RSApriv *priv) 7 | { 8 | RSApub *pub; 9 | 10 | pub = rsapuballoc(); 11 | if(pub == nil) 12 | return nil; 13 | pub->n = mpcopy(priv->pub.n); 14 | pub->ek = mpcopy(priv->pub.ek); 15 | return pub; 16 | } 17 | -------------------------------------------------------------------------------- /libsec/rsatest.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | #include 4 | #include 5 | 6 | void 7 | main(void) 8 | { 9 | int n; 10 | vlong start; 11 | char *p; 12 | uchar buf[4096]; 13 | Biobuf b; 14 | RSApriv *rsa; 15 | mpint *clr, *enc, *clr2; 16 | 17 | fmtinstall('B', mpfmt); 18 | 19 | rsa = rsagen(1024, 16, 0); 20 | if(rsa == nil) 21 | sysfatal("rsagen"); 22 | Binit(&b, 0, OREAD); 23 | clr = mpnew(0); 24 | clr2 = mpnew(0); 25 | enc = mpnew(0); 26 | 27 | strtomp("123456789abcdef123456789abcdef123456789abcdef123456789abcdef", nil, 16, clr); 28 | rsaencrypt(&rsa->pub, clr, enc); 29 | 30 | start = nsec(); 31 | for(n = 0; n < 10; n++) 32 | rsadecrypt(rsa, enc, clr); 33 | print("%lld\n", nsec()-start); 34 | 35 | start = nsec(); 36 | for(n = 0; n < 10; n++) 37 | mpexp(enc, rsa->dk, rsa->pub.n, clr2); 38 | print("%lld\n", nsec()-start); 39 | 40 | if(mpcmp(clr, clr2) != 0) 41 | print("%B != %B\n", clr, clr2); 42 | 43 | print("> "); 44 | while(p = Brdline(&b, '\n')){ 45 | n = Blinelen(&b); 46 | letomp((uchar*)p, n, clr); 47 | print("clr %B\n", clr); 48 | rsaencrypt(&rsa->pub, clr, enc); 49 | print("enc %B\n", enc); 50 | rsadecrypt(rsa, enc, clr); 51 | print("clr %B\n", clr); 52 | n = mptole(clr, buf, sizeof(buf), nil); 53 | write(1, buf, n); 54 | print("> "); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /libsec/sha1pickle.c: -------------------------------------------------------------------------------- 1 | #include "os.h" 2 | #include 3 | 4 | char* 5 | sha1pickle(SHA1state *s) 6 | { 7 | char *p; 8 | int m, n; 9 | 10 | m = 5*9+4*((s->blen+3)/3); 11 | p = malloc(m); 12 | if(p == nil) 13 | return p; 14 | n = sprint(p, "%8.8ux %8.8ux %8.8ux %8.8ux %8.8ux ", 15 | s->state[0], s->state[1], s->state[2], 16 | s->state[3], s->state[4]); 17 | enc64(p+n, m-n, s->buf, s->blen); 18 | return p; 19 | } 20 | 21 | SHA1state* 22 | sha1unpickle(char *p) 23 | { 24 | SHA1state *s; 25 | 26 | s = malloc(sizeof(*s)); 27 | if(s == nil) 28 | return nil; 29 | s->state[0] = strtoul(p, &p, 16); 30 | s->state[1] = strtoul(p, &p, 16); 31 | s->state[2] = strtoul(p, &p, 16); 32 | s->state[3] = strtoul(p, &p, 16); 33 | s->state[4] = strtoul(p, &p, 16); 34 | s->blen = dec64(s->buf, sizeof(s->buf), p, strlen(p)); 35 | s->malloced = 1; 36 | s->seeded = 1; 37 | return s; 38 | } 39 | -------------------------------------------------------------------------------- /libsec/sha2test.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "libsec.h" 4 | 5 | char *tests[] = { 6 | "", 7 | "a", 8 | "abc", 9 | "message digest", 10 | "abcdefghijklmnopqrstuvwxyz", 11 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", 12 | "123456789012345678901234567890123456789012345678901234567890" 13 | "12345678901234567890", 14 | "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 15 | "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" 16 | "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 17 | 0 18 | }; 19 | 20 | void 21 | main(void) 22 | { 23 | int i; 24 | char **pp; 25 | uchar *p; 26 | uchar digest[SHA2_512dlen]; 27 | 28 | print("SHA2_224 tests:\n"); 29 | for(pp = tests; *pp; pp++){ 30 | p = (uchar*)*pp; 31 | sha2_224(p, strlen(*pp), digest, 0); 32 | for(i = 0; i < SHA2_224dlen; i++) 33 | print("%2.2ux", digest[i]); 34 | print("\n"); 35 | } 36 | 37 | print("\nSHA256 tests:\n"); 38 | for(pp = tests; *pp; pp++){ 39 | p = (uchar*)*pp; 40 | sha2_256(p, strlen(*pp), digest, 0); 41 | for(i = 0; i < SHA2_256dlen; i++) 42 | print("%2.2ux", digest[i]); 43 | print("\n"); 44 | } 45 | 46 | print("\nSHA384 tests:\n"); 47 | for(pp = tests; *pp; pp++){ 48 | p = (uchar*)*pp; 49 | sha2_384(p, strlen(*pp), digest, 0); 50 | for(i = 0; i < SHA2_384dlen; i++) 51 | print("%2.2ux", digest[i]); 52 | print("\n"); 53 | } 54 | 55 | print("\nSHA512 tests:\n"); 56 | for(pp = tests; *pp; pp++){ 57 | p = (uchar*)*pp; 58 | sha2_512(p, strlen(*pp), digest, 0); 59 | for(i = 0; i < SHA2_512dlen; i++) 60 | print("%2.2ux", digest[i]); 61 | print("\n"); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /posix-386/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | tas.$O 10 | 11 | default: $(LIB) 12 | $(LIB): $(OFILES) 13 | $(AR) r $(LIB) $(OFILES) 14 | $(RANLIB) $(LIB) 15 | 16 | %.$O: %.c 17 | $(CC) $(CFLAGS) $*.c 18 | 19 | %.$O: %.s 20 | $(AS) -o $*.$O $*.s 21 | 22 | md5block.s: md5block.spp 23 | gcc -E - < md5block.spp >md5block.s 24 | 25 | sha1block.s: sha1block.spp 26 | gcc -E - < sha1block.spp >sha1block.s 27 | 28 | -------------------------------------------------------------------------------- /posix-386/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | uintptr 5 | getcallerpc(void *a) 6 | { 7 | return ((uintptr*)a)[-1]; 8 | } 9 | -------------------------------------------------------------------------------- /posix-386/tas.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | int 5 | tas(long *x) 6 | { 7 | int v; 8 | 9 | __asm__( "movl $1, %%eax\n\t" 10 | "xchgl %%eax,(%%ecx)" 11 | : "=a" (v) 12 | : "c" (x) 13 | ); 14 | switch(v) { 15 | case 0: 16 | case 1: 17 | return v; 18 | default: 19 | print("canlock: corrupted 0x%lux\n", v); 20 | return 1; 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /posix-amd64/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | tas.$O 10 | 11 | default: $(LIB) 12 | $(LIB): $(OFILES) 13 | $(AR) r $(LIB) $(OFILES) 14 | $(RANLIB) $(LIB) 15 | 16 | %.$O: %.c 17 | $(CC) $(CFLAGS) $*.c 18 | -------------------------------------------------------------------------------- /posix-amd64/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | uintptr 5 | getcallerpc(void *a) 6 | { 7 | return ((uintptr*)a)[-1]; 8 | } 9 | -------------------------------------------------------------------------------- /posix-amd64/tas.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | int 5 | tas(long *x) 6 | { 7 | int v; 8 | 9 | __asm__( "movl $1, %%eax\n\t" 10 | "xchgl %%eax,(%%rcx)" 11 | : "=a" (v) 12 | : "c" (x) 13 | ); 14 | switch(v) { 15 | case 0: 16 | case 1: 17 | return v; 18 | default: 19 | print("canlock: corrupted 0x%lux\n", v); 20 | return 1; 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /posix-arm/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | tas.$O 10 | 11 | default: $(LIB) 12 | $(LIB): $(OFILES) 13 | $(AR) r $(LIB) $(OFILES) 14 | $(RANLIB) $(LIB) 15 | 16 | %.$O: %.c 17 | $(CC) $(CFLAGS) $*.c 18 | 19 | %.$O: %.s 20 | $(AS) -o $*.$O $*.s 21 | 22 | %.s: %.spp 23 | cpp $*.spp >$*.s 24 | 25 | 26 | -------------------------------------------------------------------------------- /posix-arm/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | uintptr 5 | getcallerpc(void *a) 6 | { 7 | return ((uintptr*)a)[-1]; 8 | } 9 | -------------------------------------------------------------------------------- /posix-arm/tas.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | int 5 | tas(long *x) 6 | { 7 | int v, t, i = 1; 8 | 9 | #if ARMv5 10 | __asm__( 11 | "swp %0, %1, [%2]" 12 | : "=&r" (v) 13 | : "r" (1), "r" (x) 14 | : "memory" 15 | ); 16 | #else 17 | __asm__ ( 18 | "1: ldrex %0, [%2]\n" 19 | " strex %1, %3, [%2]\n" 20 | " teq %1, #0\n" 21 | " bne 1b" 22 | : "=&r" (v), "=&r" (t) 23 | : "r" (x), "r" (i) 24 | : "cc"); 25 | #endif 26 | switch(v) { 27 | case 0: 28 | case 1: 29 | return v; 30 | default: 31 | print("canlock: corrupted 0x%lux\n", v); 32 | return 1; 33 | } 34 | } 35 | 36 | -------------------------------------------------------------------------------- /posix-mips/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | tas.$O 10 | 11 | default: $(LIB) 12 | $(LIB): $(OFILES) 13 | $(AR) r $(LIB) $(OFILES) 14 | $(RANLIB) $(LIB) 15 | 16 | %.$O: %.c 17 | $(CC) $(CFLAGS) $*.c 18 | 19 | %.$O: %.s 20 | $(AS) $(ASFLAGS) -o $*.$O $*.s 21 | 22 | %.s: %.spp 23 | cpp $*.spp >$*.s 24 | 25 | 26 | -------------------------------------------------------------------------------- /posix-mips/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | ulong 5 | getcallerpc(void *a) 6 | { 7 | return ((ulong*)a)[-1]; 8 | } 9 | -------------------------------------------------------------------------------- /posix-mips/tas.s: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | .globl tas 5 | .ent tas 2 6 | 7 | tas: 8 | .set noreorder 9 | 1: 10 | ori t1, zero, 12345 /* t1 = 12345 */ 11 | ll t0, (a0) /* t0 = *a0 */ 12 | sc t1, (a0) /* *a0 = t1 if *a0 hasn't changed; t1=success */ 13 | beq t1, zero, 1b /* repeat if *a0 did change */ 14 | nop 15 | 16 | j $31 /* return */ 17 | or v0, t0, zero /* set return value on way out */ 18 | 19 | .set reorder 20 | .end tas 21 | 22 | -------------------------------------------------------------------------------- /posix-port/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | 10 | default: $(LIB) 11 | $(LIB): $(OFILES) 12 | $(AR) r $(LIB) $(OFILES) 13 | $(RANLIB) $(LIB) 14 | 15 | %.$O: %.c 16 | $(CC) $(CFLAGS) $*.c 17 | 18 | %.$O: %.s 19 | $(AS) -o $*.$O $*.s 20 | 21 | %.s: %.spp 22 | cpp $*.spp >$*.s 23 | 24 | 25 | -------------------------------------------------------------------------------- /posix-port/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | uintptr 5 | getcallerpc(void *a) 6 | { 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /posix-power/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | tas.$O 10 | 11 | default: $(LIB) 12 | $(LIB): $(OFILES) 13 | $(AR) r $(LIB) $(OFILES) 14 | $(RANLIB) $(LIB) 15 | 16 | %.$O: %.c 17 | $(CC) $(CFLAGS) $*.c 18 | 19 | %.$O: %.s 20 | $(AS) -o $*.$O $*.s 21 | 22 | %.s: %.spp 23 | cpp $*.spp >$*.s 24 | 25 | 26 | -------------------------------------------------------------------------------- /posix-power/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | uintptr 5 | getcallerpc(void *a) 6 | { 7 | return ((uintptr*)a)[-1]; 8 | } 9 | -------------------------------------------------------------------------------- /posix-power/tas.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | /* 5 | * first argument (l) is in r3 at entry. 6 | * r3 contains return value upon return. 7 | */ 8 | int 9 | tas(long *x) 10 | { 11 | int v; 12 | /* 13 | * this __asm__ works with gcc 2.95.2 (mac os x 10.1). 14 | * this assembly language destroys r0 (0), some other register (v), 15 | * r4 (x) and r5 (temp). 16 | */ 17 | __asm__("\n sync\n" 18 | " li r0,0\n" 19 | " mr r4,%1 /* &l->val */\n" 20 | " lis r5,0xdead /* assemble constant 0xdeaddead */\n" 21 | " ori r5,r5,0xdead /* \" */\n" 22 | "tas1:\n" 23 | " dcbf r4,r0 /* cache flush; \"fix for 603x bug\" */\n" 24 | " lwarx %0,r4,r0 /* v = l->val with reservation */\n" 25 | " cmp cr0,0,%0,r0 /* v == 0 */\n" 26 | " bne tas0\n" 27 | " stwcx. r5,r4,r0 /* if (l->val same) l->val = 0xdeaddead */\n" 28 | " bne tas1\n" 29 | "tas0:\n" 30 | " sync\n" 31 | " isync\n" 32 | : "=r" (v) 33 | : "r" (x) 34 | : "cc", "memory", "r0", "r4", "r5" 35 | ); 36 | switch(v) { 37 | case 0: return 0; 38 | case 0xdeaddead: return 1; 39 | default: print("tas: corrupted 0x%lux\n", v); 40 | } 41 | return 0; 42 | } 43 | -------------------------------------------------------------------------------- /posix-sun4u/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | tas.$O 10 | 11 | default: $(LIB) 12 | $(LIB): $(OFILES) 13 | $(AR) r $(LIB) $(OFILES) 14 | $(RANLIB) $(LIB) 15 | 16 | %.$O: %.c 17 | $(CC) $(CFLAGS) $*.c 18 | 19 | %.$O: %.s 20 | $(AS) -o $*.$O $*.s 21 | 22 | %.s: %.spp 23 | cpp $*.spp >$*.s 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /posix-sun4u/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | ulong 5 | getcallerpc(void *a) 6 | { 7 | return ((ulong*)a)[-1]; 8 | } 9 | 10 | -------------------------------------------------------------------------------- /posix-sun4u/tas.s: -------------------------------------------------------------------------------- 1 | .globl tas 2 | tas: 3 | retl 4 | ldstub [%o0], %o0 5 | 6 | -------------------------------------------------------------------------------- /resource.h: -------------------------------------------------------------------------------- 1 | //{{NO_DEPENDENCIES}} 2 | // Microsoft Developer Studio generated include file. 3 | // Used by drawterm.rc 4 | // 5 | #define IDI_ICON1 101 6 | 7 | // Next default values for new objects 8 | // 9 | #ifdef APSTUDIO_INVOKED 10 | #ifndef APSTUDIO_READONLY_SYMBOLS 11 | #define _APS_NEXT_RESOURCE_VALUE 102 12 | #define _APS_NEXT_COMMAND_VALUE 40001 13 | #define _APS_NEXT_CONTROL_VALUE 1000 14 | #define _APS_NEXT_SYMED_VALUE 101 15 | #endif 16 | #endif 17 | -------------------------------------------------------------------------------- /win32-386/Makefile: -------------------------------------------------------------------------------- 1 | ROOT=.. 2 | include ../Make.config 3 | LIB=../libmachdep.a 4 | 5 | OFILES=\ 6 | getcallerpc.$O\ 7 | md5block.$O\ 8 | sha1block.$O\ 9 | tas.$O 10 | 11 | default: $(LIB) 12 | $(LIB): $(OFILES) 13 | $(AR) r $(LIB) $(OFILES) 14 | $(RANLIB) $(LIB) 15 | 16 | %.$O: %.c 17 | $(CC) $(CFLAGS) $*.c 18 | 19 | %.$O: %.s 20 | $(AS) -o $*.$O $*.s 21 | 22 | %.s: %.spp 23 | cpp $*.spp >$*.s 24 | 25 | 26 | -------------------------------------------------------------------------------- /win32-386/getcallerpc.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | uintptr 5 | getcallerpc(void *a) 6 | { 7 | return ((uintptr*)a)[-1]; 8 | } 9 | -------------------------------------------------------------------------------- /win32-386/tas.c: -------------------------------------------------------------------------------- 1 | #include "u.h" 2 | #include "libc.h" 3 | 4 | int 5 | tas(long *x) 6 | { 7 | int v; 8 | 9 | __asm__( "movl $1, %%eax\n\t" 10 | "xchgl %%eax,(%%ecx)" 11 | : "=a" (v) 12 | : "c" (x) 13 | ); 14 | switch(v) { 15 | case 0: 16 | case 1: 17 | return v; 18 | default: 19 | print("canlock: corrupted 0x%lux\n", v); 20 | return 1; 21 | } 22 | } 23 | 24 | -------------------------------------------------------------------------------- /win32-factotum.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include "drawterm.h" 8 | 9 | #undef getenv 10 | 11 | char* 12 | getuser(void) 13 | { 14 | return getenv("USER"); 15 | } 16 | 17 | int 18 | dialfactotum(void) 19 | { 20 | return -1; 21 | } 22 | 23 | --------------------------------------------------------------------------------