Run runs the user server using the configured executable. This function only works on UNIX systems, but those are the only ones on which we use userServers anyway.
()
| 327 | // works on UNIX systems, but those are the only ones on which we use |
| 328 | // userServers anyway. |
| 329 | func (s *userServer) run() error { |
| 330 | // set up the command |
| 331 | args := []string{"serve-taildrive"} |
| 332 | for _, s := range s.shares { |
| 333 | args = append(args, s.Name, s.Path) |
| 334 | } |
| 335 | var cmd *exec.Cmd |
| 336 | |
| 337 | if s.canSudo() { |
| 338 | s.logf("starting taildrive file server with sudo as user %q", s.username) |
| 339 | allArgs := []string{"-n", "-u", s.username, s.executable} |
| 340 | allArgs = append(allArgs, args...) |
| 341 | cmd = exec.Command("sudo", allArgs...) |
| 342 | } else if su := s.canSU(); su != "" { |
| 343 | s.logf("starting taildrive file server with su as user %q", s.username) |
| 344 | // Quote and escape arguments. Use single quotes to prevent shell substitutions. |
| 345 | for i, arg := range args { |
| 346 | args[i] = "'" + strings.ReplaceAll(arg, "'", "'\"'\"'") + "'" |
| 347 | } |
| 348 | cmdString := fmt.Sprintf("%s %s", s.executable, strings.Join(args, " ")) |
| 349 | allArgs := []string{s.username, "-c", cmdString} |
| 350 | cmd = exec.Command(su, allArgs...) |
| 351 | } else { |
| 352 | // If we were root, we should have been able to sudo or su as a specific |
| 353 | // user, but let's check just to make sure, since we never want to |
| 354 | // access shared folders as root. |
| 355 | err := s.assertNotRoot() |
| 356 | if err != nil { |
| 357 | return err |
| 358 | } |
| 359 | s.logf("starting taildrive file server as ourselves") |
| 360 | cmd = exec.Command(s.executable, args...) |
| 361 | } |
| 362 | stdout, err := cmd.StdoutPipe() |
| 363 | if err != nil { |
| 364 | return fmt.Errorf("stdout pipe: %w", err) |
| 365 | } |
| 366 | defer stdout.Close() |
| 367 | stderr, err := cmd.StderrPipe() |
| 368 | if err != nil { |
| 369 | return fmt.Errorf("stderr pipe: %w", err) |
| 370 | } |
| 371 | defer stderr.Close() |
| 372 | |
| 373 | err = cmd.Start() |
| 374 | if err != nil { |
| 375 | return fmt.Errorf("start: %w", err) |
| 376 | } |
| 377 | s.mu.Lock() |
| 378 | s.cmd = cmd |
| 379 | s.mu.Unlock() |
| 380 | |
| 381 | // read address |
| 382 | stdoutScanner := bufio.NewScanner(stdout) |
| 383 | stdoutScanner.Scan() |
| 384 | if stdoutScanner.Err() != nil { |
| 385 | return fmt.Errorf("read addr: %w", stdoutScanner.Err()) |
| 386 | } |
no test coverage detected