Compare commits

...

16 Commits

Author SHA1 Message Date
Roy Marples
7c5047acfc Release OpenRC-0.5.2 2009-10-17 00:32:40 +01:00
Roy Marples
f2f7d0ae6d Add README.net to describe the networking goals for OpenRC. 2009-10-17 00:18:39 +01:00
Roy Marples
d27655c908 Add domainname to the network script 2009-10-16 12:04:20 +01:00
Roy Marples
9f4a7afd83 Add staticroute to the boot runlevel 2009-10-16 09:25:08 +01:00
Roy Marples
ac6808a73e Regenerate version.h if necessary 2009-10-16 08:13:34 +01:00
Roy Marples
baeb59cd2e Add a new staticroute init script so that .... static routes can be configured!
Fixes Gentoo #288421.
2009-10-16 08:08:22 +01:00
Roy Marples
a4b03ead79 Add lustre 2009-10-15 23:48:40 +01:00
William Hubbs
c96a015742 fix wait time for gentoo bug 288495
The wait time was in seconds.  This patch converts it to milliseconds.
2009-10-15 20:25:01 +01:00
Roy Marples
fdca530d4f Address iproute2 mtu. 2009-10-15 20:20:36 +01:00
Roy Marples
da08e3822f Ensure ip brings interface up when adding addresses.
Fixes Gentoo #288889
2009-10-15 20:17:51 +01:00
Roy Marples
ac7af85813 Provide clock 2009-10-13 21:06:35 +01:00
Roy Marples
a8f6a9b654 Add new utility and init script swclock that sets the system time based on
the mtime of a file. It saves the shutdown time to this file also.
This is handy for systems without a working RTC chip.
Based on an idea by Michael A. Smith <michael@smith-li.com>.
Fixes Gentoo #272073.
2009-10-13 08:03:45 +01:00
Semen Maryasin
aaa0498bf8 EeePC 901 has /proc/acpi/ac_adapter/AC0, so check all AC entries. 2009-10-12 08:21:50 +01:00
Roy Marples
0ffe5caf18 Add more net fs's, Gentoo #284327. 2009-10-11 08:18:35 +01:00
Roy Marples
5e8e38b9cf Improve comments, Gentoo #282243. 2009-10-11 08:15:10 +01:00
Roy Marples
454bd460c4 Multihomed rules show not be applied to the interface, Gentoo #273303. 2009-10-11 08:03:30 +01:00
29 changed files with 336 additions and 29 deletions

View File

@@ -1,3 +1,3 @@
NAME= openrc NAME= openrc
VERSION= 0.5.1 VERSION= 0.5.2
PKG= ${NAME}-${VERSION} PKG= ${NAME}-${VERSION}

36
README.net Normal file
View File

@@ -0,0 +1,36 @@
OpenRC Network Ideals
---------------------
The new style networking for OpenRC is very simplistic - provide a basic means
of configuring static interface address and routes whilst allowing the
possibility to run any command at any point.
In a nutshell, init.d/network is a wrapper around ifconfig(8) and
init.d/staticroute is wrapper around route(8).
In the Perfect World (TM) ifconfig should be able to configure everything
about the interface easily * . The BSD family almost get this right and Linux
epically fails.
* Only static confguration, including link setup.
For dynmaic, static, IPv4LL, arping and per ssid IPv4 setup dhcpcd-5.x
provides your needs.
It fails because there are many tools to do the same job and often have
vastly different syntax where they could be similar. In other words, there
is no coherence.
OpenRC-0.4.x and older (inc Gentoo baselayout-1) had a collection of scripts
for each tool and allowed a script per interface. Over the years, this design
has proven very hard to maintain as each user has their own idea of how
things should work. Also, there were (and still are) race conditions.
So where do we go from here?
Well, it's possible to use the new network scripts using the tools
currently available. It's just harder as you have to know them and their
documentation can be lacking at times.
The correct end goal is a BSD style ifconfig tool.
I've started work on it, but the project has stalled somewhat.
It's display only right now and the source is not yet publically available.
If you have the skills and share the vision then contact me privately and
we'll take it from there.

