diff --git a/init/edit_launchd.cgi b/init/edit_launchd.cgi
new file mode 100755
index 000000000..1b9bd85b5
--- /dev/null
+++ b/init/edit_launchd.cgi
@@ -0,0 +1,65 @@
+#!/usr/local/bin/perl
+# Show a form for creating or editing a launchd agent
+
+require './init-lib.pl';
+$access{'bootup'} || &error($text{'edit_ecannot'});
+&ReadParse();
+
+if ($in{'new'}) {
+ &ui_print_header(undef, $text{'launchd_title1'}, "");
+ $u = { };
+ }
+else {
+ &ui_print_header(undef, $text{'launchd_title2'}, "");
+ @systemds = &list_launchd_agents();
+ ($u) = grep { $_->{'name'} eq $in{'name'} } @systemds;
+ $u || &error($text{'launchd_egone'});
+ }
+
+print &ui_form_start("save_launchd.cgi", "post");
+print &ui_hidden("new", $in{'new'});
+print &ui_hidden("name", $in{'name'}) if (!$in{'new'});
+print &ui_table_start($text{'launchd_header'}, undef, 2);
+
+if ($in{'new'}) {
+ # Service name
+ print &ui_table_row($text{'launchd_name'},
+ &ui_textbox("name", undef, 30).".service");
+
+ # Server command and args
+ print &ui_table_row($text{'launchd_start'},
+ &ui_textarea("atstart", undef, 5, 80));
+ }
+else {
+ # Service name (non-editable)
+ print &ui_table_row($text{'launchd_name'},
+ "$in{'name'}");
+
+ # Config file
+ $conf = &read_file_contents($u->{'file'});
+ print &ui_table_row($text{'launchd_conf'},
+ &ui_textarea("conf", $conf, 20, 80));
+
+ # Current status
+ print &ui_table_row($text{'launchd_status'},
+ $u->{'status'} && $u->{'pid'} ?
+ &text('systemd_status1', $u->{'pid'}) :
+ $u->{'status'} ?
+ $text{'systemd_status2'} :
+ $text{'systemd_status0'});
+ }
+
+print &ui_table_end();
+if ($in{'new'}) {
+ print &ui_form_end([ [ undef, $text{'create'} ] ]);
+ }
+else {
+ print &ui_form_end([ [ undef, $text{'save'} ],
+ [ 'start', $text{'edit_startnow'} ],
+ [ 'restart', $text{'edit_restartnow'} ],
+ [ 'stop', $text{'edit_stopnow'} ],
+ [ 'delete', $text{'delete'} ] ]);
+ }
+
+&ui_print_footer("", $text{'index_return'});
+
diff --git a/init/lang/en b/init/lang/en
index 0699570af..cd2d25683 100644
--- a/init/lang/en
+++ b/init/lang/en
@@ -239,4 +239,23 @@ systemd_return=systemd service
systemd_econf=No systemd configuration entered
systemd_estart=Missing commands to run on startup
+launchd_title1=Create Launchd Agent
+launchd_title2=Edit Launchd Agent
+launchd_egone=Agent no longer exists!
+launchd_header=Launchd service details
+launchd_name=Agent name
+launchd_start=Server command
+launchd_conf=Launchd configuration
+launchd_boot=Start at boot time?
+launchd_status=Current status
+launchd_status0=Not running
+launchd_status1=Running with PID $1
+launchd_status2=Running
+launchd_err=Failed to save launchd agent
+launchd_ename=Missing or invalid-lookup launchd agent name
+launchd_eclash=An agent with the same name already exists
+launchd_return=launchd agent
+launchd_econf=No launchd configuration entered
+launchd_estart=Missing server command
+
__norefs=1