# transfer a simple script from debian to FreeBSD



## boistordu (Mar 17, 2018)

```
#!/usr/bin/env bash


# Dependance : screen, killall et rtorrent

### BEGIN INIT INFO

# Provides:          <username>-rtorrent

# Required-Start:    $syslog $network

# Required-Stop:     $syslog $network

# Default-Start:     2 3 4 5

# Default-Stop:      0 1 6

# Short-Description: Start daemon at boot time

# Description:       Start-Stop rtorrent user session

### END INIT INFO


## Debut configuration ##

user="flood"

## Fin configuration ##

rt_start() {

    su flood -m -c 'screen -S flood-rtorrent -dm rtorrent'

}


rt_stop() {

    su flood -m -c 'screen -S flood-rtorrent -X quit'

}


case "$1" in

    start)

        echo "Demarrage de rtorrent..."

        rt_start

    ;;

    stop)

        echo "Arret de rtorrent..."

        rt_stop

    ;;

    restart)

        echo "Redemarrage de rtorrent..."

        rt_stop

        sleep 1

        rt_start

    ;;

    *)


        rt_start

    ;;

    stop)

        echo "Arret de rtorrent..."

        rt_stop

    ;;

    restart)

        echo "Redemarrage de rtorrent..."

        rt_stop

        sleep 1

        rt_start

    ;;

    *)

        echo "Usage: $0 {start|stop|restart}"

        exit 1

    ;;

esac


exit 0
```

This the script I try to run but it doesn't seem to work for now. I've tried several variations. It works on debian.
Doesn't work very well on FreeBSD for mysterious ways. 
the '$user' env doesn't work because I can see that it's root which is used if I replace flood by $user in the script*.
At first in place of the -c there was --command= and that doesn't work either so I change it.

What I could state also, it's not the same version of manual between FreeBSD and debian/ubuntu . In FreeBSD there is no command line. So maybe I'm not doing something which is compatible with the FREEBSD way?


----------



## scottro (Mar 17, 2018)

The stupid question, is bash installed?  Although it makes it less portable, what about trying #!/usr/local/bin/bash


----------



## ralphbsz (Mar 18, 2018)

This is not a regular script that is intended to be run from the command line.  It looks like a rc script that is used by some flavor of init. Did you run it from the command line, or did you try to install it in /usr/local/etc/rc.d ?

And a more general question: What are you trying to accomplish?  Don't say "run this script", because we know that!  Tell us something like "start rtorrent with parameters X and Y, running as user Foo, but only if there isn't a purple flying elephant in /tmp already".


----------



## boistordu (Mar 18, 2018)

yes just verified, bash is installed. 
Can someone try it ? 
and according to echo $0  I'm using it right now.
Actually I have different result if I use the script of if I directly use the command from the script. That's why it would be great if someone could use it.


----------



## boistordu (Mar 18, 2018)

the script is located in /usr/local/etc/rc.d yes. 
I thought that I could launch the script also in in bash or am I wrong? 

The goal here is to launch a rtorrent session under the flood user and this session of rtorrent should be in a screen's session called flood-rtorrent which is of course called also by the user flood.


----------



## boistordu (Mar 18, 2018)

and also as you can see I don't check if any other variable like a pid file is launched or things like that since the screen session should be able to do that by itself. Taht's why it should be compartimentalized in a screen's session with a specific name.


----------



## ralphbsz (Mar 18, 2018)

boistordu said:


> the script is located in /usr/local/etc/rc.d yes.


If you are trying to take an rc script from a Debian system, and use it on FreeBSD as an rc script (one that is installed in /usr/local/etc/rc.d), that will simply not work.  The interface that init uses into rc scripts is completely different between the two operating systems.

If you want to start rtorrent as user flood as an init service, you should take an existing FreeBSD rc script, copy it, and modify it for your purposes.  I'm including an example for a service I have on my home machine called "eqmon" (don't copy it slavishly, look at the concepts):

```
#!/bin/sh

# PROVIDE: eqmon
# REQUIRE: DAEMON

# Add the following lines to /etc/rc.conf to enable':
# eqmon_enable="YES"

. /etc/rc.subr

name="eqmon"
rcvar=`set_rcvar`

command="/usr/local/sbin/eqmon_daemon"
pidfile="/var/run/$name.pid"

# read configuration and set defaults
load_rc_config "$name"
: ${eqmon_enable="NO"}

if [ $# -gt 0 -a "$1" = "stop" ]
then
  /usr/local/bin/eqctl quit
  exit
fi

run_rc_command "$1"
```


----------



## boistordu (Mar 18, 2018)

okey. Sorry I was naively thinking that it would be the same package and so working as intended in the same way. 
So should I take as granted that any package on freeBSD is working differently than a debian system then ?


----------



## boistordu (Mar 18, 2018)