1
conf.d/.gitignore vendored
View File

@@ -1 +1,2 @@
network network
staticroute

View File

@@ -1,14 +1,19 @@
DIR= ${CONFDIR} DIR= ${CONFDIR}
CONF= bootmisc fsck hostname local localmount network urandom CONF= bootmisc fsck hostname local localmount network staticroute urandom
TARGETS+= network TARGETS+= network staticroute
CLEANFILES+= network CLEANFILES+= network staticroute
MK= ../mk MK= ../mk
include ${MK}/os.mk include ${MK}/os.mk
include Makefile.${OS} include Makefile.${OS}
include ${MK}/scripts.mk include ${MK}/scripts.mk
SOS?= BSD
network: network.in network.${OS} network: network.in network.${OS}
cp network.in network cp $@.in $@
[ -e network.${OS} ] && cat network.${OS} >> network || true [ -e $@.${OS} ] && cat $@.${OS} >> $@ || true
staticroute: staticroute.${SOS}
cp $@.${SOS} $@

View File

@@ -1 +1,2 @@
CONF+= consolefont dmesg hwclock keymaps modules CONF+= consolefont dmesg hwclock keymaps modules
SOS= Linux

View File

@@ -1,11 +1,11 @@
# Set CLOCK to "UTC" if your system clock is set to UTC (also known as # Set CLOCK to "UTC" if your Hardware Clock is set to UTC (also known as
# Greenwich Mean Time). If your clock is set to the local time, then # Greenwich Mean Time). If that clock is set to the local time, then
# set CLOCK to "local". Note that if you dual boot with Windows, then # set CLOCK to "local". Note that if you dual boot with Windows, then
# you should set it to "local". # you should set it to "local".
clock="UTC" clock="UTC"
# If you want to set the Hardware Clock to the current System Time # If you want to set the Hardware Clock to the current System Time
# during shutdown, then say "YES" here. # (software clock) during shutdown, then say "YES" here.
# You normally don't need to do this if you run a ntp daemon. # You normally don't need to do this if you run a ntp daemon.
clock_systohc="NO" clock_systohc="NO"

View File

@@ -3,6 +3,9 @@
# On the other hand, ip (iproute2) is quite powerful and is also supported # On the other hand, ip (iproute2) is quite powerful and is also supported
#ip_eth0="192.168.0.10/24; 192.168.10.10/24" #ip_eth0="192.168.0.10/24; 192.168.10.10/24"
# ip doesn't handle MTU like ifconfig, but we can do it like so
#ifup_eth0="ip link set \$int mtu 1500"
# Create a bonded interface # Create a bonded interface
#interfaces="bond0" #interfaces="bond0"
#ifup_bond0="modprobe bonding; ifconfig \$int up; ifenslave \$int bge0" #ifup_bond0="modprobe bonding; ifconfig \$int up; ifenslave \$int bge0"

View File

@@ -26,3 +26,5 @@
# If you require DHCP, you should install dhcpcd and it to the boot or # If you require DHCP, you should install dhcpcd and it to the boot or
# default runlevel. # default runlevel.
# NIS users can set the domain name here
#domainname="foobar"

2
conf.d/staticroute.BSD Normal file
View File

@@ -0,0 +1,2 @@
# Example static route. See route(8) for syntax.
staticroute="net 192.168.0.0 -netmask 255.255.0.0 10.73.1.1"

2
conf.d/staticroute.Linux Normal file
View File

@@ -0,0 +1,2 @@
# Example static route. See route(8) for syntax.
staticroute="net 192.168.0.0 netmask 255.255.0.0 gw 10.73.1.1"

View File

@@ -1003,7 +1003,7 @@
# else # else
# for x; do # for x; do
# ebegin "${x}" # ebegin "${x}"
# ip rule add ${x} dev "${IFACE}" # ip rule add ${x}
# eend $? # eend $?
# done # done
# fi # fi

View File

