From be3e64e5ea637c5d98fb9f450a36a9d2f40450e9 Mon Sep 17 00:00:00 2001 From: ridiculousfish Date: Thu, 5 Jun 2014 11:49:05 -0700 Subject: [PATCH] Remove fishd.cpp source, docs, and target from Makefile and Xcode project --- Makefile.in | 20 +- doc_src/fishd.txt | 33 - fish.xcodeproj/project.pbxproj | 123 --- .../xcshareddata/xcschemes/fishd.xcscheme | 86 -- fishd.cpp | 971 ------------------ 5 files changed, 1 insertion(+), 1232 deletions(-) delete mode 100644 doc_src/fishd.txt delete mode 100644 fish.xcodeproj/xcshareddata/xcschemes/fishd.xcscheme delete mode 100644 fishd.cpp diff --git a/Makefile.in b/Makefile.in index f2761e963..3d68a01db 100644 --- a/Makefile.in +++ b/Makefile.in @@ -111,14 +111,6 @@ BUILTIN_FILES := builtin_set.cpp builtin_commandline.cpp \ FISH_TESTS_OBJS := $(FISH_OBJS) fish_tests.o -# -# All objects that the system needs to build fishd -# - -FISHD_OBJS := fishd.o env_universal_common.o wutil.o print_help.o \ - common.o utf8.o fish_version.o - - # # All objects needed to build mimedb # @@ -181,7 +173,7 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish) # Programs to install # -PROGRAMS := fish mimedb fishd fish_indent +PROGRAMS := fish mimedb fish_indent # # Manual pages to install @@ -688,14 +680,6 @@ fish: $(FISH_OBJS) fish.o $(CXX) $(CXXFLAGS) $(LDFLAGS_FISH) $(FISH_OBJS) fish.o $(LIBS) -o $@ -# -# Build the fishd program. -# - -fishd: $(FISHD_OBJS) - $(CXX) $(CXXFLAGS) $(LDFLAGS) $(FISHD_OBJS) $(LIBS) -o $@ - - # # Build the fish_tests program. # @@ -842,8 +826,6 @@ fish.o: highlight.h env.h color.h builtin.h function.h event.h wutil.h fish.o: sanity.h proc.h parse_tree.h tokenizer.h parse_constants.h parser.h fish.o: expand.h intern.h exec.h output.h screen.h history.h path.h input.h fish.o: input_common.h fish_version.h -fishd.o: config.h signal.h fallback.h util.h common.h wutil.h -fishd.o: env_universal_common.h env.h path.h print_help.h fish_version.h fish_indent.o: config.h fallback.h signal.h util.h common.h wutil.h fish_indent.o: tokenizer.h print_help.h parser_keywords.h fish_version.h fish_tests.o: config.h signal.h fallback.h util.h common.h proc.h io.h diff --git a/doc_src/fishd.txt b/doc_src/fishd.txt deleted file mode 100644 index 0eb3088a4..000000000 --- a/doc_src/fishd.txt +++ /dev/null @@ -1,33 +0,0 @@ -\section fishd fishd - universal variable daemon - -\subsection fishd-synopsis Synopsis - fishd [(-h|--help|-v|--version)] - -\subsection fishd-description Description - -The \c fishd daemon is used to load, save and distribute universal -variable information. \c fish automatically connects to \c fishd via a socket -on startup. - -\c fishd is started and stopped automatically. - -The following options are available if starting \c fishd manually: - -- -h or --help displays this help message and then exits -- -v or --version displays the current fish version and then exits - -\subsection fishd-files Files - -- \c ~/.config/fish/fishd.MACHINE_ID - permanent storage location for universal - variable data. \c MACHINE_ID is generally based on the machine's MAC address. - - The data is stored as a set of \c set and \c set_export commands such as - would be parsed by fishd. The file must always be stored in YAML format. - If an instance of fishd is running (which is generally the case), manual - modifications to \c ~/.fishd.MACHINE_ID will be lost. Do NOT edit this file manually! - -- \c /tmp/fishd.socket.USERNAME - the socket which fishd uses to communicate -with all clients. - -- /tmp/fishd.log.USERNAME - the fishd log file - diff --git a/fish.xcodeproj/project.pbxproj b/fish.xcodeproj/project.pbxproj index 762d73c21..aecda2bd7 100644 --- a/fish.xcodeproj/project.pbxproj +++ b/fish.xcodeproj/project.pbxproj @@ -17,7 +17,6 @@ ); dependencies = ( D07D265715E33B86009E43F6 /* PBXTargetDependency */, - D07D265915E33B86009E43F6 /* PBXTargetDependency */, D07D265D15E33B86009E43F6 /* PBXTargetDependency */, D0A56500168D257900AF6161 /* PBXTargetDependency */, ); @@ -47,7 +46,6 @@ ); dependencies = ( D0F01A1315AA36280034B3B1 /* PBXTargetDependency */, - D0F01A1515AA362E0034B3B1 /* PBXTargetDependency */, D0F01A1715AA36300034B3B1 /* PBXTargetDependency */, D0A564EF168D09C000AF6161 /* PBXTargetDependency */, ); @@ -59,7 +57,6 @@ /* Begin PBXBuildFile section */ D00F63F119137E9D00FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; }; D00F63F219137E9D00FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; }; - D00F63F31914C5F800FCCDEC /* fish_version.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D00F63F019137E9D00FCCDEC /* fish_version.cpp */; }; D01A2D24169B736200767098 /* man1 in Copy Files */ = {isa = PBXBuildFile; fileRef = D01A2D23169B730A00767098 /* man1 */; }; D01A2D25169B737700767098 /* man1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = D01A2D23169B730A00767098 /* man1 */; }; D031890C15E36E4600D9CC39 /* base in Resources */ = {isa = PBXBuildFile; fileRef = D031890915E36D9800D9CC39 /* base */; }; @@ -120,7 +117,6 @@ D0A56501168D258300AF6161 /* man in Copy Files */ = {isa = PBXBuildFile; fileRef = D0A564F1168D0BAB00AF6161 /* man */; }; D0C52F371765284C00BFAB82 /* parse_tree.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C52F351765284C00BFAB82 /* parse_tree.cpp */; }; D0C9733818DE5449002D7C81 /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C9733718DE5449002D7C81 /* utf8.cpp */; }; - D0C9733918DE5449002D7C81 /* utf8.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0C9733718DE5449002D7C81 /* utf8.cpp */; }; D0CBD587159EF0E10024809C /* launch_fish.scpt in Resources */ = {isa = PBXBuildFile; fileRef = D0CBD586159EF0E10024809C /* launch_fish.scpt */; }; D0D02A67159837AD008E62BD /* complete.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853713B3ACEE0099B651 /* complete.cpp */; }; D0D02A69159837B2008E62BD /* env.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853A13B3ACEE0099B651 /* env.cpp */; }; @@ -158,12 +154,6 @@ D0D02A89159839DF008E62BD /* fish.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854213B3ACEE0099B651 /* fish.cpp */; }; D0D02A8D15983CFA008E62BD /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; }; D0D02A8F15983D8F008E62BD /* parser_keywords.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855313B3ACEE0099B651 /* parser_keywords.cpp */; }; - D0D02AC215985F3F008E62BD /* fishd.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854313B3ACEE0099B651 /* fishd.cpp */; }; - D0D02AC315985F43008E62BD /* env_universal_common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853813B3ACEE0099B651 /* env_universal_common.cpp */; }; - D0D02AC415985F4D008E62BD /* wutil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0856113B3ACEE0099B651 /* wutil.cpp */; }; - D0D02AC515985F5B008E62BD /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; }; - D0D02AC615985F65008E62BD /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853613B3ACEE0099B651 /* common.cpp */; }; - D0D02AC715985F9D008E62BD /* libncurses.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = D0D02A8C15983CFA008E62BD /* libncurses.dylib */; }; D0D02AD615986492008E62BD /* fish_indent.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853F13B3ACEE0099B651 /* fish_indent.cpp */; }; D0D02AD715986498008E62BD /* print_help.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0855613B3ACEE0099B651 /* print_help.cpp */; }; D0D02AD81598649E008E62BD /* common.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853613B3ACEE0099B651 /* common.cpp */; }; @@ -174,7 +164,6 @@ D0D2694915983772005D9B9C /* function.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0854413B3ACEE0099B651 /* function.cpp */; }; D0D2694A15983779005D9B9C /* builtin.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D0A0853513B3ACEE0099B651 /* builtin.cpp */; }; D0F019F115A977140034B3B1 /* fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D2693C159835CA005D9B9C /* fish */; }; - D0F019F215A977270034B3B1 /* fishd in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02ABC15985EF9008E62BD /* fishd */; }; D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0D02AD01598642A008E62BD /* fish_indent */; }; D0F019F815A977AB0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0CBD580159EE48F0024809C /* config.fish */; }; D0F019FD15A977CA0034B3B1 /* config.fish in CopyFiles */ = {isa = PBXBuildFile; fileRef = D0C4FD9415A7D7EE00212EF1 /* config.fish */; }; @@ -198,13 +187,6 @@ remoteGlobalIDString = D0D2693B159835CA005D9B9C; remoteInfo = fish_shell; }; - D07D265A15E33B86009E43F6 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D0A084F213B3AC130099B651 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D02ABB15985EF9008E62BD; - remoteInfo = fishd; - }; D07D265E15E33B86009E43F6 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D0A084F213B3AC130099B651 /* Project object */; @@ -233,13 +215,6 @@ remoteGlobalIDString = D0D2693B159835CA005D9B9C; remoteInfo = fish_shell; }; - D0F01A1415AA362E0034B3B1 /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = D0A084F213B3AC130099B651 /* Project object */; - proxyType = 1; - remoteGlobalIDString = D0D02ABB15985EF9008E62BD; - remoteInfo = fishd; - }; D0F01A1615AA36300034B3B1 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = D0A084F213B3AC130099B651 /* Project object */; @@ -325,7 +300,6 @@ dstSubfolderSpec = 1; files = ( D0F019F115A977140034B3B1 /* fish in CopyFiles */, - D0F019F215A977270034B3B1 /* fishd in CopyFiles */, D0F019F315A977290034B3B1 /* fish_indent in CopyFiles */, ); runOnlyForDeploymentPostprocessing = 0; @@ -486,7 +460,6 @@ D0D02A8C15983CFA008E62BD /* libncurses.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libncurses.dylib; path = usr/lib/libncurses.dylib; sourceTree = SDKROOT; }; D0D02A9A15985A75008E62BD /* fish.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = fish.app; sourceTree = BUILT_PRODUCTS_DIR; }; D0D02AA915985C0C008E62BD /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = osx/Info.plist; sourceTree = ""; }; - D0D02ABC15985EF9008E62BD /* fishd */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fishd; sourceTree = BUILT_PRODUCTS_DIR; }; D0D02AD01598642A008E62BD /* fish_indent */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish_indent; sourceTree = BUILT_PRODUCTS_DIR; }; D0D02AFA159871B2008E62BD /* osx_fish_launcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = osx_fish_launcher.m; path = osx/osx_fish_launcher.m; sourceTree = ""; }; D0D2693C159835CA005D9B9C /* fish */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = fish; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -506,14 +479,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - D0D02AB915985EF9008E62BD /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - D0D02AC715985F9D008E62BD /* libncurses.dylib in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; D0D02ACD1598642A008E62BD /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -746,7 +711,6 @@ children = ( D0D2693C159835CA005D9B9C /* fish */, D0D02A9A15985A75008E62BD /* fish.app */, - D0D02ABC15985EF9008E62BD /* fishd */, D0D02AD01598642A008E62BD /* fish_indent */, D08A328D17B4455100F3A533 /* fish_tests */, ); @@ -816,22 +780,6 @@ productReference = D0D02A9A15985A75008E62BD /* fish.app */; productType = "com.apple.product-type.application"; }; - D0D02ABB15985EF9008E62BD /* fishd */ = { - isa = PBXNativeTarget; - buildConfigurationList = D0D02ABF15985EFA008E62BD /* Build configuration list for PBXNativeTarget "fishd" */; - buildPhases = ( - D0D02AB815985EF9008E62BD /* Sources */, - D0D02AB915985EF9008E62BD /* Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = fishd; - productName = fishd; - productReference = D0D02ABC15985EF9008E62BD /* fishd */; - productType = "com.apple.product-type.tool"; - }; D0D02ACF1598642A008E62BD /* fish_indent */ = { isa = PBXNativeTarget; buildConfigurationList = D0D02AD31598642A008E62BD /* Build configuration list for PBXNativeTarget "fish_indent" */; @@ -888,7 +836,6 @@ D0F019EC15A976F30034B3B1 /* base */, D0D02A9915985A75008E62BD /* fish.app */, D0D2693B159835CA005D9B9C /* fish_shell */, - D0D02ABB15985EF9008E62BD /* fishd */, D0D02ACF1598642A008E62BD /* fish_indent */, D08A328C17B4455100F3A533 /* fish_tests */, D0A564E6168CFDD800AF6161 /* man_pages */, @@ -1115,20 +1062,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - D0D02AB815985EF9008E62BD /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - D00F63F31914C5F800FCCDEC /* fish_version.cpp in Sources */, - D0D02AC215985F3F008E62BD /* fishd.cpp in Sources */, - D0D02AC315985F43008E62BD /* env_universal_common.cpp in Sources */, - D0C9733918DE5449002D7C81 /* utf8.cpp in Sources */, - D0D02AC415985F4D008E62BD /* wutil.cpp in Sources */, - D0D02AC515985F5B008E62BD /* print_help.cpp in Sources */, - D0D02AC615985F65008E62BD /* common.cpp in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; D0D02ACC1598642A008E62BD /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1214,11 +1147,6 @@ target = D0D2693B159835CA005D9B9C /* fish_shell */; targetProxy = D07D265815E33B86009E43F6 /* PBXContainerItemProxy */; }; - D07D265915E33B86009E43F6 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D02ABB15985EF9008E62BD /* fishd */; - targetProxy = D07D265A15E33B86009E43F6 /* PBXContainerItemProxy */; - }; D07D265D15E33B86009E43F6 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D0D02ACF1598642A008E62BD /* fish_indent */; @@ -1239,11 +1167,6 @@ target = D0D2693B159835CA005D9B9C /* fish_shell */; targetProxy = D0F01A1215AA36280034B3B1 /* PBXContainerItemProxy */; }; - D0F01A1515AA362E0034B3B1 /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = D0D02ABB15985EF9008E62BD /* fishd */; - targetProxy = D0F01A1415AA362E0034B3B1 /* PBXContainerItemProxy */; - }; D0F01A1715AA36300034B3B1 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = D0D02ACF1598642A008E62BD /* fish_indent */; @@ -1328,18 +1251,6 @@ }; name = "Release_C++11"; }; - D007FDDF17136EAA00A52BE6 /* Release_C++11 */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = "Release_C++11"; - }; D007FDE017136EAA00A52BE6 /* Release_C++11 */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1596,30 +1507,6 @@ }; name = Release; }; - D0D02AC015985EFA008E62BD /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = NO; - GCC_DYNAMIC_NO_PIC = NO; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Debug; - }; - D0D02AC115985EFA008E62BD /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - COPY_PHASE_STRIP = YES; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - GCC_ENABLE_OBJC_EXCEPTIONS = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES; - PRODUCT_NAME = "$(TARGET_NAME)"; - }; - name = Release; - }; D0D02AD41598642A008E62BD /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { @@ -1755,16 +1642,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - D0D02ABF15985EFA008E62BD /* Build configuration list for PBXNativeTarget "fishd" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - D0D02AC015985EFA008E62BD /* Debug */, - D0D02AC115985EFA008E62BD /* Release */, - D007FDDF17136EAA00A52BE6 /* Release_C++11 */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; D0D02AD31598642A008E62BD /* Build configuration list for PBXNativeTarget "fish_indent" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/fish.xcodeproj/xcshareddata/xcschemes/fishd.xcscheme b/fish.xcodeproj/xcshareddata/xcschemes/fishd.xcscheme deleted file mode 100644 index a2741de25..000000000 --- a/fish.xcodeproj/xcshareddata/xcschemes/fishd.xcscheme +++ /dev/null @@ -1,86 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/fishd.cpp b/fishd.cpp deleted file mode 100644 index 4bb80b50c..000000000 --- a/fishd.cpp +++ /dev/null @@ -1,971 +0,0 @@ -/** \file fishd.c - -The universal variable server. fishd is automatically started by fish -if a fishd server isn't already running. fishd reads any saved -variables from ~/.fishd, and takes care of communication between fish -instances. When no clients are running, fishd will automatically shut -down and save. - -\section fishd-commands Commands - -Fishd works by sending and receiving commands. Each command is ended -with a newline. These are the commands supported by fishd: - -
set KEY:VALUE
-set_export KEY:VALUE
-
- -These commands update the value of a variable. The only difference -between the two is that set_export-variables should be -exported to children of the process using them. When sending messages, -all values below 32 or above 127 must be escaped using C-style -backslash escapes. This means that the over the wire protocol is -ASCII. However, any conforming reader must also accept non-ascii -characters and interpret them as UTF-8. Lines containing invalid UTF-8 -escape sequences must be ignored entirely. - -
erase KEY
-
- -Erase the variable with the specified name. - -
barrier
-barrier_reply
-
- -A \c barrier command will result in a barrier_reply being added to -the end of the senders queue of unsent messages. These commands are -used to synchronize clients, since once the reply for a barrier -message returns, the sender can know that any updates available at the -time the original barrier request was sent have been received. - -*/ - -#include "config.h" - - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef HAVE_GETOPT_H -#include -#endif - -#include -#include -#include -#include - -#include "fallback.h" -#include "util.h" - -#include "common.h" -#include "wutil.h" -#include "env_universal_common.h" -#include "path.h" -#include "print_help.h" -#include "fish_version.h" - -#ifndef HOST_NAME_MAX -/** - Maximum length of hostname return. It is ok if this is too short, - getting the actual hostname is not critical, so long as the string - is unique in the filesystem namespace. - */ -#define HOST_NAME_MAX 255 -#endif - -/** - Maximum length of socket filename -*/ -#ifndef UNIX_PATH_MAX -#define UNIX_PATH_MAX 100 -#endif - -/** - Fallback if MSG_DONTWAIT isn't defined. That's actually prerry bad, - and may lead to strange fishd behaviour, but at least it should - work most of the time. -*/ -#ifndef MSG_DONTWAIT -#define MSG_DONTWAIT 0 -#endif - -/** - Small greeting to show that fishd is running -*/ -#define GREETING "# Fish universal variable daemon\n" - -/** - Small not about not editing ~/.fishd manually. Inserted at the top of all .fishd files. -*/ -#define SAVE_MSG "# This file is automatically generated by the fishd universal variable daemon.\n# Do NOT edit it directly, your changes will be overwritten.\n" - -/** - The name of the save file. The machine identifier is appended to this. -*/ -#define FILE "fishd." - -/** - Maximum length of hostname. Longer hostnames are truncated -*/ -#define HOSTNAME_LEN 32 - -/** - The string to append to the socket name to name the lockfile -*/ -#define LOCKPOSTFIX ".lock" - -/** - The timeout in seconds on the lockfile for critical section -*/ -#define LOCKTIMEOUT 1 - -/** - Getopt short switches for fishd -*/ -#define GETOPT_STRING "hv" - -/** - The list of connections to clients -*/ -typedef std::list connection_list_t; -static connection_list_t connections; - -/** - The socket to accept new clients on -*/ -static int sock; - -/** - Set to one when fishd should save and exit -*/ -static int quit=0; - -/** - Constructs the fish socket filename -*/ -static std::string get_socket_filename(void) -{ - const char *dir = getenv("FISHD_SOCKET_DIR"); - char *uname = getenv("USER"); - - if (dir == NULL) - { - dir = "/tmp"; - } - - if (uname == NULL) - { - const struct passwd *pw = getpwuid(getuid()); - uname = pw->pw_name; - } - - std::string name; - name.reserve(strlen(dir)+ strlen(uname)+ strlen(SOCK_FILENAME) + 1); - name.append(dir); - name.push_back('/'); - name.append(SOCK_FILENAME); - name.append(uname); - - if (name.size() >= UNIX_PATH_MAX) - { - debug(1, L"Filename too long: '%s'", name.c_str()); - exit(EXIT_FAILURE); - } - return name; -} - -/** - Signal handler for the term signal. -*/ -static void handle_term(int signal) -{ - quit=1; -} - - -/** - Writes a pseudo-random number (between one and maxlen) of pseudo-random - digits into str. - str must point to an allocated buffer of size of at least maxlen chars. - Returns the number of digits written. - Since the randomness in part depends on machine time it has _some_ extra - strength but still not enough for use in concurrent locking schemes on a - single machine because gettimeofday may not return a different value on - consecutive calls when: - a) the OS does not support fine enough resolution - b) the OS is running on an SMP machine. - Additionally, gettimeofday errors are ignored. - Excludes chars other than digits since ANSI C only guarantees that digits - are consecutive. - */ -static void sprint_rand_digits(char *str, int maxlen) -{ - int i, max; - struct timeval tv; - - /* - Seed the pseudo-random generator based on time - this assumes - that consecutive calls to gettimeofday will return different values - and ignores errors returned by gettimeofday. - Cast to unsigned so that wrapping occurs on overflow as per ANSI C. - */ - static bool seeded = false; - if (! seeded) - { - (void)gettimeofday(&tv, NULL); - unsigned long long seed = tv.tv_sec + tv.tv_usec * 1000000ULL; - srand((unsigned int)seed); - seeded = true; - } - max = (int)(1 + (maxlen - 1) * (rand() / (RAND_MAX + 1.0))); - for (i = 0; i < max; i++) - { - str[i] = '0' + 10 * (rand() / (RAND_MAX + 1.0)); - } - str[i] = 0; -} - - - -/** - Generate a filename unique in an NFS namespace by creating a copy of str and - appending .{hostname}.{pid} to it. If gethostname() fails then a pseudo- - random string is substituted for {hostname} - the randomness of the string - should be strong enough across different machines. The main assumption - though is that gethostname will not fail and this is just a "safe enough" - fallback. - The memory returned should be freed using free(). - */ -static std::string gen_unique_nfs_filename(const std::string &filename) -{ - char hostname[HOST_NAME_MAX + 1]; - char pid_str[256]; - snprintf(pid_str, sizeof pid_str, "%ld", (long)getpid()); - - if (gethostname(hostname, sizeof hostname) != 0) - { - sprint_rand_digits(hostname, HOST_NAME_MAX); - } - - std::string newname(filename); - newname.push_back('.'); - newname.append(hostname); - newname.push_back('.'); - newname.append(pid_str); - return newname; -} - -/** - The number of milliseconds to wait between polls when attempting to acquire - a lockfile - */ -#define LOCKPOLLINTERVAL 10 - -/** - Attempt to acquire a lock based on a lockfile, waiting LOCKPOLLINTERVAL - milliseconds between polls and timing out after timeout seconds, - thereafter forcibly attempting to obtain the lock if force is non-zero. - Returns 1 on success, 0 on failure. - To release the lock the lockfile must be unlinked. - A unique temporary file named by appending characters to the lockfile name - is used; any pre-existing file of the same name is subject to deletion. - */ -static int acquire_lock_file(const std::string &lockfile_str, const int timeout, int force) -{ - int fd, timed_out = 0; - int ret = 0; /* early exit returns failure */ - struct timespec pollint; - struct timeval start, end; - double elapsed; - struct stat statbuf; - const char * const lockfile = lockfile_str.c_str(); - - /* - (Re)create a unique file and check that it has one only link. - */ - const std::string linkfile_str = gen_unique_nfs_filename(lockfile); - const char * const linkfile = linkfile_str.c_str(); - (void)unlink(linkfile); - /* OK to not use CLO_EXEC here because fishd is single threaded */ - if ((fd = open(linkfile, O_CREAT|O_RDONLY, 0600)) == -1) - { - debug(1, L"acquire_lock_file: open: %s", strerror(errno)); - goto done; - } - /* - Don't need to check exit status of close on read-only file descriptors - */ - close(fd); - if (stat(linkfile, &statbuf) != 0) - { - debug(1, L"acquire_lock_file: stat: %s", strerror(errno)); - goto done; - } - if (statbuf.st_nlink != 1) - { - debug(1, L"acquire_lock_file: number of hardlinks on unique " - L"tmpfile is %d instead of 1.", (int)statbuf.st_nlink); - goto done; - } - if (gettimeofday(&start, NULL) != 0) - { - debug(1, L"acquire_lock_file: gettimeofday: %s", strerror(errno)); - goto done; - } - end = start; - pollint.tv_sec = 0; - pollint.tv_nsec = LOCKPOLLINTERVAL * 1000000; - do - { - /* - Try to create a hard link to the unique file from the - lockfile. This will only succeed if the lockfile does not - already exist. It is guaranteed to provide race-free - semantics over NFS which the alternative of calling - open(O_EXCL|O_CREAT) on the lockfile is not. The lock - succeeds if the call to link returns 0 or the link count on - the unique file increases to 2. - */ - if (link(linkfile, lockfile) == 0 || - (stat(linkfile, &statbuf) == 0 && - statbuf.st_nlink == 2)) - { - /* Successful lock */ - ret = 1; - break; - } - elapsed = end.tv_sec + end.tv_usec/1000000.0 - - (start.tv_sec + start.tv_usec/1000000.0); - /* - The check for elapsed < 0 is to deal with the unlikely event - that after the loop is entered the system time is set forward - past the loop's end time. This would otherwise result in a - (practically) infinite loop. - */ - if (timed_out || elapsed >= timeout || elapsed < 0) - { - if (timed_out == 0 && force) - { - /* - Timed out and force was specified - attempt to - remove stale lock and try a final time - */ - (void)unlink(lockfile); - timed_out = 1; - continue; - } - else - { - /* - Timed out and final try was unsuccessful or - force was not specified - */ - debug(1, L"acquire_lock_file: timed out " - L"trying to obtain lockfile %s using " - L"linkfile %s", lockfile, linkfile); - break; - } - } - nanosleep(&pollint, NULL); - } - while (gettimeofday(&end, NULL) == 0); -done: - /* The linkfile is not needed once the lockfile has been created */ - (void)unlink(linkfile); - return ret; -} - -/** - Acquire the lock for the socket - Returns the name of the lock file if successful or - NULL if unable to obtain lock. - The returned string must be free()d after unlink()ing the file to release - the lock -*/ -static bool acquire_socket_lock(const std::string &sock_name, std::string *out_lockfile_name) -{ - bool success = false; - std::string lockfile; - lockfile.reserve(sock_name.size() + strlen(LOCKPOSTFIX)); - lockfile = sock_name; - lockfile.append(LOCKPOSTFIX); - if (acquire_lock_file(lockfile, LOCKTIMEOUT, 1)) - { - out_lockfile_name->swap(lockfile); - success = true; - } - return success; -} - -/** - Connects to the fish socket and starts listening for connections -*/ -static int get_socket(void) -{ - // Cygwin has random problems involving sockets. When using Cygwin, - // allow 20 attempts at making socket correctly. -#ifdef __CYGWIN__ - int attempts = 0; -repeat: - attempts += 1; -#endif - - int s, len, doexit = 0; - int exitcode = EXIT_FAILURE; - struct sockaddr_un local; - const std::string sock_name = get_socket_filename(); - - /* - Start critical section protected by lock - */ - std::string lockfile; - if (! acquire_socket_lock(sock_name, &lockfile)) - { - debug(0, L"Unable to obtain lock on socket, exiting"); - exit(EXIT_FAILURE); - } - debug(4, L"Acquired lockfile: %s", lockfile.c_str()); - - local.sun_family = AF_UNIX; - strcpy(local.sun_path, sock_name.c_str()); - len = sizeof(local); - - debug(1, L"Connect to socket at %s", sock_name.c_str()); - - if ((s = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) - { - wperror(L"socket"); - doexit = 1; - goto unlock; - } - - /* - First check whether the socket has been opened by another fishd; - if so, exit with success status - */ - if (connect(s, (struct sockaddr *)&local, len) == 0) - { - debug(1, L"Socket already exists, exiting"); - doexit = 1; - exitcode = 0; - goto unlock; - } - - unlink(local.sun_path); - if (bind(s, (struct sockaddr *)&local, len) == -1) - { - wperror(L"bind"); - doexit = 1; - goto unlock; - } - - if (make_fd_nonblocking(s) != 0) - { - wperror(L"fcntl"); - close(s); - doexit = 1; - } - else if (listen(s, 64) == -1) - { - wperror(L"listen"); - doexit = 1; - } - -unlock: - (void)unlink(lockfile.c_str()); - debug(4, L"Released lockfile: %s", lockfile.c_str()); - /* - End critical section protected by lock - */ - - if (doexit) - { - // If Cygwin, only allow normal quit when made lots of attempts. -#ifdef __CYGWIN__ - if (exitcode && attempts < 20) goto repeat; -#endif - exit_without_destructors(exitcode); - } - - return s; -} - -/** - Event handler. Broadcasts updates to all clients. -*/ -static void broadcast(fish_message_type_t type, const wchar_t *key, const wchar_t *val) -{ - message_t *msg; - - if (connections.empty()) - return; - - msg = create_message(type, key, val); - - /* - Don't merge these loops, or try_send_all can free the message - prematurely - */ - - for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter) - { - msg->count++; - iter->unsent.push(msg); - } - - for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter) - { - try_send_all(&*iter); - } -} - -/** - Make program into a creature of the night. -*/ -static void daemonize() -{ - /* - Fork, and let parent exit - */ - switch (fork()) - { - case -1: - debug(0, L"Could not put fishd in background. Quitting"); - wperror(L"fork"); - exit(1); - - case 0: - { - /* Ordinarily there's very limited things we will do after fork, due to multithreading. But fishd is safe because it's single threaded. So don't die in is_forked_child. */ - setup_fork_guards(); - - /* - Make fishd ignore the HUP and PIPE signals. - */ - struct sigaction act; - sigemptyset(& act.sa_mask); - act.sa_flags=0; - act.sa_handler=SIG_IGN; - sigaction(SIGHUP, &act, 0); - sigaction(SIGPIPE, &act, 0); - - /* - Make fishd save and exit on the TERM signal. - */ - sigfillset(& act.sa_mask); - act.sa_flags=0; - act.sa_handler=&handle_term; - sigaction(SIGTERM, &act, 0); - break; - - } - - default: - { - debug(0, L"Parent process exiting (This is normal)"); - exit(0); - } - } - - /* - Put ourself in our own process group - */ - setsid(); - - /* - Close stdin and stdout. We only use stderr, anyway. - */ - close(0); - close(1); - -} - -/** - Get environment variable value. -*/ -static env_var_t fishd_env_get(const char *key) -{ - const char *env = getenv(key); - if (env != NULL) - { - return env_var_t(str2wcstring(env)); - } - else - { - const wcstring wkey = str2wcstring(key); - return env_universal_common_get(wkey); - } -} - -/** - Get the configuration directory. The resulting string needs to be - free'd. This is mostly the same code as path_get_config(), but had - to be rewritten to avoid dragging in additional library - dependencies. -*/ -static wcstring fishd_get_config() -{ - bool done = false; - wcstring result; - - env_var_t xdg_dir = fishd_env_get("XDG_CONFIG_HOME"); - if (! xdg_dir.missing_or_empty()) - { - result = xdg_dir; - append_path_component(result, L"/fish"); - if (!create_directory(result)) - { - done = true; - } - } - else - { - env_var_t home = fishd_env_get("HOME"); - if (! home.missing_or_empty()) - { - result = home; - append_path_component(result, L"/.config/fish"); - if (!create_directory(result)) - { - done = 1; - } - } - } - - if (! done) - { - /* Bad juju */ - debug(0, _(L"Unable to create a configuration directory for fish. Your personal settings will not be saved. Please set the $XDG_CONFIG_HOME variable to a directory where the current user has write access.")); - result.clear(); - } - - return result; -} - -/** - Load or save all variables -*/ -static bool load_or_save_variables_at_path(bool save, const std::string &path) -{ - bool result = false; - - debug(4, L"Open file for %s: '%s'", - save?"saving":"loading", - path.c_str()); - - /* OK to not use CLO_EXEC here because fishd is single threaded */ - int fd = open(path.c_str(), save?(O_CREAT | O_TRUNC | O_WRONLY):O_RDONLY, 0600); - if (fd >= 0) - { - /* Success */ - result = true; - connection_t c(fd); - - if (save) - { - /* Save to the file */ - write_loop(c.fd, SAVE_MSG, strlen(SAVE_MSG)); - enqueue_all(&c); - } - else - { - /* Read from the file */ - read_message(&c); - } - - connection_destroy(&c); - } - return result; -} - - -static std::string get_variables_file_path(const std::string &dir, const std::string &identifier) -{ - std::string name; - name.append(dir); - name.append("/"); - name.append(FILE); - name.append(identifier); - return name; -} - - -static bool load_or_save_variables(bool save) -{ - const wcstring wdir = fishd_get_config(); - const std::string dir = wcs2string(wdir); - if (dir.empty()) - return false; - - const std::string machine_id = get_machine_identifier(); - const std::string machine_id_path = get_variables_file_path(dir, machine_id); - bool success = load_or_save_variables_at_path(save, machine_id_path); - if (! success && ! save && errno == ENOENT) - { - /* We failed to load, because the file was not found. Older fish used the hostname only. Try *moving* the filename based on the hostname into place; if that succeeds try again. Silently "upgraded." */ - std::string hostname_id; - if (get_hostname_identifier(&hostname_id) && hostname_id != machine_id) - { - std::string hostname_path = get_variables_file_path(dir, hostname_id); - if (0 == rename(hostname_path.c_str(), machine_id_path.c_str())) - { - /* We renamed - try again */ - success = load_or_save_variables_at_path(save, machine_id_path); - } - } - } - return success; -} - -/** - Load variables from disk -*/ -static void load() -{ - load_or_save_variables(false /* load, not save */); -} - -/** - Save variables to disk -*/ -static void save() -{ - load_or_save_variables(true /* save, not load */); -} - -/** - Do all sorts of boring initialization. -*/ -static void init() -{ - - sock = get_socket(); - daemonize(); - env_universal_common_init(&broadcast); - - load(); -} - -/** - Main function for fishd -*/ -int main(int argc, char ** argv) -{ - int child_socket; - struct sockaddr_un remote; - socklen_t t; - uid_t sock_euid; - gid_t sock_egid; - int max_fd; - int update_count=0; - - fd_set read_fd, write_fd; - - set_main_thread(); - setup_fork_guards(); - - program_name=L"fishd"; - wsetlocale(LC_ALL, L""); - - /* - Parse options - */ - while (1) - { - static struct option - long_options[] = - { - { - "help", no_argument, 0, 'h' - } - , - { - "version", no_argument, 0, 'v' - } - , - { - 0, 0, 0, 0 - } - } - ; - - int opt_index = 0; - - int opt = getopt_long(argc, - argv, - GETOPT_STRING, - long_options, - &opt_index); - - if (opt == -1) - break; - - switch (opt) - { - case 0: - break; - - case 'h': - print_help(argv[0], 1); - exit(0); - - case 'v': - debug(0, L"%ls, version %s\n", program_name, get_fish_version()); - exit(0); - - case '?': - return 1; - - } - } - - init(); - while (1) - { - int res; - - t = sizeof(remote); - - FD_ZERO(&read_fd); - FD_ZERO(&write_fd); - FD_SET(sock, &read_fd); - max_fd = sock+1; - for (connection_list_t::const_iterator iter = connections.begin(); iter != connections.end(); ++iter) - { - const connection_t &c = *iter; - FD_SET(c.fd, &read_fd); - max_fd = maxi(max_fd, c.fd+1); - - if (! c.unsent.empty()) - { - FD_SET(c.fd, &write_fd); - } - } - - while (1) - { - res=select(max_fd, &read_fd, &write_fd, 0, 0); - - if (quit) - { - save(); - exit(0); - } - - if (res != -1) - break; - - if (errno != EINTR) - { - wperror(L"select"); - exit(1); - } - } - - if (FD_ISSET(sock, &read_fd)) - { - if ((child_socket = - accept(sock, - (struct sockaddr *)&remote, - &t)) == -1) - { - wperror(L"accept"); - exit(1); - } - else - { - debug(4, L"Connected with new child on fd %d", child_socket); - - if (((getpeereid(child_socket, &sock_euid, &sock_egid) != 0) || sock_euid != geteuid())) - { - debug(1, L"Wrong credentials for child on fd %d", child_socket); - close(child_socket); - } - else if (make_fd_nonblocking(child_socket) != 0) - { - wperror(L"fcntl"); - close(child_socket); - } - else - { - connections.push_front(connection_t(child_socket)); - connection_t &newc = connections.front(); - send(newc.fd, GREETING, strlen(GREETING), MSG_DONTWAIT); - enqueue_all(&newc); - } - } - } - - for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter) - { - if (FD_ISSET(iter->fd, &write_fd)) - { - try_send_all(&*iter); - } - } - - for (connection_list_t::iterator iter = connections.begin(); iter != connections.end(); ++iter) - { - if (FD_ISSET(iter->fd, &read_fd)) - { - read_message(&*iter); - - /* - Occasionally we save during normal use, so that we - won't lose everything on a system crash - */ - update_count++; - if (update_count >= 64) - { - save(); - update_count = 0; - } - } - } - - for (connection_list_t::iterator iter = connections.begin(); iter != connections.end();) - { - if (iter->killme) - { - debug(4, L"Close connection %d", iter->fd); - - while (! iter->unsent.empty()) - { - message_t *msg = iter->unsent.front(); - iter->unsent.pop(); - msg->count--; - if (! msg->count) - free(msg); - } - - connection_destroy(&*iter); - iter = connections.erase(iter); - } - else - { - ++iter; - } - } - - if (connections.empty()) - { - debug(0, L"No more clients. Quitting"); - save(); - break; - } - - } -} -