From 4a7273b827d4179c66c1353623215348df6f4131 Mon Sep 17 00:00:00 2001 From: "Anselm R. Garbe" Date: Thu, 12 Oct 2006 15:11:25 +0200 Subject: [PATCH] reorganized, still liblitz there --- Makefile | 2 +- cmd/wm/area.c => area.c | 0 cmd/wm/bar.c => bar.c | 0 cmd/wm/client.c => client.c | 0 cmd/Makefile | 28 - cmd/wmiimenu.1 | 84 --- cmd/wmiir.1 | 86 --- cmd/wmiir.c | 324 ----------- cmd/wm/column.c => column.c | 0 doc/Makefile | 25 - doc/guide_en.tex | 1005 ----------------------------------- doc/wmii.tex | 83 --- cmd/wm/event.c => event.c | 0 cmd/wm/frame.c => frame.c | 0 cmd/wm/fs.c => fs.c | 0 cmd/wm/geom.c => geom.c | 0 cmd/wm/key.c => key.c | 0 libcext/Makefile | 28 - libcext/assert.c | 10 - libcext/cext.h | 38 -- libcext/malloc.c | 54 -- libcext/strlcat.c | 55 -- libcext/strlcpy.c | 47 -- libcext/tokenize.c | 34 -- libcext/trim.c | 35 -- libixp/Makefile | 25 - libixp/client.c | 220 -------- libixp/convert.c | 236 -------- libixp/intmap.c | 144 ----- libixp/ixp.h | 369 ------------- libixp/message.c | 243 --------- libixp/request.c | 394 -------------- libixp/server.c | 130 ----- libixp/socket.c | 200 ------- libixp/transport.c | 77 --- liblitz/brush.c | 3 +- liblitz/color.c | 3 +- liblitz/font.c | 10 +- cmd/wm/mouse.c => mouse.c | 0 cmd/wm/rule.c => rule.c | 0 test/test_fs.sh | 19 - cmd/wm/view.c => view.c | 0 cmd/wm/wm.c => wm.c | 0 cmd/wm/wm.h => wm.h | 0 cmd/wm/wmii => wmii | 0 cmd/wm/wmii.1 => wmii.1 | 0 doc/wmii.svg => wmii.svg | 0 cmd/wm/wmiiwm.1 => wmiiwm.1 | 0 48 files changed, 7 insertions(+), 4004 deletions(-) rename cmd/wm/area.c => area.c (100%) rename cmd/wm/bar.c => bar.c (100%) rename cmd/wm/client.c => client.c (100%) delete mode 100644 cmd/Makefile delete mode 100644 cmd/wmiimenu.1 delete mode 100644 cmd/wmiir.1 delete mode 100644 cmd/wmiir.c rename cmd/wm/column.c => column.c (100%) delete mode 100644 doc/Makefile delete mode 100644 doc/guide_en.tex delete mode 100644 doc/wmii.tex rename cmd/wm/event.c => event.c (100%) rename cmd/wm/frame.c => frame.c (100%) rename cmd/wm/fs.c => fs.c (100%) rename cmd/wm/geom.c => geom.c (100%) rename cmd/wm/key.c => key.c (100%) delete mode 100644 libcext/Makefile delete mode 100644 libcext/assert.c delete mode 100644 libcext/cext.h delete mode 100644 libcext/malloc.c delete mode 100644 libcext/strlcat.c delete mode 100644 libcext/strlcpy.c delete mode 100644 libcext/tokenize.c delete mode 100644 libcext/trim.c delete mode 100644 libixp/Makefile delete mode 100644 libixp/client.c delete mode 100644 libixp/convert.c delete mode 100644 libixp/intmap.c delete mode 100644 libixp/ixp.h delete mode 100644 libixp/message.c delete mode 100644 libixp/request.c delete mode 100644 libixp/server.c delete mode 100644 libixp/socket.c delete mode 100644 libixp/transport.c rename cmd/wm/mouse.c => mouse.c (100%) rename cmd/wm/rule.c => rule.c (100%) delete mode 100644 test/test_fs.sh rename cmd/wm/view.c => view.c (100%) rename cmd/wm/wm.c => wm.c (100%) rename cmd/wm/wm.h => wm.h (100%) rename cmd/wm/wmii => wmii (100%) rename cmd/wm/wmii.1 => wmii.1 (100%) rename doc/wmii.svg => wmii.svg (100%) rename cmd/wm/wmiiwm.1 => wmiiwm.1 (100%) diff --git a/Makefile b/Makefile index c4dced1b..8519ba24 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ include config.mk -SUBDIRS = libcext liblitz libixp cmd +SUBDIRS = liblitz BIN = cmd/wm/wmii cmd/wm/wmiiwm cmd/wmiir diff --git a/cmd/wm/area.c b/area.c similarity index 100% rename from cmd/wm/area.c rename to area.c diff --git a/cmd/wm/bar.c b/bar.c similarity index 100% rename from cmd/wm/bar.c rename to bar.c diff --git a/cmd/wm/client.c b/client.c similarity index 100% rename from cmd/wm/client.c rename to client.c diff --git a/cmd/Makefile b/cmd/Makefile deleted file mode 100644 index cb762b2c..00000000 --- a/cmd/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# window manager improved 2 utilities -# (C)opyright MMIV-MMVI Anselm R. Garbe - -include ../config.mk - -CFLAGS += -I../liblitz -I../libixp -I../libcext -LDFLAGS += -L../libixp -lixp -L../libcext -lcext -X11LDFLAGS += -L../liblitz -llitz -L../libcext -lcext - -SRC = wmiir.c -ALLSRC = ${SRC} - -all: ${ALLSRC:.c=} - @echo built wmii commands - -.c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< - -${SRC:.c=}: ${SRC:.c=.o} - @echo LD $@ - @${CC} -o $@ $@.o ${LDFLAGS} - -# Solaris -# @${CC} -o $* $*.o ${LDFLAGS} -lsocket - -clean: - rm -f ${ALLSRC:.c=} *.o diff --git a/cmd/wmiimenu.1 b/cmd/wmiimenu.1 deleted file mode 100644 index 5d76ff18..00000000 --- a/cmd/wmiimenu.1 +++ /dev/null @@ -1,84 +0,0 @@ -.TH WMIIMENU 1 wmii-4 -.SH NAME -wmiimenu \- window manager improved 2 menu -.SH SYNOPSIS -.B wmiimenu -.RB [ \-v ] -.RB [ \-t -.IR title ] -.SH DESCRIPTION -.SS Overview -.B wmiimenu -is a generic, highly customizable, and efficient menu for the X Window System, -originally designed for -.BR wmii (1). -It supports arbitrary, user defined menu contents. -.SS Options -.TP -.B \-v -prints version information to stdout, then exits. -.TP -.BI \-t " title" -displays -.I title -above the menu. -.SS Usage -.B wmiimenu -reads a list of newline-separated items from stdin and creates a menu. -When the user selects an item or enters any text and presses Enter, his choice -is printed to stdout and -.B wmiimenu -terminates. -.SS Keyboard Control -.B wmiimenu -is completely controlled by the keyboard. The following keys are recognized: -.TP 2 -Any printable character -appends the character to the text in the input field. This works as a filter: -only items containing this text will be displayed. -.TP 2 -Left/Right (Control-p/Control-n) -select the previous/next item. -.TP 2 -Tab (Control-i) -copy the selected item to the input field. -.TP 2 -Enter (Control-j) -confirm selection and quit (print the selected item to stdout). -.TP 2 -Shift-Enter (Shift-Control-j) -confirm selection and quit (print the text in the input field to stdout). -.TP 2 -Escape (Control-[) -quit without selecting an item. -.TP 2 -Backspace (Control-h) -remove enough characters from the input field to change its filtering effect. -.TP 2 -Control-u -remove all characters from the input field. -.SS Exit codes -.B wmiimenu -returns -.B 0 -if Enter is pressed on termination, -.B 1 -if Escape is pressed. -.SH ENVIRONMENT -.TP -WMII_FONT -The X11 font used to display each item in the menu. -.br -Default: fixed -.TP -WMII_NORMCOLORS -The foreground, background, and border colors of a label. Syntactically, three blank-separated color values of the form #RRGGBB are expected. -.br -Default: #222222 #eeeeee #666666 -.TP -WMII_SELCOLORS -Like WMII_NORMCOLORS, but for the selected label. -.br -Default: #ffffff #335577 #447799 -.SH SEE ALSO -.BR wmii (1) diff --git a/cmd/wmiir.1 b/cmd/wmiir.1 deleted file mode 100644 index b8f05e9e..00000000 --- a/cmd/wmiir.1 +++ /dev/null @@ -1,86 +0,0 @@ -.TH WMIIR 1 wmii-4 -.SH NAME -wmiir \- window manager improved 2 remote -.SH SYNOPSIS -.B wmiir -.RB [ \-a -.IR address ] -.I action -.I file -.br -.B wmiir -.B \-v -.SH DESCRIPTION -.SS Overview -.B wmiir -is a client to access the filesystem of -.BR wmiiwm (1) -from the command line or from shell -scripts. It can be used to configure -.BR wmii (1). -.SS Options -.TP -.BI \-a " address" -Lets you specify the address to which -.B wmiir -will establish a connection. If this option is not supplied, and the -environment variable WMII_ADDRESS is set, -.B wmiir -will use this value as its address. Currently, the address can only be a -unix socket file or a tcp socket. The syntax for -.I address -is taken (along with many other profound ideas) from the Plan 9 operating -system and has the form -.BR unix!/path/to/socket -for unix socket files, and -.BR tcp!hostname!port -for tcp sockets. -.TP -.B \-v -Prints version information to stdout, then exits. -.TP -The syntax of the actions is as follows: -.TP -.B write -Writes the supplied data from stdin to -.IR file, -overwriting any previous data. The data to be written is arbitrary -and only gains meaning (and restrictions) when it is interpreted by -.BR wmiiwm (1). -See -.B EXAMPLES -below. -.TP -.B create -Creates file or directory but does not write any data. If the file exists, -nothing is done. -.TP -.B read -Reads file or directory contents -.TP -.B remove -Removes file or directory tree -.SH ENVIRONMENT -.TP -WMII_ADDRESS -See above. -.SH EXAMPLES -.TP -.B wmiir read / -This prints the root directory of the wmii filesystem. For more information -about the contents of this filesystem, see -.BR wmiiwm (1). -.TP -.B echo -n quit | wmiir write /ctl -Write 'quit' to the main control file of the wmii filesystem, effectively -leaving wmii. -.TP -.B echo -n view 2 | wmiir write /ctl -Bring into view all clients tagged '2'. To learn about clients and -tags, see -.BR wmiiwm (1). -.SH SEE ALSO -.BR wmii (1), -.BR wmiiwm (1) - -http://www.cs.bell-labs.com/sys/man/5/INDEX.html diff --git a/cmd/wmiir.c b/cmd/wmiir.c deleted file mode 100644 index 27d25063..00000000 --- a/cmd/wmiir.c +++ /dev/null @@ -1,324 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include -#include -#include -#include - -#include - -static IXPClient c = { 0 }; - -static char version[] = "wmiir - " VERSION ", (C)opyright MMIV-MMVI Anselm R. Garbe\n"; - -static void -usage() -{ - fprintf(stderr, "%s", - "usage: wmiir [-a
] [-v] create | read | ls [-l] | remove | write \n"); - exit(1); -} - -static void -write_data(unsigned int fid) -{ - void *data = cext_emallocz(c.ofcall.iounit); - unsigned long long offset = 0; - unsigned int len = 0; - - while((len = read(0, data, c.ofcall.iounit)) > 0) { - if(ixp_client_write(&c, fid, offset, len, data) != len) { - fprintf(stderr, "wmiir: cannot write file: %s\n", c.errstr); - break; - } - offset += len; - } - if(offset == 0) /* do an explicit empty write when no writing has been done yet */ - if(ixp_client_write(&c, fid, offset, 0, 0) != 0) - fprintf(stderr, "wmiir: cannot write file: %s\n", c.errstr); - free(data); -} - -static int -xcreate(char *file) -{ - unsigned int fid; - char *p = strrchr(file, '/'); - - if(!p) - p = file; - - fid = c.root_fid << 2; - /* walk to bottom-most directory */ - *p = 0; - if(ixp_client_walk(&c, fid, file) == -1) { - fprintf(stderr, "wmiir: cannot walk to '%s': %s\n", file, c.errstr); - return -1; - } - p++; - if(ixp_client_create(&c, fid, p, IXP_DMWRITE, IXP_OWRITE) == -1) { - fprintf(stderr, "wmiir: cannot create file '%s': %s\n", p, c.errstr); - return -1; - } - if(!(c.ofcall.qid.type&P9DMDIR)) - write_data(fid); - return ixp_client_close(&c, fid); -} - -static int -xwrite(char *file, unsigned char mode) -{ - /* open */ - unsigned int fid = c.root_fid << 2; - if(ixp_client_walkopen(&c, fid, file, mode) == -1) { - fprintf(stderr, "wmiir: cannot open file '%s': %s\n", file, c.errstr); - return -1; - } - write_data(fid); - return ixp_client_close(&c, fid); -} - -static int -comp_stat(const void *s1, const void *s2) -{ - Stat *st1 = (Stat *)s1; - Stat *st2 = (Stat *)s2; - return strcmp(st1->name, st2->name); -} - -static void -setrwx(long m, char *s) -{ - static char *modes[] = - { - "---", - "--x", - "-w-", - "-wx", - "r--", - "r-x", - "rw-", - "rwx", - }; - strncpy(s, modes[m], 3); -} - -static char * -str_of_mode(unsigned int mode) -{ - static char buf[16]; - - if(mode & IXP_DMDIR) - buf[0]='d'; - else - buf[0]='-'; - - buf[1]='-'; - setrwx((mode >> 6) & 7, &buf[2]); - setrwx((mode >> 3) & 7, &buf[5]); - setrwx((mode >> 0) & 7, &buf[8]); - buf[11] = 0; - return buf; -} - -static char * -str_of_time(unsigned int val) -{ - static char buf[32]; - time_t t = (time_t)(int)val; - char *tstr = ctime(&t); - cext_strlcpy(buf, tstr ? tstr : "in v a l id ", sizeof(buf)); - buf[strlen(buf) - 1] = 0; - return buf; -} - -static void -print_stat(Stat *s, int details) -{ - if(details) - fprintf(stdout, "%s %s %s %5llu %s %s\n", str_of_mode(s->mode), - s->uid, s->gid, s->length, str_of_time(s->mtime), s->name); - else { - if(s->mode & IXP_DMDIR) - fprintf(stdout, "%s/\n", s->name); - else - fprintf(stdout, "%s\n", s->name); - } -} - -static void -xls(void *result, unsigned int msize, int details) -{ - unsigned int n = 0, i = 0; - unsigned char *p = result; - Stat *dir; - static Stat stat; - - do { - ixp_unpack_stat(&p, nil, &stat); - n++; - } - while(p - (unsigned char*)result < msize); - dir = (Stat *)cext_emallocz(sizeof(Stat) * n); - p = result; - do { - ixp_unpack_stat(&p, nil, &dir[i++]); - } - while(p - (unsigned char*)result < msize); - qsort(dir, n, sizeof(Stat), comp_stat); - for(i = 0; i < n; i++) - print_stat(&dir[i], details); - free(dir); - fflush(stdout); -} - -static int -xdir(char *file, int details) -{ - unsigned int fid = c.root_fid << 2; - /* XXX: buffer overflow */ - Stat *s = cext_emallocz(sizeof(Stat)); - unsigned char *buf; - int count; - static unsigned char result[IXP_MAX_MSG]; - void *data = nil; - unsigned long long offset = 0; - - if(ixp_client_stat(&c, fid, file) == -1) { - fprintf(stderr, "wmiir: cannot stat file '%s': %s\n", file, c.errstr); - return -1; - } - buf = c.ofcall.stat; - ixp_unpack_stat(&buf, nil, s); - if(!(s->mode & IXP_DMDIR)) { - print_stat(s, details); - fflush(stdout); - return 0; - } - - /* directory */ - if(ixp_client_open(&c, fid, IXP_OREAD) == -1) { - fprintf(stderr, "wmiir: cannot open directory '%s': %s\n", file, c.errstr); - return -1; - } - while((count = ixp_client_read(&c, fid, offset, result, IXP_MAX_MSG)) > 0) { - data = cext_erealloc(data, offset + count); - memcpy(data + offset, result, count); - offset += count; - } - if(count == -1) { - fprintf(stderr, "wmiir: cannot read directory '%s': %s\n", file, c.errstr); - return -1; - } - if(data) - xls(data, offset + count, details); - return ixp_client_close(&c, fid); -} - -static int -xread(char *file) -{ - unsigned int fid = c.root_fid << 2; - int count; - static unsigned char result[IXP_MAX_MSG]; - unsigned long long offset = 0; - - if(ixp_client_walkopen(&c, fid, file, IXP_OREAD) == -1) { - fprintf(stderr, "wmiir: cannot open file '%s': %s\n", file, c.errstr); - return -1; - } - - while((count = ixp_client_read(&c, fid, offset, result, IXP_MAX_MSG)) > 0) { - write(1, result, count); - offset += count; - } - if(count == -1) { - fprintf(stderr, "wmiir: cannot read file/directory '%s': %s\n", file, c.errstr); - return -1; - } - return ixp_client_close(&c, fid); -} - -static int -xremove(char *file) -{ - unsigned int fid; - - fid = c.root_fid << 2; - if(ixp_client_remove(&c, fid, file) == -1) { - fprintf(stderr, "wmiir: cannot remove file '%s': %s\n", file, c.errstr); - return -1; - } - return 0; -} - -int -main(int argc, char *argv[]) -{ - int ret = 0, i = 0, details = 0; - char *cmd, *file, *address = getenv("WMII_ADDRESS"); - - /* command line args */ - if(argc < 2) - usage(); - - for(i = 1; (i < argc) && (argv[i][0] == '-'); i++) { - switch (argv[i][1]) { - case 'v': - fprintf(stdout, "%s", version); - exit(0); - break; - case 'a': - if(i + 1 < argc) - address = argv[++i]; - else - usage(); - break; - default: - usage(); - break; - } - } - cmd = argv[argc - 2]; - file = argv[argc - 1]; - if((details = !strncmp(cmd, "-l", 3))) { - if(argc < 3) - usage(); - if(strncmp(argv[argc - 3], "ls", 3)) - usage(); - cmd = argv[argc - 3]; - } - - if(!address) { - fprintf(stderr, "%s", "wmiir: error: $WMII_ADDRESS not set\n"); - usage(); - } - - if(ixp_client_dial(&c, address, getpid()) == -1) { - fprintf(stderr, "wmiir: %s\n", c.errstr); - exit(1); - } - - if(!strncmp(cmd, "create", 7)) - ret = xcreate(file); - else if(!strncmp(cmd, "ls", 3)) - ret = xdir(file, details); - else if(!strncmp(cmd, "read", 5)) - ret = xread(file); - else if(!strncmp(cmd, "remove", 7)) - ret = xremove(file); - else if(!strncmp(cmd, "write", 6)) - ret = xwrite(file, IXP_OWRITE); - else - usage(); - - /* close socket */ - ixp_client_hangup(&c); - - return ret; -} diff --git a/cmd/wm/column.c b/column.c similarity index 100% rename from cmd/wm/column.c rename to column.c diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 0386ef5e..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# window manager improved 2 user guide -l2h_opts=-local_icons -scalable_fonts -split +1 -subdir -show_section_numbers -address "
Last update: $(shell date) by $$USER@$$HOSTNAME" - -SRC = guide_en.tex wmii.tex -DVI = ${SRC:.tex=.dvi} -PDF = ${SRC:.tex=.pdf} -PS = ${SRC:.tex=.ps} -HTML = ${SRC:.tex=.html} - -.SUFFIXES: .tex .dvi .pdf .ps .html - -all: ${DVI} ${PDF} #${PS} ${HTML} -.tex.dvi: - latex -interaction=batchmode $< - latex -interaction=batchmode $< -.tex.pdf: - pdflatex $< - pdflatex $< -.dvi.ps: - dvips -o $@ $< -.tex.html: - latex2html ${l2h_opts} $< -clean: - rm -f *.pdf *.ps *.dvi *.log *.aux *.out *.toc - rm -rf guide_en diff --git a/doc/guide_en.tex b/doc/guide_en.tex deleted file mode 100644 index 752b2523..00000000 --- a/doc/guide_en.tex +++ /dev/null @@ -1,1005 +0,0 @@ -%TODO: please mention the /def/rules mechanism! - - -%guide to wmii-4 -%Copyright (C) 2005, 2006 by Steffen Liebergeld, Salva Peir\'o - -%This program is free software; you can redistribute it and/or -%modify it under the terms of the GNU General Public License -%as published by the Free Software Foundation, version 2 - -%This program is distributed in the hope that it will be useful, -%but WITHOUT ANY WARRANTY; without even the implied warranty of -%MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -%GNU General Public License for more details. - -%You should have received a copy of the GNU General Public License -%along with this program; if not, write to the Free Software -%Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA -%02110-1301, USA. - -\documentclass[12pt,a4paper]{article} %options given to article are inherited to all packages -\usepackage[latin1]{inputenc} -\usepackage[left=3cm,top=2cm,right=2cm,bottom=3cm]{geometry} -\usepackage{times} -\usepackage{hyperref} % option [dvipdfm] disables clickable refs -\hypersetup{pdftex, colorlinks=true, linkcolor=blue, filecolor=blue, -pagecolor=blue, urlcolor=blue, pdfauthor={Steffen Liebergeld, Salva Pei\'ro}, -pdftitle={A Guide to wmii-4}} -\usepackage{indentfirst,moreverb} -% remove this if you want, it's just a matter of imposed imperialist cultures -% so if I'm given the chance to choose I choose to indent the first paragraph -% (I learn this way in the school, and don't want to relearn the British way) - -%% welcome to the dirty tricks section -\newcommand{\hrefx}[1]{\href{#1}{#1}} % explicit \href -% un'% below so latex2html can handle refs correctly (until a better solution is found) -%\usepackage{html} % gives clickable refs to latex2html -%\renewcommand{\href}[2]{\htmladdnormallink{#2}{#1}} -%\renewcommand{\hrefx}[1]{\htmladdnormallink{#1}{#1}} -%\renewcommand{\verbatiminput}[1]{\input{#1}} -\renewcommand{\familydefault}{\sfdefault} -\newcommand{\wmii}{\emph{wmii}} - -\newenvironment{itemize*} - {\begin{itemize} - \setlength{\itemsep}{0pt} - \setlength{\parskip}{0pt}} - {\end{itemize}} -\date{\today} -\author{ -Steffen\\Liebergeld \\\\ -\small{with help from}\\ -Salvador\\Peir\'o -} - -\title{A Guide to wmii-4% -\thanks{Thanks to the wmii community, in particular all the -people mentioned at \href{http://suckless.org/index.php/WMII/People}{WMII/people}.} -} -%\email{stepardo@gmail.com \and saoret.one@gmail.com} - -\begin{document} - -\maketitle - -\tableofcontents - -\newpage - -\section{Abstract} - - \subsection{The purpose of this document} - - This document tries to be a good starting point for people new to - \wmii-4. People who have used wmi, \wmii-2.5 or even ion will get - to know what is new and different in \wmii-4, and people who have - never used a tiling window manager before will fall in love with - the new concept. - - \subsection{wmii---the second generation of window manager improved} - - \wmii-4 is a new kind of window manager. It is designed to have a - small memory footprint, be extremely modularised and have as - little code as possible, thus ensuring as few bugs as possible. In - fact, one of our official goals is to not exceed $10 k$ lines of - code~\footnote{ benefit of the $10 k$ SLOC restriction is that - it's easier to read/understand, thus it's easier to use and get - used to it}. - - \wmii{} tries to be very portable and to give the user as much - freedom as possible. - - \wmii-4 is the third major release of the second generation of the - window manager improved~\footnote{ the ii is actually the roman - numeral for 2.}. \wmii{} first introduced a new paradigm in version - 2.5, namely dynamic window management, that overcomes the - limitations imposed by the WIMP paradigm (see also the companion - \emph{wmii.tex}). - - \subsection{Target audience} - - I presume the reader already has experience with Unix, knows all - the basic terminology and concepts like files and editors. - - I hope you are open minded towards new ideas, and willing to spend some - time learning \wmii-4~\footnote{remember the refrain: ``nobody - can teach you what you don't want to know''.}. - - If you only want to know how to operate \wmii-4 and are not - interested in the inner workings or in scripting, you may read - sections \ref{sec:conf&install}, \ref{sec:terms} and subsection - \ref{subsec:firststeps} and skip the rest. - - However, to get the most out of \wmii-4 you should probably read - the whole document ``sequentially'', i.e. from beginning to end. - Another possibility is to read/consume the guide ``on demand'' as - you notice you need more information or details to understand - better some concept. We recommend you to read the introductory - chapters first, use some time to get settled in the \wmii-world - and read the scripting chapters later on. - - \section{Configuration and install} - \label{sec:conf&install} - - \subsection{Obtaining wmii} - - \wmii{} is licensed under the MIT/X Consortium License, which - basically means it is free software, and you are free to download - it from \hrefx{http://suckless.org} free of charge~\footnote{ please have - a look at \hrefx{http://suckless.org/repos/wmii/LICENSE} for - details}. - - \subsection{Configuration and installation} - - First of all, have a look if there are binary packages of \wmii{} in - your distribution. Debian, Ubuntu and Gentoo should already have - good packages. If you found a trustworthy package, you may now safely - skip this section. - - For all those who are still reading this, let me tell you that you are - on the good side because if you grab the sources and compile them yourself - you'll benefit from having everything in it's original place, which will - ease your use of \wmii. - - \begin{enumerate} - - \item Uninstalling a previous version: - \begin{verbatim} - cd /path/to/wmii-previous - make uninstall && make clean - \end{verbatim} - - In case you're installing a newer version of \wmii, this is the - first thing you should do otherwise you'll end up mixing - binaries, configuration files and manual-pages of different and - potentially incompatible versions. - - \item Unpack it: - \begin{verbatim} - tar xzf wmii-4.tar.gz - cd wmii-4 - \end{verbatim} - - \item Edit the configuration: - \begin{verbatim} - vim config.mk - \end{verbatim} - - The most important variable to set is the \verb+PREFIX+, which - states, where you want \wmii-4 to be installed to. If you are unsure, keep the - default, it won't break your system. - - \item Run make and make install: - \begin{verbatim} - make && make install - \end{verbatim} - - \item Setup the X-server to start \wmii{} as your default window - manager. You may do that by editing the file \emph{\~{}/.xinitrc}. - - \begin{verbatim} - #!/bin/sh - exec wmii - \end{verbatim} - - % Not necessary, .xinitrc is sourced by xinit anyways - % - % Make sure that the \emph{\~{}/.xinitrc} is executable: - % - % \begin{verbatim} - % chmod u+x ~/.xinitrc - % \end{verbatim} - - \end{enumerate} - - Now you are finished. Please note that autoconf tools are not used - for various reasons~\footnote{ read - \hrefx{http://www.ohse.de/uwe/articles/aal.html} and - \hrefx{http://lists.cse.psu.edu/archives/9fans/2003-November/029714.html} - for further details}. Please don't ask the \wmii{} developers to use autoconf, - they won't listen to you. - - - \section{Terminology} - \label{sec:terms} - - Before you actually start doing your first steps in \wmii, first the - terminology has to be clarified. - - \subsection{Clients} - - A client is a program, that provides you a graphical user interface for - a special purpose, e.g. a web browser, or a terminal. - - \subsection{Focus} - - The (input) focus is the client, which currently receives your input. - In X11 exactly one client can get your input at a time. If you input - some command into your terminal, the terminal window has the input focus, - whereas all the other windows do not receive the input you enter. - - \subsection{Events} - - An event is a message generated by X server to notify X clients about - states. For instance, X generates a button press event, if you click - into a window. - - \subsection{Tags} - - A tag is an alphanumeric string you can associate to clients, - which allows you to group clients in a natural way. - - In \wmii, there are no workspaces anymore. Instead, all clients matching a - particular tag are displayed at a time. For instance, if you tag your - browser and a terminal window with the tag ``web-browser'', and you request - to view all clients matching this tag, \wmii{} will display your browser - and the terminal on the screen. - It is also possible to give clients multiple tags, which is described later. - - \subsection{View} - - A view is the set of displayed clients, which match a specific single tag. - A view is pretty similar to the ``workspace'' metaphor in other window - managers, though more powerful. - - Only one view can be visible at a time. - - Views are related to the tags, which are currently in use. You have exactly - one view for each single tag, thus you can only view sets of clients which - match an existing tag. - - If you destroy the last client with a tag, the view of this tag is - destroyed. - - \subsection{Column} - - A column is a distinct part of a view, where clients are arranged - automatically in a vertical direction. - - In \wmii, you are able to divide each view into different columns. - You should be aware, that every column holds at least one client. - As soon as you close the last client of a column, the column is - destroyed automatically. - - % no, a view might contain floating clients only as well - % Please be aware, that every view has at least one column or a floating window. - - \subsection{Layout} - - A layout is the arrangement of clients in a column. - There are three different ways to arrange clients in a column. - \paragraph{default} This layout arranges each client with - equally vertical space fitting into the column's height. - \paragraph{maximum} This layout arranges all clients with - the same geometry as the column, showing only one of them at a time. - \paragraph{stacking} This layout arranges all clients - like a stack, where only the focused client is completely - visible, and all other clients can be accessed through its title-bars. - This is an alternative approach to \emph{tabbing}. - - \section{Getting started} - - Now it is time to start diving into the \wmii{} user experience. I suggest you - to try everything described by yourself immediately, instead of first reading - it, to avoid "memory leakage". It is very helpful, if you print this - document on paper or have it available on a different screen, because you might not - be able to view it during your first steps in \wmii. - - Note, that the \emph{MOD} key I am referring to, may resemble - different keys on different systems. By default it is the - \emph{Mod1} or \emph{Alt} key in X11. Normally this is the key labelled with - \emph{Alt} on your keyboard. - - The notation \emph{MOD}-\emph{Key} means to press \emph{MOD} and - \emph{Key} both at the same time. - - All key combinations can be freely configured, but for the sake of - simplicity I'll stick with the default key combinations for this - guide. You will learn how to alter the bindings in the - section \ref{sec:scripting}. - - The default key combinations heavily use the home row navigation keys - \emph{h} (left), \emph{j} (down), \emph{k} (up), and \emph{l} (right), - which are associated with the specific direction. - - \subsection{First steps} - \label{subsec:firststeps} - - Start your X session now. Since it is the first time you - start \wmii, a window with a little tutorial will show up. You are - free to read it, but you may also follow this guide :-) - - First of all, press \emph{MOD-Enter} to start an xterm. It will - take half of the vertical space, so you have two equally arranged - windows. If you press \emph{MOD-Enter} again, you have three - windows that are arranged equally. - - To switch between the three windows, press - \emph{MOD-j}, which cycles the focus between the three windows. - - You can also press \emph{MOD-k} to switch to the window above or - \emph{MOD-j} to switch to the window below the current. - - Now look at the title-bars of those windows. They display - important information: the first label contains the tag of - the window. The second label displays the window's title. - - Similar information is displayed in the status-bar at the bottom. The - first labels display the tags currently in use and highlight the currently - selected view. On the right side some status information is displayed, by - default the system load and the current time (see - subsection~\ref{subsec:status} for details). - - \subsection{Using columns} - - As described earlier, \wmii{} uses columns to arrange your windows. - Your view already consists of a single column. - Next, you will create a new column. - - In \wmii{} columns always consists of at least a single client, - thus to create a new column, you need at least two clients at hand. - - Now focus a client of your choice and press \emph{MOD-Shift-l}, - which moves the client rightwards. As you see, \wmii{} creates - a new column by dividing the view horizontally in two equally big - areas. The focused client has been moved into the new column. - - If you close the last client of a column, the column is destroyed - immediately. If the last client of the current view is closed, - the view will be removed accordingly as well. - - If you press \emph{MOD-j} to change focus, you will see that \wmii - actually cycles the focus in the current column only. - - To change the focus to a different column, you can press \emph{MOD-l} - (right) and \emph{MOD-h} (left) respectively. - - It is also possible to swap adjacent clients among columns. To swap - clients leftwards, press \emph{MOD-Control-h}. To swap clients - rightwards, press \emph{MOD-Control-l}. - - \subsection{What about layouts?} - - Layouts arrange clients in a column. They are related to a single - column. Thus it is possible to have different columns in one view, each - using another layout. - - The default layout arranges each client of the column with equally - vertical space. You can enable this layout with \emph{MOD-d} - (where the ``d'' stands for default) explicitly. - - The stacking layout can be enabled with \emph{MOD-s}. As you see now, - there is only one client using as much space as possible, and only - title-bars of the other clients displayed in the column. You can - switch between the clients in the column using \emph{MOD-j}. - - The max-layout maximises all clients to the same geometry as the column. - Only the focused client is displayed at a time, all other clients - are behind it. You can switch between the clients with \emph{MOD-j}. - - \subsection{Floating layer} - - To handle clients in the classical way, like in conventional window - managers, the so-called ``floating layer'' is used. Actually there are a - bunch of clients which don't fit well into the tiled world, because they - have been designed with the conventional window management in mind, - for instance clients like the Gimp or xmms. - - While \wmii{} is a dynamic window manager, which does the window arrangement - for you automatically, those old fashioned programs rely on the - conventional window managing concept, where all the clients fly around on - your desktop and you are forced to constantly order the mess. - - To attach such broken clients to the floating layer, you can toggle the - focus between floating and managed layer through pressing \emph{MOD-Space}. - The \emph{MOD-Shift-Space} shortcut toggles the focused window between - floating and managed layer. - - Note, the floating layer is addressed as the zeroth-column internally. - - \subsection{Tags} - - Up to now all your clients were tagged with ``1'', and you only had - this single view. But a single view does not scale well, once - too many clients appear which are used for different unrelated tasks. - Thus you might want to have a view per task, e.g. a view - with your editor and your programming tools, another view - with your browser, and a third view with your music jukebox. - - The good news is, that the tagging concept provides a very dynamic way to - achieve such kinds of grouping. - - You can give the focused client another tag by pressing - \emph{MOD-Shift-Number}, number being one of the numbers 0 to 9. - - You can then switch views through pressing \emph{MOD-Number}. - - Normally, whenever a new client appears, it automatically inherits the tag - of the currently selected view. - - %% TODO: better tag handling (this is about to change in \wmii{} till - %%version 3) - - Note, there are more powerful uses of tags you will learn about in the next - chapter. You will then be able to assign multiple tags to one client and to - use proper strings as tags. - - \subsection{How do I close a window?} - - Most X-clients have a menu option or button to be closed. For the rare - cases they don't provide a mouse-driven way, like in most terminals, - you can press \emph{MOD-Shift-c} to close a window. - - \subsection{How do I start programs?} - - You may start programs from a terminal. But \wmii{} contains a special - keyboard-driven program menu, which is accessible through pressing - \emph{MOD-p}. Please note, that the content of this menu is provided by a - simple shell-script. - - You will see a list of programs. If you start typing, the - menu will cut the list and only display items which match - the input you entered so far (in that order). Whenever there is - only one item left, the menu highlights it and you can start it - by pressing \emph{Enter}. You are free to cancel any action by - pressing \emph{ESC}. - - Thus, if you want to start firefox, just type ``fire'' and press - enter~\footnote{On my system it is sufficient to type ``efo'' to - start firefox ;-)}. - - \subsection{How do I quit wmii?} - You can quit \wmii, by using the action's menu (\emph{MOD-a}) - and selecting the action ``quit''. That's all. - - \section{Looking under the hood} - - In this chapter you will learn how \wmii{} was designed, which ideas - the \wmii{} developers followed and how it was implemented. - - \subsection{Dynamic window management} - - \wmii{} was designed around the new idea of dynamic window management. - Dynamic window management means, that the window manager should make all - decisions about window arrangement, thus taking most extra work away - from the user and letting him concentrate on his work. This can also be - seen as tacit window management. - - \subsection{Modularity---using distinct tools for distinct tasks} - - The developers of \wmii{} know about the most powerful ideas of - Unix. One of them is the idea to use distinct tools for distinct - tasks. By carefully designing the window manager, they were able to - split the task into several smaller binaries, each with a distinct - job. - - \subsection{The glue that puts it all together---9P} - - Programs in the Unix world usually communicate via buffers which are - addressed by (file) descriptors, one of them are sockets. - - To create a lightweight but powerful communication protocol, the \wmii - developers closely looked at the design of Plan9 and chose the 9P - protocol. - - The basic ideas for configuring and running \wmii{} were taken from - the Acme user interface for programmers of Plan9. Similar to Acme, - \wmii{} provides a filesystem-interface, which can be accessed by - 9P clients. This allows to interact with any different kind of - application through a file system interface, which might be implemented - in any programming language of choice. This also avoids to force - client programmers to a specific programming language or paradigm. - - The interface of \wmii{} can be compared to the \emph{procfs} file - system of the Linux kernel. - - If you want to interact with a running \wmii{} process, you can access its 9P - file-system service through either using the bundled tool \emph{wmiir} or - the 9P2000 kernel module of a Linux kernel later than 2.4.16+. Using the - kernel module has the advantage to mount the filesystem of \wmii{} into your - file system hierarchy directly, though it has the drawback that this need - \emph{root} privileges. - - \subsection{Tools} - - This section provides a basic overview about the tools which are bundled - with \wmii. But for a more detailed description, you should read the associated - man page of the specific tool. - - \begin{description} - - \item - \emph{wmiir} is a small tool we is used to access the - virtual file-system service of \wmii{} remotely. It basically supports four - operations: - - \begin{itemize*} - \item read - \item write - \item remove - \item create - \end{itemize*} - - wmiir needs to know the address of the file-system service to work - with. On startup, \wmii{} exports the \verb+WMII_ADDRESS+ environment variable, - which points to the address of the file-system service of \wmii. - This address can be: - \begin{itemize*} - \item a local unix socket address like \verb+unix!/path/to/socket+ - \item a tcp-capable socket address like \verb+tcp!hostname:port+ - \end{itemize*} - - If you want to work on a different filesystem, you may specify it - manually with the \emph{-a address} command line option. - A sample invocation looks like: - \begin{verbatim} - wmiir read / - \end{verbatim} - This command actually prints the contents of the root directory of the - virtual file-system of \wmii. - - \item - \emph{wmiimenu} is a generic keyboard-driven menu, which matches items - through providing patterns. You may want to learn more about it by reading - the man-page. - - \item - \emph{wmiiwarp} is a tiny tool to warp the mouse pointer at specific - coordinates on your screen. - - \item - \emph{wmiiwm} is the main window manager binary. You may interact - with its virtual file-system only. - - \item - \emph{wmiipsel} prints the contents of the current X selection to - STDOUT. This is useful for scripts. - - \end{description} - - \subsection{Conclusion} - - The virtual file-system service of \wmii{} and the tools presented enable - you to fully control the window manager from scripts. - You will see some examples in the next section - \ref{sec:scripting}. - - \section{Scripting wmii} - \label{sec:scripting} - - In this chapter you will see how to control \wmii{} through scripts. I will - give you some pointers, that you can start scripting on your own. - - \subsection{Language} - - As mentioned earlier, the only requirement for interacting with \wmii{} is to - access its file-system service. The easiest way to do this, is by using - the wmiir tool. Thus shell scripts are the easiest way of adapting \wmii - too fit your needs. - - Hence, you can control \wmii{} in any programming language you want. However, - \wmii's default scripts are written in a subset of ``sh'' that is POSIX - compliant, to keep \wmii{} as \emph{portable} as possible. - - To keep simplicity, the following examples will stick to ``sh'' as well, - and don't depend on python, tcl, ruby, \dots - - % - who doesn't have a shell?, extra! we're giving them for free this week - - \subsection{Actions} - - In \wmii{} you may group certain tasks into \emph{actions}. Actions - are nothing more than simple scripts which are located either in - your local or in the default \wmii{} configuration - directory~\footnote{ \texttt{\$CONFPREFIX} is set in - \emph{config.mk} which points to \texttt{/usr/local/etc} - or \texttt{\$HOME/.wmii-4} by default}. - Through pressing \emph{MOD-a} you can open the actions menu. It works - similar to the program menu, but only displays actions. - - You might want to add your own actions through writing shell scripts in the - default \wmii{} configuration directory or in the \texttt{\$HOME/.wmii-4}. - - This works, because in the \wmii{} controlling script exports the variable - \verb+$PATH+ as\\ \verb+$PATH=~/.wmii-4:$CONFPREFIX/wmii:$PATH+ before - launching the wmiiwm, this way local user actions under - \verb+~/.wmii-4+ take precedence over the defaults from - \verb+$CONFPREFIX/wmii+ of the default actions. - - You may edit this file on the fly, which means you don't need to - stop \wmii{} before editing. After you've finished editing, you may - simply run wmiirc and the changes will take effect immediately. - To do so, just open the actions menu (with pressing \emph{MOD-a}) and - choose the \emph{wmiirc} action. It's also possible to launch \wmii{} actions - directly from a terminal, which is a neat side effect that results from - exporting \verb+$PATH+ in the \wmii{} startup script. - - \subsection{wmiirc} - - \emph{wmiirc} is a special ``sh''-script which is launched on startup - of \wmii{} to take care of configuring and controlling \wmii. - - It does so through writing data to several files of the virtual \wmii - file-system, and through reading events reported by \wmii{} during runtime. - Events are mostly shortcut presses, mouse clicks or user-defined. - The events are processed in a loop in the script. - - Thus, for the basic configuration of \wmii, like changing the default - modifier key \emph{MOD=Mod1} or the navigation keys this script is - the place to look at. - - The name \emph{wmiirc} means \wmii{} \emph{run command}, because ``rc'' is an - old Unix abbreviation for ``run command''. - - \subsection{Changing the style} - - The style of \wmii-4 is defined through font and colour values, which are - unobtrusively exported with the following \emph{environment variables}. - - \begin{verbatim} - WMII_SELCOLORS='#000000 #eaffff #8888cc' - WMII_NORMCOLORS='#000000 #ffffea #bdb76b' - WMII_FONT=static - \end{verbatim} - - \verb+WMII_SELCOLORS+ defines the colours of the selected client's window - title and border, whereas \verb+WMII_NORMCOLORS+ defines the colours of all - unselected clients. The numbers are hexadecimal rgb tuple-values, which you - might know from HTML. You can grab them with the Gimps colour-chooser for instance. - - The first colour defines the text colour of strings in bars and menus. - The second colour defines the background colour of bars and clients, and - the third colour defines the 1px borders surrounding bars and clients. - - \verb+WMII_FONT+ defines the font which should be used for drawing text. - in title-bars, the status-bar, and the wmiimenu. - You can query for different fonts using \emph{xfontsel} for instance. - - \subsection{Filling the status-bar} - \label{subsec:status} - - The status bar of \wmii{} has it's own \verb+/bar+ directory with - a subdirectory for each of the labels created. So while editing - this document my status-bar looked like: - - \begin{verbatim} - $ wmiir read /bar - d-r-x------ salva salva 0 Mon Apr 17 14:19:51 2006 1 - d-r-x------ salva salva 0 Mon Apr 17 14:19:51 2006 2 - d-r-x------ salva salva 0 Mon Apr 17 14:19:51 2006 status - \end{verbatim} - - At the same time each of the subdirectories contains two files, - - \begin{verbatim} - $ wmiir read /bar/status - --rw------- salva salva 23 Mon Apr 17 14:22:14 2006 colors - --rw------- salva salva 23 Mon Apr 17 14:22:14 2006 data - \end{verbatim} - - - The first file contains the colour definitions that control how the - bar will be drawn, while the second contains the data - which is displayed. - - Now you can start your own experiments by creating a new label, and - exploring and modifying it by reading \& writing values to it's - \verb+colors+ \& \verb+data+ files. A nice feature of the bar - (and clients) is that they generate events corresponding to mouse - clicks on them. You can open a terminal and run - \verb+wmiir read /event+ to see how the events are generated - when you click onto the status-bar. This is a mechanism that allows - controlling applications directly from the bar. If you've - finished and you want to get rid of your label, - a \verb+wmiir remove /bar/foo+ command. - - If you want to learn more, take a look at the status script and - visit \hrefx{http://suckless.org} for good examples, like the following: - - \begin{itemize*} - \item \emph{status}: monitoring remaining battery, temperature, \dots on laptops - \item \emph{status-mpd}: controlling the running mpd - \item \emph{status-load}: show the machine load - \item \emph{status-net}: monitoring wireless network signal - \end{itemize*} - - Now open the default status script and try to understand yourself, - how it works \verbatiminput{../rc/status}. The first line is a handy - \verb+xwrite+ function declaration, to prevent you from several verbosity - when issuing a write to some file. The following 3 lines take care of - creating and setting up the \verb+status+ label. The last section is a - \verb+while+ loop - that \emph{tries} to write the system load and date information - to the bar.\\ - - The tricky bit is, that it \emph{tries}. So what could make the write - fail? If \verb+xwrite+ tried to write to a non existent (removed) - label, then it would fail, thus the condition of the loop would be - false, and the status script exits cleanly, which makes sense - because nobody wants a program that updates a nonexistent label.\\ - - Now go back to the first lines of the script, and note - that there is a \verb+sleep delay+ between the removal of the - label and it's creation. - - This ensures that the \verb+status+ label will not exist, hence all - the writes made from any previously running \verb+status+ script - will fail, thus they will finish. This way we make sure that - we only run one status script at each time. And thus we keep the - one-to-one correspondence between label and status script. - - \subsection{Assigning new tags} - - As mentioned before, you can achieve more powerful things with tags, than - with the standard key-bindings. You might use any string as a tag. You may - even use more than one tag per client. To do so, you have to separate the - tags with a ``+''. - - \begin{verbatim} - echo -n web+code | wmiir write /view/sel/sel/tags - \end{verbatim} - - This command would give the current focused client the tags - ``web'' and ``code''. - - You can now view the ``web'' tag by executing the following: - - \begin{verbatim} - echo -n view web | wmiir write /ctl - \end{verbatim} - - As the development of \wmii-4 progressed, it became clear that this - action is so common, that it got its own keybinding. By default - \emph{MOD-t} brings up a menu to choose a view and - \emph{MOD-Shift-t} brings up a menu enabling you to assign new - tags to the focused client. - - % TODO: - % I would also like to put/see a recommended readings or bibliography - % section this will be of course biased by my use of plumber and acme - % from p9p but i think it's worth mentioning both them here. similar to: - % http://suckless.org/contrib/guide-es/beginnersguide/node10.html - - \section{The End} - \label{sec:end} - - We hope this helps you getting used to \wmii. - If you've seen something that you think is wrong, confusing or missing in - this document, feel free to drop us a note: - - Contact information is to be found here: - \href{http://suckless.org/index.php/BeginnersGuide}{direct mail}, - \href{http://suckless.org/index.php/MailingList}{[wmii]} mailing-list, - \href{http://suckless.org/index.php/IRC}{\#wmii} irc channel or even - with smoke signals~\footnote{ but don't ask us for advice, here - you're on your own \texttt{;-P}.}. - - Also remember that \wmii{} is written by people with taste, so most - of the decisions made have strong reasons supporting them, so if - you think something doesn't make sense or doesn't fit into the - picture, just try to understand it by yourself first before - asking, probably you'll end up learning a lot and if its really - wrong in the end, you'll provide us with much better feedback to - solve the issue. - - \newpage - - \section{Appendix} - \label{sec:appendix} - - \subsection{filesystem} - - \begin{description} - - \item [/bar] - \begin{itemize*} - \item the bar namespace - \item to add a label, create /bar/\verb+label+ (this automatically creates the - \verb+colors+ and \verb+data+ files. - \item to delete it, remove /bar/\verb+label+ - \end{itemize*} - - \item [/bar/label] - \begin{itemize*} - \item each bar has it's own namespace which is named according to it's - label - \item label can be any arbitrary string - \end{itemize*} - - \item [/bar/label/data] - \begin{itemize*} - \item the data written to the label \verb+label+ - \end{itemize*} - - \item [/bar/label/colors] - \begin{itemize*} - \item the colours of the bar - \end{itemize*} - - \item [/client] - \begin{itemize*} - \item the clients namespace - \end{itemize*} - - \item [/client/n] - \begin{itemize*} - \item every client, including ones not shown in the view has a namespace here - \item \verb+n+ is a non-negative integer and clients are numbered oldest first - \end{itemize*} - - \item [/client/n/class] - \begin{itemize*} - \item a file containing the class:instance information for client \verb+n+ - \end{itemize*} - - \item [/client/n/ctl] - \begin{itemize*} - \item control file for client \verb+n+ - \item accepted commands: - \begin{itemize*} - \item kill (removes client) - \item sendto \verb+area|prev|next|new+ - \item swap \verb+up|down|prev|next+ - \end{itemize*} - \end{itemize*} - - \item [/client/n/geom] - \begin{itemize*} - \item the window geometry of client \verb+n+ - \item displayed as four blank separated integers (x y width height?) - \end{itemize*} - - \item [/client/n/index] contains the client's index in the /client namespace, in this case n - - \item [/client/n/name] - \begin{itemize*} - \item the name of client \verb+n+ as it's seen by \wmii{} (displayed in the tagbar) - \end{itemize*} - - \item [/client/n/tags] - \begin{itemize*} - \item a plus(+)-separated list of tags to which client \verb+n+ is related - \end{itemize*} - - \item [/ctl] - \begin{itemize*} - \item the \wmii{} control file and command interface - \item accepted commands: - \begin{itemize*} - \item quit - \item retag - \item view \verb+tag+ - \end{itemize*} - \end{itemize*} - - \item [/def] - \item [/def/border] width of the border around clients - \item [/def/font] the font used by \wmii{} (an xlib font name) - \item [/def/keys] a newline separated list of the keys to be grabbed by \wmii - \item [/def/rules] - \begin{itemize*} - \item a newline separated list of rules to specify how to automatically tag clients - \item matches against the class.instance values of a client - \item syntax: \verb+/$regex/ -> $tag+ (tag might be \~{} to indicate floating mode - \end{itemize*} - \item [/def/colwidth] with of newly created columns (in px) - \item [/def/colmode] mode of newly created columns - - - \item [/view] - \begin{itemize*} - \item a manifestation of the collection of clients associated with a specific - tag - \end{itemize*} - - \item [/view/area] - \begin{itemize*} - \item each area has its own namespace in the current view - \item the areas are numbered starting with 0 - \item 0 is always the floating area, the others are columns - \end{itemize*} - - \item [/view/area/ctl] - \begin{itemize*} - \item accepted commands: - \begin{itemize*} - \item select \verb+client|prev|next+ - \item client refers to the client number relative to the number and - age of the clients in \verb+area+ - \end{itemize*} - \end{itemize*} - - \item [/view/area/mode] the current layout for the area, equal, stack or max - \item [/view/area/sel] the selected client of the area - \item [/view/area/client] the namespace for each client in \verb+area+ - \item [/view/ctl] accepted commands: select \verb+area|prev|next|toggle+ - \item [/view/sel] the selected area in workspace - \item [/view/tag] the tag which is common to all clients in the workspace - - \end{description} - - \newpage - - \subsection{keybindings} - Here are the default keybindings. \verb+$MODKEY+ is a placeholder, which is - usually mapped to Mod1 or Alt. - \begin{table}[h] - \begin{tabular}{|l|l|} - \hline % Puts in a horizontal line - Keybinding &Action \\ %Table Headers , columns separated by &, - %rows ended by \\ - \hline - \hline - Moving Focus&\\ - \verb+$MODKEY+-h&move focus to prev column \\ - \verb+$MODKEY+-l&move focus to next column \\ - \verb+$MODKEY+-j&move focus to next client in column \\ - \verb+$MODKEY+-k&move focus to prev client in column \\ - \verb+$MODKEY+-space&toggle to/from floating column 0 \\ - \verb+$MODKEY+-[0-9]&select tag/view [0-9] \\ - Moving Clients&\\ - \verb+$MODKEY+-Control-h&swap client with last client of prev column \\ - \verb+$MODKEY+-Control-l&swap client with last client of next column \\ - \verb+$MODKEY+-Control-j&swap client down in the column \\ - \verb+$MODKEY+-Control-k&swap client up in the column \\ - \verb+$MODKEY+-Shift-h&send client to prev column \\ - \verb+$MODKEY+-Shift-l&send client to next column \\ - \verb+$MODKEY+-Shift-space&send client to/from floating column 0 \\ - \verb+$MODKEY+-Shift-[0-9]&send client to tag/view [0-9] \\ - Layouts&\\ - \verb+$MODKEY+-d&select default layout \\ - \verb+$MODKEY+-s&select stacked layout \\ - \verb+$MODKEY+-m&select max layout \\ - Menu Bar Functions&\\ - \verb+$MODKEY+-a&choose action from menu bar \\ - \verb+$MODKEY+-p&choose program from menu bar \\ - \verb+$MODKEY+-t&choose view from menu bar \\ - \verb+$MODKEY+-Shift-t&assign tag(s) to client from menu bar \\ - Clients and Applications&\\ - \verb+$MODKEY+-Return&open terminal client \\ - \verb+$MODKEY+-Shift-c&kill client \\ - \hline - \end{tabular} - \caption{Default keybindings of \wmii} - \end{table} - - \newpage - - \section{Credits} - \label{sec:credits} - - - \begin{description} - \item [Author] Steffen Liebergeld - \item [Main critic and inquisitor] Salvador Peir\'o - - \item [Helpers] - Anselm Garbe \\ - Denis Grelich \\ - Ross Mohn \\ - Neptun Florin \\ - Jochen Schwartz \\ - Adrian Ratnapala \\ - \end{description} - - \section{Copyright notice} - - guide to wmii-4\\ - Copyright (C) 2005, 2006 by Steffen Liebergeld, Salva Peir\'o - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, version 2 - - This program is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA - 02110-1301, USA. - -\end{document} diff --git a/doc/wmii.tex b/doc/wmii.tex deleted file mode 100644 index cb087686..00000000 --- a/doc/wmii.tex +++ /dev/null @@ -1,83 +0,0 @@ -% (C)opyright 2005 by Anselm R. Garbe -\documentclass{article} \usepackage{times} \begin{document} - -\title{Improved GUI concepts for experienced users} - -\author{Anselm R. Garbe\\ \small garbeam at gmail dot com} - -\maketitle \thispagestyle{empty} - -\begin{abstract} -This article presents the motivation and concepts of the dynamic -window manager wmii and the graphical toolkit liblitz for the -\it{X Window System}. -\end{abstract} - - -%------------------------------------------------------------------------- -\section{Motivation} - -Most common graphical user interfaces are designed after the WIMP\cite{wimp} -paradigm, which has dominated the desktop environment -landscape since late 1980s. While research has been done on alternative -user interfaces, often the focus targeted more in ease of use and low -learning curves for new computer users rather than in efficiency and -power of abstraction. - -The main reason has been the economical success of computers -in the normal consumer market, which consists of unexperienced users mainly. -Our motivation is to change this situation and to provide a graphical -user interface for experienced users, though we know that this market is -a niche. - -There has been done rarly research in the non-wimp GUI landscape for years. -Back in 80s and early 90s there has been some research in -this area for the Plan 9\cite{plan9} operating system at Bell Labs. -Most recent research has been done by individuals only, like Tuomo Valkonen with -his Ion\cite{ion} project and Lars Bernhardsson with his -LarsWM\cite{larswm} project. - -The approaches found in the Plan 9 operating system are interesting, because -on the one hand they cancelled the Unix tradition to work in Teletype emulators -and on the other hand, they didn't followed the WIMP paradigm propagated by Apple, -IBM or Microsoft. This makes Plan 9 the most unique approach compared to the -classical WIMP world. - -The main aspects of an improved GUI consists of two things, a powerful -window management approach and a sane and simple widget set which fits well -into this window management approach. - -In the area of improved window management concepts there has been done more -research, thus there appeared several different approaches. But the area -of improved widget sets which form powerful applications with a simple widget -set has been ignored for long time. Instead, the WIMP world introduced many -widgets which seem to focus on eye-candy, like progress bars, but don't -fix the essential problems with WIMP toolkits. - - - -\section{Future} - - -\section*{Acknowlegdements} Following people provided useful feedback or several -grammar fixes to this article: -\begin{itemize} -\item Frank Boehme (1st version of this article) -\item Tuncer M zayamut Ayaz (1st version of this article) -\end{itemize} - -\begin{thebibliography}{99} -\bibitem{wimp} Ashley George Taylor, WIMP Interfaces, CS6751 Topic Report: Winter '97 -\bibitem{x} X Window System - http://www.freedesktop.org -\bibitem{plan9} plan9 operating system - http://cm.bell-labs.com/plan9dist/ -\bibitem{acme} Rob Pike, Acme: A User Interface for Programmers - -http://www.cs.bell-labs.com/sys/doc/acme/acme.html -\bibitem{rat} Ratpoison window manager - http://www.nongnu.org/ratpoison/ -\bibitem{evil} evilwm window manager - http://evilwm.sf.net -\bibitem{ion} Ion window manager - http://modeemi.cs.tut.fi/~tuomov/ion/ -\bibitem{larswm} LarsWM window manager - http://www.fnurt.net/larswm/ -\bibitem{vi} Vi Improved (VIM) - http://www.vim.org -\bibitem{9p} 9P protocol - http://www.cs.bell-labs.com/sys/man/5/INDEX.html -\end{thebibliography} - -\end{document} diff --git a/cmd/wm/event.c b/event.c similarity index 100% rename from cmd/wm/event.c rename to event.c diff --git a/cmd/wm/frame.c b/frame.c similarity index 100% rename from cmd/wm/frame.c rename to frame.c diff --git a/cmd/wm/fs.c b/fs.c similarity index 100% rename from cmd/wm/fs.c rename to fs.c diff --git a/cmd/wm/geom.c b/geom.c similarity index 100% rename from cmd/wm/geom.c rename to geom.c diff --git a/cmd/wm/key.c b/key.c similarity index 100% rename from cmd/wm/key.c rename to key.c diff --git a/libcext/Makefile b/libcext/Makefile deleted file mode 100644 index 61af1623..00000000 --- a/libcext/Makefile +++ /dev/null @@ -1,28 +0,0 @@ -# libcext - c extensions for wmii project -# (C)opyright MMIV-MMVI Anselm R. Garbe - -include ../config.mk - -SRC = assert.c malloc.c strlcat.c strlcpy.c tokenize.c \ - trim.c - -OBJ = ${SRC:.c=.o} - -.PREFIXES = .c .o - -all: libcext.a - @echo built libcext - -.c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< - -$(OBJ): cext.h - -libcext.a: ${OBJ} - @echo AR $@ - @${AR} $@ ${OBJ} - @${RANLIB} $@ - -clean: - rm -f libcext.a *.o diff --git a/libcext/assert.c b/libcext/assert.c deleted file mode 100644 index 1a3f2847..00000000 --- a/libcext/assert.c +++ /dev/null @@ -1,10 +0,0 @@ -/* Public Domain */ -#include -#include - -void -cext_failed_assert(char *a, char *file, int line) -{ - fprintf(stderr, "Assertion \"%s\" failed at %s:%d\n", a, file, line); - abort(); -} diff --git a/libcext/cext.h b/libcext/cext.h deleted file mode 100644 index fcc4a840..00000000 --- a/libcext/cext.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include - -#ifndef nil -#define nil (void *)0 -#endif - -/* asprintf.c */ -extern int cext_asprintf(char **str, char const *fmt, ...); - -/* malloc.c */ -extern void *cext_emallocz(unsigned int size); -extern void *cext_emalloc(unsigned int size); -extern void *cext_erealloc(void *ptr, unsigned int size); -extern char *cext_estrdup(const char *str); - -/* strlcat.c */ -extern unsigned int cext_strlcat(char *dst, const char *src, unsigned int siz); - -/* strlcpy.c */ -extern unsigned int cext_strlcpy(char *dst, const char *src, unsigned int siz); - -/* tokenize.c */ -extern unsigned int cext_tokenize(char **result, unsigned int reslen, char *str, char delim); - -/* trim.c */ -extern void cext_trim(char *str, const char *chars); - -/* assert.c */ -#define cext_assert(a) do { \ - if(!(a)) \ - cext_failed_assert(#a, __FILE__, __LINE__); \ - } while (0) -extern void cext_failed_assert(char *a, char *file, int line); diff --git a/libcext/malloc.c b/libcext/malloc.c deleted file mode 100644 index 8ce624fb..00000000 --- a/libcext/malloc.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include - -#include "cext.h" - -static void -bad_malloc(unsigned int size) -{ - fprintf(stderr, "fatal: could not malloc() %d bytes\n", - (int) size); - exit(1); -} - -void * -cext_emallocz(unsigned int size) -{ - void *res = calloc(1, size); - if(!res) - bad_malloc(size); - return res; -} - -void * -cext_emalloc(unsigned int size) -{ - void *res = malloc(size); - if(!res) - bad_malloc(size); - return res; -} - -void * -cext_erealloc(void *ptr, unsigned int size) -{ - void *res = realloc(ptr, size); - if(!res) - bad_malloc(size); - return res; -} - -char * -cext_estrdup(const char *str) -{ - void *res = strdup(str); - if(!res) - bad_malloc(strlen(str)); - return res; -} diff --git a/libcext/strlcat.c b/libcext/strlcat.c deleted file mode 100644 index ef2ce993..00000000 --- a/libcext/strlcat.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include -#include - -#include "cext.h" - -/* - * Appends src to string dst of size siz (unlike strncat, siz is the - * full size of dst, not space left). At most siz-1 characters - * will be copied. Always NUL terminates (unless siz <= strlen(dst)). - * Returns strlen(src) + MIN(siz, strlen(initial dst)). - * If retval >= siz, truncation occurred. - */ -unsigned int -cext_strlcat(char *dst, const char *src, unsigned int siz) -{ - register char *d = dst; - register const char *s = src; - register unsigned int n = siz; - unsigned int dlen; - - /* Find the end of dst and adjust bytes left but don't go past end */ - while(n-- != 0 && *d != 0) - d++; - dlen = d - dst; - n = siz - dlen; - - if(n == 0) - return (dlen + strlen(s)); - while(*s != 0) { - if(n != 1) { - *d++ = *s; - n--; - } - s++; - } - *d = 0; - - return (dlen + (s - src)); /* count does not include NUL */ -} diff --git a/libcext/strlcpy.c b/libcext/strlcpy.c deleted file mode 100644 index df049d72..00000000 --- a/libcext/strlcpy.c +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 1998 Todd C. Miller - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include - -#include "cext.h" - -/* - * Copy src to string dst of size siz. At most siz-1 characters - * will be copied. Always NUL terminates (unless siz == 0). - * Returns strlen(src); if retval >= siz, truncation occurred. - */ -unsigned int -cext_strlcpy(char *dst, const char *src, unsigned int siz) -{ - register char *d = dst; - register const char *s = src; - register unsigned int n = siz; - - /* Copy as many bytes as will fit */ - if(n != 0 && --n != 0) { - do { - if((*d++ = *s++) == 0) - break; - } while(--n != 0); - } - /* Not enough room in dst, add NUL and traverse rest of src */ - if(n == 0) { - if(siz != 0) - *d = '\0'; /* NUL-terminate dst */ - while(*s++); - } - return (s - src - 1); /* count does not include NUL */ -} diff --git a/libcext/tokenize.c b/libcext/tokenize.c deleted file mode 100644 index bbc017fe..00000000 --- a/libcext/tokenize.c +++ /dev/null @@ -1,34 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include - -#include "cext.h" - -unsigned int -cext_tokenize(char **result, unsigned int reslen, char *str, char delim) -{ - char *p, *n; - unsigned int i = 0; - - if(!str) - return 0; - for(n = str; *n == delim; n++); - p = n; - for(i = 0; *n != 0;) { - if(i == reslen) - return i; - if(*n == delim) { - *n = 0; - if(strlen(p)) - result[i++] = p; - p = ++n; - } else - n++; - } - if((i < reslen) && (p < n) && strlen(p)) - result[i++] = p; - return i; /* number of tokens */ -} diff --git a/libcext/trim.c b/libcext/trim.c deleted file mode 100644 index e4f1163d..00000000 --- a/libcext/trim.c +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (c) MMVI Anselm R. Garbe - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -#include "cext.h" - -/* - * Removes all characters in chars from str. - */ -void -cext_trim(char *str, const char *chars) -{ - const char *cp; - char *sp, *sn; - - for(cp = chars; *cp; cp++) { - for(sp = sn = str; *sn; sn++) { - if(*sn != *cp) - *(sp++) = *sn; - } - *sp = 0; - } -} diff --git a/libixp/Makefile b/libixp/Makefile deleted file mode 100644 index 22e3888a..00000000 --- a/libixp/Makefile +++ /dev/null @@ -1,25 +0,0 @@ -# libixp - lib ixp protocol -# (C)opyright MMIV-MMVI Anselm R. Garbe - -include ../config.mk - -CFLAGS += -I ../libcext - -SRC = client.c convert.c message.c server.c socket.c transport.c intmap.c request.c - -OBJ = ${SRC:.c=.o} - -all: libixp.a - @echo built libixp - -.c.o: - @echo CC $< - @${CC} -c ${CFLAGS} $< - -libixp.a: ${OBJ} - @echo AR $@ - @${AR} $@ ${OBJ} - @${RANLIB} $@ - -clean: - rm -f libixp.a *.o diff --git a/libixp/client.c b/libixp/client.c deleted file mode 100644 index bd9b90aa..00000000 --- a/libixp/client.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include -#include -#include -#include - -#include "ixp.h" - -int -ixp_client_do_fcall(IXPClient *c) -{ - static unsigned char msg[IXP_MAX_MSG]; - unsigned int msize = ixp_fcall2msg(msg, &c->ifcall, IXP_MAX_MSG); - - c->errstr = 0; - if(ixp_send_message(c->fd, msg, msize, &c->errstr) != msize) - return -1; - if(!ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &c->errstr)) - return -1; - if(!(msize = ixp_msg2fcall(&c->ofcall, msg, IXP_MAX_MSG))) { - c->errstr = "received bad message"; - return -1; - } - if(c->ofcall.type == RERROR) { - c->errstr = c->ofcall.ename; - return -1; - } - - return 0; -} - -int -ixp_client_dial(IXPClient *c, char *sockfile, unsigned int rootfid) -{ - - if((c->fd = ixp_connect_sock(sockfile)) < 0) { - c->errstr = "cannot connect server"; - return -1; - } - - c->ifcall.type = TVERSION; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.msize = IXP_MAX_MSG; - c->ifcall.version = IXP_VERSION; - if(ixp_client_do_fcall(c) == -1) { - fprintf(stderr, "error: %s\n", c->errstr); - ixp_client_hangup(c); - return -1; - } - if(strncmp(c->ofcall.version, IXP_VERSION, strlen(IXP_VERSION))) { - fprintf(stderr, "error: %s\n", c->errstr); - c->errstr = "9P versions differ"; - ixp_client_hangup(c); - return -1; /* we cannot handle this version */ - } - free(c->ofcall.version); - c->root_fid = rootfid; - - c->ifcall.type = TATTACH; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = c->root_fid; - c->ifcall.afid = IXP_NOFID; - c->ifcall.uname = getenv("USER"); - c->ifcall.aname = ""; - if(ixp_client_do_fcall(c) == -1) { - fprintf(stderr, "error: %s\n", c->errstr); - ixp_client_hangup(c); - return -1; - } - c->root_qid = c->ofcall.qid; - - return 0; -} - -int -ixp_client_remove(IXPClient *c, unsigned int newfid, char *filepath) -{ - - if(ixp_client_walk(c, newfid, filepath) == -1) - return -1; - c->ifcall.type = TREMOVE; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = newfid; - - return ixp_client_do_fcall(c); -} - -int -ixp_client_create(IXPClient *c, unsigned int dirfid, char *name, - unsigned int perm, unsigned char mode) -{ - c->ifcall.type = TCREATE; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = dirfid; - c->ifcall.name = name; - c->ifcall.perm = perm; - c->ifcall.mode = mode; - return ixp_client_do_fcall(c); -} - -int -ixp_client_walk(IXPClient *c, unsigned int newfid, char *filepath) -{ - unsigned int i; - char *wname[IXP_MAX_WELEM]; - - c->ifcall.type = TWALK; - c->ifcall.fid = c->root_fid; - c->ifcall.newfid = newfid; - if(filepath) { - c->ifcall.name = filepath; - c->ifcall.nwname = - cext_tokenize(wname, IXP_MAX_WELEM, c->ifcall.name, '/'); - for(i = 0; i < c->ifcall.nwname; i++) - c->ifcall.wname[i] = wname[i]; - } - return ixp_client_do_fcall(c); -} - -int -ixp_client_stat(IXPClient *c, unsigned int newfid, char *filepath) -{ - - if(ixp_client_walk(c, newfid, filepath) == -1) - return -1; - - c->ifcall.type = TSTAT; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = newfid; - return ixp_client_do_fcall(c); -} - -int -ixp_client_open(IXPClient *c, unsigned int newfid, unsigned char mode) -{ - - c->ifcall.type = TOPEN; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = newfid; - c->ifcall.mode = mode; - return ixp_client_do_fcall(c); -} - -int -ixp_client_walkopen(IXPClient *c, unsigned int newfid, char *filepath, - unsigned char mode) -{ - - if(ixp_client_walk(c, newfid, filepath) == -1) - return -1; - return ixp_client_open(c, newfid, mode); -} - -int -ixp_client_read(IXPClient *c, unsigned int fid, unsigned long long offset, - void *result, unsigned int res_len) -{ - unsigned int bytes = c->ofcall.iounit; - - c->ifcall.type = TREAD; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = fid; - c->ifcall.offset = offset; - c->ifcall.count = res_len < bytes ? res_len : bytes; - if(ixp_client_do_fcall(c) == -1) - return -1; - memcpy(result, c->ofcall.data, c->ofcall.count); - free(c->ofcall.data); - - return c->ofcall.count; -} - -int -ixp_client_write(IXPClient *c, unsigned int fid, - unsigned long long offset, unsigned int count, - unsigned char *data) -{ - - if(count > c->ofcall.iounit) { - c->errstr = "iounit exceeded"; - return -1; - } - - c->ifcall.type = TWRITE; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = fid; - c->ifcall.offset = offset; - c->ifcall.count = count; - c->ifcall.data = (void *)data; - if(ixp_client_do_fcall(c) == -1) - return -1; - - return c->ofcall.count; -} - -int -ixp_client_close(IXPClient *c, unsigned int fid) -{ - - c->ifcall.type = TCLUNK; - c->ifcall.tag = IXP_NOTAG; - c->ifcall.fid = fid; - return ixp_client_do_fcall(c); -} - -void -ixp_client_hangup(IXPClient *c) -{ - /* session finished, now shutdown */ - if(c->fd) { - shutdown(c->fd, SHUT_RDWR); - close(c->fd); - } -} diff --git a/libixp/convert.c b/libixp/convert.c deleted file mode 100644 index c8aacd5f..00000000 --- a/libixp/convert.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include "ixp.h" - -/* packode/unpackode stuff */ - -void -ixp_pack_u8(unsigned char **msg, int *msize, unsigned char val) -{ - if(!msize || (*msize -= 1) >= 0) - *(*msg)++ = val; -} - -void -ixp_unpack_u8(unsigned char **msg, int *msize, unsigned char *val) -{ - if(!msize || (*msize -= 1) >= 0) - *val = *(*msg)++; -} - -void -ixp_pack_u16(unsigned char **msg, int *msize, unsigned short val) -{ - if(!msize || (*msize -= 2) >= 0) { - *(*msg)++ = val; - *(*msg)++ = val >> 8; - } -} - -void -ixp_unpack_u16(unsigned char **msg, int *msize, unsigned short *val) -{ - if(!msize || (*msize -= 2) >= 0) { - *val = *(*msg)++; - *val |= *(*msg)++ << 8; - } -} - -void -ixp_pack_u32(unsigned char **msg, int *msize, unsigned int val) -{ - if(!msize || (*msize -= 4) >= 0) { - *(*msg)++ = val; - *(*msg)++ = val >> 8; - *(*msg)++ = val >> 16; - *(*msg)++ = val >> 24; - } -} - -void -ixp_unpack_u32(unsigned char **msg, int *msize, unsigned int *val) -{ - if(!msize || (*msize -= 4) >= 0) { - *val = *(*msg)++; - *val |= *(*msg)++ << 8; - *val |= *(*msg)++ << 16; - *val |= *(*msg)++ << 24; - } -} - -void -ixp_pack_u64(unsigned char **msg, int *msize, unsigned long long val) -{ - if(!msize || (*msize -= 8) >= 0) { - *(*msg)++ = val; - *(*msg)++ = val >> 8; - *(*msg)++ = val >> 16; - *(*msg)++ = val >> 24; - *(*msg)++ = val >> 32; - *(*msg)++ = val >> 40; - *(*msg)++ = val >> 48; - *(*msg)++ = val >> 56; - } -} - -void -ixp_unpack_u64(unsigned char **msg, int *msize, unsigned long long *val) -{ - if(!msize || (*msize -= 8) >= 0) { - *val |= *(*msg)++; - *val |= *(*msg)++ << 8; - *val |= *(*msg)++ << 16; - *val |= *(*msg)++ << 24; - *val |= (unsigned long long)*(*msg)++ << 32; - *val |= (unsigned long long)*(*msg)++ << 40; - *val |= (unsigned long long)*(*msg)++ << 48; - *val |= (unsigned long long)*(*msg)++ << 56; - } -} - -void -ixp_pack_string(unsigned char **msg, int *msize, const char *s) -{ - unsigned short len = s ? strlen(s) : 0; - ixp_pack_u16(msg, msize, len); - if(s) - ixp_pack_data(msg, msize, (void *)s, len); -} - -void -ixp_unpack_strings(unsigned char **msg, int *msize, unsigned short n, char **strings) { - unsigned char *s = *msg; - unsigned int i, size = 0; - unsigned short len; - for(i=0; i= 0) { - *string = cext_emalloc(*len+1); - if(*len) - memcpy(*string, *msg, *len); - (*string)[*len] = 0; - *msg += *len; - } -} - -void -ixp_pack_data(unsigned char **msg, int *msize, unsigned char *data, unsigned int datalen) -{ - if(!msize || (*msize -= datalen) >= 0) { - memcpy(*msg, data, datalen); - *msg += datalen; - } -} - -void -ixp_unpack_data(unsigned char **msg, int *msize, unsigned char **data, unsigned int datalen) -{ - if(!msize || (*msize -= datalen) >= 0) { - *data = cext_emallocz(datalen); - memcpy(*data, *msg, datalen); - *msg += datalen; - } -} - -void -ixp_pack_prefix(unsigned char *msg, unsigned int size, unsigned char id, - unsigned short tag) -{ - ixp_pack_u32(&msg, 0, size); - ixp_pack_u8(&msg, 0, id); - ixp_pack_u16(&msg, 0, tag); -} - -void -ixp_unpack_prefix(unsigned char **msg, unsigned int *size, unsigned char *id, - unsigned short *tag) -{ - int msize; - ixp_unpack_u32(msg, nil, size); - msize = *size; - ixp_unpack_u8(msg, &msize, id); - ixp_unpack_u16(msg, &msize, tag); -} - -void -ixp_pack_qid(unsigned char **msg, int *msize, Qid * qid) -{ - ixp_pack_u8(msg, msize, qid->type); - ixp_pack_u32(msg, msize, qid->version); - ixp_pack_u64(msg, msize, qid->path); -} - -void -ixp_unpack_qid(unsigned char **msg, int *msize, Qid * qid) -{ - ixp_unpack_u8(msg, msize, &qid->type); - ixp_unpack_u32(msg, msize, &qid->version); - ixp_unpack_u64(msg, msize, &qid->path); -} - -void -ixp_pack_stat(unsigned char **msg, int *msize, Stat * stat) -{ - ixp_pack_u16(msg, msize, ixp_sizeof_stat(stat) - sizeof(unsigned short)); - ixp_pack_u16(msg, msize, stat->type); - ixp_pack_u32(msg, msize, stat->dev); - ixp_pack_qid(msg, msize, &stat->qid); - ixp_pack_u32(msg, msize, stat->mode); - ixp_pack_u32(msg, msize, stat->atime); - ixp_pack_u32(msg, msize, stat->mtime); - ixp_pack_u64(msg, msize, stat->length); - ixp_pack_string(msg, msize, stat->name); - ixp_pack_string(msg, msize, stat->uid); - ixp_pack_string(msg, msize, stat->gid); - ixp_pack_string(msg, msize, stat->muid); -} - -void -ixp_unpack_stat(unsigned char **msg, int *msize, Stat * stat) -{ - unsigned short dummy; - *msg += sizeof(unsigned short); - ixp_unpack_u16(msg, msize, &stat->type); - ixp_unpack_u32(msg, msize, &stat->dev); - ixp_unpack_qid(msg, msize, &stat->qid); - ixp_unpack_u32(msg, msize, &stat->mode); - ixp_unpack_u32(msg, msize, &stat->atime); - ixp_unpack_u32(msg, msize, &stat->mtime); - ixp_unpack_u64(msg, msize, &stat->length); - ixp_unpack_string(msg, msize, &stat->name, &dummy); - ixp_unpack_string(msg, msize, &stat->uid, &dummy); - ixp_unpack_string(msg, msize, &stat->gid, &dummy); - ixp_unpack_string(msg, msize, &stat->muid, &dummy); -} diff --git a/libixp/intmap.c b/libixp/intmap.c deleted file mode 100644 index 13491901..00000000 --- a/libixp/intmap.c +++ /dev/null @@ -1,144 +0,0 @@ -/* This file is derived from src/lib9p/intmap.c from plan9port */ -/* See LICENCE.p9p for terms of use */ -#include -#include "ixp.h" -#define USED(v) if(v){}else{} - -struct Intlist { - unsigned long id; - void* aux; - Intlist* link; - unsigned int ref; -}; - -static unsigned long -hashid(Intmap *map, unsigned long id) -{ - return id%map->nhash; -} - -static void -nop(void *v) -{ - USED(v); -} - -void -initmap(Intmap *m, unsigned long nhash, void *hash) -{ - m->nhash = nhash; - m->hash = hash; -} - -static Intlist** -llookup(Intmap *map, unsigned long id) -{ - Intlist **lf; - - for(lf=&map->hash[hashid(map, id)]; *lf; lf=&(*lf)->link) - if((*lf)->id == id) - break; - return lf; -} - -void -freemap(Intmap *map, void (*destroy)(void*)) -{ - int i; - Intlist *p, *nlink; - - if(destroy == nil) - destroy = nop; - for(i=0; inhash; i++){ - for(p=map->hash[i]; p; p=nlink){ - nlink = p->link; - destroy(p->aux); - free(p); - } - } -} -void -execmap(Intmap *map, void (*run)(void*)) -{ - int i; - Intlist *p, *nlink; - - for(i=0; inhash; i++){ - for(p=map->hash[i]; p; p=nlink){ - nlink = p->link; - run(p->aux); - } - } -} - -void* -lookupkey(Intmap *map, unsigned long id) -{ - Intlist *f; - void *v; - - if((f = *llookup(map, id))) - v = f->aux; - else - v = nil; - return v; -} - -void* -insertkey(Intmap *map, unsigned long id, void *v) -{ - Intlist *f; - void *ov; - unsigned long h; - - if((f = *llookup(map, id))){ - /* no decrement for ov because we're returning it */ - ov = f->aux; - f->aux = v; - }else{ - f = cext_emallocz(sizeof(*f)); - f->id = id; - f->aux = v; - h = hashid(map, id); - f->link = map->hash[h]; - map->hash[h] = f; - ov = nil; - } - return ov; -} - -int -caninsertkey(Intmap *map, unsigned long id, void *v) -{ - Intlist *f; - int rv; - unsigned long h; - - if(*llookup(map, id)) - rv = 0; - else{ - f = cext_emallocz(sizeof *f); - f->id = id; - f->aux = v; - h = hashid(map, id); - f->link = map->hash[h]; - map->hash[h] = f; - rv = 1; - } - return rv; -} - -void* -deletekey(Intmap *map, unsigned long id) -{ - Intlist **lf, *f; - void *ov; - - if((f = *(lf = llookup(map, id)))){ - ov = f->aux; - *lf = f->link; - free(f); - }else - ov = nil; - return ov; -} diff --git a/libixp/ixp.h b/libixp/ixp.h deleted file mode 100644 index a1bfd096..00000000 --- a/libixp/ixp.h +++ /dev/null @@ -1,369 +0,0 @@ -/* - *(C)opyright MMIV-MMVI Anselm R. Garbe - *See LICENSE file for license details. - */ - -#include -#include - -#define IXP_VERSION "9P2000" -#define IXP_NOTAG (unsigned short)~0U /*Dummy tag */ -#define IXP_NOFID (unsigned int)~0 /*No auth */ - -enum { IXP_MAX_VERSION = 32, - IXP_MAX_ERROR = 128, - IXP_MAX_CACHE = 32, - IXP_MAX_MSG = 8192, - IXP_MAX_FLEN = 128, - IXP_MAX_ULEN = 32, - IXP_MAX_WELEM = 16 }; - -/* 9P message types */ -enum { TVERSION = 100, - RVERSION, - TAUTH = 102, - RAUTH, - TATTACH = 104, - RATTACH, - TERROR = 106, /* illegal */ - RERROR, - TFLUSH = 108, - RFLUSH, - TWALK = 110, - RWALK, - TOPEN = 112, - ROPEN, - TCREATE = 114, - RCREATE, - TREAD = 116, - RREAD, - TWRITE = 118, - RWRITE, - TCLUNK = 120, - RCLUNK, - TREMOVE = 122, - RREMOVE, - TSTAT = 124, - RSTAT, - TWSTAT = 126, - RWSTAT, -}; - -/* borrowed from libc.h of Plan 9 */ -enum { IXP_DMDIR = 0x80000000, /* mode bit for directories */ - IXP_DMAPPEND = 0x40000000, /* mode bit for append only files */ - IXP_DMEXCL = 0x20000000, /* mode bit for exclusive use files */ - IXP_DMMOUNT = 0x10000000, /* mode bit for mounted channel */ - IXP_DMAUTH = 0x08000000, /* mode bit for authentication file */ - IXP_DMTMP = 0x04000000, /* mode bit for non-backed-up file */ - IXP_DMREAD = 0x4<<6, /* mode bit for read permission */ - IXP_DMWRITE = 0x2<<6, /* mode bit for write permission */ - IXP_DMEXEC = 0x1<<6 /* mode bit for execute permission */ -}; - -/* modes */ -enum { IXP_OREAD = 0x00, - IXP_OWRITE = 0x01, - IXP_ORDWR = 0x02, - IXP_OEXEC = 0x03, - IXP_OEXCL = 0x04, - IXP_OTRUNC = 0x10, - IXP_OREXEC = 0x20, - IXP_ORCLOSE = 0x40, - IXP_OAPPEND = 0x80, -}; - -/* qid.types */ -enum { IXP_QTDIR = 0x80, - IXP_QTAPPEND = 0x40, - IXP_QTEXCL = 0x20, - IXP_QTMOUNT = 0x10, - IXP_QTAUTH = 0x08, - IXP_QTTMP = 0x04, - IXP_QTSYMLINK = 0x02, - IXP_QTLINK = 0x01, - IXP_QTFILE = 0x00, -}; - -/* from libc.h in p9p */ -enum { P9OREAD = 0, /* open for read */ - P9OWRITE = 1, /* write */ - P9ORDWR = 2, /* read and write */ - P9OEXEC = 3, /* execute, == read but check execute permission */ - P9OTRUNC = 16, /* or'ed in (except for exec), truncate file first */ - P9OCEXEC = 32, /* or'ed in, close on exec */ - P9ORCLOSE = 64, /* or'ed in, remove on close */ - P9ODIRECT = 128, /* or'ed in, direct access */ - P9ONONBLOCK = 256, /* or'ed in, non-blocking call */ - P9OEXCL = 0x1000, /* or'ed in, exclusive use (create only) */ - P9OLOCK = 0x2000, /* or'ed in, lock after opening */ - P9OAPPEND = 0x4000 /* or'ed in, append only */ -}; - -/* bits in Qid.type */ -enum { P9QTDIR = 0x80, /* type bit for directories */ - P9QTAPPEND = 0x40, /* type bit for append only files */ - P9QTEXCL = 0x20, /* type bit for exclusive use files */ - P9QTMOUNT = 0x10, /* type bit for mounted channel */ - P9QTAUTH = 0x08, /* type bit for authentication file */ - P9QTTMP = 0x04, /* type bit for non-backed-up file */ - P9QTSYMLINK = 0x02, /* type bit for symbolic link */ - P9QTFILE = 0x00 /* type bits for plain file */ -}; - -/* bits in Dir.mode */ -#define P9DMDIR 0x80000000 /* mode bit for directories */ -#define P9DMAPPEND 0x40000000 /* mode bit for append only files */ -#define P9DMEXCL 0x20000000 /* mode bit for exclusive use files */ -#define P9DMMOUNT 0x10000000 /* mode bit for mounted channel */ -#define P9DMAUTH 0x08000000 /* mode bit for authentication file */ -#define P9DMTMP 0x04000000 /* mode bit for non-backed-up file */ -#define P9DMSYMLINK 0x02000000 /* mode bit for symbolic link (Unix, 9P2000.u) */ -#define P9DMDEVICE 0x00800000 /* mode bit for device file (Unix, 9P2000.u) */ -#define P9DMNAMEDPIPE 0x00200000 /* mode bit for named pipe (Unix, 9P2000.u) */ -#define P9DMSOCKET 0x00100000 /* mode bit for socket (Unix, 9P2000.u) */ -#define P9DMSETUID 0x00080000 /* mode bit for setuid (Unix, 9P2000.u) */ -#define P9DMSETGID 0x00040000 /* mode bit for setgid (Unix, 9P2000.u) */ - -enum { P9DMREAD = 0x4, /* mode bit for read permission */ - P9DMWRITE = 0x2, /* mode bit for write permission */ - P9DMEXEC = 0x1 /* mode bit for execute permission */ -}; - - -typedef struct Qid Qid; -struct Qid { - unsigned char type; - unsigned int version; - unsigned long long path; - /* internal use only */ - unsigned char dir_type; -}; - -/* stat structure */ -typedef struct Stat { - unsigned short type; - unsigned int dev; - Qid qid; - unsigned int mode; - unsigned int atime; - unsigned int mtime; - unsigned long long length; - char *name; - char *uid; - char *gid; - char *muid; -} Stat; - -/* from fcall(3) in plan9port */ -typedef struct Fcall { - unsigned char type; - unsigned short tag; - unsigned int fid; - union { - struct { /* Tversion, Rversion */ - unsigned int msize; - char *version; - }; - struct { /* Tflush */ - unsigned short oldtag; - }; - struct { /* Rerror */ - char *ename; - }; - struct { /* Ropen, Rcreate */ - Qid qid; /* +Rattach */ - unsigned int iounit; - }; - struct { /* Rauth */ - Qid aqid; - }; - struct { /* Tauth, Tattach */ - unsigned int afid; - char *uname; - char *aname; - }; - struct { /* Tcreate */ - unsigned int perm; - char *name; - unsigned char mode; /* +Topen */ - }; - struct { /* Twalk */ - unsigned int newfid; - unsigned short nwname; - char *wname[IXP_MAX_WELEM]; - }; - struct { /* Rwalk */ - unsigned short nwqid; - Qid wqid[IXP_MAX_WELEM]; - }; - struct { /* Twrite */ - unsigned long long offset; /* +Tread */ - /* +Rread */ - unsigned int count; /* +Tread */ - char *data; - }; - struct { /* Twstat, Rstat */ - unsigned short nstat; - unsigned char *stat; - }; - }; -} Fcall; - -typedef struct IXPServer IXPServer; -typedef struct IXPConn IXPConn; -typedef struct Intmap Intmap; - -typedef struct Intlist Intlist; -struct Intmap { - unsigned long nhash; - Intlist **hash; -}; - -struct IXPConn { - IXPServer *srv; - void *aux; - int fd; - void (*read) (IXPConn *); - void (*close) (IXPConn *); - char closed; - - /* Implementation details */ - /* do not use */ - IXPConn *next; -}; - -struct IXPServer { - int running; - IXPConn *conn; - int maxfd; - fd_set rd; -}; - -typedef struct IXPClient { - int fd; - unsigned int root_fid; - Qid root_qid; - Fcall ifcall; - Fcall ofcall; - char *errstr; -} IXPClient; - -typedef struct P9Conn P9Conn; -typedef struct Fid { - P9Conn *conn; - Intmap *map; - char *uid; - void *aux; - unsigned long fid; - Qid qid; - signed char omode; -} Fid; - -typedef struct P9Req P9Req; -struct P9Req { - P9Conn *conn; - Fid *fid; - Fid *newfid; - P9Req *oldreq; - Fcall ifcall; - Fcall ofcall; - void *aux; -}; - -typedef struct P9Srv { - void (*attach)(P9Req *r); - void (*clunk)(P9Req *r); - void (*create)(P9Req *r); - void (*flush)(P9Req *r); - void (*open)(P9Req *r); - void (*read)(P9Req *r); - void (*remove)(P9Req *r); - void (*stat)(P9Req *r); - void (*walk)(P9Req *r); - void (*write)(P9Req *r); - void (*freefid)(Fid *f); -} P9Srv; - -/* client.c */ -extern int ixp_client_dial(IXPClient *c, char *address, unsigned int rootfid); -extern void ixp_client_hangup(IXPClient *c); -extern int ixp_client_remove(IXPClient *c, unsigned int newfid, char *filepath); -extern int ixp_client_create(IXPClient *c, unsigned int dirfid, char *name, - unsigned int perm, unsigned char mode); -extern int ixp_client_walk(IXPClient *c, unsigned int newfid, char *filepath); -extern int ixp_client_stat(IXPClient *c, unsigned int newfid, char *filepath); -extern int ixp_client_walkopen(IXPClient *c, unsigned int newfid, char *filepath, - unsigned char mode); -extern int ixp_client_open(IXPClient *c, unsigned int newfid, unsigned char mode); -extern int ixp_client_read(IXPClient *c, unsigned int fid, - unsigned long long offset, void *result, - unsigned int res_len); -extern int ixp_client_write(IXPClient *c, unsigned int fid, - unsigned long long offset, - unsigned int count, unsigned char *data); -extern int ixp_client_close(IXPClient *c, unsigned int fid); -extern int ixp_client_do_fcall(IXPClient * c); - -/* convert.c */ -extern void ixp_pack_u8(unsigned char **msg, int *msize, unsigned char val); -extern void ixp_unpack_u8(unsigned char **msg, int *msize, unsigned char *val); -extern void ixp_pack_u16(unsigned char **msg, int *msize, unsigned short val); -extern void ixp_unpack_u16(unsigned char **msg, int *msize, unsigned short *val); -extern void ixp_pack_u32(unsigned char **msg, int *msize, unsigned int val); -extern void ixp_unpack_u32(unsigned char **msg, int *msize, unsigned int *val); -extern void ixp_pack_u64(unsigned char **msg, int *msize, unsigned long long val); -extern void ixp_unpack_u64(unsigned char **msg, int *msize, unsigned long long *val); -extern void ixp_pack_string(unsigned char **msg, int *msize, const char *s); -extern void ixp_unpack_strings(unsigned char **msg, int *msize, unsigned short n, char **strings); -extern void ixp_unpack_string(unsigned char **msg, int *msize, char **string, unsigned short *len); -extern void ixp_pack_data(unsigned char **msg, int *msize, unsigned char *data, - unsigned int datalen); -extern void ixp_unpack_data(unsigned char **msg, int *msize, unsigned char **data, - unsigned int datalen); -extern void ixp_pack_prefix(unsigned char *msg, unsigned int size, - unsigned char id, unsigned short tag); -extern void ixp_unpack_prefix(unsigned char **msg, unsigned int *size, - unsigned char *id, unsigned short *tag); -extern void ixp_pack_qid(unsigned char **msg, int *msize, Qid *qid); -extern void ixp_unpack_qid(unsigned char **msg, int *msize, Qid *qid); -extern void ixp_pack_stat(unsigned char **msg, int *msize, Stat *stat); -extern void ixp_unpack_stat(unsigned char **msg, int *msize, Stat *stat); - -/* request.c */ -extern void respond(P9Req *r, char *error); -extern void serve_9pcon(IXPConn *c); - -/* intmap.c */ -extern void initmap(Intmap *m, unsigned long nhash, void *hash); -extern void incref_map(Intmap *m); -extern void decref_map(Intmap *m); -extern void freemap(Intmap *map, void (*destroy)(void*)); -extern void execmap(Intmap *map, void (*destroy)(void*)); -extern void* lookupkey(Intmap *map, unsigned long id); -extern void* insertkey(Intmap *map, unsigned long id, void *v); -extern int caninsertkey(Intmap *map, unsigned long id, void *v); -extern void* deletekey(Intmap *map, unsigned long id); - -/* message.c */ -extern unsigned short ixp_sizeof_stat(Stat *stat); -extern unsigned int ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen); -extern unsigned int ixp_msg2fcall(Fcall *call, void *msg, unsigned int msglen); - -/* server.c */ -extern IXPConn *ixp_server_open_conn(IXPServer *s, int fd, void *aux, - void (*read)(IXPConn *c), void (*close)(IXPConn *c)); -extern void ixp_server_close_conn(IXPConn *c); -extern char *ixp_server_loop(IXPServer *s); -extern unsigned int ixp_server_receive_fcall(IXPConn *c, Fcall *fcall); -extern int ixp_server_respond_fcall(IXPConn *c, Fcall *fcall); -extern int ixp_server_respond_error(IXPConn *c, Fcall *fcall, char *errstr); -extern void ixp_server_close(IXPServer *s); - -/* socket.c */ -extern int ixp_connect_sock(char *address); -extern int ixp_create_sock(char *address, char **errstr); - -/* transport.c */ -extern unsigned int ixp_send_message(int fd, void *msg, unsigned int msize, char **errstr); -extern unsigned int ixp_recv_message(int fd, void *msg, unsigned int msglen, char **errstr); diff --git a/libixp/message.c b/libixp/message.c deleted file mode 100644 index b493047c..00000000 --- a/libixp/message.c +++ /dev/null @@ -1,243 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include -#include "ixp.h" - -#define IXP_QIDSZ (sizeof(unsigned char) + sizeof(unsigned int)\ - + sizeof(unsigned long long)) - -static unsigned short -sizeof_string(const char *s) -{ - return sizeof(unsigned short) + strlen(s); -} - -unsigned short -ixp_sizeof_stat(Stat * stat) -{ - return IXP_QIDSZ - + 2 * sizeof(unsigned short) - + 4 * sizeof(unsigned int) - + sizeof(unsigned long long) - + sizeof_string(stat->name) - + sizeof_string(stat->uid) - + sizeof_string(stat->gid) - + sizeof_string(stat->muid); -} - -unsigned int -ixp_fcall2msg(void *msg, Fcall *fcall, unsigned int msglen) -{ - unsigned int i = sizeof(unsigned char) + - sizeof(unsigned short) + sizeof(unsigned int); - int msize = msglen - i; - unsigned char *p = msg + i; - - switch (fcall->type) { - case TVERSION: - case RVERSION: - ixp_pack_u32(&p, &msize, fcall->msize); - ixp_pack_string(&p, &msize, fcall->version); - break; - case TAUTH: - ixp_pack_u32(&p, &msize, fcall->afid); - ixp_pack_string(&p, &msize, fcall->uname); - ixp_pack_string(&p, &msize, fcall->aname); - break; - case RAUTH: - ixp_pack_qid(&p, &msize, &fcall->aqid); - break; - case RATTACH: - ixp_pack_qid(&p, &msize, &fcall->qid); - break; - case TATTACH: - ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_u32(&p, &msize, fcall->afid); - ixp_pack_string(&p, &msize, fcall->uname); - ixp_pack_string(&p, &msize, fcall->aname); - break; - case RERROR: - ixp_pack_string(&p, &msize, fcall->ename); - break; - case TFLUSH: - ixp_pack_u16(&p, &msize, fcall->oldtag); - break; - case TWALK: - ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_u32(&p, &msize, fcall->newfid); - ixp_pack_u16(&p, &msize, fcall->nwname); - for(i = 0; i < fcall->nwname; i++) - ixp_pack_string(&p, &msize, fcall->wname[i]); - break; - case RWALK: - ixp_pack_u16(&p, &msize, fcall->nwqid); - for(i = 0; i < fcall->nwqid; i++) - ixp_pack_qid(&p, &msize, &fcall->wqid[i]); - break; - case TOPEN: - ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_u8(&p, &msize, fcall->mode); - break; - case ROPEN: - case RCREATE: - ixp_pack_qid(&p, &msize, &fcall->qid); - ixp_pack_u32(&p, &msize, fcall->iounit); - break; - case TCREATE: - ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_string(&p, &msize, fcall->name); - ixp_pack_u32(&p, &msize, fcall->perm); - ixp_pack_u8(&p, &msize, fcall->mode); - break; - case TREAD: - ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_u64(&p, &msize, fcall->offset); - ixp_pack_u32(&p, &msize, fcall->count); - break; - case RREAD: - ixp_pack_u32(&p, &msize, fcall->count); - ixp_pack_data(&p, &msize, (unsigned char *)fcall->data, fcall->count); - break; - case TWRITE: - ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_u64(&p, &msize, fcall->offset); - ixp_pack_u32(&p, &msize, fcall->count); - ixp_pack_data(&p, &msize, (unsigned char *)fcall->data, fcall->count); - break; - case RWRITE: - ixp_pack_u32(&p, &msize, fcall->count); - break; - case TCLUNK: - case TREMOVE: - case TSTAT: - ixp_pack_u32(&p, &msize, fcall->fid); - break; - case RSTAT: - ixp_pack_u16(&p, &msize, fcall->nstat); - ixp_pack_data(&p, &msize, fcall->stat, fcall->nstat); - break; - case TWSTAT: - ixp_pack_u32(&p, &msize, fcall->fid); - ixp_pack_u16(&p, &msize, fcall->nstat); - ixp_pack_data(&p, &msize, fcall->stat, fcall->nstat); - break; - } - - if(msize < 0) - return 0; - - msize = msglen - msize; - ixp_pack_prefix(msg, msize, fcall->type, fcall->tag); - return msize; -} - -unsigned int -ixp_msg2fcall(Fcall *fcall, void *msg, unsigned int msglen) -{ - int msize; - unsigned int i, tsize; - unsigned short len; - unsigned char *p = msg; - ixp_unpack_prefix(&p, (unsigned int *)&msize, &fcall->type, &fcall->tag); - tsize = msize; - - if(msize > msglen) /* bad message */ - return 0; - switch (fcall->type) { - case TVERSION: - case RVERSION: - ixp_unpack_u32(&p, &msize, &fcall->msize); - ixp_unpack_string(&p, &msize, &fcall->version, &len); - break; - case TAUTH: - ixp_unpack_u32(&p, &msize, &fcall->afid); - ixp_unpack_string(&p, &msize, &fcall->uname, &len); - ixp_unpack_string(&p, &msize, &fcall->aname, &len); - break; - case RAUTH: - ixp_unpack_qid(&p, &msize, &fcall->aqid); - break; - case RATTACH: - ixp_unpack_qid(&p, &msize, &fcall->qid); - break; - case TATTACH: - ixp_unpack_u32(&p, &msize, &fcall->fid); - ixp_unpack_u32(&p, &msize, &fcall->afid); - ixp_unpack_string(&p, &msize, &fcall->uname, &len); - ixp_unpack_string(&p, &msize, &fcall->aname, &len); - break; - case RERROR: - ixp_unpack_string(&p, &msize, &fcall->ename, &len); - break; - case TFLUSH: - ixp_unpack_u16(&p, &msize, &fcall->oldtag); - break; - case TWALK: - ixp_unpack_u32(&p, &msize, &fcall->fid); - ixp_unpack_u32(&p, &msize, &fcall->newfid); - ixp_unpack_u16(&p, &msize, &fcall->nwname); - ixp_unpack_strings(&p, &msize, fcall->nwname, fcall->wname); - break; - case RWALK: - ixp_unpack_u16(&p, &msize, &fcall->nwqid); - for(i = 0; i < fcall->nwqid; i++) - ixp_unpack_qid(&p, &msize, &fcall->wqid[i]); - break; - case TOPEN: - ixp_unpack_u32(&p, &msize, &fcall->fid); - ixp_unpack_u8(&p, &msize, &fcall->mode); - break; - case ROPEN: - case RCREATE: - ixp_unpack_qid(&p, &msize, &fcall->qid); - ixp_unpack_u32(&p, &msize, &fcall->iounit); - break; - case TCREATE: - ixp_unpack_u32(&p, &msize, &fcall->fid); - ixp_unpack_string(&p, &msize, &fcall->name, &len); - ixp_unpack_u32(&p, &msize, &fcall->perm); - ixp_unpack_u8(&p, &msize, &fcall->mode); - break; - case TREAD: - ixp_unpack_u32(&p, &msize, &fcall->fid); - ixp_unpack_u64(&p, &msize, &fcall->offset); - ixp_unpack_u32(&p, &msize, &fcall->count); - break; - case RREAD: - ixp_unpack_u32(&p, &msize, &fcall->count); - ixp_unpack_data(&p, &msize, (void *)&fcall->data, fcall->count); - break; - case TWRITE: - ixp_unpack_u32(&p, &msize, &fcall->fid); - ixp_unpack_u64(&p, &msize, &fcall->offset); - ixp_unpack_u32(&p, &msize, &fcall->count); - ixp_unpack_data(&p, &msize, (void *)&fcall->data, fcall->count); - break; - case RWRITE: - ixp_unpack_u32(&p, &msize, &fcall->count); - break; - case TCLUNK: - case TREMOVE: - case TSTAT: - ixp_unpack_u32(&p, &msize, &fcall->fid); - break; - case RSTAT: - ixp_unpack_u16(&p, &msize, &len); - ixp_unpack_data(&p, &msize, &fcall->stat, len); - break; - case TWSTAT: - ixp_unpack_u32(&p, &msize, &fcall->fid); - ixp_unpack_u16(&p, &msize, &len); - ixp_unpack_data(&p, &msize, &fcall->stat, len); - break; - } - - if(msize > 0) - return tsize; - return 0; -} diff --git a/libixp/request.c b/libixp/request.c deleted file mode 100644 index f1123f71..00000000 --- a/libixp/request.c +++ /dev/null @@ -1,394 +0,0 @@ -/* - * (C)opyright MMVI Kris Maglione - * See LICENSE file for license details. - */ - -#include -#include -#include -#include -#include "ixp.h" - -static void ixp_handle_req(P9Req *r); - -/* We use string literals rather than arrays here because - * they're allocated in a readonly section */ -static char - *Eduptag = "tag in use", - *Edupfid = "fid in use", - *Enofunc = "function not implemented", - *Ebotch = "9P protocol botch", - *Enofile = "file does not exist", - *Enofid = "fid does not exist", - *Enotag = "tag does not exist", - *Enotdir = "not a directory", - *Einterrupted = "interrupted", - *Eisdir = "cannot perform operation on a directory"; - -enum { TAG_BUCKETS = 64, - FID_BUCKETS = 64 }; - -struct P9Conn { - Intmap tagmap; - void *taghash[TAG_BUCKETS]; - Intmap fidmap; - void *fidhash[FID_BUCKETS]; - P9Srv *srv; - IXPConn *conn; - unsigned int msize; - unsigned char *buf; - unsigned int ref; -}; - -static void -free_p9conn(P9Conn *pc) { - free(pc->buf); - free(pc); -} - -static void * -createfid(Intmap *map, int fid, P9Conn *pc) { - Fid *f = cext_emallocz(sizeof(Fid)); - f->fid = fid; - f->omode = -1; - f->map = map; - f->conn = pc; - if(caninsertkey(map, fid, f)) - return f; - free(f); - return nil; -} - -static int -destroyfid(P9Conn *pc, unsigned long fid) { - Fid *f; - if(!(f = deletekey(&pc->fidmap, fid))) - return 0; - if(pc->srv->freefid) - pc->srv->freefid(f); - free(f); - return 1; -} - -void -ixp_server_handle_fcall(IXPConn *c) -{ - Fcall fcall = {0}; - P9Conn *pc = c->aux; - P9Req *req; - unsigned int msize; - char *errstr = nil; - - if(!(msize = ixp_recv_message(c->fd, pc->buf, pc->msize, &errstr))) - goto Fail; - if(!(msize = ixp_msg2fcall(&fcall, pc->buf, IXP_MAX_MSG))) - goto Fail; - - req = cext_emallocz(sizeof(P9Req)); - req->conn = pc; - req->ifcall = fcall; - pc->conn = c; - - if(lookupkey(&pc->tagmap, fcall.tag)) - return respond(req, Eduptag); - - insertkey(&pc->tagmap, fcall.tag, req); - return ixp_handle_req(req); - -Fail: - ixp_server_close_conn(c); -} - -static void -ixp_handle_req(P9Req *r) -{ - P9Conn *pc = r->conn; - P9Srv *srv = pc->srv; - - switch(r->ifcall.type) { - default: - respond(r, Enofunc); - break; - case TVERSION: - if(!strncmp(r->ifcall.version, "9P", 3)) { - r->ofcall.version = "9P"; - }else - if(!strncmp(r->ifcall.version, "9P2000", 7)) { - r->ofcall.version = "9P2000"; - }else{ - r->ofcall.version = "unknown"; - } - r->ofcall.msize = r->ifcall.msize; - respond(r, nil); - break; - case TATTACH: - if(!(r->fid = createfid(&pc->fidmap, r->ifcall.fid, pc))) - return respond(r, Edupfid); - /* attach is a required function */ - srv->attach(r); - break; - case TCLUNK: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if(!srv->clunk) - return respond(r, nil); - srv->clunk(r); - break; - case TFLUSH: - if(!(r->oldreq = lookupkey(&pc->tagmap, r->ifcall.oldtag))) - return respond(r, Enotag); - if(!srv->flush) - return respond(r, Enofunc); - srv->flush(r); - break; - case TCREATE: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if(r->fid->omode != -1) - return respond(r, Ebotch); - if(!(r->fid->qid.type&P9QTDIR)) - return respond(r, Enotdir); - if(!pc->srv->create) - return respond(r, Enofunc); - pc->srv->create(r); - break; - case TOPEN: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if((r->fid->qid.type&P9QTDIR) && (r->ifcall.mode|P9ORCLOSE) != (P9OREAD|P9ORCLOSE)) - return respond(r, Eisdir); - r->ofcall.qid = r->fid->qid; - if(!pc->srv->open) - return respond(r, Enofunc); - pc->srv->open(r); - break; - case TREAD: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if(r->fid->omode == -1 || r->fid->omode == P9OWRITE) - return respond(r, Ebotch); - if(!pc->srv->read) - return respond(r, Enofunc); - pc->srv->read(r); - break; - case TREMOVE: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if(!pc->srv->remove) - return respond(r, Enofunc); - pc->srv->remove(r); - break; - case TSTAT: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if(!pc->srv->stat) - return respond(r, Enofunc); - pc->srv->stat(r); - break; - case TWALK: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if(r->fid->omode != -1) - return respond(r, "cannot walk from an open fid"); - if(r->ifcall.nwname && !(r->fid->qid.type&P9QTDIR)) - return respond(r, Enotdir); - if((r->ifcall.fid != r->ifcall.newfid)) { - if(!(r->newfid = createfid(&pc->fidmap, r->ifcall.newfid, pc))) - return respond(r, Edupfid); - }else - r->newfid = r->fid; - if(!pc->srv->walk) - return respond(r, Enofunc); - pc->srv->walk(r); - break; - case TWRITE: - if(!(r->fid = lookupkey(&pc->fidmap, r->ifcall.fid))) - return respond(r, Enofid); - if((r->fid->omode&3) != P9OWRITE && (r->fid->omode&3) != P9ORDWR) - return respond(r, "write on fid not opened for writing"); - if(!pc->srv->write) - return respond(r, Enofunc); - pc->srv->write(r); - break; - /* Still to be implemented: flush, wstat, auth */ - } -} - -void -respond(P9Req *r, char *error) { - P9Conn *pc = r->conn; - switch(r->ifcall.type) { - default: - if(!error) - cext_assert(!"Respond called on unsupported fcall type"); - break; - case TVERSION: - cext_assert(!error); - free(r->ifcall.version); - pc->msize = (r->ofcall.msize < IXP_MAX_MSG) ? r->ofcall.msize : IXP_MAX_MSG; - free(pc->buf); - pc->buf = cext_emallocz(r->ofcall.msize); - break; - case TATTACH: - if(error) - destroyfid(pc, r->fid->fid); - free(r->ifcall.uname); - free(r->ifcall.aname); - break; - case TOPEN: - case TCREATE: - if(!error) { - r->fid->omode = r->ifcall.mode; - r->fid->qid = r->ofcall.qid; - } - free(r->ifcall.name); - r->ofcall.iounit = pc->msize - sizeof(unsigned long); - break; - case TWALK: - if(error || r->ofcall.nwqid < r->ifcall.nwname) { - if(r->ifcall.fid != r->ifcall.newfid && r->newfid) - destroyfid(pc, r->newfid->fid); - if(!error && r->ofcall.nwqid == 0) - error = Enofile; - }else{ - if(r->ofcall.nwqid == 0) - r->newfid->qid = r->fid->qid; - else - r->newfid->qid = r->ofcall.wqid[r->ofcall.nwqid-1]; - } - free(*r->ifcall.wname); - break; - case TWRITE: - free(r->ifcall.data); - break; - case TREMOVE: - if(r->fid) - destroyfid(pc, r->fid->fid); - break; - case TCLUNK: - if(r->fid) - destroyfid(pc, r->fid->fid); - if(!pc->conn && r->ifcall.tag == IXP_NOTAG) - pc->ref--; - break; - case TFLUSH: - if((r->oldreq = lookupkey(&pc->tagmap, r->ifcall.oldtag))) - respond(r->oldreq, Einterrupted); - if(!pc->conn && r->ifcall.tag == IXP_NOTAG) - pc->ref--; - break; - case TREAD: - case TSTAT: - break; - /* Still to be implemented: flush, wstat, auth */ - } - - r->ofcall.tag = r->ifcall.tag; - if(!error) - r->ofcall.type = r->ifcall.type + 1; - else { - r->ofcall.type = RERROR; - r->ofcall.ename = error; - } - - if(pc->conn) - ixp_server_respond_fcall(pc->conn, &r->ofcall); - - switch(r->ofcall.type) { - case RSTAT: - free(r->ofcall.stat); - break; - case RREAD: - free(r->ofcall.data); - break; - } - - deletekey(&pc->tagmap, r->ifcall.tag);; - free(r); - - if(!pc->conn && pc->ref == 0) - free_p9conn(pc); -} - -/* Pending request cleanup */ -static void -ixp_void_request(void *t) { - P9Req *r, *tr; - P9Conn *pc; - - r = t; - pc = r->conn; - - tr = cext_emallocz(sizeof(P9Req)); - tr->conn = pc; - tr->ifcall.type = TFLUSH; - tr->ifcall.tag = IXP_NOTAG; - tr->ifcall.oldtag = r->ifcall.tag; - ixp_handle_req(tr); -} - -/* Open FID cleanup */ -static void -ixp_void_fid(void *t) { - P9Conn *pc; - P9Req *tr; - Fid *f; - - f = t; - pc = f->conn; - - tr = cext_emallocz(sizeof(P9Req)); - tr->fid = f; - tr->conn = pc; - tr->ifcall.type = TCLUNK; - tr->ifcall.tag = IXP_NOTAG; - tr->ifcall.fid = f->fid; - ixp_handle_req(tr); -} - -static void -ixp_p9conn_incref(void *r) { - P9Conn *pc = *(P9Conn **)r; - pc->ref++; -} - -/* To cleanup a connction, we increase the ref count for - * each open FID and pending request and generate clunk and - * flush requests. As each request is responded to and each - * FID is clunked, we decrease the ref count. When the ref - * count is 0, we free the P9Conn and its buf. The IXPConn - * is taken care of in server.c */ -static void -ixp_cleanup_conn(IXPConn *c) { - P9Conn *pc = c->aux; - pc->conn = nil; - pc->ref = 1; - execmap(&pc->tagmap, ixp_p9conn_incref); - execmap(&pc->fidmap, ixp_p9conn_incref); - if(pc->ref > 1) { - execmap(&pc->tagmap, ixp_void_request); - execmap(&pc->fidmap, ixp_void_fid); - } - if(--pc->ref == 0) - free_p9conn(pc); -} - -/* Handle incoming 9P connections */ -void -serve_9pcon(IXPConn *c) { - int fd = accept(c->fd, nil, nil); - if(fd < 0) - return; - - P9Conn *pc = cext_emallocz(sizeof(P9Conn)); - pc->srv = c->aux; - - /* XXX */ - pc->msize = 1024; - pc->buf = cext_emallocz(pc->msize); - - initmap(&pc->tagmap, TAG_BUCKETS, &pc->taghash); - initmap(&pc->fidmap, FID_BUCKETS, &pc->fidhash); - - ixp_server_open_conn(c->srv, fd, pc, ixp_server_handle_fcall, ixp_cleanup_conn); -} diff --git a/libixp/server.c b/libixp/server.c deleted file mode 100644 index 6d828306..00000000 --- a/libixp/server.c +++ /dev/null @@ -1,130 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ixp.h" - -static unsigned char *msg[IXP_MAX_MSG]; - -IXPConn * -ixp_server_open_conn(IXPServer *s, int fd, void *aux, - void (*read)(IXPConn *c), void (*close)(IXPConn *c)) -{ - IXPConn *c = cext_emallocz(sizeof(IXPConn)); - c->fd = fd; - c->aux = aux; - c->srv = s; - c->read = read; - c->close = close; - c->next = s->conn; - s->conn = c; - return c; -} - -void -ixp_server_close_conn(IXPConn *c) -{ - IXPServer *s = c->srv; - IXPConn **tc; - for(tc=&s->conn; *tc && *tc != c; tc=&(*tc)->next); - cext_assert(*tc == c); - *tc = c->next; - c->closed = 1; - if(c->close) - c->close(c); - else - shutdown(c->fd, SHUT_RDWR); - close(c->fd); - free(c); -} - -static void -prepare_select(IXPServer *s) -{ - IXPConn **c; - FD_ZERO(&s->rd); - for(c=&s->conn; *c; *c && (c=&(*c)->next)) { - if(s->maxfd < (*c)->fd) - s->maxfd = (*c)->fd; - if((*c)->read) - FD_SET((*c)->fd, &s->rd); - } -} - -static void -handle_conns(IXPServer *s) -{ - IXPConn *c, *n; - for((c=s->conn) && (n=c->next); c; (c=n) && (n=c->next)) - if(FD_ISSET(c->fd, &s->rd) && c->read) - c->read(c); -} - -char * -ixp_server_loop(IXPServer *s) -{ - int r; - s->running = 1; - - /* main loop */ - while(s->running) { - prepare_select(s); - - r = select(s->maxfd + 1, &s->rd, 0, 0, 0); - if(r == -1 && errno == EINTR) - continue; - if(r < 0) - return "fatal select error"; - else if(r > 0) - handle_conns(s); - } - return nil; -} - -unsigned int -ixp_server_receive_fcall(IXPConn *c, Fcall *fcall) -{ - unsigned int msize; - char *errstr = 0; - if(!(msize = ixp_recv_message(c->fd, msg, IXP_MAX_MSG, &errstr))) { - ixp_server_close_conn(c); - return 0; - } - return ixp_msg2fcall(fcall, msg, IXP_MAX_MSG); -} - -int -ixp_server_respond_fcall(IXPConn *c, Fcall *fcall) -{ - char *errstr; - unsigned int msize = ixp_fcall2msg(msg, fcall, IXP_MAX_MSG); - if(c->closed) - return 0; - if(ixp_send_message(c->fd, msg, msize, &errstr) != msize) { - ixp_server_close_conn(c); - return -1; - } - return 0; -} - -void -ixp_server_close(IXPServer *s) -{ - IXPConn *c, *next; - for(c=s->conn; c; c=next) { - next=c->next; - ixp_server_close_conn(c); - } -} diff --git a/libixp/socket.c b/libixp/socket.c deleted file mode 100644 index 157c4cdd..00000000 --- a/libixp/socket.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ixp.h" - -static int -connect_unix_sock(char *address) -{ - int fd = 0; - struct sockaddr_un addr = { 0 }; - socklen_t su_len; - - /* init */ - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, address, sizeof(addr.sun_path)); - su_len = sizeof(struct sockaddr) + strlen(addr.sun_path); - - if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) - return -1; - if(connect(fd, (struct sockaddr *) &addr, su_len)) { - close(fd); - return -1; - } - return fd; -} - -static int -connect_inet_sock(char *host) -{ - int fd = 0; - struct sockaddr_in addr = { 0 }; - struct hostent *hp; - char *port = strrchr(host, '!'); - unsigned int prt; - - if(!port) - return -1; - *port = 0; - port++; - if(sscanf(port, "%d", &prt) != 1) - return -1; - - /* init */ - if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) - return -1; - hp = gethostbyname(host); - addr.sin_family = AF_INET; - addr.sin_port = htons(prt); - bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); - - if(connect(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in))) { - close(fd); - return -1; - } - return fd; -} - -int -ixp_connect_sock(char *address) -{ - char *p; - - if((p = strchr(address, '!'))) { - *p = 0; - p++; - - if(!strncmp(address, "unix", 5)) - return connect_unix_sock(p); - else if(!strncmp(address, "tcp", 4)) - return connect_inet_sock(p); - } - return -1; -} - -static int -create_inet_sock(char *host, char **errstr) -{ - int fd; - struct sockaddr_in addr = { 0 }; - struct hostent *hp; - char *port = strrchr(host, '!'); - unsigned int prt; - - if(!port) { - *errstr = "no port provided in address"; - return -1; - } - *port = 0; - port++; - if(sscanf(port, "%d", &prt) != 1) { - *errstr = "invalid port number"; - return -1; - } - signal(SIGPIPE, SIG_IGN); - if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - *errstr = "cannot open socket"; - return -1; - } - addr.sin_family = AF_INET; - addr.sin_port = htons(prt); - - if(!strncmp(host, "*", 2)) - addr.sin_addr.s_addr = htonl(INADDR_ANY); - else if((hp = gethostbyname(host))) - bcopy(hp->h_addr, &addr.sin_addr, hp->h_length); - else { - *errstr = "cannot translate hostname to an address"; - return -1; - } - - if(bind(fd, (struct sockaddr *) &addr, sizeof(struct sockaddr_in)) < 0) { - *errstr = "cannot bind socket"; - close(fd); - return -1; - } - - if(listen(fd, IXP_MAX_CACHE) < 0) { - *errstr = "cannot listen on socket"; - close(fd); - return -1; - } - return fd; -} - -static int -create_unix_sock(char *file, char **errstr) -{ - int fd; - int yes = 1; - struct sockaddr_un addr = { 0 }; - socklen_t su_len; - - signal(SIGPIPE, SIG_IGN); - if((fd = socket(AF_UNIX, SOCK_STREAM, 0)) < 0) { - *errstr = "cannot open socket"; - return -1; - } - if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, - (char *) &yes, sizeof(yes)) < 0) { - *errstr = "cannot set socket options"; - close(fd); - return -1; - } - addr.sun_family = AF_UNIX; - strncpy(addr.sun_path, file, sizeof(addr.sun_path)); - su_len = sizeof(struct sockaddr) + strlen(addr.sun_path); - - unlink(file); /* remove old socket, if any */ - if(bind(fd, (struct sockaddr *) &addr, su_len) < 0) { - *errstr = "cannot bind socket"; - close(fd); - return -1; - } - chmod(file, S_IRWXU); - - if(listen(fd, IXP_MAX_CACHE) < 0) { - *errstr = "cannot listen on socket"; - close(fd); - return -1; - } - return fd; -} - -int -ixp_create_sock(char *address, char **errstr) -{ - char *p = strchr(address, '!'); - char *addr, *type; - - if(!p) { - *errstr = "no socket type defined"; - return -1; - } - *p = 0; - - addr = &p[1]; - type = address; /* unix, inet */ - - if(!strncmp(type, "unix", 5)) - return create_unix_sock(addr, errstr); - else if(!strncmp(type, "tcp", 4)) - return create_inet_sock(addr, errstr); - else - *errstr = "unkown socket type"; - return -1; -} diff --git a/libixp/transport.c b/libixp/transport.c deleted file mode 100644 index d73ccba8..00000000 --- a/libixp/transport.c +++ /dev/null @@ -1,77 +0,0 @@ -/* - * (C)opyright MMIV-MMVI Anselm R. Garbe - * See LICENSE file for license details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "ixp.h" - -unsigned int -ixp_send_message(int fd, void *msg, unsigned int msize, char **errstr) -{ - unsigned int num = 0; - int r; - - /* send message */ - while(num < msize) { - r = write(fd, msg + num, msize - num); - if(r == -1 && errno == EINTR) - continue; - if(r < 1) { - *errstr = "broken pipe"; - return 0; - } - num += r; - } - return num; -} - -static unsigned int -ixp_recv_data(int fd, void *msg, unsigned int msize, char **errstr) -{ - unsigned int num = 0; - int r = 0; - - /* receive data */ - while(num < msize) { - r = read(fd, msg + num, msize - num); - if(r == -1 && errno == EINTR) - continue; - if(r < 1) { - *errstr = "broken pipe"; - return 0; - } - num += r; - } - return num; -} - -unsigned int -ixp_recv_message(int fd, void *msg, unsigned int msglen, char **errstr) -{ - unsigned int msize; - - /* receive header */ - if(ixp_recv_data(fd, msg, sizeof(unsigned int), errstr) != - sizeof(unsigned int)) - return 0; - ixp_unpack_u32((void *)&msg, nil, &msize); - if(msize > msglen) { - *errstr = "invalid message header"; - return 0; - } - /* receive message */ - if(ixp_recv_data(fd, msg, msize - sizeof(unsigned int), errstr) - != msize - sizeof(unsigned int)) - return 0; - return msize; -} diff --git a/liblitz/brush.c b/liblitz/brush.c index e0f7b850..442235e3 100644 --- a/liblitz/brush.c +++ b/liblitz/brush.c @@ -6,7 +6,6 @@ #include #include #include -#include #include "blitz.h" void @@ -30,7 +29,7 @@ blitz_draw_label(BlitzBrush *b, char *text) return; shortened = 0; - cext_strlcpy(buf, text, sizeof(buf)); + strncpy(buf, text, sizeof(buf)); len = strlen(buf); gcv.foreground = b->color.fg; gcv.background = b->color.bg; diff --git a/liblitz/color.c b/liblitz/color.c index d618599c..fbe033b8 100644 --- a/liblitz/color.c +++ b/liblitz/color.c @@ -4,7 +4,6 @@ */ #include -#include #include "blitz.h" @@ -14,7 +13,7 @@ xloadcolor(Blitz *blitz, char *colstr) XColor color; char col[8]; - cext_strlcpy(col, colstr, sizeof(col)); + strncpy(col, colstr, sizeof(col)); col[7] = 0; XAllocNamedColor(blitz->dpy, DefaultColormap(blitz->dpy, blitz->screen), col, &color, &color); diff --git a/liblitz/font.c b/liblitz/font.c index a48947ff..ce960ecc 100644 --- a/liblitz/font.c +++ b/liblitz/font.c @@ -7,8 +7,6 @@ #include #include #include -#include - #include "blitz.h" unsigned int @@ -16,7 +14,7 @@ blitz_textwidth_l(BlitzFont *font, char *text, unsigned int len) { if(font->set) { XRectangle r; - XmbTextExtents(font->set, text, len, nil, &r); + XmbTextExtents(font->set, text, len, NULL, &r); return r.width; } return XTextWidth(font->xfont, text, len); @@ -32,7 +30,7 @@ void blitz_loadfont(Blitz *blitz, BlitzFont *font) { char *fontname = font->fontstr; - char **missing = nil, *def = "?"; + char **missing = NULL, *def = "?"; int n; setlocale(LC_ALL, ""); @@ -45,7 +43,7 @@ blitz_loadfont(Blitz *blitz, BlitzFont *font) XFreeStringList(missing); if(font->set) { XFreeFontSet(blitz->dpy, font->set); - font->set = nil; + font->set = NULL; } } if(font->set) { @@ -68,7 +66,7 @@ blitz_loadfont(Blitz *blitz, BlitzFont *font) else { if(font->xfont) XFreeFont(blitz->dpy, font->xfont); - font->xfont = nil; + font->xfont = NULL; font->xfont = XLoadQueryFont(blitz->dpy, fontname); if (!font->xfont) { fontname = "fixed"; diff --git a/cmd/wm/mouse.c b/mouse.c similarity index 100% rename from cmd/wm/mouse.c rename to mouse.c diff --git a/cmd/wm/rule.c b/rule.c similarity index 100% rename from cmd/wm/rule.c rename to rule.c diff --git a/test/test_fs.sh b/test/test_fs.sh deleted file mode 100644 index a513a1d1..00000000 --- a/test/test_fs.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -# Heavy access test of wmiiwm's fs - -dump_fs() { - echo $1 - wmiir read $1|wmiir write $1; - for i in `wmiir read $1|awk '{print $10}'` - do - if test $i != "event" - then - dump_fs $1/$i - fi - done -} - -while true -do - dump_fs / -done diff --git a/cmd/wm/view.c b/view.c similarity index 100% rename from cmd/wm/view.c rename to view.c diff --git a/cmd/wm/wm.c b/wm.c similarity index 100% rename from cmd/wm/wm.c rename to wm.c diff --git a/cmd/wm/wm.h b/wm.h similarity index 100% rename from cmd/wm/wm.h rename to wm.h diff --git a/cmd/wm/wmii b/wmii similarity index 100% rename from cmd/wm/wmii rename to wmii diff --git a/cmd/wm/wmii.1 b/wmii.1 similarity index 100% rename from cmd/wm/wmii.1 rename to wmii.1 diff --git a/doc/wmii.svg b/wmii.svg similarity index 100% rename from doc/wmii.svg rename to wmii.svg diff --git a/cmd/wm/wmiiwm.1 b/wmiiwm.1 similarity index 100% rename from cmd/wm/wmiiwm.1 rename to wmiiwm.1