@@ -76,7 +76,7 @@
#unicode="NO" #unicode="NO"
# Network fstypes. Below is the default. # Network fstypes. Below is the default.
net_fs_list="afs cifs coda davfs fuse gfs ncpfs nfs nfs4 ocfs2 shfs smbfs" net_fs_list="afs cifs coda davfs fuse fuse.sshfs gfs glusterfs lustre ncpfs nfs nfs4 ocfs2 shfs smbfs"
############################################################################## ##############################################################################
# SERVICE CONFIGURATION VARIABLES # SERVICE CONFIGURATION VARIABLES

11
init.d.misc/.gitignore vendored Normal file
View File

@@ -0,0 +1,11 @@
avahi-dnsconfd
avahid
dhcpcd
dbus
hald
named
ntpd
openvpn
polkitd
sshd
wpa_supplicant

2
init.d/.gitignore vendored
View File

@@ -24,6 +24,7 @@ mount-ro
mtab mtab
numlock numlock
procfs procfs
staticroute
sysfs sysfs
devdb devdb
hostid hostid
@@ -34,6 +35,7 @@ rc-enabled
rpcbind rpcbind
savecore savecore
swap-blk swap-blk
swclock
syslogd syslogd
termencoding termencoding
ttys ttys

View File

@@ -1,6 +1,7 @@
DIR= ${INITDIR} DIR= ${INITDIR}
SRCS= bootmisc.in fsck.in hostname.in local.in localmount.in netmount.in \ SRCS= bootmisc.in fsck.in hostname.in local.in localmount.in netmount.in \
network.in root.in savecache.in swap.in sysctl.in urandom.in network.in root.in savecache.in staticroute.in swap.in swclock.in \
sysctl.in urandom.in
BIN= ${OBJS} BIN= ${OBJS}
# Build our old net foo or not # Build our old net foo or not

View File

@@ -32,8 +32,8 @@ _forcefsck()
_on_ac_power() _on_ac_power()
{ {
if [ -f /proc/acpi/ac_adapter/AC/state ]; then if [ -f /proc/acpi/ac_adapter/AC*/state ]; then
cat /proc/acpi/ac_adapter/AC/state | while read line; do cat /proc/acpi/ac_adapter/AC*/state | while read line; do
case "$line" in case "$line" in
"state:"*"off-line") return 128;; "state:"*"off-line") return 128;;
esac esac

View File

@@ -103,13 +103,21 @@ dumpargs()
esac esac
} }
intup=false
runip() runip()
{ {
local int="$1" err= local int="$1" err=
shift shift
err=$(LC_ALL=C ip address add "$@" dev "$int" 2>&1) err=$(LC_ALL=C ip address add "$@" dev "$int" 2>&1)
[ -z "$err" ] && return 0 if [ -z "$err" ]; then
# ip does not bring up the interface when adding addresses
if ! intup; then
ip set link up dev "$int"
intup=true
fi
return 0
fi
if [ "$err" = "RTNETLINK answers: File exists" ]; then if [ "$err" = "RTNETLINK answers: File exists" ]; then
ip address del "$@" dev "$int" 2>/dev/null ip address del "$@" dev "$int" 2>/dev/null
fi fi
@@ -165,6 +173,16 @@ runargs()
start() start()
{ {
local cr=0 r= int= intv= cmd= args= upcmd= local cr=0 r= int= intv= cmd= args= upcmd=
if [ -z "$domainname" && -s /etc/defaultdomain ]; then
domainname=$(cat /etc/defaultdomain)
fi
if [ -n "$domainname" ]; then
ebegin "Setting NIS domainname: $domainname"
domainname "$domainname"
eend $?
fi
einfo "Starting network" einfo "Starting network"
routeflush routeflush
if [ "$RC_UNAME" = "Linux" ]; then if [ "$RC_UNAME" = "Linux" ]; then
@@ -194,7 +212,7 @@ start()
-f /etc/ifup."$int" -o -f "$cf" ] || continue -f /etc/ifup."$int" -o -f "$cf" ] || continue
veinfo "$int" veinfo "$int"
case "$func" in case "$func" in
ip) func=runip;; ip) func=runip; intup=false;;
esac esac
eindent eindent
runargs /etc/ifup."$int" "$upcmd" runargs /etc/ifup."$int" "$upcmd"