and also another question: How can I test a script like that without rebooting the system? 
On debian, I could simply launch the script to test it since it is simple bash command. But here it seems clearly more advanced.


----------



## Spartrekus (Mar 18, 2018)

boistordu said:


> ```
> #!/usr/bin/env bash
> 
> 
> ...



Hi,

In plain C, you may mod / use a cool quick and dirty PID check, and let it run if you'd like.

Cron/crontab could do the check for you.


```
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <dirent.h>
#include <ctype.h>
#include <sys/stat.h>
#include <dirent.h>
#include <sys/types.h>
#include <unistd.h>  //define getcwd
#include <time.h>


///////////////////////////////
///////////////////////////////
///////////////////////////////
char *strtimestampstatic()
{
      long t;
      struct tm *ltime;
      time(&t);
      ltime=localtime(&t);
      char charo[50];  int fooi ;
      fooi = snprintf( charo, 50 , "%04d%02d%02d%02d%02d%02d",
    1900 + ltime->tm_year, ltime->tm_mon +1 , ltime->tm_mday,
    ltime->tm_hour, ltime->tm_min, ltime->tm_sec
    );
    size_t siz = sizeof charo ;
    char *r = malloc( sizeof charo );
    return r ? memcpy(r, charo, siz ) : NULL;
}








////////////////////////////////////////
int main( int argc, char *argv[])
{
    printf( "LSPID\n" );

    FILE *fp;
    int i ;
    char charo[PATH_MAX];
    char cmdi[PATH_MAX];
    char processname[PATH_MAX];
    strncpy( processname, "ndaemon" , PATH_MAX );

    ////////////////////////////////////////////////////////
   /*
     if ( argc == 2)
      if ( strcmp( argv[1] , "" ) !=  0 )
      {
         strncpy( processname, argv[ 1 ], PATH_MAX );
         //return 0;
      }
      */
   //printf( "Search %s\n", processname );

   int psfound = 0;
   const char* directory = "/proc";
   size_t      taskNameSize = 1024;
   char*       taskName = calloc(1, taskNameSize);
   DIR* dir = opendir(directory);
   if (dir)
   {
      struct dirent* de = 0;

      while ((de = readdir(dir)) != 0)
      {
         if (strcmp(de->d_name, ".") == 0 || strcmp(de->d_name, "..") == 0)
            continue;

         int pid = -1;
         int res = sscanf(de->d_name, "%d", &pid);

         if (res == 1)
         {
            // we have a valid pid
            // open the cmdline file to determine what's the name of the process running
            char cmdline_file[1024] = {0};
            sprintf(cmdline_file, "%s/%d/cmdline", directory, pid);

            FILE* cmdline = fopen(cmdline_file, "r");

            if (getline(&taskName, &taskNameSize, cmdline) > 0)
            {
               // is it the process we care about?
               //if (strstr(taskName, processname ) != 0)
               {
                  //fprintf(stdout, "A %s process, with PID %d, has been detected.\n", argv[1], pid);
                  i = snprintf( charo, 100 , "A %s process, with PID %d, has been detected.", taskName , pid);
          printf( "%s \n", charo );
               }
            }

            fclose(cmdline);
         }
      }

      closedir(dir);
   }



  return 0;
}
```


----------



## acheron (Mar 18, 2018)

boistordu said:


> and also another question: How can I test a script like that without rebooting the system?
> On debian, I could simply launch the script to test it since it is simple bash command. But here it seems clearly more advanced.


It's a service so just use `service myservicename start` (or onestart if you don't put myservicename_enable="YES" in /etc/rc.conf
or use `bash scriptname`


----------



## ralphbsz (Mar 18, 2018)

What acheron said: You want to start and stop a service or daemon.  Write the rc script, then use the appropriate commands to have the script exercised within the "service" infrastructure.  Rc scripts are not intended to be general-purpose scripts, and are not intended to be run from the command line.

For general scripts, `bash script name` is one good answer.  Another one is: Every script should have the so-called "bang-pound" line at the beginning, so it can be executed.  So if you write a shell script, you put "#!/bin/sh" at the top of the script, mark it as executable with `chmod`, and then you can run it by typing the file name of the script (perhaps shorten it by using the executable path).


----------



## boistordu (Mar 20, 2018)

I understand yes. 
And yes I totally agree that rc script are not basic bash script. But under debian the philosophy, which I know later past week, is other than FreeBSD about those script and that why it is more simpler to start a script like that in debian and not in FreeBSD. 
And also what have I learned it's that if they use the same daemon name "service" it's an historical inheritance and not the fact that it was the same dev team nor the same package which can lead to some confusion, especially when all other packages in FreeBSD are using different names than debian package for their daemons. 

So I continue to look to learn the syntax for those script on FreeBSD and will test it with the appropriate command yes.


----------

