Best way to get a bash script working in C

Ahoy friends.
Currently i got a bash script running to manage my minecraft servers.

All of them are stored in /home/minecraft_servers directory.
Using my script im able to start a server (e.g. ./minecraft start ftb_continuum) because server name and server name are the same.(e.g. /home/minecraft_servers/ftb_continuum)
Because of security and efficiency reasons i want to get this script working in C but unfortunately i dont know how to begin, even using my rusty knowledge of my study.
Does someone have any advice how to begin?

Thats my bash script:

#!/bin/bash
# /etc/init.d/minecraft
# version 0.4.2 2016-02-09 (YYYY-MM-DD)
#
### BEGIN INIT INFO
# Provides:   minecraft
# Required-Start: $local_fs $remote_fs screen-cleanup
# Required-Stop:  $local_fs $remote_fs
# Should-Start:   $network
# Should-Stop:    $network
# Default-Start:  2 3 4 5
# Default-Stop:   0 1 6
# Short-Description:    Minecraft server
# Description:    Starts the minecraft server
### END INIT INFO

#Settings
SERVICE="${2}.jar"
SCREENNAME=$2
OPTIONS='nogui'
USERNAME='root'
WORLD='world'
MCPATH="/home/minecraft_servers/${2}/"
MINHEAP=4096
HISTORY=4096
CPU_COUNT=16
Xms=1G
JAVACMD="java"
MAX_RAM="8192M"     # -Xmx
JAVA_PARAMETERS="-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=${CPU_COUNT} -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:+AggressiveOpts -Xms${Xms}"
INVOCATION="${JAVACMD} -server -Xmx${MAX_RAM} ${JAVA_PARAMETERS} -jar ${SERVICE} nogui"
Backuppath="/var/www/backup_folder/Minecraft/modded/"
Zielordner="${Backuppath}Minecraft_Modded_Backup_${SERVICE}_$(date +%Y-%m-%d_%H-%M).7z"
Password="FASkog4AmtO1XIvGbkh8sqppYs51Eo7E7drbVpCSXOIsX4yyaUsIXvVEnLGQELMh3n1eqI23QiOGVhnsnlCX7GGMQKVapKCfoqnei2u8Ssb7ZDgbbbfYgpoo0DT"




ME=`whoami`
as_user() {
  if [ "$ME" = "$USERNAME" ] ; then
    bash -c "$1"
  else
    su - "$USERNAME" -c "$1"
  fi
}

mc_start() {
  if  pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is already running!"
  else
    echo "Starting $SERVICE..."
    cd $MCPATH
    as_user "cd $MCPATH && screen -h $HISTORY -dmS ${SCREENNAME} $INVOCATION"
    sleep 7
    if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
      echo "$SERVICE is now running."
    else
      echo "Error! Could not start $SERVICE!"
    fi
  fi
}

mc_saveoff() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is running... suspending saves"
   as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-off\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-all\"\015'"
    sync
    sleep 10
  else
    echo "$SERVICE is not running. Not suspending saves."
  fi
}
mc_port(){


      grep -n 'server-port=' "$MCPATH/server.properties"


}

mc_saveon() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is running... re-enabling saves"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-on\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
  else
    echo "$SERVICE is not running. Not resuming saves."
  fi
}

mc_stop() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "Stopping $SERVICE"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"say SERVER SHUTTING DOWN IN 10 SECONDS. Saving map...\"\015'"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"save-all\"\015'"
    sleep 10
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"stop\"\015'"
    sleep 7
  else
    echo "$SERVICE was not running."
  fi
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "Error! $SERVICE could not be stopped."
  else
    echo "$SERVICE is stopped."
  fi
}