View File

@@ -22,7 +22,7 @@ start()
fi fi
fi fi
local save= local save=
for x in deptree depconfig softlevel nettree rc.log; do for x in deptree depconfig shutdowntime softlevel nettree rc.log; do
[ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x" [ -e "$RC_SVCDIR/$x" ] && save="$save $RC_SVCDIR/$x"
done done
if [ -n "$save" ]; then if [ -n "$save" ]; then

73
init.d/staticroute.in Normal file
View File

@@ -0,0 +1,73 @@
#!@PREFIX@/sbin/runscript
# Copyright (c) 2009 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
# This script was inspired by the equivalent rc.d staticroute from NetBSD.
description="Configures static routes."
__nl="
"
depend()
{
provide net
use network
keyword -jail -prefix -vserver
}
dump_args()
{
if [ -s /etc/route.conf ]; then
cat /etc/route.conf
else
case "$staticroute" in
*"$__nl"*)
echo "$staticroute"
;;
*)
(
set -o noglob
IFS=';'; set -- $staticroute
IFS="$__nl"; echo "$*"
)
;;
esac
fi
}
do_routes()
{
local xtra=
[ "$RC_UNAME" != Linux ] && xtra=-q
ebegin "$1 static routes"
dump_args | while read args; do
[ -z "$args" ] && continue
case "$args" in
"#"*)
;;
"+"*)
[ $2 = "add" ] && eval ${args#*+}
;;
"-"*)
[ $2 = "del" -o $2 = "delete" ] && eval ${args#*-}
;;
*)
route $xtra $2 -$args
;;
esac
done
eend 0
}
start()
{
do_routes "Adding" "add"
}
stop()
{
local cmd="delete"
[ "$RC_UNAME" = Linux ] && cmd="del"
do_routes "Deleting" "$cmd"
}

28
init.d/swclock.in Normal file
View File

@@ -0,0 +1,28 @@
#!@PREFIX@/sbin/runscript
# Copyright (c) 2009 Roy Marples <roy@marples.name>
# All rights reserved. Released under the 2-clause BSD license.
description="Sets the local clock to the mtime of a given file."
depend()
{
before *
provide clock
keyword -openvz -prefix -uml -vserver -xenu
}
# swclock is an OpenRC built in
start()
{
ebegin "Setting the local clock based on last shutdown time"
swclock
eend $?
}
stop()
{
ebegin "Saving the shutdown time"
swclock --save
eend $?
}

View File

@@ -22,7 +22,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE. .\" SUCH DAMAGE.
.\" .\"
.Dd September 4, 2009 .Dd October 14, 2009
.Dt START-STOP-DAEMON 8 SMM .Dt START-STOP-DAEMON 8 SMM
.Os OpenRC .Os OpenRC
.Sh NAME .Sh NAME
@@ -144,9 +144,9 @@ Redirect the standard output of the process to logfile when started with
Must be an absolute pathname, but relative to the path optionally given with Must be an absolute pathname, but relative to the path optionally given with
.Fl r , -chroot . .Fl r , -chroot .
The logfile can also be a named pipe. The logfile can also be a named pipe.
.It Fl w , -wait Ar seconds .It Fl w , -wait Ar milliseconds
Wait Wait
.Ar seconds .Ar milliseconds
after starting and check that daemon is still running. after starting and check that daemon is still running.
Useful for daemons that check configuration after forking or stopping race Useful for daemons that check configuration after forking or stopping race
conditions where the pidfile is written out after forking. conditions where the pidfile is written out after forking.

View File

@@ -1,5 +1,5 @@
BOOT= bootmisc fsck hostname localmount network \ BOOT= bootmisc fsck hostname localmount network \
root swap sysctl urandom root staticroute swap sysctl urandom
DEFAULT= local netmount DEFAULT= local netmount
SHUTDOWN= savecache SHUTDOWN= savecache

