1*b42e852eSBaptiste Daroussin.\" Copyright (c) 2026 Baptiste Daroussin <bapt@FreeBSD.org> 2*b42e852eSBaptiste Daroussin.\" 3*b42e852eSBaptiste Daroussin.\" SPDX-License-Identifier: BSD-2-Clause 4*b42e852eSBaptiste Daroussin.\" 5*b42e852eSBaptiste Daroussin.Dd March 17, 2026 6*b42e852eSBaptiste Daroussin.Dt PKG-SERVE 8 7*b42e852eSBaptiste Daroussin.Os 8*b42e852eSBaptiste Daroussin.Sh NAME 9*b42e852eSBaptiste Daroussin.Nm pkg-serve 10*b42e852eSBaptiste Daroussin.Nd serve pkg repositories over TCP via inetd 11*b42e852eSBaptiste Daroussin.Sh SYNOPSIS 12*b42e852eSBaptiste Daroussin.Nm 13*b42e852eSBaptiste Daroussin.Ar basedir 14*b42e852eSBaptiste Daroussin.Sh DESCRIPTION 15*b42e852eSBaptiste DaroussinThe 16*b42e852eSBaptiste Daroussin.Nm 17*b42e852eSBaptiste Daroussinutility serves 18*b42e852eSBaptiste Daroussin.Xr pkg 8 19*b42e852eSBaptiste Daroussinrepositories using the pkg TCP protocol. 20*b42e852eSBaptiste DaroussinIt is designed to be invoked by 21*b42e852eSBaptiste Daroussin.Xr inetd 8 22*b42e852eSBaptiste Daroussinand communicates via standard input and output. 23*b42e852eSBaptiste Daroussin.Pp 24*b42e852eSBaptiste DaroussinThe 25*b42e852eSBaptiste Daroussin.Ar basedir 26*b42e852eSBaptiste Daroussinargument specifies the root directory containing the package repositories. 27*b42e852eSBaptiste DaroussinAll file requests are resolved relative to this directory. 28*b42e852eSBaptiste Daroussin.Pp 29*b42e852eSBaptiste DaroussinOn startup, 30*b42e852eSBaptiste Daroussin.Nm 31*b42e852eSBaptiste Daroussinenters a Capsicum sandbox, restricting filesystem access to 32*b42e852eSBaptiste Daroussin.Ar basedir . 33*b42e852eSBaptiste Daroussin.Sh PROTOCOL 34*b42e852eSBaptiste DaroussinThe protocol is line-oriented. 35*b42e852eSBaptiste DaroussinUpon connection, the server sends a greeting: 36*b42e852eSBaptiste Daroussin.Bd -literal -offset indent 37*b42e852eSBaptiste Daroussinok: pkg-serve <version> 38*b42e852eSBaptiste Daroussin.Ed 39*b42e852eSBaptiste Daroussin.Pp 40*b42e852eSBaptiste DaroussinThe client may then issue commands: 41*b42e852eSBaptiste Daroussin.Bl -tag -width "get file age" 42*b42e852eSBaptiste Daroussin.It Ic get Ar file age 43*b42e852eSBaptiste DaroussinRequest a file. 44*b42e852eSBaptiste DaroussinIf the file's modification time is newer than 45*b42e852eSBaptiste Daroussin.Ar age 46*b42e852eSBaptiste Daroussin(a Unix timestamp), the server responds with: 47*b42e852eSBaptiste Daroussin.Bd -literal -offset indent 48*b42e852eSBaptiste Daroussinok: <size> 49*b42e852eSBaptiste Daroussin.Ed 50*b42e852eSBaptiste Daroussin.Pp 51*b42e852eSBaptiste Daroussinfollowed by 52*b42e852eSBaptiste Daroussin.Ar size 53*b42e852eSBaptiste Daroussinbytes of file data. 54*b42e852eSBaptiste DaroussinIf the file has not been modified, the server responds with: 55*b42e852eSBaptiste Daroussin.Bd -literal -offset indent 56*b42e852eSBaptiste Daroussinok: 0 57*b42e852eSBaptiste Daroussin.Ed 58*b42e852eSBaptiste Daroussin.Pp 59*b42e852eSBaptiste DaroussinOn error, the server responds with: 60*b42e852eSBaptiste Daroussin.Bd -literal -offset indent 61*b42e852eSBaptiste Daroussinko: <error message> 62*b42e852eSBaptiste Daroussin.Ed 63*b42e852eSBaptiste Daroussin.It Ic quit 64*b42e852eSBaptiste DaroussinClose the connection. 65*b42e852eSBaptiste Daroussin.El 66*b42e852eSBaptiste Daroussin.Sh INETD CONFIGURATION 67*b42e852eSBaptiste DaroussinAdd the following line to 68*b42e852eSBaptiste Daroussin.Xr inetd.conf 5 : 69*b42e852eSBaptiste Daroussin.Bd -literal -offset indent 70*b42e852eSBaptiste Daroussinpkg stream tcp nowait nobody /usr/libexec/pkg-serve pkg-serve /usr/local/poudriere/data/packages 71*b42e852eSBaptiste Daroussin.Ed 72*b42e852eSBaptiste Daroussin.Pp 73*b42e852eSBaptiste DaroussinAnd define the service in 74*b42e852eSBaptiste Daroussin.Xr services 5 : 75*b42e852eSBaptiste Daroussin.Bd -literal -offset indent 76*b42e852eSBaptiste Daroussinpkg 62000/tcp 77*b42e852eSBaptiste Daroussin.Ed 78*b42e852eSBaptiste Daroussin.Sh REPOSITORY CONFIGURATION 79*b42e852eSBaptiste DaroussinOn the client side, configure a repository in 80*b42e852eSBaptiste Daroussin.Pa /usr/local/etc/pkg/repos/myrepo.conf 81*b42e852eSBaptiste Daroussinto use the 82*b42e852eSBaptiste Daroussin.Ic tcp:// 83*b42e852eSBaptiste Daroussinscheme: 84*b42e852eSBaptiste Daroussin.Bd -literal -offset indent 85*b42e852eSBaptiste Daroussinmyrepo: { 86*b42e852eSBaptiste Daroussin url: "tcp://pkgserver.example.com:62000/myrepo", 87*b42e852eSBaptiste Daroussin} 88*b42e852eSBaptiste Daroussin.Ed 89*b42e852eSBaptiste Daroussin.Pp 90*b42e852eSBaptiste DaroussinThe path component of the URL is resolved relative to the 91*b42e852eSBaptiste Daroussin.Ar basedir 92*b42e852eSBaptiste Daroussingiven to 93*b42e852eSBaptiste Daroussin.Nm . 94*b42e852eSBaptiste DaroussinFor example, if 95*b42e852eSBaptiste Daroussin.Nm 96*b42e852eSBaptiste Daroussinis started with 97*b42e852eSBaptiste Daroussin.Pa /usr/local/poudriere/data/packages 98*b42e852eSBaptiste Daroussinas 99*b42e852eSBaptiste Daroussin.Ar basedir , 100*b42e852eSBaptiste Daroussinthe above configuration will serve files from 101*b42e852eSBaptiste Daroussin.Pa /usr/local/poudriere/data/packages/myrepo/ . 102*b42e852eSBaptiste Daroussin.Sh SEE ALSO 103*b42e852eSBaptiste Daroussin.Xr inetd 8 , 104*b42e852eSBaptiste Daroussin.Xr inetd.conf 5 , 105*b42e852eSBaptiste Daroussin.Xr pkg 8 106*b42e852eSBaptiste Daroussin.Sh AUTHORS 107*b42e852eSBaptiste Daroussin.An Baptiste Daroussin Aq Mt bapt@FreeBSD.org 108