mirror of
git://projects.qi-hardware.com/wernermisc.git
synced 2024-11-15 05:53:09 +02:00
Merge branch 'master' of projects.qi-hardware.com:wernermisc
This commit is contained in:
commit
ef5fa7e0c4
@ -4,56 +4,89 @@ SPOOL = $(CAE_TOOLS)/spool/spool
|
||||
CNGT = $(CAE_TOOLS)/cngt/cngt
|
||||
GP2RML = $(CAE_TOOLS)/gp2rml/gp2rml
|
||||
|
||||
# #1: 5, 5
|
||||
# #2: 5, 45
|
||||
# #3: 65, 5
|
||||
# #3: 70, 45
|
||||
# Z1 = -44
|
||||
# PIECE_Z = 5.5
|
||||
|
||||
# new run (10 45, 135 85, 7.8)
|
||||
# #1: 13 45
|
||||
# #2: 75 48
|
||||
# Z1 = -44
|
||||
# PIECE_Z = 7.9
|
||||
|
||||
X0 = 5
|
||||
Y0 = 5
|
||||
Y0 = 45
|
||||
Z1 = -44
|
||||
PIECE = -5 -5 30 55
|
||||
PIECE_Z = 5.5
|
||||
Z_STEP = 2
|
||||
CLEARANCE = 5
|
||||
CLEARANCE = 2
|
||||
SPEED_XY = 1
|
||||
SPEED_Z = 1
|
||||
OVERSHOOT = 0.2
|
||||
|
||||
PARAMS = X0=$(X0)mm Y0=$(Y0)mm Z1=$(Z1)mm PIECE_Z=$(PIECE_Z)mm
|
||||
Z_OFFSET = 0.1
|
||||
FIN_SPEED_XY = 3
|
||||
FIN_SPEED_Z = 3
|
||||
|
||||
PARAMS = X0=$(X0)mm Y0=$(Y0)mm Z1=$(Z1)mm PIECE_Z=$(PIECE_Z)mm \
|
||||
Z_OFFSET=$(Z_OFFSET)mm
|
||||
|
||||
PARTS = top mid bot
|
||||
PART = top
|
||||
|
||||
.PHONY: all plot mill pos cng clean
|
||||
|
||||
all: mill.rml
|
||||
all: $(PART)-mill.rml $(PART)-finish.rml
|
||||
|
||||
case.gp: case.fpd
|
||||
fped -g case.fpd || { rm -f $@; exit 1; }
|
||||
|
||||
top.gp: case.gp
|
||||
$(CAMEO)/fped2d2z.pl -r 0=-$(OVERSHOOT) top $^ >$@ || \
|
||||
$(PART).gp: case.gp
|
||||
$(CAMEO)/fped2d2z.pl -r 0=-$(OVERSHOOT) $(PART) $^ >$@ || \
|
||||
{ rm -f $@; exit 1; }
|
||||
|
||||
top-piece.gp: top.gp
|
||||
$(PART)-piece.gp: $(PART).gp
|
||||
./genpiece.pl -r $(PIECE) $< >$@ || { rm -f $@; exit 1; }
|
||||
|
||||
top-area.gp: top-piece.gp top.gp cam.sh Makefile
|
||||
./cam.sh PART=top CAMEO=$(CAMEO)/cameo $(PARAMS) >$@ || \
|
||||
$(PART)-area.gp: $(PART)-piece.gp $(PART).gp cam.sh Makefile
|
||||
./cam.sh PART=$(PART) CAMEO=$(CAMEO)/cameo $(PARAMS) OUT=$@ || \
|
||||
{ rm -f $@; exit 1; }
|
||||
|
||||
mill.gp: top-area.gp Makefile
|
||||
$(PART)-finish.gp: $(PART)-piece.gp $(PART).gp cam.sh Makefile
|
||||
./cam.sh PART=$(PART) CAMEO=$(CAMEO)/cameo $(PARAMS) \
|
||||
Z_OFFSET=0mm REVERSE=reverse OUT=$@ || { rm -f $@; exit 1; }
|
||||
|
||||
$(PART)-mill.gp: $(PART)-area.gp Makefile
|
||||
$(CAMEO)/zstack.pl $(Z1) $(Z_STEP) $< >$@ || \
|
||||
{ rm -f $@; exit 1; }
|
||||
|
||||
mill.rml: mill.gp Makefile
|
||||
$(PART)-mill.rml: $(PART)-mill.gp Makefile
|
||||
$(GP2RML) $(CLEARANCE) $(SPEED_XY) $(SPEED_Z) $< >$@ || \
|
||||
{ rm -f $@; exit 1; }
|
||||
|
||||
plot: mill.gp
|
||||
echo 'splot "mill.gp" with lines' | gnuplot -persist
|
||||
$(PART)-finish.rml: $(PART)-finish.gp Makefile
|
||||
$(GP2RML) $(CLEARANCE) $(FIN_SPEED_XY) $(FIN_SPEED_Z) \
|
||||
$< >$@ || { rm -f $@; exit 1; }
|
||||
|
||||
mill: mill.rml
|
||||
PORT=/dev/ttyUSB0 $(SPOOL) $<
|
||||
plot: $(PART)-mill.gp
|
||||
echo 'splot "$(PART)-mill.gp" with lines' | gnuplot -persist
|
||||
|
||||
mill: $(PART)-mill.rml $(PART)-finish.rml
|
||||
PORT=/dev/ttyUSB0 $(SPOOL) $^
|
||||
|
||||
pos:
|
||||
$(CNGT) 0
|
||||
|
||||
cng: mill.gp
|
||||
cng: $(PART)-mill.gp
|
||||
$(CNGT) $(Z1) 10 $<
|
||||
|
||||
clean:
|
||||
rm -f case.gp top-piece.gp top.gp top-area.gp mill.gp mill.rml
|
||||
rm -f case.gp
|
||||
rm -f $(PARTS:%=%-piece.gp) $(PARTS:%=%.gp)
|
||||
rm -f $(PARTS:%=%-area.gp)
|
||||
rm -f $(PARTS:%=%-mill.gp) $(PARTS:%=%-mill.rml)
|
||||
rm -f $(PARTS:%=%-finish.gp) $(PARTS:%=%-finish.rml)
|
||||
|
@ -10,16 +10,18 @@ done
|
||||
: ${Y0:=0mm}
|
||||
: ${Z1:=0mm}
|
||||
: ${PIECE_Z:=0mm}
|
||||
: ${Z_OFFSET:=0mm}
|
||||
: ${CAMEO:=cameo}
|
||||
|
||||
echo Z1 is $Z1 1>&2
|
||||
: ${OUT:=out.gp}
|
||||
|
||||
$CAMEO <<EOF
|
||||
gnuplot $MILL $PART-piece.gp
|
||||
gnuplot $MILL $PART.gp
|
||||
$REVERSE
|
||||
align 1 $X0 $Y0
|
||||
z 0 ${Z1}
|
||||
z -${PIECE_Z}
|
||||
z 0 $Z1
|
||||
z $Z_OFFSET
|
||||
z -$PIECE_Z
|
||||
area $OVERLAP
|
||||
write $PART-area.gp
|
||||
write $OUT
|
||||
EOF
|
||||
|
@ -11,6 +11,15 @@
|
||||
vc##_center: vec va rb; \
|
||||
arc vc##_center va vb
|
||||
|
||||
#define QLL(pfx, r) \
|
||||
Q(pfx##lly, pfx##llx, pfx##ll, (0mm, r), (r, 0mm))
|
||||
#define QLR(pfx, r) \
|
||||
Q(pfx##lrx, pfx##lry, pfx##lr, (-(r), 0mm), (0mm, r))
|
||||
#define QUL(pfx, r) \
|
||||
Q(pfx##ulx, pfx##uly, pfx##ul, (r, 0mm), (0mm, -(r)))
|
||||
#define QUR(pfx, r) \
|
||||
Q(pfx##ury, pfx##urx, pfx##ur, (0mm, -(r)), (-(r), 0mm))
|
||||
|
||||
/*
|
||||
* Rectangle with rounded corners.
|
||||
*
|
||||
@ -19,15 +28,17 @@
|
||||
* corners.
|
||||
*/
|
||||
|
||||
#define RRECT_SETUP(pfx, origin, w, h, r) \
|
||||
pfx##ll: vec origin(0mm, 0mm); \
|
||||
pfx##lr: vec pfx##ll(w, 0mm); \
|
||||
pfx##ul: vec pfx##ll(0mm, h); \
|
||||
pfx##ur: vec pfx##ll(w, h); \
|
||||
Q(pfx##lly, pfx##llx, pfx##ll, (0mm, r), (r, 0mm)); \
|
||||
Q(pfx##lrx, pfx##lry, pfx##lr, (-r, 0mm), (0mm, r)); \
|
||||
Q(pfx##ulx, pfx##uly, pfx##ul, (r, 0mm), (0mm, -r)); \
|
||||
Q(pfx##ury, pfx##urx, pfx##ur, (0mm, -r), (-r, 0mm))
|
||||
#define RRECT_SETUP(pfx, origin, w, h) \
|
||||
pfx##ll: vec origin(0mm, 0mm); \
|
||||
pfx##lr: vec pfx##ll(w, 0mm); \
|
||||
pfx##ul: vec pfx##ll(0mm, h); \
|
||||
pfx##ur: vec pfx##ll(w, h); \
|
||||
|
||||
#define RRECT_DRAW_ARCS(pfx, r) \
|
||||
QLL(pfx, r); \
|
||||
QLR(pfx, r); \
|
||||
QUL(pfx, r); \
|
||||
QUR(pfx, r)
|
||||
|
||||
#define RRECT_DRAW_LINES(pfx) \
|
||||
line pfx##llx pfx##lrx; \
|
||||
@ -36,7 +47,8 @@
|
||||
line pfx##lry pfx##ury
|
||||
|
||||
#define RRECT(pfx, origin, w, h, r) \
|
||||
RRECT_SETUP(pfx, origin, w, h, r); \
|
||||
RRECT_SETUP(pfx, origin, w, h); \
|
||||
RRECT_DRAW_ARCS(pfx, r); \
|
||||
RRECT_DRAW_LINES(pfx)
|
||||
|
||||
|
||||
@ -89,18 +101,179 @@ frame top_surface {
|
||||
}
|
||||
|
||||
|
||||
/* ----- Middle part ------------------------------------------------------- */
|
||||
|
||||
|
||||
frame mid_rrect_ridge {
|
||||
RRECT_SETUP(edge_, @, width, length);
|
||||
RRECT_DRAW_ARCS(edge_, ro_edge);
|
||||
|
||||
base: vec @(red, red)
|
||||
RRECT_SETUP(ridge_, base, width-2*red, length-2*red);
|
||||
RRECT_DRAW_ARCS(ridge_, r);
|
||||
|
||||
usb_ur: vec edge_ur(-usb_roff, 0mm)
|
||||
usb_ul: vec usb_ur(-usb_w, 0mm)
|
||||
usb_ll: vec usb_ul(0mm, -red)
|
||||
usb_lr: vec usb_ur(0mm, -red)
|
||||
|
||||
line edge_lly edge_uly /* outside */
|
||||
line edge_ulx usb_ul
|
||||
line usb_ul usb_ll /* USB bay */
|
||||
line usb_ll ridge_ulx
|
||||
line ridge_uly ridge_lly /* inside */
|
||||
line ridge_llx ridge_lrx
|
||||
line ridge_lry ridge_ury
|
||||
line ridge_urx usb_lr
|
||||
line usb_lr usb_ur /* USB bay */
|
||||
line usb_ur edge_urx
|
||||
line edge_ury edge_lry /* outside */
|
||||
line edge_lrx edge_llx
|
||||
}
|
||||
|
||||
|
||||
frame mid_rrect_body {
|
||||
RRECT_SETUP(edge_, @, width, length);
|
||||
RRECT_DRAW_ARCS(edge_, ro_edge);
|
||||
|
||||
usb_ur: vec edge_ur(-usb_roff, 0mm)
|
||||
usb_ul: vec usb_ur(-usb_w, 0mm)
|
||||
usb_ll: vec usb_ul(0mm, -usb_d)
|
||||
usb_lr: vec usb_ur(0mm, -usb_d)
|
||||
|
||||
line edge_llx edge_lrx
|
||||
line edge_ulx usb_ul
|
||||
|
||||
line usb_ul usb_ll /* USB bay */
|
||||
line usb_ll usb_lr
|
||||
line usb_lr usb_ur
|
||||
|
||||
line usb_ur edge_urx
|
||||
line edge_lly edge_uly
|
||||
line edge_lry edge_ury
|
||||
}
|
||||
|
||||
|
||||
frame mid_ridge {
|
||||
loop if = 1, mid_ridge
|
||||
|
||||
set red = topborder
|
||||
set r = ro_ridge
|
||||
frame mid_rrect_ridge @
|
||||
}
|
||||
|
||||
|
||||
frame mid_pcb {
|
||||
loop if = 1, mid_pcb
|
||||
|
||||
set red = topborder+topridge
|
||||
set r = ri_ridge
|
||||
frame mid_rrect_ridge @
|
||||
}
|
||||
|
||||
|
||||
frame post {
|
||||
vec @(r, 0mm)
|
||||
circ @ .
|
||||
}
|
||||
|
||||
|
||||
frame mid_body {
|
||||
loop if = 1, mid_body
|
||||
|
||||
frame mid_rrect_body @
|
||||
|
||||
bc: vec @(width/2, batt_y)
|
||||
br: vec bc(batt_d/2, 0mm)
|
||||
circ bc br
|
||||
|
||||
set r = post_do/2
|
||||
vec @(post_x, cvr_f+cvr_d+post_y)
|
||||
frame post .
|
||||
vec @(width-post_x, cvr_f+cvr_d+post_y)
|
||||
frame post .
|
||||
}
|
||||
|
||||
|
||||
/* ----- Bottom part ------------------------------------------------------- */
|
||||
|
||||
|
||||
frame bot_rrect {
|
||||
base: vec @(0mm, cvr_f)
|
||||
|
||||
RRECT_SETUP(edge_, base, width, length-cvr_f);
|
||||
QUL(edge_, ro_edge);
|
||||
QUR(edge_, ro_edge);
|
||||
|
||||
set side = (width-cvr_w-2*cvr_play)/2-red
|
||||
cvr_ll: vec edge_ll(side, 0mm)
|
||||
cvr_lr: vec edge_lr(-side, 0mm)
|
||||
cvr_ul: vec cvr_ll(0mm, cvr_d+2*cvr_play+red)
|
||||
cvr_ur: vec cvr_lr(0mm, cvr_d+2*cvr_play+red)
|
||||
|
||||
line edge_ll cvr_ll /* outside */
|
||||
|
||||
QUL(cvr_, cvr_r+red+cvr_play) /* cover bay */
|
||||
QUR(cvr_, cvr_r+red+cvr_play)
|
||||
|
||||
line cvr_ll cvr_uly
|
||||
line cvr_ulx cvr_urx
|
||||
line cvr_ury cvr_lr
|
||||
|
||||
line cvr_lr edge_lr /* outside */
|
||||
line edge_ll edge_uly
|
||||
line edge_lr edge_ury
|
||||
line edge_ulx edge_urx
|
||||
}
|
||||
|
||||
|
||||
frame bot_posts {
|
||||
loop if = 1, bot_posts
|
||||
|
||||
set r = post_di/2
|
||||
vec @(post_x, cvr_f+cvr_d+post_y)
|
||||
frame post .
|
||||
vec @(width-post_x, cvr_f+cvr_d+post_y)
|
||||
frame post .
|
||||
}
|
||||
|
||||
|
||||
frame bot_base {
|
||||
loop if = 1, bot_base
|
||||
|
||||
set red = cvr_foot
|
||||
frame bot_rrect @
|
||||
}
|
||||
|
||||
|
||||
frame bot_surface {
|
||||
loop if = 1, bot_surface
|
||||
|
||||
set red = 0mm
|
||||
frame bot_rrect @
|
||||
}
|
||||
|
||||
|
||||
/* ----- Main -------------------------------------------------------------- */
|
||||
|
||||
|
||||
package "top-$part-$z"
|
||||
package "$part-$z"
|
||||
unit mm
|
||||
|
||||
table
|
||||
{ part, z, top_surface, top_window, top_pcb, top_ridge }
|
||||
{ "top_surface", 2.5, 1, 0, 0, 0 }
|
||||
{ "top_window", 1.5, 0, 1, 0, 0 }
|
||||
// { "top_pcb", 0.5, 0, 0, 1, 0 }
|
||||
{ "top_ridge", 0.5, 0, 0, 0, 1 }
|
||||
{ part, z, top_surface, top_window, top_pcb, top_ridge,
|
||||
mid_ridge, mid_pcb, mid_body,
|
||||
bot_posts, bot_base, bot_surface}
|
||||
{ "top_surface", 2.5, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
{ "top_window", 1.5, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0 }
|
||||
// { "top_pcb", 0.5, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0 }
|
||||
{ "top_ridge", 0.5, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0 }
|
||||
{ "mid_ridge", 0.5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0 }
|
||||
{ "mid_pcb", 1.0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0 }
|
||||
{ "mid_body", 4.5, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0 }
|
||||
{ "bot_posts", 1.2, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0 }
|
||||
{ "bot_base", 2.0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0 }
|
||||
{ "bot_surface", 2.7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 }
|
||||
|
||||
table
|
||||
{ pcbw, pcbl, pcbgap }
|
||||
@ -114,7 +287,21 @@ table
|
||||
table
|
||||
/* component area position relative to lower left corner of PCB */
|
||||
{ cmp_x0, cmp_y0, cmp_x1, cmp_y1, cmp_r }
|
||||
{ 7.0mm, 1.0mm, 20.0mm, 30.0mm, 2.0mm }
|
||||
{ 6.5mm, 1.0mm, 19.5mm, 30.0mm, 2.0mm }
|
||||
|
||||
table
|
||||
/* usb_roff = offset from right outer case edge */
|
||||
{ usb_w, usb_d, usb_roff }
|
||||
{ 8.5mm, 6.0mm, 4.5mm }
|
||||
|
||||
table
|
||||
/* post_y is from the edge of the battery bay. post_x is from the edge */
|
||||
{ batt_d, batt_y, post_do, post_di, post_y, post_x }
|
||||
{ 20.2mm, 12.1mm, 4.1mm, 4.0mm, 5.0mm, 4.5mm }
|
||||
|
||||
table
|
||||
{ cvr_w, cvr_d, cvr_f, cvr_foot, cvr_play, cvr_r }
|
||||
{ 20.0mm, 15.0mm, 5.0mm, 0.8mm, 0.1mm, 2.0mm }
|
||||
|
||||
set width = pcbw+2*(pcbgap+topridge+topborder)
|
||||
set length = pcbl+2*(pcbgap+topridge+topborder)
|
||||
@ -134,6 +321,14 @@ frame top_pcb @
|
||||
frame top_window @
|
||||
frame top_surface @
|
||||
|
||||
frame mid_ridge @
|
||||
frame mid_pcb @
|
||||
frame mid_body @
|
||||
|
||||
frame bot_posts @
|
||||
frame bot_base @
|
||||
frame bot_surface @
|
||||
|
||||
measx top_outline.edge_ul -> top_outline.edge_ur 4mm
|
||||
measy top_outline.edge_ll -> top_outline.edge_ul 4mm
|
||||
measx top_pcb.pcb_ul -> top_pcb.pcb_ur 3mm
|
||||
@ -143,3 +338,6 @@ measx top_ridge.ridge_o_ul -> top_ridge.ridge_o_ur 4mm
|
||||
measy top_ridge.ridge_o_ll -> top_ridge.ridge_o_ul 4mm
|
||||
measx top_ridge.ridge_i_ul -> top_ridge.ridge_i_ur 3mm
|
||||
measy top_ridge.ridge_i_ll -> top_ridge.ridge_i_ul 3mm
|
||||
|
||||
measy bot_rrect.edge_ll -> bot_rrect.edge_ul 4mm
|
||||
measx bot_rrect.edge_ll -> bot_rrect.cvr_ll -3mm
|
||||
|
491
bacon/case/draft.fig
Normal file
491
bacon/case/draft.fig
Normal file
@ -0,0 +1,491 @@
|
||||
#FIG 3.2 Produced by xfig version 3.2.5b
|
||||
Landscape
|
||||
Center
|
||||
Metric
|
||||
A4
|
||||
100.00
|
||||
Single
|
||||
-2
|
||||
1200 2
|
||||
1 3 0 3 0 7 50 -1 -1 0.000 1 0.0000 6975 4275 720 720 6975 4275 7695 4275
|
||||
1 4 0 3 0 7 50 -1 -1 0.000 1 0.0000 9765 3285 135 135 9630 3285 9900 3285
|
||||
1 4 0 3 0 7 50 -1 -1 0.000 1 0.0000 8685 3285 135 135 8550 3285 8820 3285
|
||||
1 4 0 3 0 7 50 -1 -1 0.000 1 0.0000 7515 3285 135 135 7380 3285 7650 3285
|
||||
1 4 0 3 0 7 50 -1 -1 0.000 1 0.0000 6435 3285 135 135 6300 3285 6570 3285
|
||||
1 3 0 1 0 7 40 -1 -1 0.000 1 0.0000 8235 7740 452 452 8235 7740 8687 7740
|
||||
2 3 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 9
|
||||
6075 2025 6750 2025 6750 2700 7515 2700 7515 2025 7875 2025
|
||||
7875 5175 6075 5175 6075 2025
|
||||
2 3 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 9
|
||||
8325 2025 10125 2025 10125 4950 9900 4950 9900 3600 8550 3600
|
||||
8550 4950 8325 4950 8325 2025
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
8460 4950 8460 3510 9990 3510 9990 4950
|
||||
2 3 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 9
|
||||
10710 5175 10710 4950 10800 4950 10800 3600 12150 3600 12150 4950
|
||||
12240 4950 12240 5175 10710 5175
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
10710 4950 10710 3510 12240 3510 12240 4950
|
||||
2 2 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
5625 2025 3825 2025 3825 5175 5625 5175 5625 2025
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
4050 2250 5400 2250 5400 4950 4050 4950 4050 2250
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 6
|
||||
4500 2250 4500 3150 5310 3150 5310 4500 4500 4500 4500 4950
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4140 2250 4140 4950
|
||||
2 2 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
6075 5625 7875 5625 7875 6075 6075 6075 6075 5625
|
||||
2 2 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
8325 5625 10125 5625 10125 5850 8325 5850 8325 5625
|
||||
2 2 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
10710 5625 12240 5625 12240 5850 10710 5850 10710 5625
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
10800 5625 10800 5760 10710 5760
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
12150 5625 12150 5760 12240 5760
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
8550 5625 8550 5760 8460 5760 8460 5850
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
9900 5625 9900 5760 9990 5760 9990 5850
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 6
|
||||
6750 2115 6165 2115 6165 5085 7785 5085 7785 2115 7515 2115
|
||||
2 2 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3915 2115 5535 2115 5535 5085 3915 5085 3915 2115
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 8
|
||||
6165 5625 6165 5670 6300 5670 6300 5760 7650 5760 7650 5670
|
||||
7785 5670 7785 5625
|
||||
2 2 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
|
||||
3825 5625 5625 5625 5625 6075 3825 6075 3825 5625
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
3825 5985 3915 5985 3915 6075
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
5625 5985 5535 5985 5535 6075
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
4050 6075 4050 5850 5400 5850 5400 6075
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
6255 4275 7695 4275
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
6750 2475 7515 2475
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
8100 2025 8100 2700
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7875 2025 8145 2025
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7560 2700 8145 2700
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7785 5715 7785 6795
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7875 6120 7875 6795
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3780 5625 2700 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3780 5850 2700 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7920 5625 8100 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7920 6075 8100 6075
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
8055 5625 8055 6075
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7785 6750 7875 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
7560 6750 7785 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
8100 6750 7875 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7650 5805 7650 6525
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7650 6435 7785 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
8010 6435 7785 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
7425 6435 7650 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6750 5625 6750 5760
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
6750 5400 6750 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
6750 5985 6750 5760
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3780 5985 3150 5985
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
4500 5850 4500 5985 5400 5985
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2
|
||||
6120 5670 5850 5670
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2
|
||||
5895 5625 5895 5670
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 7 0 0 2
|
||||
5850 5625 6030 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
5895 5895 5895 5670
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5625 6120 5625 6795
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5535 6120 5535 6795
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5400 6120 5400 6525
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5400 6435 5535 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5535 6750 5625 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
5175 6435 5400 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
5805 6435 5535 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
5850 6750 5625 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
5310 6750 5535 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9855 4950 9585 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
9675 4950 9675 3600
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8550 4995 8550 5220
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9900 4995 9900 5220
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
8550 5175 9900 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4005 4950 3555 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
4005 2250 3555 2250
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
3600 2250 3600 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6255 4275 6255 3780
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6165 3825 6255 3825
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
5940 3825 6165 3825
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
6480 3825 6255 3825
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12600 5175 12285 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12555 4950 12555 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
12555 4725 12555 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
12555 5400 12555 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
2925 5625 2925 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
2925 5400 2925 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
2925 6075 2925 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3240 5850 3240 5985
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
3240 5580 3240 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
3240 6210 3240 5985
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3780 6075 3465 6075
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3555 5985 3555 6075
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
3555 5715 3555 5985
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10170 5850 10440 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10170 5760 10440 5760
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
10350 5400 10350 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
10350 6075 10350 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10350 5625 10350 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10170 5625 10440 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12285 5625 12600 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12285 5850 12600 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12285 5760 12600 5760
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12465 5625 12465 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
12465 5400 12465 5625
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
12465 6075 12465 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10125 5895 10125 6525
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9990 5895 9990 6795
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9900 5805 9900 6795
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9990 6435 10125 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9900 6750 9990 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
9765 6435 9990 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
10350 6435 10125 6435
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
9675 6750 9900 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
10215 6750 9990 6750
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12240 5895 12240 6300
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12150 5805 12150 6300
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10710 3465 10710 3105
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12240 3465 12240 3105
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12150 6210 12240 6210
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
11925 6210 12150 6210
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
12465 6210 12240 6210
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
10710 3150 12240 3150
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7920 5175 8325 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10170 2025 10395 2025
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
10170 4950 10395 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12195 3600 12870 3600
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
10350 2025 10350 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
12825 3600 12825 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3825 1980 3825 1665
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5625 1980 5625 1665
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3780 2025 2880 2025
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
3780 5175 2880 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
2925 2025 2925 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
3825 1710 5625 1710
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
10800 4275 12150 4275
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 6
|
||||
6750 2250 6300 2250 6300 4950 7650 4950 7650 2250 7515 2250
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7875 1665 7875 1980
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7515 1665 7515 1980
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
7515 1710 7875 1710
|
||||
2 3 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 9
|
||||
3825 7200 5625 7200 5625 7560 5535 7560 5535 7650 3915 7650
|
||||
3915 7560 3825 7560 3825 7200
|
||||
2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
3825 7560 3825 8010 5625 8010 5625 7560
|
||||
2 1 0 2 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
3825 8010 3825 8235 5625 8235 5625 8010
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5670 7200 6750 7200
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5670 7560 6075 7560
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5670 8010 6075 8010
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
5670 8235 6750 8235
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
6030 7200 6030 7560
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
6030 7560 6030 8010
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
6030 8460 6030 8235
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6030 8010 6030 8235
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
6705 7200 6705 8235
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
8550 5850 8550 6075 8775 6075 8775 5850
|
||||
2 1 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 4
|
||||
9675 5850 9675 6075 9900 6075 9900 5850
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8820 6075 9045 6075
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9000 5850 9000 6075
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
9000 5580 9000 5850
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
9000 6300 9000 6075
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8550 3285 9225 3285
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
8325 2925 8685 2925
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
9180 3285 9180 3600
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9630 3285 9630 2880
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
9900 3285 9900 2880
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6345 3195 6615 2925
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
6525 3375 6795 3105
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
6570 2970 6750 3150
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
9630 2925 9900 2925
|
||||
2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5
|
||||
7650 7200 9900 7200 9900 8280 7650 8280 7650 7200
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
7740 4275 8145 4275
|
||||
2 1 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 6
|
||||
7875 7200 7875 7290 8550 7290 8550 8190 7875 8190 7875 8280
|
||||
2 2 0 2 0 7 40 -1 -1 0.000 0 0 -1 0 0 5
|
||||
10125 7200 10485 7200 10485 8280 10125 8280 10125 7200
|
||||
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 0 0 3
|
||||
4050 5985 4140 5985 4140 5850
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8685 2880 8685 3420
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
12870 4950 12285 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 1 2
|
||||
0 0 1.00 120.00 120.00
|
||||
0 0 1.00 120.00 120.00
|
||||
8010 4275 8010 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
8145 5400 8145 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
8145 4725 8145 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8100 4950 8280 4950
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 0 0 2
|
||||
8145 4950 8145 5175
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
3555 6300 3555 6075
|
||||
2 1 0 1 0 7 40 -1 -1 0.000 0 0 -1 1 0 2
|
||||
0 0 1.00 120.00 120.00
|
||||
5895 5400 5895 5625
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 6975 4230 20.2\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 8100 1980 6.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 7200 2430 8.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 7830 7020 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 6975 5535 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 5895 5355 0.6\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 4995 6480 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 5580 6975 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 9225 5355 20.1\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 9450 4365 15.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 3330 3690 45.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 12780 5130 4.9\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 2745 5805 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 3240 5535 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 3555 6480 0.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 10350 5355 0.7\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 10350 6255 0.8\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 12690 5580 0.7\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 12690 6030 0.7\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 9585 6480 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 9945 6975 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 12195 6480 0.9\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 11475 4230 20.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 11475 3105 21.8\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 8100 4230 12.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 12555 4365 14.9\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 4725 1665 24.1\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 2655 3690 49.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 10620 2790 44.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 375 5850 3780 1.95\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 7290 1755 4.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 6300 7425 2.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 6300 7875 4.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 6300 8190 1.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 6930 7785 8.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 6885 3060 5.1\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 9765 2835 5.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 9000 6480 1.2\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 9180 3240 4.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 8505 2835 4.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 8100 6255 4.5\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 7245 6480 1.0\001
|
||||
4 1 0 40 -1 18 12 0.0000 4 135 270 8145 5490 5.0\001
|
||||
4 0 0 50 -1 18 15 0.0000 4 240 7065 2700 900 Dimensions only indicative (see case.fpd for real values)\001
|
||||
4 0 0 50 -1 18 15 0.0000 4 180 1485 2700 1215 Not to scale\001
|
||||
4 0 0 50 -1 18 15 0.0000 4 240 2760 2700 585 Draft of overall design\001
|
55
fakefile/Makefile
Normal file
55
fakefile/Makefile
Normal file
@ -0,0 +1,55 @@
|
||||
#
|
||||
# Makefile - Build the Fakefile libraries
|
||||
#
|
||||
# Copyright 2012 by Werner Almesberger
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
|
||||
CFLAGS = -Wall -g -Wextra -Wno-unused-parameter -fPIC
|
||||
LDFLAGS = -L. -Wl,-rpath=$(shell pwd)
|
||||
LDLIBS = -lfakefile
|
||||
|
||||
LIBFAKEFILE_OBJS = comm.o fakefile.o file.o launch.o
|
||||
LIBFFSLAVE_OBJS = comm.o slave.o
|
||||
TARGETS = libfakefile.so libfakefile_slave.so demo
|
||||
|
||||
CC_normal := $(CC)
|
||||
LD_normal := $(LD)
|
||||
DEPEND_normal := $(CPP) $(CFLAGS) -MM -MG
|
||||
|
||||
CC_quiet = @echo " CC " $@ && $(CC_normal)
|
||||
LD_quiet = @echo " LD " $@ && $(LD_normal)
|
||||
GEN_quiet = @echo " GENERATE " $@ &&
|
||||
DEPEND_quiet = @$(DEPEND_normal)
|
||||
|
||||
ifeq ($(V),1)
|
||||
CC = $(CC_normal)
|
||||
LD = $(LD_normal)
|
||||
GEN =
|
||||
DEPEND = $(DEPEND_normal)
|
||||
else
|
||||
CC = $(CC_quiet)
|
||||
LD = $(LD_quiet)
|
||||
GEN = $(GEN_quiet)
|
||||
DEPEND = $(DEPEND_quiet)
|
||||
endif
|
||||
|
||||
.PHONY: all clean spotless
|
||||
|
||||
all: $(TARGETS)
|
||||
|
||||
libfakefile.so: $(LIBFAKEFILE_OBJS)
|
||||
$(LD) -shared -o $@ $^
|
||||
|
||||
libfakefile_slave.so: $(LIBFFSLAVE_OBJS)
|
||||
$(LD) -shared -o $@ $^ -ldl
|
||||
|
||||
clean:
|
||||
rm -f $(LIBFAKEFILE_OBJS) $(LIBFFSLAVE_OBJS)
|
||||
|
||||
spotless: clean
|
||||
rm -f $(TARGETS)
|
3
fakefile/README
Normal file
3
fakefile/README
Normal file
@ -0,0 +1,3 @@
|
||||
Don't use this yet ! This was intended as a means to run Kicad in a
|
||||
"jail", but that didn't pan out. Probably have to convert it to use
|
||||
ptrace.
|
254
fakefile/comm.c
Normal file
254
fakefile/comm.c
Normal file
@ -0,0 +1,254 @@
|
||||
/*
|
||||
* comm.c - Fakefile IPC functions
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "comm.h"
|
||||
|
||||
|
||||
#define BUF_SIZE 4096
|
||||
|
||||
|
||||
struct fakefile_peer {
|
||||
int in, out;
|
||||
uint8_t buf[BUF_SIZE];
|
||||
void *pos;
|
||||
const void *end;
|
||||
};
|
||||
|
||||
|
||||
struct fakefile_msg {
|
||||
struct fakefile_peer *peer;
|
||||
void *buf; /* NULL if reading */
|
||||
void *pos; /* current position in buffer; write only */
|
||||
size_t len; /* amount of data read/written so far */
|
||||
size_t msg_size; /* declared size */
|
||||
size_t buf_size; /* allocated size; write only */
|
||||
};
|
||||
|
||||
|
||||
static int master_fd(const char *name)
|
||||
{
|
||||
const char *s;
|
||||
char *end;
|
||||
long n;
|
||||
|
||||
s = getenv(name);
|
||||
if (!s) {
|
||||
fprintf(stderr, "%s not set\n", name);
|
||||
exit(1);
|
||||
}
|
||||
n = strtol(s, &end, 0);
|
||||
if (*end || n < 0) {
|
||||
fprintf(stderr, "invalid fd \"%s\" for %s\n", s, name);
|
||||
exit(1);
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
|
||||
static struct fakefile_peer *sanitize_peer(struct fakefile_peer *peer)
|
||||
{
|
||||
static int have_peer = 0;
|
||||
static struct fakefile_peer master;
|
||||
|
||||
if (peer)
|
||||
return peer;
|
||||
if (!have_peer) {
|
||||
master.in = master_fd(FAKEFILE_MASTER_OUT_VAR);
|
||||
master.out = master_fd(FAKEFILE_MASTER_IN_VAR);
|
||||
master.pos = master.buf;
|
||||
master.end = master.buf;
|
||||
have_peer = 1;
|
||||
}
|
||||
return &master;
|
||||
}
|
||||
|
||||
|
||||
struct fakefile_peer *fakefile_peer(int in, int out)
|
||||
{
|
||||
struct fakefile_peer *peer;
|
||||
|
||||
peer = alloc_type(struct fakefile_peer);
|
||||
peer->in = in;
|
||||
peer->out = out;
|
||||
peer->pos = peer->buf;
|
||||
peer->end = peer->buf;
|
||||
return peer;
|
||||
}
|
||||
|
||||
|
||||
void fakefile_peer_close(struct fakefile_peer *peer)
|
||||
{
|
||||
(void) close(peer->in);
|
||||
(void) close(peer->out);
|
||||
free(peer);
|
||||
}
|
||||
|
||||
|
||||
int fakefile_peer_fd(const struct fakefile_peer *peer)
|
||||
{
|
||||
return peer->in;
|
||||
}
|
||||
|
||||
|
||||
struct fakefile_msg *fakefile_msg_new(struct fakefile_peer *peer, int size)
|
||||
{
|
||||
struct fakefile_msg *msg;
|
||||
size_t buf_size;
|
||||
|
||||
size += sizeof(int);
|
||||
buf_size = size > BUF_SIZE ? BUF_SIZE : size;
|
||||
msg = alloc_size(sizeof(struct fakefile_msg)+buf_size);
|
||||
msg->peer = sanitize_peer(peer);
|
||||
msg->buf = msg->pos = msg+1;
|
||||
msg->len = 0;
|
||||
msg->msg_size = size;
|
||||
msg->buf_size = buf_size;
|
||||
fakefile_msg_add_int(msg, size);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
static void flush_out(struct fakefile_msg *msg)
|
||||
{
|
||||
const void *p;
|
||||
ssize_t len;
|
||||
|
||||
if (msg->pos == msg->buf)
|
||||
return;
|
||||
for (p = msg->buf; p != msg->pos; p += len) {
|
||||
len = write(msg->peer->out, p, msg->pos-p);
|
||||
if (len <= 0) {
|
||||
perror("fakefile IPC write");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct fakefile_msg *fakefile_msg_recv(struct fakefile_peer *peer)
|
||||
{
|
||||
struct fakefile_msg *msg;
|
||||
|
||||
msg = alloc_type(struct fakefile_msg);
|
||||
msg->peer = sanitize_peer(peer);
|
||||
msg->buf = NULL;
|
||||
msg->len = 0;
|
||||
msg->msg_size = sizeof(int);
|
||||
msg->msg_size = fakefile_msg_get_int(msg);
|
||||
return msg;
|
||||
}
|
||||
|
||||
|
||||
void fakefile_msg_end(struct fakefile_msg *msg)
|
||||
{
|
||||
#if 0
|
||||
fprintf(stderr, "end: len %d size %d (%p)\n",
|
||||
(int) msg->len, (int) msg->msg_size, msg->buf);
|
||||
#endif
|
||||
assert(msg->len == msg->msg_size);
|
||||
if (msg->buf)
|
||||
flush_out(msg);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
|
||||
static void add_chunk(struct fakefile_msg *msg, const void *buf, size_t len)
|
||||
{
|
||||
memcpy(msg->pos, buf, len);
|
||||
msg->pos += len;
|
||||
if (msg->pos == msg->buf+msg->buf_size) {
|
||||
flush_out(msg);
|
||||
msg->pos = msg->buf;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fakefile_msg_add(struct fakefile_msg *msg, const void *buf, size_t len)
|
||||
{
|
||||
size_t chunk;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr, "add: %d+%d/%d (%p)\n",
|
||||
(int) msg->len, (int) len, (int) msg->msg_size, msg->buf);
|
||||
#endif
|
||||
assert(msg->len+len <= msg->msg_size);
|
||||
while (len && msg->pos+len > msg->buf+msg->buf_size) {
|
||||
chunk = msg->buf+msg->buf_size-msg->pos;
|
||||
if (chunk > len)
|
||||
chunk = len;
|
||||
add_chunk(msg, buf, chunk);
|
||||
buf += chunk;
|
||||
len -= chunk;
|
||||
msg->len += chunk;
|
||||
}
|
||||
if (len) {
|
||||
add_chunk(msg, buf, len);
|
||||
msg->len += len;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static size_t get_chunk(struct fakefile_peer *peer, void *buf, size_t len)
|
||||
{
|
||||
ssize_t got;
|
||||
|
||||
got = read(peer->in, buf, len);
|
||||
if (got < 0) {
|
||||
perror("fakefile IPC read");
|
||||
exit(1);
|
||||
}
|
||||
if (!got) {
|
||||
fprintf(stderr, "fakefile EOF\n");
|
||||
exit(1);
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
|
||||
void fakefile_msg_get(struct fakefile_msg *msg, void *buf, size_t len)
|
||||
{
|
||||
struct fakefile_peer *peer = msg->peer;
|
||||
size_t chunk, got;
|
||||
|
||||
assert(msg->len+len <= msg->msg_size);
|
||||
if (!len)
|
||||
return;
|
||||
if (peer->pos != peer->end) {
|
||||
chunk = peer->end-peer->pos;
|
||||
if (chunk > len)
|
||||
chunk = len;
|
||||
memcpy(buf, peer->pos, chunk);
|
||||
peer->pos += chunk;
|
||||
buf += chunk;
|
||||
len -= chunk;
|
||||
msg->len += chunk;
|
||||
}
|
||||
while (len >= BUF_SIZE) {
|
||||
got = get_chunk(peer, buf, BUF_SIZE);
|
||||
buf += got;
|
||||
len -= got;
|
||||
msg->len += got;
|
||||
}
|
||||
if (!len)
|
||||
return;
|
||||
peer->pos = peer->buf;
|
||||
peer->end = peer->buf+get_chunk(peer, peer->buf, BUF_SIZE);
|
||||
fakefile_msg_get(msg, buf, len);
|
||||
}
|
65
fakefile/comm.h
Normal file
65
fakefile/comm.h
Normal file
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* comm.h - Fakefile IPC functions
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef COMM_H
|
||||
#define COMM_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
|
||||
#define FAKEFILE_MASTER_OUT_VAR "FAKEFILE_MASTER_OUT"
|
||||
#define FAKEFILE_MASTER_IN_VAR "FAKEFILE_MASTER_IN"
|
||||
|
||||
|
||||
struct fakefile_peer;
|
||||
struct fakefile_msg;
|
||||
|
||||
struct fakefile_peer *fakefile_peer(int in, int out);
|
||||
void fakefile_peer_close(struct fakefile_peer *peer);
|
||||
int fakefile_peer_fd(const struct fakefile_peer *peer);
|
||||
|
||||
struct fakefile_msg *fakefile_msg_new(struct fakefile_peer *peer,
|
||||
int size);
|
||||
struct fakefile_msg *fakefile_msg_recv(struct fakefile_peer *peer);
|
||||
void fakefile_msg_end(struct fakefile_msg *msg);
|
||||
|
||||
void fakefile_msg_add(struct fakefile_msg *msg, const void *buf, size_t len);
|
||||
void fakefile_msg_get(struct fakefile_msg *msg, void *buf, size_t len);
|
||||
|
||||
|
||||
#define decl_add(type) \
|
||||
static inline void fakefile_msg_add_##type( \
|
||||
struct fakefile_msg *msg, type value) \
|
||||
{ \
|
||||
fakefile_msg_add(msg, &value, sizeof(value)); \
|
||||
}
|
||||
|
||||
#define decl_get(type) \
|
||||
static inline type fakefile_msg_get_##type( \
|
||||
struct fakefile_msg *msg) \
|
||||
{ \
|
||||
type value; \
|
||||
\
|
||||
fakefile_msg_get(msg, &value, sizeof(value)); \
|
||||
return value; \
|
||||
}
|
||||
|
||||
#define decl_access(type) decl_add(type) decl_get(type)
|
||||
|
||||
decl_access(int)
|
||||
decl_access(size_t)
|
||||
decl_access(ssize_t)
|
||||
|
||||
#undef decl_add
|
||||
#undef decl_get
|
||||
#undef decl_access
|
||||
|
||||
#endif /* !COMM_H */
|
94
fakefile/demo.c
Normal file
94
fakefile/demo.c
Normal file
@ -0,0 +1,94 @@
|
||||
/*
|
||||
* demo.c - Fakefile demo
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "fakefile.h"
|
||||
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr,
|
||||
"usage: %s command [arg ...]\n"
|
||||
" %s -e path errno command\n"
|
||||
" %s -f path content command\n",
|
||||
name, name, name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
struct fakefile *ff;
|
||||
struct fakefile_event *ev;
|
||||
int error = 0;
|
||||
const char *path = NULL, *fake = NULL;
|
||||
char *end;
|
||||
|
||||
if (argc == 1)
|
||||
usage(*argv);
|
||||
if (*argv[1] == '-') {
|
||||
if (argc < 5)
|
||||
usage(*argv);
|
||||
path = argv[2];
|
||||
switch (argv[1][1]) {
|
||||
case 'e':
|
||||
error = strtoul(argv[3], &end, 0);
|
||||
if (*end)
|
||||
usage(*argv);
|
||||
break;
|
||||
case 'f':
|
||||
fake = argv[3];
|
||||
break;
|
||||
default:
|
||||
usage(*argv);
|
||||
}
|
||||
argv += 3;
|
||||
}
|
||||
ff = fakefile_execv(argv[1], argv+1);
|
||||
while (1) {
|
||||
ev = fakefile_poll();
|
||||
switch (ev->type) {
|
||||
case ff_et_open:
|
||||
fprintf(stderr, "\"%s\"\n", ev->u.open.name);
|
||||
if (path && !strcmp(ev->u.open.name, path)) {
|
||||
if (!fake)
|
||||
ev->u.open.res = -error;
|
||||
} else {
|
||||
ev->u.open.res = 0;
|
||||
}
|
||||
break;
|
||||
case ff_et_read: {
|
||||
size_t len, left;
|
||||
|
||||
len = ev->u.read.len;
|
||||
left = strlen(fake);
|
||||
if (len > left)
|
||||
len = left;
|
||||
ev->u.read.buf = (void *) fake;
|
||||
ev->u.read.len = len;
|
||||
fake += len;
|
||||
break;
|
||||
}
|
||||
case ff_et_exit:
|
||||
goto out;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
fakefile_respond(ev);
|
||||
}
|
||||
out:
|
||||
fakefile_end(ff);
|
||||
return 0;
|
||||
}
|
302
fakefile/fakefile.c
Normal file
302
fakefile/fakefile.c
Normal file
@ -0,0 +1,302 @@
|
||||
/*
|
||||
* fakefile.c - Programmed file system illusion
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <poll.h>
|
||||
#include <assert.h>
|
||||
#include <sys/wait.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "internal.h"
|
||||
#include "fakefile.h"
|
||||
|
||||
|
||||
struct event {
|
||||
struct fakefile_event ev;
|
||||
struct fakefile *ff;
|
||||
void *tmp;
|
||||
void (*respond)(struct event *ev);
|
||||
};
|
||||
|
||||
static struct fakefile *fakefiles = NULL;
|
||||
static struct pollfd *fds = NULL;
|
||||
static int nfds = 0;
|
||||
|
||||
|
||||
static void map_slave_fd(struct fakefile *ff, int fd, void *handle)
|
||||
{
|
||||
struct fd_map *map;
|
||||
|
||||
map = alloc_type(struct fd_map);
|
||||
map->fd = fd;
|
||||
map->handle = handle;
|
||||
map->next = ff->map;
|
||||
ff->map = map;
|
||||
}
|
||||
|
||||
|
||||
static void *lookup_slave_fd(struct fakefile *ff, int fd)
|
||||
{
|
||||
const struct fd_map *map;
|
||||
|
||||
for (map = ff->map; map; map = map->next)
|
||||
if (map->fd == fd)
|
||||
return map->handle;
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
static void unmap_slave_fd(struct fakefile *ff, int fd)
|
||||
{
|
||||
struct fd_map **map, *next;
|
||||
|
||||
for (map = &ff->map; (*map)->fd != fd; map = &(*map)->next);
|
||||
next = (*map)->next;
|
||||
free(*map);
|
||||
*map = next;
|
||||
}
|
||||
|
||||
|
||||
struct fakefile *fakefile_execv(const char *path, char *const argv[])
|
||||
{
|
||||
struct fakefile *ff;
|
||||
|
||||
ff = fakefile_launch(path, argv);
|
||||
ff->map = NULL;
|
||||
ff->next = fakefiles;
|
||||
fakefiles = ff;
|
||||
fds = realloc(fds, sizeof(struct pollfd)*(nfds+1));
|
||||
if (!fds) {
|
||||
perror("realloc");
|
||||
exit(1);
|
||||
}
|
||||
fds[nfds].fd = fakefile_peer_fd(ff->peer);
|
||||
fds[nfds].events = POLLIN | POLLHUP;
|
||||
nfds++;
|
||||
return ff;
|
||||
}
|
||||
|
||||
|
||||
static void respond_open(struct event *ev)
|
||||
{
|
||||
const struct fakefile_open *prm = &ev->ev.u.open;
|
||||
struct fakefile *ff = ev->ff;
|
||||
struct fakefile_msg *msg;
|
||||
|
||||
msg = fakefile_msg_new(ff->peer, sizeof(int));
|
||||
if (prm->res > 0)
|
||||
map_slave_fd(ff, prm->res, prm->handle);
|
||||
fakefile_msg_add_int(msg, prm->res);
|
||||
fakefile_msg_end(msg);
|
||||
free(prm->name);
|
||||
}
|
||||
|
||||
|
||||
static void respond_read(struct event *ev)
|
||||
{
|
||||
const struct fakefile_read *prm = &ev->ev.u.read;
|
||||
struct fakefile *ff = ev->ff;
|
||||
struct fakefile_msg *msg;
|
||||
ssize_t size;
|
||||
|
||||
size = prm->len < 0 ? 0 : prm->len;
|
||||
msg = fakefile_msg_new(ff->peer, sizeof(ssize_t)+size);
|
||||
fakefile_msg_add_ssize_t(msg, prm->len);
|
||||
if (size)
|
||||
fakefile_msg_add(msg, prm->buf, size);
|
||||
fakefile_msg_end(msg);
|
||||
free(ev->tmp);
|
||||
}
|
||||
|
||||
|
||||
static void respond_fstat(struct event *ev)
|
||||
{
|
||||
const struct fakefile_fstat *prm = &ev->ev.u.fstat;
|
||||
struct fakefile *ff = ev->ff;
|
||||
struct fakefile_msg *msg;
|
||||
ssize_t size;
|
||||
|
||||
size = prm->res < 0 ? 0 : sizeof(struct stat);
|
||||
msg = fakefile_msg_new(ff->peer, sizeof(int)+size);
|
||||
fakefile_msg_add_int(msg, prm->res);
|
||||
if (size)
|
||||
fakefile_msg_add(msg, &prm->st, sizeof(struct stat));
|
||||
fakefile_msg_end(msg);
|
||||
}
|
||||
|
||||
|
||||
static void respond_exit(struct event *ev)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
static void respond_close(struct event *ev)
|
||||
{
|
||||
const struct fakefile_close *prm = &ev->ev.u.close;
|
||||
struct fakefile *ff = ev->ff;
|
||||
struct fakefile_msg *msg;
|
||||
|
||||
msg = fakefile_msg_new(ff->peer, sizeof(int));
|
||||
fakefile_msg_add_int(msg, prm->res);
|
||||
fakefile_msg_end(msg);
|
||||
}
|
||||
|
||||
|
||||
static struct fakefile_event *get_event(int fd)
|
||||
{
|
||||
struct fakefile *ff;
|
||||
struct event *ev;
|
||||
struct fakefile_msg *msg;
|
||||
|
||||
for (ff = fakefiles; ff; ff = ff->next)
|
||||
if (fakefile_peer_fd(ff->peer) == fd)
|
||||
break;
|
||||
assert(ff);
|
||||
|
||||
ev = alloc_type(struct event);
|
||||
ev->ff = ff;
|
||||
|
||||
msg = fakefile_msg_recv(ff->peer);
|
||||
ev->ev.type = fakefile_msg_get_int(msg);
|
||||
switch (ev->ev.type) {
|
||||
case ff_et_exit: {
|
||||
struct fakefile_exit *prm = &ev->ev.u.exit;
|
||||
|
||||
ev->respond = respond_exit;
|
||||
prm->status = fakefile_msg_get_int(msg);
|
||||
break;
|
||||
}
|
||||
case ff_et_open: {
|
||||
struct fakefile_open *prm = &ev->ev.u.open;
|
||||
int len;
|
||||
|
||||
ev->respond = respond_open;
|
||||
prm->flags = fakefile_msg_get_int(msg);
|
||||
prm->mode = fakefile_msg_get_int(msg);
|
||||
prm->res = fakefile_msg_get_int(msg);
|
||||
len = fakefile_msg_get_int(msg);
|
||||
prm->name = alloc_size(len+1);
|
||||
fakefile_msg_get(msg, prm->name, len);
|
||||
prm->name[len] = 0;
|
||||
prm->handle = NULL;
|
||||
break;
|
||||
}
|
||||
case ff_et_read: {
|
||||
struct fakefile_read *prm = &ev->ev.u.read;
|
||||
int fd;
|
||||
|
||||
ev->respond = respond_read;
|
||||
fd = fakefile_msg_get_int(msg);
|
||||
prm->handle = lookup_slave_fd(ff, fd);
|
||||
prm->len = fakefile_msg_get_size_t(msg);
|
||||
prm->buf = ev->tmp = alloc_size(prm->len);
|
||||
break;
|
||||
}
|
||||
case ff_et_write: {
|
||||
abort();
|
||||
}
|
||||
case ff_et_close: {
|
||||
struct fakefile_close *prm = &ev->ev.u.close;
|
||||
int fd;
|
||||
|
||||
ev->respond = respond_close;
|
||||
fd = fakefile_msg_get_int(msg);
|
||||
prm->handle = lookup_slave_fd(ff, fd);
|
||||
prm->res = 0;
|
||||
break;
|
||||
}
|
||||
case ff_et_unlink:
|
||||
abort();
|
||||
case ff_et_rename:
|
||||
abort();
|
||||
case ff_et_fstat: {
|
||||
struct fakefile_fstat *prm = &ev->ev.u.fstat;
|
||||
int fd;
|
||||
|
||||
ev->respond = respond_fstat;
|
||||
fd = fakefile_msg_get_int(msg);
|
||||
prm->handle = lookup_slave_fd(ff, fd);
|
||||
prm->res = fstat(fd, &prm->st);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
fakefile_msg_end(msg);
|
||||
if (fakefile_internal_event(ev))
|
||||
return NULL;
|
||||
return &ev->ev;
|
||||
}
|
||||
|
||||
|
||||
static struct fakefile_event *handle_exit(int fd)
|
||||
{
|
||||
struct fakefile *ff;
|
||||
struct fakefile_event *event;
|
||||
|
||||
for (ff = fakefiles; ff; ff = ff->next)
|
||||
if (fakefile_peer_fd(ff->peer) == fd)
|
||||
break;
|
||||
assert(ff);
|
||||
event = alloc_type(struct fakefile_event);
|
||||
event->type = ff_et_exit;
|
||||
if (waitpid(ff->pid, &event->u.exit.status, 0) < 0) {
|
||||
perror("waitpid");
|
||||
exit(1);
|
||||
}
|
||||
//@@@ destroy
|
||||
return event;
|
||||
}
|
||||
|
||||
|
||||
struct fakefile_event *fakefile_poll(void)
|
||||
{
|
||||
struct fakefile_event *event;
|
||||
struct pollfd *p;
|
||||
int n;
|
||||
|
||||
while (1) {
|
||||
n = poll(fds, nfds, -1);
|
||||
if (n < 0) {
|
||||
perror("poll");
|
||||
exit(1);
|
||||
}
|
||||
if (!n) {
|
||||
fprintf(stderr, "poll() returned 0\n");
|
||||
exit(1);
|
||||
}
|
||||
for (p = fds; n && p != fds+nfds; p++) {
|
||||
if (p->revents & POLLIN) {
|
||||
event = get_event(p->fd);
|
||||
if (event)
|
||||
return event;
|
||||
}
|
||||
if (p->revents & POLLHUP)
|
||||
return handle_exit(p->fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void fakefile_respond(struct fakefile_event *event)
|
||||
{
|
||||
struct event *ev = (struct event *) event;
|
||||
|
||||
ev->respond(ev);
|
||||
free(ev);
|
||||
}
|
||||
|
||||
|
||||
void fakefile_end(struct fakefile *ff)
|
||||
{
|
||||
}
|
91
fakefile/fakefile.h
Normal file
91
fakefile/fakefile.h
Normal file
@ -0,0 +1,91 @@
|
||||
/*
|
||||
* fakefile.h - Programmed file system illusion
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef FAKEFILE_H
|
||||
#define FAKEFILE_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
|
||||
enum fakefile_event_type {
|
||||
ff_et_exit,
|
||||
ff_et_open,
|
||||
ff_et_read,
|
||||
ff_et_write,
|
||||
ff_et_close,
|
||||
ff_et_unlink,
|
||||
ff_et_rename,
|
||||
ff_et_fstat,
|
||||
};
|
||||
|
||||
struct fakefile_event {
|
||||
enum fakefile_event_type type;
|
||||
union {
|
||||
struct fakefile_exit {
|
||||
/* in */
|
||||
int status;
|
||||
} exit;
|
||||
struct fakefile_open {
|
||||
/* in */
|
||||
char *name;
|
||||
int flags;
|
||||
int mode;
|
||||
/* out */
|
||||
void *handle;
|
||||
int res; /* < 0: -errno; 0: regular open (in slave) */
|
||||
} open;
|
||||
struct fakefile_read {
|
||||
/* in */
|
||||
const void *handle;
|
||||
/* in/out */
|
||||
void *buf;
|
||||
ssize_t len;
|
||||
} read;
|
||||
struct fakefile_write {
|
||||
/* in */
|
||||
const void *handle;
|
||||
void *buf;
|
||||
/* in/out */
|
||||
ssize_t len;
|
||||
} write;
|
||||
struct fakefile_close {
|
||||
/* in */
|
||||
const void *handle;
|
||||
/* out */
|
||||
int res;
|
||||
} close;
|
||||
struct fakefile_unlink {
|
||||
} unlink;
|
||||
struct fakefile_rename {
|
||||
} rename;
|
||||
struct fakefile_fstat {
|
||||
/* in */
|
||||
const void *handle;
|
||||
/* out */
|
||||
struct stat st;
|
||||
int res;
|
||||
} fstat;
|
||||
} u;
|
||||
void *user;
|
||||
};
|
||||
|
||||
|
||||
struct fakefile *fakefile_execv(const char *path, char *const argv[]);
|
||||
struct fakefile_event *fakefile_poll(void);
|
||||
void fakefile_respond(struct fakefile_event *event);
|
||||
void fakefile_end(struct fakefile *ff);
|
||||
|
||||
void fakefile_file(struct fakefile *ff, const char *name,
|
||||
const void *in, size_t len, void **out);
|
||||
void fakefile_antifile(struct fakefile *ff, const char *name);
|
||||
|
||||
#endif /* !FAKEFILE_H */
|
41
fakefile/file.c
Normal file
41
fakefile/file.c
Normal file
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* file.c - Whole file operations
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include "fakefile.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
int fakefile_internal_event(struct event *ev)
|
||||
{
|
||||
(void) ev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static void add_file(struct fakefile *ff, const char *name,
|
||||
const void *in, size_t len, void **out)
|
||||
{
|
||||
/* ... */
|
||||
}
|
||||
|
||||
|
||||
void fakefile_file(struct fakefile *ff, const char *name,
|
||||
const void *in, size_t len, void **out)
|
||||
{
|
||||
add_file(ff, name, in, len, out);
|
||||
}
|
||||
|
||||
|
||||
void fakefile_antifile(struct fakefile *ff, const char *name)
|
||||
{
|
||||
add_file(ff, name, NULL, 0, NULL);
|
||||
}
|
40
fakefile/internal.h
Normal file
40
fakefile/internal.h
Normal file
@ -0,0 +1,40 @@
|
||||
/*
|
||||
* internal.h - Internal functions and data structures at master
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef INTERNAL_H
|
||||
#define INTERNAL_H
|
||||
|
||||
#include <unistd.h>
|
||||
|
||||
#include "comm.h"
|
||||
|
||||
|
||||
struct fd_map {
|
||||
int fd;
|
||||
void *handle;
|
||||
struct fd_map *next;
|
||||
};
|
||||
|
||||
struct fakefile {
|
||||
pid_t pid;
|
||||
struct fakefile_peer *peer;
|
||||
struct fd_map *map;
|
||||
struct fakefile *next;
|
||||
};
|
||||
|
||||
|
||||
struct event;
|
||||
|
||||
|
||||
struct fakefile *fakefile_launch(const char *path, char *const argv[]);
|
||||
int fakefile_internal_event(struct event *ev);
|
||||
|
||||
#endif /* !INTERNAL_H */
|
162
fakefile/launch.c
Normal file
162
fakefile/launch.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* launch.c - Fakefile process launcher
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "fakefile.h"
|
||||
#include "comm.h"
|
||||
#include "internal.h"
|
||||
|
||||
|
||||
#define FD_DIR "/proc/self/fd"
|
||||
|
||||
|
||||
static void safe_setenvf(const char *var, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
char *buf;
|
||||
ssize_t len;
|
||||
|
||||
va_start(ap, fmt);
|
||||
len = vsnprintf(NULL, 0, fmt, ap);
|
||||
va_end(ap);
|
||||
if (len < 0) {
|
||||
perror("vsprintf");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
buf = alloc_size(len+1);
|
||||
|
||||
va_start(ap, fmt);
|
||||
vsprintf(buf, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (setenv(var, buf, 1) < 0) {
|
||||
perror("setenv");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
free(buf);
|
||||
}
|
||||
|
||||
|
||||
static void env_append(const char *var, const char *s)
|
||||
{
|
||||
const char *old;
|
||||
char *tmp;
|
||||
size_t len1, len2;
|
||||
|
||||
old = getenv(var);
|
||||
if (!old) {
|
||||
safe_setenvf(var, "%s", s+1);
|
||||
return;
|
||||
}
|
||||
len1 = strlen(old);
|
||||
len2 = strlen(s);
|
||||
tmp = alloc_size(len1+len2+1);
|
||||
memcpy(tmp, old, len1);
|
||||
memcpy(tmp+len1, s, len2+1);
|
||||
safe_setenvf(var, "%s", tmp);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
|
||||
static void closefds(int preserve, ...)
|
||||
{
|
||||
va_list ap;
|
||||
DIR *dir;
|
||||
int fd;
|
||||
struct dirent *de;
|
||||
int n;
|
||||
|
||||
fd = open(FD_DIR, O_RDONLY);
|
||||
if (fd < 0) {
|
||||
perror(FD_DIR);
|
||||
exit(1);
|
||||
}
|
||||
dir = fdopendir(fd);
|
||||
if (!dir) {
|
||||
perror("fdopendir");
|
||||
exit(1);
|
||||
}
|
||||
while (1) {
|
||||
next:
|
||||
de = readdir(dir);
|
||||
if (!de)
|
||||
break;
|
||||
n = atoi(de->d_name);
|
||||
if (n <= 2 || n == fd)
|
||||
continue;
|
||||
if (preserve > 0) {
|
||||
if (n == preserve)
|
||||
continue;
|
||||
va_start(ap, preserve);
|
||||
while (1) {
|
||||
n = va_arg(ap, int);
|
||||
if (n < 0)
|
||||
break;
|
||||
if (n == n)
|
||||
goto next;
|
||||
}
|
||||
va_end(ap);
|
||||
}
|
||||
(void) close(n);
|
||||
}
|
||||
if (closedir(dir) < 0) {
|
||||
perror("closedir");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
struct fakefile *fakefile_launch(const char *path, char *const argv[])
|
||||
{
|
||||
struct fakefile *ff;
|
||||
int m2s[2], s2m[2];
|
||||
pid_t pid;
|
||||
|
||||
if (pipe(m2s) < 0 || pipe(s2m) < 0) {
|
||||
perror("pipe");
|
||||
exit(1);
|
||||
}
|
||||
pid = fork();
|
||||
if (pid < 0) {
|
||||
perror("fork");
|
||||
exit(1);
|
||||
}
|
||||
if (!pid) {
|
||||
env_append("LD_LIBRARY_PATH", ":.");
|
||||
env_append("LD_PRELOAD", " libfakefile_slave.so");
|
||||
safe_setenvf(FAKEFILE_MASTER_OUT_VAR, "%d", m2s[0]);
|
||||
safe_setenvf(FAKEFILE_MASTER_IN_VAR, "%d", s2m[1]);
|
||||
closefds(m2s[0], s2m[1], -1);
|
||||
execv(path, argv);
|
||||
perror(path);
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
(void) close(m2s[0]);
|
||||
(void) close(s2m[1]);
|
||||
|
||||
ff = alloc_type(struct fakefile);
|
||||
ff->pid = pid;
|
||||
ff->peer = fakefile_peer(s2m[0], m2s[1]);
|
||||
|
||||
return ff;
|
||||
}
|
305
fakefile/slave.c
Normal file
305
fakefile/slave.c
Normal file
@ -0,0 +1,305 @@
|
||||
/*
|
||||
* slave.c - Fakefile slave library
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define __USE_GNU /* for RTLD_NEXT */
|
||||
#include <dlfcn.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "fakefile.h"
|
||||
#include "comm.h"
|
||||
|
||||
|
||||
#define DUMMY_FILE "/dev/null"
|
||||
#define master NULL
|
||||
|
||||
|
||||
static struct fd_entry {
|
||||
int fd;
|
||||
struct fd_entry *next;
|
||||
} *fake_fds = NULL;
|
||||
|
||||
static int (*libc_close)(int fd);
|
||||
static int (*libc_dup)(int oldfd);
|
||||
static int (*libc_dup2)(int oldfd, int newfd);
|
||||
static int (*libc_open)(const char *pathname, int flags, mode_t mode);
|
||||
static ssize_t (*libc_read)(int fd, void *buf, size_t count);
|
||||
|
||||
static FILE *(*libc_fopen)(const char *path, const char *mode);
|
||||
|
||||
static void init_self(void)
|
||||
{
|
||||
static int initialized = 0;
|
||||
|
||||
if (initialized)
|
||||
return;
|
||||
libc_close = dlsym(RTLD_NEXT, "close");
|
||||
libc_dup = dlsym(RTLD_NEXT, "dup");
|
||||
libc_dup2 = dlsym(RTLD_NEXT, "dup2");
|
||||
libc_open = dlsym(RTLD_NEXT, "open");
|
||||
libc_read = dlsym(RTLD_NEXT, "read");
|
||||
libc_fopen = dlsym(RTLD_NEXT, "fopen");
|
||||
if (!libc_close || !libc_dup || !libc_dup2 || !libc_open ||
|
||||
!libc_read) {
|
||||
perror("dlsym");
|
||||
_exit(1);
|
||||
}
|
||||
initialized = 1;
|
||||
}
|
||||
|
||||
|
||||
static int get_fd(void)
|
||||
{
|
||||
int fd;
|
||||
|
||||
fd = libc_open(DUMMY_FILE, O_RDONLY, 0);
|
||||
if (fd < 0) {
|
||||
perror(DUMMY_FILE);
|
||||
exit(1);
|
||||
}
|
||||
assert(fd);
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
static void add_fake_fd(int fd)
|
||||
{
|
||||
struct fd_entry *e;
|
||||
|
||||
e = alloc_type(struct fd_entry);
|
||||
e->fd = fd;
|
||||
e->next = fake_fds;
|
||||
fake_fds =e;
|
||||
}
|
||||
|
||||
|
||||
static int is_fake_fd(int fd)
|
||||
{
|
||||
const struct fd_entry *e;
|
||||
|
||||
for (e = fake_fds; e && e->fd != fd; e = e->next);
|
||||
return !!e;
|
||||
}
|
||||
|
||||
|
||||
static int del_fake_fd(int fd)
|
||||
{
|
||||
struct fd_entry **e, *next;
|
||||
|
||||
for (e = &fake_fds; *e; e = &(*e)->next)
|
||||
if ((*e)->fd == fd)
|
||||
break;
|
||||
if (!*e)
|
||||
return 0;
|
||||
next = (*e)->next;
|
||||
free(*e);
|
||||
*e = next;
|
||||
(void) libc_close(fd);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int open(const char *pathname, int flags, ...)
|
||||
{
|
||||
va_list ap;
|
||||
struct fakefile_msg *msg;
|
||||
size_t len;
|
||||
int mode = 0;
|
||||
int fd, res;
|
||||
|
||||
init_self();
|
||||
if (flags & O_CREAT) {
|
||||
va_start(ap, flags);
|
||||
mode = va_arg(ap, int);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
fd = get_fd();
|
||||
len = strlen(pathname);
|
||||
|
||||
msg = fakefile_msg_new(master, len+5*sizeof(int));
|
||||
fakefile_msg_add_int(msg, ff_et_open);
|
||||
fakefile_msg_add_int(msg, flags);
|
||||
fakefile_msg_add_int(msg, mode);
|
||||
fakefile_msg_add_int(msg, fd);
|
||||
fakefile_msg_add_int(msg, len);
|
||||
fakefile_msg_add(msg, pathname, len);
|
||||
fakefile_msg_end(msg);
|
||||
|
||||
msg = fakefile_msg_recv(master);
|
||||
res = fakefile_msg_get_int(msg);
|
||||
fakefile_msg_end(msg);
|
||||
|
||||
//fprintf(stderr, "res %d\n", (int) res);
|
||||
if (res <= 0) {
|
||||
(void) close(fd);
|
||||
if (res < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (res)
|
||||
add_fake_fd(fd);
|
||||
else
|
||||
res = libc_open(pathname, flags, mode);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
ssize_t read(int fd, void *buf, size_t count)
|
||||
{
|
||||
struct fakefile_msg *msg;
|
||||
ssize_t res;
|
||||
|
||||
init_self();
|
||||
if (!is_fake_fd(fd))
|
||||
return libc_read(fd, buf, count);
|
||||
msg = fakefile_msg_new(master, 2*sizeof(int)+sizeof(size_t));
|
||||
fakefile_msg_add_int(msg, ff_et_read);
|
||||
fakefile_msg_add_int(msg, fd);
|
||||
fakefile_msg_add_size_t(msg, count);
|
||||
fakefile_msg_end(msg);
|
||||
|
||||
msg = fakefile_msg_recv(master);
|
||||
res = fakefile_msg_get_size_t(msg);
|
||||
if (res > 0) {
|
||||
assert((size_t) res <= count);
|
||||
fakefile_msg_get(msg, buf, res);
|
||||
} else if (res < 0) {
|
||||
errno = -res;
|
||||
res = -1;
|
||||
}
|
||||
fakefile_msg_end(msg);
|
||||
//fprintf(stderr, "READ %d\n", (int) res);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int fstat(int fd, struct stat *buf)
|
||||
{
|
||||
struct fakefile_msg *msg;
|
||||
int res;
|
||||
|
||||
init_self();
|
||||
msg = fakefile_msg_new(master, 2*sizeof(int));
|
||||
fakefile_msg_add_int(msg, ff_et_fstat);
|
||||
fakefile_msg_add_int(msg, fd);
|
||||
fakefile_msg_end(msg);
|
||||
|
||||
msg = fakefile_msg_recv(master);
|
||||
res = fakefile_msg_get_size_t(msg);
|
||||
if (res < 0) {
|
||||
errno = -res;
|
||||
res = -1;
|
||||
} else {
|
||||
fakefile_msg_get(msg, buf, sizeof(struct stat));
|
||||
}
|
||||
fakefile_msg_end(msg);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int stat(const char *path, struct stat *buf)
|
||||
{
|
||||
int fd, res;
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
return fd;
|
||||
res = fstat(fd, buf);
|
||||
(void) close(fd);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int lstat(const char *path, struct stat *buf)
|
||||
{
|
||||
return stat(path, buf);
|
||||
}
|
||||
|
||||
|
||||
int close(int fd)
|
||||
{
|
||||
struct fakefile_msg *msg;
|
||||
int res;
|
||||
|
||||
init_self();
|
||||
if (!del_fake_fd(fd))
|
||||
return libc_close(fd);
|
||||
|
||||
msg = fakefile_msg_new(master, 2*sizeof(int));
|
||||
fakefile_msg_add_int(msg, ff_et_close);
|
||||
fakefile_msg_add_int(msg, fd);
|
||||
fakefile_msg_end(msg);
|
||||
|
||||
msg = fakefile_msg_recv(master);
|
||||
res = fakefile_msg_get_int(msg);
|
||||
fakefile_msg_end(msg);
|
||||
|
||||
if (res < 0) {
|
||||
errno = -res;
|
||||
return -1;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
FILE *fopen(const char *path, const char *mode)
|
||||
{
|
||||
init_self();
|
||||
fprintf(stderr, "fopen \"%s\"\n", path);
|
||||
return libc_fopen(path, mode);
|
||||
}
|
||||
|
||||
|
||||
int dup(int oldfd)
|
||||
{
|
||||
init_self();
|
||||
if (is_fake_fd(oldfd)) {
|
||||
fprintf(stderr, "not supporting \"dup\" yet\n");
|
||||
exit(1);
|
||||
}
|
||||
return libc_dup(oldfd);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int dup2(int oldfd, int newfd)
|
||||
{
|
||||
int res;
|
||||
|
||||
init_self();
|
||||
if (oldfd == newfd)
|
||||
return 0;
|
||||
if (is_fake_fd(oldfd)) {
|
||||
fprintf(stderr, "not supporting \"dup2\" yet\n");
|
||||
exit(1);
|
||||
}
|
||||
if (is_fake_fd(newfd)) {
|
||||
res = close(newfd);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
return libc_dup2(oldfd, newfd);
|
||||
}
|
26
fakefile/util.h
Normal file
26
fakefile/util.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* util.h - Utility functions
|
||||
*
|
||||
* Copyright 2012 by Werner Almesberger
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#ifndef UTIL_H
|
||||
#define UTIL_H
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define alloc_size(s) \
|
||||
({ void *alloc_size_tmp = malloc(s); \
|
||||
if (!alloc_size_tmp) \
|
||||
abort(); \
|
||||
alloc_size_tmp; })
|
||||
|
||||
#define alloc_type(t) ((t *) alloc_size(sizeof(t)))
|
||||
|
||||
#endif /* !UTIL_H */
|
@ -3,8 +3,8 @@ http://lists.en.qi-hardware.com/pipermail/discussion/
|
||||
Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
|
||||
2009 85 141 137 157 99 145
|
||||
2010 180 180 263 214 412 218 492 295 260 132 116 174
|
||||
2011 150 155 125 108 71 127 49 106 129 69 71 36
|
||||
2012 39 20
|
||||
2011 150 155 125 108 71 127 49 106 129 69 71 33
|
||||
2012 39 20 38
|
||||
|
||||
http://lists.milkymist.org/pipermail/devel-milkymist.org/
|
||||
|
||||
@ -12,4 +12,4 @@ http://lists.milkymist.org/pipermail/devel-milkymist.org/
|
||||
2009 3 8 15 27 33 14 24 14
|
||||
2010 29 28 36 28 22 25 35 14 27 39 17 12
|
||||
2011 61 43 59 81 17 48 43 35 24 78 116 183
|
||||
2012 52 67
|
||||
2012 52 67 48
|
||||
|
22
ircstat/README
Normal file
22
ircstat/README
Normal file
@ -0,0 +1,22 @@
|
||||
These are the scripts and data files used for the monthly statistics
|
||||
of the principal IRC channels and mailing lists statistics associated
|
||||
with the Qi-Hardware project.
|
||||
|
||||
Monthly process:
|
||||
|
||||
IRC:
|
||||
|
||||
./collect
|
||||
./stat
|
||||
display out.png
|
||||
qippl out.png stat/irc-qihw-MMYY.png
|
||||
|
||||
Mailing lists:
|
||||
|
||||
# update ML from archive pages
|
||||
./mlstat
|
||||
qippl out.png stat/ml-qihw-MMYY.png
|
||||
|
||||
MMYY is the last full month covered.
|
||||
|
||||
|
59
ircstat/mlstat
Executable file
59
ircstat/mlstat
Executable file
@ -0,0 +1,59 @@
|
||||
#!/bin/sh
|
||||
list=
|
||||
while read l; do
|
||||
case "$l" in
|
||||
*qi-hardware*)
|
||||
list=q;;
|
||||
*milkymist*)
|
||||
list=m;;
|
||||
20*) set -- `echo "$l" | sed "s/ / -/g"`
|
||||
y=$1
|
||||
for m in 1 2 3 4 5 6 7 8 9 10 11 12; do
|
||||
shift
|
||||
[ "$1" ] || break
|
||||
if [ "$1" = - ]; then
|
||||
v=
|
||||
else
|
||||
v=$1
|
||||
fi
|
||||
eval ${list}_${y}_${m}=$v
|
||||
done
|
||||
esac
|
||||
done <ML
|
||||
|
||||
N=3
|
||||
t=
|
||||
>_out
|
||||
n=0
|
||||
off=2
|
||||
for y in 10 11 12; do
|
||||
for m in 1 2 3 4 5 6 7 8 9 10 11 12; do
|
||||
mm=`printf "%02d" $m`
|
||||
qn=`eval echo \\$q_20${y}_${m}`
|
||||
mn=`eval echo \\$m_20${y}_${m}`
|
||||
[ -z "$qn" -a -z "$mn" ] && continue
|
||||
if [ `expr $n % $N` = 0 ]; then
|
||||
[ "$t" ] && t=$t,
|
||||
t="$t \"$m/$y\" $n"
|
||||
else
|
||||
t="$t, \"\" $n"
|
||||
fi
|
||||
# cat ${Q}_20${y}-${mm}-*.log.html | gzip -9 | wc -c >>_out
|
||||
echo ${qn:-0} ${mn:-0} >>_out
|
||||
n=`expr $n + 1`
|
||||
done
|
||||
done
|
||||
|
||||
gnuplot -persist <<EOF
|
||||
set xtics ($t)
|
||||
set grid xtics
|
||||
set title "Traffic on the Qi-Hardware Mailing Lists"
|
||||
set xlabel "Month"
|
||||
set ylabel "Traffic (kbytes gzip'ed)"
|
||||
plot "_out" using (\$1) with lines title "qi-hardware" lw 2, \
|
||||
"_out" using (\$2) with lines title "milkymist" lw 2, \
|
||||
"_out" using :(\$1+\$2) with lines title "Both" lw 2
|
||||
set term png
|
||||
set output "out.png"
|
||||
replot
|
||||
EOF
|
@ -3,10 +3,11 @@ Q=en.qi-hardware.com/irclogs/qi-hardware
|
||||
M=en.qi-hardware.com/mmlogs/milkymist
|
||||
# Saving to: `en.qi-hardware.com/irclogs/qi-hardware_2010-06-11.log.html'
|
||||
|
||||
N=2
|
||||
N=3
|
||||
t=
|
||||
>_out
|
||||
n=0
|
||||
off=2
|
||||
for y in 10 11 12; do
|
||||
for m in 1 2 3 4 5 6 7 8 9 10 11 12; do
|
||||
mm=`printf "%02d" $m`
|
||||
|
@ -1,73 +1,71 @@
|
||||
Index: rtems/c/src/lib/libbsp/lm32/shared/milkymist_ac97/ac97.c
|
||||
===================================================================
|
||||
--- rtems.orig/c/src/lib/libbsp/lm32/shared/milkymist_ac97/ac97.c 2012-03-20 17:11:20.087160002 +0800
|
||||
+++ rtems/c/src/lib/libbsp/lm32/shared/milkymist_ac97/ac97.c 2012-03-20 17:12:23.731160001 +0800
|
||||
@@ -372,6 +372,39 @@
|
||||
return sc;
|
||||
--- rtems.orig/c/src/lib/libbsp/lm32/shared/milkymist_ac97/ac97.c 2012-03-27 14:03:04.065264002 +0800
|
||||
+++ rtems/c/src/lib/libbsp/lm32/shared/milkymist_ac97/ac97.c 2012-03-29 15:58:14.440242001 +0800
|
||||
@@ -316,6 +316,7 @@
|
||||
unsigned int chan, int mono)
|
||||
{
|
||||
unsigned int *val = (unsigned int *)buf;
|
||||
+ int mic_boost;
|
||||
int codec;
|
||||
int left, right;
|
||||
|
||||
@@ -328,12 +329,14 @@
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
if (mono) {
|
||||
- right = left = 100-(((codec & 0x1f) + 1)*100)/32;
|
||||
+ left = 100-(((codec & 0x1f) + 1)*100)/32;
|
||||
+ mic_boost = (codec & (1 << 6)) >> 6;
|
||||
+ *val = left | mic_boost << 8;
|
||||
} else {
|
||||
right = 100-(((codec & 0x1f) + 1)*100)/32;
|
||||
left = 100-((((codec & 0x1f00) >> 8) + 1)*100)/32;
|
||||
+ *val = left | (right << 8);
|
||||
}
|
||||
- *val = left | (right << 8);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
+static rtems_status_code ioctl_read_mic_boost(void *buf, unsigned int chan)
|
||||
+{
|
||||
+ unsigned int *val = (unsigned int *)buf;
|
||||
+ int codec;
|
||||
+
|
||||
+ codec = read_cr(chan);
|
||||
+ if (codec < 0)
|
||||
+ return RTEMS_UNSATISFIED;
|
||||
+
|
||||
+ *val = (codec & (1 << 6)) >> 6;
|
||||
+ return RTEMS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
+static rtems_status_code ioctl_write_mic_boost(void *buf, unsigned int chan)
|
||||
+{
|
||||
+ unsigned int *val = (unsigned int *)buf;
|
||||
+ int codec;
|
||||
+
|
||||
+ codec = read_cr(chan);
|
||||
+ if (codec < 0)
|
||||
+ return RTEMS_UNSATISFIED;
|
||||
+
|
||||
+ if (*val)
|
||||
+ codec |= (1 << 6);
|
||||
+ else
|
||||
+ codec &= ~(1 << 6);
|
||||
+
|
||||
+ if (!write_cr(chan, codec))
|
||||
+ return RTEMS_UNSATISFIED;
|
||||
+
|
||||
+ return RTEMS_SUCCESSFUL;
|
||||
+}
|
||||
+
|
||||
rtems_device_driver ac97_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
@@ -419,6 +452,16 @@
|
||||
if(sc == RTEMS_SUCCESSFUL)
|
||||
args->ioctl_return = 0;
|
||||
return sc;
|
||||
+ case SOUND_MIXER_READ(SOUND_MIXER_MIC_BOOST):
|
||||
+ sc = ioctl_read_mic_boost(args->buffer, 0x0e);
|
||||
+ if(sc == RTEMS_SUCCESSFUL)
|
||||
+ args->ioctl_return = 0;
|
||||
+ return sc;
|
||||
+ case SOUND_MIXER_WRITE(SOUND_MIXER_MIC_BOOST):
|
||||
+ sc = ioctl_write_mic_boost(args->buffer, 0x0e);
|
||||
+ if(sc == RTEMS_SUCCESSFUL)
|
||||
+ args->ioctl_return = 0;
|
||||
+ return sc;
|
||||
default:
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
Index: rtems/c/src/lib/libbsp/lm32/shared/milkymist_ac97/milkymist_ac97.h
|
||||
===================================================================
|
||||
--- rtems.orig/c/src/lib/libbsp/lm32/shared/milkymist_ac97/milkymist_ac97.h 2012-03-20 17:11:23.791160002 +0800
|
||||
+++ rtems/c/src/lib/libbsp/lm32/shared/milkymist_ac97/milkymist_ac97.h 2012-03-20 17:12:23.731160001 +0800
|
||||
@@ -21,6 +21,7 @@
|
||||
/* Ioctls. 0x41 is 'A' */
|
||||
#define SOUND_MIXER_MIC 0x0
|
||||
#define SOUND_MIXER_LINE 0x1
|
||||
+#define SOUND_MIXER_MIC_BOOST 0x2
|
||||
#define SOUND_MIXER_READ(x) (0x4100+x)
|
||||
#define SOUND_MIXER_WRITE(x) (0x4110+x)
|
||||
@@ -341,21 +344,23 @@
|
||||
unsigned int chan, int mono)
|
||||
{
|
||||
unsigned int *val = (unsigned int *)buf;
|
||||
+ int mic_boost;
|
||||
int left, right;
|
||||
int codec;
|
||||
rtems_status_code sc;
|
||||
|
||||
left = *val & 0xff;
|
||||
left = (left*32)/100 - 1;
|
||||
- if(left < 0)
|
||||
+ if (left < 0)
|
||||
left = 0;
|
||||
|
||||
- if (mono)
|
||||
+ if (mono) {
|
||||
+ mic_boost = *val >> 8;
|
||||
right = 31;
|
||||
- else {
|
||||
+ } else {
|
||||
right = (*val >> 8) & 0xff;
|
||||
right = (right*32)/100 - 1;
|
||||
- if(right < 0)
|
||||
+ if (right < 0)
|
||||
right = 0;
|
||||
}
|
||||
|
||||
@@ -365,6 +370,13 @@
|
||||
else
|
||||
codec = (31-left) | ((31-right) << 8);
|
||||
|
||||
+ if (mono) {
|
||||
+ if (mic_boost)
|
||||
+ codec |= (1 << 6);
|
||||
+ else
|
||||
+ codec &= ~(1 << 6);
|
||||
+ }
|
||||
+
|
||||
if (!write_cr(chan, codec))
|
||||
sc = RTEMS_UNSATISFIED;
|
||||
else
|
||||
|
@ -11,7 +11,7 @@ The parameters are as follows:
|
||||
Label Description Type Value
|
||||
------- --------------------------------------- ------- -------
|
||||
B Baseline between J21 and Jxx typ 45 mm
|
||||
CB Clearance, back max 25 mm
|
||||
CB Clearance, back max 22 mm
|
||||
CF Clearance, front max 10 mm
|
||||
CL Clearance, left (seen from front) max 5 mm
|
||||
CR Clearance, right (seen from front) max 15 mm
|
||||
|
@ -38,7 +38,7 @@ unit mm
|
||||
|
||||
table
|
||||
{ B, CB, CF, CL, CR }
|
||||
{ 45mm, 25mm, 10mm, 5mm, 13mm }
|
||||
{ 45mm, 22mm, 10mm, 5mm, 13mm }
|
||||
|
||||
table
|
||||
{ HL, HW }
|
||||
|
Loading…
Reference in New Issue
Block a user