View File

@@ -35,6 +35,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <errno.h> #include <errno.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#define RC_LEVEL_BOOT "boot" #define RC_LEVEL_BOOT "boot"

2
src/rc/.gitignore vendored
View File

@@ -38,6 +38,7 @@ service_crashed
checkpath checkpath
fstabinfo fstabinfo
mountinfo mountinfo
swclock
rc-depend rc-depend
service_get_value service_get_value
service_set_value service_set_value
@@ -59,6 +60,7 @@ checkpath.o
fstabinfo.o fstabinfo.o
mountinfo.o mountinfo.o
start-stop-daemon.o start-stop-daemon.o
swclock.o
rc-applets.o rc-applets.o
rc-depend.o rc-depend.o
rc-logger.o rc-logger.o

View File

@@ -2,7 +2,7 @@ PROG= rc
SRCS= checkpath.c fstabinfo.c mountinfo.c start-stop-daemon.c \ SRCS= checkpath.c fstabinfo.c mountinfo.c start-stop-daemon.c \
rc-applets.c rc-depend.c rc-logger.c \ rc-applets.c rc-depend.c rc-logger.c \
rc-misc.c rc-plugin.c rc-service.c rc-status.c rc-update.c \ rc-misc.c rc-plugin.c rc-service.c rc-status.c rc-update.c \
runscript.c rc.c runscript.c rc.c swclock.c
CLEANFILES= version.h CLEANFILES= version.h
@@ -26,7 +26,7 @@ RC_SBINLINKS= mark_service_starting mark_service_started \
mark_service_stopping mark_service_stopped \ mark_service_stopping mark_service_stopped \
mark_service_inactive mark_service_wasinactive \ mark_service_inactive mark_service_wasinactive \
mark_service_hotplugged mark_service_failed \ mark_service_hotplugged mark_service_failed \
rc-abort rc-abort swclock
ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS} ALL_LINKS= ${BINLINKS} ${SBINLINKS} ${RC_BINLINKS} ${RC_SBINLINKS}
CLEANFILES+= ${ALL_LINKS} CLEANFILES+= ${ALL_LINKS}
@@ -46,12 +46,17 @@ LDADD+= ${LIBDL} ${LIBKVM}
include ${MK}/${MKPAM}.mk include ${MK}/${MKPAM}.mk
${SRCS}: version.h ${SRCS}: version.h
version.h:
echo "#define VERSION \"${VERSION}${GITVER}\"" >version.h .PHONY: version.h.tmp
version.h.tmp:
echo "#define VERSION \"${VERSION}${GITVER}\"" >$@
if test -n "${BRANDING}"; then \ if test -n "${BRANDING}"; then \
echo "#define BRANDING \"${BRANDING}\"" >> version.h; \ echo "#define BRANDING \"${BRANDING}\"" >> $@; \
fi fi
version.h: version.h.tmp
cmp -s $@.tmp $@ && rm $@.tmp || mv $@.tmp $@
install: all install: all
${INSTALL} -d ${DESTDIR}${SBINDIR} ${INSTALL} -d ${DESTDIR}${SBINDIR}
${INSTALL} -m ${BINMODE} ${PROG} ${DESTDIR}${SBINDIR} ${INSTALL} -m ${BINMODE} ${PROG} ${DESTDIR}${SBINDIR}

View File

@@ -35,6 +35,7 @@ int rc_status(int, char **);
int rc_update(int, char **); int rc_update(int, char **);
int runscript(int, char **); int runscript(int, char **);
int start_stop_daemon(int, char **); int start_stop_daemon(int, char **);
int swclock(int, char **);
void run_applets(int, char **); void run_applets(int, char **);

View File