mc_update() {
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    echo "$SERVICE is running! Will not start update."
  else
    as_user "cd $MCPATH && wget -q -O $MCPATH/versions --no-check-certificate https://launchermeta.mojang.com/mc/game/version_manifest.json"
    if [ "$1" == "snapshot" ] ; then
      JSONVERSION=`cd $MCPATH && cat versions | python -c "exec(\"import json,sys\nobj=json.load(sys.stdin)\nversion=obj['latest']['snapshot']\nfor v in obj['versions']:\n   if v['id']==version:\n    print(v['url'])\")"`
    else
      JSONVERSION=`cd $MCPATH && cat versions | python -c "exec(\"import json,sys\nobj=json.load(sys.stdin)\nversion=obj['latest']['release']\nfor v in obj['versions']:\n   if v['id']==version:\n    print(v['url'])\")"`
    fi
    as_user "cd $MCPATH && wget -q -O $MCPATH/versions --no-check-certificate $JSONVERSION"
    MC_SERVER_URL=`cd $MCPATH && cat versions | python -c 'import json,sys;obj=json.load(sys.stdin);print(obj["downloads"]["server"]["url"])'`
    as_user "rm $MCPATH/versions"
    as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update --no-check-certificate $MC_SERVER_URL"
    if [ -f $MCPATH/minecraft_server.jar.update ] ; then
      if `diff $MCPATH/$SERVICE $MCPATH/minecraft_server.jar.update >/dev/null` ; then
        echo "You are already running the latest version of $SERVICE."
      else
        as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/$SERVICE"
        echo "Minecraft successfully updated."
      fi
    else
      echo "Minecraft update could not be downloaded."
    fi
  fi
}

mc_backup() {
mc_saveoff

if [ ! -d "${MCPATH}" ]; then
    echo "MCPATH existiert nicht!"
    exit 1
fi
if [ -d "${Zielordner}" ]; then
    echo "Zielordner bereits vorhanden!"
    exit 1
fi

7z a -t7z -mx=0 -m0=LZMA2 -mmt=${CPU_COUNT} -p"${Password}" "${Zielordner}" "${MCPATH}" >> "${Backuppath}placeholder.txt"
7z h -scrcsha256 "${Zielordner}" >> "${Backuppath}placeholder.txt"
mc_saveon
}

mc_command() {
  command="$1";
  if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
    pre_log_len=`wc -l "$MCPATH/logs/latest.log" | awk '{print $1}'`
    echo "$SERVICE is running... executing command"
    as_user "screen -p 0 -S ${SCREENNAME} -X eval 'stuff \"$command\"\015'"
    sleep .1 # assumes that the command will run and print to the log file in less than .1 seconds
    # print output
    tail -n $[`wc -l "$MCPATH/logs/latest.log" | awk '{print $1}'`-$pre_log_len] "$MCPATH/logs/latest.log"
  fi
}

#Start-Stop here
case "$1" in
  start)
    mc_start
    ;;
  stop)
    mc_stop
    ;;
  restart)
    mc_stop
    mc_start
    ;;
  update)
    mc_stop
    mc_backup
    mc_update $2
    mc_start
    ;;
  backup)
    mc_backup
    ;;
  port)
    mc_port
    ;;
  status)
    if pgrep -u $USERNAME -f $SERVICE > /dev/null ; then
      echo "$SERVICE is running."
    else
      echo "$SERVICE is not running."
    fi
    ;;
  command)
    if [ $# -gt 1 ] ; then
      shift
      mc_command "$*"
    else
      echo "Must specify server command (try 'help'?)"
    fi
    ;;

  *)
  echo "Usage: $0 {start|stop|update|backup|status|restart|command|port \"server command\"}"
  exit 1
  ;;
esac

exit 0

I started to create something this way, but now i dont know how to continue.
I have to use bash commands to start the servers, like java -jar (servername) so i have to use system() command.
But i also have to know if the service is already running.

Thats what i have done, but its not working yet.

#include <stdio.h>

#define BUFSIZE 128


const char $USERNAME[]="root";




const char *identifier[5]={"ftb_continuum","ftb_continuum_last","lost+souls","final+frontier","sky_adventure"};



char OPTIONS[]="nogui";
char JAVA_PARAM[]="-XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:+CMSIncrementalPacing -XX:+CMSClassUnloadingEnabled -XX:ParallelGCThreads=${CPU_COUNT} -XX:MinHeapFreeRatio=5 -XX:MaxHeapFreeRatio=10 -XX:+AggressiveOpts -Xms${Xms}";
char INVOCATION[]="java -jar -server -Xmx4096 ${JAVA_PARAM} -jar ${SERVICE} nogui";
char Backuppath[]="/var/www/repo.openknogle.eu/Minecraft/modded/";
char Password[]="FASkog4AmtO1XIvGbkh8sqppYs51Eo7E7drbVpCSXOIsX4yyaUsIXvVEnLGQELMh3n1eqI23QiOGVhnsnlCX7GGMQKVapKCfoqnei2u8Ssb7ZDgbbbfYgpoo0DT";
int HISTORY = 4096;
const char as_user[]="su - $USERNAME -c argv[1] ";