@@ -449,6 +449,8 @@ run_applets(int argc, char **argv)
exit(start_stop_daemon(argc, argv)); exit(start_stop_daemon(argc, argv));
else if (strcmp (applet, "checkpath") == 0) else if (strcmp (applet, "checkpath") == 0)
exit(checkpath(argc, argv)); exit(checkpath(argc, argv));
else if (strcmp(applet, "swclock") == 0)
exit(swclock(argc, argv));
/* These could also be applications in their own right */ /* These could also be applications in their own right */
if (strcmp(applet, "shell_var") == 0) if (strcmp(applet, "shell_var") == 0)

View File

@@ -37,6 +37,7 @@
#define POLL_INTERVAL 20000000 #define POLL_INTERVAL 20000000
#define WAIT_PIDFILE 500000000 #define WAIT_PIDFILE 500000000
#define ONE_SECOND 1000000000 #define ONE_SECOND 1000000000
#define ONE_MS 1000000
#include <sys/types.h> #include <sys/types.h>
#include <sys/ioctl.h> #include <sys/ioctl.h>
@@ -638,7 +639,7 @@ static const char * const longopts_help[] = {
"Test actions, don't do them", "Test actions, don't do them",
"Change the process user", "Change the process user",
"Chroot to this directory", "Chroot to this directory",
"Seconds to wait for daemon start", "Milliseconds to wait for daemon start",
"Binary to start/stop", "Binary to start/stop",
"Redirect stdout to file", "Redirect stdout to file",
"Redirect stderr to file", "Redirect stderr to file",
@@ -1311,8 +1312,8 @@ start_stop_daemon(int argc, char **argv)
struct timespec ts; struct timespec ts;
bool alive = false; bool alive = false;
ts.tv_sec = start_wait; ts.tv_sec = start_wait / 1000;
ts.tv_nsec = 0; ts.tv_nsec = (start_wait % 1000) * ONE_MS;
if (nanosleep(&ts, NULL) == -1) { if (nanosleep(&ts, NULL) == -1) {
if (errno == EINTR) if (errno == EINTR)
eerror("%s: caught an interrupt", applet); eerror("%s: caught an interrupt", applet);

110
src/rc/swclock.c Normal file
View File

@@ -0,0 +1,110 @@
/*
swclock.c
Sets the system time from the mtime of the given file.
This is useful for systems who do not have a working RTC and rely on ntp.
OpenRC relies on the correct system time for a lot of operations so this is needed
quite early.
*/
/*
* Copyright (c) 2009 Roy Marples <roy@marples.name>
* All rights reserved
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
#include <sys/time.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <unistd.h>
#include <utime.h>
#include "builtins.h"
#include "einfo.h"
#include "rc-misc.h"
#define RC_SHUTDOWNTIME RC_SVCDIR "/shutdowntime"
extern const char *applet;
#include "_usage.h"
#define extraopts "file"
#define getoptstring "s" getoptstring_COMMON
static const struct option longopts[] = {
{ "save", 0, NULL, 's' },
longopts_COMMON
};
static const char * const longopts_help[] = {
"saves the time",
longopts_help_COMMON
};
#include "_usage.c"
int
swclock(int argc, char **argv)
{
int opt, sflag = 0;
const char *file = RC_SHUTDOWNTIME;
struct stat sb;
struct timeval tv;
while ((opt = getopt_long(argc, argv, getoptstring,
longopts, (int *) 0)) != -1)
{
switch (opt) {
case 's':
sflag = 1;
break;
case_RC_COMMON_GETOPT;
}
}
if (optind < argc)
file = argv[optind++];
if (sflag) {
if (stat(file, &sb) == -1) {
opt = open(file, O_WRONLY | O_CREAT, 0644);
if (opt == -1)
eerrorx("swclock: open: %s", strerror(errno));
close(opt);
} else
if (utime(file, NULL) == -1)
eerrorx("swclock: utime: %s", strerror(errno));
return 0;
}
if (stat(file, &sb) == -1)
eerrorx("swclock: `%s': %s", file, strerror(errno));
tv.tv_sec = sb.st_mtime;
tv.tv_usec = 0;
if (settimeofday(&tv, NULL) == -1)
eerrorx("swclock: settimeofday: %s", strerror(errno));
return 0;
}