int send_get_bash(const char *cmd);
int start(const char *server);


}
int main( int argc, char *argv[] )  {

    if( argc == 2 ) //Valid options entered
    {
        if(argv[1] == "start")
        {
            if(argv[2] == "all")
            {
                for(int t;t<sizeof(identifier))
                {
                    run_server(identifier[t]);
                }
            }
            else
            {
                run_server(argv[2]);
            }
        }
        if(argv[1] == "stop")
        {
            if(argv[2] == "all")
            {
                for(int t;t<sizeof(identifier))
                {
                    stop_server(identifier[t]);
                }
            }
            else
            {
                stop_server(argv[2]);
            }
        }
        if(argv[1] == "restart")
        {
            if(argv[2] == "all")
            {
                for(int t;t<sizeof(identifier))
                {
                    restart_server(identifier[t]);
                }
            }
            else
            {
                restart_server(argv[2]);
            }
        }
        if(argv[1] == "backup")
        {
            if(argv[2] == "all")
            {
                for(int t;t<sizeof(identifier))
                {
                    backup_server(identifier[t]);
                }
            }
            else
            {
                backup_server(argv[2]);
            }
        }
        
        
        
        
    }


int restart_server(char *server)
    {
        stop_server(server);
        run_server(server);
    }

    else if( argc > 2 ) {
        printf("Too many arguments supplied.\n");
    }
    else {
        printf("One argument expected.\n");
    }
}


int run_server(char *server)
{
    char buffer[128];
    snprintf(buffer, sizeof buffer, "./start.sh %s %s %s %i",server,JAVA_PARAM,$USERNAME,HISTORY,INVOCATION);
    send_get_bash(buffer);
    return 1;
}



int send_get_bash(const char *cmd) 
{
    

    char buf[BUFSIZE];
    FILE *fp;

    if ((fp = popen(cmd, "r")) == NULL) {
        printf("Error opening pipe!\n");
        return -1;
    }

    while (fgets(buf, BUFSIZE, fp) != NULL) {
    
        printf("%s", buf);
    }

    if(pclose(fp))  {
        printf("Command not found or exited with error status\n");
        return -1;
    }

    return 0;
}


mc_start(const char *server_start) 
{
    for(new t;t<sizeof(identifier))
    {
        if(strcmp(server,identifier[k]);
                {
                    
                    goto start;
                    break;
                }
                else if k=sizeof(identifier)-1;
                {
                    printf("Invalid Service!");
                }
            }
        }

start:
        
        run_server(server_start);
    }

    mc_stop(const char *server_stop) 
    {
        for(new t;t<sizeof(identifier))
        {
            if(strcmp(server,identifier[k]);
            {
                
                goto stop;
                break;
            }
            else if k=sizeof(identifier)-1;
            {
                printf("Invalid Service!");
            }
        }
    }

stop:
    
    stop_server(server_stop);
}

mc_restart(const char *server_restart) 
{
    for(new t;t<sizeof(identifier))
    {
        if(strcmp(server,identifier[k]);
        {
            
            goto restart;
            break;
        }
        else if k=sizeof(identifier)-1;
        {
            printf("Invalid Service!");
        }
    }
}

restart:

restart_server(server_restart);
}

Welcome to the forums :slight_smile:

I must be a party breaker here, without dwelling into code..
Why do you think for security and efficiency reasons would one exchange a shell script with a c program to start a java program ?

Seems like an insane overhead to me, even for someone who will write a good c program to do that action.

Would it help to rewrite shell code perhaps ?
Some features or something you would like to improve ?

Regards
Peasant.

This is premature optimization. Do you know what system() invokes? The shell. Running twenty shells isn't going to be more secure than running one shell. C isn't inherently more secure, besides -- used blindly, it's a whole lot less.

Exactly what efficiency and security problems do you wish to solve? I can think of a few ways to improve what I see but none of them require C yet.